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.Iterables;
28 import com.google.common.collect.Lists;
29 import io.netty.buffer.Unpooled;
30 import java.nio.charset.StandardCharsets;
31 import java.util.ArrayList;
32 import java.util.Collections;
33 import java.util.List;
34 import java.util.concurrent.ExecutionException;
35 import org.junit.After;
36 import org.junit.Before;
37 import org.junit.Test;
38 import org.opendaylight.mdsal.binding.api.DataTreeModification;
39 import org.opendaylight.mdsal.binding.api.WriteTransaction;
40 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressNoZone;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.AdministrativeGroup;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.Identifier;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.Ipv4RouterIdentifier;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.IsisAreaIdentifier;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.LinkstateAddressFamily;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.LinkstateSubsequentAddressFamily;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.ProtocolId;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.TopologyIdentifier;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.bgp.rib.rib.loc.rib.tables.routes.LinkstateRoutesCase;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.attribute.SrAdjIdsBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.attribute.UnreservedBandwidthBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.attribute.UnreservedBandwidthKey;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.link._case.LinkDescriptorsBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.link._case.LocalNodeDescriptorsBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.link._case.RemoteNodeDescriptorsBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.node._case.NodeDescriptorsBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.prefix._case.AdvertisingNodeDescriptorsBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.prefix._case.PrefixDescriptorsBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.LinkAttributesCaseBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.NodeAttributesCaseBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.PrefixAttributesCaseBuilder;
67 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;
68 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;
69 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;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.LinkstateRoutes;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.linkstate.routes.LinkstateRoute;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.linkstate.routes.LinkstateRouteBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.linkstate.routes.LinkstateRouteKey;
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 public void testIsisLinkstateTopologyBuilder() throws InterruptedException, ExecutionException {
176 updateLinkstateRoute(this.linkstateNodeRouteIID,
177 createLinkstateNodeRoute(ProtocolId.IsisLevel2, "node1", NODE_1_AS, ROUTER_1_ID));
178 readDataOperational(getDataBroker(), this.linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
179 assertEquals(1, topology.nonnullNode().size());
180 final Node node1 = topology.nonnullNode().values().iterator().next();
181 assertEquals(NODE_1_ISIS_ID, node1.getNodeId().getValue());
182 final IgpNodeAttributes igpNode1 = node1.augmentation(Node1.class).getIgpNodeAttributes();
183 assertEquals(ROUTER_1_ID, igpNode1.getRouterId().get(0).getIpv4Address().getValue());
184 assertEquals("node1", igpNode1.getName().getValue());
185 final IgpNodeAttributes1 igpNodeAttributes1 = igpNode1.augmentation(IgpNodeAttributes1.class);
186 assertEquals("0000.0102.0304", igpNodeAttributes1.getIsisNodeAttributes().getIso().getIsoSystemId()
188 assertEquals(ROUTER_1_ID, igpNodeAttributes1.getIsisNodeAttributes().getTed().getTeRouterIdIpv4()
190 assertEquals("47.0000.0000.0000.0000.0102.0304", igpNodeAttributes1.getIsisNodeAttributes()
191 .getNet().get(0).getValue());
192 assertNull(igpNode1.augmentation(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.ospf
193 .topology.rev131021.IgpNodeAttributes1.class));
194 assertEquals(LinkstateTopologyBuilder.LINKSTATE_TOPOLOGY_TYPE, topology.getTopologyTypes());
195 assertNull(node1.augmentation(
196 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Node1.class));
201 updateLinkstateRoute(this.linkstateLinkRouteIID,
202 createLinkstateLinkRoute(ProtocolId.IsisLevel2, NODE_1_AS, NODE_2_AS, "link1"));
203 readDataOperational(getDataBroker(), this.linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
204 assertEquals(1, topology.nonnullLink().size());
205 final Link link1 = topology.nonnullLink().values().iterator().next();
206 assertEquals(2, topology.nonnullNode().size());
207 assertEquals(1, Iterables.get(topology.getNode().values(), 0).getTerminationPoint().size());
208 assertEquals(1, Iterables.get(topology.getNode().values(), 1).getTerminationPoint().size());
209 assertEquals("bgpls://IsisLevel2:1/type=link&local-as=1&local-router=0000.0102.0304&remote-as"
210 + "=2&mt=1", link1.getLinkId().getValue());
211 assertEquals(NODE_1_ISIS_ID, link1.getSource().getSourceNode().getValue());
212 assertEquals(NODE_2_ISIS_ID, link1.getDestination().getDestNode().getValue());
213 final IgpLinkAttributes igpLink1 = link1.augmentation(Link1.class).getIgpLinkAttributes();
214 assertEquals("link1", igpLink1.getName());
215 assertEquals((short) 1, igpLink1.augmentation(IgpLinkAttributes1.class).getIsisLinkAttributes()
216 .getMultiTopologyId().shortValue());
217 assertNull(igpLink1.augmentation(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.ospf
218 .topology.rev131021.IgpLinkAttributes1.class));
219 assertEquals(LinkstateTopologyBuilder.SR_AWARE_LINKSTATE_TOPOLOGY_TYPE, topology.getTopologyTypes());
220 assertEquals(2, topology.getNode().size());
222 if (topology.getNode().values().iterator().next().getNodeId().getValue().contains("0000.0102.0304")) {
223 srcNode = topology.getNode().values().iterator().next();
225 srcNode = Iterables.get(topology.getNode().values(), 1);
227 assertEquals(1, srcNode.augmentation(
228 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Node1.class)
229 .getSegments().size());
230 assertEquals(ADJ_SID, link1.augmentation(
231 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Link1.class)
232 .getSegment().getValue().intValue());
235 removeLinkstateRoute(this.linkstateLinkRouteIID);
238 updateLinkstateRoute(this.linkstateNodeRouteIID,
239 createLinkstateNodeRoute(ProtocolId.IsisLevel2, "updated-node", NODE_1_AS, ROUTER_2_ID));
240 readDataOperational(getDataBroker(), this.linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
241 assertEquals(1, topology.getNode().size());
242 final IgpNodeAttributes igpNode2 = topology.getNode().values().iterator().next().augmentation(Node1.class)
243 .getIgpNodeAttributes();
244 assertEquals(ROUTER_2_ID, igpNode2.getRouterId().get(0).getIpv4Address().getValue());
245 assertEquals("updated-node", igpNode2.getName().getValue());
250 removeLinkstateRoute(this.linkstateNodeRouteIID);
251 readDataOperational(getDataBroker(), this.linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
252 assertEquals(LinkstateTopologyBuilder.LINKSTATE_TOPOLOGY_TYPE, topology.getTopologyTypes());
253 assertNull(topology.getNode());
254 assertNull(topology.getLink());
260 public void testOspfLinkstateTopologyBuilder() throws InterruptedException, ExecutionException {
262 updateLinkstateRoute(this.linkstateNodeRouteIID,
263 createLinkstateNodeRoute(ProtocolId.Ospf, "node1", NODE_1_AS, ROUTER_1_ID));
264 readDataOperational(getDataBroker(), this.linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
265 assertEquals(1, topology.nonnullNode().size());
266 final Node node1 = topology.nonnullNode().values().iterator().next();
267 assertEquals(NODE_1_OSPF_ID, node1.getNodeId().getValue());
268 final IgpNodeAttributes igpNode1 = node1.augmentation(Node1.class).getIgpNodeAttributes();
269 assertEquals(ROUTER_1_ID, igpNode1.getRouterId().get(0).getIpv4Address().getValue());
270 assertEquals("node1", igpNode1.getName().getValue());
271 assertNull(igpNode1.augmentation(IgpNodeAttributes1.class));
272 assertEquals(ROUTER_1_ID, igpNode1.augmentation(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns
273 .yang.ospf.topology.rev131021.IgpNodeAttributes1.class).getOspfNodeAttributes().getTed()
274 .getTeRouterIdIpv4().getValue());
275 assertEquals(LinkstateTopologyBuilder.LINKSTATE_TOPOLOGY_TYPE, topology.getTopologyTypes());
276 assertNull(node1.augmentation(
277 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Node1.class));
281 // update node with prefix
282 updateLinkstateRoute(this.linkstatePrefixRouteIID,
283 createLinkstatePrefixRoute(ProtocolId.Ospf, NODE_1_AS, NODE_1_PREFIX, 500L, ROUTER_1_ID));
284 readDataOperational(getDataBroker(), this.linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
285 final Node node1 = topology.nonnullNode().values().iterator().next();
286 final IgpNodeAttributes igpNode1 = node1.augmentation(Node1.class).getIgpNodeAttributes();
287 assertEquals(1, igpNode1.nonnullPrefix().size());
288 final Prefix prefix = igpNode1.nonnullPrefix().values().iterator().next();
289 assertEquals(NODE_1_PREFIX, prefix.getPrefix().getIpv4Prefix().getValue());
290 assertEquals(500L, prefix.getMetric().longValue());
291 assertEquals(LinkstateTopologyBuilder.SR_AWARE_LINKSTATE_TOPOLOGY_TYPE, topology.getTopologyTypes());
292 assertEquals(1, node1.augmentation(
293 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Node1.class)
294 .nonnullSegments().size());
295 assertEquals(SRGB_START + NODE_SID_INDEX, node1.augmentation(
296 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Node1.class)
297 .nonnullSegments().values().iterator().next().getSegmentId().getValue().intValue());
302 updateLinkstateRoute(this.linkstateLinkRouteIID,
303 createLinkstateLinkRoute(ProtocolId.Ospf, NODE_1_AS, NODE_2_AS, "link1"));
304 readDataOperational(getDataBroker(), this.linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
305 assertEquals(1, topology.nonnullLink().size());
306 final Link link1 = topology.nonnullLink().values().iterator().next();
307 assertEquals(2, topology.getNode().size());
308 assertEquals(1, Iterables.get(topology.getNode().values(), 0).getTerminationPoint().size());
309 assertEquals(1, Iterables.get(topology.getNode().values(), 1).getTerminationPoint().size());
310 assertEquals("bgpls://Ospf:1/type=link&local-as=1&local-router=0000.0102.0304&remote-as=2&mt=1",
311 link1.getLinkId().getValue());
312 assertEquals(NODE_1_OSPF_ID, link1.getSource().getSourceNode().getValue());
313 assertEquals(NODE_2_OSPF_ID, link1.getDestination().getDestNode().getValue());
314 final IgpLinkAttributes igpLink1 = link1.augmentation(Link1.class).getIgpLinkAttributes();
315 assertEquals("link1", igpLink1.getName());
316 assertNull(igpLink1.augmentation(IgpLinkAttributes1.class));
317 assertEquals((short) 1, igpLink1.augmentation(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang
318 .ospf.topology.rev131021.IgpLinkAttributes1.class).getOspfLinkAttributes().getMultiTopologyId()
320 assertEquals(2, igpLink1.augmentation(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns
321 .yang.ospf.topology.rev131021.IgpLinkAttributes1.class).getOspfLinkAttributes().getTed().getSrlg()
322 .getSrlgValues().size());
323 assertEquals(LinkstateTopologyBuilder.SR_AWARE_LINKSTATE_TOPOLOGY_TYPE, topology.getTopologyTypes());
324 assertEquals(2, topology.getNode().size());
326 if (topology.getNode().values().iterator().next().getNodeId().getValue().contains("0000.0102.0304")) {
327 srcNode = topology.getNode().values().iterator().next();
329 srcNode = Iterables.get(topology.getNode().values(), 1);
331 assertEquals(2, srcNode.augmentation(
332 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Node1.class)
333 .getSegments().size());
334 assertEquals(ADJ_SID, link1.augmentation(
335 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Link1.class)
336 .getSegment().getValue().intValue());
342 * This test is to verify if the AbstractTopologyBuilder/LinkstateTopologyBuilder is handling exception correctly.
345 @SuppressWarnings("checkstyle:IllegalCatch")
346 public void testRouteChangedError() throws Exception {
347 final LinkstateTopologyBuilder spiedLinkstateTopologyBuilder = spy(this.linkstateTopoBuilder);
348 doThrow(RuntimeException.class).when(spiedLinkstateTopologyBuilder).routeChanged(any(), any());
350 spiedLinkstateTopologyBuilder.routeChanged(null, null);
351 fail("Mockito failed to spy routeChanged() method");
352 } catch (final Exception e) {
353 assertTrue(e instanceof RuntimeException);
355 assertEquals(0L, spiedLinkstateTopologyBuilder.listenerScheduledRestartTime);
356 assertEquals(0L, spiedLinkstateTopologyBuilder.listenerScheduledRestartEnforceCounter);
357 // first we examine if the chain is being reset when no exception is thrown
358 spiedLinkstateTopologyBuilder.onDataTreeChanged(new ArrayList<>());
359 verify(spiedLinkstateTopologyBuilder, times(1)).restartTransactionChainOnDemand();
360 verify(spiedLinkstateTopologyBuilder, never()).scheduleListenerRestart();
361 verify(spiedLinkstateTopologyBuilder, never()).resetTransactionChain();
362 assertEquals(0L, spiedLinkstateTopologyBuilder.listenerScheduledRestartTime);
363 assertEquals(0L, spiedLinkstateTopologyBuilder.listenerScheduledRestartEnforceCounter);
364 // now pass some invalid data to cause onDataTreeChanged fail
365 final DataTreeModification<LinkstateRoute> modification = mock(DataTreeModification.class, RETURNS_SMART_NULLS);
366 final List<DataTreeModification<LinkstateRoute>> changes = new ArrayList<>();
367 changes.add(modification);
368 spiedLinkstateTopologyBuilder.onDataTreeChanged(changes);
369 // one restart transaction chain check in onDataTreeChanged()
370 // we are introducing some timeout here as transaction may be executed in a delay manner
371 verify(spiedLinkstateTopologyBuilder, timeout(5000).times(1)).scheduleListenerRestart();
372 verify(spiedLinkstateTopologyBuilder, times(2)).restartTransactionChainOnDemand();
373 assertNotEquals(0L, spiedLinkstateTopologyBuilder.listenerScheduledRestartTime);
374 assertEquals(0, spiedLinkstateTopologyBuilder.listenerScheduledRestartEnforceCounter);
375 final long listenerScheduledRestartTime = spiedLinkstateTopologyBuilder.listenerScheduledRestartTime;
376 // call again with empty change to invoke restartTransactionChainOnDemand()
377 spiedLinkstateTopologyBuilder.onDataTreeChanged(new ArrayList<>());
378 verify(spiedLinkstateTopologyBuilder, times(3)).restartTransactionChainOnDemand();
379 // transaction chain should be reset while listener should not
380 verify(spiedLinkstateTopologyBuilder, times(1)).resetTransactionChain();
381 verify(spiedLinkstateTopologyBuilder, never()).resetListener();
382 // now apply a change with bad modification again
383 spiedLinkstateTopologyBuilder.onDataTreeChanged(changes);
384 verify(spiedLinkstateTopologyBuilder, times(4)).restartTransactionChainOnDemand();
385 // listener scheduled again
386 verify(spiedLinkstateTopologyBuilder, timeout(5000).times(2)).scheduleListenerRestart();
387 // listener timer shouldn't have changed
388 assertEquals(listenerScheduledRestartTime, spiedLinkstateTopologyBuilder.listenerScheduledRestartTime);
389 assertEquals(0, spiedLinkstateTopologyBuilder.listenerScheduledRestartEnforceCounter);
390 verify(spiedLinkstateTopologyBuilder, times(2)).resetTransactionChain();
391 verify(spiedLinkstateTopologyBuilder, never()).resetListener();
392 Thread.sleep(LISTENER_RESTART_TIME);
393 // manually invoke onTransactionChainFailed() to have the listener restart scheduled again
394 spiedLinkstateTopologyBuilder.onTransactionChainFailed(null, null, null);
395 assertEquals(spiedLinkstateTopologyBuilder.listenerScheduledRestartTime, listenerScheduledRestartTime
396 + LISTENER_RESTART_TIME);
397 verify(spiedLinkstateTopologyBuilder, times(5)).restartTransactionChainOnDemand();
398 verify(spiedLinkstateTopologyBuilder, times(3)).scheduleListenerRestart();
399 // enforce counter get increased
400 assertEquals(1, spiedLinkstateTopologyBuilder.listenerScheduledRestartEnforceCounter);
401 verify(spiedLinkstateTopologyBuilder, times(3)).resetTransactionChain();
402 verify(spiedLinkstateTopologyBuilder, never()).resetListener();
403 // sleep to let the listener restart timer times out
404 Thread.sleep(LISTENER_RESTART_TIME);
405 // apply a good modification (empty change)
406 spiedLinkstateTopologyBuilder.onDataTreeChanged(new ArrayList<>());
407 assertEquals(0, spiedLinkstateTopologyBuilder.listenerScheduledRestartTime);
408 assertEquals(0, spiedLinkstateTopologyBuilder.listenerScheduledRestartEnforceCounter);
409 verify(spiedLinkstateTopologyBuilder, times(6)).restartTransactionChainOnDemand();
410 // listener restarted didn't get rescheduled again
411 verify(spiedLinkstateTopologyBuilder, times(3)).scheduleListenerRestart();
412 verify(spiedLinkstateTopologyBuilder, times(4)).resetTransactionChain();
413 verify(spiedLinkstateTopologyBuilder, times(1)).resetListener();
416 private static String getLinkstateRouteKey(final String routeKey) {
417 return Unpooled.wrappedBuffer(StandardCharsets.UTF_8.encode(routeKey)).array().toString();
420 private InstanceIdentifier<LinkstateRoute> createLinkstateRouteIID(final String linkstateRouteKey) {
421 return this.tablePathIID.builder().child(LinkstateRoutesCase.class, LinkstateRoutes.class)
422 .child(LinkstateRoute.class, new LinkstateRouteKey(new PathId(Uint32.ZERO), linkstateRouteKey)).build();
425 private void updateLinkstateRoute(final InstanceIdentifier<LinkstateRoute> linkstateRouteIID,
426 final LinkstateRoute data) {
427 final WriteTransaction wTx = getDataBroker().newWriteOnlyTransaction();
428 wTx.mergeParentStructurePut(LogicalDatastoreType.OPERATIONAL, linkstateRouteIID, data);
432 private void removeLinkstateRoute(final InstanceIdentifier<LinkstateRoute> linkstateRouteIID) {
433 final WriteTransaction wTx = getDataBroker().newWriteOnlyTransaction();
434 wTx.delete(LogicalDatastoreType.OPERATIONAL, linkstateRouteIID);
438 private LinkstateRoute createLinkstateNodeRoute(final ProtocolId protocolId, final String nodeName,
439 final AsNumber asNumber, final String ipv4RouterId) {
440 return createBaseBuilder(this.linkstateNodeRouteKey, protocolId)
441 .setObjectType(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate
442 .rev200120.linkstate.object.type.NodeCaseBuilder()
443 .setNodeDescriptors(new NodeDescriptorsBuilder()
444 .setCRouterIdentifier(new IsisNodeCaseBuilder().setIsisNode(new IsisNodeBuilder()
445 .setIsoSystemId(new IsoSystemIdentifier(new byte[]{0, 0, 1, 2, 3, 4})).build())
447 .setAsNumber(asNumber).build()).build())
448 .setAttributes(new AttributesBuilder()
449 .setOrigin(new OriginBuilder().setValue(BgpOrigin.Igp).build())
450 .addAugmentation(new Attributes1Builder()
451 .setLinkStateAttribute(new NodeAttributesCaseBuilder()
452 .setNodeAttributes(new NodeAttributesBuilder()
453 .setDynamicHostname(nodeName)
454 .setIpv4RouterId(new Ipv4RouterIdentifier(ipv4RouterId))
455 .setIsisAreaId(Collections.singletonList(
456 new IsisAreaIdentifier(new byte[]{0x47})))
457 .setSrCapabilities(new SrCapabilitiesBuilder()
458 .setRangeSize(new Uint24(Uint32.valueOf(SRGB_RANGE)))
459 .setSidLabelIndex(new LocalLabelCaseBuilder()
461 new MplsLabel(Uint32.valueOf(SRGB_START)))
464 .build()).build()).build()).build()).build();
467 private LinkstateRoute createLinkstatePrefixRoute(final ProtocolId protocolId, final AsNumber asNumber,
468 final String ipv4Prefix, final long igpMetric, final String ospfFwdAddress) {
469 return createBaseBuilder(this.linkstatePrefixRouteKey, protocolId)
470 .setObjectType(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120
471 .linkstate.object.type.PrefixCaseBuilder()
472 .setAdvertisingNodeDescriptors(new AdvertisingNodeDescriptorsBuilder()
473 .setCRouterIdentifier(new IsisNodeCaseBuilder().setIsisNode(new IsisNodeBuilder()
474 .setIsoSystemId(new IsoSystemIdentifier(new byte[]{0, 0, 1, 2, 3, 4})).build())
475 .build()).setAsNumber(asNumber).build())
476 .setPrefixDescriptors(new PrefixDescriptorsBuilder()
477 .setIpReachabilityInformation(new IpPrefix(new Ipv4Prefix(ipv4Prefix))).build()).build())
478 .setAttributes(new AttributesBuilder()
479 .setOrigin(new OriginBuilder().setValue(BgpOrigin.Igp).build())
480 .addAugmentation(new Attributes1Builder()
481 .setLinkStateAttribute(new PrefixAttributesCaseBuilder()
482 .setPrefixAttributes(new PrefixAttributesBuilder()
483 .setOspfForwardingAddress(new IpAddressNoZone(new Ipv4AddressNoZone(ospfFwdAddress)))
484 .setPrefixMetric(new IgpMetric(Uint32.valueOf(igpMetric)))
485 .setSrPrefix(new SrPrefixBuilder()
486 .setAlgorithm(Algorithm.ShortestPathFirst)
487 .setSidLabelIndex(new SidCaseBuilder()
488 .setSid(Uint32.valueOf(NODE_SID_INDEX)).build())
497 private LinkstateRoute createLinkstateLinkRoute(final ProtocolId protocolId, final AsNumber localAs,
498 final AsNumber remoteAs, final String linkName) {
499 return createBaseBuilder(this.linkstateLinkRouteKey, protocolId)
500 .setObjectType(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate
501 .rev200120.linkstate.object.type.LinkCaseBuilder()
502 .setLocalNodeDescriptors(new LocalNodeDescriptorsBuilder().setAsNumber(localAs)
503 .setCRouterIdentifier(new IsisNodeCaseBuilder().setIsisNode(new IsisNodeBuilder()
504 .setIsoSystemId(new IsoSystemIdentifier(new byte[]{0, 0, 1, 2, 3, 4}))
505 .build()).build()).build())
506 .setRemoteNodeDescriptors(new RemoteNodeDescriptorsBuilder().setAsNumber(remoteAs).build())
507 .setLinkDescriptors(new LinkDescriptorsBuilder()
508 .setMultiTopologyId(new TopologyIdentifier(Uint16.ONE)).build()).build())
509 .setAttributes(new AttributesBuilder()
510 .setOrigin(new OriginBuilder().setValue(BgpOrigin.Igp).build())
511 .addAugmentation(new Attributes1Builder()
512 .setLinkStateAttribute(new LinkAttributesCaseBuilder()
513 .setLinkAttributes(new LinkAttributesBuilder()
514 .setSharedRiskLinkGroups(Lists.newArrayList(
515 new SrlgId(Uint32.valueOf(5)), new SrlgId(Uint32.valueOf(15))))
516 .setAdminGroup(new AdministrativeGroup(Uint32.ZERO))
517 .setMaxLinkBandwidth(
518 new Bandwidth(new byte[]{0x00, 0x00, (byte) 0xff, (byte) 0xff}))
519 .setMaxReservableBandwidth(
520 new Bandwidth(new byte[]{0x00, 0x00, (byte) 0xff, (byte) 0x1f}))
521 .setUnreservedBandwidth(Lists.newArrayList(new UnreservedBandwidthBuilder()
522 .withKey(new UnreservedBandwidthKey(Uint8.ONE))
523 .setBandwidth(new Bandwidth(new byte[]{0x00, 0x00, 0x00, (byte) 0xff}))
525 .setTeMetric(new TeMetric(Uint32.valueOf(100)))
526 .setLinkName(linkName)
527 .setSrAdjIds(Collections.singletonList(new SrAdjIdsBuilder()
528 .setSidLabelIndex(new LocalLabelCaseBuilder()
529 .setLocalLabel(new MplsLabel(Uint32.valueOf(ADJ_SID)))
539 private static LinkstateRouteBuilder createBaseBuilder(final String linkstateRouteKey,
540 final ProtocolId protocolId) {
541 return new LinkstateRouteBuilder()
542 .setIdentifier(IDENTIFIER)
543 .withKey(new LinkstateRouteKey(new PathId(Uint32.ZERO), linkstateRouteKey))
544 .setRouteKey(linkstateRouteKey)
545 .setProtocolId(protocolId);