[Falcon] Componentize IntentSynchronizer and SdnIpFib.
Change-Id: Ic384ce00572ae1e4bbf94b4de814cea3499d3828
diff --git a/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java b/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java
index 96aa06e..ffbdf10 100644
--- a/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java
+++ b/apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/SdnIpReactiveRouting.java
@@ -47,9 +47,9 @@
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.routing.IntentRequestListener;
+import org.onosproject.routing.IntentSynchronizationService;
import org.onosproject.routing.RouteEntry;
import org.onosproject.routing.RoutingService;
-import org.onosproject.routing.SdnIpService;
import org.onosproject.routing.config.RoutingConfigurationService;
import org.slf4j.Logger;
@@ -86,7 +86,7 @@
protected RoutingService routingService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected SdnIpService sdnIpService;
+ protected IntentSynchronizationService intentSynchronizer;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected RoutingConfigurationService config;
@@ -109,8 +109,7 @@
appId = coreService.registerApplication(APP_NAME);
intentRequestListener = new ReactiveRoutingFib(appId, hostService,
- config, interfaceService,
- sdnIpService.getIntentSynchronizationService());
+ config, interfaceService, intentSynchronizer);
packetService.addProcessor(processor, PacketProcessor.director(2));
requestIntercepts();
diff --git a/apps/routing-api/src/main/java/org/onosproject/routing/SdnIpService.java b/apps/routing-api/src/main/java/org/onosproject/routing/IntentSynchronizationAdminService.java
similarity index 72%
rename from apps/routing-api/src/main/java/org/onosproject/routing/SdnIpService.java
rename to apps/routing-api/src/main/java/org/onosproject/routing/IntentSynchronizationAdminService.java
index 0945336..14a274f 100644
--- a/apps/routing-api/src/main/java/org/onosproject/routing/SdnIpService.java
+++ b/apps/routing-api/src/main/java/org/onosproject/routing/IntentSynchronizationAdminService.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2015 Open Networking Laboratory
+ * Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.onosproject.routing;
/**
- * Service interface exported by SDN-IP.
+ * Administrative APIs for managing intent synchronization.
*/
-public interface SdnIpService {
+public interface IntentSynchronizationAdminService {
/**
* Changes whether this SDN-IP instance is the primary or not based on the
@@ -29,11 +30,7 @@
void modifyPrimary(boolean isPrimary);
/**
- * Gets the intent synchronization service.
- *
- * @return intent synchronization service
+ * Withdraws all intents.
*/
- // TODO fix service resolution in SDN-IP
- IntentSynchronizationService getIntentSynchronizationService();
-
+ void removeIntents();
}
diff --git a/apps/routing-api/src/test/java/org/onosproject/routing/RoutingServiceAdapter.java b/apps/routing-api/src/test/java/org/onosproject/routing/RoutingServiceAdapter.java
new file mode 100644
index 0000000..6fd52fd
--- /dev/null
+++ b/apps/routing-api/src/test/java/org/onosproject/routing/RoutingServiceAdapter.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.routing;
+
+import org.onlab.packet.IpAddress;
+
+import java.util.Collection;
+
+/**
+ * Routing service adapter.
+ */
+public class RoutingServiceAdapter implements RoutingService {
+
+ @Override
+ public void start() {
+
+ }
+
+ @Override
+ public void addFibListener(FibListener fibListener) {
+
+ }
+
+ @Override
+ public void stop() {
+
+ }
+
+ @Override
+ public Collection<RouteEntry> getRoutes4() {
+ return null;
+ }
+
+ @Override
+ public Collection<RouteEntry> getRoutes6() {
+ return null;
+ }
+
+ @Override
+ public RouteEntry getLongestMatchableRouteEntry(IpAddress ipAddress) {
+ return null;
+ }
+}
diff --git a/apps/routing/src/main/java/org/onosproject/routing/impl/Router.java b/apps/routing/src/main/java/org/onosproject/routing/impl/Router.java
index 75d789a..dda533a 100644
--- a/apps/routing/src/main/java/org/onosproject/routing/impl/Router.java
+++ b/apps/routing/src/main/java/org/onosproject/routing/impl/Router.java
@@ -35,7 +35,6 @@
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onosproject.core.CoreService;
-import org.onosproject.incubator.net.intf.InterfaceService;
import org.onosproject.net.Host;
import org.onosproject.net.host.HostEvent;
import org.onosproject.net.host.HostListener;
@@ -107,9 +106,6 @@
protected BgpService bgpService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected InterfaceService interfaceService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected RoutingConfigurationService routingConfigurationService;
private ExecutorService bgpUpdatesExecutor;
@@ -123,7 +119,7 @@
new DefaultByteArrayNodeFactory());
routesWaitingOnArp = Multimaps.synchronizedSetMultimap(
- HashMultimap.<IpAddress, RouteEntry>create());
+ HashMultimap.create());
coreService.registerApplication(ROUTER_APP_ID);
diff --git a/apps/sdnip/pom.xml b/apps/sdnip/pom.xml
index 67ae9a3..1151b0e 100644
--- a/apps/sdnip/pom.xml
+++ b/apps/sdnip/pom.xml
@@ -58,7 +58,15 @@
<dependency>
<groupId>org.onosproject</groupId>
- <artifactId>onos-app-routing</artifactId>
+ <artifactId>onos-app-routing-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-app-routing-api</artifactId>
+ <scope>test</scope>
+ <classifier>tests</classifier>
<version>${project.version}</version>
</dependency>
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java
index 221fc99..35383dc 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java
@@ -15,101 +15,117 @@
*/
package org.onosproject.sdnip;
-import static java.util.concurrent.Executors.newSingleThreadExecutor;
-import static org.onlab.util.Tools.groupedThreads;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.LeadershipEvent;
+import org.onosproject.cluster.LeadershipEventListener;
+import org.onosproject.cluster.LeadershipService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.Key;
+import org.onosproject.routing.IntentSynchronizationAdminService;
+import org.onosproject.routing.IntentSynchronizationService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.IntentService;
-import org.onosproject.net.intent.IntentState;
import org.onosproject.net.intent.IntentUtils;
-import org.onosproject.net.intent.Key;
-import org.onosproject.routing.IntentSynchronizationService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import static java.util.concurrent.Executors.newSingleThreadExecutor;
+import static org.onlab.util.Tools.groupedThreads;
/**
- * Synchronizes intents between the in-memory intent store and the
- * IntentService.
+ * Synchronizes intents between an in-memory intent store and the IntentService.
*/
-public class IntentSynchronizer implements IntentSynchronizationService {
+@Service
+@Component(immediate = true)
+public class IntentSynchronizer implements IntentSynchronizationService,
+ IntentSynchronizationAdminService {
- private static final Logger log =
- LoggerFactory.getLogger(IntentSynchronizer.class);
+ private static final Logger log = LoggerFactory.getLogger(IntentSynchronizer.class);
- private final ApplicationId appId;
- private final IntentService intentService;
+ private static final String APP_NAME = "org.onosproject.intentsynchronizer";
- private final Map<Key, Intent> intents;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
- //
- // State to deal with the Leader election and pushing Intents
- //
- private final ExecutorService intentsSynchronizerExecutor;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected LeadershipService leadershipService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected ClusterService clusterService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected IntentService intentService;
+
+ private ApplicationId appId;
+
+ private final InternalLeadershipListener leadershipEventListener =
+ new InternalLeadershipListener();
+
+ private final Map<Key, Intent> intents = new ConcurrentHashMap<>();
+
+ private ExecutorService intentsSynchronizerExecutor;
+
private volatile boolean isElectedLeader = false;
private volatile boolean isActivatedLeader = false;
- /**
- * Class constructor.
- *
- * @param appId the Application ID
- * @param intentService the intent service
- */
- public IntentSynchronizer(ApplicationId appId, IntentService intentService) {
- this(appId, intentService,
- newSingleThreadExecutor(groupedThreads("onos/" + appId, "sync")));
+ @Activate
+ public void activate() {
+ intentsSynchronizerExecutor = createExecutor();
+
+ this.appId = coreService.registerApplication(APP_NAME);
+
+ leadershipService.addListener(leadershipEventListener);
+ leadershipService.runForLeadership(appId.name());
+
+ log.info("Started");
}
- /**
- * Class constructor.
- *
- * @param appId the Application ID
- * @param intentService the intent service
- * @param executorService executor service for synchronization thread
- */
- public IntentSynchronizer(ApplicationId appId, IntentService intentService,
- ExecutorService executorService) {
- this.appId = appId;
- this.intentService = intentService;
+ @Deactivate
+ public void deactivate() {
+ leadershipService.withdraw(appId.name());
+ leadershipService.removeListener(leadershipEventListener);
- intents = new ConcurrentHashMap<>();
-
- intentsSynchronizerExecutor = executorService;
- }
-
- /**
- * Starts the synchronizer.
- */
- public void start() {
-
- }
-
- /**
- * Stops the synchronizer.
- */
- public void stop() {
synchronized (this) {
- // Stop the thread(s)
intentsSynchronizerExecutor.shutdownNow();
- log.info("Intents Synchronizer Executor shutdown completed");
-
}
+
+ log.info("Stopped");
}
/**
- * Withdraws all intents.
+ * Creates an executor that will be used for synchronization tasks.
+ * <p>
+ * Can be overridden to change the type of executor used.
+ * </p>
+ *
+ * @return executor service
*/
+ protected ExecutorService createExecutor() {
+ return newSingleThreadExecutor(groupedThreads("onos/" + appId, "sync"));
+ }
+
+ @Override
public void removeIntents() {
if (!isElectedLeader) {
- // only leader will withdraw intents
+ // Only leader will withdraw intents
return;
}
@@ -152,18 +168,19 @@
*
* @param isLeader true if this instance is now the leader, otherwise false
*/
- public void leaderChanged(boolean isLeader) {
+ private void leaderChanged(boolean isLeader) {
log.debug("Leader changed: {}", isLeader);
if (!isLeader) {
this.isElectedLeader = false;
this.isActivatedLeader = false;
- return; // Nothing to do
+ // Nothing to do
+ return;
}
this.isActivatedLeader = false;
this.isElectedLeader = true;
- // Run the synchronization method off-thread
+ // Run the synchronization task
intentsSynchronizerExecutor.execute(this::synchronizeIntents);
}
@@ -232,10 +249,49 @@
}
if (isElectedLeader) {
- isActivatedLeader = true; // Allow push of Intents
+ // Allow push of Intents
+ isActivatedLeader = true;
} else {
isActivatedLeader = false;
}
log.debug("Intent synchronization completed");
}
+
+ @Override
+ public void modifyPrimary(boolean isPrimary) {
+ leaderChanged(isPrimary);
+ }
+
+ /**
+ * A listener for leadership events.
+ */
+ private class InternalLeadershipListener implements LeadershipEventListener {
+
+ @Override
+ public void event(LeadershipEvent event) {
+ if (!event.subject().topic().equals(appId.name())) {
+ // Not our topic: ignore
+ return;
+ }
+ if (!Objects.equals(event.subject().leader(),
+ clusterService.getLocalNode().id())) {
+ // The event is not about this instance: ignore
+ return;
+ }
+
+ switch (event.type()) {
+ case LEADER_ELECTED:
+ log.info("IntentSynchronizer gained leadership");
+ leaderChanged(true);
+ break;
+ case LEADER_BOOTED:
+ log.info("IntentSynchronizer lost leadership");
+ leaderChanged(false);
+ break;
+ case LEADER_REELECTED:
+ default:
+ break;
+ }
+ }
+ }
}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIp.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIp.java
index ace888d..d0a5c22 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIp.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIp.java
@@ -15,136 +15,79 @@
*/
package org.onosproject.sdnip;
-import static org.slf4j.LoggerFactory.getLogger;
-
-import java.util.Objects;
-
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.Service;
import org.onosproject.app.ApplicationService;
-import org.onosproject.cluster.ClusterService;
-import org.onosproject.cluster.ControllerNode;
-import org.onosproject.cluster.LeadershipEvent;
-import org.onosproject.cluster.LeadershipEventListener;
-import org.onosproject.cluster.LeadershipService;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.incubator.net.intf.InterfaceService;
import org.onosproject.net.config.NetworkConfigService;
-import org.onosproject.net.host.HostService;
-import org.onosproject.net.intent.IntentService;
+import org.onosproject.routing.IntentSynchronizationAdminService;
import org.onosproject.routing.IntentSynchronizationService;
import org.onosproject.routing.RoutingService;
-import org.onosproject.routing.SdnIpService;
-import org.onosproject.routing.config.RoutingConfigurationService;
import org.slf4j.Logger;
+import static org.slf4j.LoggerFactory.getLogger;
+
/**
* Component for the SDN-IP peering application.
*/
@Component(immediate = true)
-@Service
-public class SdnIp implements SdnIpService {
+public class SdnIp {
- private static final String SDN_IP_APP = "org.onosproject.sdnip";
+ public static final String SDN_IP_APP = "org.onosproject.sdnip";
private final Logger log = getLogger(getClass());
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected CoreService coreService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected IntentService intentService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ApplicationService applicationService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected HostService hostService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected ClusterService clusterService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected LeadershipService leadershipService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected RoutingService routingService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected RoutingConfigurationService config;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected NetworkConfigService networkConfigService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected InterfaceService interfaceService;
- private IntentSynchronizer intentSynchronizer;
- private PeerConnectivityManager peerConnectivity;
- private SdnIpFib fib;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected IntentSynchronizationService intentSynchronizer;
- private LeadershipEventListener leadershipEventListener =
- new InnerLeadershipEventListener();
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected IntentSynchronizationAdminService intentSynchronizerAdmin;
+
+ private PeerConnectivityManager peerConnectivity;
+
private ApplicationId appId;
- private ControllerNode localControllerNode;
@Activate
protected void activate() {
- log.info("SDN-IP started");
-
appId = coreService.registerApplication(SDN_IP_APP);
- localControllerNode = clusterService.getLocalNode();
-
- intentSynchronizer = new IntentSynchronizer(appId, intentService);
- intentSynchronizer.start();
-
peerConnectivity = new PeerConnectivityManager(appId,
intentSynchronizer,
networkConfigService,
- coreService.getAppId(RoutingService.ROUTER_APP_ID),
+ coreService.registerApplication(RoutingService.ROUTER_APP_ID),
interfaceService);
peerConnectivity.start();
- fib = new SdnIpFib(appId, interfaceService, intentSynchronizer);
-
- routingService.addFibListener(fib);
- routingService.start();
-
- leadershipService.addListener(leadershipEventListener);
- leadershipService.runForLeadership(appId.name());
-
+ // TODO fix removing intents
applicationService.registerDeactivateHook(appId,
- intentSynchronizer::removeIntents);
+ intentSynchronizerAdmin::removeIntents);
+ log.info("SDN-IP started");
}
@Deactivate
protected void deactivate() {
- routingService.stop();
peerConnectivity.stop();
- intentSynchronizer.stop();
-
- leadershipService.withdraw(appId.name());
- leadershipService.removeListener(leadershipEventListener);
log.info("SDN-IP Stopped");
}
- @Override
- public void modifyPrimary(boolean isPrimary) {
- intentSynchronizer.leaderChanged(isPrimary);
- }
-
- @Override
- public IntentSynchronizationService getIntentSynchronizationService() {
- return intentSynchronizer;
- }
-
/**
* Converts DPIDs of the form xx:xx:xx:xx:xx:xx:xx to OpenFlow provider
* device URIs.
@@ -156,38 +99,5 @@
return "of:" + dpid.replace(":", "");
}
- /**
- * A listener for Leadership Events.
- */
- private class InnerLeadershipEventListener
- implements LeadershipEventListener {
- @Override
- public void event(LeadershipEvent event) {
- log.debug("Leadership Event: time = {} type = {} event = {}",
- event.time(), event.type(), event);
-
- if (!event.subject().topic().equals(appId.name())) {
- return; // Not our topic: ignore
- }
- if (!Objects.equals(event.subject().leader(), localControllerNode.id())) {
- return; // The event is not about this instance: ignore
- }
-
- switch (event.type()) {
- case LEADER_ELECTED:
- log.info("SDN-IP Leader Elected");
- intentSynchronizer.leaderChanged(true);
- break;
- case LEADER_BOOTED:
- log.info("SDN-IP Leader Lost Election");
- intentSynchronizer.leaderChanged(false);
- break;
- case LEADER_REELECTED:
- 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 9113e01..ac9baab 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/SdnIpFib.java
@@ -17,12 +17,18 @@
package org.onosproject.sdnip;
import com.google.common.collect.ImmutableList;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
import org.onosproject.incubator.net.intf.Interface;
import org.onosproject.incubator.net.intf.InterfaceService;
import org.onosproject.net.ConnectPoint;
@@ -37,6 +43,7 @@
import org.onosproject.routing.FibListener;
import org.onosproject.routing.FibUpdate;
import org.onosproject.routing.IntentSynchronizationService;
+import org.onosproject.routing.RoutingService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -51,40 +58,49 @@
/**
* FIB component of SDN-IP.
*/
-public class SdnIpFib implements FibListener {
+@Component(immediate = true)
+public class SdnIpFib {
private Logger log = LoggerFactory.getLogger(getClass());
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected InterfaceService interfaceService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected IntentSynchronizationService intentSynchronizer;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected RoutingService routingService;
+
+ private final InternalFibListener fibListener = new InternalFibListener();
+
private static final int PRIORITY_OFFSET = 100;
private static final int PRIORITY_MULTIPLIER = 5;
protected static final ImmutableList<Constraint> CONSTRAINTS
= ImmutableList.of(new PartialFailureConstraint());
- private final Map<IpPrefix, MultiPointToSinglePointIntent> routeIntents;
+ private final Map<IpPrefix, MultiPointToSinglePointIntent> routeIntents
+ = new ConcurrentHashMap<>();
- private final ApplicationId appId;
- private final InterfaceService interfaceService;
- private final IntentSynchronizationService intentSynchronizer;
+ private ApplicationId appId;
- /**
- * Class constructor.
- *
- * @param appId application ID to use when generating intents
- * @param interfaceService interface service
- * @param intentSynchronizer intent synchronizer
- */
- public SdnIpFib(ApplicationId appId, InterfaceService interfaceService,
- IntentSynchronizationService intentSynchronizer) {
- routeIntents = new ConcurrentHashMap<>();
+ @Activate
+ public void activate() {
+ appId = coreService.getAppId(SdnIp.SDN_IP_APP);
- this.appId = appId;
- this.interfaceService = interfaceService;
- this.intentSynchronizer = intentSynchronizer;
+ routingService.addFibListener(fibListener);
+ routingService.start();
}
+ @Deactivate
+ public void deactivate() {
+ // TODO remove listener
+ routingService.stop();
+ }
- @Override
- public void update(Collection<FibUpdate> updates,
- Collection<FibUpdate> withdraws) {
+ private void update(Collection<FibUpdate> updates, Collection<FibUpdate> withdraws) {
int submitCount = 0, withdrawCount = 0;
//
// NOTE: Semantically, we MUST withdraw existing intents before
@@ -224,4 +240,11 @@
.build();
}
+ private class InternalFibListener implements FibListener {
+ @Override
+ public void update(Collection<FibUpdate> updates, Collection<FibUpdate> withdraws) {
+ SdnIpFib.this.update(updates, withdraws);
+ }
+ }
+
}
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/PrimaryChangeCommand.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/PrimaryChangeCommand.java
index 7a17cfe..11da428 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/PrimaryChangeCommand.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/cli/PrimaryChangeCommand.java
@@ -18,10 +18,10 @@
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.routing.SdnIpService;
+import org.onosproject.routing.IntentSynchronizationAdminService;
/**
- * Command to change whether this SDNIP instance is primary or not.
+ * Command to change whether this instance's intent synchronizer is primary.
*/
@Command(scope = "onos", name = "sdnip-set-primary",
description = "Changes the primary status of this SDN-IP instance")
@@ -34,7 +34,7 @@
@Override
protected void execute() {
- get(SdnIpService.class).modifyPrimary(isPrimary);
+ get(IntentSynchronizationAdminService.class).modifyPrimary(isPrimary);
}
}
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java
index 1265cc1..37c50d3 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java
@@ -29,7 +29,9 @@
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.TestApplicationId;
+import org.onosproject.cluster.LeadershipServiceAdapter;
import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.incubator.net.intf.Interface;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
@@ -43,14 +45,15 @@
import org.onosproject.net.intent.Intent;
import org.onosproject.net.intent.IntentService;
import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.IntentUtils;
import org.onosproject.net.intent.Key;
import org.onosproject.net.intent.MultiPointToSinglePointIntent;
-import org.onosproject.net.intent.IntentUtils;
import org.onosproject.routing.RouteEntry;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
+import java.util.concurrent.ExecutorService;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
@@ -88,7 +91,8 @@
private IntentSynchronizer intentSynchronizer;
private final Set<Interface> interfaces = Sets.newHashSet();
- private static final ApplicationId APPID = TestApplicationId.create("SDNIP");
+ private static final ApplicationId APPID =
+ TestApplicationId.create("intent-sync-test");
@Before
public void setUp() throws Exception {
@@ -98,8 +102,13 @@
intentService = createMock(IntentService.class);
- intentSynchronizer = new IntentSynchronizer(APPID, intentService,
- MoreExecutors.newDirectExecutorService());
+ intentSynchronizer = new TestIntentSynchronizer();
+
+ intentSynchronizer.coreService = new TestCoreService();
+ intentSynchronizer.leadershipService = new TestLeadershipService();
+ intentSynchronizer.intentService = intentService;
+
+ intentSynchronizer.activate();
}
/**
@@ -268,7 +277,7 @@
// Give the leadership to the intent synchronizer. It will now attempt
// to synchronize the intents in the store with the intents it has
// recorded based on the earlier user input.
- intentSynchronizer.leaderChanged(true);
+ intentSynchronizer.modifyPrimary(true);
verify(intentService);
}
@@ -290,7 +299,7 @@
// Give the intent synchronizer leadership so it will submit intents
// to the intent service
- intentSynchronizer.leaderChanged(true);
+ intentSynchronizer.modifyPrimary(true);
// Test the submit
intentSynchronizer.submit(intent);
@@ -303,7 +312,7 @@
reset(intentService);
replay(intentService);
- intentSynchronizer.leaderChanged(false);
+ intentSynchronizer.modifyPrimary(false);
intentSynchronizer.submit(intent);
@@ -328,7 +337,7 @@
// Give the intent synchronizer leadership so it will submit intents
// to the intent service
- intentSynchronizer.leaderChanged(true);
+ intentSynchronizer.modifyPrimary(true);
// Test the submit then withdraw
intentSynchronizer.submit(intent);
@@ -342,7 +351,7 @@
reset(intentService);
replay(intentService);
- intentSynchronizer.leaderChanged(false);
+ intentSynchronizer.modifyPrimary(false);
intentSynchronizer.submit(intent);
intentSynchronizer.withdraw(intent);
@@ -418,4 +427,22 @@
"ingressPoints", intent.ingressPoints());
return intentNew;
}
+
+ private class TestIntentSynchronizer extends IntentSynchronizer {
+ @Override
+ protected ExecutorService createExecutor() {
+ return MoreExecutors.newDirectExecutorService();
+ }
+ }
+
+ private class TestCoreService extends CoreServiceAdapter {
+ @Override
+ public ApplicationId registerApplication(String name) {
+ return APPID;
+ }
+ }
+
+ private class TestLeadershipService extends LeadershipServiceAdapter {
+
+ }
}
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 5466d52..5c3243f 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/SdnIpFibTest.java
@@ -28,6 +28,7 @@
import org.onlab.packet.VlanId;
import org.onosproject.TestApplicationId;
import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreServiceAdapter;
import org.onosproject.incubator.net.intf.Interface;
import org.onosproject.incubator.net.intf.InterfaceService;
import org.onosproject.net.ConnectPoint;
@@ -42,8 +43,10 @@
import org.onosproject.net.intent.Key;
import org.onosproject.net.intent.MultiPointToSinglePointIntent;
import org.onosproject.routing.FibEntry;
+import org.onosproject.routing.FibListener;
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;
@@ -90,6 +93,8 @@
private static final ApplicationId APPID = TestApplicationId.create("SDNIP");
+ private FibListener fibListener;
+
@Before
public void setUp() throws Exception {
super.setUp();
@@ -106,7 +111,13 @@
intentSynchronizer = createMock(IntentSynchronizationService.class);
- sdnipFib = new SdnIpFib(APPID, interfaceService, intentSynchronizer);
+ sdnipFib = new SdnIpFib();
+ sdnipFib.routingService = new TestRoutingService();
+ sdnipFib.coreService = new TestCoreService();
+ sdnipFib.interfaceService = interfaceService;
+ sdnipFib.intentSynchronizer = intentSynchronizer;
+
+ sdnipFib.activate();
}
/**
@@ -242,7 +253,7 @@
// Send in the UPDATE FibUpdate
FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
- sdnipFib.update(Collections.singleton(fibUpdate), Collections.emptyList());
+ fibListener.update(Collections.singleton(fibUpdate), Collections.emptyList());
verify(intentSynchronizer);
}
@@ -295,7 +306,7 @@
// Send in the UPDATE FibUpdate
FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
- sdnipFib.update(Collections.singleton(fibUpdate), Collections.emptyList());
+ fibListener.update(Collections.singleton(fibUpdate), Collections.emptyList());
verify(intentSynchronizer);
}
@@ -354,7 +365,7 @@
// Send in the UPDATE FibUpdate
FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE,
fibEntryUpdate);
- sdnipFib.update(Collections.singletonList(fibUpdate),
+ fibListener.update(Collections.singletonList(fibUpdate),
Collections.emptyList());
verify(intentSynchronizer);
@@ -410,8 +421,23 @@
// Send in the DELETE FibUpdate
FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.DELETE, fibEntry);
- sdnipFib.update(Collections.emptyList(), Collections.singletonList(fibUpdate));
+ fibListener.update(Collections.emptyList(), Collections.singletonList(fibUpdate));
verify(intentSynchronizer);
}
+
+ private class TestCoreService extends CoreServiceAdapter {
+ @Override
+ public ApplicationId getAppId(String name) {
+ return APPID;
+ }
+ }
+
+ private class TestRoutingService extends RoutingServiceAdapter {
+
+ @Override
+ public void addFibListener(FibListener fibListener) {
+ SdnIpFibTest.this.fibListener = fibListener;
+ }
+ }
}