2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.protocol.bmp.impl.app;
11 import static java.util.Objects.requireNonNull;
12 import static org.opendaylight.protocol.bmp.impl.app.TablesUtil.BMP_TABLES_QNAME;
14 import com.google.common.base.Preconditions;
15 import com.google.common.collect.Sets;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
19 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
20 import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTree;
21 import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTreeNode;
22 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
23 import org.opendaylight.protocol.bmp.impl.spi.BmpRouterPeer;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Timestamp;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.BgpParameters;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.bgp.parameters.OptionalCapabilities;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.bgp.parameters.optional.capabilities.CParameters;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.CParameters1;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.mp.capabilities.MultiprotocolCapability;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.AdjRibInType;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.Mirror;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.MirrorInformationCode;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.Peer.PeerDistinguisher;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.PeerDownNotification;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.PeerUp;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.PeerUpNotification;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.RouteMirroringMessage;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.RouteMonitoringMessage;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.Stat;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.StatsReportsMessage;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.header.PeerHeader;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.up.ReceivedOpen;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.up.SentOpen;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.stat.Tlvs;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.BmpMonitor;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.bmp.monitor.Monitor;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.peers.Peer;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.peers.peer.Mirrors;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.peers.peer.PeerSession;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.peers.peer.PostPolicyRib;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.peers.peer.PrePolicyRib;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.peers.peer.Stats;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev150512.routers.Router;
59 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
60 import org.opendaylight.yangtools.yang.binding.Notification;
61 import org.opendaylight.yangtools.yang.common.QName;
62 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
63 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
64 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
65 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
66 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
67 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
68 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
69 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
72 public final class BmpRouterPeerImpl implements BmpRouterPeer {
74 private static final String TIMESTAMP_SEC = "timestamp-sec";
76 private static final QName PEER_ID_QNAME = QName.create(Peer.QNAME, "peer-id").intern();
77 private static final QName PEER_TYPE_QNAME = QName.create(Peer.QNAME, "type");
78 private static final QName PEER_ADDRESS_QNAME = QName.create(Peer.QNAME, "address").intern();
79 private static final QName PEER_AS_QNAME = QName.create(Peer.QNAME, "as").intern();
80 private static final QName PEER_BGP_ID_QNAME = QName.create(Peer.QNAME, "bgp-id").intern();
81 private static final QName PEER_DISTINGUISHER_QNAME = QName.create(Peer.QNAME, "router-distinguisher").intern();
82 private static final QName PEER_LOCAL_ADDRESS_QNAME = QName.create(PeerSession.QNAME, "local-address").intern();
83 private static final QName PEER_LOCAL_PORT_QNAME = QName.create(PeerSession.QNAME, "local-port").intern();
84 private static final QName PEER_REMOTE_PORT_QNAME = QName.create(PeerSession.QNAME, "remote-port").intern();
85 private static final QName PEER_STATUS_QNAME = QName.create(PeerSession.QNAME, "status").intern();
86 private static final QName PEER_UP_TIMESTAMP_QNAME = QName.create(PeerSession.QNAME, TIMESTAMP_SEC).intern();
87 private static final QName PEER_STATS_TIMESTAMP_QNAME = QName.create(Stats.QNAME, TIMESTAMP_SEC).intern();
88 private static final QName PEER_MIRROR_INFORMATION_QNAME = QName.create(Mirrors.QNAME, "information").intern();
89 private static final QName PEER_MIRROR_TIMESTAMP_QNAME = QName.create(Mirrors.QNAME, TIMESTAMP_SEC).intern();
91 private static final QName STAT0_QNAME = QName.create(Stats.QNAME, "rejected-prefixes").intern();
92 private static final QName STAT1_QNAME = QName.create(Stats.QNAME, "duplicate-prefix-advertisements").intern();
93 private static final QName STAT2_QNAME = QName.create(Stats.QNAME, "duplicate-withdraws").intern();
94 private static final QName STAT3_QNAME = QName.create(Stats.QNAME, "invalidated-cluster-list-loop").intern();
95 private static final QName STAT4_QNAME = QName.create(Stats.QNAME, "invalidated-as-path-loop").intern();
96 private static final QName STAT5_QNAME = QName.create(Stats.QNAME, "invalidated-originator-id").intern();
97 private static final QName STAT6_QNAME = QName.create(Stats.QNAME, "invalidated-as-confed-loop").intern();
98 private static final QName STAT7_QNAME = QName.create(Stats.QNAME, "adj-ribs-in-routes");
99 private static final QName STAT8_QNAME = QName.create(Stats.QNAME, "loc-rib-routes");
100 private static final QName STAT9_QNAME = QName.create(Stats.QNAME, "per-afi-safi-adj-rib-in-routes").intern();
101 private static final QName AF_QNAME = QName.create(Stats.QNAME, "afi-safi").intern();
102 private static final QName COUNT_QNAME = QName.create(Stats.QNAME, "count").intern();
103 private static final QName STAT10_QNAME = QName.create(Stats.QNAME, "per-afi-safi-loc-rib-routes").intern();
104 private static final QName STAT11_QNAME = QName.create(Stats.QNAME, "updates-treated-as-withdraw").intern();
105 private static final QName STAT13_QNAME = QName.create(Stats.QNAME, "duplicate-updates").intern();
107 private static final TablesKey DEFAULT_TABLE = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
109 private static final InstanceIdentifier<PeerSession> PEER_SESSION_ID = InstanceIdentifier.builder(BmpMonitor.class)
110 .child(Monitor.class)
113 .child(PeerSession.class).build();
115 private static final InstanceIdentifier<SentOpen> SENT_OPEN_IID = PEER_SESSION_ID.child(SentOpen.class);
117 private static final InstanceIdentifier<ReceivedOpen> RECEIVED_OPEN_IID = PEER_SESSION_ID.child(ReceivedOpen.class);
119 private final DOMTransactionChain domTxChain;
120 private final PeerId peerId;
121 private final YangInstanceIdentifier peerYangIId;
122 private final BmpRibInWriter prePolicyWriter;
123 private final BmpRibInWriter postPolicyWriter;
124 private final BindingCodecTreeNode<SentOpen> sentOpenCodec;
125 private final BindingCodecTreeNode<ReceivedOpen> receivedOpenCodec;
126 private boolean up = true;
128 private BmpRouterPeerImpl(final DOMTransactionChain domTxChain, final YangInstanceIdentifier peersYangIId,
129 final PeerId peerId, final RIBExtensionConsumerContext extensions, final PeerUpNotification peerUp,
130 final BindingCodecTree tree) {
131 this.domTxChain = requireNonNull(domTxChain);
132 this.peerId = peerId;
133 this.peerYangIId = YangInstanceIdentifier.builder(peersYangIId).nodeWithKey(Peer.QNAME, PEER_ID_QNAME, this.peerId.getValue()).build();
134 this.sentOpenCodec = tree.getSubtreeCodec(SENT_OPEN_IID);
135 this.receivedOpenCodec = tree.getSubtreeCodec(RECEIVED_OPEN_IID);
137 final Set<TablesKey> peerTables = setPeerTables(peerUp.getReceivedOpen());
138 final DOMDataWriteTransaction wTx = this.domTxChain.newWriteOnlyTransaction();
139 wTx.put(LogicalDatastoreType.OPERATIONAL, this.peerYangIId, createPeerEntry(peerUp));
141 this.prePolicyWriter = BmpRibInWriter.create(this.peerYangIId.node(PrePolicyRib.QNAME).node(BMP_TABLES_QNAME),
142 this.domTxChain, extensions, peerTables, tree);
143 this.postPolicyWriter = BmpRibInWriter.create(this.peerYangIId.node(PostPolicyRib.QNAME).node(BMP_TABLES_QNAME),
144 this.domTxChain, extensions, peerTables, tree);
147 public static BmpRouterPeer createRouterPeer(final DOMTransactionChain domTxChain,
148 final YangInstanceIdentifier peersYangIId, final PeerUpNotification peerUp,
149 final RIBExtensionConsumerContext extensions, final BindingCodecTree tree, final PeerId peerId) {
150 return new BmpRouterPeerImpl(domTxChain, peersYangIId, peerId, extensions,
155 public void onPeerMessage(final Notification message) {
156 if (message instanceof PeerDownNotification) {
158 } else if (message instanceof RouteMonitoringMessage) {
159 onRouteMonitoring((RouteMonitoringMessage) message);
160 } else if (message instanceof StatsReportsMessage) {
161 onStatsReports((StatsReportsMessage) message);
162 } else if (message instanceof RouteMirroringMessage) {
163 onRouteMirror((RouteMirroringMessage) message);
167 private void onRouteMonitoring(final RouteMonitoringMessage routeMonitoring) {
169 final AdjRibInType ribType = routeMonitoring.getPeerHeader().getAdjRibInType();
172 this.prePolicyWriter.onMessage(routeMonitoring.getUpdate());
175 this.postPolicyWriter.onMessage(routeMonitoring.getUpdate());
183 private synchronized void onStatsReports(final StatsReportsMessage statsReports) {
185 final DOMDataWriteTransaction wTx = this.domTxChain.newWriteOnlyTransaction();
186 wTx.merge(LogicalDatastoreType.OPERATIONAL, this.peerYangIId.node(Stats.QNAME),
187 createStats(statsReports, statsReports.getPeerHeader().getTimestampSec()));
192 private synchronized void onRouteMirror(final RouteMirroringMessage mirror) {
193 final DOMDataWriteTransaction wTx = this.domTxChain.newWriteOnlyTransaction();
194 wTx.merge(LogicalDatastoreType.OPERATIONAL, this.peerYangIId.node(Mirrors.QNAME),
195 createMirrors(mirror, mirror.getPeerHeader().getTimestampSec()));
200 private synchronized void onPeerDown() {
201 final DOMDataWriteTransaction wTx = this.domTxChain.newWriteOnlyTransaction();
202 wTx.delete(LogicalDatastoreType.OPERATIONAL, this.peerYangIId);
208 public void close() {
209 Preconditions.checkState(this.up, "Already closed.");
213 private static Set<TablesKey> setPeerTables(final ReceivedOpen open) {
214 final Set<TablesKey> tables = Sets.newHashSet(DEFAULT_TABLE);
215 for (final BgpParameters param : open.getBgpParameters()) {
216 for (final OptionalCapabilities optCapa : param.getOptionalCapabilities()) {
217 final CParameters cParam = optCapa.getCParameters();
218 if ( cParam.getAugmentation(CParameters1.class) == null ||
219 cParam.getAugmentation(CParameters1.class).getMultiprotocolCapability() == null ) {
222 final MultiprotocolCapability multi = cParam.getAugmentation(CParameters1.class).getMultiprotocolCapability();
223 final TablesKey tt = new TablesKey(multi.getAfi(), multi.getSafi());
230 private ContainerNode createPeerSessionUp(final PeerUp peerUp,
231 final Timestamp timestamp) {
232 final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builder = Builders
234 .withNodeIdentifier(new NodeIdentifier(PeerSession.QNAME))
236 ImmutableNodes.leafNode(PEER_LOCAL_ADDRESS_QNAME,
237 getStringIpAddress(peerUp.getLocalAddress())))
239 ImmutableNodes.leafNode(PEER_LOCAL_PORT_QNAME, peerUp
240 .getLocalPort().getValue()))
242 ImmutableNodes.leafNode(PEER_REMOTE_PORT_QNAME, peerUp
243 .getRemotePort().getValue()))
244 .withChild(ImmutableNodes.leafNode(PEER_STATUS_QNAME, "up"))
246 ImmutableNodes.leafNode(PEER_UP_TIMESTAMP_QNAME,
247 timestamp.getValue()));
248 if (this.receivedOpenCodec != null) {
249 builder.withChild((ContainerNode) this.receivedOpenCodec.serialize(peerUp.getReceivedOpen()));
251 if (this.sentOpenCodec != null) {
252 builder.withChild((ContainerNode) this.sentOpenCodec.serialize(peerUp.getSentOpen()));
254 return builder.build();
257 private MapEntryNode createPeerEntry(final PeerUpNotification peerUp) {
258 final PeerHeader peerHeader = peerUp.getPeerHeader();
259 final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> mapEntryBuilder = Builders.mapEntryBuilder()
260 .withNodeIdentifier(new NodeIdentifierWithPredicates(Peer.QNAME, PEER_ID_QNAME, this.peerId.getValue()))
261 .withChild(ImmutableNodes.leafNode(PEER_ID_QNAME, this.peerId.getValue()))
262 .withChild(ImmutableNodes.leafNode(PEER_TYPE_QNAME, peerHeader.getType().name().toLowerCase()))
263 .withChild(ImmutableNodes.leafNode(PEER_ADDRESS_QNAME, getStringIpAddress(peerHeader.getAddress())))
264 .withChild(ImmutableNodes.leafNode(PEER_AS_QNAME, peerHeader.getAs().getValue()))
265 .withChild(ImmutableNodes.leafNode(PEER_BGP_ID_QNAME, peerHeader.getBgpId().getValue()))
266 .withChild(createPeerSessionUp(peerUp, peerHeader.getTimestampSec()))
268 Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(PrePolicyRib.QNAME))
269 .withChild(ImmutableNodes.mapNodeBuilder(BMP_TABLES_QNAME).build()).build())
271 Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(PostPolicyRib.QNAME))
272 .withChild(ImmutableNodes.mapNodeBuilder(BMP_TABLES_QNAME).build()).build());
273 final PeerDistinguisher pd = peerHeader.getPeerDistinguisher();
275 mapEntryBuilder.withChild(ImmutableNodes.leafNode(PEER_DISTINGUISHER_QNAME, pd.getRouteDistinguisher()));
277 return mapEntryBuilder.build();
280 private static ContainerNode createStats(final Stat stat, final Timestamp timestamp) {
281 final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builder =
282 Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(Stats.QNAME));
283 builder.withChild(ImmutableNodes.leafNode(PEER_STATS_TIMESTAMP_QNAME, timestamp.getValue()));
284 final Tlvs tlvs = stat.getTlvs();
286 statsForTlvs(tlvs, builder);
288 return builder.build();
291 private static void statsForTlvs(final Tlvs tlvs, final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builder) {
292 if (tlvs.getRejectedPrefixesTlv() != null) {
293 builder.withChild(ImmutableNodes.leafNode(STAT0_QNAME, tlvs.getRejectedPrefixesTlv().getCount().getValue()));
295 if (tlvs.getDuplicatePrefixAdvertisementsTlv() != null) {
296 builder.withChild(ImmutableNodes.leafNode(STAT1_QNAME, tlvs.getDuplicatePrefixAdvertisementsTlv().getCount().getValue()));
298 if (tlvs.getDuplicateWithdrawsTlv() != null) {
299 builder.withChild(ImmutableNodes.leafNode(STAT2_QNAME, tlvs.getDuplicateWithdrawsTlv().getCount().getValue()));
301 if (tlvs.getInvalidatedClusterListLoopTlv() != null) {
302 builder.withChild(ImmutableNodes.leafNode(STAT3_QNAME, tlvs.getInvalidatedClusterListLoopTlv().getCount().getValue()));
304 if (tlvs.getInvalidatedAsPathLoopTlv() != null) {
305 builder.withChild(ImmutableNodes.leafNode(STAT4_QNAME, tlvs.getInvalidatedAsPathLoopTlv().getCount().getValue()));
307 if (tlvs.getInvalidatedOriginatorIdTlv() != null) {
308 builder.withChild(ImmutableNodes.leafNode(STAT5_QNAME, tlvs.getInvalidatedOriginatorIdTlv().getCount().getValue()));
310 if (tlvs.getInvalidatedAsConfedLoopTlv() != null) {
311 builder.withChild(ImmutableNodes.leafNode(STAT6_QNAME, tlvs.getInvalidatedAsConfedLoopTlv().getCount().getValue()));
313 if (tlvs.getAdjRibsInRoutesTlv() != null) {
314 builder.withChild(ImmutableNodes.leafNode(STAT7_QNAME, tlvs.getAdjRibsInRoutesTlv().getCount().getValue()));
316 if (tlvs.getLocRibRoutesTlv() != null) {
317 builder.withChild(ImmutableNodes.leafNode(STAT8_QNAME, tlvs.getLocRibRoutesTlv().getCount().getValue()));
319 if (tlvs.getPerAfiSafiAdjRibInTlv() != null) {
320 builder.withChild(Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(STAT9_QNAME))
321 .withChild(ImmutableNodes.mapNodeBuilder(AF_QNAME)
322 .withChild(Builders.mapEntryBuilder()
323 .withChild(ImmutableNodes.leafNode(COUNT_QNAME, tlvs.getPerAfiSafiAdjRibInTlv().getCount().getValue()))
324 .withNodeIdentifier(TablesUtil.toYangTablesKey(AF_QNAME, Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class))
325 .build()).build()).build());
327 if (tlvs.getPerAfiSafiLocRibTlv() != null) {
328 builder.withChild(Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(STAT10_QNAME))
329 .withChild(ImmutableNodes.mapNodeBuilder(AF_QNAME)
330 .withChild(Builders.mapEntryBuilder()
331 .withChild(ImmutableNodes.leafNode(COUNT_QNAME, tlvs.getPerAfiSafiLocRibTlv().getCount().getValue()))
332 .withNodeIdentifier(TablesUtil.toYangTablesKey(AF_QNAME, Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class))
333 .build()).build()).build());
335 if (tlvs.getUpdatesTreatedAsWithdrawTlv() != null) {
336 builder.withChild(ImmutableNodes.leafNode(STAT11_QNAME, tlvs.getUpdatesTreatedAsWithdrawTlv().getCount().getValue()));
338 if (tlvs.getPrefixesTreatedAsWithdrawTlv() != null) {
339 builder.withChild(ImmutableNodes.leafNode(STAT11_QNAME, tlvs.getPrefixesTreatedAsWithdrawTlv().getCount().getValue()));
341 if (tlvs.getDuplicateUpdatesTlv() != null) {
342 builder.withChild(ImmutableNodes.leafNode(STAT13_QNAME, tlvs.getDuplicateUpdatesTlv().getCount().getValue()));
346 private static ContainerNode createMirrors(final Mirror mirror, final Timestamp timestamp) {
347 final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builder =
348 Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(Mirrors.QNAME));
349 builder.withChild(ImmutableNodes.leafNode(PEER_MIRROR_INFORMATION_QNAME, toDom(MirrorInformationCode.forValue(
350 mirror.getTlvs().getMirrorInformationTlv().getCode().getIntValue()))));
351 builder.withChild(ImmutableNodes.leafNode(PEER_MIRROR_TIMESTAMP_QNAME, timestamp.getValue()));
352 return builder.build();
355 private static String toDom(final MirrorInformationCode informationCode) {
356 switch (informationCode) {
358 return "errored-pdu";
360 return "message-lost";
367 private static String getStringIpAddress(final IpAddress ipAddress) {
368 if (ipAddress.getIpv4Address() != null) {
369 return ipAddress.getIpv4Address().getValue();
371 return ipAddress.getIpv6Address().getValue();