Merge "Hook the Distributed Data store into the config sub-system"
[controller.git] / opendaylight / md-sal / sal-dom-broker / src / main / java / org / opendaylight / controller / md / sal / dom / broker / impl / DOMForwardedWriteTransaction.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.md.sal.dom.broker.impl;
9
10 import static com.google.common.base.Preconditions.checkState;
11
12 import javax.annotation.concurrent.GuardedBy;
13
14 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
17 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
18 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
19 import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
20 import org.opendaylight.yangtools.yang.common.RpcResult;
21 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
22 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
23
24 import com.google.common.base.Preconditions;
25 import com.google.common.collect.ImmutableList;
26 import com.google.common.collect.ImmutableMap;
27 import com.google.common.util.concurrent.ListenableFuture;
28
29 /**
30  * /**
31  * 
32  * Read-Write Transaction, which is composed of several
33  * {@link DOMStoreReadTransaction} transactions. Subtransaction is selected by
34  * {@link LogicalDatastoreType} type parameter in:
35  * 
36  * <ul>
37  * <li>{@link #put(LogicalDatastoreType, InstanceIdentifier, NormalizedNode)}
38  * <li>{@link #delete(LogicalDatastoreType, InstanceIdentifier)}
39  * <li>{@link #merge(LogicalDatastoreType, InstanceIdentifier, NormalizedNode)}
40  * </ul>
41  * <p>
42  * {@link #commit()} will result in invocation of
43  * {@link DOMDataCommitImplementation#commit(org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction, Iterable)}
44  * invocation with all {@link DOMStoreThreePhaseCommitCohort} for underlying
45  * transactions.
46  * 
47  * @param <T>
48  *            Subtype of {@link DOMStoreWriteTransaction} which is used as
49  *            subtransaction.
50  */
51 class DOMForwardedWriteTransaction<T extends DOMStoreWriteTransaction> extends
52         AbstractDOMForwardedCompositeTransaction<LogicalDatastoreType, T> implements DOMDataWriteTransaction {
53
54     @GuardedBy("this")
55     private DOMDataCommitImplementation commitImpl;
56
57     @GuardedBy("this")
58     private boolean canceled;
59     @GuardedBy("this")
60     private ListenableFuture<RpcResult<TransactionStatus>> commitFuture;
61
62     protected DOMForwardedWriteTransaction(final Object identifier,
63             final ImmutableMap<LogicalDatastoreType, T> backingTxs, final DOMDataCommitImplementation commitImpl) {
64         super(identifier, backingTxs);
65         this.commitImpl = Preconditions.checkNotNull(commitImpl, "commitImpl must not be null.");
66     }
67
68     @Override
69     public void put(final LogicalDatastoreType store, final InstanceIdentifier path, final NormalizedNode<?, ?> data) {
70         checkNotReady();
71         getSubtransaction(store).write(path, data);
72     }
73
74     @Override
75     public void delete(final LogicalDatastoreType store, final InstanceIdentifier path) {
76         checkNotReady();
77         getSubtransaction(store).delete(path);
78     }
79
80     @Override
81     public void merge(final LogicalDatastoreType store, final InstanceIdentifier path, final NormalizedNode<?, ?> data) {
82         checkNotReady();
83         getSubtransaction(store).merge(path, data);
84     }
85
86     @Override
87     public synchronized void cancel() {
88         checkState(!canceled, "Transaction was canceled.");
89         if (commitFuture != null) {
90             // FIXME: Implement cancelation of commit future
91             // when Broker impl will support cancelation.
92             throw new UnsupportedOperationException("Not implemented yet.");
93         }
94         canceled = true;
95         commitImpl = null;
96
97     }
98
99     @Override
100     public synchronized ListenableFuture<RpcResult<TransactionStatus>> commit() {
101         checkNotReady();
102
103         ImmutableList.Builder<DOMStoreThreePhaseCommitCohort> cohortsBuilder = ImmutableList.builder();
104         for (DOMStoreWriteTransaction subTx : getSubtransactions()) {
105             cohortsBuilder.add(subTx.ready());
106         }
107         ImmutableList<DOMStoreThreePhaseCommitCohort> cohorts = cohortsBuilder.build();
108         commitFuture = commitImpl.commit(this, cohorts);
109         return commitFuture;
110     }
111
112     private void checkNotReady() {
113         checkNotCanceled();
114         checkNotCommited();
115     }
116
117     private void checkNotCanceled() {
118         Preconditions.checkState(!canceled, "Transaction was canceled.");
119     }
120
121     private void checkNotCommited() {
122         checkState(commitFuture == null, "Transaction was already commited.");
123     }
124
125 }