BUG-2383: make DOMDataBrokers implement DOMDataTreeChangeService 24/16824/6
authorRobert Varga <rovarga@cisco.com>
Thu, 19 Mar 2015 13:16:48 +0000 (14:16 +0100)
committerTony Tkacik <ttkacik@cisco.com>
Thu, 19 Mar 2015 21:17:41 +0000 (22:17 +0100)
With the datastore support in place, we can now expose the optional
functionality. In order to do so compatibly, we introduce an
experimental API to get access to optional backend features.

Change-Id: I22bf68bd95d98d3c53ee7401442e4812d3615334
Signed-off-by: Robert Varga <rovarga@cisco.com>
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerMountPointTest.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataBroker.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataBrokerExtension.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataTreeChangeService.java
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMExtensibleService.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMServiceExtension.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/AbstractDOMDataBroker.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/PingPongDataBroker.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/DOMDataBrokerProxy.java
opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/md/sal/dom/spi/ForwardingDOMDataBroker.java
opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDataBroker.java

index ee9f0063653d98b72fc0e5ee9918f501e4d71d36..1be550f82fc6b9672202c8741fce33ec870e5a1a 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.controller.sal.binding.test.connect.dom;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-
 import com.google.common.base.Optional;
 import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.Futures;
@@ -25,6 +24,7 @@ import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBrokerExtension;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
@@ -213,6 +213,11 @@ public class CrossBrokerMountPointTest {
                 public DOMTransactionChain createTransactionChain(final TransactionChainListener listener) {
                     throw new UnsupportedOperationException();
                 }
+
+                @Override
+                public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
+                    return Collections.emptyMap();
+                }
             }).register();
 
 
index 4632ed8a6f8e6ccaa86896c97f8998353f71bb2a..53b94f109ce28c7dffd6e62ec3ac479a52cdbc25 100644 (file)
@@ -23,7 +23,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
  */
 public interface DOMDataBroker extends
         AsyncDataBroker<YangInstanceIdentifier, NormalizedNode<?, ?>, DOMDataChangeListener>,
