Add support for reconfiguring interfaces in SDN-IP.
Change-Id: I2ea85d85432e661c3cbdca5e5a8b16678a242369
diff --git a/apps/sdnip/pom.xml b/apps/sdnip/pom.xml
index 2c42034..0dd4638 100644
--- a/apps/sdnip/pom.xml
+++ b/apps/sdnip/pom.xml
@@ -58,6 +58,14 @@
<dependency>
<groupId>org.onosproject</groupId>
+ <artifactId>onos-incubator-api</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ <classifier>tests</classifier>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
<artifactId>onos-app-routing</artifactId>
<version>${project.version}</version>
</dependency>
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
index b558c79..df9aee0 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java
@@ -23,6 +23,8 @@
import org.onlab.packet.TpPort;
import org.onosproject.core.ApplicationId;
import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceEvent;
+import org.onosproject.incubator.net.intf.InterfaceListener;
import org.onosproject.incubator.net.intf.InterfaceService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.config.NetworkConfigEvent;
@@ -44,9 +46,11 @@
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -77,14 +81,17 @@
private final InternalNetworkConfigListener configListener
= new InternalNetworkConfigListener();
+ private final InternalInterfaceListener interfaceListener
+ = new InternalInterfaceListener();
+
/**
* Creates a new PeerConnectivityManager.
*
* @param appId the application ID
* @param intentSynchronizer the intent synchronizer
- * @param configService the SDN-IP config service
- * @param interfaceService the interface service
+ * @param configService the network config service
* @param routerAppId application ID
+ * @param interfaceService the interface service
*/
public PeerConnectivityManager(ApplicationId appId,
IntentSynchronizationService intentSynchronizer,
@@ -105,6 +112,7 @@
*/
public void start() {
configService.addListener(configListener);
+ interfaceService.addListener(interfaceListener);
setUpConnectivity();
}
@@ -113,6 +121,7 @@
*/
public void stop() {
configService.removeListener(configListener);
+ interfaceService.removeListener(interfaceListener);
}
/**
@@ -122,14 +131,18 @@
private void setUpConnectivity() {
BgpConfig config = configService.getConfig(routerAppId, RoutingService.CONFIG_CLASS);
+ Set<BgpConfig.BgpSpeakerConfig> bgpSpeakers;
+
if (config == null) {
- log.warn("No BgpConfig found");
- return;
+ log.warn("No BGP config available");
+ bgpSpeakers = Collections.emptySet();
+ } else {
+ bgpSpeakers = config.bgpSpeakers();
}
Map<Key, PointToPointIntent> existingIntents = new HashMap<>(peerIntents);
- for (BgpConfig.BgpSpeakerConfig bgpSpeaker : config.bgpSpeakers()) {
+ for (BgpConfig.BgpSpeakerConfig bgpSpeaker : bgpSpeakers) {
log.debug("Start to set up BGP paths for BGP speaker: {}",
bgpSpeaker);
@@ -409,4 +422,19 @@
}
}
+ private class InternalInterfaceListener implements InterfaceListener {
+ @Override
+ public void event(InterfaceEvent event) {
+ switch (event.type()) {
+ case INTERFACE_ADDED:
+ case INTERFACE_UPDATED:
+ case INTERFACE_REMOVED:
+ setUpConnectivity();
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java
index a68d76c..d41d3a7 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java
@@ -17,6 +17,7 @@
package org.onosproject.sdnip;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Sets;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -30,6 +31,8 @@
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceEvent;
+import org.onosproject.incubator.net.intf.InterfaceListener;
import org.onosproject.incubator.net.intf.InterfaceService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.flow.DefaultTrafficSelector;
@@ -75,6 +78,7 @@
protected RoutingService routingService;
private final InternalFibListener fibListener = new InternalFibListener();
+ private final InternalInterfaceListener interfaceListener = new InternalInterfaceListener();
private static final int PRIORITY_OFFSET = 100;
private static final int PRIORITY_MULTIPLIER = 5;
@@ -90,12 +94,15 @@
public void activate() {
appId = coreService.getAppId(SdnIp.SDN_IP_APP);
+ interfaceService.addListener(interfaceListener);
+
routingService.addFibListener(fibListener);
routingService.start();
}
@Deactivate
public void deactivate() {
+ interfaceService.removeListener(interfaceListener);
// TODO remove listener
routingService.stop();
}
@@ -240,6 +247,51 @@
.build();
}
+ private void updateInterface(Interface intf) {
+ synchronized (this) {
+ for (Map.Entry<IpPrefix, MultiPointToSinglePointIntent> entry : routeIntents.entrySet()) {
+ MultiPointToSinglePointIntent intent = entry.getValue();
+ Set<ConnectPoint> ingress = Sets.newHashSet(intent.ingressPoints());
+ ingress.add(intf.connectPoint());
+
+ MultiPointToSinglePointIntent newIntent =
+ MultiPointToSinglePointIntent.builder(intent)
+ .ingressPoints(ingress)
+ .build();
+
+ routeIntents.put(entry.getKey(), newIntent);
+ intentSynchronizer.submit(newIntent);
+ }
+ }
+ }
+
+ private void removeInterface(Interface intf) {
+ synchronized (this) {
+ for (Map.Entry<IpPrefix, MultiPointToSinglePointIntent> entry : routeIntents.entrySet()) {
+ MultiPointToSinglePointIntent intent = entry.getValue();
+ if (intent.egressPoint().equals(intf.connectPoint())) {
+ // This intent just lost its head. Remove it and let
+ // higher layer routing reroute.
+ intentSynchronizer.withdraw(routeIntents.remove(entry.getKey()));
+ } else {
+ if (intent.ingressPoints().contains(intf.connectPoint())) {
+
+ Set<ConnectPoint> ingress = Sets.newHashSet(intent.ingressPoints());
+ ingress.remove(intf.connectPoint());
+
+ MultiPointToSinglePointIntent newIntent =
+ MultiPointToSinglePointIntent.builder(intent)
+ .ingressPoints(ingress)
+ .build();
+
+ routeIntents.put(entry.getKey(), newIntent);
+ intentSynchronizer.submit(newIntent);
+ }
+ }
+ }
+ }
+ }
+
private class InternalFibListener implements FibListener {
@Override
public void update(Collection<FibUpdate> updates, Collection<FibUpdate> withdraws) {
@@ -247,4 +299,23 @@
}
}
+ private class InternalInterfaceListener implements InterfaceListener {
+
+ @Override
+ public void event(InterfaceEvent event) {
+ switch (event.type()) {
+ case INTERFACE_ADDED:
+ updateInterface(event.subject());
+ break;
+ case INTERFACE_UPDATED:
+ break;
+ case INTERFACE_REMOVED:
+ removeInterface(event.subject());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
index 48f097e..54cb16b 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/PeerConnectivityManagerTest.java
@@ -17,7 +17,6 @@
import com.google.common.collect.Sets;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.onlab.junit.TestUtils.TestUtilsException;
import org.onlab.packet.Ethernet;
@@ -30,6 +29,7 @@
import org.onosproject.TestApplicationId;
import org.onosproject.core.ApplicationId;
import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceListener;
import org.onosproject.incubator.net.intf.InterfaceService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
@@ -48,14 +48,10 @@
import org.onosproject.routing.IntentSynchronizationService;
import org.onosproject.routing.config.BgpConfig;
import org.onosproject.routing.config.BgpPeer;
-import org.onosproject.routing.config.BgpSpeaker;
-import org.onosproject.routing.config.InterfaceAddress;
-import org.onosproject.routing.config.RoutingConfigurationService;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -81,7 +77,6 @@
private PeerConnectivityManager peerConnectivityManager;
private IntentSynchronizationService intentSynchronizer;
- private RoutingConfigurationService routingConfig;
private InterfaceService interfaceService;
private NetworkConfigService networkConfigService;
@@ -104,8 +99,6 @@
// Interfaces connected to BGP speakers
private final ConnectPoint s1Eth100 =
new ConnectPoint(deviceId1, PortNumber.portNumber(100));
- private final ConnectPoint s2Eth100 =
- new ConnectPoint(deviceId2, PortNumber.portNumber(100));
// Interfaces connected to BGP peers
private final ConnectPoint s1Eth1 =
@@ -119,8 +112,10 @@
@Before
public void setUp() throws Exception {
super.setUp();
- routingConfig = createMock(RoutingConfigurationService.class);
+
interfaceService = createMock(InterfaceService.class);
+ interfaceService.addListener(anyObject(InterfaceListener.class));
+ expectLastCall().anyTimes();
networkConfigService = createMock(NetworkConfigService.class);
networkConfigService.addListener(anyObject(NetworkConfigListener.class));
expectLastCall().anyTimes();
@@ -172,7 +167,7 @@
InterfaceIpAddress ia1 =
new InterfaceIpAddress(IpAddress.valueOf("192.168.10.101"),
IpPrefix.valueOf("192.168.10.0/24"));
- Interface intfsw1eth1 = new Interface(s1Eth1,
+ Interface intfsw1eth1 = new Interface(interfaceSw1Eth1, s1Eth1,
Collections.singletonList(ia1),
MacAddress.valueOf("00:00:00:00:00:01"),
VlanId.NONE);
@@ -182,7 +177,7 @@
InterfaceIpAddress ia2 =
new InterfaceIpAddress(IpAddress.valueOf("192.168.20.101"),
IpPrefix.valueOf("192.168.20.0/24"));
- Interface intfsw2eth1 = new Interface(s2Eth1,
+ Interface intfsw2eth1 = new Interface(interfaceSw2Eth1, s2Eth1,
Collections.singletonList(ia2),
MacAddress.valueOf("00:00:00:00:00:02"),
VlanId.NONE);
@@ -192,7 +187,7 @@
InterfaceIpAddress ia3 =
new InterfaceIpAddress(IpAddress.valueOf("192.168.30.101"),
IpPrefix.valueOf("192.168.30.0/24"));
- Interface intfsw2eth1intf2 = new Interface(s2Eth1,
+ Interface intfsw2eth1intf2 = new Interface(interfaceSw2Eth1intf2, s2Eth1,
Collections.singletonList(ia3),
MacAddress.valueOf("00:00:00:00:00:03"),
VlanId.NONE);
@@ -430,13 +425,11 @@
* @throws TestUtilsException if exceptions when using TestUtils
*/
private void initPeerConnectivity() throws TestUtilsException {
- expect(routingConfig.getBgpPeers()).andReturn(peers).anyTimes();
expect(bgpConfig.bgpSpeakers()).andReturn(bgpSpeakers).anyTimes();
replay(bgpConfig);
expect(networkConfigService.getConfig(APPID, BgpConfig.class))
.andReturn(bgpConfig).anyTimes();
replay(networkConfigService);
- replay(routingConfig);
replay(interfaceService);
intentSynchronizer = createMock(IntentSynchronizationService.class);
@@ -478,6 +471,8 @@
@Test
public void testNullInterfaces() {
reset(interfaceService);
+ interfaceService.addListener(anyObject(InterfaceListener.class));
+ expectLastCall().anyTimes();
expect(interfaceService.getInterfaces()).andReturn(
Sets.newHashSet()).anyTimes();
@@ -511,13 +506,9 @@
*/
@Test
public void testNullBgpSpeakers() {
- reset(routingConfig);
reset(bgpConfig);
-
expect(bgpConfig.bgpSpeakers()).andReturn(Collections.emptySet()).anyTimes();
replay(bgpConfig);
- expect(routingConfig.getBgpPeers()).andReturn(peers).anyTimes();
- replay(routingConfig);
reset(intentSynchronizer);
replay(intentSynchronizer);
@@ -537,21 +528,4 @@
testConnectionSetup();
}
- /**
- * Tests a corner case, when there is no Interface configured for one BGP
- * speaker.
- */
- @Ignore
- @Test
- public void testNoSpeakerInterface() {
- BgpSpeaker bgpSpeaker100 = new BgpSpeaker(
- "bgpSpeaker100",
- "00:00:00:00:00:00:01:00", 100,
- "00:00:00:00:01:00");
- List<InterfaceAddress> interfaceAddresses100 = new LinkedList<>();
- interfaceAddresses100.add(new InterfaceAddress(dpid1, 1, "192.168.10.201"));
- interfaceAddresses100.add(new InterfaceAddress(dpid2, 1, "192.168.20.201"));
- bgpSpeaker100.setInterfaceAddresses(interfaceAddresses100);
- testConnectionSetup();
- }
}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java
index 3fe048b..c23737c 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java
@@ -31,7 +31,10 @@
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceEvent;
+import org.onosproject.incubator.net.intf.InterfaceListener;
import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.incubator.net.intf.InterfaceServiceAdapter;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
@@ -48,18 +51,16 @@
import org.onosproject.routing.FibUpdate;
import org.onosproject.routing.IntentSynchronizationService;
import org.onosproject.routing.RoutingServiceAdapter;
-import org.onosproject.routing.config.BgpPeer;
-import org.onosproject.routing.config.RoutingConfigurationService;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
+import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reset;
import static org.easymock.EasyMock.verify;
@@ -70,7 +71,6 @@
*/
public class SdnIpFibTest extends AbstractIntentTest {
- private RoutingConfigurationService routingConfig;
private InterfaceService interfaceService;
private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
@@ -89,6 +89,10 @@
DeviceId.deviceId("of:0000000000000004"),
PortNumber.portNumber(1));
+ private static final ConnectPoint SW5_ETH1 = new ConnectPoint(
+ DeviceId.deviceId("of:0000000000000005"),
+ PortNumber.portNumber(1));
+
private SdnIpFib sdnipFib;
private IntentSynchronizationService intentSynchronizer;
private final Set<Interface> interfaces = Sets.newHashSet();
@@ -96,19 +100,19 @@
private static final ApplicationId APPID = TestApplicationId.create("SDNIP");
private FibListener fibListener;
+ private InterfaceListener interfaceListener;
@Before
public void setUp() throws Exception {
super.setUp();
- routingConfig = createMock(RoutingConfigurationService.class);
interfaceService = createMock(InterfaceService.class);
+ interfaceService.addListener(anyObject(InterfaceListener.class));
+ expectLastCall().andDelegateTo(new InterfaceServiceDelegate());
// These will set expectations on routingConfig and interfaceService
setUpInterfaceService();
- setUpBgpPeers();
- replay(routingConfig);
replay(interfaceService);
intentSynchronizer = createMock(IntentSynchronizationService.class);
@@ -123,33 +127,6 @@
}
/**
- * Sets up BGP peers in external networks.
- */
- private void setUpBgpPeers() {
-
- Map<IpAddress, BgpPeer> peers = new HashMap<>();
-
- String peerSw1Eth1 = "192.168.10.1";
- peers.put(IpAddress.valueOf(peerSw1Eth1),
- new BgpPeer("00:00:00:00:00:00:00:01", 1, peerSw1Eth1));
-
- // Two BGP peers are connected to switch 2 port 1.
- String peer1Sw2Eth1 = "192.168.20.1";
- peers.put(IpAddress.valueOf(peer1Sw2Eth1),
- new BgpPeer("00:00:00:00:00:00:00:02", 1, peer1Sw2Eth1));
-
- String peer2Sw2Eth1 = "192.168.20.2";
- peers.put(IpAddress.valueOf(peer2Sw2Eth1),
- new BgpPeer("00:00:00:00:00:00:00:02", 1, peer2Sw2Eth1));
-
- String peer1Sw4Eth1 = "192.168.40.1";
- peers.put(IpAddress.valueOf(peer1Sw4Eth1),
- new BgpPeer("00:00:00:00:00:00:00:04", 1, peer1Sw4Eth1));
-
- expect(routingConfig.getBgpPeers()).andReturn(peers).anyTimes();
- }
-
- /**
* Sets up InterfaceService.
*/
private void setUpInterfaceService() {
@@ -157,7 +134,7 @@
interfaceIpAddresses1.add(new InterfaceIpAddress(
IpAddress.valueOf("192.168.10.101"),
IpPrefix.valueOf("192.168.10.0/24")));
- Interface sw1Eth1 = new Interface(SW1_ETH1,
+ Interface sw1Eth1 = new Interface("sw1-eth1", SW1_ETH1,
interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"),
VlanId.NONE);
interfaces.add(sw1Eth1);
@@ -166,7 +143,7 @@
interfaceIpAddresses2.add(
new InterfaceIpAddress(IpAddress.valueOf("192.168.20.101"),
IpPrefix.valueOf("192.168.20.0/24")));
- Interface sw2Eth1 = new Interface(SW2_ETH1,
+ Interface sw2Eth1 = new Interface("sw2-eth1", SW2_ETH1,
interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"),
VlanId.NONE);
interfaces.add(sw2Eth1);
@@ -175,7 +152,7 @@
interfaceIpAddresses3.add(
new InterfaceIpAddress(IpAddress.valueOf("192.168.30.101"),
IpPrefix.valueOf("192.168.30.0/24")));
- Interface sw3Eth1 = new Interface(SW3_ETH1,
+ Interface sw3Eth1 = new Interface("sw3-eth1", SW3_ETH1,
interfaceIpAddresses3, MacAddress.valueOf("00:00:00:00:00:03"),
VlanId.NONE);
interfaces.add(sw3Eth1);
@@ -183,7 +160,7 @@
InterfaceIpAddress interfaceIpAddress4 =
new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"),
IpPrefix.valueOf("192.168.40.0/24"));
- Interface sw4Eth1 = new Interface(SW4_ETH1,
+ Interface sw4Eth1 = new Interface("sw4-eth1", SW4_ETH1,
Lists.newArrayList(interfaceIpAddress4),
MacAddress.valueOf("00:00:00:00:00:04"),
VlanId.vlanId((short) 1));
@@ -428,6 +405,100 @@
verify(intentSynchronizer);
}
+ @Test
+ public void testAddInterface() {
+ testFibAdd();
+
+ IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
+
+ // Construct the existing MultiPointToSinglePoint intent
+ TrafficSelector.Builder selectorBuilder =
+ DefaultTrafficSelector.builder();
+ selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(prefix);
+
+ TrafficTreatment.Builder treatmentBuilder =
+ DefaultTrafficTreatment.builder();
+ treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01"));
+
+ Set<ConnectPoint> ingressPoints = new HashSet<>();
+ ingressPoints.add(SW2_ETH1);
+ ingressPoints.add(SW3_ETH1);
+ ingressPoints.add(SW4_ETH1);
+ ingressPoints.add(SW5_ETH1);
+
+ MultiPointToSinglePointIntent addedIntent =
+ MultiPointToSinglePointIntent.builder()
+ .appId(APPID)
+ .key(Key.of(prefix.toString(), APPID))
+ .selector(selectorBuilder.build())
+ .treatment(treatmentBuilder.build())
+ .ingressPoints(ingressPoints)
+ .egressPoint(SW1_ETH1)
+ .constraints(SdnIpFib.CONSTRAINTS)
+ .build();
+
+ reset(intentSynchronizer);
+
+ intentSynchronizer.submit(eqExceptId(addedIntent));
+ expectLastCall().once();
+
+ replay(intentSynchronizer);
+
+ Interface intf = new Interface("newintf", SW5_ETH1,
+ Collections.singletonList(InterfaceIpAddress.valueOf("192.168.50.101/24")),
+ MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE);
+ InterfaceEvent intfEvent = new InterfaceEvent(InterfaceEvent.Type.INTERFACE_ADDED, intf);
+ interfaceListener.event(intfEvent);
+
+ verify(intentSynchronizer);
+ }
+
+ @Test
+ public void testRemoveInterface() {
+ testFibAdd();
+
+ IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
+
+ // Construct the existing MultiPointToSinglePoint intent
+ TrafficSelector.Builder selectorBuilder =
+ DefaultTrafficSelector.builder();
+ selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(prefix);
+
+ TrafficTreatment.Builder treatmentBuilder =
+ DefaultTrafficTreatment.builder();
+ treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01"));
+
+ Set<ConnectPoint> ingressPoints = new HashSet<>();
+ ingressPoints.add(SW2_ETH1);
+ ingressPoints.add(SW3_ETH1);
+
+ MultiPointToSinglePointIntent addedIntent =
+ MultiPointToSinglePointIntent.builder()
+ .appId(APPID)
+ .key(Key.of(prefix.toString(), APPID))
+ .selector(selectorBuilder.build())
+ .treatment(treatmentBuilder.build())
+ .ingressPoints(ingressPoints)
+ .egressPoint(SW1_ETH1)
+ .constraints(SdnIpFib.CONSTRAINTS)
+ .build();
+
+ reset(intentSynchronizer);
+
+ intentSynchronizer.submit(eqExceptId(addedIntent));
+ expectLastCall().once();
+
+ replay(intentSynchronizer);
+
+ Interface intf = new Interface("newintf", SW4_ETH1,
+ Collections.singletonList(InterfaceIpAddress.valueOf("192.168.50.101/24")),
+ MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE);
+ InterfaceEvent intfEvent = new InterfaceEvent(InterfaceEvent.Type.INTERFACE_REMOVED, intf);
+ interfaceListener.event(intfEvent);
+
+ verify(intentSynchronizer);
+ }
+
private class TestCoreService extends CoreServiceAdapter {
@Override
public ApplicationId getAppId(String name) {
@@ -442,4 +513,12 @@
SdnIpFibTest.this.fibListener = fibListener;
}
}
+
+ private class InterfaceServiceDelegate extends InterfaceServiceAdapter {
+
+ @Override
+ public void addListener(InterfaceListener listener) {
+ SdnIpFibTest.this.interfaceListener = listener;
+ }
+ }
}