Add read-write transaction to the AsyncDataBroker APIs 56/50156/9
authorTom Pantelis <tpanteli@brocade.com>
Tue, 10 Jan 2017 04:27:42 +0000 (23:27 -0500)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 17 Oct 2017 14:26:24 +0000 (16:26 +0200)
Read-write transactions were ommitted from the AsyncDataBroker
and related APIs. It is unclear as to why but the DOMStore API
defines read-write transaction as do the equivalent controller
APIs so clients will expect it when converting to the mdsal APIs.
Plus we want to convert the CDS to the mdsal APIs and deprecate the
controller APIs but we cannot provide an adapter between the two
without read-write transactions.

Change-Id: I46cd1783931044a34039f4a2100c50b645446bf2
Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
28 files changed:
binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/BindingTransactionChain.java
binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/DataBroker.java
binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/ReadWriteTransaction.java [new file with mode: 0644]
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMAdapterBuilder.java
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMAdapterLoader.java
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMDataBrokerAdapter.java
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMNotificationPublishServiceAdapter.java
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMNotificationServiceAdapter.java
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMReadWriteTransactionAdapter.java [new file with mode: 0644]
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMTransactionChainAdapter.java
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/data/BindingDOMDataBrokerAdapter.java
binding2/mdsal-binding2-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/javav2/dom/adapter/impl/transaction/BindingDOMTransactionChainAdapter.java
common/mdsal-common-api/src/main/java/org/opendaylight/mdsal/common/api/AsyncDataBroker.java
common/mdsal-common-api/src/main/java/org/opendaylight/mdsal/common/api/AsyncDataTransactionFactory.java
common/mdsal-common-api/src/main/java/org/opendaylight/mdsal/common/api/AsyncReadWriteTransaction.java [new file with mode: 0644]
common/mdsal-common-api/src/main/java/org/opendaylight/mdsal/common/api/TransactionChain.java
dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/DOMDataBroker.java
dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/DOMDataTreeReadWriteTransaction.java [new file with mode: 0644]
dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/DOMTransactionChain.java
dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/AbstractDOMForwardedTransactionFactory.java
dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/DOMForwardedReadWriteTransaction.java [new file with mode: 0644]
dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/ShardedDOMDataBrokerAdapter.java
dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/ShardedDOMReadWriteTransactionAdapter.java [new file with mode: 0644]
dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/ShardedDOMTransactionChainAdapter.java
dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/TransactionChainReadWriteTransaction.java [new file with mode: 0644]
dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/ForwardingDOMDataBroker.java
dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/ForwardingDOMTransactionChain.java
dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/ForwardingDOMTransactionChainTest.java

index bf1219cdd47fc80932a90698c4b2f9b57b72d720..afd2e756785b0ed9eed7da10cdb26c2f3df4a002 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.mdsal.binding.api;
 
 import org.opendaylight.mdsal.common.api.TransactionChain;
-
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
@@ -30,4 +29,7 @@ public interface BindingTransactionChain extends TransactionFactory,
 
     @Override
     WriteTransaction newWriteOnlyTransaction();
+
+    @Override
+    ReadWriteTransaction newReadWriteTransaction();
 }
index c43889c0c8de7ff13c5ff39f534dc0088fdb0c88..9ad29be2b67294d3ede00eb3b69a4baf99eb0933 100644 (file)
@@ -33,6 +33,9 @@ public interface DataBroker extends  AsyncDataBroker<InstanceIdentifier<?>, Data
     @Override
     WriteTransaction newWriteOnlyTransaction();
 
+    @Override
+    ReadWriteTransaction newReadWriteTransaction();
+
     @Override
     BindingTransactionChain createTransactionChain(TransactionChainListener listener);
 }
