1 package org.opendaylight.controller.md.sal.dom.broker.impl.compat;
3 import static com.google.common.base.Preconditions.checkNotNull;
5 import java.util.ArrayList;
6 import java.util.Collections;
7 import java.util.Iterator;
10 import java.util.Map.Entry;
12 import java.util.concurrent.ExecutionException;
13 import java.util.concurrent.Future;
15 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
18 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
19 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
20 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
21 import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
22 import org.opendaylight.yangtools.concepts.Delegator;
23 import org.opendaylight.yangtools.concepts.ListenerRegistration;
24 import org.opendaylight.yangtools.yang.common.RpcResult;
25 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
26 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
27 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
28 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
29 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
30 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
31 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
32 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
33 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
34 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
35 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
39 import com.google.common.base.Optional;
40 import com.google.common.base.Preconditions;
41 import com.google.common.collect.Iterables;
42 import com.google.common.util.concurrent.ListenableFuture;
44 public abstract class BackwardsCompatibleTransaction<T extends DOMDataReadTransaction> implements
45 DataModificationTransaction, Delegator<T> {
47 private static final Logger LOG = LoggerFactory.getLogger(BackwardsCompatibleTransaction.class);
49 private final T asyncTx;
50 private final DataNormalizer normalizer;
52 protected BackwardsCompatibleTransaction(final T asyncTx, final DataNormalizer normalizer) {
54 this.asyncTx = asyncTx;
55 this.normalizer = normalizer;
58 public static BackwardsCompatibleTransaction<?> readOnlyTransaction(final DOMDataReadTransaction readTx,
59 final DataNormalizer normalizer) {
61 return new BackwardsCompatibleTransaction<DOMDataReadTransaction>(readTx, normalizer) {
64 public TransactionStatus getStatus() {
65 return TransactionStatus.NEW;
69 public Future<RpcResult<TransactionStatus>> commit() {
70 getDelegate().close();
76 public static BackwardsCompatibleTransaction<?> readWriteTransaction(final DOMDataReadWriteTransaction rwTx,
77 final DataNormalizer normalizer) {
78 return new ReadWriteTransaction(rwTx, normalizer);
81 protected DataNormalizer getNormalizer() {
86 public T getDelegate() {
91 public CompositeNode readConfigurationData(final InstanceIdentifier legacyPath) {
93 InstanceIdentifier normalizedPath = normalizer.toNormalized(legacyPath);
95 ListenableFuture<Optional<NormalizedNode<?, ?>>> normalizedData = asyncTx.read(
96 LogicalDatastoreType.CONFIGURATION, normalizedPath);
99 return normalizer.toLegacy(normalizedPath, normalizedData.get().orNull());
100 } catch (InterruptedException | ExecutionException e) {
106 public CompositeNode readOperationalData(final InstanceIdentifier legacyPath) {
107 InstanceIdentifier normalizedPath = normalizer.toNormalized(legacyPath);
109 ListenableFuture<Optional<NormalizedNode<?, ?>>> normalizedData = asyncTx.read(
110 LogicalDatastoreType.OPERATIONAL, normalizedPath);
113 return normalizer.toLegacy(normalizedPath, normalizedData.get().orNull());
114 } catch (InterruptedException | ExecutionException e) {
120 public ListenerRegistration<DataTransactionListener> registerListener(final DataTransactionListener listener) {
121 throw new UnsupportedOperationException();
125 public Map<InstanceIdentifier, CompositeNode> getCreatedConfigurationData() {
126 return Collections.emptyMap();
130 public Map<InstanceIdentifier, CompositeNode> getCreatedOperationalData() {
131 return Collections.emptyMap();
135 public Map<InstanceIdentifier, CompositeNode> getOriginalConfigurationData() {
136 return Collections.emptyMap();
140 public Map<InstanceIdentifier, CompositeNode> getOriginalOperationalData() {
141 return Collections.emptyMap();
145 public Set<InstanceIdentifier> getRemovedConfigurationData() {
146 return Collections.emptySet();
150 public Set<InstanceIdentifier> getRemovedOperationalData() {
151 return Collections.emptySet();
155 public Map<InstanceIdentifier, CompositeNode> getUpdatedConfigurationData() {
156 return Collections.emptyMap();
160 public Map<InstanceIdentifier, CompositeNode> getUpdatedOperationalData() {
161 return Collections.emptyMap();
165 public void putConfigurationData(final InstanceIdentifier path, final CompositeNode data) {
166 throw new UnsupportedOperationException();
170 public void putOperationalData(final InstanceIdentifier path, final CompositeNode data) {
171 throw new UnsupportedOperationException();
175 public void removeConfigurationData(final InstanceIdentifier path) {
176 throw new UnsupportedOperationException();
180 public void removeOperationalData(final InstanceIdentifier path) {
181 throw new UnsupportedOperationException();
185 public Object getIdentifier() {
186 return asyncTx.getIdentifier();
189 private static final class ReadWriteTransaction extends BackwardsCompatibleTransaction<DOMDataReadWriteTransaction> {
191 private TransactionStatus status = TransactionStatus.NEW;
193 protected ReadWriteTransaction(final DOMDataReadWriteTransaction asyncTx, final DataNormalizer normalizer) {
194 super(asyncTx, normalizer);
198 public TransactionStatus getStatus() {
203 public Future<RpcResult<TransactionStatus>> commit() {
204 Preconditions.checkState(status == TransactionStatus.NEW);
205 status = TransactionStatus.SUBMITED;
206 return getDelegate().commit();
210 public void putConfigurationData(final InstanceIdentifier legacyPath, final CompositeNode legacyData) {
211 checkNotNull(legacyPath, "Path MUST NOT be null.");
212 checkNotNull(legacyData, "Data for path %s MUST NOT be null",legacyData);
213 Entry<InstanceIdentifier, NormalizedNode<?, ?>> normalizedData = getNormalizer().toNormalized(legacyPath, legacyData);
214 putWithEnsuredParents(LogicalDatastoreType.CONFIGURATION, normalizedData.getKey(), normalizedData.getValue());
218 public void putOperationalData(final InstanceIdentifier legacyPath, final CompositeNode legacyData) {
219 checkNotNull(legacyPath, "Path MUST NOT be null.");
220 checkNotNull(legacyData, "Data for path %s MUST NOT be null",legacyData);
221 Entry<InstanceIdentifier, NormalizedNode<?, ?>> normalizedData = getNormalizer().toNormalized(legacyPath, legacyData);
222 putWithEnsuredParents(LogicalDatastoreType.OPERATIONAL, normalizedData.getKey(), normalizedData.getValue());
225 private void putWithEnsuredParents(final LogicalDatastoreType store, final InstanceIdentifier normalizedPath,
226 final NormalizedNode<?, ?> normalizedData) {
228 LOG.trace("write {}:{} ",store,normalizedPath);
230 List<PathArgument> currentArguments = new ArrayList<>();
231 DataNormalizationOperation<?> currentOp = getNormalizer().getRootOperation();
232 Iterator<PathArgument> iterator = normalizedPath.getPath().iterator();
233 while(iterator.hasNext()) {
234 PathArgument currentArg = iterator.next();
235 currentOp = currentOp.getChild(currentArg);
236 currentArguments.add(currentArg);
237 InstanceIdentifier currentPath = new InstanceIdentifier(currentArguments);
238 boolean isPresent = getDelegate().read(store, currentPath).get().isPresent();
239 if(isPresent == false && iterator.hasNext()) {
240 getDelegate().put(store, currentPath, currentOp.createDefault(currentArg));
243 } catch (InterruptedException | ExecutionException e) {
244 LOG.error("Exception durring read.",e);
247 getDelegate().put(store, normalizedPath, normalizedData);
250 private boolean isAugmentationChild(final InstanceIdentifier normalizedPath) {
251 List<PathArgument> parentArgs = parentPath(normalizedPath).getPath();
252 if(parentArgs.isEmpty()) {
255 return Iterables.getLast(parentArgs) instanceof AugmentationIdentifier;
258 private void ensureParentNode(final LogicalDatastoreType store, final InstanceIdentifier normalizedPath,
259 final NormalizedNode<?, ?> normalizedData) {
260 InstanceIdentifier parentPath = parentPath(normalizedPath);
261 PathArgument parentType = Iterables.getLast(parentPath.getPath());
262 if(parentType instanceof AugmentationIdentifier) {
263 AugmentationNode node = Builders.augmentationBuilder()
264 .withNodeIdentifier((AugmentationIdentifier) parentType)
266 getDelegate().put(store, parentPath, node);
268 if(normalizedData instanceof MapEntryNode) {
269 MapNode mapNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(normalizedData.getNodeType())).build();
270 getDelegate().put(store, parentPath, mapNode);
271 } else if (normalizedData instanceof LeafSetNode<?>){
272 LeafSetNode<Object> leafNode = Builders.leafSetBuilder().withNodeIdentifier(new NodeIdentifier(normalizedData.getNodeType())).build();
273 getDelegate().put(store, parentPath, leafNode);
279 private InstanceIdentifier parentPath(final InstanceIdentifier normalizedPath) {
280 List<PathArgument> childArgs = normalizedPath.getPath();
281 return new InstanceIdentifier(childArgs.subList(0, childArgs.size() -1));
284 private boolean parentNodeDoesNotExists(final LogicalDatastoreType store, final InstanceIdentifier normalizedPath) {
286 return !getDelegate().read(store, parentPath(normalizedPath)).get().isPresent();
287 } catch (InterruptedException | ExecutionException e) {
288 throw new IllegalStateException(e);
293 public void removeConfigurationData(final InstanceIdentifier legacyPath) {
294 checkNotNull(legacyPath, "Path MUST NOT be null.");
295 getDelegate().delete(LogicalDatastoreType.CONFIGURATION, getNormalizer().toNormalized(legacyPath));
299 public void removeOperationalData(final InstanceIdentifier legacyPath) {
300 checkNotNull(legacyPath, "Path MUST NOT be null.");
301 getDelegate().delete(LogicalDatastoreType.OPERATIONAL, getNormalizer().toNormalized(legacyPath));