Add a basic framework to create DataTreeChangeListeners 77/59177/18
authorDavid Suarez <david.suarez.fuentes@ericsson.com>
Mon, 19 Jun 2017 14:03:27 +0000 (16:03 +0200)
committerVivek Srivastava <vivek.v.srivastava@ericsson.com>
Thu, 21 Sep 2017 14:31:11 +0000 (14:31 +0000)
Add a basic framework to create DataTreeChangeListeners.

Change-Id: Iaf9ddea9bf312ba7659a57f1d63d5d93fa949938
Signed-off-by: David Suarez <david.suarez.fuentes@ericsson.com>
Signed-off-by: David Suarez <david.suarez.fuentes@gmail.com>
mdsalutil/mdsalutil-api/pom.xml
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/listeners/AbstractAsyncDataTreeChangeListener.java [new file with mode: 0644]
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/listeners/AbstractClusteredAsyncDataTreeChangeListener.java [new file with mode: 0644]
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/listeners/AbstractClusteredSyncDataTreeChangeListener.java [new file with mode: 0644]
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/listeners/AbstractSyncDataTreeChangeListener.java [new file with mode: 0644]
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/listeners/DataTreeChangeListenerActions.java [new file with mode: 0644]
mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/listeners/package-info.java [new file with mode: 0644]

index d803e8d19e91e141e532e349853255d80ba1f389..54df5ee6edbf3691a81f0730219e021bb5a1de17 100644 (file)
@@ -6,7 +6,8 @@ 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
 -->
-<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">
+<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>
@@ -24,102 +25,109 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
        build failure. Please do not modify this unless you have a good reason. -->
   <name>ODL :: genius :: ${project.artifactId}</name>
 
