BUG-7407: Introduce API to request shard leader movement 40/49840/8
authorRobert Varga <rovarga@cisco.com>
Tue, 27 Dec 2016 16:57:18 +0000 (17:57 +0100)
committerTom Pantelis <tpanteli@brocade.com>
Fri, 10 Feb 2017 12:24:15 +0000 (12:24 +0000)
There are some applications which would really want to control shard
leader location, so their producers talk to the local leader and do
not cross boundaries if not necessary.

Change-Id: I6c789d91b78d42f325890e36725d03892ae4a23f
Signed-off-by: Robert Varga <rovarga@cisco.com>
12 files changed:
features/mdsal/features-mdsal/src/main/features/features.xml
features/mdsal/odl-mdsal-distributed-datastore/pom.xml
opendaylight/md-sal/cds-dom-api/pom.xml [new file with mode: 0644]
opendaylight/md-sal/cds-dom-api/src/main/java/org/opendaylight/controller/cluster/dom/api/CDSDataTreeProducer.java [new file with mode: 0644]
opendaylight/md-sal/cds-dom-api/src/main/java/org/opendaylight/controller/cluster/dom/api/CDSShardAccess.java [new file with mode: 0644]
opendaylight/md-sal/cds-dom-api/src/main/java/org/opendaylight/controller/cluster/dom/api/LeaderLocation.java [new file with mode: 0644]
opendaylight/md-sal/cds-dom-api/src/main/java/org/opendaylight/controller/cluster/dom/api/LeaderLocationListener.java [new file with mode: 0644]
opendaylight/md-sal/cds-dom-api/src/main/java/org/opendaylight/controller/cluster/dom/api/LeaderLocationListenerRegistration.java [new file with mode: 0644]
opendaylight/md-sal/cds-dom-api/src/main/java/org/opendaylight/controller/cluster/dom/api/package-info.java [new file with mode: 0644]
opendaylight/md-sal/mdsal-artifacts/pom.xml
opendaylight/md-sal/pom.xml
opendaylight/md-sal/sal-distributed-datastore/pom.xml

index 1ba88d395bd16d62861e06585ca276daf0ded6b0..6aa7798d80dcf9ac9ba993bd8f76c4760e9619ae 100644 (file)
@@ -87,6 +87,7 @@
         <feature version='${project.version}'>odl-mdsal-clustering-commons</feature>
         <bundle>mvn:org.opendaylight.controller/cds-access-api/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.controller/cds-access-client/{{VERSION}}</bundle>
+        <bundle>mvn:org.opendaylight.controller/cds-dom-api/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.controller/sal-distributed-datastore/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.controller/sal-cluster-admin-api/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.controller/sal-cluster-admin-impl/{{VERSION}}</bundle>
index 9ff7adf0435c3630da96d94c5470720f2ad19507..a78a755c24d0b7649fd35f2299f549bbefc9c6ad 100644 (file)
             <groupId>${project.groupId}</groupId>
             <artifactId>cds-access-client</artifactId>
         </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>cds-dom-api</artifactId>
+        </dependency>
         <dependency>
             <groupId>${project.groupId}</groupId>
             <artifactId>sal-distributed-datastore</artifactId>
@@ -69,4 +73,4 @@
             <artifactId>sal-cluster-admin-impl</artifactId>
         </dependency>
     </dependencies>