diff --git a/binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/ReadWriteTransaction.java b/binding/mdsal-binding-api/src/main/java/org/opendaylight/mdsal/binding/api/ReadWriteTransaction.java
new file mode 100644 (file)
index 0000000..70299ec
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017 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.mdsal.binding.api;
+
+import com.google.common.annotations.Beta;
+import org.opendaylight.mdsal.common.api.AsyncReadWriteTransaction;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * A transaction that enables combined read/write capabilities.
+ *
+ * <p>
+ * For more information on usage and examples, please see the documentation in {@link AsyncReadWriteTransaction}.
+ */
+@Beta
+public interface ReadWriteTransaction extends ReadTransaction, WriteTransaction,
+        AsyncReadWriteTransaction<InstanceIdentifier<?>, DataObject> {
+}
index 94758151e71be19d4e593869ec776186fb965ddc..bfcdbc8fde78cb9c9980dfbacb70e6f8eb18ed03 100644 (file)
@@ -14,6 +14,7 @@ import org.opendaylight.mdsal.dom.api.DOMService;
 
 abstract class BindingDOMAdapterBuilder<T extends BindingService> extends AdapterBuilder<T, DOMService> {
 
+    @FunctionalInterface
     interface Factory<T extends BindingService> {
 
         BindingDOMAdapterBuilder<T> newBuilder();
index b58e9a246c941bd07d2a913c6197071dcfd2f6f4..ec5bc81e311878c7a74e37fe6752f0a24da737dc 100644 (file)
@@ -19,14 +19,12 @@ import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMAdapterBuilder.Facto
 import org.opendaylight.mdsal.dom.api.DOMService;
 
 public abstract class BindingDOMAdapterLoader extends AdapterLoader<BindingService, DOMService> {
-
-
-    private static final Map<Class<?>,BindingDOMAdapterBuilder.Factory<?>> FACTORIES = ImmutableMap.<Class<?>,
-                BindingDOMAdapterBuilder.Factory<?>>builder()
-            .put(NotificationService.class,BindingDOMNotificationServiceAdapter.BUILDER_FACTORY)
-            .put(NotificationPublishService.class,BindingDOMNotificationPublishServiceAdapter.BUILDER_FACTORY)
-            .put(DataBroker.class,BindingDOMDataBrokerAdapter.BUILDER_FACTORY)
-            .put(RpcConsumerRegistry.class,BindingDOMRpcServiceAdapter.BUILDER_FACTORY)
+    private static final Map<Class<?>,BindingDOMAdapterBuilder.Factory<?>> FACTORIES =
+            ImmutableMap.<Class<?>, BindingDOMAdapterBuilder.Factory<?>>builder()
+            .put(NotificationService.class, BindingDOMNotificationServiceAdapter.BUILDER_FACTORY)
+            .put(NotificationPublishService.class, BindingDOMNotificationPublishServiceAdapter.BUILDER_FACTORY)
+            .put(DataBroker.class, BindingDOMDataBrokerAdapter.BUILDER_FACTORY)
+            .put(RpcConsumerRegistry.class, BindingDOMRpcServiceAdapter.BUILDER_FACTORY)
             .build();
 
     private final BindingToNormalizedNodeCodec codec;
index a40b14ed8cd1333e0e289413e74394769d42aa55..c636c81e4bc1921d3a52805d16960813e1192567 100644 (file)
@@ -16,6 +16,7 @@ import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
 import org.opendaylight.mdsal.binding.api.DataTreeChangeService;
 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
 import org.opendaylight.mdsal.binding.api.ReadTransaction;
+import org.opendaylight.mdsal.binding.api.ReadWriteTransaction;
 import org.opendaylight.mdsal.binding.api.WriteTransaction;
 import org.opendaylight.mdsal.binding.dom.adapter.BindingDOMAdapterBuilder.Factory;
 import org.opendaylight.mdsal.common.api.TransactionChainListener;
@@ -40,14 +41,7 @@ public class BindingDOMDataBrokerAdapter extends AbstractForwardedDataBroker imp
         DataBroker, DataTreeChangeService {
 
 
-    static final Factory<DataBroker> BUILDER_FACTORY = new BindingDOMAdapterBuilder.Factory<DataBroker>() {
-
-        @Override
-        public BindingDOMAdapterBuilder<DataBroker> newBuilder() {
-            return new Builder();
-        }
-
-    };
+    static final Factory<DataBroker> BUILDER_FACTORY = Builder::new;
     private final DataTreeChangeService treeChangeService;
 
     public BindingDOMDataBrokerAdapter(final DOMDataBroker domDataBroker, final BindingToNormalizedNodeCodec codec) {
@@ -63,12 +57,17 @@ public class BindingDOMDataBrokerAdapter extends AbstractForwardedDataBroker imp
 
     @Override
     public ReadTransaction newReadOnlyTransaction() {
-        return new BindingDOMReadTransactionAdapter(getDelegate().newReadOnlyTransaction(),getCodec());
+        return new BindingDOMReadTransactionAdapter(getDelegate().newReadOnlyTransaction(), getCodec());
     }
 
     @Override
     public WriteTransaction newWriteOnlyTransaction() {
-        return new BindingDOMWriteTransactionAdapter<>(getDelegate().newWriteOnlyTransaction(),getCodec());
+        return new BindingDOMWriteTransactionAdapter<>(getDelegate().newWriteOnlyTransaction(), getCodec());
+    }
+
+    @Override
+    public ReadWriteTransaction newReadWriteTransaction() {
+        return new BindingDOMReadWriteTransactionAdapter(getDelegate().newReadWriteTransaction(), getCodec());
     }
 
     @Override
@@ -101,5 +100,4 @@ public class BindingDOMDataBrokerAdapter extends AbstractForwardedDataBroker imp
         }
         return treeChangeService.registerDataTreeChangeListener(treeId, listener);
     }
-
 }
index 0f5d2582fb3ce09b5dcf0f8a72d0f7e391412597..e60aa9b6ca6629be1d14efbb56b1364d517b61d9 100644 (file)
@@ -21,15 +21,7 @@ import org.opendaylight.yangtools.yang.binding.Notification;
 
 public class BindingDOMNotificationPublishServiceAdapter implements NotificationPublishService, AutoCloseable {
 
-    static final Factory<NotificationPublishService> BUILDER_FACTORY
-            = new BindingDOMAdapterBuilder.Factory<NotificationPublishService>() {
-
-                @Override
-                public BindingDOMAdapterBuilder<NotificationPublishService> newBuilder() {
-                    return new Builder();
-                }
-
-            };
+    static final Factory<NotificationPublishService> BUILDER_FACTORY = Builder::new;
 
     private final BindingToNormalizedNodeCodec codecRegistry;
     private final DOMNotificationPublishService domPublishService;
index da5998786ee958f30deef70786468651f16b521a..1fe59805332991788e070700a19f42dbfcdf5fbd 100644 (file)
@@ -21,14 +21,8 @@ import org.opendaylight.yangtools.yang.binding.NotificationListener;
 
 public class BindingDOMNotificationServiceAdapter implements NotificationService, AutoCloseable {
 
-    public static final Factory<NotificationService> BUILDER_FACTORY = new Factory<NotificationService>() {
+    public static final Factory<NotificationService> BUILDER_FACTORY = Builder::new;
 
-        @Override
-        public BindingDOMAdapterBuilder<NotificationService> newBuilder() {
-            return new Builder();
-        }
-
-    };
     private final BindingNormalizedNodeSerializer codec;
     private final DOMNotificationService domNotifService;
 
diff --git a/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMReadWriteTransactionAdapter.java b/binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMReadWriteTransactionAdapter.java
new file mode 100644 (file)
index 0000000..b60b56c
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017 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.mdsal.binding.dom.adapter;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import org.opendaylight.mdsal.binding.api.ReadWriteTransaction;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.common.api.ReadFailedException;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+class BindingDOMReadWriteTransactionAdapter extends BindingDOMWriteTransactionAdapter<DOMDataTreeReadWriteTransaction>
+        implements ReadWriteTransaction {
+
+    BindingDOMReadWriteTransactionAdapter(DOMDataTreeReadWriteTransaction delegateTx,
+            BindingToNormalizedNodeCodec codec) {
+        super(delegateTx, codec);
+    }
+
+    @Override
+    public <T extends DataObject> CheckedFuture<Optional<T>, ReadFailedException> read(LogicalDatastoreType store,
+            InstanceIdentifier<T> path) {
+        return doRead(getDelegate(),store, path);
+    }
+
+    @Override
+    public void close() {
+    }
+}
index e80579e9b4aa1bb70adeebf5ab5c376ca5f75590..71d971606506a55e9e6b86d57ed080d6ec82b45c 100644 (file)
@@ -15,6 +15,7 @@ import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.MoreExecutors;
 import org.opendaylight.mdsal.binding.api.BindingTransactionChain;
 import org.opendaylight.mdsal.binding.api.ReadTransaction;
+import org.opendaylight.mdsal.binding.api.ReadWriteTransaction;
 import org.opendaylight.mdsal.binding.api.WriteTransaction;
 import org.opendaylight.mdsal.common.api.AsyncTransaction;
 import org.opendaylight.mdsal.common.api.TransactionChain;
@@ -22,6 +23,7 @@ import org.opendaylight.mdsal.common.api.TransactionChainListener;
 import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
 import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
 import org.opendaylight.yangtools.concepts.Delegator;
@@ -70,6 +72,19 @@ final class BindingDOMTransactionChainAdapter implements BindingTransactionChain
         };
     }
 
+    @Override
+    public ReadWriteTransaction newReadWriteTransaction() {
+        final DOMDataTreeReadWriteTransaction delegateTx = delegate.newReadWriteTransaction();
+        return new BindingDOMReadWriteTransactionAdapter(delegateTx, codec) {
+
+            @Override
+            public CheckedFuture<Void, TransactionCommitFailedException> submit() {
+                return listenForFailure(this,super.submit());
+            }
+
+        };
+    }
+
     private <T, F extends ListenableFuture<T>> F listenForFailure(final WriteTransaction tx, final F future) {
         Futures.addCallback(future, new FutureCallback<T>() {
             @Override
@@ -127,5 +142,4 @@ final class BindingDOMTransactionChainAdapter implements BindingTransactionChain
             bindingListener.onTransactionChainSuccessful(BindingDOMTransactionChainAdapter.this);
         }
     }
-
 }
index b3006f36bb75a761f787e5291bc9badcb40f6390..b3459d400e2220e955cca65af0d2c21124ffeb87 100644 (file)
@@ -30,6 +30,9 @@ import org.opendaylight.mdsal.binding.javav2.dom.adapter.spi.AbstractForwardedDa
 import org.opendaylight.mdsal.binding.javav2.dom.adapter.spi.builder.BindingDOMAdapterBuilder;
 import org.opendaylight.mdsal.binding.javav2.dom.adapter.spi.builder.BindingDOMAdapterBuilder.Factory;
 import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.common.api.AsyncReadWriteTransaction;
 import org.opendaylight.mdsal.common.api.TransactionChainListener;
 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
@@ -74,6 +77,12 @@ public class BindingDOMDataBrokerAdapter extends AbstractForwardedDataBroker imp
         return new BindingDOMWriteTransactionAdapter<>(getDelegate().newWriteOnlyTransaction(), getCodec());
     }
 
+    @Override
+    public AsyncReadWriteTransaction<InstanceIdentifier<?>, TreeNode> newReadWriteTransaction() {
+        // TODO - placeholder for now
+        throw new UnsupportedOperationException();
+    }
+
     @Override
     public BindingTransactionChain createTransactionChain(final TransactionChainListener listener) {
         return new BindingDOMTransactionChainAdapter(getDelegate(), getCodec(), listener);
index 3de3ddf68dfb83cf145faa8af854a1001d0ed7ba..10de48694b9f3d16f0c6ae256ca083391e504fc5 100644 (file)
@@ -18,6 +18,9 @@ import org.opendaylight.mdsal.binding.javav2.api.BindingTransactionChain;
 import org.opendaylight.mdsal.binding.javav2.api.ReadTransaction;
 import org.opendaylight.mdsal.binding.javav2.api.WriteTransaction;
 import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.common.api.AsyncReadWriteTransaction;
 import org.opendaylight.mdsal.common.api.AsyncTransaction;
 import org.opendaylight.mdsal.common.api.TransactionChain;
 import org.opendaylight.mdsal.common.api.TransactionChainListener;
@@ -75,6 +78,12 @@ public final class BindingDOMTransactionChainAdapter
         };
     }
 
