blob: a7585dac0e1d0d993ca1a22303eb6a9e5ff6d3b0 [file] [log] [blame]
Luca Prete9c2ee072016-02-16 11:00:44 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Luca Prete9c2ee072016-02-16 11:00:44 -08003 *
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 */
16package org.onosproject.vpls;
17
Ray Milkey6e968eb2016-06-29 09:37:27 -070018import java.util.Collections;
Luca Prete092e8952016-10-26 16:25:56 +020019import java.util.HashMap;
nosignal5fd282e2016-09-16 16:11:40 -070020import java.util.HashSet;
Ray Milkey6e968eb2016-06-29 09:37:27 -070021import java.util.List;
Luca Pretec21c6e62016-09-22 14:52:21 -070022import java.util.Map;
Ray Milkey6e968eb2016-06-29 09:37:27 -070023import java.util.Set;
24import java.util.concurrent.atomic.AtomicLong;
25import java.util.stream.Collectors;
26
Luca Prete092e8952016-10-26 16:25:56 +020027import com.google.common.collect.ImmutableList;
nosignal5fd282e2016-09-16 16:11:40 -070028import com.google.common.collect.Sets;
29import com.google.common.collect.ImmutableSet;
30import com.google.common.collect.SetMultimap;
31import com.google.common.collect.HashMultimap;
Luca Pretec21c6e62016-09-22 14:52:21 -070032import com.google.common.collect.Maps;
nosignal5fd282e2016-09-16 16:11:40 -070033import com.google.common.collect.Lists;
34import com.google.common.collect.ImmutableSetMultimap;
Ray Milkey6e968eb2016-06-29 09:37:27 -070035import org.junit.After;
Luca Prete9c2ee072016-02-16 11:00:44 -080036import org.junit.Before;
Luca Prete9c2ee072016-02-16 11:00:44 -080037import org.junit.Test;
38import org.onlab.packet.Ip4Address;
39import org.onlab.packet.MacAddress;
40import org.onlab.packet.VlanId;
41import org.onosproject.TestApplicationId;
42import org.onosproject.app.ApplicationService;
43import org.onosproject.core.ApplicationId;
44import org.onosproject.core.CoreService;
45import org.onosproject.core.IdGenerator;
46import org.onosproject.incubator.net.intf.Interface;
Luca Pretea8854822016-04-26 16:30:55 -070047import org.onosproject.incubator.net.intf.InterfaceListener;
Luca Prete9c2ee072016-02-16 11:00:44 -080048import org.onosproject.incubator.net.intf.InterfaceService;
49import org.onosproject.net.ConnectPoint;
50import org.onosproject.net.DefaultHost;
51import org.onosproject.net.DeviceId;
Luca Prete092e8952016-10-26 16:25:56 +020052import org.onosproject.net.EncapsulationType;
Luca Prete9c2ee072016-02-16 11:00:44 -080053import org.onosproject.net.Host;
54import org.onosproject.net.HostId;
55import org.onosproject.net.HostLocation;
56import org.onosproject.net.PortNumber;
nosignal5fd282e2016-09-16 16:11:40 -070057import org.onosproject.net.FilteredConnectPoint;
58import org.onosproject.net.config.NetworkConfigService;
Luca Prete9c2ee072016-02-16 11:00:44 -080059import org.onosproject.net.flow.DefaultTrafficSelector;
Luca Prete9c2ee072016-02-16 11:00:44 -080060import org.onosproject.net.flow.TrafficSelector;
nosignal5fd282e2016-09-16 16:11:40 -070061import org.onosproject.net.flow.criteria.Criterion;
62import org.onosproject.net.flow.criteria.VlanIdCriterion;
Luca Prete9c2ee072016-02-16 11:00:44 -080063import org.onosproject.net.host.HostEvent;
64import org.onosproject.net.host.HostListener;
65import org.onosproject.net.host.HostService;
66import org.onosproject.net.host.HostServiceAdapter;
Luca Prete092e8952016-10-26 16:25:56 +020067import org.onosproject.net.intent.ConnectivityIntent;
Luca Prete9c2ee072016-02-16 11:00:44 -080068import org.onosproject.net.intent.Intent;
69import org.onosproject.net.intent.IntentService;
70import org.onosproject.net.intent.IntentServiceAdapter;
71import org.onosproject.net.intent.IntentUtils;
72import org.onosproject.net.intent.Key;
73import org.onosproject.net.intent.MultiPointToSinglePointIntent;
74import org.onosproject.net.intent.SinglePointToMultiPointIntent;
Luca Prete092e8952016-10-26 16:25:56 +020075import org.onosproject.net.intent.constraint.EncapsulationConstraint;
Luca Prete9c2ee072016-02-16 11:00:44 -080076import org.onosproject.net.provider.ProviderId;
77import org.onosproject.routing.IntentSynchronizationAdminService;
78import org.onosproject.routing.IntentSynchronizationService;
nosignal5fd282e2016-09-16 16:11:40 -070079import org.onosproject.vpls.config.VplsConfigurationService;
Luca Prete9c2ee072016-02-16 11:00:44 -080080
81import static java.lang.String.format;
Ray Milkey6e968eb2016-06-29 09:37:27 -070082import static org.easymock.EasyMock.anyObject;
83import static org.easymock.EasyMock.createMock;
84import static org.easymock.EasyMock.expect;
Luca Pretea8854822016-04-26 16:30:55 -070085import static org.easymock.EasyMock.expectLastCall;
Ray Milkey6e968eb2016-06-29 09:37:27 -070086import static org.easymock.EasyMock.replay;
Luca Prete9c2ee072016-02-16 11:00:44 -080087import static org.junit.Assert.assertEquals;
88import static org.junit.Assert.assertTrue;
89
Luca Prete092e8952016-10-26 16:25:56 +020090import static org.onosproject.net.EncapsulationType.*;
nosignal5fd282e2016-09-16 16:11:40 -070091import static org.onosproject.vpls.IntentInstaller.PREFIX_BROADCAST;
92import static org.onosproject.vpls.IntentInstaller.PREFIX_UNICAST;
93
Luca Prete9c2ee072016-02-16 11:00:44 -080094/**
95 * Tests for the {@link Vpls} class.
96 */
97public class VplsTest {
nosignal5fd282e2016-09-16 16:11:40 -070098 private static final String APP_NAME = "org.onosproject.vpls";
99 private static final ApplicationId APPID = TestApplicationId.create(APP_NAME);
100 private static final String DASH = "-";
101 private static final int PRIORITY_OFFSET = 1000;
Luca Prete092e8952016-10-26 16:25:56 +0200102 private static final String VPLS1 = "vpls1";
103 private static final String VPLS2 = "vpls2";
Luca Prete9c2ee072016-02-16 11:00:44 -0800104
105 private static final PortNumber P1 = PortNumber.portNumber(1);
106
Luca Prete9c2ee072016-02-16 11:00:44 -0800107 private static final DeviceId DID1 = getDeviceId(1);
108 private static final DeviceId DID2 = getDeviceId(2);
109 private static final DeviceId DID3 = getDeviceId(3);
110 private static final DeviceId DID4 = getDeviceId(4);
111 private static final DeviceId DID5 = getDeviceId(5);
112 private static final DeviceId DID6 = getDeviceId(6);
113
nosignal5fd282e2016-09-16 16:11:40 -0700114 private static final ConnectPoint CP1 = new ConnectPoint(DID1, P1);
115 private static final ConnectPoint CP2 = new ConnectPoint(DID2, P1);
116 private static final ConnectPoint CP3 = new ConnectPoint(DID3, P1);
117 private static final ConnectPoint CP4 = new ConnectPoint(DID4, P1);
118 private static final ConnectPoint CP5 = new ConnectPoint(DID5, P1);
119 private static final ConnectPoint CP6 = new ConnectPoint(DID6, P1);
Luca Prete9c2ee072016-02-16 11:00:44 -0800120
nosignal5fd282e2016-09-16 16:11:40 -0700121 private static final VlanId VLAN100 = VlanId.vlanId((short) 100);
122 private static final VlanId VLAN200 = VlanId.vlanId((short) 200);
123 private static final VlanId VLAN300 = VlanId.vlanId((short) 300);
Luca Prete9c2ee072016-02-16 11:00:44 -0800124
nosignal5fd282e2016-09-16 16:11:40 -0700125 private static final MacAddress MAC1 =
126 MacAddress.valueOf("00:00:00:00:00:01");
127 private static final MacAddress MAC2 =
128 MacAddress.valueOf("00:00:00:00:00:02");
129 private static final MacAddress MAC3 =
130 MacAddress.valueOf("00:00:00:00:00:03");
131 private static final MacAddress MAC4 =
132 MacAddress.valueOf("00:00:00:00:00:04");
133 private static final MacAddress MAC5 =
134 MacAddress.valueOf("00:00:00:00:00:05");
135 private static final MacAddress MAC6 =
136 MacAddress.valueOf("00:00:00:00:00:06");
137 private static final MacAddress MAC7 =
138 MacAddress.valueOf("00:00:00:00:00:07");
Luca Prete9c2ee072016-02-16 11:00:44 -0800139
nosignal5fd282e2016-09-16 16:11:40 -0700140 private static final Ip4Address IP1 = Ip4Address.valueOf("192.168.1.1");
141 private static final Ip4Address IP2 = Ip4Address.valueOf("192.168.1.2");
142
143 private static final HostId HID1 = HostId.hostId(MAC1, VLAN100);
144 private static final HostId HID2 = HostId.hostId(MAC2, VLAN100);
145 private static final HostId HID3 = HostId.hostId(MAC3, VLAN200);
146 private static final HostId HID4 = HostId.hostId(MAC4, VLAN200);
147 private static final HostId HID5 = HostId.hostId(MAC5, VLAN300);
148 private static final HostId HID6 = HostId.hostId(MAC6, VLAN300);
149 private static final HostId HID7 = HostId.hostId(MAC7, VLAN300);
Luca Prete9c2ee072016-02-16 11:00:44 -0800150
151 private static final ProviderId PID = new ProviderId("of", "foo");
152
Ray Milkey6e968eb2016-06-29 09:37:27 -0700153 private static IdGenerator idGenerator;
Luca Prete9c2ee072016-02-16 11:00:44 -0800154
Luca Prete092e8952016-10-26 16:25:56 +0200155 private static final Interface V100H1 =
nosignal5fd282e2016-09-16 16:11:40 -0700156 new Interface("v100h1", CP1, null, null, VLAN100);
Luca Prete092e8952016-10-26 16:25:56 +0200157 private static final Interface V100H2 =
nosignal5fd282e2016-09-16 16:11:40 -0700158 new Interface("v100h2", CP2, null, null, VLAN100);
Luca Prete092e8952016-10-26 16:25:56 +0200159 private static final Interface V200H1 =
nosignal5fd282e2016-09-16 16:11:40 -0700160 new Interface("v200h1", CP3, null, null, VLAN200);
Luca Prete092e8952016-10-26 16:25:56 +0200161 private static final Interface V200H2 =
nosignal5fd282e2016-09-16 16:11:40 -0700162 new Interface("v200h2", CP4, null, null, VLAN200);
Luca Prete092e8952016-10-26 16:25:56 +0200163 private static final Interface V300H1 =
nosignal5fd282e2016-09-16 16:11:40 -0700164 new Interface("v300h1", CP5, null, null, VLAN300);
Luca Prete092e8952016-10-26 16:25:56 +0200165 private static final Interface V300H2 =
nosignal5fd282e2016-09-16 16:11:40 -0700166 new Interface("v300h2", CP6, null, null, VLAN300);
167
Luca Prete092e8952016-10-26 16:25:56 +0200168 private static final Host V100HOST1 =
nosignal5fd282e2016-09-16 16:11:40 -0700169 new DefaultHost(PID, HID1, MAC1, VLAN100,
170 getLocation(1), Collections.singleton(IP1));
Luca Prete092e8952016-10-26 16:25:56 +0200171 private static final Host V100HOST2 =
nosignal5fd282e2016-09-16 16:11:40 -0700172 new DefaultHost(PID, HID2, MAC2, VLAN100,
173 getLocation(2), Sets.newHashSet());
Luca Prete092e8952016-10-26 16:25:56 +0200174 private static final Host V200HOST1 =
nosignal5fd282e2016-09-16 16:11:40 -0700175 new DefaultHost(PID, HID3, MAC3, VLAN200,
176 getLocation(3), Collections.singleton(IP2));
Luca Prete092e8952016-10-26 16:25:56 +0200177 private static final Host V200HOST2 =
nosignal5fd282e2016-09-16 16:11:40 -0700178 new DefaultHost(PID, HID4, MAC4, VLAN200,
179 getLocation(4), Sets.newHashSet());
Luca Prete092e8952016-10-26 16:25:56 +0200180 private static final Host V300HOST1 =
nosignal5fd282e2016-09-16 16:11:40 -0700181 new DefaultHost(PID, HID5, MAC5, VLAN300,
182 getLocation(5), Sets.newHashSet());
Luca Prete092e8952016-10-26 16:25:56 +0200183 private static final Host V300HOST2 =
nosignal5fd282e2016-09-16 16:11:40 -0700184 new DefaultHost(PID, HID6, MAC6, VLAN300,
185 getLocation(6), Sets.newHashSet());
Luca Prete092e8952016-10-26 16:25:56 +0200186 private static final Host V300HOST3 =
nosignal5fd282e2016-09-16 16:11:40 -0700187 new DefaultHost(PID, HID7, MAC7, VLAN300,
188 getLocation(7), Sets.newHashSet());
189
Luca Prete092e8952016-10-26 16:25:56 +0200190 private static final Set<Interface> AVALIABLE_INTERFACES =
191 ImmutableSet.of(V100H1, V100H2, V200H1, V200H2, V300H1, V300H2);
nosignal5fd282e2016-09-16 16:11:40 -0700192
Luca Prete092e8952016-10-26 16:25:56 +0200193 private static final Set<Host> AVALIABLE_HOSTS =
194 ImmutableSet.of(V100HOST1, V100HOST2, V200HOST1,
195 V200HOST2, V300HOST1, V300HOST2, V300HOST3);
nosignal5fd282e2016-09-16 16:11:40 -0700196
197 private ApplicationService applicationService;
198 private CoreService coreService;
199 private HostListener hostListener;
200 private NetworkConfigService configService;
201 private Set<Host> hostsAvailable;
202 private HostService hostService;
203 private IntentService intentService;
204 private InterfaceService interfaceService;
205 private VplsConfigurationService vplsConfigService;
206 private Vpls vpls;
207
Luca Prete9c2ee072016-02-16 11:00:44 -0800208 @Before
209 public void setUp() throws Exception {
Ray Milkey6e968eb2016-06-29 09:37:27 -0700210 idGenerator = new TestIdGenerator();
211 Intent.bindIdGenerator(idGenerator);
212
Luca Prete9c2ee072016-02-16 11:00:44 -0800213 applicationService = createMock(ApplicationService.class);
214
nosignal5fd282e2016-09-16 16:11:40 -0700215 configService = createMock(NetworkConfigService.class);
216
Luca Prete9c2ee072016-02-16 11:00:44 -0800217 coreService = createMock(CoreService.class);
218 expect(coreService.registerApplication(APP_NAME))
219 .andReturn(APPID);
220 replay(coreService);
221
222 hostsAvailable = Sets.newHashSet();
223 hostService = new TestHostService(hostsAvailable);
224
225 intentService = new TestIntentService();
226
227 TestIntentSynchronizer intentSynchronizer =
228 new TestIntentSynchronizer(intentService);
229
230 interfaceService = createMock(InterfaceService.class);
Luca Pretea8854822016-04-26 16:30:55 -0700231 interfaceService.addListener(anyObject(InterfaceListener.class));
232 expectLastCall().anyTimes();
Luca Prete092e8952016-10-26 16:25:56 +0200233 addIfaceConfig();
Luca Prete9c2ee072016-02-16 11:00:44 -0800234
Luca Prete092e8952016-10-26 16:25:56 +0200235 SetMultimap<String, Interface> interfacesByVpls =
nosignal5fd282e2016-09-16 16:11:40 -0700236 HashMultimap.create();
Luca Prete092e8952016-10-26 16:25:56 +0200237 interfacesByVpls.put(VPLS1, V100H1);
238 interfacesByVpls.put(VPLS1, V200H1);
239 interfacesByVpls.put(VPLS1, V300H1);
240 interfacesByVpls.put(VPLS2, V100H2);
241 interfacesByVpls.put(VPLS2, V200H2);
242 interfacesByVpls.put(VPLS2, V300H2);
nosignal5fd282e2016-09-16 16:11:40 -0700243
Luca Prete092e8952016-10-26 16:25:56 +0200244 Map<String, EncapsulationType> encapByVpls = new HashMap<>();
245 encapByVpls.put(VPLS1, VLAN);
246 encapByVpls.put(VPLS2, NONE);
247
248 vplsConfigService = new TestVplsConfigService(interfacesByVpls, encapByVpls);
nosignal5fd282e2016-09-16 16:11:40 -0700249
Luca Prete9c2ee072016-02-16 11:00:44 -0800250 vpls = new Vpls();
251 vpls.applicationService = applicationService;
252 vpls.coreService = coreService;
253 vpls.hostService = hostService;
nosignal5fd282e2016-09-16 16:11:40 -0700254 vpls.vplsConfigService = vplsConfigService;
Luca Prete9c2ee072016-02-16 11:00:44 -0800255 vpls.intentService = intentService;
256 vpls.interfaceService = interfaceService;
nosignal5fd282e2016-09-16 16:11:40 -0700257 vpls.configService = configService;
Luca Prete9c2ee072016-02-16 11:00:44 -0800258 vpls.intentSynchronizer = intentSynchronizer;
Yi Tseng28767f02016-09-13 04:27:20 -0700259
Luca Prete9c2ee072016-02-16 11:00:44 -0800260 }
261
Ray Milkey6e968eb2016-06-29 09:37:27 -0700262 @After
263 public void tearDown() {
264 Intent.unbindIdGenerator(idGenerator);
265 }
266
Luca Prete9c2ee072016-02-16 11:00:44 -0800267 /**
nosignal5fd282e2016-09-16 16:11:40 -0700268 * Creates the interface configuration. On devices 1 and 2 is configured
269 * an interface on port 1 with vlan 100. On devices 3 and 4 is configured
270 * an interface on port 1 with vlan 200. On device 5 and 6 is configured
271 * an interface on port 1 with vlan 300.
Luca Prete9c2ee072016-02-16 11:00:44 -0800272 */
Luca Prete092e8952016-10-26 16:25:56 +0200273 private void addIfaceConfig() {
274 Set<Interface> interfaces = ImmutableSet.copyOf(AVALIABLE_INTERFACES);
275 Set<Interface> vlanOneSet = ImmutableSet.of(V100H1, V100H2);
276 Set<Interface> vlanTwoSet = ImmutableSet.of(V200H1, V200H2);
277 Set<Interface> vlanThreeSet = ImmutableSet.of(V300H1, V300H2);
Luca Prete9c2ee072016-02-16 11:00:44 -0800278
Luca Prete092e8952016-10-26 16:25:56 +0200279 AVALIABLE_INTERFACES.forEach(intf -> {
nosignal5fd282e2016-09-16 16:11:40 -0700280 expect(interfaceService.getInterfacesByPort(intf.connectPoint()))
Luca Prete9c2ee072016-02-16 11:00:44 -0800281 .andReturn(Sets.newHashSet(intf)).anyTimes();
nosignal5fd282e2016-09-16 16:11:40 -0700282 });
283 expect(interfaceService.getInterfacesByVlan(VLAN100))
Luca Prete9c2ee072016-02-16 11:00:44 -0800284 .andReturn(vlanOneSet).anyTimes();
nosignal5fd282e2016-09-16 16:11:40 -0700285 expect(interfaceService.getInterfacesByVlan(VLAN200))
Luca Prete9c2ee072016-02-16 11:00:44 -0800286 .andReturn(vlanTwoSet).anyTimes();
nosignal5fd282e2016-09-16 16:11:40 -0700287 expect(interfaceService.getInterfacesByVlan(VLAN300))
288 .andReturn(vlanThreeSet).anyTimes();
Luca Prete9c2ee072016-02-16 11:00:44 -0800289 expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
290
291 replay(interfaceService);
292 }
293
294 /**
nosignal5fd282e2016-09-16 16:11:40 -0700295 * Six ports are configured with VLANs but no hosts are registered by the
Luca Prete092e8952016-10-26 16:25:56 +0200296 * HostService. The first three ports have an interface configured on VPLS 1,
297 * the other three on VPLS 2. The number of intents expected is six: three for
298 * VPLS 1, three for VPLS 2. Six MP2SP intents. Checks if the number of intents
nosignal5fd282e2016-09-16 16:11:40 -0700299 * submitted to the intent framework is equal to the number of intents
300 * expected and if all intents are equivalent.
Luca Prete9c2ee072016-02-16 11:00:44 -0800301 */
302 @Test
Luca Prete092e8952016-10-26 16:25:56 +0200303 public void activateNoHosts() {
Luca Prete9c2ee072016-02-16 11:00:44 -0800304 vpls.activate();
305
Yi Tseng28767f02016-09-13 04:27:20 -0700306 List<Intent> expectedIntents = Lists.newArrayList();
nosignal5fd282e2016-09-16 16:11:40 -0700307 Set<FilteredConnectPoint> fcPoints;
308
Luca Prete092e8952016-10-26 16:25:56 +0200309 fcPoints = buildFCPoints(ImmutableSet.of(V100H1, V200H1, V300H1));
310 expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS1, VLAN));
nosignal5fd282e2016-09-16 16:11:40 -0700311
Luca Prete092e8952016-10-26 16:25:56 +0200312 fcPoints = buildFCPoints(ImmutableSet.of(V100H2, V200H2, V300H2));
313 expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS2, NONE));
Luca Prete9c2ee072016-02-16 11:00:44 -0800314
315 checkIntents(expectedIntents);
316 }
317
318 /**
nosignal5fd282e2016-09-16 16:11:40 -0700319 * Six ports are configured with VLANs and six hosts are registered by the
Luca Prete092e8952016-10-26 16:25:56 +0200320 * HostService. The first three ports have an interface configured on VPLS 1,
321 * the other three on VPLS 2. The number of intents expected is twelve: six
322 * for VLAN 1, six for VPLS 2. six sp2mp intents, six mp2sp intents. For VPLS 1
nosignal5fd282e2016-09-16 16:11:40 -0700323 * IPs are added to demonstrate this doesn't influence the number of intents
324 * created. Checks if the number of intents submitted to the intent
325 * framework is equal to the number of intents expected and if all intents
326 * are equivalent.
Luca Prete9c2ee072016-02-16 11:00:44 -0800327 */
328 @Test
Luca Prete092e8952016-10-26 16:25:56 +0200329 public void sixInterfacesConfiguredHostsPresent() {
330 hostsAvailable.addAll(AVALIABLE_HOSTS);
Luca Prete9c2ee072016-02-16 11:00:44 -0800331
332 vpls.activate();
333
Yi Tseng28767f02016-09-13 04:27:20 -0700334 List<Intent> expectedIntents = Lists.newArrayList();
nosignal5fd282e2016-09-16 16:11:40 -0700335 Set<FilteredConnectPoint> fcPoints;
336 Set<Host> hosts;
337
Luca Prete092e8952016-10-26 16:25:56 +0200338 fcPoints = buildFCPoints(ImmutableSet.of(V100H1, V200H1, V300H1));
339 hosts = ImmutableSet.of(V100HOST1, V200HOST1, V300HOST1);
340 expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS1, VLAN));
341 expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS1, VLAN));
nosignal5fd282e2016-09-16 16:11:40 -0700342
Luca Prete092e8952016-10-26 16:25:56 +0200343 fcPoints = buildFCPoints(ImmutableSet.of(V100H2, V200H2, V300H2));
344 hosts = ImmutableSet.of(V100HOST2, V200HOST2, V300HOST2);
345 expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS2, NONE));
346 expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS2, NONE));
Luca Prete9c2ee072016-02-16 11:00:44 -0800347
348 checkIntents(expectedIntents);
349 }
350
351 /**
nosignal5fd282e2016-09-16 16:11:40 -0700352 * Six ports are configured with VLANs and initially no hosts are registered
353 * by the HostService. The first three ports have an interface configured on
Luca Prete092e8952016-10-26 16:25:56 +0200354 * VPLS 1, the other three have an interface configured on VPLS 2. When the
nosignal5fd282e2016-09-16 16:11:40 -0700355 * module starts up, three hosts attached to device one, two and three -
356 * port 1, are registered by the HostService and events are sent to the
357 * application. sp2mp intents are created for all interfaces configured and
358 * mp2sp intents are created only for the hosts attached.
Luca Prete092e8952016-10-26 16:25:56 +0200359 * The number of intents expected is nine: six for VPLS 1, three for VPLS 2.
Luca Prete9c2ee072016-02-16 11:00:44 -0800360 * Six sp2mp intents, three mp2sp intents. IPs are added on the first two
nosignal5fd282e2016-09-16 16:11:40 -0700361 * hosts only to demonstrate this doesn't influence the number of intents
Luca Prete9c2ee072016-02-16 11:00:44 -0800362 * created.
nosignal5fd282e2016-09-16 16:11:40 -0700363 * An additional host is added on device seven - port 1, to demonstrate that
364 * the application does not generate intents, even if the interface uses the
365 * same VLAN Id of the other interfaces configured for the specifc VPLS.
366 * Checks if the number of intents submitted to the intent framework is equal
367 * to the number of intents expected and if all intents are equivalent.
Luca Prete9c2ee072016-02-16 11:00:44 -0800368 */
369 @Test
Luca Prete092e8952016-10-26 16:25:56 +0200370 public void sixInterfacesThreeHostEventsSameVpls() {
Luca Prete9c2ee072016-02-16 11:00:44 -0800371 vpls.activate();
372
nosignal5fd282e2016-09-16 16:11:40 -0700373 List<Intent> expectedIntents = Lists.newArrayList();
374 Set<FilteredConnectPoint> fcPoints;
375 Set<Host> hosts;
376
Luca Prete092e8952016-10-26 16:25:56 +0200377 hostsAvailable.addAll(Sets.newHashSet(V100HOST1, V200HOST1, V300HOST1, V300HOST3));
Luca Prete9c2ee072016-02-16 11:00:44 -0800378
379 hostsAvailable.forEach(host ->
nosignal5fd282e2016-09-16 16:11:40 -0700380 hostListener.event(new HostEvent(HostEvent.Type.HOST_ADDED, host)));
Luca Prete9c2ee072016-02-16 11:00:44 -0800381
Luca Prete092e8952016-10-26 16:25:56 +0200382 fcPoints = buildFCPoints(ImmutableSet.of(V100H1, V200H1, V300H1));
383 hosts = ImmutableSet.of(V100HOST1, V200HOST1, V300HOST1);
384 expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS1, VLAN));
385 expectedIntents.addAll(generateVplsUni(fcPoints, hosts, VPLS1, VLAN));
nosignal5fd282e2016-09-16 16:11:40 -0700386
Luca Prete092e8952016-10-26 16:25:56 +0200387 fcPoints = buildFCPoints(ImmutableSet.of(V100H2, V200H2, V300H2));
388 expectedIntents.addAll(generateVplsBrc(fcPoints, VPLS2, NONE));
Luca Prete9c2ee072016-02-16 11:00:44 -0800389
390 checkIntents(expectedIntents);
391 }
392
393 /**
nosignal5fd282e2016-09-16 16:11:40 -0700394 * Generates a list of the expected sp2mp intents for a VPLS.
395 *
396 * @param fcPoints the filtered connect point
397 * @param name the name of the VPLS
Luca Prete092e8952016-10-26 16:25:56 +0200398 * @param encap the encapsulation type
nosignal5fd282e2016-09-16 16:11:40 -0700399 * @return the list of expected sp2mp intents for the given VPLS
Luca Prete9c2ee072016-02-16 11:00:44 -0800400 */
nosignal5fd282e2016-09-16 16:11:40 -0700401 private List<SinglePointToMultiPointIntent>
Luca Prete092e8952016-10-26 16:25:56 +0200402 generateVplsBrc(Set<FilteredConnectPoint> fcPoints, String name, EncapsulationType encap) {
nosignal5fd282e2016-09-16 16:11:40 -0700403 List<SinglePointToMultiPointIntent> intents = Lists.newArrayList();
Luca Prete9c2ee072016-02-16 11:00:44 -0800404
nosignal5fd282e2016-09-16 16:11:40 -0700405 fcPoints.forEach(point -> {
406 Set<FilteredConnectPoint> otherPoints =
407 fcPoints.stream()
408 .filter(fcp -> !fcp.equals(point))
409 .collect(Collectors.toSet());
Luca Prete9c2ee072016-02-16 11:00:44 -0800410
nosignal5fd282e2016-09-16 16:11:40 -0700411 Key brckey = buildKey(PREFIX_BROADCAST,
412 point.connectPoint(), name, MacAddress.BROADCAST);
413
Luca Prete092e8952016-10-26 16:25:56 +0200414 intents.add(buildBrcIntent(brckey, point, otherPoints, encap));
Luca Prete9c2ee072016-02-16 11:00:44 -0800415 });
416
nosignal5fd282e2016-09-16 16:11:40 -0700417 return intents;
Luca Prete9c2ee072016-02-16 11:00:44 -0800418 }
419
420 /**
nosignal5fd282e2016-09-16 16:11:40 -0700421 * Generates a list of expected mp2sp intents for a given VPLS.
422 *
423 * @param fcPoints the filtered connect point
424 * @param hosts the hosts
425 * @param name the name of the VPLS
Luca Prete092e8952016-10-26 16:25:56 +0200426 * @param encap the encapsulation type
nosignal5fd282e2016-09-16 16:11:40 -0700427 * @return the list of expected mp2sp intents for the given VPLS
428 */
429 private List<MultiPointToSinglePointIntent>
Luca Prete092e8952016-10-26 16:25:56 +0200430 generateVplsUni(Set<FilteredConnectPoint> fcPoints, Set<Host> hosts,
431 String name, EncapsulationType encap) {
nosignal5fd282e2016-09-16 16:11:40 -0700432 List<MultiPointToSinglePointIntent> intents = Lists.newArrayList();
433
434 hosts.forEach(host -> {
435 FilteredConnectPoint hostPoint = getHostPoint(host, fcPoints);
436
437 Set<FilteredConnectPoint> otherPoints =
438 fcPoints.stream()
439 .filter(fcp -> !fcp.equals(hostPoint))
440 .collect(Collectors.toSet());
441
442 Key uniKey = buildKey(PREFIX_UNICAST,
443 host.location(), name, host.mac());
444
Luca Prete092e8952016-10-26 16:25:56 +0200445 intents.add(buildUniIntent(uniKey, otherPoints, hostPoint, host, encap));
nosignal5fd282e2016-09-16 16:11:40 -0700446 });
447
448 return intents;
449 }
450
451 /**
452 * Checks if the number of intents submitted to the intent framework is equal
453 * to the number of intents expected and if all intents are equivalent.
Luca Prete9c2ee072016-02-16 11:00:44 -0800454 *
455 * @param intents the list of intents expected
456 */
457 private void checkIntents(List<Intent> intents) {
Luca Prete092e8952016-10-26 16:25:56 +0200458 assertEquals("The number of intents submitted differs from the number" +
459 "of intents expected",
460 intents.size(), intentService.getIntentCount());
Luca Prete9c2ee072016-02-16 11:00:44 -0800461
462 for (Intent intentOne : intents) {
463 boolean found = false;
464 for (Intent intentTwo : intentService.getIntents()) {
465 if (intentOne.key().equals(intentTwo.key())) {
466 found = true;
Luca Prete092e8952016-10-26 16:25:56 +0200467 assertTrue(format("The intent submitted is different from" +
468 "the intent expected",
469 intentOne, intentTwo),
nosignal5fd282e2016-09-16 16:11:40 -0700470 IntentUtils.intentsAreEqual(intentOne, intentTwo));
Luca Prete9c2ee072016-02-16 11:00:44 -0800471 break;
472 }
473 }
Luca Prete092e8952016-10-26 16:25:56 +0200474 assertTrue("The intent submitted is not equal to any of the expected" +
475 "intents", found);
Luca Prete9c2ee072016-02-16 11:00:44 -0800476 }
477 }
478
479 /**
nosignal5fd282e2016-09-16 16:11:40 -0700480 * Builds a broadcast intent.
Luca Prete9c2ee072016-02-16 11:00:44 -0800481 *
nosignal5fd282e2016-09-16 16:11:40 -0700482 * @param key the key to identify the intent
483 * @param src the ingress connect point
484 * @param dsts the egress connect points
485 * @return the generated single-point to multi-point intent
Luca Prete9c2ee072016-02-16 11:00:44 -0800486 */
487 private SinglePointToMultiPointIntent buildBrcIntent(Key key,
Luca Prete092e8952016-10-26 16:25:56 +0200488 FilteredConnectPoint src,
489 Set<FilteredConnectPoint> dsts,
490 EncapsulationType encap) {
491 SinglePointToMultiPointIntent.Builder intentBuilder;
Luca Prete9c2ee072016-02-16 11:00:44 -0800492
Luca Prete9c2ee072016-02-16 11:00:44 -0800493 TrafficSelector selector = DefaultTrafficSelector.builder()
494 .matchEthDst(MacAddress.BROADCAST)
Luca Prete9c2ee072016-02-16 11:00:44 -0800495 .build();
496
Luca Prete092e8952016-10-26 16:25:56 +0200497 intentBuilder = SinglePointToMultiPointIntent.builder()
Luca Prete9c2ee072016-02-16 11:00:44 -0800498 .appId(APPID)
499 .key(key)
500 .selector(selector)
nosignal5fd282e2016-09-16 16:11:40 -0700501 .filteredIngressPoint(src)
502 .filteredEgressPoints(dsts)
Luca Prete092e8952016-10-26 16:25:56 +0200503 .priority(PRIORITY_OFFSET);
504
505 encap(intentBuilder, encap);
506
507 return intentBuilder.build();
Luca Prete9c2ee072016-02-16 11:00:44 -0800508 }
509
510 /**
nosignal5fd282e2016-09-16 16:11:40 -0700511 * Builds a unicast intent.
Luca Prete9c2ee072016-02-16 11:00:44 -0800512 *
nosignal5fd282e2016-09-16 16:11:40 -0700513 * @param key the key to identify the intent
514 * @param srcs the ingress connect points
515 * @param dst the egress connect point
516 * @param host the destination Host
517 * @return the generated multi-point to single-point intent
Luca Prete9c2ee072016-02-16 11:00:44 -0800518 */
519 private MultiPointToSinglePointIntent buildUniIntent(Key key,
Luca Prete092e8952016-10-26 16:25:56 +0200520 Set<FilteredConnectPoint> srcs,
521 FilteredConnectPoint dst,
522 Host host,
523 EncapsulationType encap) {
524 MultiPointToSinglePointIntent.Builder intentBuilder;
525
nosignal5fd282e2016-09-16 16:11:40 -0700526 TrafficSelector selector = DefaultTrafficSelector.builder()
527 .matchEthDst(host.mac())
528 .build();
Luca Prete9c2ee072016-02-16 11:00:44 -0800529
Luca Prete092e8952016-10-26 16:25:56 +0200530 intentBuilder = MultiPointToSinglePointIntent.builder()
Luca Prete9c2ee072016-02-16 11:00:44 -0800531 .appId(APPID)
532 .key(key)
533 .selector(selector)
nosignal5fd282e2016-09-16 16:11:40 -0700534 .filteredIngressPoints(srcs)
535 .filteredEgressPoint(dst)
Luca Prete092e8952016-10-26 16:25:56 +0200536 .priority(PRIORITY_OFFSET);
nosignal5fd282e2016-09-16 16:11:40 -0700537
Luca Prete092e8952016-10-26 16:25:56 +0200538 encap(intentBuilder, encap);
539
540 return intentBuilder.build();
Luca Prete9c2ee072016-02-16 11:00:44 -0800541 }
542
543 /**
nosignal5fd282e2016-09-16 16:11:40 -0700544 * Returns the filtered connect point associated to a given host.
Luca Prete9c2ee072016-02-16 11:00:44 -0800545 *
nosignal5fd282e2016-09-16 16:11:40 -0700546 * @param host the target host
547 * @param fcps the filtered connected points
548 * @return the filtered connect point associated to the given host; null
549 * otherwise
550 */
551 private FilteredConnectPoint getHostPoint(Host host,
552 Set<FilteredConnectPoint> fcps) {
553 return fcps.stream()
554 .filter(fcp -> fcp.connectPoint().equals(host.location()))
555 .filter(fcp -> {
556 VlanIdCriterion vlanCriterion =
557 (VlanIdCriterion) fcp.trafficSelector().
558 getCriterion(Criterion.Type.VLAN_VID);
559
560 return vlanCriterion != null &&
561 vlanCriterion.vlanId().equals(host.vlan());
562 })
563 .findFirst()
564 .orElse(null);
565 }
566
567 /**
568 * Computes a set of filtered connect points from given interfaces.
569 *
570 * @param interfaces the interfaces belonging to the VPLS
571 * @return the set of filtered connect points
572 */
573 private Set<FilteredConnectPoint> buildFCPoints(Set<Interface> interfaces) {
Luca Prete092e8952016-10-26 16:25:56 +0200574 // Build all filtered connected point for the VPLS
nosignal5fd282e2016-09-16 16:11:40 -0700575 return interfaces
576 .stream()
577 .map(intf -> {
578 TrafficSelector.Builder selectorBuilder =
579 DefaultTrafficSelector.builder();
580
581 if (!intf.vlan().equals(VlanId.NONE)) {
582 selectorBuilder.matchVlanId(intf.vlan());
583 }
584
585 return new FilteredConnectPoint(intf.connectPoint(),
586 selectorBuilder.build());
587 })
588 .collect(Collectors.toSet());
589 }
590
591 /**
592 * Builds an intent Key either for a single-point to multi-point or
593 * multi-point to single-point intent, based on a prefix that defines
594 * the intent type, the connection point representing the source or the
Luca Prete092e8952016-10-26 16:25:56 +0200595 * destination and the VLAN Id representing the VPLS.
nosignal5fd282e2016-09-16 16:11:40 -0700596 *
597 * @param prefix the key prefix
598 * @param cPoint the ingress/egress connect point
Luca Prete092e8952016-10-26 16:25:56 +0200599 * @param vplsName the VPLS name
nosignal5fd282e2016-09-16 16:11:40 -0700600 * @param hostMac the ingress/egress MAC address
601 * @return the key to identify the intent
602 */
603 private Key buildKey(String prefix,
604 ConnectPoint cPoint,
Luca Prete092e8952016-10-26 16:25:56 +0200605 String vplsName,
nosignal5fd282e2016-09-16 16:11:40 -0700606 MacAddress hostMac) {
Luca Prete092e8952016-10-26 16:25:56 +0200607 String keyString = vplsName +
nosignal5fd282e2016-09-16 16:11:40 -0700608 DASH +
609 prefix +
610 DASH +
611 cPoint.deviceId() +
612 DASH +
613 cPoint.port() +
614 DASH +
615 hostMac;
616
617 return Key.of(keyString, APPID);
618 }
619
620 /**
Luca Prete092e8952016-10-26 16:25:56 +0200621 * Adds an encapsulation constraint to the builder given, if encap is not
622 * equal to NONE.
623 *
624 * @param builder the intent builder
625 * @param encap the encapsulation type
626 */
627 private static void encap(ConnectivityIntent.Builder builder,
628 EncapsulationType encap) {
629 if (!encap.equals(NONE)) {
630 builder.constraints(ImmutableList.of(
631 new EncapsulationConstraint(encap)));
632 }
633 }
634
635 /**
nosignal5fd282e2016-09-16 16:11:40 -0700636 * Returns the device Id of the ith device.
637 *
638 * @param i the device to get the Id of
639 * @return the device Id
Luca Prete9c2ee072016-02-16 11:00:44 -0800640 */
641 private static DeviceId getDeviceId(int i) {
642 return DeviceId.deviceId("" + i);
643 }
644
645 private static HostLocation getLocation(int i) {
646 return new HostLocation(new ConnectPoint(getDeviceId(i), P1), 123L);
647 }
648
649 /**
nosignal5fd282e2016-09-16 16:11:40 -0700650 * Represents a fake IntentService class that allows to store and retrieve
651 * intents without implementing the IntentService logic.
Luca Prete9c2ee072016-02-16 11:00:44 -0800652 */
653 private class TestIntentService extends IntentServiceAdapter {
654
Luca Pretec21c6e62016-09-22 14:52:21 -0700655 private Map<Key, Intent> intents;
Luca Prete9c2ee072016-02-16 11:00:44 -0800656
657 public TestIntentService() {
Luca Pretec21c6e62016-09-22 14:52:21 -0700658 intents = Maps.newHashMap();
Luca Prete9c2ee072016-02-16 11:00:44 -0800659 }
660
661 @Override
662 public void submit(Intent intent) {
Luca Pretec21c6e62016-09-22 14:52:21 -0700663 intents.put(intent.key(), intent);
Luca Prete9c2ee072016-02-16 11:00:44 -0800664 }
665
666 @Override
667 public long getIntentCount() {
668 return intents.size();
669 }
670
671 @Override
672 public Iterable<Intent> getIntents() {
Luca Pretec21c6e62016-09-22 14:52:21 -0700673 return intents.values();
Luca Prete9c2ee072016-02-16 11:00:44 -0800674 }
675
676 @Override
677 public Intent getIntent(Key intentKey) {
Luca Pretec21c6e62016-09-22 14:52:21 -0700678 for (Intent intent : intents.values()) {
Luca Prete9c2ee072016-02-16 11:00:44 -0800679 if (intent.key().equals(intentKey)) {
680 return intent;
681 }
682 }
683 return null;
684 }
685 }
686
687 /**
688 * Represents a fake HostService class which allows to add hosts manually
689 * in each test, when needed.
690 */
691 private class TestHostService extends HostServiceAdapter {
692
693 private Set<Host> hosts;
694
695 public TestHostService(Set<Host> hosts) {
696 this.hosts = hosts;
697 }
698
699 @Override
700 public void addListener(HostListener listener) {
701 VplsTest.this.hostListener = listener;
702 }
703
704 @Override
705 public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
706 return hosts.stream()
nosignal5fd282e2016-09-16 16:11:40 -0700707 .filter(h -> h.location().equals(connectPoint))
Luca Prete9c2ee072016-02-16 11:00:44 -0800708 .collect(Collectors.toSet());
709 }
710
711 }
712
nosignal5fd282e2016-09-16 16:11:40 -0700713 /**
714 * Represents a fake IdGenerator class for intents.
715 */
Luca Prete9c2ee072016-02-16 11:00:44 -0800716 private static class TestIdGenerator implements IdGenerator {
717
718 private final AtomicLong id = new AtomicLong(0);
719
720 @Override
721 public long getNewId() {
722 return id.getAndIncrement();
723 }
724
725 }
726
727 /**
728 * Test IntentSynchronizer that passes all intents straight through to the
729 * intent service.
730 */
731 private class TestIntentSynchronizer implements IntentSynchronizationService,
732 IntentSynchronizationAdminService {
733
734 private final IntentService intentService;
735
736 /**
nosignal5fd282e2016-09-16 16:11:40 -0700737 * Creates a new intent test synchronizer.
Luca Prete9c2ee072016-02-16 11:00:44 -0800738 *
739 * @param intentService intent service
740 */
741 public TestIntentSynchronizer(IntentService intentService) {
742 this.intentService = intentService;
743 }
744
745 @Override
746 public void submit(Intent intent) {
747 intentService.submit(intent);
748 }
749
750 @Override
751 public void withdraw(Intent intent) {
752 intentService.withdraw(intent);
753 }
754
755 @Override
756 public void modifyPrimary(boolean isPrimary) {
Luca Prete9c2ee072016-02-16 11:00:44 -0800757 }
758
759 @Override
760 public void removeIntents() {
Luca Prete2705d662016-04-29 15:30:23 -0700761 }
Luca Prete9c2ee072016-02-16 11:00:44 -0800762
Luca Prete2705d662016-04-29 15:30:23 -0700763 @Override
764 public void removeIntentsByAppId(ApplicationId applicationId) {
Luca Prete9c2ee072016-02-16 11:00:44 -0800765 }
766 }
767
nosignal5fd282e2016-09-16 16:11:40 -0700768 /**
769 * Represents a fake VplsConfigService class which is needed for testing.
770 */
Luca Prete092e8952016-10-26 16:25:56 +0200771 private class TestVplsConfigService extends VplsConfigurationServiceAdapter {
nosignal5fd282e2016-09-16 16:11:40 -0700772
Luca Prete092e8952016-10-26 16:25:56 +0200773 private final SetMultimap<String, Interface> ifacesByVplsName;
774 private final Map<String, EncapsulationType> encapsByVplsName;
775
nosignal5fd282e2016-09-16 16:11:40 -0700776 private Set<String> vplsAffectByApi = new HashSet<>();
777
Luca Prete092e8952016-10-26 16:25:56 +0200778 TestVplsConfigService(SetMultimap<String, Interface> ifacesByVplsName,
779 Map<String, EncapsulationType> encapsByVplsName) {
780 this.ifacesByVplsName = ifacesByVplsName;
781 this.encapsByVplsName = encapsByVplsName;
nosignal5fd282e2016-09-16 16:11:40 -0700782 }
783
784 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200785 public void addVpls(String vplsName, Set<String> ifaceNames, String encap) {
786 if (!ifacesByVplsName.containsKey(vplsName)) {
787 ifaceNames.forEach(ifaceName -> {
788 AVALIABLE_INTERFACES.forEach(iface -> {
789 if (iface.name().equals(ifaceName)) {
790 ifacesByVplsName.put(vplsName, iface);
nosignal5fd282e2016-09-16 16:11:40 -0700791 }
792 });
793 });
Luca Prete092e8952016-10-26 16:25:56 +0200794 encapsByVplsName.put(vplsName, valueOf(encap));
nosignal5fd282e2016-09-16 16:11:40 -0700795 }
796 }
797
798 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200799 public void removeVpls(String vplsName) {
800 if (ifacesByVplsName.containsKey(vplsName)) {
801 ifacesByVplsName.removeAll(vplsName);
nosignal5fd282e2016-09-16 16:11:40 -0700802 }
803 }
804
805 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200806 public void addIface(String vplsName, String iface) {
807 if (!ifacesByVplsName.containsKey(vplsName)) {
808 AVALIABLE_INTERFACES.forEach(intf -> {
nosignal5fd282e2016-09-16 16:11:40 -0700809 if (intf.name().equals(iface)) {
Luca Prete092e8952016-10-26 16:25:56 +0200810 ifacesByVplsName.put(vplsName, intf);
nosignal5fd282e2016-09-16 16:11:40 -0700811 }
812 });
813 }
814 }
815
816 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200817 public void setEncap(String vplsName, String encap) {
818 encapsByVplsName.put(vplsName, EncapsulationType.enumFromString(encap));
819 }
820
821 @Override
822 public void removeIface(String iface) {
823 SetMultimap<String, Interface> search = HashMultimap.create(ifacesByVplsName);
nosignal5fd282e2016-09-16 16:11:40 -0700824 search.entries().forEach(e -> {
825 if (e.getValue().name().equals(iface)) {
Luca Prete092e8952016-10-26 16:25:56 +0200826 ifacesByVplsName.remove(e.getKey(), iface);
nosignal5fd282e2016-09-16 16:11:40 -0700827 }
828 });
829 }
830
831 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200832 public void cleanVplsConfig() {
833 ifacesByVplsName.clear();
nosignal5fd282e2016-09-16 16:11:40 -0700834 }
835
836 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200837 public EncapsulationType encap(String vplsName) {
838 EncapsulationType encap = null;
839 if (encapsByVplsName.containsKey(vplsName)) {
840 encap = encapsByVplsName.get(vplsName);
841 }
842 return encap;
843 }
844
845 @Override
846 public Set<String> vplsAffectedByApi() {
nosignal5fd282e2016-09-16 16:11:40 -0700847 Set<String> vplsNames = ImmutableSet.copyOf(vplsAffectByApi);
848
849 vplsAffectByApi.clear();
850
851 return vplsNames;
852 }
853
854 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200855 public Set<Interface> allIfaces() {
856 return ifacesByVplsName.values()
nosignal5fd282e2016-09-16 16:11:40 -0700857 .stream()
858 .collect(Collectors.toSet());
859 }
860
861 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200862 public Set<Interface> ifaces(String name) {
863 return ifacesByVplsName.get(name)
nosignal5fd282e2016-09-16 16:11:40 -0700864 .stream()
865 .collect(Collectors.toSet());
866 }
867
868 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200869 public Set<String> vplsNames() {
870 return ifacesByVplsName.keySet();
nosignal5fd282e2016-09-16 16:11:40 -0700871 }
872
873 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200874 public Set<String> vplsNamesOld() {
875 return ifacesByVplsName.keySet();
876 }
877
878 public SetMultimap<String, Interface> ifacesByVplsName() {
879 return ImmutableSetMultimap.copyOf(ifacesByVplsName);
nosignal5fd282e2016-09-16 16:11:40 -0700880 }
881
882 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200883 public SetMultimap<String, Interface> ifacesByVplsName(VlanId vlan,
nosignal5fd282e2016-09-16 16:11:40 -0700884 ConnectPoint connectPoint) {
Luca Prete092e8952016-10-26 16:25:56 +0200885 String vplsName =
886 ifacesByVplsName.entries().stream()
nosignal5fd282e2016-09-16 16:11:40 -0700887 .filter(e -> e.getValue().connectPoint().equals(connectPoint))
888 .filter(e -> e.getValue().vlan().equals(vlan))
889 .map(e -> e.getKey())
890 .findFirst()
891 .orElse(null);
892 SetMultimap<String, Interface> result = HashMultimap.create();
Luca Prete092e8952016-10-26 16:25:56 +0200893 if (vplsName != null && ifacesByVplsName.containsKey(vplsName)) {
894 ifacesByVplsName.get(vplsName)
895 .forEach(intf -> result.put(vplsName, intf));
nosignal5fd282e2016-09-16 16:11:40 -0700896 return result;
897 }
898 return null;
899 }
nosignal5fd282e2016-09-16 16:11:40 -0700900 }
Luca Prete9c2ee072016-02-16 11:00:44 -0800901}