From c02fd92c1eade50c01333b3f5c6e9f7e2faaafce Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Thu, 19 Mar 2015 14:16:48 +0100 Subject: [PATCH] BUG-2383: make DOMDataBrokers implement DOMDataTreeChangeService 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 --- .../dom/CrossBrokerMountPointTest.java | 7 +++- .../md/sal/dom/api/DOMDataBroker.java | 2 +- .../sal/dom/api/DOMDataBrokerExtension.java | 16 +++++++++ .../sal/dom/api/DOMDataTreeChangeService.java | 4 +-- .../md/sal/dom/api/DOMExtensibleService.java | 31 ++++++++++++++++ .../md/sal/dom/api/DOMServiceExtension.java | 19 ++++++++++ .../broker/impl/AbstractDOMDataBroker.java | 35 +++++++++++++++++++ .../dom/broker/impl/PingPongDataBroker.java | 15 +++++++- .../dom/broker/osgi/DOMDataBrokerProxy.java | 6 ++++ .../sal/dom/spi/ForwardingDOMDataBroker.java | 7 ++++ .../netconf/sal/NetconfDeviceDataBroker.java | 8 +++++ 11 files changed, 145 insertions(+), 5 deletions(-) create mode 100644 opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataBrokerExtension.java create mode 100644 opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMExtensibleService.java create mode 100644 opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMServiceExtension.java diff --git a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerMountPointTest.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerMountPointTest.java index ee9f006365..1be550f82f 100644 --- a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerMountPointTest.java +++ b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/CrossBrokerMountPointTest.java @@ -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, DOMDataBrokerExtension> getSupportedExtensions() { + return Collections.emptyMap(); + } }).register(); diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataBroker.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataBroker.java index 4632ed8a6f..53b94f109c 100644 --- a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataBroker.java +++ b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataBroker.java @@ -23,7 +23,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; */ public interface DOMDataBroker extends AsyncDataBroker, DOMDataChangeListener>, - TransactionChainFactory>, BrokerService, DOMService { + TransactionChainFactory>, BrokerService, DOMExtensibleService { /** * {@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 index 0000000000..abbcc404d9 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataBrokerExtension.java @@ -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 { + +} diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataTreeChangeService.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataTreeChangeService.java index e001dbbf1b..bdd853a1c0 100644 --- a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataTreeChangeService.java +++ b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataTreeChangeService.java @@ -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 index 0000000000..22334420ad --- /dev/null +++ b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMExtensibleService.java @@ -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. + * + * Base {@link DOMService} + * Extension type + */ +@Beta +public interface DOMExtensibleService, E extends DOMServiceExtension> 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, 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 index 0000000000..552b28921f --- /dev/null +++ b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMServiceExtension.java @@ -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, E extends DOMServiceExtension> { + +} diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/AbstractDOMDataBroker.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/AbstractDOMDataBroker.java index b705bd62a1..a5034cb031 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/AbstractDOMDataBroker.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/AbstractDOMDataBroker.java @@ -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, DOMDataBrokerExtension> extensions; private volatile AutoCloseable closeable; protected AbstractDOMDataBroker(final Map datastores) { super(datastores); + + boolean treeChange = true; + for (DOMStore ds : datastores.values()) { + if (!(ds instanceof DOMStoreTreeChangePublisher)) { + treeChange = false; + break; + } + } + + if (treeChange) { + extensions = ImmutableMap., DOMDataBrokerExtension>of(DOMDataTreeChangeService.class, new DOMDataTreeChangeService() { + @Override + public ListenerRegistration 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, DOMDataBrokerExtension> getSupportedExtensions() { + return extensions; + } + @Override public DOMTransactionChain createTransactionChain(final TransactionChainListener listener) { checkNotClosed(); diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/PingPongDataBroker.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/PingPongDataBroker.java index 715a13677a..b5ec58d54a 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/PingPongDataBroker.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/PingPongDataBroker.java @@ -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 ListenerRegistration 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"); + } } diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/DOMDataBrokerProxy.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/DOMDataBrokerProxy.java index b539cb948d..4ce53fd26c 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/DOMDataBrokerProxy.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/osgi/DOMDataBrokerProxy.java @@ -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, DOMDataBrokerExtension> getSupportedExtensions() { + return getDelegate().getSupportedExtensions(); + } } diff --git a/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/md/sal/dom/spi/ForwardingDOMDataBroker.java b/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/md/sal/dom/spi/ForwardingDOMDataBroker.java index e42cf10f7e..40fb95f508 100644 --- a/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/md/sal/dom/spi/ForwardingDOMDataBroker.java +++ b/opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/md/sal/dom/spi/ForwardingDOMDataBroker.java @@ -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, DOMDataBrokerExtension> getSupportedExtensions() { + return delegate().getSupportedExtensions(); + } } diff --git a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDataBroker.java b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDataBroker.java index 091c6b42e4..ae9d3888d8 100644 --- a/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDataBroker.java +++ b/opendaylight/md-sal/sal-netconf-connector/src/main/java/org/opendaylight/controller/sal/connect/netconf/sal/NetconfDeviceDataBroker.java @@ -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, DOMDataBrokerExtension> getSupportedExtensions() { + return Collections.emptyMap(); + } + } -- 2.36.6