*/
public interface DOMDataBroker extends
AsyncDataBroker<YangInstanceIdentifier, NormalizedNode<?, ?>, DOMDataChangeListener>,
- TransactionChainFactory<YangInstanceIdentifier, NormalizedNode<?, ?>>, BrokerService, DOMService {
+ TransactionChainFactory<YangInstanceIdentifier, NormalizedNode<?, ?>>, BrokerService, DOMExtensibleService<DOMDataBroker, DOMDataBrokerExtension> {
/**
* {@inheritDoc}
--- /dev/null
+/*
+ * 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> {
+
+}
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
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+/*
+ * 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>> {
+
+}
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;
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;
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) {
return potentialStore.registerChangeListener(path, listener, triggeringScope);
}
+ @Override
+ public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
+ return extensions;
+ }
+
@Override
public DOMTransactionChain createTransactionChain(final TransactionChainListener listener) {
checkNotClosed();
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.
* 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;
/**
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");
+ }
}
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;
return getDelegate().createTransactionChain(listener);
}
+ @Override
+ public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
+ return getDelegate().getSupportedExtensions();
+ }
}
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;
public DOMTransactionChain createTransactionChain(final TransactionChainListener listener) {
return delegate().createTransactionChain(listener);
}
+
+ @Override
+ public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
+ return delegate().getSupportedExtensions();
+ }
}