From: Tony Tkacik Date: Mon, 23 Jun 2014 07:29:50 +0000 (+0200) Subject: Bug 1073: Added Transaction Chain support to Binding transactions. X-Git-Tag: release/helium~570^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=747057973fbd40d1e84d6608c0dc51cb1683f697 Bug 1073: Added Transaction Chain support to Binding transactions. 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 --- 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 index 0000000000..eac65ad677 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/BindingTransactionChain.java @@ -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, DataObject> { + + @Override + ReadOnlyTransaction newReadOnlyTransaction(); + + @Override + ReadWriteTransaction newReadWriteTransaction(); + + @Override + WriteTransaction newWriteOnlyTransaction(); + +} diff --git a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataBroker.java b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataBroker.java index 0b3658a6a6..b60d8ff1be 100644 --- a/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataBroker.java +++ b/opendaylight/md-sal/sal-binding-api/src/main/java/org/opendaylight/controller/md/sal/binding/api/DataBroker.java @@ -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.TransactionChainFactory; 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; *

* For more information on usage, please see the documentation in {@link AsyncDataBroker}. */ -public interface DataBroker extends AsyncDataBroker, DataObject, DataChangeListener>, BindingService { +public interface DataBroker extends AsyncDataBroker, DataObject, DataChangeListener>, BindingService, TransactionChainFactory, DataObject> { @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 index 0000000000..2d8e51cff9 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/BindingTranslatedTransactionChain.java @@ -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 { + + private final DOMTransactionChain delegate; + + @GuardedBy("this") + private final Map, 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); + } + } + +} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedBindingDataBroker.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedBindingDataBroker.java index c8794cdc89..6359b60684 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedBindingDataBroker.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/ForwardedBindingDataBroker.java @@ -8,10 +8,12 @@ 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.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; @@ -47,4 +49,9 @@ public class ForwardedBindingDataBroker extends AbstractForwardedDataBroker impl public WriteTransaction newWriteOnlyTransaction() { return new BindingDataWriteTransactionImpl<>(getDelegate().newWriteOnlyTransaction(),getCodec()); } + + @Override + public BindingTransactionChain createTransactionChain(final TransactionChainListener listener) { + return new BindingTranslatedTransactionChain(getDelegate(), getCodec(), listener); + } }