Merge "Bug:1252 - Fix formatting errors in config code generator"
[controller.git] / opendaylight / md-sal / sal-dom-broker / src / main / java / org / opendaylight / controller / md / sal / dom / broker / impl / compat / BackwardsCompatibleTransaction.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.compat;
9
10 import static com.google.common.base.Preconditions.checkNotNull;
11
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.Iterator;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Map.Entry;
18 import java.util.Set;
19 import java.util.concurrent.ExecutionException;
20 import java.util.concurrent.Future;
21
22 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
25 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
26 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
27 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
28 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
29 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
30 import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
31 import org.opendaylight.yangtools.concepts.Delegator;
32 import org.opendaylight.yangtools.concepts.ListenerRegistration;
33 import org.opendaylight.yangtools.yang.common.RpcResult;
34 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
35 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
36 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
37 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 import com.google.common.base.Optional;
42 import com.google.common.base.Preconditions;
43 import com.google.common.util.concurrent.ListenableFuture;
44
45 public abstract class BackwardsCompatibleTransaction<T extends DOMDataReadTransaction> implements
46         DataModificationTransaction, Delegator<T> {
47
48     private static final Logger LOG = LoggerFactory.getLogger(BackwardsCompatibleTransaction.class);
49
50     private final T asyncTx;
51     private final DataNormalizer normalizer;
52
53     protected BackwardsCompatibleTransaction(final T asyncTx, final DataNormalizer normalizer) {
54         super();
55         this.asyncTx = asyncTx;
56         this.normalizer = normalizer;
57     }
58
59     public static BackwardsCompatibleTransaction<?> readOnlyTransaction(final DOMDataReadOnlyTransaction readTx,
60             final DataNormalizer normalizer) {
61
62         return new BackwardsCompatibleTransaction<DOMDataReadOnlyTransaction>(readTx, normalizer) {
63
64             @Override
65             public TransactionStatus getStatus() {
66                 return TransactionStatus.NEW;
67             }
68
69             @Override
70             public Future<RpcResult<TransactionStatus>> commit() {
71                 getDelegate().close();
72                 return null;
73             }
74         };
75     }
76
77     public static BackwardsCompatibleTransaction<?> readWriteTransaction(final DOMDataReadWriteTransaction rwTx,
78             final DataNormalizer normalizer) {
79         return new ReadWriteTransaction(rwTx, normalizer);
80     }
81
82     protected DataNormalizer getNormalizer() {
83         return normalizer;
84     }
85
86     @Override
87     public T getDelegate() {
88         return asyncTx;
89     };
90
91     @Override
92     public CompositeNode readConfigurationData(final InstanceIdentifier legacyPath) {
93
94         InstanceIdentifier normalizedPath = normalizer.toNormalized(legacyPath);
95
96         ListenableFuture<Optional<NormalizedNode<?, ?>>> normalizedData = asyncTx.read(
97                 LogicalDatastoreType.CONFIGURATION, normalizedPath);
98
99         try {
100             return normalizer.toLegacy(normalizedPath, normalizedData.get().orNull());
101         } catch (InterruptedException | ExecutionException e) {
102             return null;
103         }
104     }
105
106     @Override
107     public CompositeNode readOperationalData(final InstanceIdentifier legacyPath) {
108         InstanceIdentifier normalizedPath = normalizer.toNormalized(legacyPath);
109
110         ListenableFuture<Optional<NormalizedNode<?, ?>>> normalizedData = asyncTx.read(
111                 LogicalDatastoreType.OPERATIONAL, normalizedPath);
112
113         try {
114             return normalizer.toLegacy(normalizedPath, normalizedData.get().orNull());
115         } catch (InterruptedException | ExecutionException e) {
116             return null;
117         }
118     }
119
120     @Override
121     public ListenerRegistration<DataTransactionListener> registerListener(final DataTransactionListener listener) {
122         throw new UnsupportedOperationException();
123     }
124
125     @Override
126     public Map<InstanceIdentifier, CompositeNode> getCreatedConfigurationData() {
127         return Collections.emptyMap();
128     }
129
130     @Override
131     public Map<InstanceIdentifier, CompositeNode> getCreatedOperationalData() {
132         return Collections.emptyMap();
133     }
134
135     @Override
136     public Map<InstanceIdentifier, CompositeNode> getOriginalConfigurationData() {
137         return Collections.emptyMap();
138     }
139
140     @Override
141     public Map<InstanceIdentifier, CompositeNode> getOriginalOperationalData() {
142         return Collections.emptyMap();
143     }
144
145     @Override
146     public Set<InstanceIdentifier> getRemovedConfigurationData() {
147         return Collections.emptySet();
148     }
149
150     @Override
151     public Set<InstanceIdentifier> getRemovedOperationalData() {
152         return Collections.emptySet();
153     }
154
155     @Override
156     public Map<InstanceIdentifier, CompositeNode> getUpdatedConfigurationData() {
157         return Collections.emptyMap();
158     }
159
160     @Override
161     public Map<InstanceIdentifier, CompositeNode> getUpdatedOperationalData() {
162         return Collections.emptyMap();
163     }
164
165     @Override
166     public void putConfigurationData(final InstanceIdentifier path, final CompositeNode data) {
167         throw new UnsupportedOperationException();
168     }
169
170     @Override
171     public void putOperationalData(final InstanceIdentifier path, final CompositeNode data) {
172         throw new UnsupportedOperationException();
173     }
174
175     @Override
176     public void removeConfigurationData(final InstanceIdentifier path) {
177         throw new UnsupportedOperationException();
178     }
179
180     @Override
181     public void removeOperationalData(final InstanceIdentifier path) {
182         throw new UnsupportedOperationException();
183     }
184
185     @Override
186     public Object getIdentifier() {
187         return asyncTx.getIdentifier();
188     }
189
190     private static final class ReadWriteTransaction extends BackwardsCompatibleTransaction<DOMDataReadWriteTransaction> {
191
192         private TransactionStatus status = TransactionStatus.NEW;
193
194         protected ReadWriteTransaction(final DOMDataReadWriteTransaction asyncTx, final DataNormalizer normalizer) {
195             super(asyncTx, normalizer);
196         }
197
198         @Override
199         public TransactionStatus getStatus() {
200             return status;
201         }
202
203         @Override
204         public Future<RpcResult<TransactionStatus>> commit() {
205             Preconditions.checkState(status == TransactionStatus.NEW);
206             status = TransactionStatus.SUBMITED;
207             return getDelegate().commit();
208         }
209
210         @Override
211         public void putConfigurationData(final InstanceIdentifier legacyPath, final CompositeNode legacyData) {
212             checkNotNull(legacyPath, "Path MUST NOT be null.");
213             checkNotNull(legacyData, "Data for path %s MUST NOT be null",legacyData);
214             Entry<InstanceIdentifier, NormalizedNode<?, ?>> normalizedData = getNormalizer().toNormalized(legacyPath, legacyData);
215             putWithEnsuredParents(LogicalDatastoreType.CONFIGURATION, normalizedData.getKey(), normalizedData.getValue());
216         }
217
218         @Override
219         public void putOperationalData(final InstanceIdentifier legacyPath, final CompositeNode legacyData) {
220             checkNotNull(legacyPath, "Path MUST NOT be null.");
221             checkNotNull(legacyData, "Data for path %s MUST NOT be null",legacyData);
222             Entry<InstanceIdentifier, NormalizedNode<?, ?>> normalizedData = getNormalizer().toNormalized(legacyPath, legacyData);
223             putWithEnsuredParents(LogicalDatastoreType.OPERATIONAL, normalizedData.getKey(), normalizedData.getValue());
224         }
225
226         private void putWithEnsuredParents(final LogicalDatastoreType store, final InstanceIdentifier normalizedPath,
227                 final NormalizedNode<?, ?> normalizedData) {
228
229             LOG.trace("write {}:{} ",store,normalizedPath);
230             try {
231             List<PathArgument> currentArguments = new ArrayList<>();
232             DataNormalizationOperation<?> currentOp = getNormalizer().getRootOperation();
233             Iterator<PathArgument> iterator = normalizedPath.getPath().iterator();
234             while(iterator.hasNext()) {
235                 PathArgument currentArg = iterator.next();
236                 try {
237                     currentOp = currentOp.getChild(currentArg);
238                 } catch (DataNormalizationException e) {
239                     throw new IllegalArgumentException(String.format("Invalid child encountered in path %s", normalizedPath), e);
240                 }
241                 currentArguments.add(currentArg);
242                 InstanceIdentifier currentPath = new InstanceIdentifier(currentArguments);
243                 boolean isPresent = getDelegate().read(store, currentPath).get().isPresent();
244                 if(isPresent == false && iterator.hasNext()) {
245                     getDelegate().merge(store, currentPath, currentOp.createDefault(currentArg));
246                 }
247             }
248             } catch (InterruptedException | ExecutionException e) {
249                 LOG.error("Exception durring read.",e);
250             }
251
252             getDelegate().put(store, normalizedPath, normalizedData);
253         }
254
255         @Override
256         public void removeConfigurationData(final InstanceIdentifier legacyPath) {
257             checkNotNull(legacyPath, "Path MUST NOT be null.");
258             getDelegate().delete(LogicalDatastoreType.CONFIGURATION, getNormalizer().toNormalized(legacyPath));
259         }
260
261         @Override
262         public void removeOperationalData(final InstanceIdentifier legacyPath) {
263             checkNotNull(legacyPath, "Path MUST NOT be null.");
264             getDelegate().delete(LogicalDatastoreType.OPERATIONAL, getNormalizer().toNormalized(legacyPath));
265         }
266     }
267 }