+    @Override
+    public AsyncReadWriteTransaction<InstanceIdentifier<?>, TreeNode> newReadWriteTransaction() {
+        // TODO - placeholder for now
+        throw new UnsupportedOperationException();
+    }
+
     private <T, F extends ListenableFuture<T>> F listenForFailure(final WriteTransaction tx, final F future) {
         Futures.addCallback(future, new FutureCallback<T>() {
             @Override
index a441f528812ab66e621451b0e2050f890e5edd3f..86f201008ab87a7cfe2344f01444404556af2c6f 100644 (file)
@@ -55,4 +55,7 @@ public interface AsyncDataBroker<P extends Path<P>, D> extends
 
     @Override
     AsyncWriteTransaction<P, D> newWriteOnlyTransaction();
+
+    @Override
+    AsyncReadWriteTransaction<P, D> newReadWriteTransaction();
 }
index 8d629b77f42d3728b1a45ef84513e2600e035663..be0df369fdc4ef25c0eac2016cb334a3d457cec4 100644 (file)
@@ -90,4 +90,16 @@ public interface AsyncDataTransactionFactory<P extends Path<P>, D> {
      */
     AsyncWriteTransaction<P, D> newWriteOnlyTransaction();
 
+    /**
+     * Allocates new read-write transaction which provides a mutable view of the data tree.
+     *
+     * <p>
+     * Preconditions for mutation of data tree are captured from the snapshot of data tree state, when the transaction
+     * is allocated. If data was changed during transaction in an incompatible way then the commit of this transaction
+     * will fail. See {@link AsyncWriteTransaction#submit()} for more details about conflicting and not-conflicting
+     * changes and failure scenarios.
+     *
+     * @return new read-write transaction
+     */
+    AsyncReadWriteTransaction<P, D> newReadWriteTransaction();
 }
diff --git a/common/mdsal-common-api/src/main/java/org/opendaylight/mdsal/common/api/AsyncReadWriteTransaction.java b/common/mdsal-common-api/src/main/java/org/opendaylight/mdsal/common/api/AsyncReadWriteTransaction.java
new file mode 100644 (file)
index 0000000..068b570
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2017 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.mdsal.common.api;
+
+import org.opendaylight.yangtools.concepts.Path;
+
+/**
+ * Transaction enabling a client to have combined read/write capabilities.
+ *
+ * <p>
+ * The initial state of the write transaction is stable snapshot of current data tree
+ * state captured when transaction was created and it's state and underlying
+ * data tree are not affected by other concurrently running transactions.
+ *
+ * <p>
+ * Write transactions are isolated from other concurrent write transactions. All
+ * writes are local to the transaction and represents only a proposal of state
+ * change for data tree and it is not visible to any other concurrently running
+ * transactions.
+ *
+ * <p>
+ * Applications publish the changes proposed in the transaction by calling {@link #submit}
+ * on the transaction. This seals the transaction
+ * (preventing any further writes using this transaction) and submits it to be
+ * processed and applied to global conceptual data tree.
+ *
+ * <p>
+ * The transaction commit may fail due to a concurrent transaction modifying and committing data in
+ * an incompatible way. See {@link #submit()} for more concrete commit failure examples.
+ *
+ * <b>Implementation Note:</b> This interface is not intended to be implemented
+ * by users of MD-SAL, but only to be consumed by them.
+ *
+ * <h2>Examples</h2>
+ *
+ * <h3>Transaction local state</h3>
+ *
+ * <p>
+ * Let's assume initial state of data tree for <code>PATH</code> is <code>A</code>
+ * .
+ * <pre>
+ * txWrite = broker.newReadWriteTransaction(); // concurrent write transaction
+ *
+ * txWrite.read(OPERATIONAL,PATH).get()        // will return Optional containing A
+ * txWrite.put(OPERATIONAL,PATH,B);            // writes B to PATH
+ * txWrite.read(OPERATIONAL,PATH).get()        // will return Optional Containing B
+ *
+ * txWrite.commit().get();                     // data tree is updated, PATH contains B
+ *
+ * tx1afterCommit = broker.newReadOnlyTransaction(); // read Transaction is snapshot of new state
+ * tx1afterCommit.read(OPERATIONAL,PATH).get(); // returns Optional containing B
+ * </pre>
+ *
+ * <p>
+ * As you could see read-write transaction provides capabilities as
+ * {@link AsyncWriteTransaction} but also allows for reading proposed changes as
+ * if they already happened.
+ *
+ * <h3>Transaction isolation (read transaction, read-write transaction)</h3> Let
+ * assume initial state of data tree for <code>PATH</code> is <code>A</code>.
+ *
+ * <pre>
+ * txRead = broker.newReadOnlyTransaction();   // read Transaction is snapshot of data
+ * txWrite = broker.newReadWriteTransaction(); // concurrent write transaction
+ *
+ * txRead.read(OPERATIONAL,PATH).get();        // will return Optional containing A
+ * txWrite.read(OPERATIONAL,PATH).get()        // will return Optional containing A
+ *
+ * txWrite.put(OPERATIONAL,PATH,B);            // writes B to PATH
+ * txWrite.read(OPERATIONAL,PATH).get()        // will return Optional Containing B
+ *
+ * txRead.read(OPERATIONAL,PATH).get();        // concurrent read transaction still returns
+ *                                             // Optional containing A
+ *
+ * txWrite.commit().get();                     // data tree is updated, PATH contains B
+ * txRead.read(OPERATIONAL,PATH).get();        // still returns Optional containing A
+ *
+ * tx1afterCommit = broker.newReadOnlyTransaction(); // read Transaction is snapshot of new state
+ * tx1afterCommit.read(OPERATIONAL,PATH).get(); // returns Optional containing B
+ * </pre>
+ *
+ * <h3>Transaction isolation (2 concurrent read-write transactions)</h3> Let
+ * assume initial state of data tree for <code>PATH</code> is <code>A</code>.
+ *
+ * <pre>
+ * tx1 = broker.newReadWriteTransaction(); // read Transaction is snapshot of data
+ * tx2 = broker.newReadWriteTransaction(); // concurrent write transaction
+ *
+ * tx1.read(OPERATIONAL,PATH).get();       // will return Optional containing A
+ * tx2.read(OPERATIONAL,PATH).get()        // will return Optional containing A
+ *
+ * tx2.put(OPERATIONAL,PATH,B);            // writes B to PATH
+ * tx2.read(OPERATIONAL,PATH).get()        // will return Optional Containing B
+ *
+ * tx1.read(OPERATIONAL,PATH).get();       // tx1 read-write transaction still sees Optional
+ *                                         // containing A since is isolated from tx2
+ * tx1.put(OPERATIONAL,PATH,C);            // writes C to PATH
+ * tx1.read(OPERATIONAL,PATH).get()        // will return Optional Containing C
+ *
+ * tx2.read(OPERATIONAL,PATH).get()        // tx2 read-write transaction still sees Optional
+ *                                         // containing B since is isolated from tx1
+ *
+ * tx2.commit().get();                     // data tree is updated, PATH contains B
+ * tx1.read(OPERATIONAL,PATH).get();       // still returns Optional containing C since is isolated from tx2
+ *
+ * tx1afterCommit = broker.newReadOnlyTransaction(); // read Transaction is snapshot of new state
+ * tx1afterCommit.read(OPERATIONAL,PATH).get(); // returns Optional containing B
+ *
+ * tx1.commit()                            // Will fail with OptimisticLockFailedException
+ *                                         // which means concurrent transaction changed the same PATH
+ *
+ * </pre>
+ *
+ * <p>
+ * <b>Note:</b> examples contains blocking calls on future only to illustrate
+ * that action happened after other asynchronous action. Use of blocking call
+ * {@link com.google.common.util.concurrent.ListenableFuture#get()} is discouraged for most uses and you should
+ * use
+ * {@link com.google.common.util.concurrent.Futures#addCallback(com.google.common.util.concurrent.ListenableFuture,
+ * com.google.common.util.concurrent.FutureCallback)}
+ * or other functions from {@link com.google.common.util.concurrent.Futures} to
+ * register more specific listeners.
+ *
+ * @see AsyncReadTransaction
+ * @see AsyncWriteTransaction
+ *
+ * @param <P>
+ *            Type of path (subtree identifier), which represents location in
+ *            tree
+ * @param <D>
+ *            Type of data (payload), which represents data payload
+ */
+public interface AsyncReadWriteTransaction<P extends Path<P>, D> extends AsyncReadTransaction<P, D>,
+        AsyncWriteTransaction<P, D> {
+
+}
index d6ef81c7a70b1156fd48696763c96734d1b953a7..addddca11f1f3e2d25a196f3ff05ef2f5c8c245f 100644 (file)
@@ -93,6 +93,35 @@ public interface TransactionChain<P extends Path<P>, D> extends AutoCloseable,
     @Override
     AsyncWriteTransaction<P, D> newWriteOnlyTransaction();
 
+    /**
+     * Create a new read-write transaction which will continue the chain.
+     *
+     * <p>
+     * The previous write transaction has to be either SUBMITTED
+     * ({@link AsyncWriteTransaction#submit submit} was invoked) or CANCELLED
+     * ({@link #close close} was invoked).
+     *
+     * <p>
+     * The returned read-write transaction presents an isolated view of the data if the previous
+     * write transaction was successful - in other words, this read-write transaction will see the
+     * state changes made by the previous write transaction in the chain. However, state which
+     * was introduced by other transactions outside this transaction chain after creation of
+     * the previous transaction is not visible.
+     *
+     * <p>
+     * Committing this read-write transaction using {@link AsyncWriteTransaction#submit submit}
+     * will submit the state changes in this transaction to be visible to any subsequent
+     * transaction in this chain and also to any transaction outside this chain.
+     *
+     * @return New transaction in the chain.
+     * @throws IllegalStateException
+     *             if the previous transaction was not SUBMITTED or CANCELLED.
+     * @throws TransactionChainClosedException
+     *             if the chain has been closed.
+     */
+    @Override
+    AsyncReadWriteTransaction<P, D> newReadWriteTransaction();
+
     @Override
     void close();
 }
index 23c6efcf8cb10eec0f9a4fe715067b9413b41887..1519b9584791491ff35719ded9628d2e1525a4cb 100644 (file)
@@ -29,6 +29,9 @@ public interface DOMDataBroker extends
     @Override
     DOMDataTreeWriteTransaction newWriteOnlyTransaction();
 
+    @Override
+    DOMDataTreeReadWriteTransaction newReadWriteTransaction();
+
     @Override
     DOMTransactionChain createTransactionChain(TransactionChainListener listener);
 }
