checkStyleViolationSeverity=error implemented for mdsal-dom-broker
[mdsal.git] / dom / mdsal-dom-broker / src / main / java / org / opendaylight / mdsal / dom / broker / AbstractDOMForwardedTransactionFactory.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.mdsal.dom.broker;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.util.concurrent.CheckedFuture;
12 import java.util.Collection;
13 import java.util.EnumMap;
14 import java.util.Map;
15 import java.util.Map.Entry;
16 import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
17 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
18 import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
19 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
20 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
21 import org.opendaylight.mdsal.dom.spi.store.DOMStoreReadTransaction;
22 import org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort;
23 import org.opendaylight.mdsal.dom.spi.store.DOMStoreTransactionFactory;
24 import org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction;
25
26 /**
27  * Abstract composite transaction factory.
28  *
29  *<p>
30  * Provides an convenience common implementation for composite DOM Transactions,
31  * where subtransaction is identified by {@link LogicalDatastoreType} type and
32  * implementation of subtransaction is provided by
33  * {@link DOMStoreTransactionFactory}.
34  *
35  * <b>Note:</b>This class does not have thread-safe implementation of  {@link #close()},
36  *   implementation may allow accessing and allocating new transactions during closing
37  *   this instance.
38  *
39  * @param <T>
40  *            Type of {@link DOMStoreTransactionFactory} factory.
41  */
42 abstract class AbstractDOMForwardedTransactionFactory<T extends DOMStoreTransactionFactory> implements AutoCloseable {
43     @SuppressWarnings("rawtypes")
44     private static final AtomicIntegerFieldUpdater<AbstractDOMForwardedTransactionFactory> UPDATER =
45             AtomicIntegerFieldUpdater.newUpdater(AbstractDOMForwardedTransactionFactory.class, "closed");
46     private final Map<LogicalDatastoreType, T> storeTxFactories;
47     private volatile int closed = 0;
48
49     protected AbstractDOMForwardedTransactionFactory(final Map<LogicalDatastoreType, ? extends T> txFactories) {
50         this.storeTxFactories = new EnumMap<>(txFactories);
51     }
52
53     /**
54      * Implementations must return unique identifier for each and every call of
55      * this method.
56      *
57      * @return new Unique transaction identifier.
58      */
59     protected abstract Object newTransactionIdentifier();
60
61     /**
62      * User-supplied implementation of {@link DOMDataTreeWriteTransaction#submit()} for transaction.
63      *
64      *<p>
65      * Callback invoked when {@link DOMDataTreeWriteTransaction#submit()} is invoked on transaction
66      * created by this factory.
67      *
68      * @param transaction Transaction on which {@link DOMDataTreeWriteTransaction#submit()} was invoked.
69      * @param cohorts Iteratable of cohorts for subtransactions associated with the transaction
70      *        being committed.
71      * @return a CheckedFuture. if commit coordination on cohorts finished successfully, nothing is
72      *         returned from the Future, On failure, the Future fails with a
73      *         {@link TransactionCommitFailedException}.
74      */
75     protected abstract CheckedFuture<Void,TransactionCommitFailedException> submit(
76             final DOMDataTreeWriteTransaction transaction,
77             final Collection<DOMStoreThreePhaseCommitCohort> cohorts);
78
79     /**
80      * Creates a new composite read-only transaction.
81      *
82      *<p>
83      * Creates a new composite read-only transaction backed by one transaction per factory in
84      * {@link #getTxFactories()}.
85      *
86      *<p>
87      * Subtransaction for reading is selected by supplied {@link LogicalDatastoreType} as parameter
88      * for
89      * {@link DOMDataTreeReadTransaction#read(LogicalDatastoreType,
90      * org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier)}
91      *
92      *<p>
93      * Id of returned transaction is retrieved via {@link #newTransactionIdentifier()}.
94      *
95      * @return New composite read-only transaction.
96      */
97     public final DOMDataTreeReadTransaction newReadOnlyTransaction() {
98         checkNotClosed();
99
100         final Map<LogicalDatastoreType, DOMStoreReadTransaction> txns = new EnumMap<>(LogicalDatastoreType.class);
101         for (final Entry<LogicalDatastoreType, T> store : storeTxFactories.entrySet()) {
102             txns.put(store.getKey(), store.getValue().newReadOnlyTransaction());
103         }
104         return new DOMForwardedReadOnlyTransaction(newTransactionIdentifier(), txns);
105     }
106
107     /**
108      * Creates a new composite write-only transaction
109      *
110      * <p>
111      * Creates a new composite write-only transaction backed by one write-only transaction per
112      * factory in {@link #getTxFactories()}.
113      *
114      * <p>
115      * Implementation of composite Write-only transaction is following:
116      *
117      * <ul>
118      * <li>
119      * {@link DOMDataTreeWriteTransaction#put(LogicalDatastoreType,
120      * org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier,
121      * org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)}
122      * - backing subtransaction is selected by {@link LogicalDatastoreType},
123      * {@link DOMStoreWriteTransaction#write(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier,
124      * org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)}
125      * is invoked on selected subtransaction.</li>
126      * <li>
127      * {@link DOMDataTreeWriteTransaction#merge(LogicalDatastoreType,
128      * org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier,
129      * org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)}
130      * - backing subtransaction is selected by {@link LogicalDatastoreType},
131      * {@link DOMStoreWriteTransaction#merge(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier,
132      * org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)}
133      * is invoked on selected subtransaction.</li>
134      * <li>
135      * {@link DOMDataTreeWriteTransaction#delete(LogicalDatastoreType,
136      * org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier)}
137      * - backing subtransaction is selected by {@link LogicalDatastoreType},
138      * {@link DOMStoreWriteTransaction#delete(org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier)}
139      * is invoked on selected subtransaction.
140      * <li> {@link DOMDataTreeWriteTransaction#submit()} - results in invoking
141      * {@link DOMStoreWriteTransaction#ready()}, gathering all resulting cohorts and then invoking
142      * finalized implementation callback {@link #submit(DOMDataTreeWriteTransaction, Collection)} with
143      * transaction which was commited and gathered results.</li>
144      * </ul>
145      *
146      * <p>
147      * Id of returned transaction is generated via {@link #newTransactionIdentifier()}.
148      *
149      * @return New composite write-only transaction associated with this factory.
150      */
151     public final DOMDataTreeWriteTransaction newWriteOnlyTransaction() {
152         checkNotClosed();
153
154         final Map<LogicalDatastoreType, DOMStoreWriteTransaction> txns = new EnumMap<>(LogicalDatastoreType.class);
155         for (final Entry<LogicalDatastoreType, T> store : storeTxFactories.entrySet()) {
156             txns.put(store.getKey(), store.getValue().newWriteOnlyTransaction());
157         }
158         return new DOMForwardedWriteTransaction<DOMStoreWriteTransaction>(newTransactionIdentifier(), txns, this);
159     }
160
161     /**
162      * Convenience accessor of backing factories intended to be used only by
163      * finalization of this class.
164      *
165      * <b>Note:</b>
166      * Finalization of this class may want to access other functionality of
167      * supplied Transaction factories.
168      *
169      * @return Map of backing transaction factories.
170      */
171     protected final Map<LogicalDatastoreType, T> getTxFactories() {
172         return storeTxFactories;
173     }
174
175     /**
176      * Checks if instance is not closed.
177      *
178      * @throws IllegalStateException If instance of this class was closed.
179      *
180      */
181     protected final void checkNotClosed() {
182         Preconditions.checkState(closed == 0, "Transaction factory was closed. No further operations allowed.");
183     }
184
185     @Override
186     public void close() {
187         final boolean success = UPDATER.compareAndSet(this, 0, 1);
188         Preconditions.checkState(success, "Transaction factory was already closed");
189     }
190 }
191