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.ImmutableSet;
28 import com.google.common.collect.Iterables;
29 import io.netty.buffer.Unpooled;
30 import java.nio.charset.StandardCharsets;
31 import java.util.ArrayList;
32 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.ietf.params.xml.ns.yang.ietf.routing.types.rev171204.Uint24;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.AdministrativeGroup;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.Identifier;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.Ipv4RouterIdentifier;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.IsisAreaIdentifier;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.LinkstateAddressFamily;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.LinkstateSubsequentAddressFamily;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.ProtocolId;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.TopologyIdentifier;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.bgp.rib.rib.loc.rib.tables.routes.LinkstateRoutesCase;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.attribute.SrAdjIdsBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.attribute.UnreservedBandwidthBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.attribute.UnreservedBandwidthKey;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.link._case.LinkDescriptorsBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.link._case.LocalNodeDescriptorsBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.link._case.RemoteNodeDescriptorsBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.node._case.NodeDescriptorsBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.prefix._case.AdvertisingNodeDescriptorsBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.object.type.prefix._case.PrefixDescriptorsBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.LinkAttributesCaseBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.NodeAttributesCaseBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.path.attribute.link.state.attribute.PrefixAttributesCaseBuilder;
68 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;
69 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;
70 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;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.LinkstateRoutes;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.linkstate.routes.LinkstateRoute;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.linkstate.routes.LinkstateRouteBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.linkstate.routes.LinkstateRouteKey;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.linkstate.routes.linkstate.routes.linkstate.route.Attributes1Builder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.node.identifier.c.router.identifier.IsisNodeCaseBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.node.identifier.c.router.identifier.isis.node._case.IsisNodeBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.node.state.SrCapabilitiesBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.prefix.state.SrPrefixBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.PathId;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.AttributesBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.attributes.OriginBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.rib.LocRib;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.Tables;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.Algorithm;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.sid.label.index.sid.label.index.LocalLabelCaseBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.segment.routing.ext.rev200120.sid.label.index.sid.label.index.SidCaseBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.BgpOrigin;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.Bandwidth;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.IgpMetric;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.IsoSystemIdentifier;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.MplsLabel;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.TeMetric;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.SrlgId;
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.binding.util.BindingMap;
107 import org.opendaylight.yangtools.yang.common.Uint16;
108 import org.opendaylight.yangtools.yang.common.Uint32;
109 import org.opendaylight.yangtools.yang.common.Uint64;
110 import org.opendaylight.yangtools.yang.common.Uint8;
112 public class LinkstateTopologyBuilderTest extends AbstractTopologyBuilderTest {
114 private static final String ROUTER_1_ID = "127.0.0.1";
115 private static final String ROUTER_2_ID = "127.0.0.2";
116 private static final String NODE_1_PREFIX = "127.0.1.1/32";
117 private static final AsNumber NODE_1_AS = new AsNumber(Uint32.ONE);
118 private static final AsNumber NODE_2_AS = new AsNumber(Uint32.TWO);
119 private static final String NODE_1_ISIS_ID = "bgpls://IsisLevel2:1/type=node&as=1&router=0000.0102.0304";
120 private static final String NODE_2_ISIS_ID = "bgpls://IsisLevel2:1/type=node&as=2";
121 private static final String NODE_1_OSPF_ID = "bgpls://Ospf:1/type=node&as=1&router=0000.0102.0304";
122 private static final String NODE_2_OSPF_ID = "bgpls://Ospf:1/type=node&as=2";
123 private static final Identifier IDENTIFIER = new Identifier(Uint64.ONE);
124 private static final long LISTENER_RESTART_TIME = 20000;
125 private static final int LISTENER_ENFORCE_COUNTER = 2;
126 private static final int SRGB_START = 90000;
127 private static final int SRGB_RANGE = 16;
128 private static final int NODE_SID_INDEX = 4;
129 private static final int ADJ_SID = 24001;
131 private LinkstateTopologyBuilder linkstateTopoBuilder;
132 private InstanceIdentifier<Tables> tablePathIID;
133 private String linkstateNodeRouteKey;
134 private String linkstatePrefixRouteKey;
135 private String linkstateLinkRouteKey;
136 private InstanceIdentifier<LinkstateRoute> linkstateNodeRouteIID;
137 private InstanceIdentifier<LinkstateRoute> linkstatePrefixRouteIID;
138 private InstanceIdentifier<LinkstateRoute> linkstateLinkRouteIID;
142 public void setUp() {
144 linkstateTopoBuilder = new LinkstateTopologyBuilder(getDataBroker(), LOC_RIB_REF, TEST_TOPOLOGY_ID,
145 LISTENER_RESTART_TIME, LISTENER_ENFORCE_COUNTER);
146 linkstateTopoBuilder.start();
148 LOC_RIB_REF.getInstanceIdentifier().builder().child(LocRib.class)
150 new TablesKey(LinkstateAddressFamily.VALUE, LinkstateSubsequentAddressFamily.VALUE))
152 linkstateNodeRouteKey = getLinkstateRouteKey("node-route");
153 linkstatePrefixRouteKey = getLinkstateRouteKey("prefix-route");
154 linkstateLinkRouteKey = getLinkstateRouteKey("link-route");
155 linkstateNodeRouteIID = createLinkstateRouteIID(linkstateNodeRouteKey);
156 linkstatePrefixRouteIID = createLinkstateRouteIID(linkstatePrefixRouteKey);
157 linkstateLinkRouteIID = createLinkstateRouteIID(linkstateLinkRouteKey);
161 public void tearDown() throws Exception {
162 linkstateTopoBuilder.close();
163 checkNotPresentOperational(getDataBroker(), linkstateTopoBuilder.getInstanceIdentifier());
167 public void testLinkstateTopologyBuilderTopologyTypes() throws InterruptedException, ExecutionException {
168 readDataOperational(getDataBroker(), linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
169 assertEquals(LinkstateTopologyBuilder.LINKSTATE_TOPOLOGY_TYPE, topology.getTopologyTypes());
175 public void testIsisLinkstateTopologyBuilder() throws InterruptedException, ExecutionException {
177 updateLinkstateRoute(linkstateNodeRouteIID,
178 createLinkstateNodeRoute(ProtocolId.IsisLevel2, "node1", NODE_1_AS, ROUTER_1_ID));
179 readDataOperational(getDataBroker(), linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
180 assertEquals(1, topology.nonnullNode().size());
181 final Node node1 = topology.nonnullNode().values().iterator().next();
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().iterator().next().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().iterator().next().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(linkstateLinkRouteIID,
203 createLinkstateLinkRoute(ProtocolId.IsisLevel2, NODE_1_AS, NODE_2_AS, "link1"));
204 readDataOperational(getDataBroker(), linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
205 assertEquals(1, topology.nonnullLink().size());
206 final Link link1 = topology.nonnullLink().values().iterator().next();
207 assertEquals(2, topology.nonnullNode().size());
208 assertEquals(1, Iterables.get(topology.getNode().values(), 0).getTerminationPoint().size());
209 assertEquals(1, Iterables.get(topology.getNode().values(), 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().values().iterator().next().getNodeId().getValue().contains("0000.0102.0304")) {
224 srcNode = topology.getNode().values().iterator().next();
226 srcNode = Iterables.get(topology.getNode().values(), 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(linkstateLinkRouteIID);
239 updateLinkstateRoute(linkstateNodeRouteIID,
240 createLinkstateNodeRoute(ProtocolId.IsisLevel2, "updated-node", NODE_1_AS, ROUTER_2_ID));
241 readDataOperational(getDataBroker(), linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
242 assertEquals(1, topology.getNode().size());
243 final IgpNodeAttributes igpNode2 = topology.getNode().values().iterator().next().augmentation(Node1.class)
244 .getIgpNodeAttributes();
245 assertEquals(ROUTER_2_ID, igpNode2.getRouterId().iterator().next().getIpv4Address().getValue());
246 assertEquals("updated-node", igpNode2.getName().getValue());
251 removeLinkstateRoute(linkstateNodeRouteIID);
252 readDataOperational(getDataBroker(), linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
253 assertEquals(LinkstateTopologyBuilder.LINKSTATE_TOPOLOGY_TYPE, topology.getTopologyTypes());
254 assertNull(topology.getNode());
255 assertNull(topology.getLink());
261 public void testOspfLinkstateTopologyBuilder() throws InterruptedException, ExecutionException {
263 updateLinkstateRoute(linkstateNodeRouteIID,
264 createLinkstateNodeRoute(ProtocolId.Ospf, "node1", NODE_1_AS, ROUTER_1_ID));
265 readDataOperational(getDataBroker(), linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
266 assertEquals(1, topology.nonnullNode().size());
267 final Node node1 = topology.nonnullNode().values().iterator().next();
268 assertEquals(NODE_1_OSPF_ID, node1.getNodeId().getValue());
269 final IgpNodeAttributes igpNode1 = node1.augmentation(Node1.class).getIgpNodeAttributes();
270 assertEquals(ROUTER_1_ID, igpNode1.getRouterId().iterator().next().getIpv4Address().getValue());
271 assertEquals("node1", igpNode1.getName().getValue());
272 assertNull(igpNode1.augmentation(IgpNodeAttributes1.class));
273 assertEquals(ROUTER_1_ID, igpNode1.augmentation(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns
274 .yang.ospf.topology.rev131021.IgpNodeAttributes1.class).getOspfNodeAttributes().getTed()
275 .getTeRouterIdIpv4().getValue());
276 assertEquals(LinkstateTopologyBuilder.LINKSTATE_TOPOLOGY_TYPE, topology.getTopologyTypes());
277 assertNull(node1.augmentation(
278 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Node1.class));
282 // update node with prefix
283 updateLinkstateRoute(linkstatePrefixRouteIID,
284 createLinkstatePrefixRoute(ProtocolId.Ospf, NODE_1_AS, NODE_1_PREFIX, 500L, ROUTER_1_ID));
285 readDataOperational(getDataBroker(), linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
286 final Node node1 = topology.nonnullNode().values().iterator().next();
287 final IgpNodeAttributes igpNode1 = node1.augmentation(Node1.class).getIgpNodeAttributes();
288 assertEquals(1, igpNode1.nonnullPrefix().size());
289 final Prefix prefix = igpNode1.nonnullPrefix().values().iterator().next();
290 assertEquals(NODE_1_PREFIX, prefix.getPrefix().getIpv4Prefix().getValue());
291 assertEquals(500L, prefix.getMetric().longValue());
292 assertEquals(LinkstateTopologyBuilder.SR_AWARE_LINKSTATE_TOPOLOGY_TYPE, topology.getTopologyTypes());
293 assertEquals(1, node1.augmentation(
294 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Node1.class)
295 .nonnullSegments().size());
296 assertEquals(SRGB_START + NODE_SID_INDEX, node1.augmentation(
297 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Node1.class)
298 .nonnullSegments().values().iterator().next().getSegmentId().getValue().intValue());
303 updateLinkstateRoute(linkstateLinkRouteIID,
304 createLinkstateLinkRoute(ProtocolId.Ospf, NODE_1_AS, NODE_2_AS, "link1"));
305 readDataOperational(getDataBroker(), linkstateTopoBuilder.getInstanceIdentifier(), topology -> {
306 assertEquals(1, topology.nonnullLink().size());
307 final Link link1 = topology.nonnullLink().values().iterator().next();
308 assertEquals(2, topology.getNode().size());
309 assertEquals(1, Iterables.get(topology.getNode().values(), 0).getTerminationPoint().size());
310 assertEquals(1, Iterables.get(topology.getNode().values(), 1).getTerminationPoint().size());
311 assertEquals("bgpls://Ospf:1/type=link&local-as=1&local-router=0000.0102.0304&remote-as=2&mt=1",
312 link1.getLinkId().getValue());
313 assertEquals(NODE_1_OSPF_ID, link1.getSource().getSourceNode().getValue());
314 assertEquals(NODE_2_OSPF_ID, link1.getDestination().getDestNode().getValue());
315 final IgpLinkAttributes igpLink1 = link1.augmentation(Link1.class).getIgpLinkAttributes();
316 assertEquals("link1", igpLink1.getName());
317 assertNull(igpLink1.augmentation(IgpLinkAttributes1.class));
318 assertEquals((short) 1, igpLink1.augmentation(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang
319 .ospf.topology.rev131021.IgpLinkAttributes1.class).getOspfLinkAttributes().getMultiTopologyId()
321 assertEquals(2, igpLink1.augmentation(org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns
322 .yang.ospf.topology.rev131021.IgpLinkAttributes1.class).getOspfLinkAttributes().getTed().getSrlg()
323 .getSrlgValues().size());
324 assertEquals(LinkstateTopologyBuilder.SR_AWARE_LINKSTATE_TOPOLOGY_TYPE, topology.getTopologyTypes());
325 assertEquals(2, topology.getNode().size());
327 if (topology.getNode().values().iterator().next().getNodeId().getValue().contains("0000.0102.0304")) {
328 srcNode = topology.getNode().values().iterator().next();
330 srcNode = Iterables.get(topology.getNode().values(), 1);
332 assertEquals(2, srcNode.augmentation(
333 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Node1.class)
334 .getSegments().size());
335 assertEquals(ADJ_SID, link1.augmentation(
336 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.sr.rev130819.Link1.class)
337 .getSegment().getValue().intValue());
343 * This test is to verify if the AbstractTopologyBuilder/LinkstateTopologyBuilder is handling exception correctly.
346 @SuppressWarnings("checkstyle:IllegalCatch")
347 public void testRouteChangedError() throws Exception {
348 final LinkstateTopologyBuilder spiedLinkstateTopologyBuilder = spy(linkstateTopoBuilder);
349 doThrow(RuntimeException.class).when(spiedLinkstateTopologyBuilder).routeChanged(any(), any());
351 spiedLinkstateTopologyBuilder.routeChanged(null, null);
352 fail("Mockito failed to spy routeChanged() method");
353 } catch (final Exception e) {
354 assertTrue(e instanceof RuntimeException);
356 assertEquals(0L, spiedLinkstateTopologyBuilder.listenerScheduledRestartTime);
357 assertEquals(0L, spiedLinkstateTopologyBuilder.listenerScheduledRestartEnforceCounter);
358 // first we examine if the chain is being reset when no exception is thrown
359 spiedLinkstateTopologyBuilder.onDataTreeChanged(new ArrayList<>());
360 verify(spiedLinkstateTopologyBuilder, times(1)).restartTransactionChainOnDemand();
361 verify(spiedLinkstateTopologyBuilder, never()).scheduleListenerRestart();
362 verify(spiedLinkstateTopologyBuilder, never()).resetTransactionChain();
363 assertEquals(0L, spiedLinkstateTopologyBuilder.listenerScheduledRestartTime);
364 assertEquals(0L, spiedLinkstateTopologyBuilder.listenerScheduledRestartEnforceCounter);
365 // now pass some invalid data to cause onDataTreeChanged fail
366 final DataTreeModification<LinkstateRoute> modification = mock(DataTreeModification.class, RETURNS_SMART_NULLS);
367 final List<DataTreeModification<LinkstateRoute>> changes = new ArrayList<>();
368 changes.add(modification);
369 spiedLinkstateTopologyBuilder.onDataTreeChanged(changes);
370 // one restart transaction chain check in onDataTreeChanged()
371 // we are introducing some timeout here as transaction may be executed in a delay manner
372 verify(spiedLinkstateTopologyBuilder, timeout(5000).times(1)).scheduleListenerRestart();
373 verify(spiedLinkstateTopologyBuilder, times(2)).restartTransactionChainOnDemand();
374 assertNotEquals(0L, spiedLinkstateTopologyBuilder.listenerScheduledRestartTime);
375 assertEquals(0, spiedLinkstateTopologyBuilder.listenerScheduledRestartEnforceCounter);
376 final long listenerScheduledRestartTime = spiedLinkstateTopologyBuilder.listenerScheduledRestartTime;
377 // call again with empty change to invoke restartTransactionChainOnDemand()
378 spiedLinkstateTopologyBuilder.onDataTreeChanged(new ArrayList<>());
379 verify(spiedLinkstateTopologyBuilder, times(3)).restartTransactionChainOnDemand();
380 // transaction chain should be reset while listener should not
381 verify(spiedLinkstateTopologyBuilder, times(1)).resetTransactionChain();
382 verify(spiedLinkstateTopologyBuilder, never()).resetListener();
383 // now apply a change with bad modification again
384 spiedLinkstateTopologyBuilder.onDataTreeChanged(changes);
385 verify(spiedLinkstateTopologyBuilder, times(4)).restartTransactionChainOnDemand();
386 // listener scheduled again
387 verify(spiedLinkstateTopologyBuilder, timeout(5000).times(2)).scheduleListenerRestart();
388 // listener timer shouldn't have changed
389 assertEquals(listenerScheduledRestartTime, spiedLinkstateTopologyBuilder.listenerScheduledRestartTime);
390 assertEquals(0, spiedLinkstateTopologyBuilder.listenerScheduledRestartEnforceCounter);
391 verify(spiedLinkstateTopologyBuilder, times(2)).resetTransactionChain();
392 verify(spiedLinkstateTopologyBuilder, never()).resetListener();
393 Thread.sleep(LISTENER_RESTART_TIME);
394 // manually invoke onTransactionChainFailed() to have the listener restart scheduled again
395 spiedLinkstateTopologyBuilder.onTransactionChainFailed(null, null, null);
396 assertEquals(spiedLinkstateTopologyBuilder.listenerScheduledRestartTime, listenerScheduledRestartTime
397 + LISTENER_RESTART_TIME);
398 verify(spiedLinkstateTopologyBuilder, times(5)).restartTransactionChainOnDemand();
399 verify(spiedLinkstateTopologyBuilder, times(3)).scheduleListenerRestart();
400 // enforce counter get increased
401 assertEquals(1, spiedLinkstateTopologyBuilder.listenerScheduledRestartEnforceCounter);
402 verify(spiedLinkstateTopologyBuilder, times(3)).resetTransactionChain();
403 verify(spiedLinkstateTopologyBuilder, never()).resetListener();
404 // sleep to let the listener restart timer times out
405 Thread.sleep(LISTENER_RESTART_TIME);
406 // apply a good modification (empty change)
407 spiedLinkstateTopologyBuilder.onDataTreeChanged(new ArrayList<>());
408 assertEquals(0, spiedLinkstateTopologyBuilder.listenerScheduledRestartTime);
409 assertEquals(0, spiedLinkstateTopologyBuilder.listenerScheduledRestartEnforceCounter);
410 verify(spiedLinkstateTopologyBuilder, times(6)).restartTransactionChainOnDemand();
411 // listener restarted didn't get rescheduled again
412 verify(spiedLinkstateTopologyBuilder, times(3)).scheduleListenerRestart();
413 verify(spiedLinkstateTopologyBuilder, times(4)).resetTransactionChain();
414 verify(spiedLinkstateTopologyBuilder, times(1)).resetListener();
417 private static String getLinkstateRouteKey(final String routeKey) {
418 return Unpooled.wrappedBuffer(StandardCharsets.UTF_8.encode(routeKey)).array().toString();
421 private InstanceIdentifier<LinkstateRoute> createLinkstateRouteIID(final String linkstateRouteKey) {
422 return tablePathIID.builder().child(LinkstateRoutesCase.class, LinkstateRoutes.class)
423 .child(LinkstateRoute.class, new LinkstateRouteKey(new PathId(Uint32.ZERO), linkstateRouteKey)).build();
426 private void updateLinkstateRoute(final InstanceIdentifier<LinkstateRoute> linkstateRouteIID,
427 final LinkstateRoute data) {
428 final WriteTransaction wTx = getDataBroker().newWriteOnlyTransaction();
429 wTx.mergeParentStructurePut(LogicalDatastoreType.OPERATIONAL, linkstateRouteIID, data);
433 private void removeLinkstateRoute(final InstanceIdentifier<LinkstateRoute> linkstateRouteIID) {
434 final WriteTransaction wTx = getDataBroker().newWriteOnlyTransaction();
435 wTx.delete(LogicalDatastoreType.OPERATIONAL, linkstateRouteIID);
439 private LinkstateRoute createLinkstateNodeRoute(final ProtocolId protocolId, final String nodeName,
440 final AsNumber asNumber, final String ipv4RouterId) {
441 return createBaseBuilder(linkstateNodeRouteKey, protocolId)
442 .setObjectType(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate
443 .rev200120.linkstate.object.type.NodeCaseBuilder()
444 .setNodeDescriptors(new NodeDescriptorsBuilder()
445 .setCRouterIdentifier(new IsisNodeCaseBuilder().setIsisNode(new IsisNodeBuilder()
446 .setIsoSystemId(new IsoSystemIdentifier(new byte[]{0, 0, 1, 2, 3, 4})).build())
448 .setAsNumber(asNumber).build()).build())
449 .setAttributes(new AttributesBuilder()
450 .setOrigin(new OriginBuilder().setValue(BgpOrigin.Igp).build())
451 .addAugmentation(new Attributes1Builder()
452 .setLinkStateAttribute(new NodeAttributesCaseBuilder()
453 .setNodeAttributes(new NodeAttributesBuilder()
454 .setDynamicHostname(nodeName)
455 .setIpv4RouterId(new Ipv4RouterIdentifier(ipv4RouterId))
456 .setIsisAreaId(Set.of(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(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(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(ImmutableSet.of(
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(BindingMap.of(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(List.of(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);