Bug 7469: Advertise CDS DOMDataTreeCommitCohortRegistry 90/50090/1
authorTom Pantelis <tpanteli@brocade.com>
Fri, 6 Jan 2017 15:59:06 +0000 (10:59 -0500)
committerTom Pantelis <tpanteli@brocade.com>
Fri, 6 Jan 2017 15:59:06 +0000 (10:59 -0500)
Advertised the CDS DOMDataTreeCommitCohortRegistry implementation
via the DOMDataBrokerExtension mechanism.

I needed to add a DOMDataTreeCommitCohortRegistry interface version
in the controller DOM API package that extends the controller
DOMDataBrokerExtension since the mdsal DOMDataTreeCommitCohortRegistry
version extends the mdsal DOMDataBrokerExtension.

Change-Id: I71daac1cd7c231d071c376206d85786c333bac68
Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/AbstractDOMBroker.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/databroker/ConcurrentDOMDataBroker.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/databroker/ConcurrentDOMDataBrokerTest.java
opendaylight/md-sal/sal-dom-api/pom.xml
opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataTreeCommitCohortRegistry.java [new file with mode: 0644]

index d17de22..103f7a6 100644 (file)
@@ -11,7 +11,7 @@ package org.opendaylight.controller.cluster.databroker;
 import static com.google.common.base.Preconditions.checkState;
 
 import com.google.common.collect.ImmutableMap;
-import java.util.Collections;
+import com.google.common.collect.ImmutableMap.Builder;
 import java.util.EnumMap;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicLong;
@@ -22,11 +22,14 @@ 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.DOMDataTreeCommitCohortRegistry;
 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.mdsal.dom.api.DOMDataTreeCommitCohort;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistration;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.slf4j.Logger;
