2 * Copyright (c) 2014 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
8 package org.opendaylight.bgpcep.bgp.topology.provider;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotEquals;
12 import static org.junit.Assert.assertNull;
13 import static org.junit.Assert.assertTrue;
14 import static org.junit.Assert.fail;
15 import static org.mockito.ArgumentMatchers.any;
16 import static org.mockito.Mockito.RETURNS_SMART_NULLS;
17 import static org.mockito.Mockito.doThrow;
18 import static org.mockito.Mockito.mock;
19 import static org.mockito.Mockito.never;
20 import static org.mockito.Mockito.spy;
21 import static org.mockito.Mockito.timeout;
22 import static org.mockito.Mockito.times;
23 import static org.mockito.Mockito.verify;
24 import static org.opendaylight.protocol.util.CheckUtil.checkNotPresentOperational;
25 import static org.opendaylight.protocol.util.CheckUtil.readDataOperational;
27 import com.google.common.collect.Lists;
28 import io.netty.buffer.Unpooled;
29 import java.nio.charset.StandardCharsets;
30 import java.util.ArrayList;
31 import java.util.Collections;
32 import java.util.List;
33 import java.util.concurrent.ExecutionException;
34 import org.junit.After;
35 import org.junit.Before;
36 import org.junit.Test;
37 import org.opendaylight.mdsal.binding.api.DataTreeModification;
38 import org.opendaylight.mdsal.binding.api.WriteTransaction;
39 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressNoZone;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.AdministrativeGroup;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.Identifier;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.Ipv4RouterIdentifier;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.IsisAreaIdentifier;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.LinkstateAddressFamily;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.LinkstateSubsequentAddressFamily;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.ProtocolId;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.TopologyIdentifier;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.bgp.rib.rib.loc.rib.tables.routes.LinkstateRoutesCase;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.attribute.SrAdjIdsBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.attribute.UnreservedBandwidthBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.attribute.UnreservedBandwidthKey;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.link._case.LinkDescriptorsBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.link._case.LocalNodeDescriptorsBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.link._case.RemoteNodeDescriptorsBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.node._case.NodeDescriptorsBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.prefix._case.AdvertisingNodeDescriptorsBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.prefix._case.PrefixDescriptorsBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.LinkAttributesCaseBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.NodeAttributesCaseBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.PrefixAttributesCaseBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.link.attributes._case.LinkAttributesBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.node.attributes._case.NodeAttributesBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.prefix.attributes._case.PrefixAttributesBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.LinkstateRoutes;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.linkstate.routes.LinkstateRoute;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.linkstate.routes.LinkstateRouteBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.linkstate.routes.LinkstateRouteKey;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.linkstate.routes.linkstate.route.Attributes1;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.linkstate.routes.linkstate.route.Attributes1Builder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.node.identifier.c.router.identifier.IsisNodeCaseBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.node.identifier.c.router.identifier.isis.node._case.IsisNodeBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.node.state.SrCapabilitiesBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.prefix.state.SrPrefixBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.PathId;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.AttributesBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.attributes.OriginBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.rib.LocRib;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.Tables;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.Algorithm;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.sid.label.index.sid.label.index.LocalLabelCaseBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.sid.label.index.sid.label.index.SidCaseBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.BgpOrigin;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.Bandwidth;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.IgpMetric;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.IsoSystemIdentifier;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.MplsLabel;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.TeMetric;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.SrlgId;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.uint24.rev200104.Uint24;
96 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.isis.topology.rev131021.IgpLinkAttributes1;
97 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.isis.topology.rev131021.IgpNodeAttributes1;
98 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
99 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
100 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.Link1;
101 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.Node1;
102 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.igp.link.attributes.IgpLinkAttributes;
103 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.igp.node.attributes.IgpNodeAttributes;
104 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.igp.node.attributes.igp.node.attributes.Prefix;
105 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
106 import org.opendaylight.yangtools.yang.common.Uint16;
107 import org.opendaylight.yangtools.yang.common.Uint32;
108 import org.opendaylight.yangtools.yang.common.Uint64;
109 import org.opendaylight.yangtools.yang.common.Uint8;
111 public class LinkstateTopologyBuilderTest extends AbstractTopologyBuilderTest {
113 private static final String ROUTER_1_ID = "127.0.0.1";
114 private static final String ROUTER_2_ID = "127.0.0.2";
115 private static final String NODE_1_PREFIX = "127.0.1.1/32";
116 private static final AsNumber NODE_1_AS = new AsNumber(Uint32.ONE);
117 private static final AsNumber NODE_2_AS = new AsNumber(Uint32.TWO);
118 private static final String NODE_1_ISIS_ID = "bgpls://IsisLevel2:1/type=node&as=1&router=0000.0102.0304";
119 private static final String NODE_2_ISIS_ID = "bgpls://IsisLevel2:1/type=node&as=2";
120 private static final String NODE_1_OSPF_ID = "bgpls://Ospf:1/type=node&as=1&router=0000.0102.0304";
121 private static final String NODE_2_OSPF_ID = "bgpls://Ospf:1/type=node&as=2";
122 private static final Identifier IDENTIFIER = new Identifier(Uint64.ONE);
123 private static final long LISTENER_RESTART_TIME = 20000;
124 private static final int LISTENER_ENFORCE_COUNTER = 2;
125 private static final int SRGB_START = 90000;
126 private static final int SRGB_RANGE = 16;
127 private static final int NODE_SID_INDEX = 4;
128 private static final int ADJ_SID = 24001;
130 private LinkstateTopologyBuilder linkstateTopoBuilder;
131 private InstanceIdentifier<Tables> tablePathIID;
132 private String linkstateNodeRouteKey;
133 private String linkstatePrefixRouteKey;
134 private String linkstateLinkRouteKey;
135 private InstanceIdentifier<LinkstateRoute> linkstateNodeRouteIID;
136 private InstanceIdentifier<LinkstateRoute> linkstatePrefixRouteIID;
137 private InstanceIdentifier<LinkstateRoute> linkstateLinkRouteIID;
141 public void setUp() {
143 this.linkstateTopoBuilder = new LinkstateTopologyBuilder(getDataBroker(), LOC_RIB_REF, TEST_TOPOLOGY_ID,
144 LISTENER_RESTART_TIME, LISTENER_ENFORCE_COUNTER);
145 this.linkstateTopoBuilder.start();
147 LOC_RIB_REF.getInstanceIdentifier().builder().child(LocRib.class)
149 new TablesKey(LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class))
151 this.linkstateNodeRouteKey = getLinkstateRouteKey("node-route");
152 this.linkstatePrefixRouteKey = getLinkstateRouteKey("prefix-route");
153 this.linkstateLinkRouteKey = getLinkstateRouteKey("link-route");
154 this.linkstateNodeRouteIID = createLinkstateRouteIID(this.linkstateNodeRouteKey);
155 this.linkstatePrefixRouteIID = createLinkstateRouteIID(this.linkstatePrefixRouteKey);
156 this.linkstateLinkRouteIID = createLinkstateRouteIID(this.linkstateLinkRouteKey);
160 public void tearDown() throws Exception {
161 this.linkstateTopoBuilder.close();
162 checkNotPresentOperational(getDataBroker(), this.linkstateTopoBuilder.getInstanceIdentifier());
166 public void testLinkstateTopologyBuilderTopologyTypes() throws InterruptedException, ExecutionException {
167 readDataOperational(getDataBroker(), this.linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
168 assertEquals(LinkstateTopologyBuilder.LINKSTATE_TOPOLOGY_TYPE, topology.getTopologyTypes());
174 @SuppressWarnings("checkstyle:LineLength")
175 public void testIsisLinkstateTopologyBuilder() throws InterruptedException, ExecutionException {
177 updateLinkstateRoute(this.linkstateNodeRouteIID,
178 createLinkstateNodeRoute(ProtocolId.IsisLevel2, "node1", NODE_1_AS, ROUTER_1_ID));
179 readDataOperational(getDataBroker(), this.linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
180 assertEquals(1, topology.getNode().size());
181 final Node node1 = topology.getNode().get(0);
182 assertEquals(NODE_1_ISIS_ID, node1.getNodeId().getValue());
183 final IgpNodeAttributes igpNode1 = node1.augmentation(Node1.class).getIgpNodeAttributes();
184 assertEquals(ROUTER_1_ID, igpNode1.getRouterId().get(0).getIpv4Address().getValue());
185 assertEquals("node1", igpNode1.getName().getValue());
186 final IgpNodeAttributes1 igpNodeAttributes1 = igpNode1.augmentation(IgpNodeAttributes1.class);
187 assertEquals("0000.0102.0304", igpNodeAttributes1.getIsisNodeAttributes().getIso().getIsoSystemId()
189 assertEquals(ROUTER_1_ID, igpNodeAttributes1.getIsisNodeAttributes().getTed().getTeRouterIdIpv4()
191 assertEquals("47.0000.0000.0000.0000.0102.0304", igpNodeAttributes1.getIsisNodeAttributes()
192 .getNet().get(0).getValue());
193 assertNull(igpNode1.augmentation(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.ospf
194 .topology.rev131021.IgpNodeAttributes1.class));
195 assertEquals(LinkstateTopologyBuilder.LINKSTATE_TOPOLOGY_TYPE, topology.getTopologyTypes());
196 assertNull(node1.augmentation(
197 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Node1.class));
202 updateLinkstateRoute(this.linkstateLinkRouteIID,
203 createLinkstateLinkRoute(ProtocolId.IsisLevel2, NODE_1_AS, NODE_2_AS, "link1"));
204 readDataOperational(getDataBroker(), this.linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
205 assertEquals(1, topology.getLink().size());
206 final Link link1 = topology.getLink().get(0);
207 assertEquals(2, topology.getNode().size());
208 assertEquals(1, topology.getNode().get(0).getTerminationPoint().size());
209 assertEquals(1, topology.getNode().get(1).getTerminationPoint().size());
210 assertEquals("bgpls://IsisLevel2:1/type=link&local-as=1&local-router=0000.0102.0304&remote-as"
211 + "=2&mt=1", link1.getLinkId().getValue());
212 assertEquals(NODE_1_ISIS_ID, link1.getSource().getSourceNode().getValue());
213 assertEquals(NODE_2_ISIS_ID, link1.getDestination().getDestNode().getValue());
214 final IgpLinkAttributes igpLink1 = link1.augmentation(Link1.class).getIgpLinkAttributes();
215 assertEquals("link1", igpLink1.getName());
216 assertEquals((short) 1, igpLink1.augmentation(IgpLinkAttributes1.class).getIsisLinkAttributes()
217 .getMultiTopologyId().shortValue());
218 assertNull(igpLink1.augmentation(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.ospf
219 .topology.rev131021.IgpLinkAttributes1.class));
220 assertEquals(LinkstateTopologyBuilder.SR_AWARE_LINKSTATE_TOPOLOGY_TYPE, topology.getTopologyTypes());
221 assertEquals(2, topology.getNode().size());
223 if (topology.getNode().get(0).getNodeId().getValue().contains("0000.0102.0304")) {
224 srcNode = topology.getNode().get(0);
226 srcNode = topology.getNode().get(1);
228 assertEquals(1, srcNode.augmentation(
229 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Node1.class)
230 .getSegments().size());
231 assertEquals(ADJ_SID, link1.augmentation(
232 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Link1.class)
233 .getSegment().getValue().intValue());
236 removeLinkstateRoute(this.linkstateLinkRouteIID);
239 updateLinkstateRoute(this.linkstateNodeRouteIID,
240 createLinkstateNodeRoute(ProtocolId.IsisLevel2, "updated-node", NODE_1_AS, ROUTER_2_ID));
241 readDataOperational(getDataBroker(), this.linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
242 assertEquals(1, topology.getNode().size());
243 final IgpNodeAttributes igpNode2 = topology.getNode().get(0).augmentation(Node1.class)
244 .getIgpNodeAttributes();
245 assertEquals(ROUTER_2_ID, igpNode2.getRouterId().get(0).getIpv4Address().getValue());
246 assertEquals("updated-node", igpNode2.getName().getValue());
251 removeLinkstateRoute(this.linkstateNodeRouteIID);
252 readDataOperational(getDataBroker(), this.linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
253 assertEquals(LinkstateTopologyBuilder.LINKSTATE_TOPOLOGY_TYPE, topology.getTopologyTypes());
254 assertNull(topology.getNode());
255 assertNull(topology.getLink());
261 @SuppressWarnings("checkstyle:LineLength")
262 public void testOspfLinkstateTopologyBuilder() throws InterruptedException, ExecutionException {
264 updateLinkstateRoute(this.linkstateNodeRouteIID,
265 createLinkstateNodeRoute(ProtocolId.Ospf, "node1", NODE_1_AS, ROUTER_1_ID));
266 readDataOperational(getDataBroker(), this.linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
267 assertEquals(1, topology.getNode().size());
268 final Node node1 = topology.getNode().get(0);
269 assertEquals(NODE_1_OSPF_ID, node1.getNodeId().getValue());
270 final IgpNodeAttributes igpNode1 = node1.augmentation(Node1.class).getIgpNodeAttributes();
271 assertEquals(ROUTER_1_ID, igpNode1.getRouterId().get(0).getIpv4Address().getValue());
272 assertEquals("node1", igpNode1.getName().getValue());
273 assertNull(igpNode1.augmentation(IgpNodeAttributes1.class));
274 assertEquals(ROUTER_1_ID, igpNode1.augmentation(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns
275 .yang.ospf.topology.rev131021.IgpNodeAttributes1.class).getOspfNodeAttributes().getTed()
276 .getTeRouterIdIpv4().getValue());
277 assertEquals(LinkstateTopologyBuilder.LINKSTATE_TOPOLOGY_TYPE, topology.getTopologyTypes());
278 assertNull(node1.augmentation(
279 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Node1.class));
283 // update node with prefix
284 updateLinkstateRoute(this.linkstatePrefixRouteIID,
285 createLinkstatePrefixRoute(ProtocolId.Ospf, NODE_1_AS, NODE_1_PREFIX, 500L, ROUTER_1_ID));
286 readDataOperational(getDataBroker(), this.linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
287 final Node node1 = topology.getNode().get(0);
288 final IgpNodeAttributes igpNode1 = node1.augmentation(Node1.class).getIgpNodeAttributes();
289 assertEquals(1, igpNode1.getPrefix().size());
290 final Prefix prefix = igpNode1.getPrefix().get(0);
291 assertEquals(NODE_1_PREFIX, prefix.getPrefix().getIpv4Prefix().getValue());
292 assertEquals(500L, prefix.getMetric().longValue());
293 assertEquals(LinkstateTopologyBuilder.SR_AWARE_LINKSTATE_TOPOLOGY_TYPE, topology.getTopologyTypes());
294 assertEquals(1, node1.augmentation(
295 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Node1.class)
296 .getSegments().size());
297 assertEquals(SRGB_START + NODE_SID_INDEX, node1.augmentation(
298 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Node1.class)
299 .getSegments().get(0).getSegmentId().getValue().intValue());
304 updateLinkstateRoute(this.linkstateLinkRouteIID,
305 createLinkstateLinkRoute(ProtocolId.Ospf, NODE_1_AS, NODE_2_AS, "link1"));
306 readDataOperational(getDataBroker(), this.linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
307 assertEquals(1, topology.getLink().size());
308 final Link link1 = topology.getLink().get(0);
309 assertEquals(2, topology.getNode().size());
310 assertEquals(1, topology.getNode().get(0).getTerminationPoint().size());
311 assertEquals(1, topology.getNode().get(1).getTerminationPoint().size());
312 assertEquals("bgpls://Ospf:1/type=link&local-as=1&local-router=0000.0102.0304&remote-as=2&mt=1",
313 link1.getLinkId().getValue());
314 assertEquals(NODE_1_OSPF_ID, link1.getSource().getSourceNode().getValue());
315 assertEquals(NODE_2_OSPF_ID, link1.getDestination().getDestNode().getValue());
316 final IgpLinkAttributes igpLink1 = link1.augmentation(Link1.class).getIgpLinkAttributes();
317 assertEquals("link1", igpLink1.getName());
318 assertNull(igpLink1.augmentation(IgpLinkAttributes1.class));
319 assertEquals((short) 1, igpLink1.augmentation(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang
320 .ospf.topology.rev131021.IgpLinkAttributes1.class).getOspfLinkAttributes().getMultiTopologyId()
322 assertEquals(2, igpLink1.augmentation(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns
323 .yang.ospf.topology.rev131021.IgpLinkAttributes1.class).getOspfLinkAttributes().getTed().getSrlg()
324 .getSrlgValues().size());
325 assertEquals(LinkstateTopologyBuilder.SR_AWARE_LINKSTATE_TOPOLOGY_TYPE, topology.getTopologyTypes());
326 assertEquals(2, topology.getNode().size());
328 if (topology.getNode().get(0).getNodeId().getValue().contains("0000.0102.0304")) {
329 srcNode = topology.getNode().get(0);
331 srcNode = topology.getNode().get(1);
333 assertEquals(2, srcNode.augmentation(
334 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Node1.class)
335 .getSegments().size());
336 assertEquals(ADJ_SID, link1.augmentation(
337 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Link1.class)
338 .getSegment().getValue().intValue());
344 * This test is to verify if the AbstractTopologyBuilder/LinkstateTopologyBuilder is handling exception correctly.
347 @SuppressWarnings("checkstyle:IllegalCatch")
348 public void testRouteChangedError() throws Exception {
349 final LinkstateTopologyBuilder spiedLinkstateTopologyBuilder = spy(this.linkstateTopoBuilder);
350 doThrow(RuntimeException.class).when(spiedLinkstateTopologyBuilder).routeChanged(any(), any());
352 spiedLinkstateTopologyBuilder.routeChanged(null, null);
353 fail("Mockito failed to spy routeChanged() method");
354 } catch (final Exception e) {
355 assertTrue(e instanceof RuntimeException);
357 assertEquals(0L, spiedLinkstateTopologyBuilder.listenerScheduledRestartTime);
358 assertEquals(0L, spiedLinkstateTopologyBuilder.listenerScheduledRestartEnforceCounter);
359 // first we examine if the chain is being reset when no exception is thrown
360 spiedLinkstateTopologyBuilder.onDataTreeChanged(new ArrayList<>());
361 verify(spiedLinkstateTopologyBuilder, times(1)).restartTransactionChainOnDemand();
362 verify(spiedLinkstateTopologyBuilder, never()).scheduleListenerRestart();
363 verify(spiedLinkstateTopologyBuilder, never()).resetTransactionChain();
364 assertEquals(0L, spiedLinkstateTopologyBuilder.listenerScheduledRestartTime);
365 assertEquals(0L, spiedLinkstateTopologyBuilder.listenerScheduledRestartEnforceCounter);
366 // now pass some invalid data to cause onDataTreeChanged fail
367 final DataTreeModification<LinkstateRoute> modification = mock(DataTreeModification.class, RETURNS_SMART_NULLS);
368 final List<DataTreeModification<LinkstateRoute>> changes = new ArrayList<>();
369 changes.add(modification);
370 spiedLinkstateTopologyBuilder.onDataTreeChanged(changes);
371 // one restart transaction chain check in onDataTreeChanged()
372 // we are introducing some timeout here as transaction may be executed in a delay manner
373 verify(spiedLinkstateTopologyBuilder, timeout(5000).times(1)).scheduleListenerRestart();
374 verify(spiedLinkstateTopologyBuilder, times(2)).restartTransactionChainOnDemand();
375 assertNotEquals(0L, spiedLinkstateTopologyBuilder.listenerScheduledRestartTime);
376 assertEquals(0, spiedLinkstateTopologyBuilder.listenerScheduledRestartEnforceCounter);
377 final long listenerScheduledRestartTime = spiedLinkstateTopologyBuilder.listenerScheduledRestartTime;
378 // call again with empty change to invoke restartTransactionChainOnDemand()
379 spiedLinkstateTopologyBuilder.onDataTreeChanged(new ArrayList<>());
380 verify(spiedLinkstateTopologyBuilder, times(3)).restartTransactionChainOnDemand();
381 // transaction chain should be reset while listener should not
382 verify(spiedLinkstateTopologyBuilder, times(1)).resetTransactionChain();
383 verify(spiedLinkstateTopologyBuilder, never()).resetListener();
384 // now apply a change with bad modification again
385 spiedLinkstateTopologyBuilder.onDataTreeChanged(changes);
386 verify(spiedLinkstateTopologyBuilder, times(4)).restartTransactionChainOnDemand();
387 // listener scheduled again
388 verify(spiedLinkstateTopologyBuilder, timeout(5000).times(2)).scheduleListenerRestart();
389 // listener timer shouldn't have changed
390 assertEquals(listenerScheduledRestartTime, spiedLinkstateTopologyBuilder.listenerScheduledRestartTime);
391 assertEquals(0, spiedLinkstateTopologyBuilder.listenerScheduledRestartEnforceCounter);
392 verify(spiedLinkstateTopologyBuilder, times(2)).resetTransactionChain();
393 verify(spiedLinkstateTopologyBuilder, never()).resetListener();
394 Thread.sleep(LISTENER_RESTART_TIME);
395 // manually invoke onTransactionChainFailed() to have the listener restart scheduled again
396 spiedLinkstateTopologyBuilder.onTransactionChainFailed(null, null, null);
397 assertEquals(spiedLinkstateTopologyBuilder.listenerScheduledRestartTime, listenerScheduledRestartTime
398 + LISTENER_RESTART_TIME);
399 verify(spiedLinkstateTopologyBuilder, times(5)).restartTransactionChainOnDemand();
400 verify(spiedLinkstateTopologyBuilder, times(3)).scheduleListenerRestart();
401 // enforce counter get increased
402 assertEquals(1, spiedLinkstateTopologyBuilder.listenerScheduledRestartEnforceCounter);
403 verify(spiedLinkstateTopologyBuilder, times(3)).resetTransactionChain();
404 verify(spiedLinkstateTopologyBuilder, never()).resetListener();
405 // sleep to let the listener restart timer times out
406 Thread.sleep(LISTENER_RESTART_TIME);
407 // apply a good modification (empty change)
408 spiedLinkstateTopologyBuilder.onDataTreeChanged(new ArrayList<>());
409 assertEquals(0, spiedLinkstateTopologyBuilder.listenerScheduledRestartTime);
410 assertEquals(0, spiedLinkstateTopologyBuilder.listenerScheduledRestartEnforceCounter);
411 verify(spiedLinkstateTopologyBuilder, times(6)).restartTransactionChainOnDemand();
412 // listener restarted didn't get rescheduled again
413 verify(spiedLinkstateTopologyBuilder, times(3)).scheduleListenerRestart();
414 verify(spiedLinkstateTopologyBuilder, times(4)).resetTransactionChain();
415 verify(spiedLinkstateTopologyBuilder, times(1)).resetListener();
418 private static String getLinkstateRouteKey(final String routeKey) {
419 return Unpooled.wrappedBuffer(StandardCharsets.UTF_8.encode(routeKey)).array().toString();
422 private InstanceIdentifier<LinkstateRoute> createLinkstateRouteIID(final String linkstateRouteKey) {
423 return this.tablePathIID.builder().child(LinkstateRoutesCase.class, LinkstateRoutes.class)
424 .child(LinkstateRoute.class, new LinkstateRouteKey(new PathId(Uint32.ZERO), linkstateRouteKey)).build();
427 private void updateLinkstateRoute(final InstanceIdentifier<LinkstateRoute> linkstateRouteIID,
428 final LinkstateRoute data) {
429 final WriteTransaction wTx = getDataBroker().newWriteOnlyTransaction();
430 wTx.mergeParentStructurePut(LogicalDatastoreType.OPERATIONAL, linkstateRouteIID, data);
434 private void removeLinkstateRoute(final InstanceIdentifier<LinkstateRoute> linkstateRouteIID) {
435 final WriteTransaction wTx = getDataBroker().newWriteOnlyTransaction();
436 wTx.delete(LogicalDatastoreType.OPERATIONAL, linkstateRouteIID);
440 private LinkstateRoute createLinkstateNodeRoute(final ProtocolId protocolId, final String nodeName,
441 final AsNumber asNumber, final String ipv4RouterId) {
442 return createBaseBuilder(this.linkstateNodeRouteKey, protocolId)
443 .setObjectType(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate
444 .rev200120.linkstate.object.type.NodeCaseBuilder()
445 .setNodeDescriptors(new NodeDescriptorsBuilder()
446 .setCRouterIdentifier(new IsisNodeCaseBuilder().setIsisNode(new IsisNodeBuilder()
447 .setIsoSystemId(new IsoSystemIdentifier(new byte[]{0, 0, 1, 2, 3, 4})).build())
449 .setAsNumber(asNumber).build()).build())
450 .setAttributes(new AttributesBuilder()
451 .setOrigin(new OriginBuilder().setValue(BgpOrigin.Igp).build())
452 .addAugmentation(Attributes1.class, new Attributes1Builder()
453 .setLinkStateAttribute(new NodeAttributesCaseBuilder()
454 .setNodeAttributes(new NodeAttributesBuilder()
455 .setDynamicHostname(nodeName)
456 .setIpv4RouterId(new Ipv4RouterIdentifier(ipv4RouterId))
457 .setIsisAreaId(Collections.singletonList(
458 new IsisAreaIdentifier(new byte[]{0x47})))
459 .setSrCapabilities(new SrCapabilitiesBuilder()
460 .setRangeSize(new Uint24(Uint32.valueOf(SRGB_RANGE)))
461 .setSidLabelIndex(new LocalLabelCaseBuilder()
463 new MplsLabel(Uint32.valueOf(SRGB_START)))
466 .build()).build()).build()).build()).build();
469 private LinkstateRoute createLinkstatePrefixRoute(final ProtocolId protocolId, final AsNumber asNumber,
470 final String ipv4Prefix, final long igpMetric, final String ospfFwdAddress) {
471 return createBaseBuilder(this.linkstatePrefixRouteKey, protocolId)
472 .setObjectType(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120
473 .linkstate.object.type.PrefixCaseBuilder()
474 .setAdvertisingNodeDescriptors(new AdvertisingNodeDescriptorsBuilder()
475 .setCRouterIdentifier(new IsisNodeCaseBuilder().setIsisNode(new IsisNodeBuilder()
476 .setIsoSystemId(new IsoSystemIdentifier(new byte[]{0, 0, 1, 2, 3, 4})).build())
477 .build()).setAsNumber(asNumber).build())
478 .setPrefixDescriptors(new PrefixDescriptorsBuilder()
479 .setIpReachabilityInformation(new IpPrefix(new Ipv4Prefix(ipv4Prefix))).build()).build())
480 .setAttributes(new AttributesBuilder()
481 .setOrigin(new OriginBuilder().setValue(BgpOrigin.Igp).build())
482 .addAugmentation(Attributes1.class, new Attributes1Builder()
483 .setLinkStateAttribute(new PrefixAttributesCaseBuilder()
484 .setPrefixAttributes(new PrefixAttributesBuilder()
485 .setOspfForwardingAddress(new IpAddressNoZone(new Ipv4AddressNoZone(ospfFwdAddress)))
486 .setPrefixMetric(new IgpMetric(Uint32.valueOf(igpMetric)))
487 .setSrPrefix(new SrPrefixBuilder()
488 .setAlgorithm(Algorithm.ShortestPathFirst)
489 .setSidLabelIndex(new SidCaseBuilder()
490 .setSid(Uint32.valueOf(NODE_SID_INDEX)).build())
499 private LinkstateRoute createLinkstateLinkRoute(final ProtocolId protocolId, final AsNumber localAs,
500 final AsNumber remoteAs, final String linkName) {
501 return createBaseBuilder(this.linkstateLinkRouteKey, protocolId)
502 .setObjectType(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate
503 .rev200120.linkstate.object.type.LinkCaseBuilder()
504 .setLocalNodeDescriptors(new LocalNodeDescriptorsBuilder().setAsNumber(localAs)
505 .setCRouterIdentifier(new IsisNodeCaseBuilder().setIsisNode(new IsisNodeBuilder()
506 .setIsoSystemId(new IsoSystemIdentifier(new byte[]{0, 0, 1, 2, 3, 4}))
507 .build()).build()).build())
508 .setRemoteNodeDescriptors(new RemoteNodeDescriptorsBuilder().setAsNumber(remoteAs).build())
509 .setLinkDescriptors(new LinkDescriptorsBuilder()
510 .setMultiTopologyId(new TopologyIdentifier(Uint16.ONE)).build()).build())
511 .setAttributes(new AttributesBuilder()
512 .setOrigin(new OriginBuilder().setValue(BgpOrigin.Igp).build())
513 .addAugmentation(Attributes1.class, new Attributes1Builder()
514 .setLinkStateAttribute(new LinkAttributesCaseBuilder()
515 .setLinkAttributes(new LinkAttributesBuilder()
516 .setSharedRiskLinkGroups(Lists.newArrayList(
517 new SrlgId(Uint32.valueOf(5)), new SrlgId(Uint32.valueOf(15))))
518 .setAdminGroup(new AdministrativeGroup(Uint32.ZERO))
519 .setMaxLinkBandwidth(
520 new Bandwidth(new byte[]{0x00, 0x00, (byte) 0xff, (byte) 0xff}))
521 .setMaxReservableBandwidth(
522 new Bandwidth(new byte[]{0x00, 0x00, (byte) 0xff, (byte) 0x1f}))
523 .setUnreservedBandwidth(Lists.newArrayList(new UnreservedBandwidthBuilder()
524 .withKey(new UnreservedBandwidthKey(Uint8.ONE))
525 .setBandwidth(new Bandwidth(new byte[]{0x00, 0x00, 0x00, (byte) 0xff}))
527 .setTeMetric(new TeMetric(Uint32.valueOf(100)))
528 .setLinkName(linkName)
529 .setSrAdjIds(Collections.singletonList(new SrAdjIdsBuilder()
530 .setSidLabelIndex(new LocalLabelCaseBuilder()
531 .setLocalLabel(new MplsLabel(Uint32.valueOf(ADJ_SID)))
541 private static LinkstateRouteBuilder createBaseBuilder(final String linkstateRouteKey,
542 final ProtocolId protocolId) {
543 return new LinkstateRouteBuilder()
544 .setIdentifier(IDENTIFIER)
545 .withKey(new LinkstateRouteKey(new PathId(Uint32.ZERO), linkstateRouteKey))
546 .setRouteKey(linkstateRouteKey)
547 .setProtocolId(protocolId);