Bug 1073: Added Transaction Chain support to Binding transactions. 70/8370/3
authorTony Tkacik <ttkacik@cisco.com>
Mon, 23 Jun 2014 07:29:50 +0000 (09:29 +0200)
committerTony Tkacik <ttkacik@cisco.com>
Tue, 1 Jul 2014 11:04:14 +0000 (13:04 +0200)
Added Binding Aware version of Transaction Chain
which only forwards all calls to DOM Transction Chain
and uses BindingForwarded transactions as wrappers
on top of real DOM Forwarded transactions.

Change-Id: Icf10cb8525a3229c0f41c6141bf198111fa4b240
Signed-off-by: Tony Tkacik <ttkacik@cisco.com>
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/BindingTransactionChain.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataBroker.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingTranslatedTransactionChain.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedBindingDataBroker.java

diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/BindingTransactionChain.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/BindingTransactionChain.java
new file mode 100644 (file)
index 0000000..eac65ad
--- /dev/null
@@ -0,0 +1,18 @@
+package org.opendaylight.controller.md.sal.binding.api;
+
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public interface BindingTransactionChain extends TransactionChain<InstanceIdentifier<?>, DataObject> {
+
+    @Override
+    ReadOnlyTransaction newReadOnlyTransaction();
+
+    @Override
+    ReadWriteTransaction newReadWriteTransaction();
+
+    @Override
+    WriteTransaction newWriteOnlyTransaction();
+
+}
index 0b3658a6a6b6e7b112fb89e0d9a0d1cc2ae5aa54..b60d8ff1be71ba7dc0e22a93f240445868241e10 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.controller.md.sal.binding.api;
 
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChainFactory;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -19,7 +20,7 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
  * <p>
  * For more information on usage, please see the documentation in {@link AsyncDataBroker}.
  */
  * <p>
  * For more information on usage, please see the documentation in {@link AsyncDataBroker}.
  */