@@ -45,29 +48,60 @@ abstract class AbstractDOMBroker extends AbstractDOMTransactionFactory<DOMStore>
     protected AbstractDOMBroker(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.of(DOMDataTreeChangeService.class, new DOMDataTreeChangeService() {
+        Builder<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> extBuilder = ImmutableMap.builder();
+        if (isSupported(datastores, DOMStoreTreeChangePublisher.class)) {
+            extBuilder.put(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.");
+                    DOMStore store = getTxFactories().get(treeId.getDatastoreType());
+                    checkState(store != null, "Requested logical data store is not available.");
 
-                    return ((DOMStoreTreeChangePublisher) publisher).registerTreeChangeListener(
+                    return ((DOMStoreTreeChangePublisher) store).registerTreeChangeListener(
                             treeId.getRootIdentifier(), listener);
                 }
             });
-        } else {
-            extensions = Collections.emptyMap();
         }
+
+        if (isSupported(datastores, org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistry.class)) {
+            extBuilder.put(DOMDataTreeCommitCohortRegistry.class, new DOMDataTreeCommitCohortRegistry() {
+                @Override
+                public <T extends DOMDataTreeCommitCohort> DOMDataTreeCommitCohortRegistration<T> registerCommitCohort(
+                        org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier path, T cohort) {
+                    DOMStore store = getTxFactories().get(toLegacy(path.getDatastoreType()));
+                    checkState(store != null, "Requested logical data store is not available.");
+
+                    return ((org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistry) store)
+                            .registerCommitCohort(path, cohort);
+                }
+            });
+        }
+
+        extensions = extBuilder.build();
+    }
+
+    private static LogicalDatastoreType toLegacy(org.opendaylight.mdsal.common.api.LogicalDatastoreType datastoreType) {
+        switch (datastoreType) {
+            case CONFIGURATION:
+                return LogicalDatastoreType.CONFIGURATION;
+            case OPERATIONAL:
+                return LogicalDatastoreType.OPERATIONAL;
+            default:
+                throw new IllegalArgumentException("Unsupported data store type: " + datastoreType);
+        }
+    }
+
+    private boolean isSupported(Map<LogicalDatastoreType, DOMStore> datastores,
+            Class<?> expDOMStoreInterface) {
+        boolean supported = true;
+        for (DOMStore ds : datastores.values()) {
+            if (!expDOMStoreInterface.isAssignableFrom(ds.getClass())) {
+                supported = false;
+                break;
+            }
+        }
+
+        return supported;
     }
 
     public void setCloseable(final AutoCloseable closeable) {
index b978147..1560504 100644 (file)
@@ -30,10 +30,6 @@ import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
 import org.opendaylight.controller.md.sal.dom.broker.impl.TransactionCommitFailedExceptionMapper;
 import org.opendaylight.controller.sal.core.spi.data.DOMStore;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohort;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistration;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistry;
-import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
 import org.opendaylight.yangtools.util.DurationStatisticsTracker;
 import org.opendaylight.yangtools.util.concurrent.MappingCheckedFuture;
 import org.slf4j.Logger;
@@ -47,7 +43,7 @@ import org.slf4j.LoggerFactory;
  * @author Thomas Pantelis
  */
 @Beta
-public class ConcurrentDOMDataBroker extends AbstractDOMBroker implements DOMDataTreeCommitCohortRegistry {
+public class ConcurrentDOMDataBroker extends AbstractDOMBroker {
     private static final Logger LOG = LoggerFactory.getLogger(ConcurrentDOMDataBroker.class);
     private static final String CAN_COMMIT = "CAN_COMMIT";
     private static final String PRE_COMMIT = "PRE_COMMIT";
@@ -335,27 +331,6 @@ public class ConcurrentDOMDataBroker extends AbstractDOMBroker implements DOMDat
         }
     }
 
-    @Override
-    public <T extends DOMDataTreeCommitCohort> DOMDataTreeCommitCohortRegistration<T> registerCommitCohort(
-            DOMDataTreeIdentifier path, T cohort) {
-        DOMStore store = getTxFactories().get(toLegacy(path.getDatastoreType()));
-        if (store instanceof DOMDataTreeCommitCohortRegistry) {
-            return ((DOMDataTreeCommitCohortRegistry) store).registerCommitCohort(path, cohort);
-        }
-        throw new UnsupportedOperationException("Commit cohort is not supported for " + path);
-    }
-
-    private static LogicalDatastoreType toLegacy(org.opendaylight.mdsal.common.api.LogicalDatastoreType datastoreType) {
-        switch (datastoreType) {
-            case CONFIGURATION:
-                return LogicalDatastoreType.CONFIGURATION;
-            case OPERATIONAL:
-                return LogicalDatastoreType.OPERATIONAL;
-            default:
-                throw new IllegalArgumentException("Unsupported data store type: " + datastoreType);
-        }
-    }
-
     @Override
     public String toString() {
         return "Clustered ConcurrentDOMDataBroker";
index d86f358..8aca70d 100644 (file)
@@ -33,6 +33,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.SynchronousQueue;
@@ -45,13 +46,17 @@ import org.junit.Before;
 import org.junit.Test;
 import org.mockito.InOrder;
 import org.mockito.stubbing.Answer;
+import org.opendaylight.controller.cluster.datastore.DistributedDataStore;
 import org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException;
 import org.opendaylight.controller.md.sal.common.api.data.DataStoreUnavailableException;
 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.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBrokerExtension;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeCommitCohortRegistry;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore;
@@ -61,6 +66,8 @@ import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransactio
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohort;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
@@ -570,4 +577,29 @@ public class ConcurrentDOMDataBrokerTest {
         }
     }
 
+    @Test
+    public void testExtensions() {
+        DistributedDataStore mockConfigStore = mock(DistributedDataStore.class);
+        DistributedDataStore mockOperStore = mock(DistributedDataStore.class);
+        try (ConcurrentDOMDataBroker dataBroker = new ConcurrentDOMDataBroker(ImmutableMap.of(
+                LogicalDatastoreType.OPERATIONAL, mockOperStore,
+                LogicalDatastoreType.CONFIGURATION, mockConfigStore), futureExecutor)) {
+
+            Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> supportedExtensions =
+                    dataBroker.getSupportedExtensions();
+            assertNotNull(supportedExtensions.get(DOMDataTreeChangeService.class));
+
+            DOMDataTreeCommitCohortRegistry cohortRegistry =
+                    (DOMDataTreeCommitCohortRegistry) supportedExtensions.get(DOMDataTreeCommitCohortRegistry.class);
+            assertNotNull(cohortRegistry);
+
+            DOMDataTreeCommitCohort mockCohort = mock(DOMDataTreeCommitCohort.class);
+            DOMDataTreeIdentifier path = new DOMDataTreeIdentifier(
+                    org.opendaylight.mdsal.common.api.LogicalDatastoreType.CONFIGURATION,
+                    YangInstanceIdentifier.EMPTY);
+            cohortRegistry.registerCommitCohort(path, mockCohort);
+
+            verify(mockConfigStore).registerCommitCohort(path, mockCohort);
+        }
+    }
 }
index 64c0109..c2e668a 100644 (file)
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-test-model</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.mdsal</groupId>
+      <artifactId>mdsal-dom-api</artifactId>
+    </dependency>
     <dependency>
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>yang-data-impl</artifactId>
diff --git a/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataTreeCommitCohortRegistry.java b/opendaylight/md-sal/sal-dom-api/src/main/java/org/opendaylight/controller/md/sal/dom/api/DOMDataTreeCommitCohortRegistry.java
new file mode 100644 (file)
index 0000000..15795eb
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2017 2015 Brocade Communications 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;
+
+/**
+ * Interface for a DOM commit cohort registry.
+ *
+ * @author Thomas Pantelis
+ */
+public interface DOMDataTreeCommitCohortRegistry extends DOMDataBrokerExtension,
+        org.opendaylight.mdsal.dom.api.DOMDataTreeCommitCohortRegistry {
+}