diff --git a/dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/DOMDataTreeReadWriteTransaction.java b/dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/DOMDataTreeReadWriteTransaction.java
new file mode 100644 (file)
index 0000000..7b481c7
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2017 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.mdsal.dom.api;
+
+import org.opendaylight.mdsal.common.api.AsyncReadWriteTransaction;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * A transaction that provides read/write access to a logical data store.
+ *
+ * <p>
+ * For more information on usage and examples, please see the documentation in {@link AsyncReadWriteTransaction}.
+ */
+public interface DOMDataTreeReadWriteTransaction extends DOMDataTreeReadTransaction, DOMDataTreeWriteTransaction,
+        AsyncReadWriteTransaction<YangInstanceIdentifier, NormalizedNode<?, ?>> {
+}
index 14d7929b958818e0ce3ed8c72f12e3c88fd1aef2..c8d2264755945731280e57f6a05734773ce0619d 100644 (file)
@@ -28,4 +28,6 @@ public interface DOMTransactionChain extends TransactionChain<YangInstanceIdenti
     @Override
     DOMDataTreeWriteTransaction newWriteOnlyTransaction();
 
+    @Override
+    DOMDataTreeReadWriteTransaction newReadWriteTransaction();
 }
index 2d11ddb3efef7bee4b0fcf8e002c4fba876ea4b3..e1825babd9358c25598fe0a88ba87e513a752f62 100644 (file)
@@ -17,8 +17,10 @@ import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
 import org.opendaylight.mdsal.dom.spi.store.DOMStoreReadTransaction;
