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.util.concurrent.FluentFuture;
11 import java.util.ArrayList;
12 import java.util.Iterator;
13 import java.util.List;
14 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
15 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
16 import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag;
17 import org.opendaylight.restconf.common.errors.RestconfError.ErrorType;
18 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
21 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
22 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
23 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
28 * Util class for common methods of transactions.
31 public final class TransactionUtil {
33 private static final Logger LOG = LoggerFactory.getLogger(TransactionUtil.class);
35 private TransactionUtil() {
36 throw new UnsupportedOperationException("Util class");
40 * Merged parents of data.
42 * @param path path of data
43 * @param schemaContext {@link SchemaContext}
44 * @param strategy object that perform the actual DS operations
46 public static void ensureParentsByMerge(final YangInstanceIdentifier path, final SchemaContext schemaContext,
47 final RestconfStrategy strategy) {
48 final List<PathArgument> normalizedPathWithoutChildArgs = new ArrayList<>();
49 YangInstanceIdentifier rootNormalizedPath = null;
51 final Iterator<PathArgument> it = path.getPathArguments().iterator();
53 while (it.hasNext()) {
54 final PathArgument pathArgument = it.next();
55 if (rootNormalizedPath == null) {
56 rootNormalizedPath = YangInstanceIdentifier.create(pathArgument);
60 normalizedPathWithoutChildArgs.add(pathArgument);
64 if (normalizedPathWithoutChildArgs.isEmpty()) {
68 final NormalizedNode<?, ?> parentStructure = ImmutableNodes.fromInstanceId(schemaContext,
69 YangInstanceIdentifier.create(normalizedPathWithoutChildArgs));
70 strategy.merge(LogicalDatastoreType.CONFIGURATION, rootNormalizedPath, parentStructure);
74 * Check if items already exists at specified {@code path}. Throws {@link RestconfDocumentedException} if
75 * data does NOT already exists.
77 * @param strategy Object that perform the actual DS operations
78 * @param store Datastore
79 * @param path Path to be checked
80 * @param operationType Type of operation (READ, POST, PUT, DELETE...)
82 public static void checkItemExists(final RestconfStrategy strategy,
83 final LogicalDatastoreType store, final YangInstanceIdentifier path,
84 final String operationType) {
85 final FluentFuture<Boolean> future = strategy.exists(store, path);
86 final FutureDataFactory<Boolean> response = new FutureDataFactory<>();
88 FutureCallbackTx.addCallback(future, operationType, response);
90 if (!response.result) {
94 LOG.trace("Operation via Restconf was not executed because data at {} does not exist", path);
95 throw new RestconfDocumentedException(
96 "Data does not exist", ErrorType.PROTOCOL, ErrorTag.DATA_MISSING, path);
101 * Check if items do NOT already exists at specified {@code path}. Throws {@link RestconfDocumentedException} if
102 * data already exists.
104 * @param strategy Object that perform the actual DS operations
105 * @param store Datastore
106 * @param path Path to be checked
107 * @param operationType Type of operation (READ, POST, PUT, DELETE...)
109 public static void checkItemDoesNotExists(final RestconfStrategy strategy,
110 final LogicalDatastoreType store, final YangInstanceIdentifier path,
111 final String operationType) {
112 final FluentFuture<Boolean> future = strategy.exists(store, path);
113 final FutureDataFactory<Boolean> response = new FutureDataFactory<>();
115 FutureCallbackTx.addCallback(future, operationType, response);
117 if (response.result) {
121 LOG.trace("Operation via Restconf was not executed because data at {} already exists", path);
122 throw new RestconfDocumentedException(
123 "Data already exists", ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS, path);