Leader elector distributed primitive interfaces
Change-Id: Ieebf5ddfcf8c5c6a55e4d6d328829cc8dbeef38a
diff --git a/core/api/src/main/java/org/onosproject/store/primitives/DistributedPrimitiveCreator.java b/core/api/src/main/java/org/onosproject/store/primitives/DistributedPrimitiveCreator.java
index fd38d24..08c2dbb 100644
--- a/core/api/src/main/java/org/onosproject/store/primitives/DistributedPrimitiveCreator.java
+++ b/core/api/src/main/java/org/onosproject/store/primitives/DistributedPrimitiveCreator.java
@@ -19,6 +19,7 @@
import org.onosproject.store.service.AsyncAtomicValue;
import org.onosproject.store.service.AsyncConsistentMap;
import org.onosproject.store.service.AsyncDistributedSet;
+import org.onosproject.store.service.AsyncLeaderElector;
import org.onosproject.store.service.DistributedQueue;
import org.onosproject.store.service.Serializer;
@@ -75,4 +76,12 @@
* @return set
*/
<E> AsyncDistributedSet<E> newAsyncDistributedSet(String name, Serializer serializer);
+
+ /**
+ * Creates a new {@code AsyncLeaderElector}.
+ *
+ * @param name leader elector name
+ * @return leader elector
+ */
+ AsyncLeaderElector newAsyncLeaderElector(String name);
}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/store/service/AsyncLeaderElector.java b/core/api/src/main/java/org/onosproject/store/service/AsyncLeaderElector.java
new file mode 100644
index 0000000..000d10f
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/store/service/AsyncLeaderElector.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2016 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.store.service;
+
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Consumer;
+
+import org.onosproject.cluster.Leadership;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.event.Change;
+
+/**
+ * Distributed mutual exclusion primitive.
+ * <p>
+ * {@code AsyncLeaderElector} facilitates mutually exclusive access to a shared resource by various cluster members.
+ * Each resource is identified by a unique topic name and members register their desire to access the resource by
+ * calling the {@link AsyncLeaderElector#run run} method. Access is grated on a FIFO basis. An instance can
+ * unregister itself from the leadership election by calling {@link AsyncLeaderElector#withdraw withdraw} method.
+ * If an instance currently holding the resource dies then the next instance waiting to be leader (in FIFO order)
+ * will be automatically granted access to the resource.
+ * <p>
+ * One can register listeners to be notified when a leadership change occurs. The Listeners are notified via a
+ * {@link Leadership} {@link Change change} subject.
+ * <p>
+ * Additionally, {@code AsyncLeaderElector} provides methods to query the current state of leadership for topics.
+ * <p>
+ * All methods of this interface return a {@link CompletableFuture future} immediately after a successful invocation.
+ * The operation itself is executed asynchronous and the returned future will be
+ * {@link CompletableFuture#complete completed} when the operation finishes.
+ */
+public interface AsyncLeaderElector extends DistributedPrimitive {
+
+ @Override
+ default DistributedPrimitive.Type type() {
+ return DistributedPrimitive.Type.LEADER_ELECTOR;
+ }
+
+ /**
+ * Attempts to become leader for a topic.
+ * @param topic leadership topic
+ * @param nodeId instance identifier of the node
+ * @return CompletableFuture that is completed with the current Leadership state of the topic
+ */
+ CompletableFuture<Leadership> run(String topic, NodeId nodeId);
+
+ /**
+ * Withdraws from leadership race for a topic.
+ * @param topic leadership topic
+ * @return CompletableFuture that is completed when the withdraw is done
+ */
+ CompletableFuture<Void> withdraw(String topic);
+
+ /**
+ * Attempts to promote a node to leadership displacing the current leader.
+ * @param topic leadership topic
+ * @param nodeId instance identifier of the new leader
+ * @return CompletableFuture that is completed with a boolean when the operation is done. Boolean is true if
+ * leadership transfer was successfully executed; false if it failed. This operation can fail (i.e. return false)
+ * if the node to be made new leader is not registering to run for election for the topic.
+ */
+ CompletableFuture<Boolean> anoint(String topic, NodeId nodeId);
+
+ /**
+ * Returns the {@link Leadership} for the specified topic.
+ * @param topic leadership topic
+ * @return CompletableFuture that is completed with the current Leadership state of the topic
+ */
+ CompletableFuture<Leadership> getLeadership(String topic);
+
+ /**
+ * Returns the current {@link Leadership}s for all topics.
+ * @return CompletableFuture that is completed with the topic to Leadership mapping
+ */
+ CompletableFuture<Map<String, Leadership>> getLeaderships();
+
+ /**
+ * Registers a listener to be notified of Leadership changes for all topics.
+ * @param consumer listener to notify
+ * @return CompletableFuture that is completed when the operation completes
+ */
+ CompletableFuture<Void> addChangeListener(Consumer<Change<Leadership>> consumer);
+
+ /**
+ * Unregisters a previously registered change notification listener.
+ * <p>
+ * If the specified listener was not previously registered, this operation will be a noop.
+ * @param consumer listener to remove
+ * @return CompletableFuture that is completed when the operation completes
+ */
+ CompletableFuture<Void> removeChangeListener(Consumer<Change<Leadership>> consumer);
+}
diff --git a/core/api/src/main/java/org/onosproject/store/service/LeaderElector.java b/core/api/src/main/java/org/onosproject/store/service/LeaderElector.java
new file mode 100644
index 0000000..b5d1c66
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/store/service/LeaderElector.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2016 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.store.service;
+
+import java.util.Map;
+import java.util.function.Consumer;
+
+import org.onosproject.cluster.Leadership;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.event.Change;
+
+/**
+ * {@code LeaderElector} provides the same functionality as {@link AsyncLeaderElector} with
+ * the only difference that all its methods block until the corresponding operation completes.
+ */
+public interface LeaderElector extends DistributedPrimitive {
+
+ @Override
+ default DistributedPrimitive.Type type() {
+ return DistributedPrimitive.Type.LEADER_ELECTOR;
+ }
+
+ /**
+ * Attempts to become leader for a topic.
+ * @param topic leadership topic
+ * @param nodeId instance identifier of the node
+ * @return current Leadership state of the topic
+ */
+ Leadership run(String topic, NodeId nodeId);
+
+ /**
+ * Withdraws from leadership race for a topic.
+ * @param topic leadership topic
+ */
+ void withdraw(String topic);
+
+ /**
+ * Attempts to promote a node to leadership displacing the current leader.
+ * @param topic leadership topic
+ * @param nodeId instance identifier of the new leader
+ * @return {@code true} if leadership transfer was successfully executed; {@code false} if it failed.
+ * This operation can return {@code false} if the node to be made new leader is not registered to
+ * run for election for the topic.
+ */
+ boolean anoint(String topic, NodeId nodeId);
+
+ /**
+ * Returns the {@link Leadership} for the specified topic.
+ * @param topic leadership topic
+ * @return current Leadership state of the topic
+ */
+ Leadership getLeadership(String topic);
+
+ /**
+ * Returns the current {@link Leadership}s for all topics.
+ * @return topic name to Leadership mapping
+ */
+ Map<String, Leadership> getLeaderships();
+
+ /**
+ * Registers a listener to be notified of Leadership changes for all topics.
+ * @param consumer listener to add
+ */
+ void addChangeListener(Consumer<Change<Leadership>> consumer);
+
+ /**
+ * Unregisters a previously registered change notification listener.
+ * <p>
+ * If the specified listener was not previously registered, this operation will be a noop.
+ * @param consumer listener to remove
+ */
+ void removeChangeListener(Consumer<Change<Leadership>> consumer);
+}