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.services.impl;
10 import static java.util.Objects.requireNonNull;
12 import java.io.InputStream;
13 import javax.ws.rs.Consumes;
14 import javax.ws.rs.Encoded;
15 import javax.ws.rs.POST;
16 import javax.ws.rs.Path;
17 import javax.ws.rs.PathParam;
18 import javax.ws.rs.Produces;
19 import javax.ws.rs.container.AsyncResponse;
20 import javax.ws.rs.container.Suspended;
21 import javax.ws.rs.core.Context;
22 import javax.ws.rs.core.MediaType;
23 import javax.ws.rs.core.Response;
24 import javax.ws.rs.core.UriInfo;
25 import org.opendaylight.restconf.nb.rfc8040.MediaTypes;
26 import org.opendaylight.restconf.nb.rfc8040.databind.JsonOperationInputBody;
27 import org.opendaylight.restconf.nb.rfc8040.databind.OperationInputBody;
28 import org.opendaylight.restconf.nb.rfc8040.databind.XmlOperationInputBody;
29 import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
30 import org.opendaylight.restconf.server.spi.OperationOutput;
33 * An operation resource represents a protocol operation defined with the YANG {@code rpc} statement. It is invoked
34 * using a POST method on the operation resource.
37 public final class RestconfInvokeOperationsServiceImpl {
38 private final MdsalRestconfServer server;
40 public RestconfInvokeOperationsServiceImpl(final MdsalRestconfServer server) {
41 this.server = requireNonNull(server);
45 * Invoke RPC operation.
47 * @param identifier module name and rpc identifier string for the desired operation
48 * @param body the body of the operation
49 * @param uriInfo URI info
50 * @param ar {@link AsyncResponse} which needs to be completed with a {@link NormalizedNodePayload} output
53 // FIXME: identifier is just a *single* QName
54 @Path("/operations/{identifier:.+}")
56 MediaTypes.APPLICATION_YANG_DATA_XML,
57 MediaType.APPLICATION_XML,
61 MediaTypes.APPLICATION_YANG_DATA_JSON,
62 MediaTypes.APPLICATION_YANG_DATA_XML,
63 MediaType.APPLICATION_JSON,
64 MediaType.APPLICATION_XML,
67 public void invokeRpcXML(@Encoded @PathParam("identifier") final String identifier, final InputStream body,
68 @Context final UriInfo uriInfo, @Suspended final AsyncResponse ar) {
69 try (var xmlBody = new XmlOperationInputBody(body)) {
70 invokeRpc(identifier, uriInfo, ar, xmlBody);
75 * Invoke RPC operation.
77 * @param identifier module name and rpc identifier string for the desired operation
78 * @param body the body of the operation
79 * @param uriInfo URI info
80 * @param ar {@link AsyncResponse} which needs to be completed with a {@link NormalizedNodePayload} output
83 // FIXME: identifier is just a *single* QName
84 @Path("/operations/{identifier:.+}")
86 MediaTypes.APPLICATION_YANG_DATA_JSON,
87 MediaType.APPLICATION_JSON,
90 MediaTypes.APPLICATION_YANG_DATA_JSON,
91 MediaTypes.APPLICATION_YANG_DATA_XML,
92 MediaType.APPLICATION_JSON,
93 MediaType.APPLICATION_XML,
96 public void invokeRpcJSON(@Encoded @PathParam("identifier") final String identifier, final InputStream body,
97 @Context final UriInfo uriInfo, @Suspended final AsyncResponse ar) {
98 try (var jsonBody = new JsonOperationInputBody(body)) {
99 invokeRpc(identifier, uriInfo, ar, jsonBody);
103 private void invokeRpc(final String identifier, final UriInfo uriInfo, final AsyncResponse ar,
104 final OperationInputBody body) {
105 server.invokeRpc(uriInfo.getBaseUri(), identifier, body)
106 .addCallback(new JaxRsRestconfCallback<OperationOutput>(ar) {
108 Response transform(final OperationOutput result) {
109 final var body = result.output();
110 return body == null ? Response.noContent().build()
111 : Response.ok().entity(new NormalizedNodePayload(result.operation(), body)).build();