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;
11 import com.google.common.base.Optional;
12 import com.google.common.base.Preconditions;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.Iterator;
17 import java.util.List;
19 import java.util.Map.Entry;
21 import java.util.concurrent.ExecutionException;
22 import java.util.concurrent.Future;
23 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
24 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
25 import org.opendaylight.controller.md.sal.common.impl.service.AbstractDataTransaction;
26 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationException;
27 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizationOperation;
28 import org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer;
29 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
30 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadTransaction;
31 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
32 import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
33 import org.opendaylight.yangtools.concepts.Delegator;
34 import org.opendaylight.yangtools.concepts.ListenerRegistration;
35 import org.opendaylight.yangtools.yang.common.RpcResult;
36 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
37 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
38 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
39 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
44 public abstract class BackwardsCompatibleTransaction<T extends DOMDataReadTransaction> implements DataModificationTransaction, Delegator<T> {
46 private static final Logger LOG = LoggerFactory.getLogger(BackwardsCompatibleTransaction.class);
48 private final T asyncTx;
49 private final DataNormalizer normalizer;
51 protected BackwardsCompatibleTransaction(final T asyncTx, final DataNormalizer normalizer) {
53 this.asyncTx = asyncTx;
54 this.normalizer = normalizer;
57 public static BackwardsCompatibleTransaction<?> readOnlyTransaction(final DOMDataReadOnlyTransaction readTx,
58 final DataNormalizer normalizer) {
60 return new BackwardsCompatibleTransaction<DOMDataReadOnlyTransaction>(readTx, normalizer) {
63 public TransactionStatus getStatus() {
64 return TransactionStatus.NEW;
68 public Future<RpcResult<TransactionStatus>> commit() {
69 getDelegate().close();
75 public static BackwardsCompatibleTransaction<?> readWriteTransaction(final DOMDataReadWriteTransaction rwTx,
76 final DataNormalizer normalizer) {
77 return new ReadWriteTransaction(rwTx, normalizer);
80 protected DataNormalizer getNormalizer() {
85 public T getDelegate() {
90 public CompositeNode readConfigurationData(final YangInstanceIdentifier legacyPath) {
92 YangInstanceIdentifier normalizedPath = normalizer.toNormalized(legacyPath);
94 ListenableFuture<Optional<NormalizedNode<?, ?>>> normalizedData = asyncTx.read(
95 LogicalDatastoreType.CONFIGURATION, normalizedPath);
98 return normalizer.toLegacy(normalizedPath, normalizedData.get().orNull());
99 } catch (InterruptedException | ExecutionException e) {
105 public CompositeNode readOperationalData(final YangInstanceIdentifier legacyPath) {
106 YangInstanceIdentifier normalizedPath = normalizer.toNormalized(legacyPath);
108 ListenableFuture<Optional<NormalizedNode<?, ?>>> normalizedData = asyncTx.read(
109 LogicalDatastoreType.OPERATIONAL, normalizedPath);
112 return normalizer.toLegacy(normalizedPath, normalizedData.get().orNull());
113 } catch (InterruptedException | ExecutionException e) {
119 public ListenerRegistration<DataTransactionListener> registerListener(final DataTransactionListener listener) {
120 throw new UnsupportedOperationException();
124 public Map<YangInstanceIdentifier, CompositeNode> getCreatedConfigurationData() {
125 return Collections.emptyMap();
129 public Map<YangInstanceIdentifier, CompositeNode> getCreatedOperationalData() {
130 return Collections.emptyMap();
134 public Map<YangInstanceIdentifier, CompositeNode> getOriginalConfigurationData() {
135 return Collections.emptyMap();
139 public Map<YangInstanceIdentifier, CompositeNode> getOriginalOperationalData() {
140 return Collections.emptyMap();
144 public Set<YangInstanceIdentifier> getRemovedConfigurationData() {
145 return Collections.emptySet();
149 public Set<YangInstanceIdentifier> getRemovedOperationalData() {
150 return Collections.emptySet();
154 public Map<YangInstanceIdentifier, CompositeNode> getUpdatedConfigurationData() {
155 return Collections.emptyMap();
159 public Map<YangInstanceIdentifier, CompositeNode> getUpdatedOperationalData() {
160 return Collections.emptyMap();
164 public void putConfigurationData(final YangInstanceIdentifier path, final CompositeNode data) {
165 throw new UnsupportedOperationException();
169 public void putOperationalData(final YangInstanceIdentifier path, final CompositeNode data) {
170 throw new UnsupportedOperationException();
174 public void removeConfigurationData(final YangInstanceIdentifier path) {
175 throw new UnsupportedOperationException();
179 public void removeOperationalData(final YangInstanceIdentifier path) {
180 throw new UnsupportedOperationException();
184 public Object getIdentifier() {
185 return asyncTx.getIdentifier();
188 private static final class ReadWriteTransaction extends BackwardsCompatibleTransaction<DOMDataReadWriteTransaction> {
190 private TransactionStatus status = TransactionStatus.NEW;
192 protected ReadWriteTransaction(final DOMDataReadWriteTransaction asyncTx, final DataNormalizer normalizer) {
193 super(asyncTx, normalizer);
197 public TransactionStatus getStatus() {
202 public Future<RpcResult<TransactionStatus>> commit() {
203 Preconditions.checkState(status == TransactionStatus.NEW);
204 status = TransactionStatus.SUBMITED;
205 return AbstractDataTransaction.convertToLegacyCommitFuture(getDelegate().submit());
209 public void putConfigurationData(final YangInstanceIdentifier legacyPath, final CompositeNode legacyData) {
210 checkNotNull(legacyPath, "Path MUST NOT be null.");
211 checkNotNull(legacyData, "Data for path %s MUST NOT be null",legacyData);
212 Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedData = getNormalizer().toNormalized(legacyPath, legacyData);
213 putWithEnsuredParents(LogicalDatastoreType.CONFIGURATION, normalizedData.getKey(), normalizedData.getValue());
217 public void putOperationalData(final YangInstanceIdentifier legacyPath, final CompositeNode legacyData) {
218 checkNotNull(legacyPath, "Path MUST NOT be null.");
219 checkNotNull(legacyData, "Data for path %s MUST NOT be null",legacyData);
220 Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedData = getNormalizer().toNormalized(legacyPath, legacyData);
221 putWithEnsuredParents(LogicalDatastoreType.OPERATIONAL, normalizedData.getKey(), normalizedData.getValue());
224 private void putWithEnsuredParents(final LogicalDatastoreType store, final YangInstanceIdentifier normalizedPath,
225 final NormalizedNode<?, ?> normalizedData) {
227 LOG.trace("write {}:{} ",store,normalizedPath);
229 List<PathArgument> currentArguments = new ArrayList<>();
230 DataNormalizationOperation<?> currentOp = getNormalizer().getRootOperation();
231 Iterator<PathArgument> iterator = normalizedPath.getPathArguments().iterator();
232 while(iterator.hasNext()) {
233 PathArgument currentArg = iterator.next();
235 currentOp = currentOp.getChild(currentArg);
236 } catch (DataNormalizationException e) {
237 throw new IllegalArgumentException(String.format("Invalid child encountered in path %s", normalizedPath), e);
239 currentArguments.add(currentArg);
240 YangInstanceIdentifier currentPath = YangInstanceIdentifier.create(currentArguments);
241 boolean isPresent = getDelegate().read(store, currentPath).get().isPresent();
242 if(isPresent == false && iterator.hasNext()) {
243 getDelegate().merge(store, currentPath, currentOp.createDefault(currentArg));
246 } catch (InterruptedException | ExecutionException e) {
247 LOG.error("Exception durring read.",e);
250 getDelegate().put(store, normalizedPath, normalizedData);
254 public void removeConfigurationData(final YangInstanceIdentifier legacyPath) {
255 checkNotNull(legacyPath, "Path MUST NOT be null.");
256 getDelegate().delete(LogicalDatastoreType.CONFIGURATION, getNormalizer().toNormalized(legacyPath));
260 public void removeOperationalData(final YangInstanceIdentifier legacyPath) {
261 checkNotNull(legacyPath, "Path MUST NOT be null.");
262 getDelegate().delete(LogicalDatastoreType.OPERATIONAL, getNormalizer().toNormalized(legacyPath));