import org.opendaylight.restconf.server.api.DataPostBody;
import org.opendaylight.restconf.server.api.DataPostResult;
import org.opendaylight.restconf.server.api.DataPostResult.CreateResource;
-import org.opendaylight.restconf.server.api.DataPostResult.InvokeOperation;
import org.opendaylight.restconf.server.api.DataPutResult;
import org.opendaylight.restconf.server.api.DataYangPatchResult;
import org.opendaylight.restconf.server.api.DatabindContext;
import org.opendaylight.restconf.server.api.DatabindPath.Action;
import org.opendaylight.restconf.server.api.DatabindPath.Data;
import org.opendaylight.restconf.server.api.DatabindPath.InstanceReference;
+import org.opendaylight.restconf.server.api.DatabindPath.OperationPath;
import org.opendaylight.restconf.server.api.DatabindPath.Rpc;
+import org.opendaylight.restconf.server.api.InvokeParams;
+import org.opendaylight.restconf.server.api.InvokeResult;
import org.opendaylight.restconf.server.api.OperationInputBody;
import org.opendaylight.restconf.server.api.OperationOutputBody;
import org.opendaylight.restconf.server.api.OperationsGetResult;
-import org.opendaylight.restconf.server.api.OperationsPostResult;
import org.opendaylight.restconf.server.api.PatchBody;
import org.opendaylight.restconf.server.api.ResourceBody;
import org.opendaylight.restconf.server.spi.ApiPathCanonizer;
return RestconfFuture.of(new OperationsGetResult.Leaf(rpc.inference().modelContext(), rpc.rpc().argument()));
}
- public @NonNull RestconfFuture<OperationsPostResult> operationsPOST(final URI restconfURI, final ApiPath apiPath,
- final OperationInputBody body) {
+ public @NonNull RestconfFuture<InvokeResult> operationsPOST(final URI restconfURI, final ApiPath apiPath,
+ final Map<String, String> queryParameters, final OperationInputBody body) {
final Rpc path;
try {
path = pathNormalizer.normalizeRpcPath(apiPath);
return RestconfFuture.failed(e);
}
+ final InvokeParams params;
+ try {
+ params = InvokeParams.ofQueryParameters(queryParameters);
+ } catch (IllegalArgumentException e) {
+ return RestconfFuture.failed(new RestconfDocumentedException(e.getMessage(),
+ ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, e));
+ }
+
final ContainerNode data;
try {
data = body.toContainerNode(path);
final var type = path.rpc().argument();
final var local = localRpcs.get(type);
if (local != null) {
- return local.invoke(restconfURI, new OperationInput(path, data));
+ return local.invoke(restconfURI, new OperationInput(path, data))
+ .transform(output -> outputToInvokeResult(path, params, output));
}
if (rpcService == null) {
LOG.debug("RPC invocation is not available");
ErrorType.PROTOCOL, ErrorTag.OPERATION_NOT_SUPPORTED));
}
- final var ret = new SettableRestconfFuture<OperationsPostResult>();
+ final var ret = new SettableRestconfFuture<InvokeResult>();
Futures.addCallback(rpcService.invokeRpc(type, data), new FutureCallback<DOMRpcResult>() {
@Override
public void onSuccess(final DOMRpcResult response) {
final var errors = response.errors();
if (errors.isEmpty()) {
- ret.set(new OperationsPostResult(path, response.value()));
+ ret.set(outputToInvokeResult(path, params, response.value()));
} else {
LOG.debug("RPC invocation reported {}", response.errors());
ret.setFailure(new RestconfDocumentedException("RPC implementation reported errors", null,
return ret;
}
+ private static @NonNull InvokeResult outputToInvokeResult(final @NonNull OperationPath path,
+ final @NonNull InvokeParams params, final @Nullable ContainerNode value) {
+ return value == null || value.isEmpty() ? InvokeResult.EMPTY
+ : new InvokeResult(new OperationOutputBody(params, path, value));
+ }
+
public @NonNull RestconfFuture<CharSource> resolveSource(final SourceIdentifier source,
final Class<? extends SourceRepresentation> representation) {
final var src = requireNonNull(source);
}
if (path instanceof Action actionPath) {
try (var inputBody = body.toOperationInput()) {
- return dataInvokePOST(actionPath, inputBody);
+ return dataInvokePOST(actionPath, inputBody, queryParameters);
}
}
// Note: this should never happen
return ret;
}
- private @NonNull RestconfFuture<InvokeOperation> dataInvokePOST(final @NonNull Action path,
- final @NonNull OperationInputBody body) {
+ private @NonNull RestconfFuture<InvokeResult> dataInvokePOST(final @NonNull Action path,
+ final @NonNull OperationInputBody body, final Map<String, String> queryParameters) {
+ final InvokeParams params;
+ try {
+ params = InvokeParams.ofQueryParameters(queryParameters);
+ } catch (IllegalArgumentException e) {
+ return RestconfFuture.failed(new RestconfDocumentedException(e.getMessage(),
+ ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE, e));
+ }
+
final ContainerNode input;
try {
input = body.toContainerNode(path);
return RestconfFuture.failed(new RestconfDocumentedException("DOMActionService is missing."));
}
- final var future = dataInvokePOST(actionService, path, input);
- return future.transform(result -> result.getOutput()
- .flatMap(output -> output.isEmpty() ? Optional.empty()
- : Optional.of(new InvokeOperation(new OperationOutputBody(path, output, false))))
- .orElse(InvokeOperation.EMPTY));
+ return dataInvokePOST(actionService, path, input)
+ .transform(result -> outputToInvokeResult(path, params, result.getOutput().orElse(null)));
}
/**