f48667b04f21bea53606c043f3f5bc06c2476df5
[controller.git] / opendaylight / md-sal / sal-dom-broker / src / main / java / org / opendaylight / controller / md / sal / dom / broker / impl / 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.controller.md.sal.dom.broker.impl;
9
10 import com.google.common.base.Preconditions;
11 import com.google.common.collect.ImmutableMap;
12 import java.util.EnumMap;
13 import java.util.Map;
14 import java.util.Map.Entry;
15 import javax.annotation.concurrent.GuardedBy;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
18 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
19 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
20 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
21 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
22 import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionFactory;
23 import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
24
25 /**
26  *
27  * Abstract composite transaction factory.
28  *
29  * Provides an convenience common implementation for composite DOM Transactions,
30  * where subtransaction is identified by {@link LogicalDatastoreType} type and
31  * implementation of subtransaction is provided by
32  * {@link DOMStoreTransactionFactory}.
33  *
34  * <b>Note:</b>This class does not have thread-safe implementation of  {@link #close()},
35  *   implementation may allow accessing and allocating new transactions during closing
36  *   this instance.
37  *
38  * @param <T>
39  *            Type of {@link DOMStoreTransactionFactory} factory.
40  */
41 public abstract class AbstractDOMForwardedTransactionFactory<T extends DOMStoreTransactionFactory> implements DOMDataCommitImplementation, AutoCloseable {
42
43     private final Map<LogicalDatastoreType, T> storeTxFactories;
44
45     private boolean closed;
46
47     protected AbstractDOMForwardedTransactionFactory(final Map<LogicalDatastoreType, ? extends T> txFactories) {
48         this.storeTxFactories = ImmutableMap.copyOf(txFactories);
49     }
50
51     /**
52      * Implementations must return unique identifier for each and every call of
53      * this method;
54      *
55      * @return new Unique transaction identifier.
56      */
57     protected abstract Object newTransactionIdentifier();
58
59     /**
60      * Creates a new composite read-only transaction
61      *
62      * Creates a new composite read-only transaction backed by one transaction
63      * per factory in {@link #getTxFactories()}.
64      *
65      * Subtransaction for reading is selected by supplied
66      * {@link LogicalDatastoreType} as parameter for
67      * {@link DOMDataReadOnlyTransaction#read(LogicalDatastoreType,org.opendaylight.yangtools.yang.data.api.InstanceIdentifier)}
68      * .
69      *
70      * Id of returned transaction is retrieved via
71      * {@link #newTransactionIdentifier()}.
72      *
73      * @return New composite read-only transaction.
74      */
75     public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
76         checkNotClosed();
77
78         final Map<LogicalDatastoreType, DOMStoreReadTransaction> txns = new EnumMap<>(LogicalDatastoreType.class);
79         for (Entry<LogicalDatastoreType, T> store : storeTxFactories.entrySet()) {
80             txns.put(store.getKey(), store.getValue().newReadOnlyTransaction());
81         }
82         return new DOMForwardedReadOnlyTransaction(newTransactionIdentifier(), txns);
83     }
84
85
86
87     /**
88      * Creates a new composite write-only transaction
89      *
90      * <p>
91      * Creates a new composite write-only transaction backed by one write-only
92      * transaction per factory in {@link #getTxFactories()}.
93      *
94      * <p>
95      * Implementation of composite Write-only transaction is following:
96      *
97      * <ul>
98      * <li>
99      * {@link DOMDataWriteTransaction#put(LogicalDatastoreType, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)}
100      * - backing subtransaction is selected by {@link LogicalDatastoreType},
101      * {@link DOMStoreWriteTransaction#write(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)}
102      * is invoked on selected subtransaction.
103      * <li>
104      * {@link DOMDataWriteTransaction#merge(LogicalDatastoreType, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)}
105      * - backing subtransaction is selected by {@link LogicalDatastoreType},
106      * {@link DOMStoreWriteTransaction#merge(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)}
107      * is invoked on selected subtransaction.
108      * <li>
109      * {@link DOMDataWriteTransaction#delete(LogicalDatastoreType, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier)
110      * - backing subtransaction is selected by {@link LogicalDatastoreType},
111      * {@link DOMStoreWriteTransaction#delete(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier)} is invoked on
112      * selected subtransaction.
113      * <li> {@link DOMDataWriteTransaction#commit()} - results in invoking
114      * {@link DOMStoreWriteTransaction#ready()}, gathering all resulting cohorts
115      * and then invoking finalized implementation callback
116      * {@link #submit(DOMDataWriteTransaction, Iterable)} with transaction which
117      * was commited and gathered results.
118      * </ul>
119      *
120      * Id of returned transaction is generated via
121      * {@link #newTransactionIdentifier()}.
122      *
123      * @return New composite write-only transaction associated with this
124      *         factory.
125      */
126     public DOMDataWriteTransaction newWriteOnlyTransaction() {
127         checkNotClosed();
128
129         final Map<LogicalDatastoreType, DOMStoreWriteTransaction> txns = new EnumMap<>(LogicalDatastoreType.class);
130         for (Entry<LogicalDatastoreType, T> store : storeTxFactories.entrySet()) {
131             txns.put(store.getKey(), store.getValue().newWriteOnlyTransaction());
132         }
133         return new DOMForwardedWriteTransaction<DOMStoreWriteTransaction>(newTransactionIdentifier(), txns, this);
134     }
135
136     /**
137      * Creates a new composite write-only transaction
138      *
139      * <p>
140      * Creates a new composite write-only transaction backed by one write-only
141      * transaction per factory in {@link #getTxFactories()}.
142      * <p>
143      * Implementation of composite Write-only transaction is following:
144      *
145      * <ul>
146      * <li>
147      * {@link DOMDataWriteTransaction#read(LogicalDatastoreType, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier)}
148      * - backing subtransaction is selected by {@link LogicalDatastoreType},
149      * {@link DOMStoreWriteTransaction#read(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier)} is invoked on
150      * selected subtransaction.
151      * <li>
152      * {@link DOMDataWriteTransaction#put(LogicalDatastoreType, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)}
153      * - backing subtransaction is selected by {@link LogicalDatastoreType},
154      * {@link DOMStoreWriteTransaction#write(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)}
155      * is invoked on selected subtransaction.
156      * <li>
157      * {@link DOMDataWriteTransaction#merge(LogicalDatastoreType, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)}
158      * - backing subtransaction is selected by {@link LogicalDatastoreType},
159      * {@link DOMStoreWriteTransaction#merge(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode)}
160      * is invoked on selected subtransaction.
161      * <li>
162      * {@link DOMDataWriteTransaction#delete(LogicalDatastoreType, org.opendaylight.yangtools.yang.data.api.InstanceIdentifier)
163      * - backing subtransaction is selected by {@link LogicalDatastoreType},
164      * {@link DOMStoreWriteTransaction#delete(org.opendaylight.yangtools.yang.data.api.InstanceIdentifier)} is invoked on
165      * selected subtransaction.
166      * <li> {@link DOMDataWriteTransaction#commit()} - results in invoking
167      * {@link DOMStoreWriteTransaction#ready()}, gathering all resulting cohorts
168      * and then invoking finalized implementation callback
169      * {@link #submit(DOMDataWriteTransaction, Iterable)} with transaction which
170      * was commited and gathered results.
171      * <li>
172      * </ul>
173      *
174      * Id of returned transaction is generated via
175      * {@link #newTransactionIdentifier()}.
176      *
177      * @return New composite read-write transaction associated with this
178      *         factory.
179      *
180      */
181     public DOMDataReadWriteTransaction newReadWriteTransaction() {
182         checkNotClosed();
183
184         final Map<LogicalDatastoreType, DOMStoreReadWriteTransaction> txns = new EnumMap<>(LogicalDatastoreType.class);
185         for (Entry<LogicalDatastoreType, T> store : storeTxFactories.entrySet()) {
186             txns.put(store.getKey(), store.getValue().newReadWriteTransaction());
187         }
188         return new DOMForwardedReadWriteTransaction(newTransactionIdentifier(), txns, this);
189     }
190
191     /**
192      * Convenience accessor of backing factories intended to be used only by
193      * finalization of this class.
194      *
195      * <b>Note:</b>
196      * Finalization of this class may want to access other functionality of
197      * supplied Transaction factories.
198      *
199      * @return Map of backing transaction factories.
200      */
201     protected final Map<LogicalDatastoreType, T> getTxFactories() {
202         return storeTxFactories;
203     }
204
205     /**
206      *
207      * Checks if instance is not closed.
208      *
209      * @throws IllegalStateException If instance of this class was closed.
210      *
211      */
212     @GuardedBy("this")
213     protected synchronized void checkNotClosed() {
214         Preconditions.checkState(!closed,"Transaction factory was closed. No further operations allowed.");
215     }
216
217     @Override
218     @GuardedBy("this")
219     public synchronized void close() {
220         closed = true;
221     }
222
223 }