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 final String errMsg = "Operation via Restconf was not executed because data does not exist";
108 LOG.trace("{}:{}", errMsg, path);
109 throw new RestconfDocumentedException(
110 "Data does not exist", ErrorType.PROTOCOL, ErrorTag.DATA_MISSING, path);
115 * Check if items do NOT already exists at specified {@code path}. Throws {@link RestconfDocumentedException} if
116 * data already exists.
117 * @param transactionChainHandler Transaction chain handler
118 * @param rwTransaction Transaction
119 * @param store Datastore
120 * @param path Path to be checked
121 * @param operationType Type of operation (READ, POST, PUT, DELETE...)
123 public static void checkItemDoesNotExists(final TransactionChainHandler transactionChainHandler,
124 final DOMDataReadWriteTransaction rwTransaction,
125 final LogicalDatastoreType store, final YangInstanceIdentifier path,
126 final String operationType) {
127 final CheckedFuture<Boolean, ReadFailedException> future = rwTransaction.exists(store, path);
128 final FutureDataFactory<Boolean> response = new FutureDataFactory<>();
130 FutureCallbackTx.addCallback(future, operationType, response);
132 if (response.result) {
133 // close transaction and reset transaction chain
134 rwTransaction.cancel();
135 transactionChainHandler.reset();
138 final String errMsg = "Operation via Restconf was not executed because data already exists";
139 LOG.trace("{}:{}", errMsg, path);
140 throw new RestconfDocumentedException(
141 "Data already exists", ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS, path);