2 * Copyright (c) 2016 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.restconf.nb.rfc8040.rests.utils;
10 import com.google.common.base.Preconditions;
11 import com.google.common.util.concurrent.FluentFuture;
12 import java.util.ArrayList;
13 import java.util.Iterator;
14 import java.util.List;
15 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
16 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
17 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
18 import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
19 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
20 import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag;
21 import org.opendaylight.restconf.common.errors.RestconfError.ErrorType;
22 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
23 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
24 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
25 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
26 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
31 * Util class for common methods of transactions.
34 public final class TransactionUtil {
36 private static final Logger LOG = LoggerFactory.getLogger(TransactionUtil.class);
38 private TransactionUtil() {
39 throw new UnsupportedOperationException("Util class");
43 * Merged parents of data.
47 * @param schemaContext
48 * {@link SchemaContext}
52 public static void ensureParentsByMerge(final YangInstanceIdentifier path, final SchemaContext schemaContext,
53 final DOMDataTreeWriteTransaction writeTx) {
54 final List<PathArgument> normalizedPathWithoutChildArgs = new ArrayList<>();
55 YangInstanceIdentifier rootNormalizedPath = null;
57 final Iterator<PathArgument> it = path.getPathArguments().iterator();
59 while (it.hasNext()) {
60 final PathArgument pathArgument = it.next();
61 if (rootNormalizedPath == null) {
62 rootNormalizedPath = YangInstanceIdentifier.create(pathArgument);
66 normalizedPathWithoutChildArgs.add(pathArgument);
70 if (normalizedPathWithoutChildArgs.isEmpty()) {
74 Preconditions.checkArgument(rootNormalizedPath != null, "Empty path received");
76 final NormalizedNode<?, ?> parentStructure = ImmutableNodes.fromInstanceId(schemaContext,
77 YangInstanceIdentifier.create(normalizedPathWithoutChildArgs));
78 writeTx.merge(LogicalDatastoreType.CONFIGURATION, rootNormalizedPath, parentStructure);
82 * Check if items already exists at specified {@code path}. Throws {@link RestconfDocumentedException} if
83 * data does NOT already exists.
84 * @param transactionChain Transaction chain
85 * @param rwTransaction Transaction
86 * @param store Datastore
87 * @param path Path to be checked
88 * @param operationType Type of operation (READ, POST, PUT, DELETE...)
90 public static void checkItemExists(final DOMTransactionChain transactionChain,
91 final DOMDataTreeReadWriteTransaction rwTransaction,
92 final LogicalDatastoreType store, final YangInstanceIdentifier path,
93 final String operationType) {
94 final FluentFuture<Boolean> future = rwTransaction.exists(store, path);
95 final FutureDataFactory<Boolean> response = new FutureDataFactory<>();
97 FutureCallbackTx.addCallback(future, operationType, response);
99 if (!response.result) {
101 rwTransaction.cancel();
102 transactionChain.close();
104 LOG.trace("Operation via Restconf was not executed because data at {} does not exist", path);
105 throw new RestconfDocumentedException(
106 "Data does not exist", ErrorType.PROTOCOL, ErrorTag.DATA_MISSING, path);
111 * Check if items do NOT already exists at specified {@code path}. Throws {@link RestconfDocumentedException} if
112 * data already exists.
113 * @param transactionChain Transaction chain
114 * @param rwTransaction Transaction
115 * @param store Datastore
116 * @param path Path to be checked
117 * @param operationType Type of operation (READ, POST, PUT, DELETE...)
119 public static void checkItemDoesNotExists(final DOMTransactionChain transactionChain,
120 final DOMDataTreeReadWriteTransaction rwTransaction,
121 final LogicalDatastoreType store, final YangInstanceIdentifier path,
122 final String operationType) {
123 final FluentFuture<Boolean> future = rwTransaction.exists(store, path);
124 final FutureDataFactory<Boolean> response = new FutureDataFactory<>();
126 FutureCallbackTx.addCallback(future, operationType, response);
128 if (response.result) {
130 rwTransaction.cancel();
131 transactionChain.close();
133 LOG.trace("Operation via Restconf was not executed because data at {} already exists", path);
134 throw new RestconfDocumentedException(
135 "Data already exists", ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS, path);