[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. 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. 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. 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. 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 {
+}
diff --git a/core/api/src/main/java/org/onosproject/store/cluster/messaging/ClusterCommunicationService.java b/core/api/src/main/java/org/onosproject/store/cluster/messaging/ClusterCommunicationService.java
index 4a46885..dfc558d 100644
--- a/core/api/src/main/java/org/onosproject/store/cluster/messaging/ClusterCommunicationService.java
+++ b/core/api/src/main/java/org/onosproject/store/cluster/messaging/ClusterCommunicationService.java
@@ -15,152 +15,15 @@
*/
package org.onosproject.store.cluster.messaging;
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.function.Consumer;
-import java.util.function.Function;
-
-import org.onosproject.cluster.NodeId;
-
/**
* Service for assisting communications between controller cluster nodes.
+ * <p>
+ * Communication via this service is isolated to nodes running a single version of the software. During upgrades, when
+ * nodes may be running multiple versions simultaneously, this service prevents nodes running different versions of
+ * the software from communicating with each other, thus avoiding compatibility issues. For an equivalent cross-version
+ * compatible service, see {@link UnifiedClusterCommunicationService}.
+ *
+ * @see UnifiedClusterCommunicationService
*/
-public interface ClusterCommunicationService {
-
- /**
- * Adds a new subscriber for the specified message subject.
- *
- * @param subject message subject
- * @param subscriber message subscriber
- * @param executor executor to use for running handler.
- * @deprecated in Cardinal Release
- */
- @Deprecated
- void addSubscriber(MessageSubject subject, ClusterMessageHandler subscriber, ExecutorService executor);
-
- /**
- * Broadcasts a message to all controller nodes.
- *
- * @param message message to send
- * @param subject message subject
- * @param encoder function for encoding message to byte[]
- * @param <M> message type
- */
- <M> void broadcast(M message,
- MessageSubject subject,
- Function<M, byte[]> encoder);
-
- /**
- * Broadcasts a message to all controller nodes including self.
- *
- * @param message message to send
- * @param subject message subject
- * @param encoder function for encoding message to byte[]
- * @param <M> message type
- */
- <M> void broadcastIncludeSelf(M message,
- MessageSubject subject,
- Function<M, byte[]> encoder);
-
- /**
- * Sends a message to the specified controller node.
- *
- * @param message message to send
- * @param subject message subject
- * @param encoder function for encoding message to byte[]
- * @param toNodeId destination node identifier
- * @param <M> message type
- * @return future that is completed when the message is sent
- */
- <M> CompletableFuture<Void> unicast(M message,
- MessageSubject subject,
- Function<M, byte[]> encoder,
- NodeId toNodeId);
-
- /**
- * Multicasts a message to a set of controller nodes.
- *
- * @param message message to send
- * @param subject message subject
- * @param encoder function for encoding message to byte[]
- * @param nodeIds recipient node identifiers
- * @param <M> message type
- */
- <M> void multicast(M message,
- MessageSubject subject,
- Function<M, byte[]> encoder,
- Set<NodeId> nodeIds);
-
- /**
- * Sends a message and expects a reply.
- *
- * @param message message to send
- * @param subject message subject
- * @param encoder function for encoding request to byte[]
- * @param decoder function for decoding response from byte[]
- * @param toNodeId recipient node identifier
- * @param <M> request type
- * @param <R> reply type
- * @return reply future
- */
- <M, R> CompletableFuture<R> sendAndReceive(M message,
- MessageSubject subject,
- Function<M, byte[]> encoder,
- Function<byte[], R> decoder,
- NodeId toNodeId);
-
- /**
- * Adds a new subscriber for the specified message subject.
- *
- * @param subject message subject
- * @param decoder decoder for resurrecting incoming message
- * @param handler handler function that processes the incoming message and produces a reply
- * @param encoder encoder for serializing reply
- * @param executor executor to run this handler on
- * @param <M> incoming message type
- * @param <R> reply message type
- */
- <M, R> void addSubscriber(MessageSubject subject,
- Function<byte[], M> decoder,
- Function<M, R> handler,
- Function<R, byte[]> encoder,
- Executor executor);
-
- /**
- * Adds a new subscriber for the specified message subject.
- *
- * @param subject message subject
- * @param decoder decoder for resurrecting incoming message
- * @param handler handler function that processes the incoming message and produces a reply
- * @param encoder encoder for serializing reply
- * @param <M> incoming message type
- * @param <R> reply message type
- */
- <M, R> void addSubscriber(MessageSubject subject,
- Function<byte[], M> decoder,
- Function<M, CompletableFuture<R>> handler,
- Function<R, byte[]> encoder);
-
- /**
- * Adds a new subscriber for the specified message subject.
- *
- * @param subject message subject
- * @param decoder decoder to resurrecting incoming message
- * @param handler handler for handling message
- * @param executor executor to run this handler on
- * @param <M> incoming message type
- */
- <M> void addSubscriber(MessageSubject subject,
- Function<byte[], M> decoder,
- Consumer<M> handler,
- Executor executor);
-
- /**
- * Removes a subscriber for the specified message subject.
- *
- * @param subject message subject
- */
- void removeSubscriber(MessageSubject subject);
+public interface ClusterCommunicationService extends ClusterCommunicator {
}
diff --git a/core/api/src/main/java/org/onosproject/store/cluster/messaging/ClusterCommunicator.java b/core/api/src/main/java/org/onosproject/store/cluster/messaging/ClusterCommunicator.java
new file mode 100644
index 0000000..7d2480e
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/store/cluster/messaging/ClusterCommunicator.java
@@ -0,0 +1,166 @@
+/*
+ * 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.store.cluster.messaging;
+
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+import org.onosproject.cluster.NodeId;
+
+/**
+ * Service for assisting communications between controller cluster nodes.
+ */
+public interface ClusterCommunicator {
+
+ /**
+ * Adds a new subscriber for the specified message subject.
+ *
+ * @param subject message subject
+ * @param subscriber message subscriber
+ * @param executor executor to use for running handler.
+ * @deprecated in Cardinal Release
+ */
+ @Deprecated
+ void addSubscriber(MessageSubject subject, ClusterMessageHandler subscriber, ExecutorService executor);
+
+ /**
+ * Broadcasts a message to all controller nodes.
+ *
+ * @param message message to send
+ * @param subject message subject
+ * @param encoder function for encoding message to byte[]
+ * @param <M> message type
+ */
+ <M> void broadcast(M message,
+ MessageSubject subject,
+ Function<M, byte[]> encoder);
+
+ /**
+ * Broadcasts a message to all controller nodes including self.
+ *
+ * @param message message to send
+ * @param subject message subject
+ * @param encoder function for encoding message to byte[]
+ * @param <M> message type
+ */
+ <M> void broadcastIncludeSelf(M message,
+ MessageSubject subject,
+ Function<M, byte[]> encoder);
+
+ /**
+ * Sends a message to the specified controller node.
+ *
+ * @param message message to send
+ * @param subject message subject
+ * @param encoder function for encoding message to byte[]
+ * @param toNodeId destination node identifier
+ * @param <M> message type
+ * @return future that is completed when the message is sent
+ */
+ <M> CompletableFuture<Void> unicast(M message,
+ MessageSubject subject,
+ Function<M, byte[]> encoder,
+ NodeId toNodeId);
+
+ /**
+ * Multicasts a message to a set of controller nodes.
+ *
+ * @param message message to send
+ * @param subject message subject
+ * @param encoder function for encoding message to byte[]
+ * @param nodeIds recipient node identifiers
+ * @param <M> message type
+ */
+ <M> void multicast(M message,
+ MessageSubject subject,
+ Function<M, byte[]> encoder,
+ Set<NodeId> nodeIds);
+
+ /**
+ * Sends a message and expects a reply.
+ *
+ * @param message message to send
+ * @param subject message subject
+ * @param encoder function for encoding request to byte[]
+ * @param decoder function for decoding response from byte[]
+ * @param toNodeId recipient node identifier
+ * @param <M> request type
+ * @param <R> reply type
+ * @return reply future
+ */
+ <M, R> CompletableFuture<R> sendAndReceive(M message,
+ MessageSubject subject,
+ Function<M, byte[]> encoder,
+ Function<byte[], R> decoder,
+ NodeId toNodeId);
+
+ /**
+ * Adds a new subscriber for the specified message subject.
+ *
+ * @param subject message subject
+ * @param decoder decoder for resurrecting incoming message
+ * @param handler handler function that processes the incoming message and produces a reply
+ * @param encoder encoder for serializing reply
+ * @param executor executor to run this handler on
+ * @param <M> incoming message type
+ * @param <R> reply message type
+ */
+ <M, R> void addSubscriber(MessageSubject subject,
+ Function<byte[], M> decoder,
+ Function<M, R> handler,
+ Function<R, byte[]> encoder,
+ Executor executor);
+
+ /**
+ * Adds a new subscriber for the specified message subject.
+ *
+ * @param subject message subject
+ * @param decoder decoder for resurrecting incoming message
+ * @param handler handler function that processes the incoming message and produces a reply
+ * @param encoder encoder for serializing reply
+ * @param <M> incoming message type
+ * @param <R> reply message type
+ */
+ <M, R> void addSubscriber(MessageSubject subject,
+ Function<byte[], M> decoder,
+ Function<M, CompletableFuture<R>> handler,
+ Function<R, byte[]> encoder);
+
+ /**
+ * Adds a new subscriber for the specified message subject.
+ *
+ * @param subject message subject
+ * @param decoder decoder to resurrecting incoming message
+ * @param handler handler for handling message
+ * @param executor executor to run this handler on
+ * @param <M> incoming message type
+ */
+ <M> void addSubscriber(MessageSubject subject,
+ Function<byte[], M> decoder,
+ Consumer<M> handler,
+ Executor executor);
+
+ /**
+ * Removes a subscriber for the specified message subject.
+ *
+ * @param subject message subject
+ */
+ void removeSubscriber(MessageSubject subject);
+}
diff --git a/core/api/src/main/java/org/onosproject/store/cluster/messaging/UnifiedClusterCommunicationService.java b/core/api/src/main/java/org/onosproject/store/cluster/messaging/UnifiedClusterCommunicationService.java
new file mode 100644
index 0000000..042c803
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/store/cluster/messaging/UnifiedClusterCommunicationService.java
@@ -0,0 +1,31 @@
+/*
+ * 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.store.cluster.messaging;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Service for unified communication across controller nodes running multiple software versions.
+ * <p>
+ * This service supports communicating across nodes running different versions of the software simultaneously. During
+ * upgrades, when nodes may be running a mixture of versions, this service can be used to coordinate across those
+ * versions. But users of this service must be extremely careful to preserve backward/forward compatibility for
+ * messages sent across versions. Encoders and decoders used for messages sent/received on this service should
+ * support evolving schemas.
+ */
+@Beta
+public interface UnifiedClusterCommunicationService extends ClusterCommunicator {
+}
diff --git a/core/api/src/main/java/org/onosproject/store/service/AtomicValue.java b/core/api/src/main/java/org/onosproject/store/service/AtomicValue.java
index a9547c9..adca843 100644
--- a/core/api/src/main/java/org/onosproject/store/service/AtomicValue.java
+++ b/core/api/src/main/java/org/onosproject/store/service/AtomicValue.java
@@ -22,6 +22,11 @@
*/
public interface AtomicValue<V> extends DistributedPrimitive {
+ @Override
+ default Type primitiveType() {
+ return Type.VALUE;
+ }
+
/**
* Atomically sets the value to the given updated value if the current value is equal to the expected value.
* <p>
diff --git a/core/api/src/main/java/org/onosproject/store/service/CoordinationService.java b/core/api/src/main/java/org/onosproject/store/service/CoordinationService.java
new file mode 100644
index 0000000..8725a06
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/store/service/CoordinationService.java
@@ -0,0 +1,35 @@
+/*
+ * 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.store.service;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Cross-version storage/coordination service.
+ * <p>
+ * This is a special type of {@link PrimitiveService} that differs semantically from {@link StorageService} in that
+ * it supports cross-version backward/forward compatible storage. During upgrades, when nodes are running different
+ * versions of the software, this service guarantees that cross-version compatibility will be maintained and provides
+ * shared compatible primitives for coordinating across versions. Users must ensure that all objects stored in
+ * primitives created via this service are stored using a serialization format that is backward/forward compatible,
+ * e.g. using {@link org.onlab.util.KryoNamespace.Builder#setCompatible(boolean)}.
+ *
+ * @see org.onlab.util.KryoNamespace.Builder#setCompatible(boolean)
+ * @see StorageService
+ */
+@Beta
+public interface CoordinationService extends PrimitiveService {
+}
diff --git a/core/api/src/main/java/org/onosproject/store/service/PartitionInfo.java b/core/api/src/main/java/org/onosproject/store/service/PartitionInfo.java
index fb903b8..c3c3835 100644
--- a/core/api/src/main/java/org/onosproject/store/service/PartitionInfo.java
+++ b/core/api/src/main/java/org/onosproject/store/service/PartitionInfo.java
@@ -15,15 +15,16 @@
*/
package org.onosproject.store.service;
-import com.google.common.collect.ImmutableList;
-
import java.util.List;
+import com.google.common.collect.ImmutableList;
+import org.onosproject.cluster.PartitionId;
+
/**
* Contains information about a database partition.
*/
public class PartitionInfo {
- private final String name;
+ private final PartitionId partitionId;
private final long term;
private final List<String> members;
private final String leader;
@@ -31,25 +32,25 @@
/**
* Class constructor.
*
- * @param name partition name
+ * @param partitionId partition identifier
* @param term term number
* @param members partition members
* @param leader leader name
*/
- public PartitionInfo(String name, long term, List<String> members, String leader) {
- this.name = name;
+ public PartitionInfo(PartitionId partitionId, long term, List<String> members, String leader) {
+ this.partitionId = partitionId;
this.term = term;
this.members = ImmutableList.copyOf(members);
this.leader = leader;
}
/**
- * Returns the name of the partition.
+ * Returns the partition ID.
*
- * @return partition name
+ * @return partition ID
*/
- public String name() {
- return name;
+ public PartitionId id() {
+ return partitionId;
}
/**
diff --git a/core/api/src/main/java/org/onosproject/store/service/PrimitiveService.java b/core/api/src/main/java/org/onosproject/store/service/PrimitiveService.java
new file mode 100644
index 0000000..7be0480
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/store/service/PrimitiveService.java
@@ -0,0 +1,217 @@
+/*
+ * 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.store.service;
+
+/**
+ * Primitive service.
+ * <p>
+ * This service provides builders for various distributed primitives.
+ * <p>
+ * It is expected that services and applications will leverage the primitives indirectly provided by
+ * this service for their distributed state management and coordination.
+ */
+public interface PrimitiveService {
+
+ /**
+ * Creates a new EventuallyConsistentMapBuilder.
+ *
+ * @param <K> key type
+ * @param <V> value type
+ * @return builder for an eventually consistent map
+ */
+ <K, V> EventuallyConsistentMapBuilder<K, V> eventuallyConsistentMapBuilder();
+
+ /**
+ * Creates a new ConsistentMapBuilder.
+ *
+ * @param <K> key type
+ * @param <V> value type
+ * @return builder for a consistent map
+ */
+ <K, V> ConsistentMapBuilder<K, V> consistentMapBuilder();
+
+ /**
+ * Creates a new ConsistentMapBuilder.
+ *
+ * @param <V> value type
+ * @return builder for a document tree
+ */
+ <V> DocumentTreeBuilder<V> documentTreeBuilder();
+
+ /**
+ * Creates a new {@code AsyncConsistentTreeMapBuilder}.
+ *
+ * @param <V> value type
+ * @return builder for a consistent tree map
+ */
+ <V> ConsistentTreeMapBuilder<V> consistentTreeMapBuilder();
+
+ /**
+ * Creates a new {@code AsyncConsistentSetMultimapBuilder}.
+ *
+ * @param <K> key type
+ * @param <V> value type
+ * @return builder for a set based consistent multimap
+ */
+ <K, V> ConsistentMultimapBuilder<K, V> consistentMultimapBuilder();
+
+ /**
+ * Creates a new {@code AtomicCounterMapBuilder}.
+ *
+ * @param <K> key type
+ * @return builder for an atomic counter map
+ */
+ <K> AtomicCounterMapBuilder<K> atomicCounterMapBuilder();
+
+ /**
+ * Creates a new DistributedSetBuilder.
+ *
+ * @param <E> set element type
+ * @return builder for a distributed set
+ */
+ <E> DistributedSetBuilder<E> setBuilder();
+
+ /**
+ * Creates a new AtomicCounterBuilder.
+ *
+ * @return atomic counter builder
+ */
+ AtomicCounterBuilder atomicCounterBuilder();
+
+ /**
+ * Creates a new AtomicIdGeneratorBuilder.
+ *
+ * @return atomic ID generator builder
+ */
+ AtomicIdGeneratorBuilder atomicIdGeneratorBuilder();
+
+ /**
+ * Creates a new AtomicValueBuilder.
+ *
+ * @param <V> atomic value type
+ * @return atomic value builder
+ */
+ <V> AtomicValueBuilder<V> atomicValueBuilder();
+
+ /**
+ * Creates a new LeaderElectorBuilder.
+ *
+ * @return leader elector builder
+ */
+ LeaderElectorBuilder leaderElectorBuilder();
+
+ /**
+ * Creates a new transaction context builder.
+ *
+ * @return a builder for a transaction context.
+ */
+ TransactionContextBuilder transactionContextBuilder();
+
+ /**
+ * Returns an instance of {@code AsyncAtomicCounter} with specified name.
+ * @param name counter name
+ *
+ * @return AsyncAtomicCounter instance
+ */
+ default AsyncAtomicCounter getAsyncAtomicCounter(String name) {
+ return atomicCounterBuilder().withName(name).build();
+ }
+
+ /**
+ * Returns an instance of {@code AsyncAtomicIdGenerator} with specified name.
+ *
+ * @param name ID generator name
+ * @return AsyncAtomicIdGenerator instance
+ */
+ default AsyncAtomicIdGenerator getAsyncAtomicIdGenerator(String name) {
+ return atomicIdGeneratorBuilder().withName(name).build();
+ }
+
+ /**
+ * Returns an instance of {@code AtomicCounter} with specified name.
+ * @param name counter name
+ *
+ * @return AtomicCounter instance
+ */
+ default AtomicCounter getAtomicCounter(String name) {
+ return getAsyncAtomicCounter(name).asAtomicCounter();
+ }
+
+ /**
+ * Returns an instance of {@code AtomicIdGenerator} with specified name.
+ *
+ * @param name ID generator name
+ * @return AtomicIdGenerator instance
+ */
+ default AtomicIdGenerator getAtomicIdGenerator(String name) {
+ return getAsyncAtomicIdGenerator(name).asAtomicIdGenerator();
+ }
+
+ /**
+ * Returns an instance of {@code WorkQueue} with specified name.
+ *
+ * @param <E> work element type
+ * @param name work queue name
+ * @param serializer serializer
+ * @return WorkQueue instance
+ */
+ <E> WorkQueue<E> getWorkQueue(String name, Serializer serializer);
+
+ /**
+ * Returns an instance of {@code AsyncDocumentTree} with specified name.
+ *
+ * @param <V> tree node value type
+ * @param name document tree name
+ * @param serializer serializer
+ * @return AsyncDocumentTree instance
+ */
+ <V> AsyncDocumentTree<V> getDocumentTree(String name, Serializer serializer);
+
+ /** Returns a set backed instance of {@code AsyncConsistentMultimap} with
+ * the specified name.
+ *
+ * @param name the multimap name
+ * @param serializer serializer
+ * @param <K> key type
+ * @param <V> value type
+ * @return set backed {@code AsyncConsistentMultimap} instance
+ */
+ <K, V> AsyncConsistentMultimap<K, V> getAsyncSetMultimap(String name,
+ Serializer serializer);
+
+ /**
+ * Returns an instance of {@code AsyncConsistentTreeMap} with the specified
+ * name.
+ *
+ * @param name the treemap name
+ * @param serializer serializer
+ * @param <V> value type
+ * @return set backed {@code AsyncConsistentTreeMap} instance
+ */
+ <V> AsyncConsistentTreeMap<V> getAsyncTreeMap(String name,
+ Serializer serializer);
+
+ /**
+ * Returns an instance of {@code Topic} with specified name.
+ *
+ * @param <T> topic message type
+ * @param name topic name
+ * @param serializer serializer
+ *
+ * @return Topic instance
+ */
+ <T> Topic<T> getTopic(String name, Serializer serializer);
+}
diff --git a/core/api/src/main/java/org/onosproject/store/service/StorageService.java b/core/api/src/main/java/org/onosproject/store/service/StorageService.java
index d863983..94843fc 100644
--- a/core/api/src/main/java/org/onosproject/store/service/StorageService.java
+++ b/core/api/src/main/java/org/onosproject/store/service/StorageService.java
@@ -23,195 +23,5 @@
* It is expected that services and applications will leverage the primitives indirectly provided by
* this service for their distributed state management and coordination.
*/
-public interface StorageService {
-
- /**
- * Creates a new EventuallyConsistentMapBuilder.
- *
- * @param <K> key type
- * @param <V> value type
- * @return builder for an eventually consistent map
- */
- <K, V> EventuallyConsistentMapBuilder<K, V> eventuallyConsistentMapBuilder();
-
- /**
- * Creates a new ConsistentMapBuilder.
- *
- * @param <K> key type
- * @param <V> value type
- * @return builder for a consistent map
- */
- <K, V> ConsistentMapBuilder<K, V> consistentMapBuilder();
-
- /**
- * Creates a new ConsistentMapBuilder.
- *
- * @param <V> value type
- * @return builder for a consistent map
- */
- <V> DocumentTreeBuilder<V> documentTreeBuilder();
-
- /**
- * Creates a new {@code AsyncConsistentTreeMapBuilder}.
- *
- * @param <V> value type
- * @return builder for a async consistent tree map
- */
- <V> ConsistentTreeMapBuilder<V> consistentTreeMapBuilder();
-
- /**
- * Creates a new {@code AsyncConsistentSetMultimapBuilder}.
- *
- * @param <K> key type
- * @param <V> value type
- * @return builder for a set based async consistent multimap
- */
- <K, V> ConsistentMultimapBuilder<K, V> consistentMultimapBuilder();
-
- /**
- * Creates a new {@code AtomicCounterMapBuilder}.
- *
- * @param <K> key type
- * @return builder for an atomic counter map
- */
- <K> AtomicCounterMapBuilder<K> atomicCounterMapBuilder();
-
- /**
- * Creates a new DistributedSetBuilder.
- *
- * @param <E> set element type
- * @return builder for an distributed set
- */
- <E> DistributedSetBuilder<E> setBuilder();
-
- /**
- * Creates a new AtomicCounterBuilder.
- *
- * @return atomic counter builder
- */
- AtomicCounterBuilder atomicCounterBuilder();
-
- /**
- * Creates a new AtomicIdGeneratorBuilder.
- *
- * @return atomic ID generator builder
- */
- AtomicIdGeneratorBuilder atomicIdGeneratorBuilder();
-
- /**
- * Creates a new AtomicValueBuilder.
- *
- * @param <V> atomic value type
- * @return atomic value builder
- */
- <V> AtomicValueBuilder<V> atomicValueBuilder();
-
- /**
- * Creates a new LeaderElectorBuilder.
- *
- * @return leader elector builder
- */
- LeaderElectorBuilder leaderElectorBuilder();
-
- /**
- * Creates a new transaction context builder.
- *
- * @return a builder for a transaction context.
- */
- TransactionContextBuilder transactionContextBuilder();
-
- /**
- * Returns an instance of {@code AsyncAtomicCounter} with specified name.
- * @param name counter name
- *
- * @return AsyncAtomicCounter instance
- */
- default AsyncAtomicCounter getAsyncAtomicCounter(String name) {
- return atomicCounterBuilder().withName(name).build();
- }
-
- /**
- * Returns an instance of {@code AsyncAtomicIdGenerator} with specified name.
- *
- * @param name ID generator name
- * @return AsyncAtomicIdGenerator instance
- */
- default AsyncAtomicIdGenerator getAsyncAtomicIdGenerator(String name) {
- return atomicIdGeneratorBuilder().withName(name).build();
- }
-
- /**
- * Returns an instance of {@code AtomicCounter} with specified name.
- * @param name counter name
- *
- * @return AtomicCounter instance
- */
- default AtomicCounter getAtomicCounter(String name) {
- return getAsyncAtomicCounter(name).asAtomicCounter();
- }
-
- /**
- * Returns an instance of {@code AtomicIdGenerator} with specified name.
- *
- * @param name ID generator name
- * @return AtomicIdGenerator instance
- */
- default AtomicIdGenerator getAtomicIdGenerator(String name) {
- return getAsyncAtomicIdGenerator(name).asAtomicIdGenerator();
- }
-
- /**
- * Returns an instance of {@code WorkQueue} with specified name.
- *
- * @param <E> work element type
- * @param name work queue name
- * @param serializer serializer
- * @return WorkQueue instance
- */
- <E> WorkQueue<E> getWorkQueue(String name, Serializer serializer);
-
- /**
- * Returns an instance of {@code AsyncDocumentTree} with specified name.
- *
- * @param <V> tree node value type
- * @param name document tree name
- * @param serializer serializer
- * @return AsyncDocumentTree instance
- */
- <V> AsyncDocumentTree<V> getDocumentTree(String name, Serializer serializer);
-
- /** Returns a set backed instance of {@code AsyncConsistentMultimap} with
- * the specified name.
- *
- * @param name the multimap name
- * @param serializer serializer
- * @param <K> key type
- * @param <V> value type
- * @return set backed {@code AsyncConsistentMultimap} instance
- */
- <K, V> AsyncConsistentMultimap<K, V> getAsyncSetMultimap(String name,
- Serializer serializer);
-
- /**
- * Returns an instance of {@code AsyncConsistentTreeMap} with the specified
- * name.
- *
- * @param name the treemap name
- * @param serializer serializer
- * @param <V> value type
- * @return set backed {@code AsyncConsistentTreeMap} instance
- */
- <V> AsyncConsistentTreeMap<V> getAsyncTreeMap(String name,
- Serializer serializer);
-
- /**
- * Returns an instance of {@code Topic} with specified name.
- *
- * @param <T> topic message type
- * @param name topic name
- * @param serializer serializer
- *
- * @return Topic instance
- */
- <T> Topic<T> getTopic(String name, Serializer serializer);
+public interface StorageService extends PrimitiveService {
}
diff --git a/core/api/src/main/java/org/onosproject/upgrade/Upgrade.java b/core/api/src/main/java/org/onosproject/upgrade/Upgrade.java
new file mode 100644
index 0000000..79fa7ba
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/upgrade/Upgrade.java
@@ -0,0 +1,165 @@
+/*
+ * 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.upgrade;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.core.Version;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Represents the state of an upgrade.
+ * <p>
+ * An upgrade consists of a {@link #source() source} and {@link #target() target} version and an upgrade
+ * {@link #status()}.
+ */
+@Beta
+public class Upgrade {
+
+ /**
+ * Represents the phase of the upgrade protocol.
+ */
+ @Beta
+ public enum Status {
+
+ /**
+ * Represents state in which no upgrade has been initialized.
+ */
+ INACTIVE(false, false),
+
+ /**
+ * Indicates that an upgrade is being initialized.
+ */
+ INITIALIZING(true, false),
+
+ /**
+ * Indicates that an upgrade has been initialized.
+ */
+ INITIALIZED(true, false),
+
+ /**
+ * Indicates that an upgrade is in progress.
+ */
+ UPGRADING(true, true),
+
+ /**
+ * Indicates that an upgrade is complete.
+ */
+ UPGRADED(true, true),
+
+ /**d
+ * Indicates that an upgrade is being committed.
+ */
+ COMMITTING(true, true),
+
+ /**
+ * Indicates that an upgrade has been committed.
+ */
+ COMMITTED(false, true),
+
+ /**
+ * Indicates that an upgrade is being rolled back.
+ */
+ ROLLING_BACK(true, false),
+
+ /**
+ * Indicates that an upgrade has been rolled back.
+ */
+ ROLLED_BACK(true, false),
+
+ /**
+ * Indicates that an upgrade is being reset.
+ */
+ RESETTING(true, false),
+
+ /**
+ * Indicates that an upgrade has been reset.
+ */
+ RESET(false, false);
+
+ private final boolean active;
+ private final boolean upgraded;
+
+ Status(boolean active, boolean upgraded) {
+ this.active = active;
+ this.upgraded = upgraded;
+ }
+
+ /**
+ * Returns whether the upgrade status is active.
+ *
+ * @return whether the upgrade status is active
+ */
+ public boolean active() {
+ return active;
+ }
+
+ /**
+ * Returns whether the upgraded version is active.
+ *
+ * @return whether the upgraded version is active
+ */
+ public boolean upgraded() {
+ return upgraded;
+ }
+ }
+
+ private final Version source;
+ private final Version target;
+ private final Status status;
+
+ public Upgrade(Version source, Version target, Status status) {
+ this.source = source;
+ this.target = target;
+ this.status = status;
+ }
+
+ /**
+ * Returns the source version.
+ *
+ * @return the source version
+ */
+ public Version source() {
+ return source;
+ }
+
+ /**
+ * Returns the target version.
+ *
+ * @return the target version
+ */
+ public Version target() {
+ return target;
+ }
+
+ /**
+ * Returns the upgrade status.
+ *
+ * @return the upgrade status
+ */
+ public Status status() {
+ return status;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("source", source)
+ .add("target", target)
+ .add("status", status)
+ .toString();
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/upgrade/UpgradeAdminService.java b/core/api/src/main/java/org/onosproject/upgrade/UpgradeAdminService.java
new file mode 100644
index 0000000..38c1bb1
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/upgrade/UpgradeAdminService.java
@@ -0,0 +1,84 @@
+/*
+ * 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.upgrade;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Abstraction for executing the stages of the upgrade process.
+ * <p>
+ * Upgrades are performed in three phases:
+ * <ul>
+ * <li>{@code initialize} - Initializes an upgrade</li>
+ * <li>{@code upgrade} - Performs an upgrade, transferring device mastership from the current version to the
+ * upgraded version</li>
+ * <li>{@code commit} or {@code rollback} - Completes or rolls back an upgrade, transferring mastership back
+ * to nodes running the previous version</li>
+ * </ul>
+ */
+@Beta
+public interface UpgradeAdminService {
+
+ /**
+ * Initializes an upgrade.
+ * <p>
+ * This method must be called to initialize an upgrade and prior to physically upgrading any nodes.
+ *
+ * @throws IllegalStateException if an upgrade is already in progress
+ */
+ void initialize();
+
+ /**
+ * Performs an upgrade, transferring device mastership to upgraded nodes.
+ * <p>
+ * This method transfers mastership from the current version of the software to the upgraded version. Thus,
+ * a subset of the nodes in the cluster must have been physically upgraded and restarted prior to executing this
+ * phase of the upgrade protocol.
+ *
+ * @throws IllegalStateException if no upgrade has been initialized
+ */
+ void upgrade();
+
+ /**
+ * Commits an upgrade.
+ * <p>
+ * Completes the upgrade process, committing the new cluster version.
+ *
+ * @throws IllegalStateException if no upgrade is in progress or not all nodes have been upgraded
+ */
+ void commit();
+
+ /**
+ * Rolls back an upgrade.
+ * <p>
+ * When an upgrade is rolled back, mastership is transferred from upgraded nodes back to nodes running the
+ * version of the software prior to the upgrade.
+ *
+ * @throws IllegalStateException if no upgrade is in progress
+ */
+ void rollback();
+
+ /**
+ * Resets an upgrade.
+ * <p>
+ * When an upgrade is rolled back, once nodes have been restored to the previos version the upgrade must be reset
+ * to restore the upgrade state to {@link Upgrade.Status#INACTIVE}.
+ *
+ * @throws IllegalStateException if nodes have not been restored to the previous state
+ */
+ void reset();
+
+}
diff --git a/core/api/src/main/java/org/onosproject/upgrade/UpgradeEvent.java b/core/api/src/main/java/org/onosproject/upgrade/UpgradeEvent.java
new file mode 100644
index 0000000..43cf523
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/upgrade/UpgradeEvent.java
@@ -0,0 +1,112 @@
+/*
+ * 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.upgrade;
+
+import java.util.Objects;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects;
+import org.onosproject.event.AbstractEvent;
+
+/**
+ * Upgrade event.
+ */
+@Beta
+public class UpgradeEvent extends AbstractEvent<UpgradeEvent.Type, Upgrade> {
+
+ /**
+ * Type of upgrade-related events.
+ */
+ @Beta
+ public enum Type {
+
+ /**
+ * Indicates that a new upgrade was initialized.
+ */
+ INITIALIZED,
+
+ /**
+ * Indicates that mastership was reassigned to the upgraded cluster.
+ */
+ UPGRADED,
+
+ /**
+ * Indicates that an upgrade was committed.
+ */
+ COMMITTED,
+
+ /**
+ * Indicates that an upgrade was rolled back.
+ */
+ ROLLED_BACK,
+
+ /**
+ * Indicates that an upgrade was reset.
+ */
+ RESET,
+ }
+
+ /**
+ * Creates an event of a given type and for the specified state and the
+ * current time.
+ *
+ * @param type upgrade event type
+ * @param state upgrade state
+ */
+ public UpgradeEvent(UpgradeEvent.Type type, Upgrade state) {
+ super(type, state);
+ }
+
+ /**
+ * Creates an event of a given type and for the specified state and time.
+ *
+ * @param type upgrade event type
+ * @param state upgrade state
+ * @param time occurrence time
+ */
+ public UpgradeEvent(UpgradeEvent.Type type, Upgrade state, long time) {
+ super(type, state, time);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type(), subject(), time());
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof UpgradeEvent) {
+ final UpgradeEvent other = (UpgradeEvent) obj;
+ return Objects.equals(this.type(), other.type()) &&
+ Objects.equals(this.subject(), other.subject()) &&
+ Objects.equals(this.time(), other.time());
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this.getClass())
+ .add("type", type())
+ .add("subject", subject())
+ .add("time", time())
+ .toString();
+ }
+
+}
diff --git a/core/api/src/main/java/org/onosproject/upgrade/UpgradeEventListener.java b/core/api/src/main/java/org/onosproject/upgrade/UpgradeEventListener.java
new file mode 100644
index 0000000..876d35a
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/upgrade/UpgradeEventListener.java
@@ -0,0 +1,26 @@
+/*
+ * 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.upgrade;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.event.EventListener;
+
+/**
+ * Upgrade event listener.
+ */
+@Beta
+public interface UpgradeEventListener extends EventListener<UpgradeEvent> {
+}
diff --git a/core/api/src/main/java/org/onosproject/upgrade/UpgradeService.java b/core/api/src/main/java/org/onosproject/upgrade/UpgradeService.java
new file mode 100644
index 0000000..ba5889c
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/upgrade/UpgradeService.java
@@ -0,0 +1,74 @@
+/*
+ * 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.upgrade;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.core.Version;
+import org.onosproject.event.ListenerService;
+
+/**
+ * Upgrade service.
+ */
+@Beta
+public interface UpgradeService
+ extends ListenerService<UpgradeEvent, UpgradeEventListener> {
+
+ /**
+ * Returns whether an upgrade is in progress.
+ * <p>
+ * An upgrade is in progress if the upgrade {@link Upgrade.Status} is active, e.g.
+ * {@link Upgrade.Status#INITIALIZED}, {@link Upgrade.Status#UPGRADED}, etc.
+ *
+ * @return indicates whether an upgrade is in progress
+ */
+ boolean isUpgrading();
+
+ /**
+ * Returns the current upgrade state.
+ *
+ * @return the current upgrade state
+ */
+ Upgrade getState();
+
+ /**
+ * Returns the currently active software version.
+ * <p>
+ * The returned version is representative of the version currently in control of the network. When the upgrade
+ * transitions to the {@link Upgrade.Status#UPGRADING} state, control over the network is transferred from
+ * {@link Upgrade#source()} nodes to {@link Upgrade#target()} nodes, and the version returned by this method
+ * represents that change.
+ *
+ * @return the software version
+ */
+ Version getVersion();
+
+ /**
+ * Returns whether the local node is active.
+ * <p>
+ * The local node will be active if its {@link Version} matches the version returned by {@link #getVersion()}.
+ *
+ * @return indicates whether the local node is active according to its version
+ */
+ boolean isLocalActive();
+
+ /**
+ * Returns whether the local node is an upgraded node.
+ *
+ * @return {@code true} if the local node's version matches {@link Upgrade#target()}
+ */
+ boolean isLocalUpgraded();
+
+}
diff --git a/core/api/src/main/java/org/onosproject/upgrade/package-info.java b/core/api/src/main/java/org/onosproject/upgrade/package-info.java
new file mode 100644
index 0000000..5f19a54
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/upgrade/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Abstractions for managing software upgrades.
+ */
+package org.onosproject.upgrade;
diff --git a/core/api/src/test/java/org/onosproject/cluster/UnifiedClusterServiceAdapter.java b/core/api/src/test/java/org/onosproject/cluster/UnifiedClusterServiceAdapter.java
new file mode 100644
index 0000000..aca74ec
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/cluster/UnifiedClusterServiceAdapter.java
@@ -0,0 +1,66 @@
+/*
+ * 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;
+
+/**
+ * Compatible cluster service adapter.
+ */
+public class UnifiedClusterServiceAdapter implements UnifiedClusterService {
+ @Override
+ public ControllerNode getLocalNode() {
+ return null;
+ }
+
+ @Override
+ public Set<ControllerNode> getNodes() {
+ return null;
+ }
+
+ @Override
+ public ControllerNode getNode(NodeId nodeId) {
+ return null;
+ }
+
+ @Override
+ public ControllerNode.State getState(NodeId nodeId) {
+ return null;
+ }
+
+ @Override
+ public Version getVersion(NodeId nodeId) {
+ return null;
+ }
+
+ @Override
+ public DateTime getLastUpdated(NodeId nodeId) {
+ return null;
+ }
+
+ @Override
+ public void addListener(ClusterEventListener listener) {
+
+ }
+
+ @Override
+ public void removeListener(ClusterEventListener listener) {
+
+ }
+}
diff --git a/core/api/src/test/java/org/onosproject/store/service/AsyncAtomicValueAdapter.java b/core/api/src/test/java/org/onosproject/store/service/AsyncAtomicValueAdapter.java
new file mode 100644
index 0000000..0aefe8c
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/store/service/AsyncAtomicValueAdapter.java
@@ -0,0 +1,58 @@
+/*
+ * 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.store.service;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * Async atomic value adapter.
+ */
+public class AsyncAtomicValueAdapter<V> implements AsyncAtomicValue<V> {
+ @Override
+ public String name() {
+ return null;
+ }
+
+ @Override
+ public CompletableFuture<Boolean> compareAndSet(V expect, V update) {
+ return null;
+ }
+
+ @Override
+ public CompletableFuture<V> get() {
+ return null;
+ }
+
+ @Override
+ public CompletableFuture<V> getAndSet(V value) {
+ return null;
+ }
+
+ @Override
+ public CompletableFuture<Void> set(V value) {
+ return null;
+ }
+
+ @Override
+ public CompletableFuture<Void> addListener(AtomicValueEventListener<V> listener) {
+ return null;
+ }
+
+ @Override
+ public CompletableFuture<Void> removeListener(AtomicValueEventListener<V> listener) {
+ return null;
+ }
+}
diff --git a/core/api/src/test/java/org/onosproject/store/service/AtomicValueAdapter.java b/core/api/src/test/java/org/onosproject/store/service/AtomicValueAdapter.java
new file mode 100644
index 0000000..e6a4e2f
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/store/service/AtomicValueAdapter.java
@@ -0,0 +1,71 @@
+/*
+ * 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.store.service;
+
+/**
+ * Atomic value adapter.
+ */
+public class AtomicValueAdapter<V> implements AtomicValue<V> {
+ private final String name;
+
+ public AtomicValueAdapter() {
+ this(null);
+ }
+
+ public AtomicValueAdapter(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String name() {
+ return null;
+ }
+
+ @Override
+ public Type primitiveType() {
+ return null;
+ }
+
+ @Override
+ public boolean compareAndSet(V expect, V update) {
+ return false;
+ }
+
+ @Override
+ public V get() {
+ return null;
+ }
+
+ @Override
+ public V getAndSet(V value) {
+ return null;
+ }
+
+ @Override
+ public void set(V value) {
+
+ }
+
+ @Override
+ public void addListener(AtomicValueEventListener<V> listener) {
+
+ }
+
+ @Override
+ public void removeListener(AtomicValueEventListener<V> listener) {
+
+ }
+}
diff --git a/core/api/src/test/java/org/onosproject/store/service/CoordinationServiceAdapter.java b/core/api/src/test/java/org/onosproject/store/service/CoordinationServiceAdapter.java
new file mode 100644
index 0000000..f05d9aa
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/store/service/CoordinationServiceAdapter.java
@@ -0,0 +1,106 @@
+/*
+ * 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.store.service;
+
+/**
+ * Coordination service adapter.
+ */
+public class CoordinationServiceAdapter implements CoordinationService {
+ @Override
+ public <K, V> EventuallyConsistentMapBuilder<K, V> eventuallyConsistentMapBuilder() {
+ return null;
+ }
+
+ @Override
+ public <K, V> ConsistentMapBuilder<K, V> consistentMapBuilder() {
+ return null;
+ }
+
+ @Override
+ public <V> DocumentTreeBuilder<V> documentTreeBuilder() {
+ return null;
+ }
+
+ @Override
+ public <V> ConsistentTreeMapBuilder<V> consistentTreeMapBuilder() {
+ return null;
+ }
+
+ @Override
+ public <K, V> ConsistentMultimapBuilder<K, V> consistentMultimapBuilder() {
+ return null;
+ }
+
+ @Override
+ public <K> AtomicCounterMapBuilder<K> atomicCounterMapBuilder() {
+ return null;
+ }
+
+ @Override
+ public <E> DistributedSetBuilder<E> setBuilder() {
+ return null;
+ }
+
+ @Override
+ public AtomicCounterBuilder atomicCounterBuilder() {
+ return null;
+ }
+
+ @Override
+ public AtomicIdGeneratorBuilder atomicIdGeneratorBuilder() {
+ return null;
+ }
+
+ @Override
+ public <V> AtomicValueBuilder<V> atomicValueBuilder() {
+ return null;
+ }
+
+ @Override
+ public LeaderElectorBuilder leaderElectorBuilder() {
+ return null;
+ }
+
+ @Override
+ public TransactionContextBuilder transactionContextBuilder() {
+ return null;
+ }
+
+ @Override
+ public <E> WorkQueue<E> getWorkQueue(String name, Serializer serializer) {
+ return null;
+ }
+
+ @Override
+ public <V> AsyncDocumentTree<V> getDocumentTree(String name, Serializer serializer) {
+ return null;
+ }
+
+ @Override
+ public <K, V> AsyncConsistentMultimap<K, V> getAsyncSetMultimap(String name, Serializer serializer) {
+ return null;
+ }
+
+ @Override
+ public <V> AsyncConsistentTreeMap<V> getAsyncTreeMap(String name, Serializer serializer) {
+ return null;
+ }
+
+ @Override
+ public <T> Topic<T> getTopic(String name, Serializer serializer) {
+ return null;
+ }
+}