Convert yangtools binding APIs to mdsal bindings
[bgpcep.git] / bgp / bmp-impl / src / main / java / org / opendaylight / protocol / bmp / impl / app / BmpRouterPeerImpl.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.protocol.bmp.impl.app;
10
11 import static org.opendaylight.protocol.bmp.impl.app.TablesUtil.BMP_TABLES_QNAME;
12
13 import com.google.common.base.Preconditions;
14 import com.google.common.collect.Sets;
15 import java.util.Set;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
18 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
19 import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTree;
20 import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeNode;
21 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
22 import org.opendaylight.protocol.bmp.impl.spi.BmpRouterPeer;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Timestamp;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.BgpParameters;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.bgp.parameters.OptionalCapabilities;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.bgp.parameters.optional.capabilities.CParameters;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.CParameters1;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.mp.capabilities.MultiprotocolCapability;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.AdjRibInType;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.Mirror;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.MirrorInformationCode;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.PeerDownNotification;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.PeerUp;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.PeerUpNotification;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.RouteMirroringMessage;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.RouteMonitoringMessage;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.Stat;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.StatsReportsMessage;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.header.PeerHeader;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.up.ReceivedOpen;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.up.SentOpen;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.stat.Tlvs;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.BmpMonitor;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.bmp.monitor.Monitor;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.peers.Peer;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.peers.peer.Mirrors;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.peers.peer.PeerSession;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.peers.peer.PostPolicyRib;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.peers.peer.PrePolicyRib;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.peers.peer.Stats;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.routers.Router;
57 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
58 import org.opendaylight.yangtools.yang.binding.Notification;
59 import org.opendaylight.yangtools.yang.common.QName;
60 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
61 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
62 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
63 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
64 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
65 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
66 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
67 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
68
69
70 public final class BmpRouterPeerImpl implements BmpRouterPeer {
71
72     private static final String TIMESTAMP_SEC = "timestamp-sec";
73
74     private static final QName PEER_ID_QNAME = QName.create(Peer.QNAME, "peer-id").intern();
75     private static final QName PEER_TYPE_QNAME = QName.create(Peer.QNAME, "type");
76     private static final QName PEER_ADDRESS_QNAME = QName.create(Peer.QNAME, "address").intern();
77     private static final QName PEER_AS_QNAME = QName.create(Peer.QNAME, "as").intern();
78     private static final QName PEER_BGP_ID_QNAME = QName.create(Peer.QNAME, "bgp-id").intern();
79     private static final QName PEER_DISTINGUISHER_QNAME = QName.create(Peer.QNAME, "router-distinguisher").intern();
80     private static final QName PEER_LOCAL_ADDRESS_QNAME = QName.create(PeerSession.QNAME, "local-address").intern();
81     private static final QName PEER_LOCAL_PORT_QNAME = QName.create(PeerSession.QNAME, "local-port").intern();
82     private static final QName PEER_REMOTE_PORT_QNAME = QName.create(PeerSession.QNAME, "remote-port").intern();
83     private static final QName PEER_STATUS_QNAME = QName.create(PeerSession.QNAME, "status").intern();
84     private static final QName PEER_UP_TIMESTAMP_QNAME = QName.create(PeerSession.QNAME, TIMESTAMP_SEC).intern();
85     private static final QName PEER_STATS_TIMESTAMP_QNAME = QName.create(Stats.QNAME, TIMESTAMP_SEC).intern();
86     private static final QName PEER_MIRROR_INFORMATION_QNAME = QName.create(Mirrors.QNAME, "information").intern();
87     private static final QName PEER_MIRROR_TIMESTAMP_QNAME = QName.create(Mirrors.QNAME, TIMESTAMP_SEC).intern();
88
89     private static final QName STAT0_QNAME = QName.create(Stats.QNAME, "rejected-prefixes").intern();
90     private static final QName STAT1_QNAME = QName.create(Stats.QNAME, "duplicate-prefix-advertisements").intern();
91     private static final QName STAT2_QNAME = QName.create(Stats.QNAME, "duplicate-withdraws").intern();
92     private static final QName STAT3_QNAME = QName.create(Stats.QNAME, "invalidated-cluster-list-loop").intern();
93     private static final QName STAT4_QNAME = QName.create(Stats.QNAME, "invalidated-as-path-loop").intern();
94     private static final QName STAT5_QNAME = QName.create(Stats.QNAME, "invalidated-originator-id").intern();
95     private static final QName STAT6_QNAME = QName.create(Stats.QNAME, "invalidated-as-confed-loop").intern();
96     private static final QName STAT7_QNAME = QName.create(Stats.QNAME, "adj-ribs-in-routes");
97     private static final QName STAT8_QNAME = QName.create(Stats.QNAME, "loc-rib-routes");
98     private static final QName STAT9_QNAME = QName.create(Stats.QNAME, "per-afi-safi-adj-rib-in-routes").intern();
99     private static final QName AF_QNAME = QName.create(Stats.QNAME, "afi-safi").intern();
100     private static final QName COUNT_QNAME = QName.create(Stats.QNAME, "count").intern();
101     private static final QName STAT10_QNAME = QName.create(Stats.QNAME, "per-afi-safi-loc-rib-routes").intern();
102     private static final QName STAT11_QNAME = QName.create(Stats.QNAME, "updates-treated-as-withdraw").intern();
103     private static final QName STAT13_QNAME = QName.create(Stats.QNAME, "duplicate-updates").intern();
104
105     private static final TablesKey DEFAULT_TABLE = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
106
107     private static final InstanceIdentifier<PeerSession> PEER_SESSION_ID = InstanceIdentifier.builder(BmpMonitor.class)
108             .child(Monitor.class)
109             .child(Router.class)
110             .child(Peer.class)
111             .child(PeerSession.class).build();
112
113     private static final InstanceIdentifier<SentOpen> SENT_OPEN_IID = PEER_SESSION_ID.child(SentOpen.class);
114
115     private static final InstanceIdentifier<ReceivedOpen> RECEIVED_OPEN_IID = PEER_SESSION_ID.child(ReceivedOpen.class);
116
117     private final DOMTransactionChain domTxChain;
118     private final PeerId peerId;
119     private final YangInstanceIdentifier peerYangIId;
120     private final BmpRibInWriter prePolicyWriter;
121     private final BmpRibInWriter postPolicyWriter;
122     private final BindingCodecTreeNode<SentOpen> sentOpenCodec;
123     private final BindingCodecTreeNode<ReceivedOpen> receivedOpenCodec;
124     private boolean up = true;
125
126     private BmpRouterPeerImpl(final DOMTransactionChain domTxChain, final YangInstanceIdentifier peersYangIId, final PeerId peerId,
127             final RIBExtensionConsumerContext extensions, final PeerUpNotification peerUp,
128             final BindingCodecTree tree) {
129         this.domTxChain = Preconditions.checkNotNull(domTxChain);
130         this.peerId = peerId;
131         this.peerYangIId = YangInstanceIdentifier.builder(peersYangIId).nodeWithKey(Peer.QNAME, PEER_ID_QNAME, this.peerId.getValue()).build();
132         this.sentOpenCodec = tree.getSubtreeCodec(SENT_OPEN_IID);
133         this.receivedOpenCodec = tree.getSubtreeCodec(RECEIVED_OPEN_IID);
134
135         final Set<TablesKey> peerTables = setPeerTables(peerUp.getReceivedOpen());
136         final DOMDataWriteTransaction wTx = this.domTxChain.newWriteOnlyTransaction();
137         wTx.put(LogicalDatastoreType.OPERATIONAL, this.peerYangIId, createPeerEntry(peerUp));
138         wTx.submit();
139         this.prePolicyWriter = BmpRibInWriter.create(this.peerYangIId.node(PrePolicyRib.QNAME).node(BMP_TABLES_QNAME),
140                 this.domTxChain, extensions, peerTables, tree);
141         this.postPolicyWriter = BmpRibInWriter.create(this.peerYangIId.node(PostPolicyRib.QNAME).node(BMP_TABLES_QNAME),
142                 this.domTxChain, extensions, peerTables, tree);
143     }
144
145     public static BmpRouterPeer createRouterPeer(final DOMTransactionChain domTxChain,
146             final YangInstanceIdentifier peersYangIId, final PeerUpNotification peerUp,
147             final RIBExtensionConsumerContext extensions, final BindingCodecTree tree, final PeerId peerId) {
148         return new BmpRouterPeerImpl(domTxChain, peersYangIId, peerId, extensions,
149                 peerUp, tree);
150     }
151
152     @Override
153     public void onPeerMessage(final Notification message) {
154         if (message instanceof PeerDownNotification) {
155             onPeerDown();
156         } else if (message instanceof RouteMonitoringMessage) {
157             onRouteMonitoring((RouteMonitoringMessage) message);
158         } else if (message instanceof StatsReportsMessage) {
159             onStatsReports((StatsReportsMessage) message);
160         } else if (message instanceof RouteMirroringMessage) {
161             onRouteMirror((RouteMirroringMessage) message);
162         }
163     }
164
165     private void onRouteMonitoring(final RouteMonitoringMessage routeMonitoring) {
166         if (this.up) {
167             final AdjRibInType ribType = routeMonitoring.getPeerHeader().getAdjRibInType();
168             switch (ribType) {
169                 case PrePolicy:
170                     this.prePolicyWriter.onMessage(routeMonitoring.getUpdate());
171                     break;
172                 case PostPolicy:
173                     this.postPolicyWriter.onMessage(routeMonitoring.getUpdate());
174                     break;
175                 default:
176                     break;
177             }
178         }
179     }
180
181     private void onStatsReports(final StatsReportsMessage statsReports) {
182         if (this.up) {
183             final DOMDataWriteTransaction wTx = this.domTxChain.newWriteOnlyTransaction();
184             wTx.merge(LogicalDatastoreType.OPERATIONAL, this.peerYangIId.node(Stats.QNAME),
185                     createStats(statsReports, statsReports.getPeerHeader().getTimestampSec()));
186             wTx.submit();
187         }
188     }
189
190     private void onRouteMirror(final RouteMirroringMessage mirror) {
191         final DOMDataWriteTransaction wTx = this.domTxChain.newWriteOnlyTransaction();
192         wTx.merge(LogicalDatastoreType.OPERATIONAL, this.peerYangIId.node(Mirrors.QNAME),
193                 createMirrors(mirror, mirror.getPeerHeader().getTimestampSec()));
194         wTx.submit();
195     }
196
197
198     private void onPeerDown() {
199         final DOMDataWriteTransaction wTx = this.domTxChain.newWriteOnlyTransaction();
200         wTx.delete(LogicalDatastoreType.OPERATIONAL, this.peerYangIId);
201         wTx.submit();
202         close();
203     }
204
205     @Override
206     public PeerId getPeerId() {
207         return this.peerId;
208     }
209
210     @Override
211     public void close() {
212         Preconditions.checkState(this.up, "Already closed.");
213         this.up = false;
214     }
215
216     private Set<TablesKey> setPeerTables(final ReceivedOpen open) {
217         final Set<TablesKey> tables = Sets.newHashSet(DEFAULT_TABLE);
218         for (final BgpParameters param : open.getBgpParameters()) {
219             for (final OptionalCapabilities optCapa : param.getOptionalCapabilities()) {
220                 final CParameters cParam = optCapa.getCParameters();
221                 if ( cParam.getAugmentation(CParameters1.class) == null ||
222                         cParam.getAugmentation(CParameters1.class).getMultiprotocolCapability() == null ) {
223                     continue;
224                 }
225                 final MultiprotocolCapability multi = cParam.getAugmentation(CParameters1.class).getMultiprotocolCapability();
226                 final TablesKey tt = new TablesKey(multi.getAfi(), multi.getSafi());
227                 tables.add(tt);
228             }
229         }
230         return tables;
231     }
232
233     private ContainerNode createPeerSessionUp(final PeerUp peerUp,
234             final Timestamp timestamp) {
235         final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builder = Builders
236                 .containerBuilder()
237                 .withNodeIdentifier(new NodeIdentifier(PeerSession.QNAME))
238                 .withChild(
239                         ImmutableNodes.leafNode(PEER_LOCAL_ADDRESS_QNAME,
240                                 getStringIpAddress(peerUp.getLocalAddress())))
241                                 .withChild(
242                                         ImmutableNodes.leafNode(PEER_LOCAL_PORT_QNAME, peerUp
243                                                 .getLocalPort().getValue()))
244                                                 .withChild(
245                                                         ImmutableNodes.leafNode(PEER_REMOTE_PORT_QNAME, peerUp
246                                                                 .getRemotePort().getValue()))
247                                                                 .withChild(ImmutableNodes.leafNode(PEER_STATUS_QNAME, "up"))
248                                                                 .withChild(
249                                                                         ImmutableNodes.leafNode(PEER_UP_TIMESTAMP_QNAME,
250                                                                                 timestamp.getValue()));
251         if (this.receivedOpenCodec != null) {
252             builder.withChild((ContainerNode) this.receivedOpenCodec.serialize(peerUp.getReceivedOpen()));
253         }
254         if (this.sentOpenCodec != null) {
255             builder.withChild((ContainerNode) this.sentOpenCodec.serialize(peerUp.getSentOpen()));
256         }
257         return builder.build();
258     }
259
260     private MapEntryNode createPeerEntry(final PeerUpNotification peerUp) {
261         final PeerHeader peerHeader = peerUp.getPeerHeader();
262         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder = Builders.mapEntryBuilder()
263                 .withNodeIdentifier(new NodeIdentifierWithPredicates(Peer.QNAME, PEER_ID_QNAME, this.peerId.getValue()))
264                 .withChild(ImmutableNodes.leafNode(PEER_ID_QNAME, this.peerId.getValue()))
265                 .withChild(ImmutableNodes.leafNode(PEER_TYPE_QNAME, peerHeader.getType().name().toLowerCase()))
266                 .withChild(ImmutableNodes.leafNode(PEER_ADDRESS_QNAME, getStringIpAddress(peerHeader.getAddress())))
267                 .withChild(ImmutableNodes.leafNode(PEER_AS_QNAME, peerHeader.getAs().getValue()))
268                 .withChild(ImmutableNodes.leafNode(PEER_BGP_ID_QNAME, peerHeader.getBgpId().getValue()))
269                 .withChild(createPeerSessionUp(peerUp, peerHeader.getTimestampSec()))
270                 .withChild(
271                         Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(PrePolicyRib.QNAME))
272                         .withChild(ImmutableNodes.mapNodeBuilder(BMP_TABLES_QNAME).build()).build())
273                         .withChild(
274                                 Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(PostPolicyRib.QNAME))
275                                 .withChild(ImmutableNodes.mapNodeBuilder(BMP_TABLES_QNAME).build()).build());
276         if (peerHeader.getDistinguisher() != null) {
277             mapEntryBuilder.withChild(ImmutableNodes.leafNode(PEER_DISTINGUISHER_QNAME, peerHeader.getDistinguisher().getDistinguisher()));
278         }
279         return mapEntryBuilder.build();
280     }
281
282     private ContainerNode createStats(final Stat stat, final Timestamp timestamp) {
283         final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builder =
284                 Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(Stats.QNAME));
285         builder.withChild(ImmutableNodes.leafNode(PEER_STATS_TIMESTAMP_QNAME, timestamp.getValue()));
286         final Tlvs tlvs = stat.getTlvs();
287         if (tlvs != null) {
288             statsForTlvs(tlvs, builder);
289         }
290         return builder.build();
291     }
292
293     private static void statsForTlvs(final Tlvs tlvs, final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builder) {
294         if (tlvs.getRejectedPrefixesTlv() != null) {
295             builder.withChild(ImmutableNodes.leafNode(STAT0_QNAME, tlvs.getRejectedPrefixesTlv().getCount().getValue()));
296         }
297         if (tlvs.getDuplicatePrefixAdvertisementsTlv() != null) {
298             builder.withChild(ImmutableNodes.leafNode(STAT1_QNAME, tlvs.getDuplicatePrefixAdvertisementsTlv().getCount().getValue()));
299         }
300         if (tlvs.getDuplicateWithdrawsTlv() != null) {
301             builder.withChild(ImmutableNodes.leafNode(STAT2_QNAME, tlvs.getDuplicateWithdrawsTlv().getCount().getValue()));
302         }
303         if (tlvs.getInvalidatedClusterListLoopTlv() != null) {
304             builder.withChild(ImmutableNodes.leafNode(STAT3_QNAME, tlvs.getInvalidatedClusterListLoopTlv().getCount().getValue()));
305         }
306         if (tlvs.getInvalidatedAsPathLoopTlv() != null) {
307             builder.withChild(ImmutableNodes.leafNode(STAT4_QNAME, tlvs.getInvalidatedAsPathLoopTlv().getCount().getValue()));
308         }
309         if (tlvs.getInvalidatedOriginatorIdTlv() != null) {
310             builder.withChild(ImmutableNodes.leafNode(STAT5_QNAME, tlvs.getInvalidatedOriginatorIdTlv().getCount().getValue()));
311         }
312         if (tlvs.getInvalidatedAsConfedLoopTlv() != null) {
313             builder.withChild(ImmutableNodes.leafNode(STAT6_QNAME, tlvs.getInvalidatedAsConfedLoopTlv().getCount().getValue()));
314         }
315         if (tlvs.getAdjRibsInRoutesTlv() != null) {
316             builder.withChild(ImmutableNodes.leafNode(STAT7_QNAME, tlvs.getAdjRibsInRoutesTlv().getCount().getValue()));
317         }
318         if (tlvs.getLocRibRoutesTlv() != null) {
319             builder.withChild(ImmutableNodes.leafNode(STAT8_QNAME, tlvs.getLocRibRoutesTlv().getCount().getValue()));
320         }
321         if (tlvs.getPerAfiSafiAdjRibInTlv() != null) {
322             builder.withChild(Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(STAT9_QNAME))
323                     .withChild(ImmutableNodes.mapNodeBuilder(AF_QNAME)
324                             .withChild(Builders.mapEntryBuilder()
325                                     .withChild(ImmutableNodes.leafNode(COUNT_QNAME, tlvs.getPerAfiSafiAdjRibInTlv().getCount().getValue()))
326                                     .withNodeIdentifier(TablesUtil.toYangTablesKey(AF_QNAME, Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class))
327                                     .build()).build()).build());
328         }
329         if (tlvs.getPerAfiSafiLocRibTlv() != null) {
330             builder.withChild(Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(STAT10_QNAME))
331                     .withChild(ImmutableNodes.mapNodeBuilder(AF_QNAME)
332                             .withChild(Builders.mapEntryBuilder()
333                                     .withChild(ImmutableNodes.leafNode(COUNT_QNAME, tlvs.getPerAfiSafiLocRibTlv().getCount().getValue()))
334                                     .withNodeIdentifier(TablesUtil.toYangTablesKey(AF_QNAME, Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class))
335                                     .build()).build()).build());
336         }
337         if (tlvs.getUpdatesTreatedAsWithdrawTlv() != null) {
338             builder.withChild(ImmutableNodes.leafNode(STAT11_QNAME, tlvs.getUpdatesTreatedAsWithdrawTlv().getCount().getValue()));
339         }
340         if (tlvs.getPrefixesTreatedAsWithdrawTlv() != null) {
341             builder.withChild(ImmutableNodes.leafNode(STAT11_QNAME, tlvs.getPrefixesTreatedAsWithdrawTlv().getCount().getValue()));
342         }
343         if (tlvs.getDuplicateUpdatesTlv() != null) {
344             builder.withChild(ImmutableNodes.leafNode(STAT13_QNAME, tlvs.getDuplicateUpdatesTlv().getCount().getValue()));
345         }
346     }
347
348     private ContainerNode createMirrors(final Mirror mirror, final Timestamp timestamp) {
349         final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builder =
350                 Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(Mirrors.QNAME));
351         builder.withChild(ImmutableNodes.leafNode(PEER_MIRROR_INFORMATION_QNAME, toDom(MirrorInformationCode.forValue(
352                 mirror.getTlvs().getMirrorInformationTlv().getCode().getIntValue()))));
353         builder.withChild(ImmutableNodes.leafNode(PEER_MIRROR_TIMESTAMP_QNAME, timestamp.getValue()));
354         return builder.build();
355     }
356
357     private static String toDom(final MirrorInformationCode informationCode) {
358         switch (informationCode) {
359             case ErroredPdu:
360                 return "errored-pdu";
361             case MessageLost:
362                 return "message-lost";
363             default:
364                 return null;
365         }
366     }
367
368
369     private static String getStringIpAddress(final IpAddress ipAddress) {
370         if (ipAddress.getIpv4Address() != null) {
371             return ipAddress.getIpv4Address().getValue();
372         }
373         return ipAddress.getIpv6Address().getValue();
374     }
375
376 }