[ONOS-7054] Implement prototype of ISSU protocol

Change-Id: Id543c0de9c97b68f977c824cbc987b35d81beb2d
diff --git a/core/api/src/main/java/org/onosproject/cluster/ClusterAdminService.java b/core/api/src/main/java/org/onosproject/cluster/ClusterAdminService.java
index 625183a..e680877 100644
--- a/core/api/src/main/java/org/onosproject/cluster/ClusterAdminService.java
+++ b/core/api/src/main/java/org/onosproject/cluster/ClusterAdminService.java
@@ -15,56 +15,14 @@
  */
 package org.onosproject.cluster;
 
-import org.onlab.packet.IpAddress;
-
-import java.util.Set;
-
 /**
  * Service for administering the cluster node membership.
+ * <p>
+ * This service has a view of the cluster membership that is isolated to the local node's version during upgrades.
+ * For an equivalent service that has control over all nodes during an upgrade use
+ * {@link UnifiedClusterAdminService}.
+ *
+ * @see UnifiedClusterAdminService
  */
-public interface ClusterAdminService extends ClusterService {
-
-    /**
-     * Forms cluster configuration based on the specified set of node
-     * information.&nbsp; This method resets and restarts the controller
-     * instance.
-     *
-     * @param nodes    set of nodes that form the cluster
-     */
-    void formCluster(Set<ControllerNode> nodes);
-
-    /**
-     * Forms cluster configuration based on the specified set of node
-     * information.&nbsp; This method resets and restarts the controller
-     * instance.
-     *
-     * @param nodes    set of nodes that form the cluster
-     * @param partitionSize number of nodes to compose a partition
-     */
-    void formCluster(Set<ControllerNode> nodes, int partitionSize);
-
-    /**
-     * Adds a new controller node to the cluster.
-     *
-     * @param nodeId  controller node identifier
-     * @param ip      node IP listen address
-     * @param tcpPort tcp listen port
-     * @return newly added node
-     */
-    ControllerNode addNode(NodeId nodeId, IpAddress ip, int tcpPort);
-
-    /**
-     * Removes the specified node from the cluster node list.
-     *
-     * @param nodeId controller node identifier
-     */
-    void removeNode(NodeId nodeId);
-
-    /**
-     * Marks the current node as fully started or not.
-     *
-     * @param started true indicates all components have been started
-     */
-    void markFullyStarted(boolean started);
-
+public interface ClusterAdminService extends MembershipAdminService {
 }
diff --git a/core/api/src/main/java/org/onosproject/cluster/ClusterService.java b/core/api/src/main/java/org/onosproject/cluster/ClusterService.java
index 964357f..f17e4d9 100644
--- a/core/api/src/main/java/org/onosproject/cluster/ClusterService.java
+++ b/core/api/src/main/java/org/onosproject/cluster/ClusterService.java
@@ -15,65 +15,13 @@
  */
 package org.onosproject.cluster;
 
-import java.util.Set;
-
-import org.joda.time.DateTime;
-import org.onosproject.core.Version;
-import org.onosproject.event.ListenerService;
-
 /**
- * Service for obtaining information about the individual nodes within
- * the controller cluster.
+ * Service for obtaining information about the individual nodes within the controller cluster.
+ * <p>
+ * This service's view of the nodes in the cluster is isolated to a single version of the software. During upgrades,
+ * when multiple versions of the software are running in the same cluster, users of this service will only be able
+ * to see nodes running the same version as the local node. This is useful for limiting communication to nodes running
+ * the same version of the software.
  */
-public interface ClusterService
-    extends ListenerService<ClusterEvent, ClusterEventListener> {
-
-    /**
-     * Returns the local controller node.
-     *
-     * @return local controller node
-     */
-    ControllerNode getLocalNode();
-
-    /**
-     * Returns the set of current cluster members.
-     *
-     * @return set of cluster members
-     */
-    Set<ControllerNode> getNodes();
-
-    /**
-     * Returns the specified controller node.
-     *
-     * @param nodeId controller node identifier
-     * @return controller node
-     */
-    ControllerNode getNode(NodeId nodeId);
-
-    /**
-     * Returns the availability state of the specified controller node. Note
-     * that this does not imply that all the core and application components
-     * have been fully activated; only that the node has joined the cluster.
-     *
-     * @param nodeId controller node identifier
-     * @return availability state
-     */
-    ControllerNode.State getState(NodeId nodeId);
-
-    /**
-     * Returns the version of the given controller node.
-     *
-     * @param nodeId controller node identifier
-     * @return controller version
-     */
-    Version getVersion(NodeId nodeId);
-
-    /**
-     * Returns the system time when the availability state was last updated.
-     *
-     * @param nodeId controller node identifier
-     * @return system time when the availability state was last updated.
-     */
-    DateTime getLastUpdated(NodeId nodeId);
-
+public interface ClusterService extends MembershipService {
 }
diff --git a/core/api/src/main/java/org/onosproject/cluster/MembershipAdminService.java b/core/api/src/main/java/org/onosproject/cluster/MembershipAdminService.java
new file mode 100644
index 0000000..908a963
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/cluster/MembershipAdminService.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.cluster;
+
+import java.util.Set;
+
+import org.onlab.packet.IpAddress;
+
+/**
+ * Service for administering the cluster node membership.
+ */
+public interface MembershipAdminService extends MembershipService {
+
+    /**
+     * Forms cluster configuration based on the specified set of node
+     * information.&nbsp; This method resets and restarts the controller
+     * instance.
+     *
+     * @param nodes    set of nodes that form the cluster
+     */
+    void formCluster(Set<ControllerNode> nodes);
+
+    /**
+     * Forms cluster configuration based on the specified set of node
+     * information.&nbsp; This method resets and restarts the controller
+     * instance.
+     *
+     * @param nodes    set of nodes that form the cluster
+     * @param partitionSize number of nodes to compose a partition
+     */
+    void formCluster(Set<ControllerNode> nodes, int partitionSize);
+
+    /**
+     * Adds a new controller node to the cluster.
+     *
+     * @param nodeId  controller node identifier
+     * @param ip      node IP listen address
+     * @param tcpPort tcp listen port
+     * @return newly added node
+     */
+    ControllerNode addNode(NodeId nodeId, IpAddress ip, int tcpPort);
+
+    /**
+     * Removes the specified node from the cluster node list.
+     *
+     * @param nodeId controller node identifier
+     */
+    void removeNode(NodeId nodeId);
+
+    /**
+     * Marks the current node as fully started or not.
+     *
+     * @param started true indicates all components have been started
+     */
+    void markFullyStarted(boolean started);
+
+}
diff --git a/core/api/src/main/java/org/onosproject/cluster/MembershipService.java b/core/api/src/main/java/org/onosproject/cluster/MembershipService.java
new file mode 100644
index 0000000..7b366f6
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/cluster/MembershipService.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.cluster;
+
+import java.util.Set;
+
+import org.joda.time.DateTime;
+import org.onosproject.core.Version;
+import org.onosproject.event.ListenerService;
+
+/**
+ * Service for obtaining information about the individual nodes within
+ * the controller cluster.
+ */
+public interface MembershipService
+    extends ListenerService<ClusterEvent, ClusterEventListener> {
+
+    /**
+     * Returns the local controller node.
+     *
+     * @return local controller node
+     */
+    ControllerNode getLocalNode();
+
+    /**
+     * Returns the set of current cluster members.
+     *
+     * @return set of cluster members
+     */
+    Set<ControllerNode> getNodes();
+
+    /**
+     * Returns the specified controller node.
+     *
+     * @param nodeId controller node identifier
+     * @return controller node
+     */
+    ControllerNode getNode(NodeId nodeId);
+
+    /**
+     * Returns the availability state of the specified controller node. Note
+     * that this does not imply that all the core and application components
+     * have been fully activated; only that the node has joined the cluster.
+     *
+     * @param nodeId controller node identifier
+     * @return availability state
+     */
+    ControllerNode.State getState(NodeId nodeId);
+
+    /**
+     * Returns the version of the given controller node.
+     *
+     * @param nodeId controller node identifier
+     * @return controller version
+     */
+    Version getVersion(NodeId nodeId);
+
+    /**
+     * Returns the system time when the availability state was last updated.
+     *
+     * @param nodeId controller node identifier
+     * @return system time when the availability state was last updated.
+     */
+    DateTime getLastUpdated(NodeId nodeId);
+
+}
diff --git a/core/api/src/main/java/org/onosproject/cluster/PartitionId.java b/core/api/src/main/java/org/onosproject/cluster/PartitionId.java
index f8b65e7..39852de 100644
--- a/core/api/src/main/java/org/onosproject/cluster/PartitionId.java
+++ b/core/api/src/main/java/org/onosproject/cluster/PartitionId.java
@@ -25,6 +25,11 @@
 public class PartitionId extends Identifier<Integer> implements Comparable<PartitionId> {
 
     /**
+     * The {@code PartitionId} for the shared coordination partition.
+     */
+    public static final PartitionId SHARED = PartitionId.from(0);
+
+    /**
      * Creates a partition identifier from an integer.
      *
      * @param id input integer
diff --git a/core/api/src/main/java/org/onosproject/cluster/UnifiedClusterAdminService.java b/core/api/src/main/java/org/onosproject/cluster/UnifiedClusterAdminService.java
new file mode 100644
index 0000000..9fb7407
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/cluster/UnifiedClusterAdminService.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.cluster;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Cluster membership administration service that supports modification of all nodes during an upgrade.
+ */
+@Beta
+public interface UnifiedClusterAdminService extends MembershipAdminService {
+}
diff --git a/core/api/src/main/java/org/onosproject/cluster/UnifiedClusterService.java b/core/api/src/main/java/org/onosproject/cluster/UnifiedClusterService.java
new file mode 100644
index 0000000..f690f3e
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/cluster/UnifiedClusterService.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.cluster;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Unified multi-version cluster membership service.
+ * <p>
+ * During upgrades, the nodes within a cluster may be running multiple versions of the software.
+ * This service has a view of the entire cluster running any version. Users of this service must be careful when
+ * communicating with nodes described by this service as compatibility issues can result from communicating across
+ * versions. For an equivalent service that has an isolated view of the cluster, see {@link ClusterService}.
+ *
+ * @see ClusterService
+ */
+@Beta
+public interface UnifiedClusterService extends MembershipService {
+}