2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.controller.md.sal.dom.broker.impl.compat;
10 import static com.google.common.base.Preconditions.checkNotNull;
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.Iterator;
15 import java.util.List;
17 import java.util.Map.Entry;
19 import java.util.concurrent.ExecutionException;
20 import java.util.concurrent.Future;
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.service.AbstractDataTransaction;
25 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
26 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
27 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
28 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
29 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
30 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
31 import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
32 import org.opendaylight.yangtools.concepts.Delegator;
33 import org.opendaylight.yangtools.concepts.ListenerRegistration;
34 import org.opendaylight.yangtools.yang.common.RpcResult;
35 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
36 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
37 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
38 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
42 import com.google.common.base.Optional;
43 import com.google.common.base.Preconditions;
44 import com.google.common.util.concurrent.ListenableFuture;
46 public abstract class BackwardsCompatibleTransaction<T extends DOMDataReadTransaction> implements
47 DataModificationTransaction, Delegator<T> {
49 private static final Logger LOG = LoggerFactory.getLogger(BackwardsCompatibleTransaction.class);
51 private final T asyncTx;
52 private final DataNormalizer normalizer;
54 protected BackwardsCompatibleTransaction(final T asyncTx, final DataNormalizer normalizer) {
56 this.asyncTx = asyncTx;
57 this.normalizer = normalizer;
60 public static BackwardsCompatibleTransaction<?> readOnlyTransaction(final DOMDataReadOnlyTransaction readTx,
61 final DataNormalizer normalizer) {
63 return new BackwardsCompatibleTransaction<DOMDataReadOnlyTransaction>(readTx, normalizer) {
66 public TransactionStatus getStatus() {
67 return TransactionStatus.NEW;
71 public Future<RpcResult<TransactionStatus>> commit() {
72 getDelegate().close();
78 public static BackwardsCompatibleTransaction<?> readWriteTransaction(final DOMDataReadWriteTransaction rwTx,
79 final DataNormalizer normalizer) {
80 return new ReadWriteTransaction(rwTx, normalizer);
83 protected DataNormalizer getNormalizer() {
88 public T getDelegate() {
93 public CompositeNode readConfigurationData(final InstanceIdentifier legacyPath) {
95 InstanceIdentifier normalizedPath = normalizer.toNormalized(legacyPath);
97 ListenableFuture<Optional<NormalizedNode<?, ?>>> normalizedData = asyncTx.read(
98 LogicalDatastoreType.CONFIGURATION, normalizedPath);
101 return normalizer.toLegacy(normalizedPath, normalizedData.get().orNull());
102 } catch (InterruptedException | ExecutionException e) {
108 public CompositeNode readOperationalData(final InstanceIdentifier legacyPath) {
109 InstanceIdentifier normalizedPath = normalizer.toNormalized(legacyPath);
111 ListenableFuture<Optional<NormalizedNode<?, ?>>> normalizedData = asyncTx.read(
112 LogicalDatastoreType.OPERATIONAL, normalizedPath);
115 return normalizer.toLegacy(normalizedPath, normalizedData.get().orNull());
116 } catch (InterruptedException | ExecutionException e) {
122 public ListenerRegistration<DataTransactionListener> registerListener(final DataTransactionListener listener) {
123 throw new UnsupportedOperationException();
127 public Map<InstanceIdentifier, CompositeNode> getCreatedConfigurationData() {
128 return Collections.emptyMap();
132 public Map<InstanceIdentifier, CompositeNode> getCreatedOperationalData() {
133 return Collections.emptyMap();
137 public Map<InstanceIdentifier, CompositeNode> getOriginalConfigurationData() {
138 return Collections.emptyMap();
142 public Map<InstanceIdentifier, CompositeNode> getOriginalOperationalData() {
143 return Collections.emptyMap();
147 public Set<InstanceIdentifier> getRemovedConfigurationData() {
148 return Collections.emptySet();
152 public Set<InstanceIdentifier> getRemovedOperationalData() {
153 return Collections.emptySet();
157 public Map<InstanceIdentifier, CompositeNode> getUpdatedConfigurationData() {
158 return Collections.emptyMap();
162 public Map<InstanceIdentifier, CompositeNode> getUpdatedOperationalData() {
163 return Collections.emptyMap();
167 public void putConfigurationData(final InstanceIdentifier path, final CompositeNode data) {
168 throw new UnsupportedOperationException();
172 public void putOperationalData(final InstanceIdentifier path, final CompositeNode data) {
173 throw new UnsupportedOperationException();
177 public void removeConfigurationData(final InstanceIdentifier path) {
178 throw new UnsupportedOperationException();
182 public void removeOperationalData(final InstanceIdentifier path) {
183 throw new UnsupportedOperationException();
187 public Object getIdentifier() {
188 return asyncTx.getIdentifier();
191 private static final class ReadWriteTransaction extends BackwardsCompatibleTransaction<DOMDataReadWriteTransaction> {
193 private TransactionStatus status = TransactionStatus.NEW;
195 protected ReadWriteTransaction(final DOMDataReadWriteTransaction asyncTx, final DataNormalizer normalizer) {
196 super(asyncTx, normalizer);
200 public TransactionStatus getStatus() {
205 public Future<RpcResult<TransactionStatus>> commit() {
206 Preconditions.checkState(status == TransactionStatus.NEW);
207 status = TransactionStatus.SUBMITED;
208 return AbstractDataTransaction.convertToLegacyCommitFuture(getDelegate().submit());
212 public void putConfigurationData(final InstanceIdentifier legacyPath, final CompositeNode legacyData) {
213 checkNotNull(legacyPath, "Path MUST NOT be null.");
214 checkNotNull(legacyData, "Data for path %s MUST NOT be null",legacyData);
215 Entry<InstanceIdentifier, NormalizedNode<?, ?>> normalizedData = getNormalizer().toNormalized(legacyPath, legacyData);
216 putWithEnsuredParents(LogicalDatastoreType.CONFIGURATION, normalizedData.getKey(), normalizedData.getValue());
220 public void putOperationalData(final InstanceIdentifier legacyPath, final CompositeNode legacyData) {
221 checkNotNull(legacyPath, "Path MUST NOT be null.");
222 checkNotNull(legacyData, "Data for path %s MUST NOT be null",legacyData);
223 Entry<InstanceIdentifier, NormalizedNode<?, ?>> normalizedData = getNormalizer().toNormalized(legacyPath, legacyData);
224 putWithEnsuredParents(LogicalDatastoreType.OPERATIONAL, normalizedData.getKey(), normalizedData.getValue());
227 private void putWithEnsuredParents(final LogicalDatastoreType store, final InstanceIdentifier normalizedPath,
228 final NormalizedNode<?, ?> normalizedData) {
230 LOG.trace("write {}:{} ",store,normalizedPath);
232 List<PathArgument> currentArguments = new ArrayList<>();
233 DataNormalizationOperation<?> currentOp = getNormalizer().getRootOperation();
234 Iterator<PathArgument> iterator = normalizedPath.getPathArguments().iterator();
235 while(iterator.hasNext()) {
236 PathArgument currentArg = iterator.next();
238 currentOp = currentOp.getChild(currentArg);
239 } catch (DataNormalizationException e) {
240 throw new IllegalArgumentException(String.format("Invalid child encountered in path %s", normalizedPath), e);
242 currentArguments.add(currentArg);
243 InstanceIdentifier currentPath = InstanceIdentifier.create(currentArguments);
244 boolean isPresent = getDelegate().read(store, currentPath).get().isPresent();
245 if(isPresent == false && iterator.hasNext()) {
246 getDelegate().merge(store, currentPath, currentOp.createDefault(currentArg));
249 } catch (InterruptedException | ExecutionException e) {
250 LOG.error("Exception durring read.",e);
253 getDelegate().put(store, normalizedPath, normalizedData);
257 public void removeConfigurationData(final InstanceIdentifier legacyPath) {
258 checkNotNull(legacyPath, "Path MUST NOT be null.");
259 getDelegate().delete(LogicalDatastoreType.CONFIGURATION, getNormalizer().toNormalized(legacyPath));
263 public void removeOperationalData(final InstanceIdentifier legacyPath) {
264 checkNotNull(legacyPath, "Path MUST NOT be null.");
265 getDelegate().delete(LogicalDatastoreType.OPERATIONAL, getNormalizer().toNormalized(legacyPath));