private boolean eof;
public OpenApiInputStream(final EffectiveModelContext context, final String openApiVersion, final Info info,
- final List<Server> servers, final List<Map<String, List<String>>> security) throws IOException {
+ final List<Server> servers, final List<Map<String, List<String>>> security, final String deviceName,
+ final String urlPrefix) throws IOException {
final OpenApiBodyWriter writer = new OpenApiBodyWriter(generator, stream);
stack.add(new OpenApiVersionStream(new OpenApiVersionEntity(), writer));
stack.add(new InfoStream(new InfoEntity(info.version(), info.title(), info.description()), writer));
stack.add(new ServersStream(new ServersEntity(
List.of(new ServerEntity(servers.iterator().next().url()))), writer));
- stack.add(new PathsSteam(context, writer, generator, stream));
+ stack.add(new PathsSteam(context, writer, generator, stream, deviceName, urlPrefix));
stack.add(new SchemasStream(context, writer, generator, stream));
stack.add(new SecurityStream(writer));
}
private final JsonGenerator generator;
private final OpenApiBodyWriter writer;
private final ByteArrayOutputStream stream;
+ private final String deviceName;
+ private final String urlPrefix;
private Reader reader;
private boolean eof;
public PathsSteam(final EffectiveModelContext context, final OpenApiBodyWriter writer,
- final JsonGenerator generator, final ByteArrayOutputStream stream) {
+ final JsonGenerator generator, final ByteArrayOutputStream stream, final String deviceName,
+ final String urlPrefix) {
iterator = context.getModules().iterator();
this.generator = generator;
this.writer = writer;
this.stream = stream;
+ this.deviceName = deviceName;
+ this.urlPrefix = urlPrefix;
}
@Override
return super.read(array, off, len);
}
- private static Deque<PathEntity> toPaths(final Module module) {
+ private Deque<PathEntity> toPaths(final Module module) {
final var result = new ArrayDeque<PathEntity>();
// RPC operations (via post) - RPCs have their own path
for (final var rpc : module.getRpcs()) {
// TODO connect path with payload
- final var post = new PostEntity(rpc, "controller", module.getName());
- final String resolvedPath = "rests/operations/" + "/" + module.getName() + ":"
+ final var post = new PostEntity(rpc, deviceName, module.getName());
+ final String resolvedPath = "/rests/operations" + urlPrefix + "/" + module.getName() + ":"
+ rpc.getQName().getLocalName();
final var entity = new PathEntity(resolvedPath, post);
result.add(entity);
*/
package org.opendaylight.restconf.openapi.model;
+import static javax.ws.rs.core.Response.Status.NO_CONTENT;
+import static javax.ws.rs.core.Response.Status.OK;
+import static org.opendaylight.restconf.openapi.impl.DefinitionGenerator.OUTPUT_SUFFIX;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import java.io.IOException;
import javax.ws.rs.HttpMethod;
+import javax.ws.rs.core.MediaType;
+import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.yangtools.yang.model.api.OperationDefinition;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
public final class PostEntity extends OperationEntity {
private static final String SUMMARY_TEMPLATE = "%s - %s - %s - %s";
private static final String INPUT_SUFFIX = "_input";
+ private static final String INPUT_KEY = "input";
+ private static final String OBJECT = "object";
+ private static final String SCHEMA = "schema";
+ private static final String TYPE = "type";
+ private static final String DESCRIPTION = "description";
+ private static final String COMPONENTS_PREFIX = "#/components/schemas/";
public PostEntity(final OperationDefinition schema, final String deviceName, final String moduleName) {
super(schema, deviceName, moduleName);
final var operationName = schema().getQName().getLocalName() + INPUT_SUFFIX;
return SUMMARY_TEMPLATE.formatted(HttpMethod.POST, deviceName(), moduleName(), operationName);
}
+
+ @Override
+ void generateResponses(final @NonNull JsonGenerator generator) throws IOException {
+ if (schema() instanceof RpcDefinition rpc) {
+ generator.writeObjectFieldStart("responses");
+ final var output = rpc.getOutput();
+ final var operationName = rpc.getQName().getLocalName();
+ if (!output.getChildNodes().isEmpty()) {
+ // TODO: add proper discriminator from DefinitionNames when schemas re-implementation is done
+ final var ref = COMPONENTS_PREFIX + moduleName() + "_" + operationName + OUTPUT_SUFFIX;
+ generator.writeObjectFieldStart(String.valueOf(OK.getStatusCode()));
+ generator.writeStringField(DESCRIPTION, String.format("RPC %s success", operationName));
+
+ generator.writeObjectFieldStart("content");
+ generateMediaTypeSchemaRef(generator, MediaType.APPLICATION_JSON, ref);
+ generateMediaTypeSchemaRef(generator, MediaType.APPLICATION_XML, ref);
+ generator.writeEndObject();
+
+ generator.writeEndObject();
+
+ } else {
+ generator.writeObjectFieldStart(String.valueOf(NO_CONTENT.getStatusCode()));
+ generator.writeStringField(DESCRIPTION, String.format("RPC %s success", operationName));
+ generator.writeEndObject();
+
+ }
+ generator.writeEndObject();
+ }
+ }
+
+ @Override
+ void generateRequestBody(final @NonNull JsonGenerator generator) throws IOException {
+ if (schema() instanceof RpcDefinition rpc) {
+ generator.writeObjectFieldStart("requestBody");
+ final var input = rpc.getInput();
+ final var operationName = rpc.getQName().getLocalName();
+ generator.writeStringField(DESCRIPTION, operationName + INPUT_SUFFIX);
+ generator.writeObjectFieldStart("content");
+ if (!input.getChildNodes().isEmpty()) {
+ // TODO: add proper discriminator from DefinitionNames when schemas re-implementation is done
+ final var ref = COMPONENTS_PREFIX + moduleName() + "_" + operationName + INPUT_SUFFIX;
+ generator.writeObjectFieldStart(MediaType.APPLICATION_JSON);
+ generator.writeObjectFieldStart(SCHEMA);
+ generator.writeObjectFieldStart("properties");
+ generator.writeObjectFieldStart(INPUT_KEY);
+ generator.writeStringField("$ref", ref);
+ generator.writeStringField(TYPE, OBJECT);
+ generator.writeEndObject();
+ generator.writeEndObject();
+ generator.writeEndObject();
+ generator.writeEndObject();
+ generateMediaTypeSchemaRef(generator, MediaType.APPLICATION_XML, ref);
+ } else {
+ generator.writeObjectFieldStart(MediaType.APPLICATION_JSON);
+ generator.writeObjectFieldStart(SCHEMA);
+
+ generator.writeObjectFieldStart("properties");
+ generator.writeObjectFieldStart(INPUT_KEY);
+ generator.writeStringField(TYPE, OBJECT);
+ generator.writeEndObject();
+ generator.writeEndObject();
+
+ generator.writeStringField(TYPE, OBJECT);
+ generator.writeEndObject();
+ generator.writeEndObject();
+
+ generator.writeObjectFieldStart(MediaType.APPLICATION_XML);
+ generator.writeObjectFieldStart(SCHEMA);
+
+ generator.writeObjectFieldStart("xml");
+ generator.writeStringField("name", INPUT_KEY);
+ generator.writeStringField("namespace", input.getQName().getNamespace().toString());
+ generator.writeEndObject();
+
+ generator.writeStringField(TYPE, OBJECT);
+ generator.writeEndObject();
+ generator.writeEndObject();
+ }
+ generator.writeEndObject();
+ generator.writeEndObject();
+ }
+ }
+
+ private static void generateMediaTypeSchemaRef(final JsonGenerator generator, final String mediaType,
+ final String ref) throws IOException {
+ generator.writeObjectFieldStart(mediaType);
+ generator.writeObjectFieldStart(SCHEMA);
+ generator.writeStringField("$ref", ref);
+ generator.writeEndObject();
+ generator.writeEndObject();
+ }
}