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
9 package org.opendaylight.restconf.nb.rfc8040.rests.utils;
11 import com.google.common.base.Preconditions;
12 import com.google.common.util.concurrent.CheckedFuture;
13 import java.util.ArrayList;
14 import java.util.Iterator;
15 import java.util.List;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
18 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
19 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
20 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
21 import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag;
22 import org.opendaylight.restconf.common.errors.RestconfError.ErrorType;
23 import org.opendaylight.restconf.nb.rfc8040.handlers.TransactionChainHandler;
24 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
25 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
26 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
27 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
28 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
33 * Util class for common methods of transactions.
36 public final class TransactionUtil {
38 private static final Logger LOG = LoggerFactory.getLogger(TransactionUtil.class);
40 private TransactionUtil() {
41 throw new UnsupportedOperationException("Util class");
45 * Merged parents of data.
49 * @param schemaContext
50 * {@link SchemaContext}
54 public static void ensureParentsByMerge(final YangInstanceIdentifier path, final SchemaContext schemaContext,
55 final DOMDataWriteTransaction writeTx) {
56 final List<PathArgument> normalizedPathWithoutChildArgs = new ArrayList<>();
57 YangInstanceIdentifier rootNormalizedPath = null;
59 final Iterator<PathArgument> it = path.getPathArguments().iterator();
61 while (it.hasNext()) {
62 final PathArgument pathArgument = it.next();
63 if (rootNormalizedPath == null) {
64 rootNormalizedPath = YangInstanceIdentifier.create(pathArgument);
68 normalizedPathWithoutChildArgs.add(pathArgument);
72 if (normalizedPathWithoutChildArgs.isEmpty()) {
76 Preconditions.checkArgument(rootNormalizedPath != null, "Empty path received");
78 final NormalizedNode<?, ?> parentStructure = ImmutableNodes.fromInstanceId(schemaContext,
79 YangInstanceIdentifier.create(normalizedPathWithoutChildArgs));
80 writeTx.merge(LogicalDatastoreType.CONFIGURATION, rootNormalizedPath, parentStructure);
84 * Check if items already exists at specified {@code path}. Throws {@link RestconfDocumentedException} if
85 * data does NOT already exists.
86 * @param transactionChainHandler Transaction chain handler
87 * @param rwTransaction Transaction
88 * @param store Datastore
89 * @param path Path to be checked
90 * @param operationType Type of operation (READ, POST, PUT, DELETE...)
92 public static void checkItemExists(final TransactionChainHandler transactionChainHandler,
93 final DOMDataReadWriteTransaction rwTransaction,
94 final LogicalDatastoreType store, final YangInstanceIdentifier path,
95 final String operationType) {
96 final CheckedFuture<Boolean, ReadFailedException> future = rwTransaction.exists(store, path);
97 final FutureDataFactory<Boolean> response = new FutureDataFactory<>();
99 FutureCallbackTx.addCallback(future, operationType, response);
101 if (!response.result) {
102 // close transaction and reset transaction chain
103 rwTransaction.cancel();
104 transactionChainHandler.reset();
107 LOG.trace("Operation via Restconf was not executed because data at {} does not exist", path);
108 throw new RestconfDocumentedException(
109 "Data does not exist", ErrorType.PROTOCOL, ErrorTag.DATA_MISSING, path);
114 * Check if items do NOT already exists at specified {@code path}. Throws {@link RestconfDocumentedException} if
115 * data already exists.
116 * @param transactionChainHandler Transaction chain handler
117 * @param rwTransaction Transaction
118 * @param store Datastore
119 * @param path Path to be checked
120 * @param operationType Type of operation (READ, POST, PUT, DELETE...)
122 public static void checkItemDoesNotExists(final TransactionChainHandler transactionChainHandler,
123 final DOMDataReadWriteTransaction rwTransaction,
124 final LogicalDatastoreType store, final YangInstanceIdentifier path,
125 final String operationType) {
126 final CheckedFuture<Boolean, ReadFailedException> future = rwTransaction.exists(store, path);
127 final FutureDataFactory<Boolean> response = new FutureDataFactory<>();
129 FutureCallbackTx.addCallback(future, operationType, response);
131 if (response.result) {
132 // close transaction and reset transaction chain
133 rwTransaction.cancel();
134 transactionChainHandler.reset();
137 LOG.trace("Operation via Restconf was not executed because data at {} already exists", path);
138 throw new RestconfDocumentedException(
139 "Data already exists", ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS, path);