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.restconf.common.errors.RestconfDocumentedException;
19 import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag;
20 import org.opendaylight.restconf.common.errors.RestconfError.ErrorType;
21 import org.opendaylight.restconf.nb.rfc8040.handlers.TransactionChainHandler;
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 transactionChainHandler Transaction chain handler
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 TransactionChainHandler transactionChainHandler,
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) {
100 // close transaction and reset transaction chain
101 rwTransaction.cancel();
102 transactionChainHandler.reset();
105 LOG.trace("Operation via Restconf was not executed because data at {} does not exist", path);
106 throw new RestconfDocumentedException(
107 "Data does not exist", ErrorType.PROTOCOL, ErrorTag.DATA_MISSING, path);
112 * Check if items do NOT already exists at specified {@code path}. Throws {@link RestconfDocumentedException} if
113 * data already exists.
114 * @param transactionChainHandler Transaction chain handler
115 * @param rwTransaction Transaction
116 * @param store Datastore
117 * @param path Path to be checked
118 * @param operationType Type of operation (READ, POST, PUT, DELETE...)
120 public static void checkItemDoesNotExists(final TransactionChainHandler transactionChainHandler,
121 final DOMDataTreeReadWriteTransaction rwTransaction,
122 final LogicalDatastoreType store, final YangInstanceIdentifier path,
123 final String operationType) {
124 final FluentFuture<Boolean> future = rwTransaction.exists(store, path);
125 final FutureDataFactory<Boolean> response = new FutureDataFactory<>();
127 FutureCallbackTx.addCallback(future, operationType, response);
129 if (response.result) {
130 // close transaction and reset transaction chain
131 rwTransaction.cancel();
132 transactionChainHandler.reset();
135 LOG.trace("Operation via Restconf was not executed because data at {} already exists", path);
136 throw new RestconfDocumentedException(
137 "Data already exists", ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS, path);