--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.javav2.dom.adapter.test;
+
+import com.google.common.annotations.Beta;
+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.javav2.api.DataBroker;
+import org.opendaylight.mdsal.dom.api.DOMDataBroker;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+@Beta
+public class AbstractDataBrokerTest extends AbstractSchemaAwareTest {
+
+ private DataBrokerTestCustomizer testCustomizer;
+ private DataBroker dataBroker;
+ private DOMDataBroker domBroker;
+
+ @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 dataBroker) {
+ // Intentionally left No-op, subclasses may customize it
+ }
+
+ protected DataBrokerTestCustomizer createDataBrokerTestCustomizer() {
+ return new DataBrokerTestCustomizer();
+ }
+
+ public DataBroker getDataBroker() {
+ return dataBroker;
+ }
+
+ public DOMDataBroker getDomBroker() {
+ return domBroker;
+ }
+
+ protected static final void assertCommit(final ListenableFuture<Void> commit) {
+ try {
+ commit.get(500, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.javav2.dom.adapter.test;
+
+import com.google.common.annotations.Beta;
+import org.junit.Before;
+import org.opendaylight.mdsal.binding.javav2.runtime.context.ModuleInfoBackedContext;
+import org.opendaylight.mdsal.binding.javav2.runtime.reflection.BindingReflections;
+import org.opendaylight.mdsal.binding.javav2.spec.runtime.YangModuleInfo;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+@Beta
+public abstract class AbstractSchemaAwareTest {
+
+ private Iterable<YangModuleInfo> moduleInfos;
+ private SchemaContext schemaContext;
+
+ protected Iterable<YangModuleInfo> getModuleInfos() throws Exception {
+ return BindingReflections.loadModuleInfos();
+ }
+
+ @Before
+ public final void setup() throws Exception {
+ moduleInfos = getModuleInfos();
+ final ModuleInfoBackedContext moduleContext = ModuleInfoBackedContext.create();
+ moduleContext.addModuleInfos(moduleInfos);
+ schemaContext = moduleContext.tryToCreateSchemaContext().get();
+ setupWithSchema(schemaContext);
+ }
+
+ /**
+ * Setups test with Schema context.
+ *
+ * @param context
+ * schema context
+ */
+ protected abstract void setupWithSchema(SchemaContext context);
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.javav2.dom.adapter.test;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import java.util.concurrent.ExecutorService;
+import javassist.ClassPool;
+
+@Beta
+public class BindingBrokerTestFactory {
+
+ private static final ClassPool CLASS_POOL = ClassPool.getDefault();
+ private boolean startWithParsedSchema = true;
+ private ExecutorService executor;
+ private ClassPool classPool;
+
+ public boolean isStartWithParsedSchema() {
+ return startWithParsedSchema;
+ }
+
+ public void setStartWithParsedSchema(final boolean startWithParsedSchema) {
+ this.startWithParsedSchema = startWithParsedSchema;
+ }
+
+ public ExecutorService getExecutor() {
+ return executor;
+ }
+
+ public void setExecutor(final ExecutorService executor) {
+ this.executor = executor;
+ }
+
+ public BindingTestContext getTestContext() {
+ Preconditions.checkState(executor != null, "Executor is not set.");
+ final ListeningExecutorService listenableExecutor = MoreExecutors.listeningDecorator(executor);
+ return new BindingTestContext(listenableExecutor, getClassPool(), startWithParsedSchema);
+ }
+
+ public ClassPool getClassPool() {
+ if (classPool == null) {
+ return CLASS_POOL;
+ }
+
+ return classPool;
+ }
+
+ public void setClassPool(final ClassPool classPool) {
+ this.classPool = classPool;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.javav2.dom.adapter.test;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import javassist.ClassPool;
+import org.opendaylight.mdsal.binding.javav2.api.DataBroker;
+import org.opendaylight.mdsal.binding.javav2.api.MountPointService;
+import org.opendaylight.mdsal.binding.javav2.api.NotificationPublishService;
+import org.opendaylight.mdsal.binding.javav2.api.NotificationService;
+import org.opendaylight.mdsal.binding.javav2.api.RpcActionConsumerRegistry;
+import org.opendaylight.mdsal.binding.javav2.dom.adapter.impl.data.BindingDOMDataBrokerAdapter;
+import org.opendaylight.mdsal.binding.javav2.dom.adapter.impl.mountpoint.BindingDOMMountPointServiceAdapter;
+import org.opendaylight.mdsal.binding.javav2.dom.adapter.impl.notification.BindingDOMNotificationPublishServiceAdapter;
+import org.opendaylight.mdsal.binding.javav2.dom.adapter.impl.notification.BindingDOMNotificationServiceAdapter;
+import org.opendaylight.mdsal.binding.javav2.dom.adapter.impl.operation.BindingDOMOperationProviderServiceAdapter;
+import org.opendaylight.mdsal.binding.javav2.dom.adapter.impl.operation.BindingDOMOperationServiceAdapter;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.generator.api.TreeNodeSerializerGenerator;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.generator.impl.StreamWriterGenerator;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.mdsal.binding.javav2.generator.impl.GeneratedClassLoadingStrategy;
+import org.opendaylight.mdsal.binding.javav2.runtime.context.ModuleInfoBackedContext;
+import org.opendaylight.mdsal.binding.javav2.runtime.javassist.JavassistUtils;
+import org.opendaylight.mdsal.binding.javav2.runtime.reflection.BindingReflections;
+import org.opendaylight.mdsal.binding.javav2.spec.runtime.YangModuleInfo;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.dom.api.DOMDataBroker;
+import org.opendaylight.mdsal.dom.api.DOMMountPointService;
+import org.opendaylight.mdsal.dom.api.DOMNotificationPublishService;
+import org.opendaylight.mdsal.dom.api.DOMNotificationService;
+import org.opendaylight.mdsal.dom.api.DOMRpcProviderService;
+import org.opendaylight.mdsal.dom.api.DOMRpcService;
+import org.opendaylight.mdsal.dom.broker.DOMMountPointServiceImpl;
+import org.opendaylight.mdsal.dom.broker.DOMNotificationRouter;
+import org.opendaylight.mdsal.dom.broker.DOMRpcRouter;
+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;
+
+@Beta
+public class BindingTestContext implements AutoCloseable {
+
+ private final MockSchemaService mockSchemaService = new MockSchemaService();
+ private final ListeningExecutorService executor;
+ private final ClassPool classPool;
+ private final boolean startWithSchema;
+
+ private DOMMountPointService biMountImpl;
+ private BindingToNormalizedNodeCodec codec;
+ private ImmutableMap<LogicalDatastoreType, DOMStore> newDatastores;
+ private DOMDataBroker newDOMDataBroker;
+ private DataBroker dataBroker;
+ private RpcActionConsumerRegistry baConsumerRpc;
+ private BindingDOMOperationProviderServiceAdapter baProviderRpc;
+ private DOMRpcRouter domRouter;
+ private NotificationPublishService publishService;
+ private NotificationService listenService;
+ private DOMNotificationPublishService domPublishService;
+ private DOMNotificationService domListenService;
+
+ public DOMDataBroker getDomAsyncDataBroker() {
+ return newDOMDataBroker;
+ }
+
+ public BindingToNormalizedNodeCodec getCodec() {
+ return codec;
+ }
+
+ protected BindingTestContext(final ListeningExecutorService executor, final ClassPool classPool,
+ final boolean startWithSchema) {
+ this.executor = executor;
+ this.classPool = classPool;
+ this.startWithSchema = startWithSchema;
+ }
+
+ public void startDomDataBroker() {
+ }
+
+ public void startNewDataBroker() {
+ checkState(executor != null, "Executor needs to be set");
+ checkState(newDOMDataBroker != null, "DOM Data Broker must be set");
+ dataBroker = new BindingDOMDataBrokerAdapter(newDOMDataBroker, codec);
+ }
+
+ public void startNewDomDataBroker() {
+ checkState(executor != null, "Executor needs to be set");
+ final InMemoryDOMDataStore operStore =
+ new InMemoryDOMDataStore("OPER", MoreExecutors.newDirectExecutorService());
+ final InMemoryDOMDataStore configStore =
+ new InMemoryDOMDataStore("CFG", MoreExecutors.newDirectExecutorService());
+ newDatastores =
+ ImmutableMap.<LogicalDatastoreType, DOMStore>builder().put(LogicalDatastoreType.OPERATIONAL, operStore)
+ .put(LogicalDatastoreType.CONFIGURATION, configStore).build();
+
+ newDOMDataBroker = new SerializedDOMDataBroker(newDatastores, executor);
+
+ mockSchemaService.registerSchemaContextListener(configStore);
+ mockSchemaService.registerSchemaContextListener(operStore);
+ }
+
+ public void startBindingDataBroker() {
+
+ }
+
+ public void startBindingBroker() {
+ checkState(executor != null, "Executor needs to be set");
+
+ baConsumerRpc = new BindingDOMOperationServiceAdapter(getDomRpcInvoker(), codec);
+ baProviderRpc = new BindingDOMOperationProviderServiceAdapter(getDomRpcRegistry(), codec);
+ final MountPointService mountService = new BindingDOMMountPointServiceAdapter(biMountImpl, codec);
+ }
+
+ public void startForwarding() {
+
+ }
+
+ public void startBindingToDomMappingService() {
+ checkState(classPool != null, "ClassPool needs to be present");
+
+ final TreeNodeSerializerGenerator generator =
+ StreamWriterGenerator.create(JavassistUtils.forClassPool(classPool));
+ final BindingNormalizedNodeCodecRegistry codecRegistry = new BindingNormalizedNodeCodecRegistry(generator);
+ final GeneratedClassLoadingStrategy loading =
+ (GeneratedClassLoadingStrategy) GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy();
+ codec = new BindingToNormalizedNodeCodec(loading, codecRegistry);
+ mockSchemaService.registerSchemaContextListener(codec);
+ }
+
+ private void updateYangSchema(final ImmutableSet<YangModuleInfo> moduleInfos) {
+ mockSchemaService.changeSchema(getContext(moduleInfos));
+ }
+
+ private SchemaContext getContext(final ImmutableSet<YangModuleInfo> moduleInfos) {
+ final ModuleInfoBackedContext ctx = ModuleInfoBackedContext.create();
+ ctx.addModuleInfos(moduleInfos);
+ return ctx.tryToCreateSchemaContext().get();
+ }
+
+ public SchemaContext getContext() {
+ return mockSchemaService.getSchemaContext();
+ }
+
+ public void start() {
+ startNewDomDataBroker();
+
+ startDomBroker();
+ startDomMountPoint();
+ startBindingToDomMappingService();
+ startNewDataBroker();
+ startBindingNotificationBroker();
+ startBindingBroker();
+
+ startForwarding();
+ if (startWithSchema) {
+ loadYangSchemaFromClasspath();
+ }
+ }
+
+ private void startDomMountPoint() {
+ biMountImpl = new DOMMountPointServiceImpl();
+ }
+
+ private void startDomBroker() {
+ checkState(executor != null);
+ domRouter = new DOMRpcRouter();
+ mockSchemaService.registerSchemaContextListener(domRouter);
+ }
+
+ public void startBindingNotificationBroker() {
+ checkState(executor != null);
+ final DOMNotificationRouter router = DOMNotificationRouter.create(16);
+ domPublishService = router;
+ domListenService = router;
+ publishService = new BindingDOMNotificationPublishServiceAdapter(codec, domPublishService);
+ listenService = new BindingDOMNotificationServiceAdapter(codec, domListenService);
+
+ }
+
+ public void loadYangSchemaFromClasspath() {
+ final ImmutableSet<YangModuleInfo> moduleInfos = BindingReflections.loadModuleInfos();
+ updateYangSchema(moduleInfos);
+ }
+
+ public DOMRpcProviderService getDomRpcRegistry() {
+ return domRouter;
+ }
+
+ public DOMRpcService getDomRpcInvoker() {
+ return domRouter;
+ }
+
+ @Override
+ public void close() throws Exception {
+
+ }
+
+ public DOMMountPointService getDomMountProviderService() {
+ return biMountImpl;
+ }
+
+ public DataBroker getDataBroker() {
+ return dataBroker;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.javav2.dom.adapter.test;
+
+import com.google.common.annotations.Beta;
+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.javav2.api.DataBroker;
+import org.opendaylight.mdsal.binding.javav2.api.NotificationPublishService;
+import org.opendaylight.mdsal.binding.javav2.api.NotificationService;
+import org.opendaylight.mdsal.binding.javav2.dom.adapter.impl.data.BindingDOMDataBrokerAdapter;
+import org.opendaylight.mdsal.binding.javav2.dom.adapter.impl.notification.BindingDOMNotificationPublishServiceAdapter;
+import org.opendaylight.mdsal.binding.javav2.dom.adapter.impl.notification.BindingDOMNotificationServiceAdapter;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.generator.api.TreeNodeSerializerGenerator;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.generator.impl.StreamWriterGenerator;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.mdsal.binding.javav2.generator.impl.GeneratedClassLoadingStrategy;
+import org.opendaylight.mdsal.binding.javav2.runtime.javassist.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;
+
+@Beta
+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 TreeNodeSerializerGenerator generator = StreamWriterGenerator.create(JavassistUtils.forClassPool(pool));
+ final BindingNormalizedNodeCodecRegistry codecRegistry = new BindingNormalizedNodeCodecRegistry(generator);
+ final GeneratedClassLoadingStrategy loading =
+ (GeneratedClassLoadingStrategy) 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);
+ }
+
+ 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;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. 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.javav2.dom.adapter.test;
+
+import com.google.common.annotations.Beta;
+import org.opendaylight.mdsal.dom.api.DOMSchemaService;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.util.ListenerRegistry;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
+import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
+
+@Beta
+public final class MockSchemaService implements DOMSchemaService, SchemaContextProvider {
+
+ private SchemaContext schemaContext;
+
+ ListenerRegistry<SchemaContextListener> listeners = ListenerRegistry.create();
+
+ @Override
+ public synchronized SchemaContext getGlobalContext() {
+ return schemaContext;
+ }
+
+ @Override
+ public synchronized SchemaContext getSessionContext() {
+ return schemaContext;
+ }
+
+ @Override
+ public ListenerRegistration<SchemaContextListener>
+ registerSchemaContextListener(final SchemaContextListener listener) {
+ return listeners.register(listener);
+ }
+
+ @Override
+ public synchronized SchemaContext getSchemaContext() {
+ return schemaContext;
+ }
+
+ public synchronized void changeSchema(final SchemaContext newContext) {
+ schemaContext = newContext;
+ for (final ListenerRegistration<SchemaContextListener> listener : listeners) {
+ listener.getInstance().onGlobalContextUpdated(schemaContext);
+ }
+ }
+}
\ No newline at end of file