+import org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction;
 import org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort;
 import org.opendaylight.mdsal.dom.spi.store.DOMStoreTransactionFactory;
 import org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction;
@@ -158,6 +160,21 @@ abstract class AbstractDOMForwardedTransactionFactory<T extends DOMStoreTransact
         return new DOMForwardedWriteTransaction<>(newTransactionIdentifier(), txns, this);
     }
 
+    /**
+     * Creates a new composite read-write transaction.
+     *
+     * @return New composite read-write transaction associated with this factory.
+     */
+    public final DOMDataTreeReadWriteTransaction newReadWriteTransaction() {
+        checkNotClosed();
+
+        final Map<LogicalDatastoreType, DOMStoreReadWriteTransaction> txns = new EnumMap<>(LogicalDatastoreType.class);
+        for (Entry<LogicalDatastoreType, T> store : storeTxFactories.entrySet()) {
+            txns.put(store.getKey(), store.getValue().newReadWriteTransaction());
+        }
+        return new DOMForwardedReadWriteTransaction(newTransactionIdentifier(), txns, this);
+    }
+
     /**
      * Convenience accessor of backing factories intended to be used only by
      * finalization of this class.
diff --git a/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/DOMForwardedReadWriteTransaction.java b/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/DOMForwardedReadWriteTransaction.java
new file mode 100644 (file)
index 0000000..efeab63
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017 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.mdsal.dom.broker;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import java.util.Map;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.common.api.ReadFailedException;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
+import org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * Read-Write Transaction, which is composed of several
+ * {@link DOMStoreReadWriteTransaction} transactions. Subtransaction is selected by
+ * {@link LogicalDatastoreType} type parameter in:
+ *
+ * <ul>
+ * <li>{@link #read(LogicalDatastoreType, YangInstanceIdentifier)}
+ * <li>{@link #put(LogicalDatastoreType, YangInstanceIdentifier, NormalizedNode)}
+ * <li>{@link #delete(LogicalDatastoreType, YangInstanceIdentifier)}
+ * <li>{@link #merge(LogicalDatastoreType, YangInstanceIdentifier, NormalizedNode)}
+ * </ul>
+ *
+ * <p>
+ * {@link #submit()} will result in invocation of
+ * {@link DOMDataCommitImplementation#submit(org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction, Iterable)}
+ * invocation with all
+ * {@link org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort} for
+ * underlying transactions.
+ */
+final class DOMForwardedReadWriteTransaction extends DOMForwardedWriteTransaction<DOMStoreReadWriteTransaction>
+        implements DOMDataTreeReadWriteTransaction {
+
+    protected DOMForwardedReadWriteTransaction(final Object identifier,
+            final Map<LogicalDatastoreType, DOMStoreReadWriteTransaction> backingTxs,
+            final AbstractDOMForwardedTransactionFactory<?> commitImpl) {
+        super(identifier, backingTxs, commitImpl);
+    }
+
+    @Override
+    public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(final LogicalDatastoreType store,
+            final YangInstanceIdentifier path) {
+        return getSubtransaction(store).read(path);
+    }
+
+    @Override
+    public CheckedFuture<Boolean, ReadFailedException> exists(final LogicalDatastoreType store,
+            final YangInstanceIdentifier path) {
+        return getSubtransaction(store).exists(path);
+    }
+
+    @Override
+    public void close() {
+        closeSubtransactions();
+    }
+}
index 7faad87787305f2db79aae3ae9ff11251d700549..826bb0d4b91d9254a3dfe55298715ad436ccb6ab 100644 (file)
@@ -15,6 +15,7 @@ import org.opendaylight.mdsal.common.api.TransactionChainListener;
 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
 import org.opendaylight.mdsal.dom.api.DOMDataBrokerExtension;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
 import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