-public interface DataBroker extends AsyncDataBroker<InstanceIdentifier<?>, DataObject, DataChangeListener>, BindingService {
+public interface DataBroker extends AsyncDataBroker<InstanceIdentifier<?>, DataObject, DataChangeListener>, BindingService, TransactionChainFactory<InstanceIdentifier<?>, DataObject> {
     @Override
     ReadOnlyTransaction newReadOnlyTransaction();
 
     @Override
     ReadOnlyTransaction newReadOnlyTransaction();
 
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingTranslatedTransactionChain.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingTranslatedTransactionChain.java
new file mode 100644 (file)
index 0000000..2d8e51c
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.impl;
+
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import javax.annotation.concurrent.GuardedBy;
+
+import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
+import org.opendaylight.yangtools.concepts.Delegator;
+
+import com.google.common.base.Preconditions;
+
+class BindingTranslatedTransactionChain implements BindingTransactionChain, Delegator<DOMTransactionChain> {
+
+    private final DOMTransactionChain delegate;
+
+    @GuardedBy("this")
+    private final Map<AsyncTransaction<?, ?>, AsyncTransaction<?, ?>> delegateTxToBindingTx = new WeakHashMap<>();
+    private final BindingToNormalizedNodeCodec codec;
+
+    public BindingTranslatedTransactionChain(final DOMDataBroker chainFactory,
+            final BindingToNormalizedNodeCodec codec, final TransactionChainListener listener) {
+        Preconditions.checkNotNull(chainFactory, "DOM Transaction chain factory must not be null");
+        this.delegate = chainFactory.createTransactionChain(new ListenerInvoker(listener));
+        this.codec = codec;
+    }
+
+    @Override
+    public DOMTransactionChain getDelegate() {
+        return delegate;
+    }
+
+    @Override
+    public ReadOnlyTransaction newReadOnlyTransaction() {
+        DOMDataReadOnlyTransaction delegateTx = delegate.newReadOnlyTransaction();
+        ReadOnlyTransaction bindingTx = new BindingDataReadTransactionImpl(delegateTx, codec);
+        putDelegateToBinding(delegateTx, bindingTx);
+        return bindingTx;
+    }
+
+    @Override
+    public ReadWriteTransaction newReadWriteTransaction() {
+        DOMDataReadWriteTransaction delegateTx = delegate.newReadWriteTransaction();
+        ReadWriteTransaction bindingTx = new BindingDataReadWriteTransactionImpl(delegateTx, codec);
+        putDelegateToBinding(delegateTx, bindingTx);
+        return bindingTx;
+    }
+
+    @Override
+    public WriteTransaction newWriteOnlyTransaction() {
+        DOMDataWriteTransaction delegateTx = delegate.newWriteOnlyTransaction();
+        WriteTransaction bindingTx = new BindingDataWriteTransactionImpl<>(delegateTx, codec);
+        putDelegateToBinding(delegateTx, bindingTx);
+        return bindingTx;
+    }
+
+    @Override
+    public void close() {
+        delegate.close();
+    }
+
+    private synchronized void putDelegateToBinding(final AsyncTransaction<?, ?> domTx,
+            final AsyncTransaction<?, ?> bindingTx) {
+        final Object previous = delegateTxToBindingTx.put(domTx, bindingTx);
+        Preconditions.checkState(previous == null, "DOM Transaction %s has already associated binding transation %s",domTx,previous);
+    }
+
+    private synchronized AsyncTransaction<?, ?> getBindingTransaction(final AsyncTransaction<?, ?> transaction) {
+        return delegateTxToBindingTx.get(transaction);
+    }
+
+    private final class ListenerInvoker implements TransactionChainListener {
+
+        private final TransactionChainListener listener;
+
+        public ListenerInvoker(final TransactionChainListener listener) {
+            this.listener = Preconditions.checkNotNull(listener, "Listener must not be null.");
+        }
+
+        @Override
+        public void onTransactionChainFailed(final TransactionChain<?, ?> chain,
+                final AsyncTransaction<?, ?> transaction, final Throwable cause) {
+            Preconditions.checkState(delegate.equals(chain),
+                    "Illegal state - listener for %s was invoked for incorrect chain %s.", delegate, chain);
+            AsyncTransaction<?, ?> bindingTx = getBindingTransaction(transaction);
+            listener.onTransactionChainFailed(chain, bindingTx, cause);
+        }
+
+        @Override
+        public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
+            Preconditions.checkState(delegate.equals(chain),
+                    "Illegal state - listener for %s was invoked for incorrect chain %s.", delegate, chain);
+            listener.onTransactionChainSuccessful(BindingTranslatedTransactionChain.this);
+        }
+    }
+
+}
index c8794cdc892d08e259e6ecfa3da6bcc8a736a8dc..6359b60684ef45e18d2185d1231b14b165497724 100644 (file)
@@ -8,10 +8,12 @@
 package org.opendaylight.controller.md.sal.binding.impl;
 
 
 package org.opendaylight.controller.md.sal.binding.impl;
 
 
+import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.yangtools.yang.data.impl.codec.BindingIndependentMappingService;
@@ -47,4 +49,9 @@ public class ForwardedBindingDataBroker extends AbstractForwardedDataBroker impl
     public WriteTransaction newWriteOnlyTransaction() {
         return new BindingDataWriteTransactionImpl<>(getDelegate().newWriteOnlyTransaction(),getCodec());
     }
     public WriteTransaction newWriteOnlyTransaction() {
         return new BindingDataWriteTransactionImpl<>(getDelegate().newWriteOnlyTransaction(),getCodec());
     }
+
+    @Override
+    public BindingTransactionChain createTransactionChain(final TransactionChainListener listener) {
+        return new BindingTranslatedTransactionChain(getDelegate(), getCodec(), listener);
+    }
 }
 }