<dependency>
<groupId>org.opendaylight.mdsal</groupId>
<artifactId>mdsal-dom-broker</artifactId>
- <scope>test</scope>
+ <scope>compile</scope>
</dependency>
<dependency>
<groupId>org.opendaylight.mdsal</groupId>
--- /dev/null
+/*
+ * Copyright (c) 2017 Red Hat, 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.mdsal.binding.dom.adapter.test;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.dom.api.DOMDataBroker;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public abstract class AbstractBaseDataBrokerTest extends AbstractSchemaAwareTest {
+
+ private static final int ASSERT_COMMIT_DEFAULT_TIMEOUT = 5000;
+
+ private AbstractDataBrokerTestCustomizer testCustomizer;
+ private DataBroker dataBroker;
+ private DOMDataBroker domBroker;
+
+ protected abstract AbstractDataBrokerTestCustomizer createDataBrokerTestCustomizer();
+
+ public AbstractDataBrokerTestCustomizer getDataBrokerTestCustomizer() {
+ if (testCustomizer == null) {
+ throw new IllegalStateException("testCustomizer not yet set by call to createDataBrokerTestCustomizer()");
+ }
+ return testCustomizer;
+ }
+
+ @Override
+ protected void setupWithSchema(final SchemaContext context) {
+ testCustomizer = createDataBrokerTestCustomizer();
+ dataBroker = testCustomizer.createDataBroker();
+ domBroker = testCustomizer.getDOMDataBroker();
+ testCustomizer.updateSchema(context);
+ }
+
+ public DataBroker getDataBroker() {
+ return dataBroker;
+ }
+
+ public DOMDataBroker getDomBroker() {
+ return domBroker;
+ }
+
+ protected static final void assertCommit(final ListenableFuture<Void> commit) {
+ assertCommit(commit, ASSERT_COMMIT_DEFAULT_TIMEOUT);
+ }
+
+ protected static final void assertCommit(final ListenableFuture<Void> commit, long timeoutInMS) {
+ try {
+ commit.get(timeoutInMS, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Red Hat, 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.mdsal.binding.dom.adapter.test;
+
+/**
+ * Abstract base for DataBroker tests.
+ *
+ * <p>Uses single thread executor for the Serialized DOM DataBroker (instead of the direct executor used by the
+ * AbstractDataBrokerTest) in order to allow tests to use the DataBroker concurrently from several threads.
+ *
+ * @author Michael Vorburger
+ */
+public abstract class AbstractConcurrentDataBrokerTest extends AbstractBaseDataBrokerTest {
+ private final boolean useMTDataTreeChangeListenerExecutor;
+
+ protected AbstractConcurrentDataBrokerTest() {
+ this(false);
+ }
+
+ protected AbstractConcurrentDataBrokerTest(final boolean useMTDataTreeChangeListenerExecutor) {
+ this.useMTDataTreeChangeListenerExecutor = useMTDataTreeChangeListenerExecutor;
+ }
+
+ @Override
+ protected AbstractDataBrokerTestCustomizer createDataBrokerTestCustomizer() {
+ return new ConcurrentDataBrokerTestCustomizer(useMTDataTreeChangeListenerExecutor);
+ }
+}
*/
package org.opendaylight.mdsal.binding.dom.adapter.test;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
import org.opendaylight.mdsal.binding.api.DataBroker;
-import org.opendaylight.mdsal.dom.api.DOMDataBroker;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-public class AbstractDataBrokerTest extends AbstractSchemaAwareTest {
-
- private DataBrokerTestCustomizer testCustomizer;
- private DataBroker dataBroker;
- private DOMDataBroker domBroker;
-
+/**
+ * Abstract base for DataBroker tests. Note that it performs synchronous commits via a direct executor which can cause
+ * issues if used in a concurrent manner so it is recommended to use AbstractConcurrentDataBrokerTest instead.
+ */
+public class AbstractDataBrokerTest extends AbstractBaseDataBrokerTest {
@Override
- protected void setupWithSchema(final SchemaContext context) {
- testCustomizer = createDataBrokerTestCustomizer();
- dataBroker = testCustomizer.createDataBroker();
- domBroker = testCustomizer.createDOMDataBroker();
- testCustomizer.updateSchema(context);
- setupWithDataBroker(dataBroker);
- }
-
- protected void setupWithDataBroker(final DataBroker broker) {
- // Intentionally left No-op, subclasses may customize it
- }
-
- protected DataBrokerTestCustomizer createDataBrokerTestCustomizer() {
+ protected AbstractDataBrokerTestCustomizer createDataBrokerTestCustomizer() {
return new DataBrokerTestCustomizer();
}
- public DataBroker getDataBroker() {
- return dataBroker;
- }
-
- public DOMDataBroker getDomBroker() {
- return domBroker;
+ @Override
+ protected void setupWithSchema(SchemaContext context) {
+ super.setupWithSchema(context);
+ setupWithDataBroker(getDataBroker());
}
- protected static final void assertCommit(final ListenableFuture<Void> commit) {
- try {
- commit.get(500, TimeUnit.MILLISECONDS);
- } catch (InterruptedException | ExecutionException | TimeoutException e) {
- throw new IllegalStateException(e);
- }
+ protected void setupWithDataBroker(final DataBroker dataBroker) {
+ // Intentionally left No-op, subclasses may customize it
}
}
--- /dev/null
+/*
+ * Copyright (c) 2017 Red Hat, 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.mdsal.binding.dom.adapter.test;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import javassist.ClassPool;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.api.NotificationPublishService;
+import org.opendaylight.mdsal.binding.api.NotificationService;
+import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMDataBrokerAdapter;
+import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMNotificationPublishServiceAdapter;
+import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMNotificationServiceAdapter;
+import org.opendaylight.mdsal.binding.dom.adapter.BindingToNormalizedNodeCodec;
+import org.opendaylight.mdsal.binding.dom.adapter.test.util.MockSchemaService;
+import org.opendaylight.mdsal.binding.dom.codec.gen.impl.DataObjectSerializerGenerator;
+import org.opendaylight.mdsal.binding.dom.codec.gen.impl.StreamWriterGenerator;
+import org.opendaylight.mdsal.binding.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.mdsal.binding.generator.impl.GeneratedClassLoadingStrategy;
+import org.opendaylight.mdsal.binding.generator.util.JavassistUtils;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.dom.api.DOMDataBroker;
+import org.opendaylight.mdsal.dom.api.DOMSchemaService;
+import org.opendaylight.mdsal.dom.broker.DOMNotificationRouter;
+import org.opendaylight.mdsal.dom.broker.SerializedDOMDataBroker;
+import org.opendaylight.mdsal.dom.spi.store.DOMStore;
+import org.opendaylight.mdsal.dom.store.inmemory.InMemoryDOMDataStore;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public abstract class AbstractDataBrokerTestCustomizer {
+
+ private DOMDataBroker domDataBroker;
+ private final DOMNotificationRouter domNotificationRouter;
+ private final MockSchemaService schemaService;
+ private ImmutableMap<LogicalDatastoreType, DOMStore> datastores;
+ private final BindingToNormalizedNodeCodec bindingToNormalized;
+
+ public ImmutableMap<LogicalDatastoreType, DOMStore> createDatastores() {
+ return ImmutableMap.<LogicalDatastoreType, DOMStore>builder()
+ .put(LogicalDatastoreType.OPERATIONAL, createOperationalDatastore())
+ .put(LogicalDatastoreType.CONFIGURATION,createConfigurationDatastore())
+ .build();
+ }
+
+ public AbstractDataBrokerTestCustomizer() {
+ this.schemaService = new MockSchemaService();
+ final ClassPool pool = ClassPool.getDefault();
+ final DataObjectSerializerGenerator generator = StreamWriterGenerator.create(JavassistUtils.forClassPool(pool));
+ final BindingNormalizedNodeCodecRegistry codecRegistry = new BindingNormalizedNodeCodecRegistry(generator);
+ final GeneratedClassLoadingStrategy loading = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
+ this.bindingToNormalized = new BindingToNormalizedNodeCodec(loading, codecRegistry);
+ this.schemaService.registerSchemaContextListener(this.bindingToNormalized);
+ this.domNotificationRouter = DOMNotificationRouter.create(16);
+ }
+
+ public DOMStore createConfigurationDatastore() {
+ final InMemoryDOMDataStore store = new InMemoryDOMDataStore("CFG", getDataTreeChangeListenerExecutor());
+ this.schemaService.registerSchemaContextListener(store);
+ return store;
+ }
+
+ public DOMStore createOperationalDatastore() {
+ final InMemoryDOMDataStore store = new InMemoryDOMDataStore("OPER", getDataTreeChangeListenerExecutor());
+ this.schemaService.registerSchemaContextListener(store);
+ return store;
+ }
+
+ public DOMDataBroker createDOMDataBroker() {
+ return new SerializedDOMDataBroker(getDatastores(), getCommitCoordinatorExecutor());
+ }
+
+ public NotificationService createNotificationService() {
+ return new BindingDOMNotificationServiceAdapter(this.domNotificationRouter,
+ this.bindingToNormalized.getCodecRegistry());
+ }
+
+ public NotificationPublishService createNotificationPublishService() {
+ return new BindingDOMNotificationPublishServiceAdapter(this.domNotificationRouter, this.bindingToNormalized);
+ }
+
+ public abstract ListeningExecutorService getCommitCoordinatorExecutor();
+
+ public ListeningExecutorService getDataTreeChangeListenerExecutor() {
+ return MoreExecutors.newDirectExecutorService();
+ }
+
+ public DataBroker createDataBroker() {
+ return new BindingDOMDataBrokerAdapter(getDOMDataBroker(), this.bindingToNormalized);
+ }
+
+ public BindingToNormalizedNodeCodec getBindingToNormalized() {
+ return this.bindingToNormalized;
+ }
+
+ public DOMSchemaService getSchemaService() {
+ return this.schemaService;
+ }
+
+ public DOMDataBroker getDOMDataBroker() {
+ if (this.domDataBroker == null) {
+ this.domDataBroker = createDOMDataBroker();
+ }
+ return this.domDataBroker;
+ }
+
+ private synchronized ImmutableMap<LogicalDatastoreType, DOMStore> getDatastores() {
+ if (this.datastores == null) {
+ this.datastores = createDatastores();
+ }
+ return this.datastores;
+ }
+
+ public void updateSchema(final SchemaContext ctx) {
+ this.schemaService.changeSchema(ctx);
+ }
+
+ public DOMNotificationRouter getDomNotificationRouter() {
+ return this.domNotificationRouter;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Red Hat, 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.mdsal.binding.dom.adapter.test;
+
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import java.util.concurrent.Executors;
+
+/**
+ * AbstractDataBrokerTestCustomizer implementation that uses a single-threaded executor for commits.
+
+ * @author Michael Vorburger
+ */
+public class ConcurrentDataBrokerTestCustomizer extends AbstractDataBrokerTestCustomizer {
+
+ private final ListeningExecutorService dataTreeChangeListenerExecutorSingleton;
+
+ public ConcurrentDataBrokerTestCustomizer(boolean useMTDataTreeChangeListenerExecutor) {
+ if (useMTDataTreeChangeListenerExecutor) {
+ dataTreeChangeListenerExecutorSingleton = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
+ } else {
+ dataTreeChangeListenerExecutorSingleton = MoreExecutors.newDirectExecutorService();
+ }
+ }
+
+ @Override
+ public ListeningExecutorService getCommitCoordinatorExecutor() {
+ return MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor());
+ }
+
+ @Override
+ public ListeningExecutorService getDataTreeChangeListenerExecutor() {
+ return dataTreeChangeListenerExecutorSingleton;
+ }
+}
*/
package org.opendaylight.mdsal.binding.dom.adapter.test;
-import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
-import javassist.ClassPool;
-import org.opendaylight.mdsal.binding.api.DataBroker;
-import org.opendaylight.mdsal.binding.api.NotificationPublishService;
-import org.opendaylight.mdsal.binding.api.NotificationService;
-import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMDataBrokerAdapter;
-import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMNotificationPublishServiceAdapter;
-import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMNotificationServiceAdapter;
-import org.opendaylight.mdsal.binding.dom.adapter.BindingToNormalizedNodeCodec;
-import org.opendaylight.mdsal.binding.dom.adapter.test.util.MockSchemaService;
-import org.opendaylight.mdsal.binding.dom.codec.gen.impl.DataObjectSerializerGenerator;
-import org.opendaylight.mdsal.binding.dom.codec.gen.impl.StreamWriterGenerator;
-import org.opendaylight.mdsal.binding.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
-import org.opendaylight.mdsal.binding.generator.impl.GeneratedClassLoadingStrategy;
-import org.opendaylight.mdsal.binding.generator.util.JavassistUtils;
-import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
-import org.opendaylight.mdsal.dom.api.DOMDataBroker;
-import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.mdsal.dom.broker.DOMNotificationRouter;
-import org.opendaylight.mdsal.dom.broker.SerializedDOMDataBroker;
-import org.opendaylight.mdsal.dom.spi.store.DOMStore;
-import org.opendaylight.mdsal.dom.store.inmemory.InMemoryDOMDataStore;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-
-public class DataBrokerTestCustomizer {
-
- private DOMDataBroker domDataBroker;
- private final DOMNotificationRouter domNotificationRouter;
- private final MockSchemaService schemaService;
- private ImmutableMap<LogicalDatastoreType, DOMStore> datastores;
- private final BindingToNormalizedNodeCodec bindingToNormalized;
-
- public ImmutableMap<LogicalDatastoreType, DOMStore> createDatastores() {
- return ImmutableMap.<LogicalDatastoreType, DOMStore>builder()
- .put(LogicalDatastoreType.OPERATIONAL, createOperationalDatastore())
- .put(LogicalDatastoreType.CONFIGURATION,createConfigurationDatastore())
- .build();
- }
-
- public DataBrokerTestCustomizer() {
- schemaService = new MockSchemaService();
- final ClassPool pool = ClassPool.getDefault();
- final DataObjectSerializerGenerator generator = StreamWriterGenerator.create(JavassistUtils.forClassPool(pool));
- final BindingNormalizedNodeCodecRegistry codecRegistry = new BindingNormalizedNodeCodecRegistry(generator);
- final GeneratedClassLoadingStrategy loading = GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
- bindingToNormalized = new BindingToNormalizedNodeCodec(loading, codecRegistry);
- schemaService.registerSchemaContextListener(bindingToNormalized);
- domNotificationRouter = DOMNotificationRouter.create(16);
- }
-
- public DOMStore createConfigurationDatastore() {
- final InMemoryDOMDataStore store = new InMemoryDOMDataStore("CFG", MoreExecutors.newDirectExecutorService());
- schemaService.registerSchemaContextListener(store);
- return store;
- }
-
- public DOMStore createOperationalDatastore() {
- final InMemoryDOMDataStore store = new InMemoryDOMDataStore("OPER", MoreExecutors.newDirectExecutorService());
- schemaService.registerSchemaContextListener(store);
- return store;
- }
-
- public DOMDataBroker createDOMDataBroker() {
- return new SerializedDOMDataBroker(getDatastores(), getCommitCoordinatorExecutor());
- }
-
- public NotificationService createNotificationService() {
- return new BindingDOMNotificationServiceAdapter(bindingToNormalized.getCodecRegistry(), domNotificationRouter);
- }
-
- public NotificationPublishService createNotificationPublishService() {
- return new BindingDOMNotificationPublishServiceAdapter(bindingToNormalized, domNotificationRouter);
- }
+/**
+ * AbstractDataBrokerTestCustomizer implementation that performs synchronous commits via a direct executor.
+ * Note that this can cause issues if used in a concurrent manner so it is recommended to use
+ * ConcurrentDataBrokerTestCustomizer instead.
+ */
+public class DataBrokerTestCustomizer extends AbstractDataBrokerTestCustomizer {
+ @Override
public ListeningExecutorService getCommitCoordinatorExecutor() {
return MoreExecutors.newDirectExecutorService();
}
-
- public DataBroker createDataBroker() {
- return new BindingDOMDataBrokerAdapter(getDOMDataBroker(), bindingToNormalized);
- }
-
- public BindingToNormalizedNodeCodec getBindingToNormalized() {
- return bindingToNormalized;
- }
-
- public DOMSchemaService getSchemaService() {
- return schemaService;
- }
-
- private DOMDataBroker getDOMDataBroker() {
- if (domDataBroker == null) {
- domDataBroker = createDOMDataBroker();
- }
- return domDataBroker;
- }
-
- private synchronized ImmutableMap<LogicalDatastoreType, DOMStore> getDatastores() {
- if (datastores == null) {
- datastores = createDatastores();
- }
- return datastores;
- }
-
- public void updateSchema(final SchemaContext ctx) {
- schemaService.changeSchema(ctx);
- }
-
- public DOMNotificationRouter getDomNotificationRouter() {
- return domNotificationRouter;
- }
}