@@ -44,6 +45,11 @@ public class ShardedDOMDataBrokerAdapter implements DOMDataBroker {
         return new ShardedDOMWriteTransactionAdapter(newTransactionIdentifier(), service);
     }
 
+    @Override
+    public DOMDataTreeReadWriteTransaction newReadWriteTransaction() {
+        return new ShardedDOMReadWriteTransactionAdapter(newTransactionIdentifier(), service);
+    }
+
     @Override
     public DOMTransactionChain createTransactionChain(final TransactionChainListener listener) {
         return new ShardedDOMTransactionChainAdapter(newChainIdentifier(), service, listener);
@@ -56,5 +62,4 @@ public class ShardedDOMDataBrokerAdapter implements DOMDataBroker {
     private Object newChainIdentifier() {
         return "DOM-CHAIN-" + chainNum;
     }
-
 }
diff --git a/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/ShardedDOMReadWriteTransactionAdapter.java b/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/ShardedDOMReadWriteTransactionAdapter.java
new file mode 100644 (file)
index 0000000..0c95814
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017 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.mdsal.dom.broker;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.common.api.ReadFailedException;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public class ShardedDOMReadWriteTransactionAdapter extends ShardedDOMWriteTransactionAdapter
+        implements DOMDataTreeReadWriteTransaction {
+
+    private final ShardedDOMReadTransactionAdapter readAdapter;
+
+    ShardedDOMReadWriteTransactionAdapter(Object identifier, DOMDataTreeService transactionDelegator) {
+        super(identifier, transactionDelegator);
+        readAdapter = new ShardedDOMReadTransactionAdapter(identifier, transactionDelegator);
+    }
+
+    @Override
+    public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(LogicalDatastoreType store,
+            YangInstanceIdentifier path) {
+        return readAdapter.read(store, path);
+    }
+
+    @Override
+    public CheckedFuture<Boolean, ReadFailedException> exists(LogicalDatastoreType store, YangInstanceIdentifier path) {
+        return readAdapter.exists(store, path);
+    }
+
+    @Override
+    public void close() {
+        readAdapter.close();
+    }
+
+    ShardedDOMReadTransactionAdapter getReadAdapter() {
+        return readAdapter;
+    }
+}
index 8d38f863c23b78f7bd7562bd0b67c6d818340b34..f08aa2a78b58a1e30ed407c9b0be4e6b2c80b62c 100644 (file)
@@ -30,6 +30,7 @@ import org.opendaylight.mdsal.dom.api.DOMDataTreeLoopException;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeProducer;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeProducerException;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeService;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
 import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
@@ -82,6 +83,20 @@ public class ShardedDOMTransactionChainAdapter implements DOMTransactionChain {
         return writeTx;
     }
 
+    @Override
+    public DOMDataTreeReadWriteTransaction newReadWriteTransaction() {
+        checkRunning();
+        checkWriteTxClosed();
+        checkReadTxClosed();
+        ShardedDOMReadWriteTransactionAdapter adapter = new ShardedDOMReadWriteTransactionAdapter(
+                newTransactionIdentifier(), cachedDataTreeService);
+        TransactionChainReadWriteTransaction readWriteTx = new TransactionChainReadWriteTransaction(
+                newTransactionIdentifier(), adapter, adapter.getReadAdapter(), writeTxSubmitFuture, this);
+
+        writeTx = readWriteTx;
+        return readWriteTx;
+    }
+
     @Override
     public void close() {
         if (finished) {
diff --git a/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/TransactionChainReadWriteTransaction.java b/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/TransactionChainReadWriteTransaction.java
new file mode 100644 (file)
index 0000000..430b5dd
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017 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.mdsal.dom.broker;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.common.api.ReadFailedException;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+class TransactionChainReadWriteTransaction extends TransactionChainWriteTransaction
+        implements DOMDataTreeReadWriteTransaction {
+
+    private final TransactionChainReadTransaction readTx;
+
+    TransactionChainReadWriteTransaction(final Object identifier,
+            final DOMDataTreeReadWriteTransaction delegateWriteTx, final DOMDataTreeReadTransaction delegateReadTx,
+            final ListenableFuture<Void> previousWriteTxFuture, final ShardedDOMTransactionChainAdapter txChain) {
+        super(identifier, delegateWriteTx, txChain);
+        readTx = new TransactionChainReadTransaction(identifier, delegateReadTx, previousWriteTxFuture, txChain);
+    }
+
+    @Override
+    public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(LogicalDatastoreType store,
+            YangInstanceIdentifier path) {
+        return readTx.read(store, path);
+    }
+
+    @Override
+    public CheckedFuture<Boolean, ReadFailedException> exists(LogicalDatastoreType store, YangInstanceIdentifier path) {
+        return readTx.exists(store, path);
+    }
+
+    @Override
+    public void close() {
+    }
+}
index 5048f98901bdb56fa718772423a2abf10d29a71d..915f4547bd06ab9723f0e73fff3cabfa516d4b79 100644 (file)
@@ -14,6 +14,7 @@ import org.opendaylight.mdsal.common.api.TransactionChainListener;
 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
 import org.opendaylight.mdsal.dom.api.DOMDataBrokerExtension;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
 import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
 
@@ -37,6 +38,11 @@ public abstract class ForwardingDOMDataBroker extends ForwardingObject implement
         return delegate().newWriteOnlyTransaction();
     }
 
+    @Override
+    public DOMDataTreeReadWriteTransaction newReadWriteTransaction() {
+        return delegate().newReadWriteTransaction();
+    }
+
     @Override
     public DOMTransactionChain createTransactionChain(final TransactionChainListener listener) {
         return delegate().createTransactionChain(listener);
index a66bc0a83ec926b9e128e621892715aa4ee82732..8e1d9b8e57a798859f139858bf5dd5c433238b9e 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.mdsal.dom.spi;
 import com.google.common.collect.ForwardingObject;
 import javax.annotation.Nonnull;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
 import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
 
@@ -36,4 +37,9 @@ public abstract class ForwardingDOMTransactionChain extends ForwardingObject imp
     public DOMDataTreeWriteTransaction newWriteOnlyTransaction() {
         return delegate().newWriteOnlyTransaction();
     }
+
+    @Override
+    public DOMDataTreeReadWriteTransaction newReadWriteTransaction() {
+        return delegate().newReadWriteTransaction();
+    }
 }
index 82ab02ee22b3e7496539638713e233ae08447306..14d7c7a96c20e58a4bad66c1b6458903a1dfa3a4 100644 (file)
@@ -44,4 +44,4 @@ public class ForwardingDOMTransactionChainTest extends ForwardingDOMTransactionC
     protected DOMTransactionChain delegate() {
         return domTransactionChain;
     }
-}
\ No newline at end of file
+}