blob: 0172dc7c9fe982e78d52f113ebc161aa04c17de3 [file] [log] [blame]
alshabibab984662014-12-04 18:56:18 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
alshabibab984662014-12-04 18:56:18 -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 */
Jonathan Hart6af92be2016-01-05 20:52:25 -080016package org.onosproject.routing.impl;
Pingpingf5d90932014-10-27 10:50:04 -070017
Jonathan Hart00cddda2016-02-16 10:30:37 -080018import com.google.common.collect.Lists;
Jonathan Hart552e31f2015-02-06 11:11:59 -080019import com.google.common.collect.Sets;
Jonathan Hart9a426f82015-09-03 15:43:13 +020020import com.google.common.util.concurrent.MoreExecutors;
Pingpingf5d90932014-10-27 10:50:04 -070021import org.junit.Before;
22import org.junit.Test;
23import org.onlab.junit.TestUtils;
24import org.onlab.junit.TestUtils.TestUtilsException;
Jonathan Hart6cd2f352015-01-13 17:44:45 -080025import org.onlab.packet.Ethernet;
26import org.onlab.packet.Ip4Address;
27import org.onlab.packet.Ip4Prefix;
28import org.onlab.packet.IpAddress;
29import org.onlab.packet.IpPrefix;
30import org.onlab.packet.MacAddress;
31import org.onlab.packet.VlanId;
Jonathan Hart9a426f82015-09-03 15:43:13 +020032import org.onosproject.TestApplicationId;
Madan Jampani620f70d2016-01-30 22:22:47 -080033import org.onosproject.cluster.ClusterServiceAdapter;
34import org.onosproject.cluster.ControllerNode;
35import org.onosproject.cluster.DefaultControllerNode;
Jonathan Hart365335e2015-12-10 11:09:53 -080036import org.onosproject.cluster.LeadershipServiceAdapter;
Madan Jampani620f70d2016-01-30 22:22:47 -080037import org.onosproject.cluster.NodeId;
Brian O'Connorabafb502014-12-02 22:26:20 -080038import org.onosproject.core.ApplicationId;
Jonathan Hart365335e2015-12-10 11:09:53 -080039import org.onosproject.core.CoreServiceAdapter;
Jonathan Hart4cb39882015-08-12 23:50:55 -040040import org.onosproject.incubator.net.intf.Interface;
Brian O'Connorabafb502014-12-02 22:26:20 -080041import org.onosproject.net.ConnectPoint;
Brian O'Connorabafb502014-12-02 22:26:20 -080042import org.onosproject.net.DeviceId;
Brian O'Connorabafb502014-12-02 22:26:20 -080043import org.onosproject.net.PortNumber;
44import org.onosproject.net.flow.DefaultTrafficSelector;
45import org.onosproject.net.flow.DefaultTrafficTreatment;
46import org.onosproject.net.flow.TrafficSelector;
47import org.onosproject.net.flow.TrafficTreatment;
Brian O'Connorabafb502014-12-02 22:26:20 -080048import org.onosproject.net.host.InterfaceIpAddress;
49import org.onosproject.net.intent.AbstractIntentTest;
50import org.onosproject.net.intent.Intent;
Brian O'Connorabafb502014-12-02 22:26:20 -080051import org.onosproject.net.intent.IntentService;
52import org.onosproject.net.intent.IntentState;
Jonathan Hart365335e2015-12-10 11:09:53 -080053import org.onosproject.net.intent.IntentUtils;
Jonathan Hart9a426f82015-09-03 15:43:13 +020054import org.onosproject.net.intent.Key;
Brian O'Connorabafb502014-12-02 22:26:20 -080055import org.onosproject.net.intent.MultiPointToSinglePointIntent;
Jonathan Hart2da1e602015-02-18 19:09:24 -080056import org.onosproject.routing.RouteEntry;
Pingpingf5d90932014-10-27 10:50:04 -070057
Jonathan Hart41349e92015-02-09 14:14:02 -080058import java.util.Collections;
Jonathan Hart552e31f2015-02-06 11:11:59 -080059import java.util.HashSet;
Jonathan Hart00cddda2016-02-16 10:30:37 -080060import java.util.List;
Jonathan Hart552e31f2015-02-06 11:11:59 -080061import java.util.Set;
Jonathan Hart365335e2015-12-10 11:09:53 -080062import java.util.concurrent.ExecutorService;
Jonathan Hart552e31f2015-02-06 11:11:59 -080063
Jonathan Hart4cb39882015-08-12 23:50:55 -040064import static org.easymock.EasyMock.createMock;
65import static org.easymock.EasyMock.expect;
66import static org.easymock.EasyMock.replay;
67import static org.easymock.EasyMock.reset;
68import static org.easymock.EasyMock.verify;
Jonathan Hart552e31f2015-02-06 11:11:59 -080069import static org.hamcrest.Matchers.is;
Jonathan Hartcb726fc2015-02-13 16:26:22 -080070import static org.junit.Assert.assertFalse;
71import static org.junit.Assert.assertThat;
Pingpingf5d90932014-10-27 10:50:04 -070072
73/**
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -080074 * This class tests the intent synchronization function in the
75 * IntentSynchronizer class.
Pingpingf5d90932014-10-27 10:50:04 -070076 */
Jonathan Hart6af92be2016-01-05 20:52:25 -080077public class IntentSynchronizerTest extends AbstractIntentTest {
Pingpingf5d90932014-10-27 10:50:04 -070078
Pingpingf5d90932014-10-27 10:50:04 -070079 private IntentService intentService;
Pingpingf5d90932014-10-27 10:50:04 -070080
81 private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
82 DeviceId.deviceId("of:0000000000000001"),
83 PortNumber.portNumber(1));
84
85 private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
86 DeviceId.deviceId("of:0000000000000002"),
87 PortNumber.portNumber(1));
88
89 private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
90 DeviceId.deviceId("of:0000000000000003"),
91 PortNumber.portNumber(1));
92
Jonathan Hart41349e92015-02-09 14:14:02 -080093 private static final ConnectPoint SW4_ETH1 = new ConnectPoint(
94 DeviceId.deviceId("of:0000000000000004"),
95 PortNumber.portNumber(1));
96
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -080097 private IntentSynchronizer intentSynchronizer;
Jonathan Hart4cb39882015-08-12 23:50:55 -040098 private final Set<Interface> interfaces = Sets.newHashSet();
Pingpingf5d90932014-10-27 10:50:04 -070099
Jonathan Hart365335e2015-12-10 11:09:53 -0800100 private static final ApplicationId APPID =
101 TestApplicationId.create("intent-sync-test");
Pingpingf5d90932014-10-27 10:50:04 -0700102
Madan Jampani620f70d2016-01-30 22:22:47 -0800103 private static final ControllerNode LOCAL_NODE =
104 new DefaultControllerNode(new NodeId("foo"), IpAddress.valueOf("127.0.0.1"));
105
Pingpingf5d90932014-10-27 10:50:04 -0700106 @Before
107 public void setUp() throws Exception {
Brian O'Connor520c0522014-11-23 23:50:47 -0800108 super.setUp();
Jonathan Hart41349e92015-02-09 14:14:02 -0800109
Jonathan Hart90a02c22015-02-13 11:52:07 -0800110 setUpInterfaceService();
Jonathan Hart90a02c22015-02-13 11:52:07 -0800111
Pingpingf5d90932014-10-27 10:50:04 -0700112 intentService = createMock(IntentService.class);
113
Jonathan Hart365335e2015-12-10 11:09:53 -0800114 intentSynchronizer = new TestIntentSynchronizer();
115
116 intentSynchronizer.coreService = new TestCoreService();
Madan Jampani620f70d2016-01-30 22:22:47 -0800117 intentSynchronizer.clusterService = new TestClusterService();
Jonathan Hart365335e2015-12-10 11:09:53 -0800118 intentSynchronizer.leadershipService = new TestLeadershipService();
119 intentSynchronizer.intentService = intentService;
120
121 intentSynchronizer.activate();
Pingpingf5d90932014-10-27 10:50:04 -0700122 }
123
124 /**
125 * Sets up InterfaceService.
126 */
127 private void setUpInterfaceService() {
Jonathan Hart00cddda2016-02-16 10:30:37 -0800128 List<InterfaceIpAddress> interfaceIpAddresses1 = Lists.newArrayList();
Pingpingf5d90932014-10-27 10:50:04 -0700129 interfaceIpAddresses1.add(new InterfaceIpAddress(
130 IpAddress.valueOf("192.168.10.101"),
131 IpPrefix.valueOf("192.168.10.0/24")));
132 Interface sw1Eth1 = new Interface(SW1_ETH1,
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800133 interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"),
134 VlanId.NONE);
Pingpingf5d90932014-10-27 10:50:04 -0700135 interfaces.add(sw1Eth1);
136
Jonathan Hart00cddda2016-02-16 10:30:37 -0800137 List<InterfaceIpAddress> interfaceIpAddresses2 = Lists.newArrayList();
Jonathan Hart41349e92015-02-09 14:14:02 -0800138 interfaceIpAddresses2.add(
139 new InterfaceIpAddress(IpAddress.valueOf("192.168.20.101"),
140 IpPrefix.valueOf("192.168.20.0/24")));
Pingpingf5d90932014-10-27 10:50:04 -0700141 Interface sw2Eth1 = new Interface(SW2_ETH1,
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800142 interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"),
143 VlanId.NONE);
Pingpingf5d90932014-10-27 10:50:04 -0700144 interfaces.add(sw2Eth1);
145
Jonathan Hart00cddda2016-02-16 10:30:37 -0800146 List<InterfaceIpAddress> interfaceIpAddresses3 = Lists.newArrayList();
Jonathan Hart41349e92015-02-09 14:14:02 -0800147 interfaceIpAddresses3.add(
148 new InterfaceIpAddress(IpAddress.valueOf("192.168.30.101"),
149 IpPrefix.valueOf("192.168.30.0/24")));
Pingpingf5d90932014-10-27 10:50:04 -0700150 Interface sw3Eth1 = new Interface(SW3_ETH1,
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800151 interfaceIpAddresses3, MacAddress.valueOf("00:00:00:00:00:03"),
152 VlanId.NONE);
Pingpingf5d90932014-10-27 10:50:04 -0700153 interfaces.add(sw3Eth1);
154
Jonathan Hart41349e92015-02-09 14:14:02 -0800155 InterfaceIpAddress interfaceIpAddress4 =
156 new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"),
157 IpPrefix.valueOf("192.168.40.0/24"));
158 Interface sw4Eth1 = new Interface(SW4_ETH1,
Jonathan Hart00cddda2016-02-16 10:30:37 -0800159 Lists.newArrayList(interfaceIpAddress4),
Jonathan Hart41349e92015-02-09 14:14:02 -0800160 MacAddress.valueOf("00:00:00:00:00:04"),
161 VlanId.vlanId((short) 1));
162
Jonathan Hart41349e92015-02-09 14:14:02 -0800163 interfaces.add(sw4Eth1);
Pingpingf5d90932014-10-27 10:50:04 -0700164 }
165
166 /**
Jonathan Hart9a426f82015-09-03 15:43:13 +0200167 * Tests the synchronization behavior of intent synchronizer. We set up
168 * a discrepancy between the intent service state and the intent
169 * synchronizer's state and ensure that this is reconciled correctly.
Pingpingf5d90932014-10-27 10:50:04 -0700170 *
171 * @throws TestUtilsException
172 */
173 @Test
174 public void testIntentSync() throws TestUtilsException {
175
176 //
177 // Construct routes and intents.
178 // This test simulates the following cases during the master change
179 // time interval:
180 // 1. RouteEntry1 did not change and the intent also did not change.
181 // 2. RouteEntry2 was deleted, but the intent was not deleted.
182 // 3. RouteEntry3 was newly added, and the intent was also submitted.
183 // 4. RouteEntry4 was updated to RouteEntry4Update, and the intent was
184 // also updated to a new one.
185 // 5. RouteEntry5 did not change, but its intent id changed.
186 // 6. RouteEntry6 was newly added, but the intent was not submitted.
187 //
188 RouteEntry routeEntry1 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800189 Ip4Prefix.valueOf("1.1.1.0/24"),
190 Ip4Address.valueOf("192.168.10.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700191
192 RouteEntry routeEntry2 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800193 Ip4Prefix.valueOf("2.2.2.0/24"),
194 Ip4Address.valueOf("192.168.20.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700195
196 RouteEntry routeEntry3 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800197 Ip4Prefix.valueOf("3.3.3.0/24"),
198 Ip4Address.valueOf("192.168.30.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700199
200 RouteEntry routeEntry4 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800201 Ip4Prefix.valueOf("4.4.4.0/24"),
202 Ip4Address.valueOf("192.168.30.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700203
204 RouteEntry routeEntry4Update = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800205 Ip4Prefix.valueOf("4.4.4.0/24"),
206 Ip4Address.valueOf("192.168.20.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700207
208 RouteEntry routeEntry5 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800209 Ip4Prefix.valueOf("5.5.5.0/24"),
210 Ip4Address.valueOf("192.168.10.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700211
212 RouteEntry routeEntry6 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800213 Ip4Prefix.valueOf("6.6.6.0/24"),
214 Ip4Address.valueOf("192.168.10.1"));
Pingpingf5d90932014-10-27 10:50:04 -0700215
Jonathan Hartec2df012014-10-23 16:40:24 -0700216 RouteEntry routeEntry7 = new RouteEntry(
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800217 Ip4Prefix.valueOf("7.7.7.0/24"),
218 Ip4Address.valueOf("192.168.10.1"));
Jonathan Hartec2df012014-10-23 16:40:24 -0700219
Pingpingf5d90932014-10-27 10:50:04 -0700220 MultiPointToSinglePointIntent intent1 = intentBuilder(
221 routeEntry1.prefix(), "00:00:00:00:00:01", SW1_ETH1);
222 MultiPointToSinglePointIntent intent2 = intentBuilder(
223 routeEntry2.prefix(), "00:00:00:00:00:02", SW2_ETH1);
224 MultiPointToSinglePointIntent intent3 = intentBuilder(
225 routeEntry3.prefix(), "00:00:00:00:00:03", SW3_ETH1);
226 MultiPointToSinglePointIntent intent4 = intentBuilder(
227 routeEntry4.prefix(), "00:00:00:00:00:03", SW3_ETH1);
228 MultiPointToSinglePointIntent intent4Update = intentBuilder(
229 routeEntry4Update.prefix(), "00:00:00:00:00:02", SW2_ETH1);
230 MultiPointToSinglePointIntent intent5 = intentBuilder(
231 routeEntry5.prefix(), "00:00:00:00:00:01", SW1_ETH1);
Jonathan Hartec2df012014-10-23 16:40:24 -0700232 MultiPointToSinglePointIntent intent7 = intentBuilder(
233 routeEntry7.prefix(), "00:00:00:00:00:01", SW1_ETH1);
Pingpingf5d90932014-10-27 10:50:04 -0700234
235 // Compose a intent, which is equal to intent5 but the id is different.
236 MultiPointToSinglePointIntent intent5New =
237 staticIntentBuilder(intent5, routeEntry5, "00:00:00:00:00:01");
Ray Milkey4fd3ceb2015-12-10 14:43:08 -0800238 assertThat(IntentUtils.intentsAreEqual(intent5, intent5New), is(true));
Jonathan Hartec2df012014-10-23 16:40:24 -0700239 assertFalse(intent5.equals(intent5New));
Pingpingf5d90932014-10-27 10:50:04 -0700240
241 MultiPointToSinglePointIntent intent6 = intentBuilder(
242 routeEntry6.prefix(), "00:00:00:00:00:01", SW1_ETH1);
243
Pingpingf5d90932014-10-27 10:50:04 -0700244 // Set up expectation
Jonathan Hart90a02c22015-02-13 11:52:07 -0800245 Set<Intent> intents = new HashSet<>();
Pingpingf5d90932014-10-27 10:50:04 -0700246 intents.add(intent1);
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800247 expect(intentService.getIntentState(intent1.key()))
Jonathan Hartec2df012014-10-23 16:40:24 -0700248 .andReturn(IntentState.INSTALLED).anyTimes();
Pingpingf5d90932014-10-27 10:50:04 -0700249 intents.add(intent2);
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800250 expect(intentService.getIntentState(intent2.key()))
Jonathan Hartec2df012014-10-23 16:40:24 -0700251 .andReturn(IntentState.INSTALLED).anyTimes();
Pingpingf5d90932014-10-27 10:50:04 -0700252 intents.add(intent4);
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800253 expect(intentService.getIntentState(intent4.key()))
Jonathan Hartec2df012014-10-23 16:40:24 -0700254 .andReturn(IntentState.INSTALLED).anyTimes();
Pingpingf5d90932014-10-27 10:50:04 -0700255 intents.add(intent5);
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800256 expect(intentService.getIntentState(intent5.key()))
Jonathan Hartec2df012014-10-23 16:40:24 -0700257 .andReturn(IntentState.INSTALLED).anyTimes();
258 intents.add(intent7);
Ray Milkeyf9af43c2015-02-09 16:45:48 -0800259 expect(intentService.getIntentState(intent7.key()))
Jonathan Hartec2df012014-10-23 16:40:24 -0700260 .andReturn(IntentState.WITHDRAWING).anyTimes();
Pingpingf5d90932014-10-27 10:50:04 -0700261 expect(intentService.getIntents()).andReturn(intents).anyTimes();
262
Jonathan Hart9a426f82015-09-03 15:43:13 +0200263 // These are the operations that should be done to the intentService
264 // during synchronization
Brian O'Connor03406a42015-02-03 17:28:57 -0800265 intentService.withdraw(intent2);
Brian O'Connor03406a42015-02-03 17:28:57 -0800266 intentService.submit(intent3);
267 intentService.submit(intent4Update);
268 intentService.submit(intent6);
269 intentService.submit(intent7);
Pingpingf5d90932014-10-27 10:50:04 -0700270 replay(intentService);
271
272 // Start the test
Pingpingf5d90932014-10-27 10:50:04 -0700273
Jonathan Hart9a426f82015-09-03 15:43:13 +0200274 // Simulate some input from the clients. The intent synchronizer has not
275 // gained the global leadership yet, but it will remember this input for
276 // when it does.
277 intentSynchronizer.submit(intent1);
278 intentSynchronizer.submit(intent2);
279 intentSynchronizer.withdraw(intent2);
280 intentSynchronizer.submit(intent3);
281 intentSynchronizer.submit(intent4);
282 intentSynchronizer.submit(intent4Update);
283 intentSynchronizer.submit(intent5);
284 intentSynchronizer.submit(intent6);
285 intentSynchronizer.submit(intent7);
286
287 // Give the leadership to the intent synchronizer. It will now attempt
288 // to synchronize the intents in the store with the intents it has
289 // recorded based on the earlier user input.
Jonathan Hart365335e2015-12-10 11:09:53 -0800290 intentSynchronizer.modifyPrimary(true);
Jonathan Hart9a426f82015-09-03 15:43:13 +0200291
292 verify(intentService);
293 }
294
295 /**
296 * Tests the behavior of the submit API, both when the synchronizer has
297 * leadership and when it does not.
298 */
299 @Test
300 public void testSubmit() {
301 IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
302 Intent intent = intentBuilder(prefix, "00:00:00:00:00:01", SW1_ETH1);
303
304 // Set up expectations
305 intentService.submit(intent);
306 expect(intentService.getIntents()).andReturn(Collections.emptyList())
307 .anyTimes();
308 replay(intentService);
309
310 // Give the intent synchronizer leadership so it will submit intents
311 // to the intent service
Jonathan Hart365335e2015-12-10 11:09:53 -0800312 intentSynchronizer.modifyPrimary(true);
Jonathan Hart9a426f82015-09-03 15:43:13 +0200313
314 // Test the submit
315 intentSynchronizer.submit(intent);
316
317 verify(intentService);
318
319 // Now we'll remove leadership from the intent synchronizer and verify
320 // that it does not submit any intents to the intent service when we
321 // call the submit API
322 reset(intentService);
323 replay(intentService);
324
Jonathan Hart365335e2015-12-10 11:09:53 -0800325 intentSynchronizer.modifyPrimary(false);
Jonathan Hart9a426f82015-09-03 15:43:13 +0200326
327 intentSynchronizer.submit(intent);
328
329 verify(intentService);
330 }
331
332 /**
333 * Tests the behavior of the withdraw API, both when the synchronizer has
334 * leadership and when it does not.
335 */
336 @Test
337 public void testWithdraw() {
338 IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
339 Intent intent = intentBuilder(prefix, "00:00:00:00:00:01", SW1_ETH1);
340
341 // Submit an intent first so we can withdraw it later
342 intentService.submit(intent);
343 intentService.withdraw(intent);
344 expect(intentService.getIntents()).andReturn(Collections.emptyList())
345 .anyTimes();
346 replay(intentService);
347
348 // Give the intent synchronizer leadership so it will submit intents
349 // to the intent service
Jonathan Hart365335e2015-12-10 11:09:53 -0800350 intentSynchronizer.modifyPrimary(true);
Jonathan Hart9a426f82015-09-03 15:43:13 +0200351
352 // Test the submit then withdraw
353 intentSynchronizer.submit(intent);
354 intentSynchronizer.withdraw(intent);
355
356 verify(intentService);
357
358 // Now we'll remove leadership from the intent synchronizer and verify
359 // that it does not withdraw any intents to the intent service when we
360 // call the withdraw API
361 reset(intentService);
362 replay(intentService);
363
Jonathan Hart365335e2015-12-10 11:09:53 -0800364 intentSynchronizer.modifyPrimary(false);
Jonathan Hart9a426f82015-09-03 15:43:13 +0200365
366 intentSynchronizer.submit(intent);
367 intentSynchronizer.withdraw(intent);
Pingpingf5d90932014-10-27 10:50:04 -0700368
369 verify(intentService);
370 }
371
372 /**
373 * MultiPointToSinglePointIntent builder.
374 *
375 * @param ipPrefix the ipPrefix to match
376 * @param nextHopMacAddress to which the destination MAC address in packet
377 * should be rewritten
378 * @param egressPoint to which packets should be sent
379 * @return the constructed MultiPointToSinglePointIntent
380 */
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800381 private MultiPointToSinglePointIntent intentBuilder(IpPrefix ipPrefix,
Pingpingf5d90932014-10-27 10:50:04 -0700382 String nextHopMacAddress, ConnectPoint egressPoint) {
383
384 TrafficSelector.Builder selectorBuilder =
385 DefaultTrafficSelector.builder();
Pavlin Radoslavov87dd9302015-03-10 13:53:24 -0700386 if (ipPrefix.isIp4()) {
Jonathan Hart9a426f82015-09-03 15:43:13 +0200387 selectorBuilder.matchEthType(Ethernet.TYPE_IPV4);
Pavlin Radoslavova8537092015-02-23 10:15:20 -0800388 selectorBuilder.matchIPDst(ipPrefix);
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800389 } else {
Jonathan Hart9a426f82015-09-03 15:43:13 +0200390 selectorBuilder.matchEthType(Ethernet.TYPE_IPV6);
Pavlin Radoslavova8537092015-02-23 10:15:20 -0800391 selectorBuilder.matchIPv6Dst(ipPrefix);
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800392 }
Pingpingf5d90932014-10-27 10:50:04 -0700393
394 TrafficTreatment.Builder treatmentBuilder =
395 DefaultTrafficTreatment.builder();
396 treatmentBuilder.setEthDst(MacAddress.valueOf(nextHopMacAddress));
397
Jonathan Hart90a02c22015-02-13 11:52:07 -0800398 Set<ConnectPoint> ingressPoints = new HashSet<>();
Jonathan Hart4cb39882015-08-12 23:50:55 -0400399 for (Interface intf : interfaces) {
400 if (!intf.connectPoint().equals(egressPoint)) {
Pingpingf5d90932014-10-27 10:50:04 -0700401 ConnectPoint srcPort = intf.connectPoint();
402 ingressPoints.add(srcPort);
403 }
404 }
405 MultiPointToSinglePointIntent intent =
Ray Milkeyebc5d222015-03-18 15:45:36 -0700406 MultiPointToSinglePointIntent.builder()
407 .appId(APPID)
Jonathan Hart9a426f82015-09-03 15:43:13 +0200408 .key(Key.of(ipPrefix.toString(), APPID))
Ray Milkeyebc5d222015-03-18 15:45:36 -0700409 .selector(selectorBuilder.build())
410 .treatment(treatmentBuilder.build())
411 .ingressPoints(ingressPoints)
412 .egressPoint(egressPoint)
413 .build();
Pingpingf5d90932014-10-27 10:50:04 -0700414 return intent;
415 }
416
417 /**
418 * A static MultiPointToSinglePointIntent builder, the returned intent is
419 * equal to the input intent except that the id is different.
420 *
Pingpingf5d90932014-10-27 10:50:04 -0700421 * @param intent the intent to be used for building a new intent
422 * @param routeEntry the relative routeEntry of the intent
423 * @return the newly constructed MultiPointToSinglePointIntent
424 * @throws TestUtilsException
425 */
Jonathan Hart9a426f82015-09-03 15:43:13 +0200426 private MultiPointToSinglePointIntent staticIntentBuilder(
Pingpingf5d90932014-10-27 10:50:04 -0700427 MultiPointToSinglePointIntent intent, RouteEntry routeEntry,
428 String nextHopMacAddress) throws TestUtilsException {
429
430 // Use a different egress ConnectPoint with that in intent
431 // to generate a different id
432 MultiPointToSinglePointIntent intentNew = intentBuilder(
433 routeEntry.prefix(), nextHopMacAddress, SW2_ETH1);
434 TestUtils.setField(intentNew, "egressPoint", intent.egressPoint());
435 TestUtils.setField(intentNew,
436 "ingressPoints", intent.ingressPoints());
437 return intentNew;
438 }
Jonathan Hart365335e2015-12-10 11:09:53 -0800439
440 private class TestIntentSynchronizer extends IntentSynchronizer {
441 @Override
442 protected ExecutorService createExecutor() {
443 return MoreExecutors.newDirectExecutorService();
444 }
445 }
446
447 private class TestCoreService extends CoreServiceAdapter {
448 @Override
449 public ApplicationId registerApplication(String name) {
450 return APPID;
451 }
452 }
453
Madan Jampani620f70d2016-01-30 22:22:47 -0800454 private class TestClusterService extends ClusterServiceAdapter {
455 @Override
456 public ControllerNode getLocalNode() {
457 return LOCAL_NODE;
458 }
459 }
460
Jonathan Hart365335e2015-12-10 11:09:53 -0800461 private class TestLeadershipService extends LeadershipServiceAdapter {
462
463 }
Pingpingf5d90932014-10-27 10:50:04 -0700464}