CORD-151 Refactor cordvtn service to reduce complexity
Change-Id: I489e1d3df7f08d04d6b6a2aa23b9d4e6d7a054e4
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/NodeConnectionManager.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/NodeConnectionManager.java
index 908aff2..ebba4cd 100644
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/NodeConnectionManager.java
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/NodeConnectionManager.java
@@ -15,12 +15,19 @@
*/
package org.onosproject.cordvtn;
+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.onosproject.cluster.ClusterService;
import org.onosproject.cluster.LeadershipService;
import org.onosproject.cluster.NodeId;
-import org.onosproject.core.ApplicationId;
import org.onosproject.mastership.MastershipService;
-import org.onosproject.net.DeviceId;
-import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.net.Device;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
import org.slf4j.Logger;
import java.util.concurrent.Executors;
@@ -28,120 +35,131 @@
import java.util.concurrent.TimeUnit;
import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.cordvtn.OvsdbNode.State.CONNECTED;
+import static org.onosproject.cordvtn.OvsdbNode.State.DISCONNECTED;
+import static org.onosproject.cordvtn.OvsdbNode.State.READY;
import static org.slf4j.LoggerFactory.getLogger;
/**
- * Node connection manager.
+ * Provides the connection state management of all nodes registered to the service
+ * so that the nodes keep connected unless it is requested to be deleted.
*/
+@Component(immediate = true)
public class NodeConnectionManager {
protected final Logger log = getLogger(getClass());
- private final ApplicationId appId;
- private final NodeId localId;
- private final EventuallyConsistentMap<DeviceId, OvsdbNode> nodeStore;
- private final MastershipService mastershipService;
- private final LeadershipService leadershipService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ MastershipService mastershipService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ LeadershipService leadershipService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ ClusterService clusterService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ DeviceService deviceService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ CordVtnService cordVtnService;
private static final int DELAY_SEC = 5;
- private ScheduledExecutorService connectionExecutor;
- /**
- * Creates a new NodeConnectionManager.
- *
- * @param appId app id
- * @param localId local id
- * @param nodeStore node store
- * @param mastershipService mastership service
- * @param leadershipService leadership service
- */
- public NodeConnectionManager(ApplicationId appId, NodeId localId,
- EventuallyConsistentMap<DeviceId, OvsdbNode> nodeStore,
- MastershipService mastershipService,
- LeadershipService leadershipService) {
- this.appId = appId;
- this.localId = localId;
- this.nodeStore = nodeStore;
- this.mastershipService = mastershipService;
- this.leadershipService = leadershipService;
- }
+ private final DeviceListener deviceListener = new InternalDeviceListener();
+ private final ScheduledExecutorService connectionExecutor = Executors
+ .newSingleThreadScheduledExecutor(groupedThreads("onos/cordvtn", "connection-manager"));
- /**
- * Starts the node connection manager.
- */
- public void start() {
- connectionExecutor = Executors.newSingleThreadScheduledExecutor(
- groupedThreads("onos/cordvtn", "connection-executor"));
- connectionExecutor.scheduleWithFixedDelay(() -> nodeStore.values()
+ private NodeId localId;
+
+ @Activate
+ protected void activate() {
+ localId = clusterService.getLocalNode().id();
+ deviceService.addListener(deviceListener);
+
+ connectionExecutor.scheduleWithFixedDelay(() -> cordVtnService.getNodes()
.stream()
.filter(node -> localId.equals(getMaster(node)))
- .forEach(this::connectNode), 0, DELAY_SEC, TimeUnit.SECONDS);
+ .forEach(node -> {
+ connect(node);
+ disconnect(node);
+ }), 0, DELAY_SEC, TimeUnit.SECONDS);
}
- /**
- * Stops the node connection manager.
- */
+ @Deactivate
public void stop() {
connectionExecutor.shutdown();
+ deviceService.removeListener(deviceListener);
}
- /**
- * Adds a new node to the system.
- *
- * @param ovsdbNode ovsdb node
- */
- public void connectNode(OvsdbNode ovsdbNode) {
+ public void connect(OvsdbNode ovsdbNode) {
switch (ovsdbNode.state()) {
case INIT:
case DISCONNECTED:
- // TODO: set the node to passive mode
+ setPassiveMode(ovsdbNode);
case READY:
- // TODO: initiate connection
- break;
- case CONNECTED:
+ setupConnection(ovsdbNode);
break;
default:
+ break;
}
}
- /**
- * Deletes the ovsdb node.
- *
- * @param ovsdbNode ovsdb node
- */
- public void disconnectNode(OvsdbNode ovsdbNode) {
+ public void disconnect(OvsdbNode ovsdbNode) {
switch (ovsdbNode.state()) {
- case CONNECTED:
+ case DISCONNECT:
// TODO: disconnect
break;
- case INIT:
- case READY:
- case DISCONNECTED:
- break;
default:
+ break;
+ }
+ }
+
+ private class InternalDeviceListener implements DeviceListener {
+
+ @Override
+ public void event(DeviceEvent event) {
+ Device device = event.subject();
+ if (device.type() != Device.Type.CONTROLLER) {
+ return;
+ }
+
+ DefaultOvsdbNode node;
+ switch (event.type()) {
+ case DEVICE_ADDED:
+ node = (DefaultOvsdbNode) cordVtnService.getNode(device.id());
+ if (node != null) {
+ cordVtnService.updateNode(node, CONNECTED);
+ }
+ break;
+ case DEVICE_AVAILABILITY_CHANGED:
+ node = (DefaultOvsdbNode) cordVtnService.getNode(device.id());
+ if (node != null) {
+ cordVtnService.updateNode(node, DISCONNECTED);
+ }
+ break;
+ default:
+ break;
+ }
}
}
private NodeId getMaster(OvsdbNode ovsdbNode) {
- // Return the master of the bridge(switch) if it exist or
- // return the current leader
- if (ovsdbNode.bridgeId() == DeviceId.NONE) {
- return leadershipService.getLeader(this.appId.name());
- } else {
- return mastershipService.getMasterFor(ovsdbNode.bridgeId());
+ NodeId master = mastershipService.getMasterFor(ovsdbNode.intBrId());
+
+ // master is null if there's no such device
+ if (master == null) {
+ master = leadershipService.getLeader(CordVtnService.CORDVTN_APP_ID);
}
+ return master;
}
private void setPassiveMode(OvsdbNode ovsdbNode) {
// TODO: need ovsdb client implementation first
// TODO: set the remove ovsdb server passive mode
- // TODO: set the node state READY if it succeed
+ cordVtnService.updateNode(ovsdbNode, READY);
}
- private void connect(OvsdbNode ovsdbNode) {
- // TODO: need ovsdb client implementation first
- }
-
- private void disconnect(OvsdbNode ovsdbNode) {
- // TODO: need ovsdb client implementation first
+ private void setupConnection(OvsdbNode ovsdbNode) {
+ // TODO initiate connection
}
}