import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
+import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
ImmutableNodes.leafNode(YANG_LIBRARY_VERSION, YANG_LIBRARY_REVISION));
}
+ @Override
+ public String operationsGET(final OperationsContent contentType) {
+ return operationsGET(contentType, bindRequestRoot().inference());
+ }
+
+ @Override
+ public String operationsGET(final OperationsContent contentType, final String operation) {
+ return operationsGET(contentType, bindRequestPath(operation).inference());
+ }
+
+ @VisibleForTesting
+ static @NonNull String operationsGET(final OperationsContent contentType, final @NonNull Inference inference) {
+ return contentType.bodyFor(inference);
+ }
+
@Override
public RestconfFuture<OperationOutput> operationsPOST(final URI restconfURI, final String apiPath,
final OperationInputBody body) {
* RESTCONF {@code /operations} content for a {@code GET} operation as per
* <a href="https://www.rfc-editor.org/rfc/rfc8040#section-3.3.2">RFC8040</a>.
*/
-enum OperationsContent {
+public enum OperationsContent {
JSON("{ \"ietf-restconf:operations\" : { } }") {
@Override
String createBody(final List<Entry<String, List<String>>> rpcsByPrefix) {
@Path("/operations")
@Produces({ MediaTypes.APPLICATION_YANG_DATA_JSON, MediaType.APPLICATION_JSON })
public String getOperationsJSON() {
- return OperationsContent.JSON.bodyFor(server.bindRequestRoot().inference());
+ return server.operationsGET(OperationsContent.JSON);
}
/**
@Path("/operations/{identifier:.+}")
@Produces({ MediaTypes.APPLICATION_YANG_DATA_JSON, MediaType.APPLICATION_JSON })
public String getOperationJSON(@PathParam("identifier") final String identifier) {
- return OperationsContent.JSON.bodyFor(server.bindRequestPath(identifier).inference());
+ return server.operationsGET(OperationsContent.JSON, identifier);
}
/**
@GET
@Path("/operations")
@Produces({ MediaTypes.APPLICATION_YANG_DATA_XML, MediaType.APPLICATION_XML, MediaType.TEXT_XML })
- public String getOperationsXML() {
- return OperationsContent.XML.bodyFor(server.bindRequestRoot().inference());
+ public String operationsGetXML() {
+ return server.operationsGET(OperationsContent.XML);
}
/**
@GET
@Path("/operations/{identifier:.+}")
@Produces({ MediaTypes.APPLICATION_YANG_DATA_XML, MediaType.APPLICATION_XML, MediaType.TEXT_XML })
- public String getOperationXML(@PathParam("identifier") final String identifier) {
- return OperationsContent.XML.bodyFor(server.bindRequestPath(identifier).inference());
+ public String operationsGetXML(@PathParam("identifier") final String identifier) {
+ return server.operationsGET(OperationsContent.XML, identifier);
}
/**
MediaType.APPLICATION_XML,
MediaType.TEXT_XML
})
- public void invokeRpcXML(@Encoded @PathParam("identifier") final String identifier, final InputStream body,
+ public void operationsPostXML(@Encoded @PathParam("identifier") final String identifier, final InputStream body,
@Context final UriInfo uriInfo, @Suspended final AsyncResponse ar) {
try (var xmlBody = new XmlOperationInputBody(body)) {
- invokeRpc(identifier, uriInfo, ar, xmlBody);
+ operationsPOST(identifier, uriInfo, ar, xmlBody);
}
}
MediaType.APPLICATION_XML,
MediaType.TEXT_XML
})
- public void invokeRpcJSON(@Encoded @PathParam("identifier") final String identifier, final InputStream body,
+ public void operationsPostJSON(@Encoded @PathParam("identifier") final String identifier, final InputStream body,
@Context final UriInfo uriInfo, @Suspended final AsyncResponse ar) {
try (var jsonBody = new JsonOperationInputBody(body)) {
- invokeRpc(identifier, uriInfo, ar, jsonBody);
+ operationsPOST(identifier, uriInfo, ar, jsonBody);
}
}
- private void invokeRpc(final String identifier, final UriInfo uriInfo, final AsyncResponse ar,
+ private void operationsPOST(final String identifier, final UriInfo uriInfo, final AsyncResponse ar,
final OperationInputBody body) {
server.operationsPOST(uriInfo.getBaseUri(), identifier, body)
.addCallback(new JaxRsRestconfCallback<OperationOutput>(ar) {
import org.opendaylight.restconf.common.errors.RestconfFuture;
import org.opendaylight.restconf.nb.rfc8040.databind.OperationInputBody;
import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
+import org.opendaylight.restconf.nb.rfc8040.rests.services.impl.OperationsContent;
import org.opendaylight.restconf.server.spi.OperationOutput;
/**
// FIXME: RestconfFuture if we transition to being used by restconf-client implementation
NormalizedNodePayload yangLibraryVersionGET();
+ /**
+ * Return the set of supported RPCs supported by {@link #operationsPOST(URI, String, OperationInputBody)}.
+ *
+ * @param contentType Formatting type
+ * @return A formatted string
+ */
+ String operationsGET(OperationsContent contentType);
+
+ /*
+ * Return the details about a particular operation supported by
+ * {@link #operationsPOST(URI, String, OperationInputBody)}, as expressed in the
+ * <a href="https://www.rfc-editor.org/rfc/rfc8040#page-84>RFC8040<a> {@code container operations} statement.
+ *
+ * @param contentType Formatting type
+ * @param operation An operation
+ * @return A formatted string
+ */
+ // FIXME: 'operation' should really be an ApiIdentifier with non-null module, but we also support ang-ext:mount,
+ // and hence it is a path right now
+ // FIXME: use ApiPath instead of String
+ String operationsGET(OperationsContent contentType, String operation);
+
/**
* Invoke an RPC operation, as defined in
* <a href="https://www.rfc-editor.org/rfc/rfc8040#section-3.6">RFC8040 Operation Resource</a>.
"foo:new": [null],
"foo:new1": [null]
}
- }""", OperationsContent.JSON.bodyFor(SchemaInferenceStack.of(SCHEMA).toInference()));
+ }""",
+ MdsalRestconfServer.operationsGET(OperationsContent.JSON, SchemaInferenceStack.of(SCHEMA).toInference()));
}
@Test
"ietf-restconf:operations" : {
"foo:new1": [null]
}
- }""", OperationsContent.JSON.bodyFor(SchemaInferenceStack.of(SCHEMA, NEW1).toInference()));
+ }""",
+ MdsalRestconfServer.operationsGET(OperationsContent.JSON, SchemaInferenceStack.of(SCHEMA, NEW1).toInference()));
}
@Test
xmlns:ns0="foo" >
<ns0:new/>
<ns0:new1/>
- </operations>""", OperationsContent.XML.bodyFor(SchemaInferenceStack.of(SCHEMA).toInference()));
+ </operations>""",
+ MdsalRestconfServer.operationsGET(OperationsContent.XML, SchemaInferenceStack.of(SCHEMA).toInference()));
}
@Test
<operations xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf"
xmlns:ns0="foo" >
<ns0:new1/>
- </operations>""", OperationsContent.XML.bodyFor(SchemaInferenceStack.of(SCHEMA, NEW1).toInference()));
+ </operations>""",
+ MdsalRestconfServer.operationsGET(OperationsContent.XML,
+ SchemaInferenceStack.of(SCHEMA, NEW1).toInference()));
}
}
prepNNC(result);
final var ar = mock(AsyncResponse.class);
final var captor = ArgumentCaptor.forClass(Response.class);
- invokeOperationsService.invokeRpcXML("invoke-rpc-module:rpc-test", new ByteArrayInputStream("""
+ invokeOperationsService.operationsPostXML("invoke-rpc-module:rpc-test", new ByteArrayInputStream("""
<input xmlns="invoke:rpc:module"/>
""".getBytes(StandardCharsets.UTF_8)), mock(UriInfo.class), ar);
verify(ar).resume(captor.capture());
prepNNC(result);
final var ar = mock(AsyncResponse.class);
final var response = ArgumentCaptor.forClass(Response.class);
- invokeOperationsService.invokeRpcJSON("invoke-rpc-module:rpc-test", new ByteArrayInputStream("""
+ invokeOperationsService.operationsPostJSON("invoke-rpc-module:rpc-test", new ByteArrayInputStream("""
{
"invoke-rpc-module:input" : {
}
@Test
public void testOperationsXml() {
- final var operationsXML = opService.getOperationsXML();
+ final var operationsXML = opService.operationsGetXML();
assertEquals(EXPECTED_XML, operationsXML);
}
@Test
public void testMountPointOperationsXml() {
- final var operationXML = opService.getOperationXML(DEVICE_ID);
+ final var operationXML = opService.operationsGetXML(DEVICE_ID);
assertEquals(EXPECTED_XML, operationXML);
}
@Test
public void testMountPointSpecificOperationsXml() {
- final var operationXML = opService.getOperationXML(DEVICE_RPC1_MODULE1_ID);
+ final var operationXML = opService.operationsGetXML(DEVICE_RPC1_MODULE1_ID);
assertEquals("""
<?xml version="1.0" encoding="UTF-8"?>
<operations xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf"