d1857be0df6943f37c540d2360f7241eb0f29a6b
[netconf.git] / restconf / restconf-nb-rfc8040 / src / main / java / org / opendaylight / restconf / nb / rfc8040 / rests / utils / PlainPatchDataTransactionUtil.java
1 /*
2  * Copyright (c) 2020 Lumina Networks, Inc. and others.  All rights reserved.
3  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7  * and is available at http://www.eclipse.org/legal/epl-v10.html
8  */
9 package org.opendaylight.restconf.nb.rfc8040.rests.utils;
10
11 import com.google.common.util.concurrent.FluentFuture;
12 import javax.ws.rs.core.Response;
13 import javax.ws.rs.core.Response.Status;
14 import org.opendaylight.mdsal.common.api.CommitInfo;
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.context.NormalizedNodeContext;
20 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
21 import org.opendaylight.restconf.nb.rfc8040.references.SchemaContextRef;
22 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.TransactionVarsWrapper;
23 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
24 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
25 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 /**
30  * Util class for plain patch data to DS.
31  */
32 public final class PlainPatchDataTransactionUtil {
33
34     private static final Logger LOG = LoggerFactory.getLogger(PlainPatchDataTransactionUtil.class);
35
36     private PlainPatchDataTransactionUtil() {
37     }
38
39     /**
40      * Prepare variables for put data to DS. Close {@link DOMTransactionChain} inside of object
41      * {@link TransactionVarsWrapper} provided as a parameter.
42      *
43      * @param payload
44      *             data to put
45      * @param schemaContextRef
46      *             reference to {@link SchemaContext}
47      * @param transactionNode
48      *             wrapper of variables for transaction
49      * @return {@link Response}
50      */
51     public static Response patchData(final NormalizedNodeContext payload,
52                                      final TransactionVarsWrapper transactionNode,
53                                      final SchemaContextRef schemaContextRef) {
54
55         final DOMTransactionChain transactionChain = transactionNode.getTransactionChain();
56         final DOMDataTreeReadWriteTransaction tx = transactionChain.newReadWriteTransaction();
57
58         YangInstanceIdentifier path = payload.getInstanceIdentifierContext().getInstanceIdentifier();
59         NormalizedNode<?, ?> data = payload.getData();
60
61         try {
62             mergeDataWithinTransaction(LogicalDatastoreType.CONFIGURATION,
63                     path, data, tx, schemaContextRef);
64         } catch (final RestconfDocumentedException e) {
65             tx.cancel();
66             transactionChain.close();
67
68             throw new IllegalArgumentException(e);
69         }
70
71         final FluentFuture<? extends CommitInfo> future = tx.commit();
72         final ResponseFactory response = new ResponseFactory(Status.OK);
73
74         FutureCallbackTx.addCallback(future,
75                 RestconfDataServiceConstant.PatchData.PATCH_TX_TYPE,
76                 response,
77                 transactionChain); // closes transactionChain, may throw
78
79         return response.build();
80     }
81
82     /**
83      * Merge data within one transaction.
84      * @param dataStore Datastore to merge data to
85      * @param path Path for data to be merged
86      * @param payload Data to be merged
87      * @param writeTransaction Transaction
88      * @param schemaContextRef Soft reference for global schema context
89      */
90     private static void mergeDataWithinTransaction(final LogicalDatastoreType dataStore,
91                                                    final YangInstanceIdentifier path,
92                                                    final NormalizedNode<?, ?> payload,
93                                                    final DOMDataTreeWriteTransaction writeTransaction,
94                                                    final SchemaContextRef schemaContextRef) {
95         LOG.trace("Merge {} within Restconf Patch: {} with payload {}", dataStore.name(), path, payload);
96         TransactionUtil.ensureParentsByMerge(path, schemaContextRef.get(), writeTransaction);
97         writeTransaction.merge(dataStore, path, payload);
98     }
99 }