blob: 66edd130f3689a8a61fa0bc04b1c4bc3463e1a0b [file] [log] [blame]
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -07001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.vpls;
18
19import com.google.common.collect.HashMultimap;
20import com.google.common.collect.ImmutableSet;
21import com.google.common.collect.ImmutableSetMultimap;
Luca Prete092e8952016-10-26 16:25:56 +020022import com.google.common.collect.Maps;
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070023import com.google.common.collect.SetMultimap;
24import com.google.common.collect.Sets;
25import org.junit.After;
26import org.junit.Before;
27import org.junit.Test;
28import org.onlab.packet.Ethernet;
29import org.onlab.packet.IpAddress;
30import org.onlab.packet.MacAddress;
31import org.onlab.packet.VlanId;
32import org.onosproject.core.ApplicationId;
33import org.onosproject.incubator.net.intf.Interface;
34import org.onosproject.incubator.net.intf.InterfaceListener;
35import org.onosproject.incubator.net.intf.InterfaceService;
36import org.onosproject.incubator.net.neighbour.NeighbourHandlerRegistration;
37import org.onosproject.incubator.net.neighbour.NeighbourMessageContext;
38import org.onosproject.incubator.net.neighbour.NeighbourMessageHandler;
39import org.onosproject.incubator.net.neighbour.NeighbourMessageType;
40import org.onosproject.incubator.net.neighbour.NeighbourProtocol;
41import org.onosproject.incubator.net.neighbour.NeighbourResolutionService;
42import org.onosproject.net.ConnectPoint;
43import org.onosproject.net.DefaultHost;
44import org.onosproject.net.DeviceId;
Luca Prete092e8952016-10-26 16:25:56 +020045import org.onosproject.net.EncapsulationType;
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070046import org.onosproject.net.Host;
47import org.onosproject.net.HostId;
48import org.onosproject.net.HostLocation;
49import org.onosproject.net.PortNumber;
50import org.onosproject.net.host.HostService;
51import org.onosproject.net.host.HostServiceAdapter;
52import org.onosproject.net.provider.ProviderId;
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070053
54import java.util.Collection;
Luca Prete092e8952016-10-26 16:25:56 +020055import java.util.HashMap;
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070056import java.util.Map;
57import java.util.Set;
58import java.util.stream.Collectors;
59
60import static junit.framework.TestCase.assertEquals;
61
62/**
63 * Tests the the {@link VplsNeighbourHandler} class.
64 */
65public class VplsNeighbourHandlerTest {
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070066
Luca Prete092e8952016-10-26 16:25:56 +020067 private static final String IFACES_NOT_EXPECTED =
68 "The interfaces reached by the packet are not equal to the " +
69 "interfaces expected";
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070070
Luca Prete092e8952016-10-26 16:25:56 +020071 private static final DeviceId DID1 = getDeviceId(1);
72 private static final DeviceId DID2 = getDeviceId(2);
73 private static final DeviceId DID3 = getDeviceId(3);
74 private static final DeviceId DID4 = getDeviceId(4);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070075
Luca Prete092e8952016-10-26 16:25:56 +020076 private static final PortNumber P1 = PortNumber.portNumber(1);
77 private static final PortNumber P2 = PortNumber.portNumber(2);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070078
Luca Prete092e8952016-10-26 16:25:56 +020079 private static final ConnectPoint OF1P1 = new ConnectPoint(DID1, P1);
80 private static final ConnectPoint OF2P1 = new ConnectPoint(DID2, P1);
81 private static final ConnectPoint OF3P1 = new ConnectPoint(DID3, P1);
82 private static final ConnectPoint OF4P1 = new ConnectPoint(DID4, P1);
83 private static final ConnectPoint OF4P2 = new ConnectPoint(DID4, P2);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070084
Luca Prete092e8952016-10-26 16:25:56 +020085 private static final String VPLS1 = "vpls1";
86 private static final String VPLS2 = "vpls2";
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070087
Luca Prete092e8952016-10-26 16:25:56 +020088 private static final VlanId VLAN100 = VlanId.vlanId("100");
89 private static final VlanId VLAN200 = VlanId.vlanId("200");
90 private static final VlanId VLAN300 = VlanId.vlanId("300");
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070091
Luca Prete092e8952016-10-26 16:25:56 +020092 private static final Interface V100H1 =
93 new Interface("v100h1", OF1P1, null, null, VLAN100);
94 private static final Interface V100H2 =
95 new Interface("v100h2", OF4P1, null, null, VLAN100);
96 private static final Interface V200H1 =
97 new Interface("v200h1", OF4P2, null, null, VLAN200);
98 private static final Interface V200H2 =
99 new Interface("v200h2", OF2P1, null, null, VLAN200);
100 private static final Interface V300H1 =
101 new Interface("v300h1", OF3P1, null, null, VLAN300);
102
103 private static final MacAddress MAC1 = MacAddress.valueOf("00:00:00:00:00:01");
104 private static final MacAddress MAC2 = MacAddress.valueOf("00:00:00:00:00:02");
105 private static final MacAddress MAC3 = MacAddress.valueOf("00:00:00:00:00:03");
106 private static final MacAddress MAC4 = MacAddress.valueOf("00:00:00:00:00:04");
107 private static final MacAddress MAC5 = MacAddress.valueOf("00:00:00:00:00:05");
108
109 private static final ProviderId PID = new ProviderId("of", "foo");
110
111 private final Host v100Host1 = makeHost(MAC1, VLAN100, OF1P1);
112 private final Host v100Host2 = makeHost(MAC2, VLAN100, OF4P1);
113 private final Host v200Host1 = makeHost(MAC3, VLAN200, OF4P2);
114 private final Host v200Host2 = makeHost(MAC5, VLAN200, OF2P1);
115 private final Host v300Host1 = makeHost(MAC4, VLAN300, OF3P1);
116
117 private final Set<Host> availableHosts = ImmutableSet.of(v100Host1,
118 v100Host2,
119 v200Host1,
120 v300Host1,
121 v200Host2);
122
123 private final Set<Interface> availableInterfaces =
124 ImmutableSet.of(V100H1, V100H2, V200H1, V200H2, V300H1);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700125
126 private VplsNeighbourHandler vplsNeighbourHandler;
127
128 private HostService hostService;
129
130 /**
Luca Prete092e8952016-10-26 16:25:56 +0200131 * Sets up 2 VPLS.
132 * VPLS 1 contains 3 hosts: v100h1, v200h1 and v300h1
133 * VPLS 2 contains 2 hosts: v100h2, v200h2
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700134 */
135 @Before
136 public void setUp() {
137 vplsNeighbourHandler = new VplsNeighbourHandler();
Luca Prete092e8952016-10-26 16:25:56 +0200138 SetMultimap<String, Interface> ifacesByVpls =
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700139 HashMultimap.create();
Luca Prete092e8952016-10-26 16:25:56 +0200140 ifacesByVpls.put(VPLS1, V100H1);
141 ifacesByVpls.put(VPLS1, V200H1);
142 ifacesByVpls.put(VPLS1, V300H1);
143 ifacesByVpls.put(VPLS2, V100H2);
144 ifacesByVpls.put(VPLS2, V200H2);
145 HashMap<String, EncapsulationType> encap = Maps.newHashMap();
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700146 vplsNeighbourHandler.vplsConfigService =
Luca Prete092e8952016-10-26 16:25:56 +0200147 new TestVplsConfigService(ifacesByVpls, encap);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700148 vplsNeighbourHandler.interfaceService =
149 new TestInterfaceService();
150 vplsNeighbourHandler.neighbourService =
151 new TestNeighbourService();
152
153 hostService = new TestHostService();
154 }
155
156 @After
157 public void tearDown() {
158
159 }
160
161 /**
Luca Prete092e8952016-10-26 16:25:56 +0200162 * Sends request messages to all hosts in VPLS 1.
163 * Request messages should be received from other hosts in VPLS 1.
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700164 */
165 @Test
Luca Prete092e8952016-10-26 16:25:56 +0200166 public void vpls1RequestMessage() {
167 // Request messages from v100h1 (VPLS 1) should be received by v200h1 and v300h1
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700168 TestMessageContext requestMessage =
Luca Prete092e8952016-10-26 16:25:56 +0200169 makeBroadcastRequestContext(v100Host1);
170 Set<Interface> expectInterfaces = ImmutableSet.of(V200H1, V300H1);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700171 vplsNeighbourHandler.handleRequest(requestMessage);
Luca Prete092e8952016-10-26 16:25:56 +0200172 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700173
Luca Prete092e8952016-10-26 16:25:56 +0200174 // Request messages from v200h1 (VPLS 1) should be received by v100h1 and v300h1
175 requestMessage = makeBroadcastRequestContext(v200Host1);
176 expectInterfaces = ImmutableSet.of(V100H1, V300H1);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700177 vplsNeighbourHandler.handleRequest(requestMessage);
Luca Prete092e8952016-10-26 16:25:56 +0200178 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700179
Luca Prete092e8952016-10-26 16:25:56 +0200180 // Request from v300h1 (VPLS 1) should be received by v100h1 and v200h1
181 requestMessage = makeBroadcastRequestContext(v300Host1);
182 expectInterfaces = ImmutableSet.of(V100H1, V200H1);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700183 vplsNeighbourHandler.handleRequest(requestMessage);
Luca Prete092e8952016-10-26 16:25:56 +0200184 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700185 }
186
187 /**
Luca Prete092e8952016-10-26 16:25:56 +0200188 * Sends request messages to all hosts in VPLS 2.
189 * Request messages should be received from other hosts in VPLS 2.
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700190 */
191 @Test
Luca Prete092e8952016-10-26 16:25:56 +0200192 public void vpls2RequestMessage() {
193 // Request messages from v100h2 (VPLS 2) should be received by v200h2
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700194 TestMessageContext requestMessage =
Luca Prete092e8952016-10-26 16:25:56 +0200195 makeBroadcastRequestContext(v100Host2);
196 Set<Interface> expectInterfaces = ImmutableSet.of(V200H2);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700197 vplsNeighbourHandler.handleRequest(requestMessage);
Luca Prete092e8952016-10-26 16:25:56 +0200198 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700199
Luca Prete092e8952016-10-26 16:25:56 +0200200 // Request messages from v200h2 (VPLS 2) should be received by v100h2
201 requestMessage = makeBroadcastRequestContext(v200Host2);
202 expectInterfaces = ImmutableSet.of(V100H2);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700203 vplsNeighbourHandler.handleRequest(requestMessage);
Luca Prete092e8952016-10-26 16:25:56 +0200204 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700205 }
206
207 /**
Luca Prete092e8952016-10-26 16:25:56 +0200208 * Sends reply messages to hosts in VPLS 1.
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700209 * Reply messages should be received by the host with MAC address equal to
210 * the dstMac of the message context.
211 */
212 @Test
Luca Prete092e8952016-10-26 16:25:56 +0200213 public void vpls1ReplyMessage() {
214 // Reply messages from v100h1 (VPLS 1) should be received by v200h1
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700215 TestMessageContext replyMessage =
Luca Prete092e8952016-10-26 16:25:56 +0200216 makeReplyContext(v100Host1, v200Host1);
217 Set<Interface> expectInterfaces = ImmutableSet.of(V200H1);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700218 vplsNeighbourHandler.handleReply(replyMessage, hostService);
Luca Prete092e8952016-10-26 16:25:56 +0200219 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700220
Luca Prete092e8952016-10-26 16:25:56 +0200221 // Reply messages from v200h1 (VPLS 1) should be received by v300h1
222 replyMessage = makeReplyContext(v200Host1, v300Host1);
223 expectInterfaces = ImmutableSet.of(V300H1);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700224 vplsNeighbourHandler.handleReply(replyMessage, hostService);
Luca Prete092e8952016-10-26 16:25:56 +0200225 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700226
Luca Prete092e8952016-10-26 16:25:56 +0200227 // Reply messages from v300h1 (VPLS 1) should be received by v100h1
228 replyMessage = makeReplyContext(v300Host1, v100Host1);
229 expectInterfaces = ImmutableSet.of(V100H1);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700230 vplsNeighbourHandler.handleReply(replyMessage, hostService);
Luca Prete092e8952016-10-26 16:25:56 +0200231 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700232 }
233
234 /**
Luca Prete092e8952016-10-26 16:25:56 +0200235 * Sends reply messages to hosts in VPLS 2.
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700236 * Reply messages should be received by the host with MAC address equal to
237 * the dstMac of the message context.
238 */
239 @Test
Luca Prete092e8952016-10-26 16:25:56 +0200240 public void vpls2ReplyMessage() {
241 // Reply messages from v100h2 (VPLS 2) should be received by v200h2
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700242 TestMessageContext replyMessage =
Luca Prete092e8952016-10-26 16:25:56 +0200243 makeReplyContext(v100Host2, v200Host2);
244 Set<Interface> expectInterfaces = ImmutableSet.of(V200H2);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700245 vplsNeighbourHandler.handleReply(replyMessage, hostService);
Luca Prete092e8952016-10-26 16:25:56 +0200246 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700247
Luca Prete092e8952016-10-26 16:25:56 +0200248 // Reply messages from v200h2 (VPLS 2) should be received by v100h2
249 replyMessage = makeReplyContext(v200Host2, v100Host2);
250 expectInterfaces = ImmutableSet.of(V100H2);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700251 vplsNeighbourHandler.handleReply(replyMessage, hostService);
Luca Prete092e8952016-10-26 16:25:56 +0200252 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700253 }
254
255 /**
256 * Sends wrong reply messages to hosts.
257 * The source and the destination MAC addresses are not set on any host of the VPLS.
Luca Prete092e8952016-10-26 16:25:56 +0200258 * The reply messages will not be received by any hosts.
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700259 */
260 @Test
Luca Prete092e8952016-10-26 16:25:56 +0200261 public void wrongReplyMessage() {
262 // Reply message from v100h1 (VPLS 1) to v100h2 (VPLS 2).
263 // Forward results should be empty
264 TestMessageContext replyMessage = makeReplyContext(v100Host1, v100Host2);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700265 Set<Interface> expectInterfaces = ImmutableSet.of();
266 vplsNeighbourHandler.handleReply(replyMessage, hostService);
Luca Prete092e8952016-10-26 16:25:56 +0200267 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700268
Luca Prete092e8952016-10-26 16:25:56 +0200269 // Reply message from v200h2 (VPLS 2) to v300h1 (VPLS 1).
270 // Forward results should be empty
271 replyMessage = makeReplyContext(v200Host2, v300Host1);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700272 expectInterfaces = ImmutableSet.of();
273 vplsNeighbourHandler.handleReply(replyMessage, hostService);
Luca Prete092e8952016-10-26 16:25:56 +0200274 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
275 }
276
277 /**
278 * Returns the device Id of the ith device.
279 *
280 * @param i the device to get the Id of
281 * @return the device Id
282 */
283 private static DeviceId getDeviceId(int i) {
284 return DeviceId.deviceId("" + i);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700285 }
286
287 private Host makeHost(MacAddress mac, VlanId vlan, ConnectPoint cp) {
Luca Prete092e8952016-10-26 16:25:56 +0200288 return new DefaultHost(PID,
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700289 HostId.hostId(mac, vlan),
290 mac,
291 vlan,
292 new HostLocation(cp, 0),
293 Sets.newHashSet());
294 }
295
296 private TestMessageContext makeBroadcastRequestContext(Host host) {
297 return new TestMessageContext(host.location(),
298 host.mac(),
299 MacAddress.BROADCAST,
300 host.vlan(),
301 NeighbourMessageType.REQUEST);
302 }
303
304 private TestMessageContext makeReplyContext(Host src, Host dst) {
305 return new TestMessageContext(src.location(),
306 src.mac(),
307 dst.mac(),
308 src.vlan(),
309 NeighbourMessageType.REPLY);
310 }
311
312 private class TestMessageContext implements NeighbourMessageContext {
313
314
315 private final NeighbourMessageType type;
316 private final MacAddress srcMac;
317 private final MacAddress dstMac;
318 private final ConnectPoint inPort;
319 private final VlanId vlanId;
320
321 public Set<Interface> forwardResults;
322
323 /**
324 * Creates new neighbour message context for test.
325 *
326 * @param inPort the input port
327 * @param srcMac the source Mac
328 * @param dstMac the destination Mac
329 * @param vlanId the VLAN Id
330 * @param type the message context type
331 */
332 public TestMessageContext(
333 ConnectPoint inPort,
334 MacAddress srcMac,
335 MacAddress dstMac,
336 VlanId vlanId,
337 NeighbourMessageType type) {
338
339 this.inPort = inPort;
340 this.srcMac = srcMac;
341 this.dstMac = dstMac;
342 this.vlanId = vlanId;
343 this.type = type;
344
345 this.forwardResults = Sets.newHashSet();
346
347 }
Luca Prete092e8952016-10-26 16:25:56 +0200348
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700349 @Override
350 public ConnectPoint inPort() {
351 return inPort;
352 }
353
354 @Override
355 public NeighbourMessageType type() {
356 return type;
357 }
358
359 @Override
360 public VlanId vlan() {
361 return vlanId;
362 }
363
364 @Override
365 public MacAddress srcMac() {
366 return srcMac;
367 }
368
369 @Override
370 public MacAddress dstMac() {
371 return dstMac;
372 }
373
374 @Override
375 public IpAddress target() {
376 return null;
377 }
378
379 @Override
380 public IpAddress sender() {
381 return null;
382 }
383
384 @Override
385 public void forward(ConnectPoint outPort) {
386
387 }
388
389 @Override
390 public void forward(Interface outIntf) {
391 forwardResults.add(outIntf);
392 }
393
394 @Override
395 public void reply(MacAddress targetMac) {
396
397 }
398
399 @Override
400 public void flood() {
401
402 }
403
404 @Override
405 public void drop() {
406
407 }
408
409 @Override
410 public Ethernet packet() {
411 return null;
412 }
413
414 @Override
415 public NeighbourProtocol protocol() {
416 return null;
417 }
418 }
419
Luca Prete092e8952016-10-26 16:25:56 +0200420 private class TestVplsConfigService extends VplsConfigurationServiceAdapter {
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700421
Luca Prete092e8952016-10-26 16:25:56 +0200422 private final SetMultimap<String, Interface> ifacesByVplsName;
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700423
Luca Prete092e8952016-10-26 16:25:56 +0200424 public TestVplsConfigService(SetMultimap<String, Interface> ifacesByVplsName,
425 HashMap<String, EncapsulationType> encapByVplsName) {
426 this.ifacesByVplsName = ifacesByVplsName;
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700427 }
428
429 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200430 public void addVpls(String vplsName, Set<String> ifaceNames, String encap) {
431 if (!ifacesByVplsName.containsKey(vplsName)) {
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700432 ifaceNames.forEach(ifaceName -> {
Luca Prete092e8952016-10-26 16:25:56 +0200433 availableInterfaces.forEach(iface -> {
434 if (iface.name().equals(ifaceName)) {
435 ifacesByVplsName.put(vplsName, iface);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700436 }
437 });
438 });
439 }
440 }
441
442 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200443 public void removeVpls(String vplsName) {
444 if (ifacesByVplsName.containsKey(vplsName)) {
445 ifacesByVplsName.removeAll(vplsName);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700446 }
447 }
448
449 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200450 public void addIface(String vplsName, String ifaceName) {
451 availableInterfaces.forEach(intf -> {
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700452 if (intf.name().equals(ifaceName)) {
Luca Prete092e8952016-10-26 16:25:56 +0200453 ifacesByVplsName.put(vplsName, intf);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700454 }
455 });
456 }
457
458 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200459 public void removeIface(String ifaceName) {
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700460 SetMultimap<String, Interface> toBeRemoved = HashMultimap.create();
Luca Prete092e8952016-10-26 16:25:56 +0200461 ifacesByVplsName.entries().forEach(e -> {
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700462 if (e.getValue().name().equals(ifaceName)) {
463 toBeRemoved.put(e.getKey(), e.getValue());
464 }
465 });
466
467 toBeRemoved.entries()
Luca Prete092e8952016-10-26 16:25:56 +0200468 .forEach(e -> ifacesByVplsName.remove(e.getKey(),
469 e.getValue()));
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700470 }
471
472 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200473 public void cleanVplsConfig() {
474 ifacesByVplsName.clear();
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700475 }
476
477 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200478 public Set<Interface> allIfaces() {
479 return ImmutableSet.copyOf(ifacesByVplsName.values());
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700480 }
481
482 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200483 public Set<Interface> ifaces(String name) {
484 return ifacesByVplsName.get(name)
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700485 .stream()
486 .collect(Collectors.toSet());
487 }
488
489 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200490 public Set<String> vplsNames() {
491 return ifacesByVplsName.keySet();
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700492 }
493
494 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200495 public SetMultimap<String, Interface> ifacesByVplsName() {
496 return ImmutableSetMultimap.copyOf(ifacesByVplsName);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700497 }
498
499 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200500 public SetMultimap<String, Interface> ifacesByVplsName(VlanId vlan,
501 ConnectPoint connectPoint) {
502 String vplsName =
503 ifacesByVplsName.entries().stream()
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700504 .filter(e -> e.getValue().connectPoint().equals(connectPoint))
505 .filter(e -> e.getValue().vlan().equals(vlan))
506 .map(e -> e.getKey())
507 .findFirst()
508 .orElse(null);
509 SetMultimap<String, Interface> result = HashMultimap.create();
Luca Prete092e8952016-10-26 16:25:56 +0200510 if (vplsName != null &&
511 ifacesByVplsName.containsKey(vplsName)) {
512 ifacesByVplsName.get(vplsName)
513 .forEach(intf -> result.put(vplsName, intf));
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700514 return result;
515 }
516 return null;
517 }
518 }
519
520 class TestHostService extends HostServiceAdapter {
521 @Override
522 public Set<Host> getHostsByMac(MacAddress mac) {
523 return availableHosts.stream()
524 .filter(host -> host.mac().equals(mac))
525 .collect(Collectors.toSet());
526 }
527
528 @Override
529 public Iterable<Host> getHosts() {
530 return availableHosts;
531 }
532
533 @Override
534 public Set<Host> getHostsByVlan(VlanId vlanId) {
535 return availableHosts.stream()
536 .filter(host -> host.vlan().equals(vlanId))
537 .collect(Collectors.toSet());
538 }
539
540 @Override
541 public int getHostCount() {
542 return availableHosts.size();
543 }
544
545 @Override
546 public Host getHost(HostId hostId) {
547 return availableHosts.stream()
548 .filter(host -> host.id().equals(hostId))
549 .findFirst()
550 .orElse(null);
551 }
552 }
553
554 private class TestNeighbourService implements NeighbourResolutionService {
555 private SetMultimap<ConnectPoint, NeighbourHandlerRegistration> handlerRegs;
556
557 public TestNeighbourService() {
558 handlerRegs = HashMultimap.create();
559 }
560
561 @Override
562 public void registerNeighbourHandler(ConnectPoint connectPoint,
563 NeighbourMessageHandler handler,
564 ApplicationId appId) {
565 Interface intf =
566 new Interface(null, connectPoint, null, null, null);
567
568 NeighbourHandlerRegistration reg =
569 new HandlerRegistration(handler, intf, appId);
570
571 handlerRegs.put(connectPoint, reg);
572 }
573
574 @Override
575 public void registerNeighbourHandler(Interface intf,
576 NeighbourMessageHandler handler,
577 ApplicationId appId) {
578 NeighbourHandlerRegistration reg =
579 new HandlerRegistration(handler, intf, appId);
580 handlerRegs.put(intf.connectPoint(), reg);
581 }
582
583 @Override
584 public void unregisterNeighbourHandler(ConnectPoint connectPoint,
585 NeighbourMessageHandler handler,
586 ApplicationId appId) {
587 handlerRegs.removeAll(connectPoint);
588 }
589
590 @Override
591 public void unregisterNeighbourHandler(Interface intf,
592 NeighbourMessageHandler handler,
593 ApplicationId appId) {
594 handlerRegs.removeAll(intf.connectPoint());
595 }
596
597 @Override
598 public void unregisterNeighbourHandlers(ApplicationId appId) {
599 handlerRegs.clear();
600 }
601
602 @Override
603 public Map<ConnectPoint, Collection<NeighbourHandlerRegistration>> getHandlerRegistrations() {
604 return handlerRegs.asMap();
605 }
606
607 private class HandlerRegistration implements NeighbourHandlerRegistration {
608 private final Interface intf;
609 private final NeighbourMessageHandler handler;
610 private final ApplicationId appId;
611
612 /**
613 * Creates a new registration handler.
614 *
615 * @param handler the neighbour message handler
616 * @param intf the interface
617 */
618 public HandlerRegistration(NeighbourMessageHandler handler,
619 Interface intf,
620 ApplicationId appId) {
621 this.intf = intf;
622 this.handler = handler;
623 this.appId = appId;
624 }
625
626 @Override
627 public Interface intf() {
628 return intf;
629 }
630
631 @Override
632 public NeighbourMessageHandler handler() {
633 return handler;
634 }
635
636 @Override
637 public ApplicationId appId() {
638 return appId;
639 }
640
641 }
642 }
643
644 class TestInterfaceService implements InterfaceService {
645
646 @Override
647 public void addListener(InterfaceListener listener) {
648
649 }
650
651 @Override
652 public void removeListener(InterfaceListener listener) {
653
654 }
655
656 @Override
657 public Set<Interface> getInterfaces() {
Luca Prete092e8952016-10-26 16:25:56 +0200658 return availableInterfaces;
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700659 }
660
661 @Override
662 public Interface getInterfaceByName(ConnectPoint connectPoint,
663 String name) {
Luca Prete092e8952016-10-26 16:25:56 +0200664 return availableInterfaces.stream()
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700665 .filter(intf -> intf.name().equals(name))
666 .findFirst()
667 .orElse(null);
668
669 }
670
671 @Override
672 public Set<Interface> getInterfacesByPort(ConnectPoint port) {
Luca Prete092e8952016-10-26 16:25:56 +0200673 return availableInterfaces.stream()
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700674 .filter(intf -> intf.connectPoint().equals(port))
675 .collect(Collectors.toSet());
676 }
677
678 @Override
679 public Set<Interface> getInterfacesByIp(IpAddress ip) {
Luca Prete092e8952016-10-26 16:25:56 +0200680 return availableInterfaces.stream()
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700681 .filter(intf -> intf.ipAddressesList().contains(ip))
682 .collect(Collectors.toSet());
683 }
684
685 @Override
686 public Set<Interface> getInterfacesByVlan(VlanId vlan) {
Luca Prete092e8952016-10-26 16:25:56 +0200687 return availableInterfaces.stream()
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700688 .filter(intf -> intf.vlan().equals(vlan))
689 .collect(Collectors.toSet());
690 }
691
692 @Override
693 public Interface getMatchingInterface(IpAddress ip) {
Luca Prete092e8952016-10-26 16:25:56 +0200694 return availableInterfaces.stream()
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700695 .filter(intf -> intf.ipAddressesList().contains(ip))
696 .findFirst()
697 .orElse(null);
698 }
699 }
700}