-</project>
\ No newline at end of file
+</project>
diff --git a/opendaylight/md-sal/cds-dom-api/pom.xml b/opendaylight/md-sal/cds-dom-api/pom.xml
new file mode 100644 (file)
index 0000000..bcd28a5
--- /dev/null
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.opendaylight.odlparent</groupId>
+        <artifactId>bundle-parent</artifactId>
+        <version>1.8.0-SNAPSHOT</version>
+        <relativePath/>
+    </parent>
+
+    <groupId>org.opendaylight.controller</groupId>
+    <artifactId>cds-dom-api</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>yangtools-artifacts</artifactId>
+                <version>1.1.0-SNAPSHOT</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.opendaylight.mdsal</groupId>
+                <artifactId>mdsal-artifacts</artifactId>
+                <version>2.2.0-SNAPSHOT</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.typesafe.akka</groupId>
+            <artifactId>akka-actor_${scala.version}</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>concepts</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>mdsal-dom-api</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-checkstyle-plugin</artifactId>
+          <configuration>
+            <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.codehaus.mojo</groupId>
+          <artifactId>findbugs-maven-plugin</artifactId>
+          <configuration>
+            <failOnError>true</failOnError>
+          </configuration>
+        </plugin>
+      </plugins>
+    </build>
+
+    <scm>
+        <connection>scm:git:http://git.opendaylight.org/gerrit/controller.git</connection>
+        <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
+        <tag>HEAD</tag>
+        <url>https://wiki.opendaylight.org/view/OpenDaylight_Controller:MD-SAL:Architecture:Clustering</url>
+    </scm>
+</project>
diff --git a/opendaylight/md-sal/cds-dom-api/src/main/java/org/opendaylight/controller/cluster/dom/api/CDSDataTreeProducer.java b/opendaylight/md-sal/cds-dom-api/src/main/java/org/opendaylight/controller/cluster/dom/api/CDSDataTreeProducer.java
new file mode 100644 (file)
index 0000000..0d54235
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.cluster.dom.api;
+
+import com.google.common.annotations.Beta;
+import javax.annotation.Nonnull;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
+
+/**
+ * An extension to {@link DOMDataTreeProducer}, which allows users access
+ * to information about the backing shard.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public interface CDSDataTreeProducer extends DOMDataTreeProducer {
+    /**
+     * Return a {@link CDSShardAccess} handle. This handle will remain valid
+     * as long as this producer is operational. Returned handle can be accessed
+     * independently from this producer and is not subject to the usual access
+     * restrictions imposed on DOMDataTreeProducer state.
+     *
+     * @param subtree One of the subtrees to which are currently under control of this producer
+     * @return A shard access handle.
+     * @throws NullPointerException when subtree is null
+     * @throws IllegalArgumentException if the specified subtree is not controlled by this producer
+     * @throws IllegalStateException if this producer is no longer operational
+     * @throws IllegalThreadStateException if the access rules to this producer
+     *         are violated, for example if this producer is bound and this thread
+     *         is currently not executing from a listener context.
+     */
+    @Nonnull CDSShardAccess getShardAccess(@Nonnull DOMDataTreeIdentifier subtree);
+}
+
diff --git a/opendaylight/md-sal/cds-dom-api/src/main/java/org/opendaylight/controller/cluster/dom/api/CDSShardAccess.java b/opendaylight/md-sal/cds-dom-api/src/main/java/org/opendaylight/controller/cluster/dom/api/CDSShardAccess.java
new file mode 100644 (file)
index 0000000..d08b99a
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.cluster.dom.api;
+
+import com.google.common.annotations.Beta;
+import java.util.concurrent.CompletionStage;
+import javax.annotation.Nonnull;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
+
+/**
+ * Unprivileged access interface to shard information. Provides read-only access to operational details about a CDS
+ * shard.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public interface CDSShardAccess {
+    /**
+     * Return the shard identifier.
+     *
+     * @return Shard identifier.
+     * @throws IllegalStateException if the {@link CDSDataTreeProducer} from which the associated
+     *         {@link CDSDataTreeProducer} is no longer valid.
+     */
+    @Nonnull DOMDataTreeIdentifier getShardIdentifier();
+
+    /**
+     * Return the shard leader location relative to the local node.
+     *
+     * @return Shard leader location.
+     * @throws IllegalStateException if the {@link CDSDataTreeProducer} from which the associated
+     *         {@link CDSDataTreeProducer} is no longer valid.
+     */
+    @Nonnull LeaderLocation getLeaderLocation();
+
+    /**
+     * Request the shard leader to be moved to the local node. The request will be evaluated against shard state and
+     * satisfied if leader movement is possible. If current shard policy or state prevents the movement from happening,
+     * the returned {@link CompletionStage} will report an exception.
+     *
+     * <p>
+     * This is a one-time operation, which does not prevent further movement happening in future. Even if this request
+     * succeeds, there is no guarantee that the leader will remain local in face of failures, shutdown or any future
+     * movement requests from other nodes.
+     *
+     * <p>
+     * Note that due to asynchronous nature of CDS, the leader may no longer be local by the time the returned
+     * {@link CompletionStage} reports success.
+     *
+     * @return A {@link CompletionStage} representing the request.
+     * @throws IllegalStateException if the {@link CDSDataTreeProducer} from which the associated
+     *         {@link CDSDataTreeProducer} is no longer valid.
+     */
+    @Nonnull CompletionStage<Void> makeLeaderLocal();
+
+    /**
+     * Register a listener to shard location changes. Each listener object can be registered at most once.
+     *
+     * @param listener Listener object
+     * @return A {@link LeaderLocationListenerRegistration} for the listener.
+     * @throws IllegalArgumentException if the specified listener is already registered.
+     * @throws IllegalStateException if the {@link CDSDataTreeProducer} from which the associated
+     *         {@link CDSDataTreeProducer} is no longer valid.
+     * @throws NullPointerException if listener is null.
+     */
+    @Nonnull <L extends LeaderLocationListener> LeaderLocationListenerRegistration<L> registerLeaderLocationListener(
+            @Nonnull L listener);
+}
diff --git a/opendaylight/md-sal/cds-dom-api/src/main/java/org/opendaylight/controller/cluster/dom/api/LeaderLocation.java b/opendaylight/md-sal/cds-dom-api/src/main/java/org/opendaylight/controller/cluster/dom/api/LeaderLocation.java
new file mode 100644 (file)
index 0000000..696fec2
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.cluster.dom.api;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Enumeration of possible shard leader locations relative to the local node.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public enum LeaderLocation {
+    /**
+     * The leader is co-located on this node.
+     */
+    LOCAL,
+    /**
+     * The leader is resident on a different node.
+     */
+    REMOTE,
+    /**
+     * The leader is residence is currently unknown. This is a transition state during a leader failure, which can be
+     * caused by a network partition. This state is not observed during a leadership transfer vote initiated by
+     * the leader shutting down.
+     */
+    UNKNOWN,
+}
diff --git a/opendaylight/md-sal/cds-dom-api/src/main/java/org/opendaylight/controller/cluster/dom/api/LeaderLocationListener.java b/opendaylight/md-sal/cds-dom-api/src/main/java/org/opendaylight/controller/cluster/dom/api/LeaderLocationListener.java
new file mode 100644 (file)
index 0000000..489539a
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.cluster.dom.api;
+
+import com.google.common.annotations.Beta;
+import java.util.EventListener;
+import javax.annotation.Nonnull;
+
+/**
+ * Listener for shard leader location changes.
+ *
+ * @author Robert Varga
+ */
+@Beta
+public interface LeaderLocationListener extends EventListener {
+    /**
+     * Invoked when shard leader location changes.
+     *
+     * @param location Current leader location as known by the local node.
+     */
+    void onLeaderLocationChanged(@Nonnull LeaderLocation location);
+}
diff --git a/opendaylight/md-sal/cds-dom-api/src/main/java/org/opendaylight/controller/cluster/dom/api/LeaderLocationListenerRegistration.java b/opendaylight/md-sal/cds-dom-api/src/main/java/org/opendaylight/controller/cluster/dom/api/LeaderLocationListenerRegistration.java
new file mode 100644 (file)
index 0000000..61f6426
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.cluster.dom.api;
+
+import com.google.common.annotations.Beta;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+
+/**
+ * Registration of a {@link LeaderLocationListener}.
+ *
+ * @author Robert Varga
+ *
+ * @param <T> Listener type
+ */
+@Beta
+public interface LeaderLocationListenerRegistration<T extends LeaderLocationListener> extends ListenerRegistration<T> {
+
+}
diff --git a/opendaylight/md-sal/cds-dom-api/src/main/java/org/opendaylight/controller/cluster/dom/api/package-info.java b/opendaylight/md-sal/cds-dom-api/src/main/java/org/opendaylight/controller/cluster/dom/api/package-info.java
new file mode 100644 (file)
index 0000000..5c65801
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+/**
+ * This package defines extensions to org.opendaylight.mdsal.dom.api specific
+ * to Clustered Datastore implementation.
+ */
+package org.opendaylight.controller.cluster.dom.api;
index a2b6a9c89fc8a34aebef19ec9375e8d145e42954..b7ce936dd3efbc96a90141b259762063d2874734 100644 (file)
                 <artifactId>sal-cluster-admin-impl</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.opendaylight.controller</groupId>
+                <artifactId>cds-dom-api</artifactId>
+                <version>1.1.0-SNAPSHOT</version>
+            </dependency>
 
             <!-- RESTCONF -->
             <dependency>
index dc504ad720c105857b44f4ec38b6e616112ddaff..865675258f42d3390b88c25bcbaf7f6ac13cc5eb 100644 (file)
@@ -80,6 +80,7 @@
     <module>sal-clustering-commons</module>
     <module>cds-access-api</module>
     <module>cds-access-client</module>
+    <module>cds-dom-api</module>
 
     <!-- sal clustering configuration -->
     <module>sal-clustering-config</module>
index e8c927f3fd5dd30c8f84ad4cb6ba8c66dc9825d8..b0e92c87f192f4e5d1d4321ab59eabb0ff3aa825 100644 (file)
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>cds-access-client</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>cds-dom-api</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-akka-raft-example</artifactId>