2 * Copyright (c) 2020 Orange. 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
8 package org.opendaylight.bgpcep.bgp.topology.provider;
10 import static java.util.Objects.requireNonNull;
12 import com.google.common.annotations.VisibleForTesting;
13 import com.google.common.base.Preconditions;
14 import java.math.BigDecimal;
15 import java.net.Inet4Address;
16 import java.net.Inet6Address;
17 import java.net.UnknownHostException;
18 import java.nio.ByteBuffer;
19 import java.util.ArrayList;
20 import java.util.List;
21 import org.opendaylight.graph.ConnectedGraph;
22 import org.opendaylight.graph.ConnectedGraphProvider;
23 import org.opendaylight.mdsal.binding.api.DataBroker;
24 import org.opendaylight.mdsal.binding.api.ReadWriteTransaction;
25 import org.opendaylight.protocol.bgp.rib.RibReference;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.LinkstateAddressFamily;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.LinkstateSubsequentAddressFamily;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.bgp.rib.rib.loc.rib.tables.routes.LinkstateRoutesCase;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.ObjectType;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.attribute.SrAdjIds;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.LinkCase;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.NodeCase;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.PrefixCase;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.link._case.LinkDescriptors;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.LinkStateAttribute;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.LinkAttributesCase;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.NodeAttributesCase;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.PrefixAttributesCase;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.link.attributes._case.LinkAttributes;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.node.attributes._case.NodeAttributes;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.prefix.attributes._case.PrefixAttributes;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.LinkstateRoutes;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.linkstate.routes.LinkstateRoute;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.linkstate.routes.linkstate.route.Attributes1;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.node.identifier.CRouterIdentifier;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.node.identifier.c.router.identifier.IsisNodeCase;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.node.identifier.c.router.identifier.OspfNodeCase;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.Attributes;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.Tables;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.adj.flags.flags.isis.adj.flags._case.IsisAdjFlags;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.adj.flags.flags.ospf.adj.flags._case.OspfAdjFlags;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.prefix.sid.tlv.flags.IsisPrefixFlagsCase;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.sid.label.index.sid.label.index.LocalLabelCase;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.sid.label.index.sid.label.index.SidCase;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.DecimalBandwidth;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.Delay;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.Loss;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.Vertex.VertexType;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.EdgeAttributes;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.EdgeAttributesBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.attributes.MinMaxDelay;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.attributes.MinMaxDelayBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.attributes.UnreservedBandwidth;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.attributes.UnreservedBandwidthBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.edge.attributes.UnreservedBandwidthKey;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.Graph.DomainScope;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Edge;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.EdgeBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.EdgeKey;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Prefix;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.PrefixBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.Vertex;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.VertexBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.graph.topology.graph.VertexKey;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev191125.vertex.SrgbBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.Bandwidth;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.odl.bgp.topology.types.rev160524.TopologyTypes1;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.odl.bgp.topology.types.rev160524.TopologyTypes1Builder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.odl.bgp.topology.types.rev160524.bgp.linkstate.topology.type.BgpLinkstateTopologyBuilder;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.SrlgId;
87 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
88 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypes;
89 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypesBuilder;
90 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
91 import org.opendaylight.yangtools.yang.common.Uint32;
92 import org.opendaylight.yangtools.yang.common.Uint64;
93 import org.slf4j.Logger;
94 import org.slf4j.LoggerFactory;
97 * This Class build the Traffic Engineering Database as a Connected Graph
98 * suitable to be used latter by Path Computation algorithms to compute end to
101 * @author Olivier Dugeon
102 * @author Philippe Niger
106 public class LinkstateGraphBuilder extends AbstractTopologyBuilder<LinkstateRoute> {
107 private static final TopologyTypes LINKSTATE_TOPOLOGY_TYPE = new TopologyTypesBuilder().addAugmentation(
108 TopologyTypes1.class,
109 new TopologyTypes1Builder().setBgpLinkstateTopology(new BgpLinkstateTopologyBuilder().build()).build())
112 private static final String UNHANDLED_OBJECT_CLASS = "Unhandled object class {}";
114 private static final Logger LOG = LoggerFactory.getLogger(LinkstateGraphBuilder.class);
116 private ConnectedGraphProvider graphProvider;
117 private ConnectedGraph cgraph;
119 public LinkstateGraphBuilder(final DataBroker dataProvider, final RibReference locRibReference,
120 final TopologyId topologyId, ConnectedGraphProvider provider) {
121 super(dataProvider, locRibReference, topologyId, LINKSTATE_TOPOLOGY_TYPE, LinkstateAddressFamily.class,
122 LinkstateSubsequentAddressFamily.class);
123 this.graphProvider = requireNonNull(provider);
124 this.cgraph = provider.createConnectedGraph("ted://" + topologyId.getValue(),
125 DomainScope.IntraDomain);
126 /* LinkStateGraphBuilder doesn't write information in the Network Topology tree of the Data Store.
127 * This is performed by ConnectedGraphProvider which write element in Graph tree of the Data Store */
128 this.networkTopologyTransaction = false;
129 LOG.info("Started Traffic Engineering Graph Builder");
133 LinkstateGraphBuilder(final DataBroker dataProvider, final RibReference locRibReference,
134 final TopologyId topologyId, ConnectedGraphProvider provider, final long listenerResetLimitInMillsec,
135 final int listenerResetEnforceCounter) {
136 super(dataProvider, locRibReference, topologyId, LINKSTATE_TOPOLOGY_TYPE, LinkstateAddressFamily.class,
137 LinkstateSubsequentAddressFamily.class, listenerResetLimitInMillsec, listenerResetEnforceCounter);
138 this.graphProvider = requireNonNull(provider);
139 this.cgraph = provider.createConnectedGraph("ted://" + topologyId.getValue(),
140 DomainScope.IntraDomain);
141 /* LinkStateGraphBuilder doesn't write information in the Network Topology tree of the Data Store.
142 * This is performed by ConnectedGraphProvider which write element in Graph tree of the Data Store */
143 this.networkTopologyTransaction = false;
144 LOG.info("Started Traffic Engineering Graph Builder");
148 protected void createObject(final ReadWriteTransaction trans, final InstanceIdentifier<LinkstateRoute> id,
149 final LinkstateRoute value) {
150 final ObjectType t = value.getObjectType();
151 Preconditions.checkArgument(t != null, "Route %s value %s has null object type", id, value);
153 if (t instanceof LinkCase) {
154 createEdge(value, (LinkCase) t, value.getAttributes());
155 } else if (t instanceof NodeCase) {
156 createVertex(value, (NodeCase) t, value.getAttributes());
157 } else if (t instanceof PrefixCase) {
158 createPrefix(value, (PrefixCase) t, value.getAttributes());
160 LOG.debug(UNHANDLED_OBJECT_CLASS, t.implementedInterface());
165 * Verify that mandatory information (Local & Remote Node and Link
166 * descriptors) are present in the link.
168 * @param linkCase The Link part of the Linkstate route
170 * @return True if all information are present, false otherwise
172 private boolean checkLinkState(final LinkCase linkCase) {
173 if (linkCase.getLocalNodeDescriptors() == null || linkCase.getRemoteNodeDescriptors() == null) {
174 LOG.warn("Missing Local or Remote Node descriptor in link {}, skipping it", linkCase);
177 if (linkCase.getLinkDescriptors() == null) {
178 LOG.warn("Missing Link descriptor in link {}, skipping it", linkCase);
185 * Get Link attributes from the Link State route.
187 * @param attributes Link State Route Attributes
189 * @return Link Attributes
191 private LinkAttributes getLinkAttributes(final Attributes attributes) {
192 final LinkAttributes la;
193 final Attributes1 attr = attributes.augmentation(Attributes1.class);
195 final LinkStateAttribute attrType = attr.getLinkStateAttribute();
196 if (attrType != null) {
197 la = ((LinkAttributesCase) attrType).getLinkAttributes();
208 * Determine the Source Edge Key from the link descriptor.
209 * There is several case: IPv4, IPv6 address or Unnumbered Interface.
211 * @param linkCase The Link part of the Linkstate route
215 private Uint64 getEdgeId(LinkCase linkCase) {
217 if (linkCase.getLinkDescriptors().getIpv4InterfaceAddress() != null) {
218 key = ipv4ToKey(linkCase.getLinkDescriptors().getIpv4InterfaceAddress().getValue());
220 if (linkCase.getLinkDescriptors().getIpv6InterfaceAddress() != null) {
221 key = ipv6ToKey(linkCase.getLinkDescriptors().getIpv6InterfaceAddress().getValue());
223 if (linkCase.getLinkDescriptors().getLinkLocalIdentifier() != null) {
224 key = linkCase.getLinkDescriptors().getLinkLocalIdentifier().longValue();
226 return Uint64.valueOf(key);
230 * Create new Connected Edge in the Connected Graph.
232 * @param value The complete Linkstate route information
233 * @param linkCase The Link part of the Linkstate route
234 * @param attributes The Link attributes
237 private void createEdge(final LinkstateRoute value, final LinkCase linkCase, final Attributes attributes) {
238 Preconditions.checkArgument(checkLinkState(linkCase), "Missing mandatory information in link {}", linkCase);
240 final LinkAttributes la = getLinkAttributes(attributes);
242 LOG.warn("Missing attributes in link {} route {}, skipping it", linkCase, value);
246 /* Get Source and Destination Vertex from the graph */
247 Uint64 srcId = getVertexId(linkCase.getLocalNodeDescriptors().getCRouterIdentifier());
248 Uint64 dstId = getVertexId(linkCase.getRemoteNodeDescriptors().getCRouterIdentifier());
249 if (srcId == Uint64.ZERO || dstId == Uint64.ZERO) {
250 LOG.warn("Unable to get the Source or Destination Vertex Identifier from link {}, skipping it", linkCase);
254 /* Get Source and Destination Key for the corresponding Edge */
255 Uint64 edgeId = getEdgeId(linkCase);
256 if (edgeId == Uint64.ZERO) {
257 LOG.warn("Unable to get the Edge Identifier from link {}, skipping it", linkCase);
261 /* Add associated Edge */
262 Edge edge = new EdgeBuilder().setEdgeId(edgeId).setLocalVertexId(srcId).setRemoteVertexId(dstId)
263 .setName(srcId + " - " + dstId)
264 .setEdgeAttributes(createEdgeAttributes(la, linkCase.getLinkDescriptors())).build();
267 * Add corresponding Prefix for the Local Address. Remote address will be added with the remote Edge */
268 PrefixBuilder prefBuilder = new PrefixBuilder().setVertexId(srcId);
269 if (edge.getEdgeAttributes().getLocalAddress().getIpv4Address() != null) {
270 prefBuilder.setPrefix(new IpPrefix(
271 new Ipv4Prefix(edge.getEdgeAttributes().getLocalAddress().getIpv4Address().getValue() + "/32")));
273 if (edge.getEdgeAttributes().getLocalAddress().getIpv6Address() != null) {
274 prefBuilder.setPrefix(new IpPrefix(
275 new Ipv6Prefix(edge.getEdgeAttributes().getLocalAddress().getIpv6Address().getValue() + "/128")));
277 Prefix prefix = prefBuilder.build();
279 /* Add the Edge in the Connected Graph */
280 LOG.info("Add Edge {} and associated Prefix {} in TED[{}]", edge.getName(), prefix.getPrefix(), cgraph);
281 cgraph.addEdge(edge);
282 cgraph.addPrefix(prefix);
286 * Create Edge Attributes from Link attributes.
288 * @param la Linkstate Attributes
289 * @param linkDesc Linkstate Descriptors
291 * @return EdgeAttributes
293 private static final int MAX_PRIORITY = 8;
295 private EdgeAttributes createEdgeAttributes(LinkAttributes la, final LinkDescriptors linkDesc) {
296 EdgeAttributesBuilder builder = new EdgeAttributesBuilder();
298 if (linkDesc.getIpv4InterfaceAddress() != null) {
299 builder.setLocalAddress(new IpAddress(new Ipv4Address(linkDesc.getIpv4InterfaceAddress())));
301 if (linkDesc.getIpv6InterfaceAddress() != null) {
302 builder.setLocalAddress(new IpAddress(new Ipv6Address(linkDesc.getIpv6InterfaceAddress())));
304 if (linkDesc.getIpv4NeighborAddress() != null) {
305 builder.setRemoteAddress(new IpAddress(new Ipv4Address(linkDesc.getIpv4NeighborAddress())));
307 if (linkDesc.getIpv6NeighborAddress() != null) {
308 builder.setRemoteAddress(new IpAddress(new Ipv6Address(linkDesc.getIpv6NeighborAddress())));
310 if (linkDesc.getLinkLocalIdentifier() != null) {
311 builder.setLocalIdentifier(linkDesc.getLinkLocalIdentifier());
313 if (linkDesc.getLinkRemoteIdentifier() != null) {
314 builder.setRemoteIdentifier(linkDesc.getLinkRemoteIdentifier());
316 if (la.getMetric() != null) {
317 builder.setMetric(la.getMetric().getValue());
319 if (la.getTeMetric() != null) {
320 builder.setTeMetric(la.getTeMetric().getValue());
322 if (la.getMaxLinkBandwidth() != null) {
323 builder.setMaxLinkBandwidth(bandwithToDecimalBandwidth(la.getMaxLinkBandwidth()));
325 if (la.getMaxReservableBandwidth() != null) {
326 builder.setMaxResvLinkBandwidth(bandwithToDecimalBandwidth(la.getMaxReservableBandwidth()));
328 if (la.getUnreservedBandwidth() != null) {
329 int upperBound = Math.min(la.getUnreservedBandwidth().size(), MAX_PRIORITY);
330 final List<UnreservedBandwidth> unRsvBw = new ArrayList<>(upperBound);
332 for (final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120
333 .UnreservedBandwidth bandwidth : la.getUnreservedBandwidth()) {
334 unRsvBw.add(new UnreservedBandwidthBuilder()
335 .setBandwidth(bandwithToDecimalBandwidth(bandwidth.getBandwidth()))
336 .withKey(new UnreservedBandwidthKey(bandwidth.getPriority())).build());
338 builder.setUnreservedBandwidth(unRsvBw);
340 if (la.getAdminGroup() != null) {
341 builder.setAdminGroup(la.getAdminGroup().getValue());
343 if (la.getLinkDelay() != null) {
344 builder.setDelay(new Delay(la.getLinkDelay().getValue()));
346 if (la.getLinkMinMaxDelay() != null && la.getLinkMinMaxDelay() != null) {
347 MinMaxDelay mmDelay = new MinMaxDelayBuilder()
348 .setMaxDelay(new Delay(la.getLinkMinMaxDelay().getMaxDelay().getValue()))
349 .setMinDelay(new Delay(la.getLinkMinMaxDelay().getMinDelay().getValue())).build();
350 builder.setMinMaxDelay(mmDelay);
352 if (la.getDelayVariation() != null) {
353 builder.setJitter(new Delay(la.getDelayVariation().getValue()));
355 if (la.getLinkLoss() != null) {
356 builder.setLoss(new Loss(la.getLinkLoss().getValue()));
358 if (la.getAvailableBandwidth() != null) {
359 builder.setAvailableBandwidth(bandwithToDecimalBandwidth(la.getAvailableBandwidth()));
361 if (la.getResidualBandwidth() != null) {
362 builder.setResidualBandwidth(bandwithToDecimalBandwidth(la.getResidualBandwidth()));
364 if (la.getUtilizedBandwidth() != null) {
365 builder.setUtilizedBandwidth(bandwithToDecimalBandwidth(la.getUtilizedBandwidth()));
367 if (la.getSharedRiskLinkGroups() != null) {
368 List<Uint32> srlgs = new ArrayList<Uint32>();
369 for (SrlgId srlg : la.getSharedRiskLinkGroups()) {
370 srlgs.add(srlg.getValue());
372 builder.setSrlgs(srlgs);
374 if (la.getSrAdjIds() != null) {
375 for (SrAdjIds adj : la.getSrAdjIds()) {
376 if (adj.getSidLabelIndex() instanceof LocalLabelCase) {
377 boolean backup = false;
378 if (adj.getFlags() instanceof OspfAdjFlags) {
379 backup = ((OspfAdjFlags) adj.getFlags()).isBackup();
381 if (adj.getFlags() instanceof IsisAdjFlags) {
382 backup = ((IsisAdjFlags) adj.getFlags()).isBackup();
385 builder.setAdjSid(((LocalLabelCase) adj.getSidLabelIndex()).getLocalLabel().getValue());
387 builder.setBackupAdjSid(((LocalLabelCase) adj.getSidLabelIndex()).getLocalLabel().getValue());
392 return builder.build();
396 * Get Node Attributes from Link State Route attributes.
398 * @param attributes The attribute part from the Link State route
400 * @return Node Attributes
402 private NodeAttributes getNodeAttributes(final Attributes attributes) {
403 final NodeAttributes na;
404 final Attributes1 attr = attributes.augmentation(Attributes1.class);
406 final LinkStateAttribute attrType = attr.getLinkStateAttribute();
407 if (attrType != null) {
408 na = ((NodeAttributesCase) attrType).getNodeAttributes();
419 * Create Vertex from the Node Attributes.
421 * @param na Node Attributes
422 * @param cvertex Connected Vertex associated to this Vertex
423 * @param as As number
427 private Vertex getVertex(NodeAttributes na, Uint64 id, int as) {
428 VertexBuilder builder = new VertexBuilder().setVertexId(id).setAsn(Uint32.valueOf(as));
429 if (na.getIpv4RouterId() != null) {
430 builder.setRouterId(new IpAddress(new Ipv4Address(na.getIpv4RouterId().getValue())));
432 if (na.getIpv6RouterId() != null) {
433 builder.setRouterId(new IpAddress(new Ipv6Address(na.getIpv6RouterId().getValue())));
436 * Set Router Name with dynamic hostname (IS-IS) or IPv4 address in dot decimal format (OSPF)
438 if (na.getDynamicHostname() != null) {
439 builder.setName(na.getDynamicHostname());
441 int key = id.intValue();
443 ((key << 24) & 0xFF) + "." + ((key << 16) & 0xFF) + "." + ((key << 8) & 0xFF) + "." + (key & 0xFF));
445 if (na.getSrCapabilities() != null) {
446 builder.setSrgb(new SrgbBuilder()
448 ((LocalLabelCase) na.getSrCapabilities().getSidLabelIndex()).getLocalLabel().getValue())
449 .setRangeSize(na.getSrCapabilities().getRangeSize().getValue())
452 if (na.getNodeFlags() != null) {
453 if (na.getNodeFlags().isAbr()) {
454 builder.setVertexType(VertexType.Abr);
456 if (na.getNodeFlags().isExternal()) {
457 builder.setVertexType(VertexType.AsbrOut);
460 builder.setVertexType(VertexType.Standard);
462 return builder.build();
466 * Create new Connected Vertex in the Connected Graph.
468 * @param value The complete Linkstate route information
469 * @param nodeCase The node part of the Linkstate route
470 * @param attributes The node attributes
472 private void createVertex(final LinkstateRoute value, final NodeCase nodeCase, final Attributes attributes) {
473 Preconditions.checkArgument(nodeCase != null, "Missing Node Case. Skip this Node");
474 Preconditions.checkArgument(nodeCase.getNodeDescriptors() != null, "Missing Node Descriptors. Skip this Node");
476 Uint64 vertexId = getVertexId(nodeCase.getNodeDescriptors().getCRouterIdentifier());
477 if (vertexId == Uint64.ZERO) {
478 LOG.warn("Unable to get Vertex Identifier from descriptor {}, skipping it", nodeCase.getNodeDescriptors());
482 NodeAttributes na = getNodeAttributes(attributes);
484 LOG.warn("Missing attributes in node {} route {}, skipping it", nodeCase, value);
489 if (nodeCase.getNodeDescriptors() != null) {
490 asNumber = nodeCase.getNodeDescriptors().getAsNumber().getValue().intValue();
492 Vertex vertex = getVertex(na, vertexId, asNumber);
494 /* Add the Connected Vertex and associated Vertex in the Graph */
495 LOG.info("Add Vertex {} in TED[{}]", vertex.getName(), cgraph);
496 cgraph.addVertex(vertex);
500 * Create new Prefix in the Connected Graph.
502 * @param value The complete Linkstate route information
503 * @param prefixCase The Prefix part of the Linkstate route
504 * @param attributes The Prefix attributes
506 private void createPrefix(final LinkstateRoute value, final PrefixCase prefixCase, final Attributes attributes) {
507 final IpPrefix ippfx = prefixCase.getPrefixDescriptors().getIpReachabilityInformation();
509 LOG.warn("IP reachability not present in prefix {} route {}, skipping it", prefixCase, value);
513 /* Verify that all mandatory information are present */
514 final PrefixAttributes pa;
515 final Attributes1 attr = attributes.augmentation(Attributes1.class);
517 final LinkStateAttribute attrType = attr.getLinkStateAttribute();
518 if (attrType != null) {
519 pa = ((PrefixAttributesCase) attrType).getPrefixAttributes();
521 LOG.warn("Missing attribute type in IP {} prefix {} route {}, skipping it", ippfx, prefixCase, value);
525 LOG.warn("Missing attributes in IP {} prefix {} route {}, skipping it", ippfx, prefixCase, value);
530 * Get Connected Vertex from Connected Graph corresponding to the
531 * Advertising Node Descriptor
533 Uint64 vertexId = getVertexId(prefixCase.getAdvertisingNodeDescriptors().getCRouterIdentifier());
534 if (vertexId == Uint64.ZERO) {
535 LOG.warn("Unable to get the Vertex Identifier from descriptor {}, skipping it",
536 prefixCase.getAdvertisingNodeDescriptors());
541 PrefixBuilder builder = new PrefixBuilder().setVertexId(vertexId);
542 if (pa.getSrPrefix() != null && pa.getSrPrefix().getSidLabelIndex() instanceof SidCase) {
543 builder.setPrefixSid(((SidCase) pa.getSrPrefix().getSidLabelIndex()).getSid());
544 if (pa.getSrPrefix().getFlags() instanceof IsisPrefixFlagsCase) {
546 ((IsisPrefixFlagsCase) pa.getSrPrefix().getFlags()).getIsisPrefixFlags().isNodeSid());
549 * Seems that OSPF Flags are not accessible. Assuming that the
550 * Prefix is a Node SID
552 builder.setNodeSid(true);
555 if (ippfx.getIpv4Prefix() != null) {
556 builder.setPrefix(new IpPrefix(ippfx.getIpv4Prefix()));
558 if (ippfx.getIpv6Prefix() != null) {
559 builder.setPrefix(new IpPrefix(ippfx.getIpv6Prefix()));
561 Prefix prefix = builder.build();
563 /* Add the Prefix to the Connected Vertex within the Connected Graph */
564 LOG.info("Add prefix {} in TED[{}]", builder.getPrefix(), cgraph);
565 cgraph.addPrefix(prefix);
569 protected void removeObject(final ReadWriteTransaction trans, final InstanceIdentifier<LinkstateRoute> id,
570 final LinkstateRoute value) {
572 LOG.error("Empty before-data received in delete data change notification for instance id {}", id);
576 final ObjectType t = value.getObjectType();
577 if (t instanceof LinkCase) {
578 removeEdge((LinkCase) t);
579 } else if (t instanceof NodeCase) {
580 removeVertex((NodeCase) t);
581 } else if (t instanceof PrefixCase) {
582 removePrefix((PrefixCase) t);
584 LOG.debug(UNHANDLED_OBJECT_CLASS, t.implementedInterface());
588 private void removeEdge(LinkCase linkCase) {
589 /* Get Source and Destination Connected Vertex */
590 if (linkCase.getLinkDescriptors() == null) {
591 LOG.warn("Missing Link descriptor in link {}, skipping it", linkCase);
594 EdgeKey edgeKey = new EdgeKey(getEdgeId(linkCase));
595 if ((edgeKey == null) || (edgeKey.getEdgeId() == Uint64.ZERO)) {
596 LOG.warn("Unable to get the Edge Key from link {}, skipping it", linkCase);
600 LOG.info("Deleted Edge {} from TED[{}]", edgeKey, cgraph);
601 cgraph.deleteEdge(edgeKey);
604 private void removeVertex(NodeCase nodeCase) {
605 VertexKey vertexKey = new VertexKey(getVertexId(nodeCase.getNodeDescriptors().getCRouterIdentifier()));
606 if ((vertexKey == null) || (vertexKey.getVertexId() == Uint64.ZERO)) {
607 LOG.warn("Unable to get Vertex Key from descriptor {}, skipping it", nodeCase.getNodeDescriptors());
611 LOG.info("Deleted Vertex {} in TED[{}]", vertexKey, cgraph);
612 cgraph.deleteVertex(vertexKey);
615 private void removePrefix(PrefixCase prefixCase) {
616 final IpPrefix ippfx = prefixCase.getPrefixDescriptors().getIpReachabilityInformation();
618 LOG.warn("IP reachability not present in prefix {}, skipping it", prefixCase);
622 LOG.info("Deleted prefix {} in TED[{}]", ippfx, cgraph);
623 cgraph.deletePrefix(ippfx);
627 * Get Vertex in the Graph by the OSPF Router ID or IS-IS-System ID.
629 * @param routerID The Router Identifier entry
631 * @return Vertex in the Connected Graph that corresponds to this Router ID. Vertex is created if not found.
633 private Uint64 getVertexId(CRouterIdentifier routerID) {
636 if (routerID instanceof IsisNodeCase) {
637 byte[] isoId = ((IsisNodeCase) routerID).getIsisNode().getIsoSystemId().getValue();
638 final byte[] convert = {0, 0, isoId[0], isoId[1], isoId[2], isoId[3], isoId[4], isoId[5]};
639 rid = ByteBuffer.wrap(convert).getLong();
641 if (routerID instanceof OspfNodeCase) {
642 rid = ((OspfNodeCase) routerID).getOspfNode().getOspfRouterId().longValue();
645 LOG.debug("Get Vertex Identifier {}", rid);
646 return Uint64.valueOf(rid);
649 private DecimalBandwidth bandwithToDecimalBandwidth(Bandwidth bw) {
650 return new DecimalBandwidth(BigDecimal.valueOf(ByteBuffer.wrap(bw.getValue()).getFloat()));
653 private long ipv4ToKey(String str) {
656 ip = ((Inet4Address) Inet4Address.getByName(str)).getAddress();
657 } catch (UnknownHostException e) {
660 return (((0xFF & ip[0]) << 24) | ((0xFF & ip[1]) << 16) | ((0xFF & ip[2]) << 8) | (0xFF & ip[3]));
663 private Long ipv6ToKey(String str) {
666 ip = ((Inet6Address) Inet6Address.getByName(str)).getAddress();
667 } catch (UnknownHostException e) {
670 /* Keep only the lower 64bits from the IP address */
671 byte[] lowerIP = {ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7]};
672 return ByteBuffer.wrap(lowerIP).getLong();
676 protected InstanceIdentifier<LinkstateRoute> getRouteWildcard(final InstanceIdentifier<Tables> tablesId) {
677 return tablesId.child(LinkstateRoutesCase.class, LinkstateRoutes.class).child(LinkstateRoute.class);
681 protected void clearTopology() {