public interface BindingDataBroker extends AsyncDataBroker<InstanceIdentifier<?>, DataObject, BindingDataChangeListener>, BindingService {
@Override
- BindingDataReadTransaction newReadOnlyTransaction();
+ BindingDataReadOnlyTransaction newReadOnlyTransaction();
@Override
BindingDataReadWriteTransaction newReadWriteTransaction();
--- /dev/null
+/*
+ * 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.api;
+
+import org.opendaylight.controller.md.sal.common.api.data.AsyncReadOnlyTransaction;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public interface BindingDataReadOnlyTransaction extends BindingDataReadTransaction, AsyncReadOnlyTransaction<InstanceIdentifier<?>, DataObject> {
+
+}
return writeTransaction.commit();
}
- protected void doCancel(final DOMDataWriteTransaction writeTransaction) {
- writeTransaction.cancel();
+ protected boolean doCancel(final DOMDataWriteTransaction writeTransaction) {
+ return writeTransaction.cancel();
}
protected ListenableFuture<Optional<DataObject>> doRead(final DOMDataReadTransaction readTransaction,
package org.opendaylight.controller.md.sal.binding.impl;
import org.opendaylight.controller.md.sal.binding.api.BindingDataBroker;
-import org.opendaylight.controller.md.sal.binding.api.BindingDataReadTransaction;
+import org.opendaylight.controller.md.sal.binding.api.BindingDataReadOnlyTransaction;
import org.opendaylight.controller.md.sal.binding.api.BindingDataReadWriteTransaction;
import org.opendaylight.controller.md.sal.binding.api.BindingDataWriteTransaction;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
+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.sal.core.api.model.SchemaService;
}
@Override
- public BindingDataReadTransaction newReadOnlyTransaction() {
+ public BindingDataReadOnlyTransaction newReadOnlyTransaction() {
return new BindingDataReadTransactionImpl(getDelegate().newReadOnlyTransaction(),getCodec());
}
return getDelegate().getIdentifier();
}
- @Override
- public void close() {
- getDelegate().close();
- }
-
}
- private class BindingDataReadTransactionImpl extends AbstractBindingTransaction<DOMDataReadTransaction> implements
- BindingDataReadTransaction {
+ private class BindingDataReadTransactionImpl extends AbstractBindingTransaction<DOMDataReadOnlyTransaction> implements
+ BindingDataReadOnlyTransaction {
- protected BindingDataReadTransactionImpl(final DOMDataReadTransaction delegate,
+ protected BindingDataReadTransactionImpl(final DOMDataReadOnlyTransaction delegate,
final BindingToNormalizedNodeCodec codec) {
super(delegate, codec);
}
final InstanceIdentifier<?> path) {
return doRead(getDelegate(), store, path);
}
+
+ @Override
+ public void close() {
+ getDelegate().close();
+ }
}
private class BindingDataWriteTransactionImpl<T extends DOMDataWriteTransaction> extends
}
@Override
- public void cancel() {
- doCancel(getDelegate());
+ public boolean cancel() {
+ return doCancel(getDelegate());
}
@Override
import org.junit.Test;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.store.rev140422.Lists;
private NormalizedNode<?, ?> resolveDataAsserted(
final org.opendaylight.yangtools.yang.data.api.InstanceIdentifier domPath) {
- try (DOMDataReadTransaction readTx = testContext.getDomAsyncDataBroker().newReadOnlyTransaction()){
+ try (DOMDataReadOnlyTransaction readTx = testContext.getDomAsyncDataBroker().newReadOnlyTransaction()){
ListenableFuture<Optional<NormalizedNode<?, ?>>> data = readTx.read(LogicalDatastoreType.OPERATIONAL, domPath);
Optional<NormalizedNode<?, ?>> potential = data.get();
assertTrue(potential.isPresent());
* {@inheritDoc}
*/
@Override
- public AsyncReadTransaction<P, D> newReadOnlyTransaction();
+ public AsyncReadOnlyTransaction<P, D> newReadOnlyTransaction();
/**
* {@inheritDoc}
*
* @return new read-only transaction
*/
- AsyncReadTransaction<P, D> newReadOnlyTransaction();
+ AsyncReadOnlyTransaction<P, D> newReadOnlyTransaction();
/**
* Allocates new read-write transaction which provides a mutable view of the data
--- /dev/null
+/*
+ * 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.common.api.data;
+
+import org.opendaylight.yangtools.concepts.Path;
+
+/**
+ * Read-only transaction, which provides stable view of data
+ * and is {@link AutoCloseable} resource.
+ *
+ * @see AsyncReadTransaction
+ *
+* @param <P>
+ * Type of path (subtree identifier), which represents location in
+ * tree
+ * @param <D>
+ * Type of data (payload), which represents data payload
+ */
+public interface AsyncReadOnlyTransaction<P extends Path<P>, D> extends AsyncReadTransaction<P, D>, AutoCloseable {
+
+ /**
+ * Closes transaction and releases all resources associated with it.
+ *
+ */
+ @Override
+ public void close();
+}
/**
*
- * Provides a stateful read-only view of the data tree.
+ * Provides a stateful read view of the data tree.
*
* <p>
* View of the data tree is a stable point-in-time snapshot of the current data tree state when
* @param <D> Type of data (payload), which represents data payload
*/
public interface AsyncTransaction<P extends Path<P>,D> extends //
- Identifiable<Object>,
- AutoCloseable {
+ Identifiable<Object> {
@Override
public Object getIdentifier();
- /**
- * Closes transaction and releases all resources associated with it.
- */
- @Override
- public void close();
+
}
* {@link TransactionStatus#NEW} or {@link TransactionStatus#SUBMITED}
*
* Invoking cancel() on {@link TransactionStatus#FAILED} or
- * {@link TransactionStatus#CANCELED} will have no effect.
+ * {@link TransactionStatus#CANCELED} will have no effect, and transaction
+ * is considered cancelled.
*
- * @throws IllegalStateException
- * If transaction status is {@link TransactionStatus#COMMITED}
+ * Invoking cancel() on finished transaction (future returned by {@link #commit()}
+ * already completed with {@link TransactionStatus#COMMITED}) will always
+ * fail (return false).
+ *
+ * @return <tt>false</tt> if the task could not be cancelled,
+ * typically because it has already completed normally;
+ * <tt>true</tt> otherwise
*
*/
- public void cancel();
+ public boolean cancel();
/**
* Store a piece of data at specified path. This acts as an add / replace
*/
public void delete(LogicalDatastoreType store, P path);
- /**
- *
- * Closes transaction and resources allocated to the transaction.
- *
- * This call does not change Transaction status. Client SHOULD explicitly
- * {@link #commit()} or {@link #cancel()} transaction.
- *
- * @throws IllegalStateException
- * if the transaction has not been updated by invoking
- * {@link #commit()} or {@link #cancel()}.
- */
- @Override
- public void close();
-
/**
* Submits transaction to be applied to update logical data tree.
* <p>
* @throws TransactionChainClosedException if the chain has been closed.
*/
@Override
- public AsyncReadTransaction<P, D> newReadOnlyTransaction();
+ public AsyncReadOnlyTransaction<P, D> newReadOnlyTransaction();
/**
* {@inheritDoc}
*/
@Override
- DOMDataReadTransaction newReadOnlyTransaction();
+ DOMDataReadOnlyTransaction newReadOnlyTransaction();
/**
* {@inheritDoc}
--- /dev/null
+package org.opendaylight.controller.md.sal.dom.api;
+
+import org.opendaylight.controller.md.sal.common.api.data.AsyncReadOnlyTransaction;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public interface DOMDataReadOnlyTransaction extends DOMDataReadTransaction, AsyncReadOnlyTransaction<InstanceIdentifier, NormalizedNode<?, ?>> {
+
+}
public interface DOMTransactionChain extends TransactionChain<InstanceIdentifier, NormalizedNode<?, ?>> {
@Override
- DOMDataReadTransaction newReadOnlyTransaction();
+ DOMDataReadOnlyTransaction newReadOnlyTransaction();
@Override
DOMDataReadWriteTransaction newReadWriteTransaction();
return identifier;
}
- @Override
- public void close() {
+ protected void closeSubtransactions() {
/*
* We share one exception for all failures, which are added
* as supressedExceptions to it.
import javax.annotation.concurrent.GuardedBy;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
+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.sal.core.spi.data.DOMStoreReadTransaction;
*
* Subtransaction for reading is selected by supplied
* {@link LogicalDatastoreType} as parameter for
- * {@link DOMDataReadTransaction#read(LogicalDatastoreType,org.opendaylight.yangtools.yang.data.api.InstanceIdentifier)}
+ * {@link DOMDataReadOnlyTransaction#read(LogicalDatastoreType,org.opendaylight.yangtools.yang.data.api.InstanceIdentifier)}
* .
*
* Id of returned transaction is retrieved via
*
* @return New composite read-only transaction.
*/
- public DOMDataReadTransaction newReadOnlyTransaction() {
+ public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
checkNotClosed();
ImmutableMap.Builder<LogicalDatastoreType, DOMStoreReadTransaction> builder = ImmutableMap.builder();
for (Entry<LogicalDatastoreType, T> store : storeTxFactories.entrySet()) {
package org.opendaylight.controller.md.sal.dom.broker.impl;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
*/
class DOMForwardedReadOnlyTransaction extends
AbstractDOMForwardedCompositeTransaction<LogicalDatastoreType, DOMStoreReadTransaction> implements
- DOMDataReadTransaction {
+ DOMDataReadOnlyTransaction {
protected DOMForwardedReadOnlyTransaction(final Object identifier,
final ImmutableMap<LogicalDatastoreType, DOMStoreReadTransaction> backingTxs) {
return getSubtransaction(store).read(path);
}
+ @Override
+ public void close() {
+ closeSubtransactions();
+ }
+
}
class DOMForwardedWriteTransaction<T extends DOMStoreWriteTransaction> extends
AbstractDOMForwardedCompositeTransaction<LogicalDatastoreType, T> implements DOMDataWriteTransaction {
+ /**
+ * Implementation of real commit.
+ *
+ * Transaction can not be commited if commitImpl is null,
+ * so this seting this property to null is also used to
+ * prevent write to
+ * already commited / canceled transaction {@link #checkNotCanceled()
+ *
+ *
+ */
@GuardedBy("this")
- private DOMDataCommitImplementation commitImpl;
-
- @GuardedBy("this")
- private boolean canceled;
+ private volatile DOMDataCommitImplementation commitImpl;
+
+ /**
+ *
+ * Future task of transaction commit.
+ *
+ * This value is initially null, and is once updated if transaction
+ * is commited {@link #commit()}.
+ * If this future exists, transaction MUST not be commited again
+ * and all modifications should fail. See {@link #checkNotCommited()}.
+ *
+ */
@GuardedBy("this")
- private ListenableFuture<RpcResult<TransactionStatus>> commitFuture;
+ private volatile ListenableFuture<RpcResult<TransactionStatus>> commitFuture;
protected DOMForwardedWriteTransaction(final Object identifier,
final ImmutableMap<LogicalDatastoreType, T> backingTxs, final DOMDataCommitImplementation commitImpl) {
}
@Override
- public synchronized void cancel() {
- checkState(!canceled, "Transaction was canceled.");
- if (commitFuture != null) {
- // FIXME: Implement cancelation of commit future
- // when Broker impl will support cancelation.
- throw new UnsupportedOperationException("Not implemented yet.");
+ public synchronized boolean cancel() {
+ // Transaction is already canceled, we are safe to return true
+ final boolean cancelationResult;
+ if (commitImpl == null && commitFuture != null) {
+ // Transaction is submitted, we try to cancel future.
+ cancelationResult = commitFuture.cancel(false);
+ } else if(commitImpl == null) {
+ return true;
+ } else {
+ cancelationResult = true;
+ commitImpl = null;
}
- canceled = true;
- commitImpl = null;
+ return cancelationResult;
}
}
ImmutableList<DOMStoreThreePhaseCommitCohort> cohorts = cohortsBuilder.build();
commitFuture = commitImpl.commit(this, cohorts);
+
+ /*
+ *We remove reference to Commit Implementation in order
+ *to prevent memory leak
+ */
+ commitImpl = null;
return commitFuture;
}
private void checkNotReady() {
- checkNotCanceled();
checkNotCommited();
+ checkNotCanceled();
}
private void checkNotCanceled() {
- Preconditions.checkState(!canceled, "Transaction was canceled.");
+ Preconditions.checkState(commitImpl != null, "Transaction was canceled.");
}
private void checkNotCommited() {
- checkState(commitFuture == null, "Transaction was already commited.");
+ checkState(commitFuture == null, "Transaction was already submited.");
}
}
\ No newline at end of file
import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
this.normalizer = normalizer;
}
- public static BackwardsCompatibleTransaction<?> readOnlyTransaction(final DOMDataReadTransaction readTx,
+ public static BackwardsCompatibleTransaction<?> readOnlyTransaction(final DOMDataReadOnlyTransaction readTx,
final DataNormalizer normalizer) {
- return new BackwardsCompatibleTransaction<DOMDataReadTransaction>(readTx, normalizer) {
+ return new BackwardsCompatibleTransaction<DOMDataReadOnlyTransaction>(readTx, normalizer) {
@Override
public TransactionStatus getStatus() {
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.DOMDataChangeListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
+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;
}
@Override
- public DOMDataReadTransaction newReadOnlyTransaction() {
+ public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
return getDelegate().newReadOnlyTransaction();
}