-<dependencies>
-  <dependency>
-    <groupId>org.opendaylight.yangtools</groupId>
-    <artifactId>util</artifactId>
-  </dependency>
-  <dependency>
-    <groupId>org.opendaylight.openflowplugin.model</groupId>
-    <artifactId>model-flow-base</artifactId>
-    <version>${openflowplugin.version}</version>
-  </dependency>
-  <dependency>
-    <groupId>org.opendaylight.openflowplugin.model</groupId>
-    <artifactId>model-flow-service</artifactId>
-    <version>${openflowplugin.version}</version>
-  </dependency>
-  <dependency>
-    <groupId>org.opendaylight.controller</groupId>
-    <artifactId>liblldp</artifactId>
-    <version>${liblldp.version}</version>
-  </dependency>
-  <dependency>
-    <groupId>org.opendaylight.controller</groupId>
-    <artifactId>sal-binding-api</artifactId>
-  </dependency>
-  <dependency>
-    <groupId>org.opendaylight.openflowplugin</groupId>
-    <artifactId>openflowplugin-extension-nicira</artifactId>
-    <version>${openflowplugin.version}</version>
-  </dependency>
-  <dependency>
-    <groupId>org.opendaylight.openflowplugin</groupId>
-    <artifactId>openflowjava-extension-nicira</artifactId>
-    <version>${openflowplugin.version}</version>
-  </dependency>
-  <dependency>
-    <groupId>org.opendaylight.ovsdb</groupId>
-    <artifactId>hwvtepsouthbound-api</artifactId>
-    <version>${genius.ovsdb.version}</version>
-  </dependency>
-  <dependency>
-    <groupId>org.opendaylight.ovsdb</groupId>
-    <artifactId>utils.config</artifactId>
-    <version>${genius.ovsdb.version}</version>
-  </dependency>
-  <dependency>
+  <dependencies>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>util</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.openflowplugin.model</groupId>
+      <artifactId>model-flow-base</artifactId>
+      <version>${openflowplugin.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.openflowplugin.model</groupId>
+      <artifactId>model-flow-service</artifactId>
+      <version>${openflowplugin.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>liblldp</artifactId>
+      <version>${liblldp.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal-binding-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.openflowplugin</groupId>
+      <artifactId>openflowplugin-extension-nicira</artifactId>
+      <version>${openflowplugin.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.openflowplugin</groupId>
+      <artifactId>openflowjava-extension-nicira</artifactId>
+      <version>${openflowplugin.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.ovsdb</groupId>
+      <artifactId>hwvtepsouthbound-api</artifactId>
+      <version>${genius.ovsdb.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.ovsdb</groupId>
+      <artifactId>utils.config</artifactId>
+      <version>${genius.ovsdb.version}</version>
+    </dependency>
+    <dependency>
       <groupId>org.opendaylight.infrautils</groupId>
       <artifactId>counters-api</artifactId>
       <version>${genius.infrautils.version}</version>
-  </dependency>
-  <dependency>
+    </dependency>
+    <dependency>
       <groupId>org.opendaylight.infrautils</groupId>
       <artifactId>inject</artifactId>
       <version>${genius.infrautils.version}</version>
-  </dependency>
-  <dependency>
-    <groupId>org.immutables</groupId>
-    <artifactId>value</artifactId>
-  </dependency>
-  <dependency>
-    <groupId>org.osgi</groupId>
-    <artifactId>org.osgi.core</artifactId>
-  </dependency>
+    </dependency>
+    <dependency>
+      <groupId>org.immutables</groupId>
+      <artifactId>value</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.cdi</groupId>
+      <artifactId>pax-cdi-api</artifactId>
+      <optional>true</optional>
+    </dependency>
+
 
   <!-- Dependencies with <scope>test -->
-  <dependency>
-    <groupId>org.opendaylight.yangtools</groupId>
-    <artifactId>testutils</artifactId>
-    <scope>test</scope>
-  </dependency>
-  <dependency>
-    <groupId>org.awaitility</groupId>
-    <artifactId>awaitility</artifactId>
-    <scope>test</scope>
-  </dependency>
-  <dependency>
-    <groupId>org.opendaylight.mdsal</groupId>
-    <artifactId>mdsal-binding-test-utils</artifactId>
-    <scope>test</scope>
-  </dependency>
-  <dependency>
-    <groupId>org.opendaylight.infrautils</groupId>
-    <artifactId>infrautils-testutils</artifactId>
-    <version>${genius.infrautils.version}</version>
-    <scope>test</scope>
-  </dependency>
-  <dependency>
-    <groupId>com.google.truth</groupId>
-    <artifactId>truth</artifactId>
-    <scope>test</scope>
-  </dependency>
-  <dependency>
-    <groupId>com.google.guava</groupId>
-    <artifactId>guava-testlib</artifactId>
-  </dependency>
-</dependencies>
- <build>
+    <dependency>
+      <groupId>org.opendaylight.yangtools</groupId>
+      <artifactId>testutils</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.awaitility</groupId>
+      <artifactId>awaitility</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.mdsal</groupId>
+      <artifactId>mdsal-binding-test-utils</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.infrautils</groupId>
+      <artifactId>infrautils-testutils</artifactId>
+      <version>${genius.infrautils.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.truth</groupId>
+      <artifactId>truth</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava-testlib</artifactId>
+    </dependency>
+  </dependencies>
+
+  <build>
     <plugins>
       <plugin>
         <groupId>org.apache.felix</groupId>
@@ -144,6 +152,17 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
          </execution>
        </executions>
      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
 </project>
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/listeners/AbstractAsyncDataTreeChangeListener.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/listeners/AbstractAsyncDataTreeChangeListener.java
new file mode 100644 (file)
index 0000000..f28ea9d
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017 Ericsson S.A. 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.genius.datastoreutils.listeners;
+
+import java.util.Collection;
+import java.util.concurrent.ExecutorService;
+import javax.inject.Inject;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * Abstract class providing some common functionality to specific listeners.
+ * This listener launches the received notifications in a different thread by
+ * using the queuing functionality of the {@link ExecutorService}.
+ *
+ * @author David Suárez (david.suarez.fuentes@gmail.com)
+ *
+ * @param <T>
+ *            type of the data object the listener is registered to.
+ */
+public abstract class AbstractAsyncDataTreeChangeListener<T extends DataObject>
+        implements DataTreeChangeListenerActions<T>, DataTreeChangeListener<T> {
+    private final ExecutorService executorService;
+
+    @Inject
+    public AbstractAsyncDataTreeChangeListener(ExecutorService executorService) {
+        this.executorService = executorService;
+    }
+
+    @Override
+    public final void onDataTreeChanged(Collection<DataTreeModification<T>> collection) {
+        executorService.submit(() -> DataTreeChangeListenerActions.super.onDataTreeChanged(collection));
+    }
+}
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/listeners/AbstractClusteredAsyncDataTreeChangeListener.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/listeners/AbstractClusteredAsyncDataTreeChangeListener.java
new file mode 100644 (file)
index 0000000..fa9fa8d
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017 Ericsson S.A. 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.genius.datastoreutils.listeners;
+
+import java.util.Collection;
+import java.util.concurrent.ExecutorService;
+import javax.inject.Inject;
+import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * Abstract class providing some common functionality to specific listeners.
+ * This listener launches the received notifications in a different thread by
+ * using the queuing functionality of the {@link ExecutorService}. This listener
+ * should be used in clustered deployments.
+ *
+ * @author David Suárez (david.suarez.fuentes@gmail.com)
+ *
+ * @param <T>
+ *            type of the data object the listener is registered to.
+ */
+public abstract class AbstractClusteredAsyncDataTreeChangeListener<T extends DataObject>
+        implements DataTreeChangeListenerActions<T>, ClusteredDataTreeChangeListener<T> {
+
+    private final ExecutorService executorService;
+
+    @Inject
+    public AbstractClusteredAsyncDataTreeChangeListener(ExecutorService executorService) {
+        this.executorService = executorService;
+    }
+
+    @Override
+    public final void onDataTreeChanged(Collection<DataTreeModification<T>> collection) {
+        executorService.submit(() -> DataTreeChangeListenerActions.super.onDataTreeChanged(collection));
+    }
+}
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/listeners/AbstractClusteredSyncDataTreeChangeListener.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/listeners/AbstractClusteredSyncDataTreeChangeListener.java
new file mode 100644 (file)
index 0000000..aa6a655
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017 Ericsson S.A. 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.genius.datastoreutils.listeners;
+
+import java.util.Collection;
+import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * Abstract class providing some common functionality to specific listeners.
+ * This listener should be used in clustered deployments.
+ *
+ * @author David Suárez (david.suarez.fuentes@gmail.com)
+ *
+ * @param <T>
+ *            type of the data object the listener is registered to.
+ */
+public abstract class AbstractClusteredSyncDataTreeChangeListener<T extends DataObject>
+        implements DataTreeChangeListenerActions<T>, ClusteredDataTreeChangeListener<T> {
+
+    @Override
+    public final void onDataTreeChanged(Collection<DataTreeModification<T>> collection) {
+        DataTreeChangeListenerActions.super.onDataTreeChanged(collection);
+    }
+}
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/listeners/AbstractSyncDataTreeChangeListener.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/listeners/AbstractSyncDataTreeChangeListener.java
new file mode 100644 (file)
index 0000000..e127c9d
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017 Ericsson S.A. 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.genius.datastoreutils.listeners;
+
+import java.util.Collection;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * Abstract class providing some common functionality to specific listeners.
+ *
+ * @author David Suárez (david.suarez.fuentes@gmail.com)
+ *
+ * @param <T>
+ *            type of the data object the listener is registered to.
+ */
+public abstract class AbstractSyncDataTreeChangeListener<T extends DataObject>
+        implements DataTreeChangeListenerActions<T>, DataTreeChangeListener<T> {
+
+    @Override
+    public final void onDataTreeChanged(Collection<DataTreeModification<T>> collection) {
+        DataTreeChangeListenerActions.super.onDataTreeChanged(collection);
+    }
+}
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/listeners/DataTreeChangeListenerActions.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/listeners/DataTreeChangeListenerActions.java
new file mode 100644 (file)
index 0000000..eac2914
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2017 Ericsson, S.A. 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.genius.datastoreutils.listeners;
+
+import java.io.Closeable;
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import javax.inject.Singleton;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * Interface to be implemented by classes interested in receiving notifications
+ * about data tree changes. It implements a default method to handle the data
+ * tree modifications. Those notifications will be forwarded to the appropriate
+ * methods (add, update, remove) depending on their action type. The listeners
+ * implementing this interface will need to be annotated as {@link Singleton}.
+ *
+ * @author David Suárez (david.suarez.fuentes@gmail.com)
+ *
+ * @param <T>
+ *            type of the data object the listener is registered to.
+ */
+public interface DataTreeChangeListenerActions<T extends DataObject> extends Closeable {
+
+    /**
+     * Default method invoked upon data tree change, in turn it calls the
+     * appropriate method (add, update, remove) depending on the type of change.
+     *
+     * @param collection
+     *            collection of changes
+     */
+    default void onDataTreeChanged(@Nonnull Collection<DataTreeModification<T>> collection) {
+        for (final DataTreeModification<T> dataTreeModification : collection) {
+            final DataObjectModification<T> dataObjectModification = dataTreeModification.getRootNode();
+            switch (dataObjectModification.getModificationType()) {
+                case SUBTREE_MODIFIED:
+                    update(dataObjectModification.getDataBefore(), dataObjectModification.getDataAfter());
+                    break;
+                case DELETE:
+                    remove(dataObjectModification.getDataBefore());
+                    break;
+                case WRITE:
+                    if (dataObjectModification.getDataBefore() == null) {
+                        add(dataObjectModification.getDataAfter());
+                    } else {
+                        update(dataObjectModification.getDataBefore(), dataObjectModification.getDataAfter());
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Invoked when new data object added.
+     *
+     * @param newDataObject
+     *            newly added object
+     */
+    void add(@Nonnull T newDataObject);
+
+    /**
+     * Invoked when the data object has been removed.
+     *
+     * @param removedDataObject
+     *            existing object being removed
+     */
+    void remove(@Nonnull T removedDataObject);
+
+    /**
+     * Invoked when there is a change in the data object.
+     *
+     * @param originalDataObject
+     *            existing object being modified
+     * @param updatedDataObject
+     *            modified data object
+     */
+    void update(@Nonnull T originalDataObject, T updatedDataObject);
+}
diff --git a/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/listeners/package-info.java b/mdsalutil/mdsalutil-api/src/main/java/org/opendaylight/genius/datastoreutils/listeners/package-info.java
new file mode 100644 (file)
index 0000000..d7beab5
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2017 Ericsson S.A. 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
+ */
+/**
+ * Incubator package for a listeners framework. This code might be proposed into
+ * upstream projects once merged and proven to be useful here for a while.
+ *
+ * @author David Suárez (david.suarez.fuentes@gmail.com)
+ *
+ */
+package org.opendaylight.genius.datastoreutils.listeners;