Remove RestconfDataServiceConstant.PostData
[netconf.git] / restconf / restconf-nb-rfc8040 / src / main / java / org / opendaylight / restconf / nb / rfc8040 / rests / utils / RestconfInvokeOperationsUtil.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.restconf.nb.rfc8040.rests.utils;
9
10 import com.google.common.util.concurrent.ListenableFuture;
11 import java.util.Optional;
12 import java.util.concurrent.CancellationException;
13 import javax.ws.rs.core.Response.Status;
14 import org.eclipse.jdt.annotation.NonNull;
15 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
16 import org.opendaylight.mdsal.dom.api.DOMActionResult;
17 import org.opendaylight.mdsal.dom.api.DOMActionService;
18 import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
19 import org.opendaylight.mdsal.dom.api.DOMMountPoint;
20 import org.opendaylight.mdsal.dom.api.DOMRpcResult;
21 import org.opendaylight.mdsal.dom.api.DOMRpcService;
22 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
23 import org.opendaylight.restconf.common.errors.RestconfError.ErrorTag;
24 import org.opendaylight.restconf.common.errors.RestconfError.ErrorType;
25 import org.opendaylight.restconf.nb.rfc8040.handlers.ActionServiceHandler;
26 import org.opendaylight.restconf.nb.rfc8040.handlers.RpcServiceHandler;
27 import org.opendaylight.yangtools.yang.common.YangConstants;
28 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
29 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
30 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
31 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
32 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 /**
37  * Util class for rpc.
38  */
39 public final class RestconfInvokeOperationsUtil {
40     private static final Logger LOG = LoggerFactory.getLogger(RestconfInvokeOperationsUtil.class);
41
42     private RestconfInvokeOperationsUtil() {
43         throw new UnsupportedOperationException("Util class");
44     }
45
46     /**
47      * Invoking rpc via mount point.
48      *
49      * @param mountPoint
50      *             mount point
51      * @param data
52      *             input data
53      * @param schemaPath
54      *             schema path of data
55      * @return {@link DOMRpcResult}
56      */
57     public static DOMRpcResult invokeRpcViaMountPoint(final DOMMountPoint mountPoint, final NormalizedNode<?, ?> data,
58             final SchemaPath schemaPath) {
59         final Optional<DOMRpcService> mountPointService = mountPoint.getService(DOMRpcService.class);
60         if (mountPointService.isPresent()) {
61             return prepareResult(mountPointService.get().invokeRpc(schemaPath, nonnullInput(schemaPath, data)));
62         }
63         final String errmsg = "RPC service is missing.";
64         LOG.debug(errmsg);
65         throw new RestconfDocumentedException(errmsg);
66     }
67
68     /**
69      * Invoke rpc.
70      *
71      * @param data
72      *             input data
73      * @param schemaPath
74      *             schema path of data
75      * @param rpcServiceHandler
76      *             rpc service handler to invoke rpc
77      * @return {@link DOMRpcResult}
78      */
79     public static DOMRpcResult invokeRpc(final NormalizedNode<?, ?> data, final SchemaPath schemaPath,
80             final RpcServiceHandler rpcServiceHandler) {
81         final DOMRpcService rpcService = rpcServiceHandler.get();
82         if (rpcService == null) {
83             throw new RestconfDocumentedException(Status.SERVICE_UNAVAILABLE);
84         }
85
86         return prepareResult(rpcService.invokeRpc(schemaPath, nonnullInput(schemaPath, data)));
87     }
88
89     private static @NonNull NormalizedNode<?, ?> nonnullInput(final SchemaPath type, final NormalizedNode<?, ?> input) {
90         return input != null ? input
91                 : ImmutableNodes.containerNode(YangConstants.operationInputQName(type.getLastComponent().getModule()));
92     }
93
94     /**
95      * Check the validity of the result.
96      *
97      * @param response
98      *             response of rpc
99      * @return {@link DOMRpcResult} result
100      */
101     public static DOMRpcResult checkResponse(final DOMRpcResult response) {
102         if (response == null) {
103             return null;
104         }
105         try {
106             if (response.getErrors().isEmpty()) {
107                 return response;
108             }
109             LOG.debug("RpcError message {}", response.getErrors());
110             throw new RestconfDocumentedException("RPCerror message ", null, response.getErrors());
111         } catch (final CancellationException e) {
112             final String errMsg = "The operation was cancelled while executing.";
113             LOG.debug("Cancel RpcExecution: {}", errMsg, e);
114             throw new RestconfDocumentedException(errMsg, ErrorType.RPC, ErrorTag.PARTIAL_OPERATION, e);
115         }
116     }
117
118     private static DOMRpcResult prepareResult(final ListenableFuture<? extends DOMRpcResult> rpc) {
119         final RpcResultFactory dataFactory = new RpcResultFactory();
120         FutureCallbackTx.addCallback(rpc, PostDataTransactionUtil.POST_TX_TYPE, dataFactory);
121         return dataFactory.build();
122     }
123
124     /**
125      * Invoking Action via mount point.
126      *
127      * @param mountPoint
128      *             mount point
129      * @param data
130      *             input data
131      * @param schemaPath
132      *             schema path of data
133      * @return {@link DOMActionResult}
134      */
135     public static DOMActionResult invokeActionViaMountPoint(final DOMMountPoint mountPoint, final ContainerNode data,
136             final SchemaPath schemaPath, final YangInstanceIdentifier yangIId) {
137         final Optional<DOMActionService> mountPointService = mountPoint.getService(DOMActionService.class);
138         if (!mountPointService.isPresent()) {
139             throw new RestconfDocumentedException("DomAction service is missing.");
140         }
141         return prepareActionResult(mountPointService.get().invokeAction(schemaPath, prepareDataTreeId(yangIId), data));
142     }
143
144     /**
145      * Invoke Action via ActionServiceHandler.
146      *
147      * @param data
148      *             input data
149      * @param schemaPath
150      *             schema path of data
151      * @param actionServiceHandler
152      *             action service handler to invoke action
153      * @return {@link DOMActionResult}
154      */
155     public static DOMActionResult invokeAction(final ContainerNode data, final SchemaPath schemaPath,
156             final ActionServiceHandler actionServiceHandler, final YangInstanceIdentifier yangIId) {
157         return prepareActionResult(
158             actionServiceHandler.get().invokeAction(schemaPath, prepareDataTreeId(yangIId), data));
159     }
160
161     /**
162      * Check the validity of the result.
163      *
164      * @param response
165      *             response of Action
166      * @return {@link DOMActionResult} result
167      */
168     public static DOMActionResult checkActionResponse(final DOMActionResult response) {
169         if (response != null) {
170             try {
171                 if (response.getErrors().isEmpty()) {
172                     return response;
173                 }
174                 LOG.debug("InvokeAction Error Message {}", response.getErrors());
175                 throw new RestconfDocumentedException("InvokeAction Error Message ", null, response.getErrors());
176             } catch (final CancellationException e) {
177                 final String errMsg = "The Action Operation was cancelled while executing.";
178                 LOG.debug("Cancel Execution: {}", errMsg, e);
179                 throw new RestconfDocumentedException(errMsg, ErrorType.RPC, ErrorTag.PARTIAL_OPERATION, e);
180             }
181         }
182         return null;
183     }
184
185     /**
186      * Prepare Action Result.
187      *
188      * @param actionResult
189      *            {@link DOMActionResult} - action result
190      * @return {@link DOMActionResult} result
191      */
192     private static DOMActionResult prepareActionResult(final ListenableFuture<? extends DOMActionResult> actionResult) {
193         final ActionResultFactory dataFactory = new ActionResultFactory();
194         FutureCallbackTx.addCallback(actionResult, PostDataTransactionUtil.POST_TX_TYPE, dataFactory);
195         return dataFactory.build();
196     }
197
198     /**
199      * Prepare DOMDataTree Identifier.
200      *
201      * @param yangIId {@link YangInstanceIdentifier}
202      * @return {@link DOMDataTreeIdentifier} domDataTreeIdentifier
203      */
204     private static DOMDataTreeIdentifier prepareDataTreeId(final YangInstanceIdentifier yangIId) {
205         return new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, yangIId.getParent());
206     }
207 }