-        TransactionChainFactory<YangInstanceIdentifier, NormalizedNode<?, ?>>, BrokerService, DOMService {
+        TransactionChainFactory<YangInstanceIdentifier, NormalizedNode<?, ?>>, BrokerService, DOMExtensibleService<DOMDataBroker, DOMDataBrokerExtension> {
 
     /**
      * {@inheritDoc}
diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataBrokerExtension.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataBrokerExtension.java
new file mode 100644 (file)
index 0000000..abbcc40
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2015 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.md.sal.dom.api;
+
+/**
+ * Type capture of a {@link DOMServiceExtension} applicable to {@link DOMDataBroker}
+ * implementations.
+ */
+public interface DOMDataBrokerExtension extends DOMServiceExtension<DOMDataBroker, DOMDataBrokerExtension> {
+
+}
index e001dbbf1bcac5b68ef80f9286810e1a2d295597..bdd853a1c08a033a6f2768f20b56eca0c2bf9977 100644 (file)
@@ -11,10 +11,10 @@ import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 
 /**
- * A {@link DOMService} which allows users to register for changes to a
+ * A {@link DOMServiceExtension} which allows users to register for changes to a
  * subtree.
  */
-public interface DOMDataTreeChangeService extends DOMService {
+public interface DOMDataTreeChangeService extends DOMDataBrokerExtension {
     /**
      * Registers a {@link DOMDataTreeChangeListener} to receive
      * notifications when data changes under a given path in the conceptual data
diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMExtensibleService.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMExtensibleService.java
new file mode 100644 (file)
index 0000000..2233442
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015 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.md.sal.dom.api;
+
+import com.google.common.annotations.Beta;
+import java.util.Map;
+import javax.annotation.Nonnull;
+
+/**
+ * Marker interface for services which can support {@link DOMServiceExtension}.
+ * Aside for marking these, they also provide runtime query to detect whether
+ * a particular trait is in fact available.
+ *
+ * <T> Base {@link DOMService}
+ * <E> Extension type
+ */
+@Beta
+public interface DOMExtensibleService<T extends DOMExtensibleService<T, E>, E extends DOMServiceExtension<T, E>> extends DOMService {
+    /**
+     * Return a map of currently-supported extensions, along with accessor services
+     * which provide access to the specific functionality bound to this service.
+     *
+     * @return A map of supported functionality.
+     */
+    @Nonnull Map<Class<? extends E>, E> getSupportedExtensions();
+}
diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMServiceExtension.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMServiceExtension.java
new file mode 100644 (file)
index 0000000..552b289
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2015 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.md.sal.dom.api;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Marker interface for services which expose additional functionality on top
+ * of some base {@link DOMService}.
+ */
+@Beta
+public interface DOMServiceExtension<T extends DOMExtensibleService<T, E>, E extends DOMServiceExtension<T, E>> {
+
+}
index b705bd62a1e38ecebe82c76f269bbe79ffd44351..a5034cb03126ceedf1eeb69b4c2e518b3f43c8d1 100644 (file)
@@ -8,6 +8,8 @@
 package org.opendaylight.controller.md.sal.dom.broker.impl;
 
 import static com.google.common.base.Preconditions.checkState;
+import com.google.common.collect.ImmutableMap;
+import java.util.Collections;
 import java.util.EnumMap;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -15,10 +17,15 @@ import java.util.concurrent.atomic.AtomicLong;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBrokerExtension;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeIdentifier;
 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
 import org.opendaylight.controller.sal.core.spi.data.DOMStore;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreTreeChangePublisher;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.slf4j.Logger;
@@ -29,10 +36,33 @@ public abstract class AbstractDOMDataBroker extends AbstractDOMForwardedTransact
 
     private final AtomicLong txNum = new AtomicLong();
     private final AtomicLong chainNum = new AtomicLong();
+    private final Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> extensions;
     private volatile AutoCloseable closeable;
 
     protected AbstractDOMDataBroker(final Map<LogicalDatastoreType, DOMStore> datastores) {
         super(datastores);
+
+        boolean treeChange = true;
+        for (DOMStore ds : datastores.values()) {
+            if (!(ds instanceof DOMStoreTreeChangePublisher)) {
+                treeChange = false;
+                break;
+            }
+        }
+
+        if (treeChange) {
+            extensions = ImmutableMap.<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension>of(DOMDataTreeChangeService.class, new DOMDataTreeChangeService() {
+                @Override
+                public <L extends DOMDataTreeChangeListener> ListenerRegistration<L> registerDataTreeChangeListener(final DOMDataTreeIdentifier treeId, final L listener) {
+                    DOMStore publisher = getTxFactories().get(treeId.getDatastoreType());
+                    checkState(publisher != null, "Requested logical data store is not available.");
+
+                    return ((DOMStoreTreeChangePublisher)publisher).registerTreeChangeListener(treeId.getRootIdentifier(), listener);
+                }
+            });
+        } else {
+            extensions = Collections.emptyMap();
+        }
     }
 
     public void setCloseable(final AutoCloseable closeable) {
@@ -66,6 +96,11 @@ public abstract class AbstractDOMDataBroker extends AbstractDOMForwardedTransact
         return potentialStore.registerChangeListener(path, listener, triggeringScope);
     }
 
+    @Override
+    public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
+        return extensions;
+    }
+
     @Override
     public DOMTransactionChain createTransactionChain(final TransactionChainListener listener) {
         checkNotClosed();
index 715a13677af54e9796dfe076f4d7032cd361bc0a..b5ec58d54add8151632b955b30fe76f42fde894e 100644 (file)
@@ -11,7 +11,11 @@ import com.google.common.base.Preconditions;
 import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeIdentifier;
 import org.opendaylight.controller.md.sal.dom.spi.ForwardingDOMDataBroker;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 
 /**
  * An implementation of a {@link DOMDataBroker}, which forwards most requests to a delegate.
@@ -20,7 +24,7 @@ import org.opendaylight.controller.md.sal.dom.spi.ForwardingDOMDataBroker;
  * guarantee transaction ordering between transactions allocated directly from the broker
  * and its transaction chains.
  */
-public final class PingPongDataBroker extends ForwardingDOMDataBroker implements AutoCloseable {
+public final class PingPongDataBroker extends ForwardingDOMDataBroker implements AutoCloseable, DOMDataTreeChangeService {
     private final DOMDataBroker delegate;
 
     /**
@@ -47,4 +51,13 @@ public final class PingPongDataBroker extends ForwardingDOMDataBroker implements
     public void close() {
         // TODO Auto-generated method stub
     }
+
+    @Override
+    public <L extends DOMDataTreeChangeListener> ListenerRegistration<L> registerDataTreeChangeListener(final DOMDataTreeIdentifier treeId, final L listener) {
+        if (delegate instanceof DOMDataTreeChangeService) {
+            return ((DOMDataTreeChangeService)delegate).registerDataTreeChangeListener(treeId, listener);
+        }
+
+        throw new UnsupportedOperationException("Delegate " + delegate + " does not support required functionality");
+    }
 }
index b539cb948daadda555060379581788c1712bc1bf..4ce53fd26ca809cfea7dadc7739b641cbe8392be 100644 (file)
@@ -1,8 +1,10 @@
 package org.opendaylight.controller.sal.dom.broker.osgi;
 
+import java.util.Map;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBrokerExtension;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
@@ -45,4 +47,8 @@ public class DOMDataBrokerProxy extends AbstractBrokerServiceProxy<DOMDataBroker
         return getDelegate().createTransactionChain(listener);
     }
 
+    @Override
+    public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
+        return getDelegate().getSupportedExtensions();
+    }
 }
index e42cf10f7e7bbc4d25bc9bb90ba4d3ab589798d4..40fb95f50817c162cf5c125b12c483327ce611b0 100644 (file)
@@ -8,10 +8,12 @@
 package org.opendaylight.controller.md.sal.dom.spi;
 
 import com.google.common.collect.ForwardingObject;
+import java.util.Map;
 import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBrokerExtension;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
@@ -54,4 +56,9 @@ public abstract class ForwardingDOMDataBroker extends ForwardingObject implement
     public DOMTransactionChain createTransactionChain(final TransactionChainListener listener) {
         return delegate().createTransactionChain(listener);
     }
+
+    @Override
+    public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
+        return delegate().getSupportedExtensions();
+    }
 }
index 091c6b42e4ace297e808e4986dd75814ef5cec1c..ae9d3888d8f49fcbdcf0273e925d5ddc4adc5d15 100644 (file)
@@ -8,9 +8,12 @@
 
 package org.opendaylight.controller.sal.connect.netconf.sal;
 
+import java.util.Collections;
+import java.util.Map;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBrokerExtension;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
@@ -73,4 +76,9 @@ final class NetconfDeviceDataBroker implements DOMDataBroker {
         throw new UnsupportedOperationException(id + ": Transaction chains not supported for netconf mount point");
     }
 
+    @Override
+    public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
+        return Collections.emptyMap();
+    }
+
 }