Priyanka B
Committed by Gerrit Code Review

[ONOS-4167] Identify the impacted tunnels based on network events, reilency with UT

Change-Id: I2bae0b789a22b8a6854f4e12b692d03cd6f7415d
...@@ -52,6 +52,7 @@ import org.onosproject.incubator.net.tunnel.TunnelId; ...@@ -52,6 +52,7 @@ import org.onosproject.incubator.net.tunnel.TunnelId;
52 import org.onosproject.incubator.net.tunnel.TunnelListener; 52 import org.onosproject.incubator.net.tunnel.TunnelListener;
53 import org.onosproject.incubator.net.tunnel.TunnelName; 53 import org.onosproject.incubator.net.tunnel.TunnelName;
54 import org.onosproject.incubator.net.tunnel.TunnelService; 54 import org.onosproject.incubator.net.tunnel.TunnelService;
55 +import org.onosproject.mastership.MastershipService;
55 import org.onosproject.net.DefaultAnnotations; 56 import org.onosproject.net.DefaultAnnotations;
56 import org.onosproject.net.DefaultAnnotations.Builder; 57 import org.onosproject.net.DefaultAnnotations.Builder;
57 import org.onosproject.net.Device; 58 import org.onosproject.net.Device;
...@@ -63,6 +64,7 @@ import org.onosproject.net.flowobjective.FlowObjectiveService; ...@@ -63,6 +64,7 @@ import org.onosproject.net.flowobjective.FlowObjectiveService;
63 import org.onosproject.net.flowobjective.Objective; 64 import org.onosproject.net.flowobjective.Objective;
64 import org.onosproject.net.intent.Constraint; 65 import org.onosproject.net.intent.Constraint;
65 import org.onosproject.net.intent.constraint.BandwidthConstraint; 66 import org.onosproject.net.intent.constraint.BandwidthConstraint;
67 +import org.onosproject.net.link.LinkEvent;
66 import org.onosproject.pce.pceservice.constraint.CapabilityConstraint; 68 import org.onosproject.pce.pceservice.constraint.CapabilityConstraint;
67 import org.onosproject.pce.pceservice.constraint.CapabilityConstraint.CapabilityType; 69 import org.onosproject.pce.pceservice.constraint.CapabilityConstraint.CapabilityType;
68 import org.onosproject.pce.pceservice.constraint.CostConstraint; 70 import org.onosproject.pce.pceservice.constraint.CostConstraint;
...@@ -76,6 +78,9 @@ import org.onosproject.net.resource.Resources; ...@@ -76,6 +78,9 @@ import org.onosproject.net.resource.Resources;
76 import org.onosproject.net.topology.LinkWeight; 78 import org.onosproject.net.topology.LinkWeight;
77 import org.onosproject.net.topology.PathService; 79 import org.onosproject.net.topology.PathService;
78 import org.onosproject.net.topology.TopologyEdge; 80 import org.onosproject.net.topology.TopologyEdge;
81 +import org.onosproject.net.topology.TopologyEvent;
82 +import org.onosproject.net.topology.TopologyListener;
83 +import org.onosproject.net.topology.TopologyService;
79 import org.onosproject.pce.pceservice.api.PceService; 84 import org.onosproject.pce.pceservice.api.PceService;
80 import org.onosproject.pce.pcestore.PcePathInfo; 85 import org.onosproject.pce.pcestore.PcePathInfo;
81 import org.onosproject.pce.pcestore.PceccTunnelInfo; 86 import org.onosproject.pce.pcestore.PceccTunnelInfo;
...@@ -171,12 +176,19 @@ public class PceManager implements PceService { ...@@ -171,12 +176,19 @@ public class PceManager implements PceService {
171 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 176 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
172 protected FlowObjectiveService flowObjectiveService; 177 protected FlowObjectiveService flowObjectiveService;
173 178
179 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
180 + protected MastershipService mastershipService;
181 +
182 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
183 + protected TopologyService topologyService;
184 +
174 private TunnelListener listener = new InnerTunnelListener(); 185 private TunnelListener listener = new InnerTunnelListener();
175 private BasicPceccHandler crHandler; 186 private BasicPceccHandler crHandler;
176 private PceccSrTeBeHandler srTeHandler; 187 private PceccSrTeBeHandler srTeHandler;
177 private ApplicationId appId; 188 private ApplicationId appId;
178 189
179 private final PcepPacketProcessor processor = new PcepPacketProcessor(); 190 private final PcepPacketProcessor processor = new PcepPacketProcessor();
191 + private final TopologyListener topologyListener = new InternalTopologyListener();
180 192
181 /** 193 /**
182 * Creates new instance of PceManager. 194 * Creates new instance of PceManager.
...@@ -204,6 +216,7 @@ public class PceManager implements PceService { ...@@ -204,6 +216,7 @@ public class PceManager implements PceService {
204 .asDistributedSet(); 216 .asDistributedSet();
205 217
206 packetService.addProcessor(processor, PacketProcessor.director(4)); 218 packetService.addProcessor(processor, PacketProcessor.director(4));
219 + topologyService.addListener(topologyListener);
207 log.info("Started"); 220 log.info("Started");
208 } 221 }
209 222
...@@ -211,6 +224,7 @@ public class PceManager implements PceService { ...@@ -211,6 +224,7 @@ public class PceManager implements PceService {
211 protected void deactivate() { 224 protected void deactivate() {
212 tunnelService.removeListener(listener); 225 tunnelService.removeListener(listener);
213 packetService.removeProcessor(processor); 226 packetService.removeProcessor(processor);
227 + topologyService.removeListener(topologyListener);
214 log.info("Stopped"); 228 log.info("Stopped");
215 } 229 }
216 230
...@@ -395,6 +409,7 @@ public class PceManager implements PceService { ...@@ -395,6 +409,7 @@ public class PceManager implements PceService {
395 List<Link> links = tunnel.path().links(); 409 List<Link> links = tunnel.path().links();
396 String lspSigType = tunnel.annotations().value(LSP_SIG_TYPE); 410 String lspSigType = tunnel.annotations().value(LSP_SIG_TYPE);
397 double bwConstraintValue = 0; 411 double bwConstraintValue = 0;
412 + String costType = null;
398 SharedBandwidthConstraint shBwConstraint = null; 413 SharedBandwidthConstraint shBwConstraint = null;
399 BandwidthConstraint bwConstraint = null; 414 BandwidthConstraint bwConstraint = null;
400 CostConstraint costConstraint = null; 415 CostConstraint costConstraint = null;
...@@ -409,6 +424,7 @@ public class PceManager implements PceService { ...@@ -409,6 +424,7 @@ public class PceManager implements PceService {
409 bwConstraintValue = bwConstraint.bandwidth().bps(); 424 bwConstraintValue = bwConstraint.bandwidth().bps();
410 } else if (constraint instanceof CostConstraint) { 425 } else if (constraint instanceof CostConstraint) {
411 costConstraint = (CostConstraint) constraint; 426 costConstraint = (CostConstraint) constraint;
427 + costType = costConstraint.type().name();
412 } 428 }
413 } 429 }
414 430
...@@ -454,6 +470,9 @@ public class PceManager implements PceService { ...@@ -454,6 +470,9 @@ public class PceManager implements PceService {
454 470
455 Builder annotationBuilder = DefaultAnnotations.builder(); 471 Builder annotationBuilder = DefaultAnnotations.builder();
456 annotationBuilder.set(BANDWIDTH, String.valueOf(bwConstraintValue)); 472 annotationBuilder.set(BANDWIDTH, String.valueOf(bwConstraintValue));
473 + if (costType != null) {
474 + annotationBuilder.set(COST_TYPE, costType);
475 + }
457 annotationBuilder.set(LSP_SIG_TYPE, lspSigType); 476 annotationBuilder.set(LSP_SIG_TYPE, lspSigType);
458 annotationBuilder.set(PCE_INIT, TRUE); 477 annotationBuilder.set(PCE_INIT, TRUE);
459 annotationBuilder.set(DELEGATE, TRUE); 478 annotationBuilder.set(DELEGATE, TRUE);
...@@ -594,8 +613,61 @@ public class PceManager implements PceService { ...@@ -594,8 +613,61 @@ public class PceManager implements PceService {
594 } 613 }
595 } 614 }
596 615
616 + //TODO: annotations used for temporarily later projection/network config will be used
617 + private class InternalTopologyListener implements TopologyListener {
618 + @Override
619 + public void event(TopologyEvent event) {
620 + event.reasons().forEach(e -> {
621 + //If event type is link removed, get the impacted tunnel
622 + if (e instanceof LinkEvent) {
623 + LinkEvent linkEvent = (LinkEvent) e;
624 + if (linkEvent.type() == LinkEvent.Type.LINK_REMOVED) {
625 + tunnelService.queryTunnel(MPLS).forEach(t -> {
626 + if (t.path().links().contains(((Link) e.subject()))) {
627 + // Check whether this ONOS instance is master for ingress device if yes,
628 + // recompute and send update
629 + checkForMasterAndUpdateTunnel(t.path().src().deviceId(), t);
630 + }
631 + });
632 + }
633 + }
634 + });
635 + }
636 + }
637 +
638 + private boolean checkForMasterAndUpdateTunnel(DeviceId src, Tunnel tunnel) {
639 + /**
640 + * Master of ingress node will recompute and also delegation flag must be set.
641 + */
642 + if (mastershipService.isLocalMaster(src)
643 + && Boolean.valueOf(tunnel.annotations().value(DELEGATE)) != null) {
644 + LinkedList<Constraint> constraintList = new LinkedList<>();
645 +
646 + if (tunnel.annotations().value(BANDWIDTH) != null) {
647 + //Requested bandwidth will be same as previous allocated bandwidth for the tunnel
648 + BandwidthConstraint localConst = new BandwidthConstraint(Bandwidth.bps(Double.parseDouble(tunnel
649 + .annotations().value(BANDWIDTH))));
650 + constraintList.add(localConst);
651 + }
652 + if (tunnel.annotations().value(COST_TYPE) != null) {
653 + constraintList.add(CostConstraint.of(CostConstraint.Type.valueOf(tunnel.annotations().value(
654 + COST_TYPE))));
655 + }
656 + if (!updatePath(tunnel.tunnelId(), constraintList)) {
657 + // If updation fails store in PCE store as failed path
658 + // then PCInitiate (Remove)
659 + pceStore.addFailedPathInfo(new PcePathInfo(tunnel.path().src().deviceId(), tunnel
660 + .path().dst().deviceId(), tunnel.tunnelName().value(), constraintList,
661 + LspType.valueOf(tunnel.annotations().value(LSP_SIG_TYPE))));
662 + //Release that tunnel calling PCInitiate
663 + releasePath(tunnel.tunnelId());
664 + }
665 + }
666 +
667 + return false;
668 + }
597 669
598 - // Allocates the bandwidth locally for PCECC tunnels. 670 + // Allocates the bandwidth locally for PCECC tunnels.
599 private TunnelConsumerId reserveBandwidth(Path computedPath, double bandwidthConstraint, 671 private TunnelConsumerId reserveBandwidth(Path computedPath, double bandwidthConstraint,
600 SharedBandwidthConstraint shBwConstraint) { 672 SharedBandwidthConstraint shBwConstraint) {
601 checkNotNull(computedPath); 673 checkNotNull(computedPath);
......
...@@ -15,10 +15,15 @@ import static org.onosproject.pce.pceservice.PathComputationTest.D1; ...@@ -15,10 +15,15 @@ import static org.onosproject.pce.pceservice.PathComputationTest.D1;
15 import static org.onosproject.pce.pceservice.PathComputationTest.D2; 15 import static org.onosproject.pce.pceservice.PathComputationTest.D2;
16 import static org.onosproject.pce.pceservice.PathComputationTest.D3; 16 import static org.onosproject.pce.pceservice.PathComputationTest.D3;
17 import static org.onosproject.pce.pceservice.PathComputationTest.D4; 17 import static org.onosproject.pce.pceservice.PathComputationTest.D4;
18 +import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE1;
19 +import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE2;
20 +import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE3;
21 +import static org.onosproject.pce.pceservice.PathComputationTest.DEVICE4;
18 import static org.onosproject.pce.pceservice.PcepAnnotationKeys.LOCAL_LSP_ID; 22 import static org.onosproject.pce.pceservice.PcepAnnotationKeys.LOCAL_LSP_ID;
19 import static org.onosproject.pce.pceservice.PcepAnnotationKeys.PLSP_ID; 23 import static org.onosproject.pce.pceservice.PcepAnnotationKeys.PLSP_ID;
20 import static org.onosproject.incubator.net.tunnel.Tunnel.State.UNSTABLE; 24 import static org.onosproject.incubator.net.tunnel.Tunnel.State.UNSTABLE;
21 import static org.onosproject.incubator.net.tunnel.Tunnel.State.ESTABLISHED; 25 import static org.onosproject.incubator.net.tunnel.Tunnel.State.ESTABLISHED;
26 +import static org.onosproject.net.MastershipRole.MASTER;
22 27
23 import java.net.URISyntaxException; 28 import java.net.URISyntaxException;
24 import java.nio.ByteBuffer; 29 import java.nio.ByteBuffer;
...@@ -35,6 +40,8 @@ import org.junit.After; ...@@ -35,6 +40,8 @@ import org.junit.After;
35 import org.junit.Before; 40 import org.junit.Before;
36 import org.junit.Test; 41 import org.junit.Test;
37 import org.onlab.graph.GraphPathSearch; 42 import org.onlab.graph.GraphPathSearch;
43 +import org.onlab.junit.TestUtils;
44 +import org.onlab.junit.TestUtils.TestUtilsException;
38 import org.onlab.packet.Ethernet; 45 import org.onlab.packet.Ethernet;
39 import org.onlab.packet.IPv4; 46 import org.onlab.packet.IPv4;
40 import org.onlab.util.Bandwidth; 47 import org.onlab.util.Bandwidth;
...@@ -43,6 +50,7 @@ import org.onosproject.core.ApplicationId; ...@@ -43,6 +50,7 @@ import org.onosproject.core.ApplicationId;
43 import org.onosproject.core.CoreServiceAdapter; 50 import org.onosproject.core.CoreServiceAdapter;
44 import org.onosproject.core.DefaultApplicationId; 51 import org.onosproject.core.DefaultApplicationId;
45 import org.onosproject.core.IdGenerator; 52 import org.onosproject.core.IdGenerator;
53 +import org.onosproject.event.Event;
46 import org.onosproject.incubator.net.resource.label.LabelResourceId; 54 import org.onosproject.incubator.net.resource.label.LabelResourceId;
47 import org.onosproject.incubator.net.resource.label.LabelResourceService; 55 import org.onosproject.incubator.net.resource.label.LabelResourceService;
48 import org.onosproject.incubator.net.tunnel.DefaultTunnel; 56 import org.onosproject.incubator.net.tunnel.DefaultTunnel;
...@@ -52,6 +60,7 @@ import org.onosproject.incubator.net.tunnel.TunnelEndPoint; ...@@ -52,6 +60,7 @@ import org.onosproject.incubator.net.tunnel.TunnelEndPoint;
52 import org.onosproject.incubator.net.tunnel.TunnelEvent; 60 import org.onosproject.incubator.net.tunnel.TunnelEvent;
53 import org.onosproject.incubator.net.tunnel.TunnelId; 61 import org.onosproject.incubator.net.tunnel.TunnelId;
54 import org.onosproject.incubator.net.tunnel.TunnelListener; 62 import org.onosproject.incubator.net.tunnel.TunnelListener;
63 +import org.onosproject.mastership.MastershipServiceAdapter;
55 import org.onosproject.net.AnnotationKeys; 64 import org.onosproject.net.AnnotationKeys;
56 import org.onosproject.net.Annotations; 65 import org.onosproject.net.Annotations;
57 import org.onosproject.net.ConnectPoint; 66 import org.onosproject.net.ConnectPoint;
...@@ -60,6 +69,7 @@ import org.onosproject.net.DefaultDevice; ...@@ -60,6 +69,7 @@ import org.onosproject.net.DefaultDevice;
60 import org.onosproject.net.DefaultLink; 69 import org.onosproject.net.DefaultLink;
61 import org.onosproject.net.Device; 70 import org.onosproject.net.Device;
62 import org.onosproject.net.DefaultAnnotations.Builder; 71 import org.onosproject.net.DefaultAnnotations.Builder;
72 +import org.onosproject.net.MastershipRole;
63 import org.onosproject.net.device.DeviceServiceAdapter; 73 import org.onosproject.net.device.DeviceServiceAdapter;
64 import org.onosproject.net.flowobjective.ForwardingObjective; 74 import org.onosproject.net.flowobjective.ForwardingObjective;
65 import org.onosproject.net.DeviceId; 75 import org.onosproject.net.DeviceId;
...@@ -71,6 +81,7 @@ import org.onosproject.net.SparseAnnotations; ...@@ -71,6 +81,7 @@ import org.onosproject.net.SparseAnnotations;
71 import org.onosproject.net.intent.Constraint; 81 import org.onosproject.net.intent.Constraint;
72 import org.onosproject.net.intent.IntentId; 82 import org.onosproject.net.intent.IntentId;
73 import org.onosproject.net.intent.constraint.BandwidthConstraint; 83 import org.onosproject.net.intent.constraint.BandwidthConstraint;
84 +import org.onosproject.net.link.LinkEvent;
74 import org.onosproject.net.packet.DefaultInboundPacket; 85 import org.onosproject.net.packet.DefaultInboundPacket;
75 import org.onosproject.net.packet.DefaultPacketContext; 86 import org.onosproject.net.packet.DefaultPacketContext;
76 import org.onosproject.net.packet.InboundPacket; 87 import org.onosproject.net.packet.InboundPacket;
...@@ -86,7 +97,9 @@ import org.onosproject.net.topology.LinkWeight; ...@@ -86,7 +97,9 @@ import org.onosproject.net.topology.LinkWeight;
86 import org.onosproject.net.topology.PathServiceAdapter; 97 import org.onosproject.net.topology.PathServiceAdapter;
87 import org.onosproject.net.topology.Topology; 98 import org.onosproject.net.topology.Topology;
88 import org.onosproject.net.topology.TopologyEdge; 99 import org.onosproject.net.topology.TopologyEdge;
100 +import org.onosproject.net.topology.TopologyEvent;
89 import org.onosproject.net.topology.TopologyGraph; 101 import org.onosproject.net.topology.TopologyGraph;
102 +import org.onosproject.net.topology.TopologyListener;
90 import org.onosproject.net.topology.TopologyServiceAdapter; 103 import org.onosproject.net.topology.TopologyServiceAdapter;
91 import org.onosproject.net.topology.TopologyVertex; 104 import org.onosproject.net.topology.TopologyVertex;
92 import org.onosproject.pce.pceservice.PathComputationTest.MockPathResourceService; 105 import org.onosproject.pce.pceservice.PathComputationTest.MockPathResourceService;
...@@ -97,6 +110,7 @@ import org.onosproject.pce.util.PceStoreAdapter; ...@@ -97,6 +110,7 @@ import org.onosproject.pce.util.PceStoreAdapter;
97 import org.onosproject.pce.util.TunnelServiceAdapter; 110 import org.onosproject.pce.util.TunnelServiceAdapter;
98 import org.onosproject.pce.util.FlowObjServiceAdapter; 111 import org.onosproject.pce.util.FlowObjServiceAdapter;
99 import org.onosproject.store.service.TestStorageService; 112 import org.onosproject.store.service.TestStorageService;
113 +
100 import com.google.common.collect.ImmutableSet; 114 import com.google.common.collect.ImmutableSet;
101 115
102 /** 116 /**
...@@ -107,6 +121,7 @@ public class PceManagerTest { ...@@ -107,6 +121,7 @@ public class PceManagerTest {
107 private PathComputationTest pathCompTest = new PathComputationTest(); 121 private PathComputationTest pathCompTest = new PathComputationTest();
108 private MockPathResourceService resourceService = pathCompTest.new MockPathResourceService(); 122 private MockPathResourceService resourceService = pathCompTest.new MockPathResourceService();
109 private MockTopologyService topologyService = new MockTopologyService(); 123 private MockTopologyService topologyService = new MockTopologyService();
124 + private MockMastershipService mastershipService = new MockMastershipService();
110 private MockPathService pathService = new MockPathService(); 125 private MockPathService pathService = new MockPathService();
111 private PceManager pceManager = new PceManager(); 126 private PceManager pceManager = new PceManager();
112 private MockCoreService coreService = new MockCoreService(); 127 private MockCoreService coreService = new MockCoreService();
...@@ -131,11 +146,17 @@ public class PceManagerTest { ...@@ -131,11 +146,17 @@ public class PceManagerTest {
131 private Link link1, link2, link3, link4; 146 private Link link1, link2, link3, link4;
132 protected static int flowsDownloaded; 147 protected static int flowsDownloaded;
133 private TunnelListener tunnelListener; 148 private TunnelListener tunnelListener;
149 + private TopologyListener listener;
150 + private Topology topology;
151 + private Set<TopologyEdge> edges;
152 + private Set<TopologyVertex> vertexes;
134 153
135 @Before 154 @Before
136 - public void startUp() { 155 + public void startUp() throws TestUtilsException {
156 + listener = TestUtils.getField(pceManager, "topologyListener");
137 pceManager.pathService = pathService; 157 pceManager.pathService = pathService;
138 pceManager.resourceService = resourceService; 158 pceManager.resourceService = resourceService;
159 + pceManager.topologyService = topologyService;
139 pceManager.tunnelService = tunnelService; 160 pceManager.tunnelService = tunnelService;
140 pceManager.coreService = coreService; 161 pceManager.coreService = coreService;
141 pceManager.storageService = storageService; 162 pceManager.storageService = storageService;
...@@ -144,34 +165,52 @@ public class PceManagerTest { ...@@ -144,34 +165,52 @@ public class PceManagerTest {
144 pceManager.labelRsrcService = labelResourceService; 165 pceManager.labelRsrcService = labelResourceService;
145 pceManager.flowObjectiveService = flowObjectiveService; 166 pceManager.flowObjectiveService = flowObjectiveService;
146 pceManager.pceStore = pceStore; 167 pceManager.pceStore = pceStore;
168 + pceManager.mastershipService = mastershipService;
147 pceManager.activate(); 169 pceManager.activate();
148 } 170 }
149 171
172 + private class MockMastershipService extends MastershipServiceAdapter {
173 + @Override
174 + public MastershipRole getLocalRole(DeviceId deviceId) {
175 + return MASTER;
176 + }
177 +
178 + @Override
179 + public boolean isLocalMaster(DeviceId deviceId) {
180 + return getLocalRole(deviceId) == MASTER;
181 + }
182 + }
183 +
150 private void build4RouterTopo(boolean setCost, boolean setPceccCap, boolean setSrCap, 184 private void build4RouterTopo(boolean setCost, boolean setPceccCap, boolean setSrCap,
151 boolean setLabelStackCap, int bandwidth) { 185 boolean setLabelStackCap, int bandwidth) {
186 + link1 = PathComputationTest.addLink(DEVICE1, 10, DEVICE2, 20, setCost, 50);
187 + link2 = PathComputationTest.addLink(DEVICE2, 30, DEVICE4, 40, setCost, 20);
188 + link3 = PathComputationTest.addLink(DEVICE1, 80, DEVICE3, 70, setCost, 100);
189 + link4 = PathComputationTest.addLink(DEVICE3, 60, DEVICE4, 50, setCost, 80);
190 +
152 Set<TopologyVertex> vertexes = new HashSet<TopologyVertex>(); 191 Set<TopologyVertex> vertexes = new HashSet<TopologyVertex>();
153 vertexes.add(D1); 192 vertexes.add(D1);
154 vertexes.add(D2); 193 vertexes.add(D2);
155 vertexes.add(D3); 194 vertexes.add(D3);
156 vertexes.add(D4); 195 vertexes.add(D4);
157 196
197 + this.vertexes = vertexes;
198 +
158 Set<TopologyEdge> edges = new HashSet<TopologyEdge>(); 199 Set<TopologyEdge> edges = new HashSet<TopologyEdge>();
159 - link1 = PathComputationTest.addLink(D1.deviceId().toString(), 10, D2.deviceId().toString(), 20, setCost, 50);
160 TopologyEdge edge1 = new DefaultTopologyEdge(D1, D2, link1); 200 TopologyEdge edge1 = new DefaultTopologyEdge(D1, D2, link1);
161 edges.add(edge1); 201 edges.add(edge1);
162 202
163 - link2 = PathComputationTest.addLink(D2.deviceId().toString(), 30, D4.deviceId().toString(), 40, setCost, 20);
164 TopologyEdge edge2 = new DefaultTopologyEdge(D2, D4, link2); 203 TopologyEdge edge2 = new DefaultTopologyEdge(D2, D4, link2);
165 edges.add(edge2); 204 edges.add(edge2);
166 205
167 - link3 = PathComputationTest.addLink(D1.deviceId().toString(), 80, D3.deviceId().toString(), 70, setCost, 100);
168 TopologyEdge edge3 = new DefaultTopologyEdge(D1, D3, link3); 206 TopologyEdge edge3 = new DefaultTopologyEdge(D1, D3, link3);
169 edges.add(edge3); 207 edges.add(edge3);
170 208
171 - link4 = PathComputationTest.addLink(D3.deviceId().toString(), 60, D4.deviceId().toString(), 50, setCost, 80);
172 TopologyEdge edge4 = new DefaultTopologyEdge(D3, D4, link4); 209 TopologyEdge edge4 = new DefaultTopologyEdge(D3, D4, link4);
173 edges.add(edge4); 210 edges.add(edge4);
174 211
212 + this.edges = edges;
213 +
175 graph = new DefaultTopologyGraph(vertexes, edges); 214 graph = new DefaultTopologyGraph(vertexes, edges);
176 215
177 DefaultAnnotations.Builder builderDev1 = DefaultAnnotations.builder(); 216 DefaultAnnotations.Builder builderDev1 = DefaultAnnotations.builder();
...@@ -800,6 +839,390 @@ public class PceManagerTest { ...@@ -800,6 +839,390 @@ public class PceManagerTest {
800 assertThat(pceStore.getFailedPathInfoCount(), is(1)); 839 assertThat(pceStore.getFailedPathInfoCount(), is(1));
801 } 840 }
802 841
842 + /**
843 + * Tests resilency when L2 link is down.
844 + */
845 + @Test
846 + public void resilencyTest1() {
847 + build4RouterTopo(true, false, false, false, 10);
848 +
849 +
850 + List<Constraint> constraints = new LinkedList<Constraint>();
851 + CostConstraint costConstraint = new CostConstraint(COST);
852 + constraints.add(costConstraint);
853 + BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
854 + constraints.add(localBwConst);
855 +
856 + //Setup the path , tunnel created
857 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
858 + assertThat(result, is(true));
859 + assertThat(pceStore.getTunnelInfoCount(), is(1));
860 + assertThat(pceStore.getFailedPathInfoCount(), is(0));
861 +
862 + List<Event> reasons = new LinkedList<>();
863 + final LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
864 + reasons.add(linkEvent);
865 + final TopologyEvent event = new TopologyEvent(
866 + TopologyEvent.Type.TOPOLOGY_CHANGED,
867 + topology,
868 + reasons);
869 +
870 + //Change Topology : remove link2
871 + Set<TopologyEdge> tempEdges = new HashSet<>();
872 + tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
873 + topologyService.changeInTopology(getGraph(null, tempEdges));
874 + listener.event(event);
875 +
876 + List<Link> links = new LinkedList<>();
877 + links.add(link3);
878 + links.add(link4);
879 +
880 + //Path is D1-D3-D4
881 + assertThat(pathService.paths().iterator().next().links(), is(links));
882 + assertThat(pathService.paths().iterator().next().cost(), is((double) 180));
883 + }
884 +
885 + /**
886 + * Tests resilency when L2 and L4 link is down.
887 + */
888 + @Test
889 + public void resilencyTest2() {
890 + build4RouterTopo(true, false, false, false, 10);
891 +
892 + List<Constraint> constraints = new LinkedList<Constraint>();
893 + CostConstraint costConstraint = new CostConstraint(COST);
894 + constraints.add(costConstraint);
895 + BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
896 + constraints.add(localBwConst);
897 +
898 + //Setup the path , tunnel created
899 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
900 + assertThat(result, is(true));
901 +
902 + List<Event> reasons = new LinkedList<>();
903 + LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
904 + reasons.add(linkEvent);
905 + linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link4);
906 + reasons.add(linkEvent);
907 + final TopologyEvent event = new TopologyEvent(
908 + TopologyEvent.Type.TOPOLOGY_CHANGED,
909 + topology,
910 + reasons);
911 +
912 + //Change Topology : remove link2 and link4
913 + Set<TopologyEdge> tempEdges = new HashSet<>();
914 + tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
915 + tempEdges.add(new DefaultTopologyEdge(D3, D4, link4));
916 + topologyService.changeInTopology(getGraph(null, tempEdges));
917 + listener.event(event);
918 +
919 + //No Path
920 + assertThat(pathService.paths().size(), is(0));
921 + }
922 +
923 + /**
924 + * Tests resilency when D2 device is down.
925 + */
926 + @Test
927 + public void resilencyTest3() {
928 + build4RouterTopo(true, false, false, false, 10);
929 +
930 + List<Constraint> constraints = new LinkedList<Constraint>();
931 + CostConstraint costConstraint = new CostConstraint(COST);
932 + constraints.add(costConstraint);
933 + BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
934 + constraints.add(localBwConst);
935 +
936 + //Setup the path , tunnel created
937 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
938 + assertThat(result, is(true));
939 +
940 + List<Event> reasons = new LinkedList<>();
941 + LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
942 + reasons.add(linkEvent);
943 + linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link1);
944 + reasons.add(linkEvent);
945 + final TopologyEvent event = new TopologyEvent(
946 + TopologyEvent.Type.TOPOLOGY_CHANGED,
947 + topology,
948 + reasons);
949 +
950 + //Change Topology : remove link2 and link1
951 + Set<TopologyEdge> tempEdges = new HashSet<>();
952 + tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
953 + tempEdges.add(new DefaultTopologyEdge(D1, D2, link1));
954 + topologyService.changeInTopology(getGraph(null, tempEdges));
955 + listener.event(event);
956 +
957 + List<Link> links = new LinkedList<>();
958 + links.add(link3);
959 + links.add(link4);
960 +
961 + //Path is D1-D3-D4
962 + assertThat(pathService.paths().iterator().next().links(), is(links));
963 + assertThat(pathService.paths().iterator().next().cost(), is((double) 180));
964 + }
965 +
966 + /**
967 + * Tests resilency when ingress device is down.
968 + */
969 + @Test
970 + public void resilencyTest4() {
971 + build4RouterTopo(true, false, false, false, 10);
972 +
973 + List<Constraint> constraints = new LinkedList<Constraint>();
974 + CostConstraint costConstraint = new CostConstraint(COST);
975 + constraints.add(costConstraint);
976 + BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
977 + constraints.add(localBwConst);
978 +
979 + //Setup the path , tunnel created
980 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
981 + assertThat(result, is(true));
982 +
983 + List<Event> reasons = new LinkedList<>();
984 + LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link3);
985 + reasons.add(linkEvent);
986 + linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link1);
987 + reasons.add(linkEvent);
988 + final TopologyEvent event = new TopologyEvent(
989 + TopologyEvent.Type.TOPOLOGY_CHANGED,
990 + topology,
991 + reasons);
992 +
993 + //Change Topology : remove link2 and link1
994 + Set<TopologyEdge> tempEdges = new HashSet<>();
995 + tempEdges.add(new DefaultTopologyEdge(D1, D3, link3));
996 + tempEdges.add(new DefaultTopologyEdge(D1, D2, link1));
997 + topologyService.changeInTopology(getGraph(null, tempEdges));
998 + listener.event(event);
999 +
1000 + //No path
1001 + assertThat(pathService.paths().size(), is(0));
1002 + }
1003 +
1004 + /**
1005 + * Tests resilency when D2 and D3 devices are down.
1006 + */
1007 + @Test
1008 + public void resilencyTest5() {
1009 + build4RouterTopo(true, false, false, false, 10);
1010 +
1011 + List<Constraint> constraints = new LinkedList<Constraint>();
1012 + CostConstraint costConstraint = new CostConstraint(COST);
1013 + constraints.add(costConstraint);
1014 + BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
1015 + constraints.add(localBwConst);
1016 +
1017 + //Setup the path , tunnel created
1018 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
1019 + assertThat(result, is(true));
1020 +
1021 + List<Event> reasons = new LinkedList<>();
1022 + LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
1023 + reasons.add(linkEvent);
1024 + linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link1);
1025 + reasons.add(linkEvent);
1026 + linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link3);
1027 + reasons.add(linkEvent);
1028 + linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link4);
1029 + reasons.add(linkEvent);
1030 +
1031 + final TopologyEvent event = new TopologyEvent(
1032 + TopologyEvent.Type.TOPOLOGY_CHANGED,
1033 + topology,
1034 + reasons);
1035 +
1036 + //Change Topology : remove device2, device3 and all links
1037 + Set<TopologyEdge> tempEdges = new HashSet<>();
1038 + tempEdges.add(new DefaultTopologyEdge(D1, D2, link1));
1039 + tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
1040 + tempEdges.add(new DefaultTopologyEdge(D1, D3, link3));
1041 + tempEdges.add(new DefaultTopologyEdge(D3, D4, link4));
1042 + Set<TopologyVertex> tempVertexes = new HashSet<>();
1043 + tempVertexes.add(D2);
1044 + tempVertexes.add(D3);
1045 + topologyService.changeInTopology(getGraph(tempVertexes, tempEdges));
1046 + listener.event(event);
1047 +
1048 + //No path
1049 + assertThat(pathService.paths().size(), is(0));
1050 + }
1051 +
1052 + /**
1053 + * Tests resilency when egress device is down.
1054 + */
1055 + @Test
1056 + public void resilencyTest6() {
1057 + build4RouterTopo(true, false, false, false, 10);
1058 +
1059 + List<Constraint> constraints = new LinkedList<Constraint>();
1060 + CostConstraint costConstraint = new CostConstraint(COST);
1061 + constraints.add(costConstraint);
1062 + BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
1063 + constraints.add(localBwConst);
1064 +
1065 + //Setup the path , tunnel created
1066 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
1067 + assertThat(result, is(true));
1068 +
1069 + List<Event> reasons = new LinkedList<>();
1070 + LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
1071 + reasons.add(linkEvent);
1072 + linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link4);
1073 + reasons.add(linkEvent);
1074 +
1075 + final TopologyEvent event = new TopologyEvent(
1076 + TopologyEvent.Type.TOPOLOGY_CHANGED,
1077 + topology,
1078 + reasons);
1079 +
1080 + //Change Topology : remove device4 , link2 and link4
1081 + Set<TopologyEdge> tempEdges = new HashSet<>();
1082 + tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
1083 + tempEdges.add(new DefaultTopologyEdge(D3, D4, link4));
1084 + Set<TopologyVertex> tempVertexes = new HashSet<>();
1085 + tempVertexes.add(D4);
1086 + topologyService.changeInTopology(getGraph(tempVertexes, tempEdges));
1087 + listener.event(event);
1088 +
1089 + //No path
1090 + assertThat(pathService.paths().size(), is(0));
1091 + }
1092 +
1093 + /**
1094 + * Tests resilency when egress device is down.
1095 + */
1096 + @Test
1097 + public void resilencyTest7() {
1098 + build4RouterTopo(true, false, false, false, 10);
1099 +
1100 + List<Constraint> constraints = new LinkedList<Constraint>();
1101 + CostConstraint costConstraint = new CostConstraint(COST);
1102 + constraints.add(costConstraint);
1103 + BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
1104 + constraints.add(localBwConst);
1105 +
1106 + //Setup the path , tunnel created
1107 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
1108 + assertThat(result, is(true));
1109 +
1110 + List<Event> reasons = new LinkedList<>();
1111 + LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
1112 + reasons.add(linkEvent);
1113 + linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link4);
1114 + reasons.add(linkEvent);
1115 +
1116 + final TopologyEvent event = new TopologyEvent(
1117 + TopologyEvent.Type.TOPOLOGY_CHANGED,
1118 + topology,
1119 + reasons);
1120 +
1121 + //Change Topology : remove device4 , link2 and link4
1122 + Set<TopologyEdge> tempEdges = new HashSet<>();
1123 + tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
1124 + tempEdges.add(new DefaultTopologyEdge(D3, D4, link4));
1125 + Set<TopologyVertex> tempVertexes = new HashSet<>();
1126 + tempVertexes.add(D4);
1127 + topologyService.changeInTopology(getGraph(tempVertexes, tempEdges));
1128 + listener.event(event);
1129 +
1130 + //No path
1131 + assertThat(pathService.paths().size(), is(0));
1132 + }
1133 +
1134 + /**
1135 + * Tests resilency when D2 device is suspended.
1136 + */
1137 + @Test
1138 + public void resilencyTest8() {
1139 + build4RouterTopo(true, false, false, false, 10);
1140 +
1141 + List<Constraint> constraints = new LinkedList<Constraint>();
1142 + CostConstraint costConstraint = new CostConstraint(COST);
1143 + constraints.add(costConstraint);
1144 + BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
1145 + constraints.add(localBwConst);
1146 +
1147 + //Setup the path , tunnel created
1148 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
1149 + assertThat(result, is(true));
1150 +
1151 + List<Event> reasons = new LinkedList<>();
1152 + LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link1);
1153 + reasons.add(linkEvent);
1154 + linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
1155 + reasons.add(linkEvent);
1156 +
1157 + final TopologyEvent event = new TopologyEvent(
1158 + TopologyEvent.Type.TOPOLOGY_CHANGED,
1159 + topology,
1160 + reasons);
1161 +
1162 + //Change Topology : remove device2 , link1 and link2
1163 + Set<TopologyEdge> tempEdges = new HashSet<>();
1164 + tempEdges.add(new DefaultTopologyEdge(D1, D2, link1));
1165 + tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
1166 + Set<TopologyVertex> tempVertexes = new HashSet<>();
1167 + tempVertexes.add(D2);
1168 + topologyService.changeInTopology(getGraph(tempVertexes, tempEdges));
1169 + listener.event(event);
1170 +
1171 + List<Link> links = new LinkedList<>();
1172 + links.add(link3);
1173 + links.add(link4);
1174 +
1175 + //Path is D1-D3-D4
1176 + assertThat(pathService.paths().iterator().next().links(), is(links));
1177 + assertThat(pathService.paths().iterator().next().cost(), is((double) 180));
1178 + }
1179 +
1180 + /**
1181 + * Tests resilency when D2 device availability is changed.
1182 + */
1183 + @Test
1184 + public void resilencyTest11() {
1185 + build4RouterTopo(true, false, false, false, 10);
1186 +
1187 + List<Constraint> constraints = new LinkedList<Constraint>();
1188 + CostConstraint costConstraint = new CostConstraint(COST);
1189 + constraints.add(costConstraint);
1190 + BandwidthConstraint localBwConst = new BandwidthConstraint(Bandwidth.bps(10));
1191 + constraints.add(localBwConst);
1192 +
1193 + //Setup the path , tunnel created
1194 + boolean result = pceManager.setupPath(D1.deviceId(), D4.deviceId(), "T123", constraints, WITH_SIGNALLING);
1195 + assertThat(result, is(true));
1196 +
1197 + List<Event> reasons = new LinkedList<>();
1198 + LinkEvent linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link1);
1199 + reasons.add(linkEvent);
1200 + linkEvent = new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2);
1201 + reasons.add(linkEvent);
1202 +
1203 + final TopologyEvent event = new TopologyEvent(
1204 + TopologyEvent.Type.TOPOLOGY_CHANGED,
1205 + topology,
1206 + reasons);
1207 +
1208 + //Change Topology : remove device2 , link1 and link2
1209 + Set<TopologyEdge> tempEdges = new HashSet<>();
1210 + tempEdges.add(new DefaultTopologyEdge(D1, D2, link1));
1211 + tempEdges.add(new DefaultTopologyEdge(D2, D4, link2));
1212 + Set<TopologyVertex> tempVertexes = new HashSet<>();
1213 + tempVertexes.add(D2);
1214 + topologyService.changeInTopology(getGraph(tempVertexes, tempEdges));
1215 + listener.event(event);
1216 +
1217 + List<Link> links = new LinkedList<>();
1218 + links.add(link3);
1219 + links.add(link4);
1220 +
1221 + //Path is D1-D3-D4
1222 + assertThat(pathService.paths().iterator().next().links(), is(links));
1223 + assertThat(pathService.paths().iterator().next().cost(), is((double) 180));
1224 + }
1225 +
803 @After 1226 @After
804 public void tearDown() { 1227 public void tearDown() {
805 pceManager.deactivate(); 1228 pceManager.deactivate();
...@@ -813,10 +1236,16 @@ public class PceManagerTest { ...@@ -813,10 +1236,16 @@ public class PceManagerTest {
813 pceManager.labelRsrcService = null; 1236 pceManager.labelRsrcService = null;
814 pceManager.flowObjectiveService = null; 1237 pceManager.flowObjectiveService = null;
815 pceManager.pceStore = null; 1238 pceManager.pceStore = null;
1239 + pceManager.topologyService = null;
1240 + pceManager.mastershipService = null;
816 flowsDownloaded = 0; 1241 flowsDownloaded = 0;
817 } 1242 }
818 1243
819 private class MockTopologyService extends TopologyServiceAdapter { 1244 private class MockTopologyService extends TopologyServiceAdapter {
1245 + private void changeInTopology(TopologyGraph graphModified) {
1246 + graph = graphModified;
1247 + }
1248 +
820 @Override 1249 @Override
821 public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeight weight) { 1250 public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeight weight) {
822 DefaultTopologyVertex srcV = new DefaultTopologyVertex(src); 1251 DefaultTopologyVertex srcV = new DefaultTopologyVertex(src);
...@@ -837,8 +1266,27 @@ public class PceManagerTest { ...@@ -837,8 +1266,27 @@ public class PceManagerTest {
837 } 1266 }
838 } 1267 }
839 1268
840 - private class MockPathService extends PathServiceAdapter { 1269 + private TopologyGraph getGraph(Set<TopologyVertex> removedVertex, Set<TopologyEdge> removedEdges) {
1270 + if (removedVertex != null) {
1271 + vertexes.remove(removedVertex);
1272 + removedVertex.forEach(v ->
1273 + {
1274 + vertexes.remove(v);
1275 + });
1276 + }
1277 +
1278 + if (removedEdges != null) {
1279 + removedEdges.forEach(e ->
1280 + {
1281 + edges.remove(e);
1282 + });
1283 + }
841 1284
1285 + return new DefaultTopologyGraph(vertexes, edges);
1286 + }
1287 +
1288 + private class MockPathService extends PathServiceAdapter {
1289 + Set<Path> computedPaths;
842 @Override 1290 @Override
843 public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) { 1291 public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) {
844 // If either edge is null, bail with no paths. 1292 // If either edge is null, bail with no paths.
...@@ -848,7 +1296,12 @@ public class PceManagerTest { ...@@ -848,7 +1296,12 @@ public class PceManagerTest {
848 1296
849 // Otherwise get all paths between the source and destination edge 1297 // Otherwise get all paths between the source and destination edge
850 // devices. 1298 // devices.
851 - return topologyService.getPaths(null, (DeviceId) src, (DeviceId) dst, weight); 1299 + computedPaths = topologyService.getPaths(null, (DeviceId) src, (DeviceId) dst, weight);
1300 + return computedPaths;
1301 + }
1302 +
1303 + private Set<Path> paths() {
1304 + return computedPaths;
852 } 1305 }
853 } 1306 }
854 1307
...@@ -946,6 +1399,31 @@ public class PceManagerTest { ...@@ -946,6 +1399,31 @@ public class PceManagerTest {
946 1399
947 return result.size() == 0 ? Collections.emptySet() : ImmutableSet.copyOf(result); 1400 return result.size() == 0 ? Collections.emptySet() : ImmutableSet.copyOf(result);
948 } 1401 }
1402 +
1403 + @Override
1404 + public Collection<Tunnel> queryAllTunnels() {
1405 + Collection<Tunnel> result = new HashSet<Tunnel>();
1406 +
1407 + for (TunnelId tunnelId : tunnelIdAsKeyStore.keySet()) {
1408 + result.add(tunnelIdAsKeyStore.get(tunnelId));
1409 + }
1410 +
1411 + return result.size() == 0 ? Collections.emptySet() : ImmutableSet.copyOf(result);
1412 + }
1413 + @Override
1414 + public Iterable<Tunnel> getTunnels(DeviceId deviceId) {
1415 + List<Tunnel> tunnelList = new LinkedList<>();
1416 +
1417 + for (Tunnel t : tunnelIdAsKeyStore.values()) {
1418 + for (Link l : t.path().links()) {
1419 + if (l.src().deviceId().equals(deviceId) || l.dst().deviceId().equals(deviceId)) {
1420 + tunnelList.add(t);
1421 + break;
1422 + }
1423 + }
1424 + }
1425 + return tunnelList;
1426 + }
949 } 1427 }
950 1428
951 public static class MockCoreService extends CoreServiceAdapter { 1429 public static class MockCoreService extends CoreServiceAdapter {
......