Adapted REST API to use new logic.
Adapted tests for OpenApiInputStream.
JIRA: NETCONF-938
Change-Id: Idc6a35bb29f77c37e7ac70e873fd6b720fc5584d
Signed-off-by: Ivan Hrasko <ivan.hrasko@pantheon.tech>
Signed-off-by: lubos-cicut <lubos.cicut@pantheon.tech>
Signed-off-by: Yaroslav Lastivka <yaroslav.lastivka@pantheon.tech>
*/
package org.opendaylight.restconf.openapi.api;
+import java.io.IOException;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
@GET
@Path("/single")
@Produces(MediaType.APPLICATION_JSON)
- Response getAllModulesDoc(@Context UriInfo uriInfo);
+ Response getAllModulesDoc(@Context UriInfo uriInfo) throws IOException;
/**
* Generates Swagger compliant document listing APIs for module.
@Path("/{module}({revision})")
@Produces(MediaType.APPLICATION_JSON)
Response getDocByModule(@PathParam("module") String module, @PathParam("revision") String revision,
- @Context UriInfo uriInfo);
+ @Context UriInfo uriInfo) throws IOException;
/**
* Redirects to embedded swagger ui.
@Produces(MediaType.APPLICATION_JSON)
Response getMountDocByModule(@PathParam("instance") String instanceNum,
@PathParam("module") String module, @PathParam("revision") String revision,
- @Context UriInfo uriInfo);
+ @Context UriInfo uriInfo) throws IOException;
/**
* Generates Swagger compliant document listing APIs for all modules of mount point.
@GET
@Path("/mounts/{instance}")
@Produces(MediaType.APPLICATION_JSON)
- Response getMountDoc(@PathParam("instance") String instanceNum, @Context UriInfo uriInfo);
+ Response getMountDoc(@PathParam("instance") String instanceNum, @Context UriInfo uriInfo) throws IOException;
}
import static org.opendaylight.restconf.openapi.util.RestDocgenUtil.resolvePathArgumentsName;
import com.google.common.base.Preconditions;
-import com.google.common.collect.Range;
import java.io.IOException;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.ws.rs.core.UriInfo;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.mdsal.dom.api.DOMSchemaService;
-import org.opendaylight.restconf.openapi.model.Components;
-import org.opendaylight.restconf.openapi.model.Info;
-import org.opendaylight.restconf.openapi.model.OpenApiObject;
import org.opendaylight.restconf.openapi.model.Operation;
import org.opendaylight.restconf.openapi.model.Parameter;
import org.opendaylight.restconf.openapi.model.Path;
import org.opendaylight.restconf.openapi.model.Schema;
-import org.opendaylight.restconf.openapi.model.Server;
-import org.opendaylight.restconf.openapi.model.security.Http;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.Revision;
import org.opendaylight.yangtools.yang.model.api.ActionNodeContainer;
private static final Logger LOG = LoggerFactory.getLogger(BaseYangOpenApiGenerator.class);
private static final String CONTROLLER_RESOURCE_NAME = "Controller";
-
- public static final String API_VERSION = "1.0.0";
- public static final String OPEN_API_VERSION = "3.0.3";
public static final String BASE_PATH = "/";
public static final String MODULE_NAME_SUFFIX = "_module";
- public static final String BASIC_AUTH_NAME = "basicAuth";
- public static final Http OPEN_API_BASIC_AUTH = new Http("basic", null, null);
- public static final List<Map<String, List<String>>> SECURITY = List.of(Map.of(BASIC_AUTH_NAME, List.of()));
- public static final String DESCRIPTION = """
- We are providing full API for configurational data which can be edited (by POST, PUT, PATCH and DELETE).
- For operational data we only provide GET API.\n
- For majority of request you can see only config data in examples. That is because we can show only one example
- per request. The exception when you can see operational data in example is when data are representing
- operational (config false) container with no config data in it.""";
+ public static final List<Map<String, List<String>>> SECURITY = List.of(Map.of("basicAuth", List.of()));
private final DOMSchemaService schemaService;
this.schemaService = requireNonNull(schemaService);
}
- public OpenApiObject getControllerModulesDoc(final UriInfo uriInfo, final DefinitionNames definitionNames) {
+ public OpenApiInputStream getControllerModulesDoc(final UriInfo uriInfo) throws IOException {
final var context = requireNonNull(schemaService.getGlobalContext());
final var schema = createSchemaFromUriInfo(uriInfo);
final var host = createHostFromUriInfo(uriInfo);
final var title = "Controller modules of RESTCONF";
- final var info = new Info(API_VERSION, title, DESCRIPTION);
- final var servers = List.of(new Server(schema + "://" + host + BASE_PATH));
-
- final var paths = new HashMap<String, Path>();
- final var schemas = new HashMap<String, Schema>();
- for (final var module : getSortedModules(context)) {
- LOG.debug("Working on [{},{}]...", module.getName(), module.getQNameModule().getRevision().orElse(null));
- schemas.putAll(getSchemas(module, context, definitionNames, false));
- paths.putAll(getPaths(module, "", CONTROLLER_RESOURCE_NAME, context, definitionNames, false));
- }
-
- final var components = new Components(schemas, Map.of(BASIC_AUTH_NAME, OPEN_API_BASIC_AUTH));
- return new OpenApiObject(OPEN_API_VERSION, info, servers, paths, components, SECURITY);
+ final var url = schema + "://" + host + BASE_PATH;
+ final var modules = context.getModules();
+ return new OpenApiInputStream(context, title, url, SECURITY, CONTROLLER_RESOURCE_NAME, "",false, false,
+ modules);
}
- public static Set<Module> filterByRange(final SortedSet<Module> modules, final Range<Integer> range) {
- if (range.equals(Range.all())) {
- return modules;
- }
- final int begin = range.lowerEndpoint();
- final int end = range.upperEndpoint();
-
- Module firstModule = null;
-
- final Iterator<Module> iterator = modules.iterator();
- int counter = 0;
- while (iterator.hasNext() && counter < end) {
- final Module module = iterator.next();
- if (containsListOrContainer(module.getChildNodes()) || !module.getRpcs().isEmpty()) {
- if (counter == begin) {
- firstModule = module;
- }
- counter++;
- }
- }
-
- if (iterator.hasNext()) {
- return modules.subSet(firstModule, iterator.next());
- } else {
- return modules.tailSet(firstModule);
- }
- }
-
- public OpenApiObject getApiDeclaration(final String module, final String revision, final UriInfo uriInfo) {
+ public OpenApiInputStream getApiDeclaration(final String module, final String revision, final UriInfo uriInfo)
+ throws IOException {
final EffectiveModelContext schemaContext = schemaService.getGlobalContext();
Preconditions.checkState(schemaContext != null);
return getApiDeclaration(module, revision, uriInfo, schemaContext, "", CONTROLLER_RESOURCE_NAME);
}
- public OpenApiObject getApiDeclaration(final String moduleName, final String revision, final UriInfo uriInfo,
- final EffectiveModelContext schemaContext, final String context, final @NonNull String deviceName) {
+ public OpenApiInputStream getApiDeclaration(final String moduleName, final String revision, final UriInfo uriInfo,
+ final EffectiveModelContext schemaContext, final String urlPrefix, final @NonNull String deviceName)
+ throws IOException {
final Optional<Revision> rev;
try {
final var schema = createSchemaFromUriInfo(uriInfo);
final var host = createHostFromUriInfo(uriInfo);
- final var info = new Info(API_VERSION, module.getName(), DESCRIPTION);
- final var servers = List.of(new Server(schema + "://" + host + BASE_PATH));
- final var definitionNames = new DefinitionNames();
- final var schemas = getSchemas(module, schemaContext, definitionNames, true);
- final var components = new Components(schemas, Map.of(BASIC_AUTH_NAME, OPEN_API_BASIC_AUTH));
- final var paths = getPaths(module, context, deviceName, schemaContext, definitionNames, true);
- return new OpenApiObject(OPEN_API_VERSION, info, servers, paths, components, SECURITY);
+ final var title = module.getName();
+ final var url = schema + "://" + host + BASE_PATH;
+ final var modules = List.of(module);
+ return new OpenApiInputStream(schemaContext, title, url, SECURITY, deviceName, urlPrefix, true, false,
+ modules);
}
public String createHostFromUriInfo(final UriInfo uriInfo) {
}
}
- private static boolean containsListOrContainer(final Iterable<? extends DataSchemaNode> nodes) {
- for (final DataSchemaNode child : nodes) {
- if (child instanceof ListSchemaNode || child instanceof ContainerSchemaNode) {
- return true;
- }
- }
- return false;
- }
-
private static Path operations(final DataSchemaNode node, final String moduleName,
final String deviceName, final List<Parameter> pathParams, final boolean isConfig, final String parentName,
final DefinitionNames definitionNames, final String fullName) {
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayDeque;
+import java.util.Collection;
import java.util.Deque;
import java.util.List;
import java.util.Map;
import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
-import org.opendaylight.restconf.openapi.model.Info;
import org.opendaylight.restconf.openapi.model.InfoEntity;
import org.opendaylight.restconf.openapi.model.OpenApiVersionEntity;
import org.opendaylight.restconf.openapi.model.SecurityEntity;
-import org.opendaylight.restconf.openapi.model.Server;
import org.opendaylight.restconf.openapi.model.ServerEntity;
import org.opendaylight.restconf.openapi.model.ServersEntity;
import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.api.Module;
public final class OpenApiInputStream extends InputStream {
private final ByteArrayOutputStream stream = new ByteArrayOutputStream();
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, final String deviceName,
- final String urlPrefix, final boolean isForSingleModule, final boolean includeDataStore)
+ public OpenApiInputStream(final EffectiveModelContext context, final String title, final String url,
+ final List<Map<String, List<String>>> security, final String deviceName, final String urlPrefix,
+ final boolean isForSingleModule, final boolean includeDataStore, final Collection<? extends Module> modules)
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 InfoStream(new InfoEntity(title), writer));
+ stack.add(new ServersStream(new ServersEntity(List.of(new ServerEntity(url))), writer));
stack.add(new PathsStream(context, writer, generator, stream, deviceName, urlPrefix, isForSingleModule,
- includeDataStore));
- stack.add(new SchemasStream(context, writer, generator, stream));
+ includeDataStore, modules.iterator()));
+ stack.add(new SchemasStream(context, writer, generator, stream, modules.iterator()));
stack.add(new SecurityStream(writer, new SecurityEntity(security)));
}
import static java.util.Objects.requireNonNull;
import com.google.common.annotations.VisibleForTesting;
+import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;
import javax.inject.Inject;
import org.opendaylight.mdsal.dom.api.DOMSchemaService;
import org.opendaylight.restconf.openapi.api.OpenApiService;
import org.opendaylight.restconf.openapi.model.MountPointInstance;
-import org.opendaylight.restconf.openapi.model.OpenApiObject;
import org.opendaylight.restconf.openapi.mountpoints.MountPointOpenApi;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
}
@Override
- public Response getAllModulesDoc(final UriInfo uriInfo) {
- final DefinitionNames definitionNames = new DefinitionNames();
- final OpenApiObject doc = openApiGeneratorRFC8040.getControllerModulesDoc(uriInfo, definitionNames);
- return Response.ok(doc).build();
+ public Response getAllModulesDoc(final UriInfo uriInfo) throws IOException {
+ final OpenApiInputStream stream = openApiGeneratorRFC8040.getControllerModulesDoc(uriInfo);
+ return Response.ok(stream).build();
}
/**
* Generates Swagger compliant document listing APIs for module.
*/
@Override
- public Response getDocByModule(final String module, final String revision, final UriInfo uriInfo) {
- return Response.ok(
- openApiGeneratorRFC8040.getApiDeclaration(module, revision, uriInfo))
- .build();
+ public Response getDocByModule(final String module, final String revision, final UriInfo uriInfo)
+ throws IOException {
+ final OpenApiInputStream stream = openApiGeneratorRFC8040.getApiDeclaration(module, revision, uriInfo);
+ return Response.ok(stream).build();
}
/**
@Override
public Response getMountDocByModule(final String instanceNum, final String module,
- final String revision, final UriInfo uriInfo) {
- final OpenApiObject api = mountPointOpenApiRFC8040.getMountPointApi(uriInfo, Long.parseLong(instanceNum),
- module, revision);
- return Response.ok(api).build();
+ final String revision, final UriInfo uriInfo) throws IOException {
+ final OpenApiInputStream stream =
+ mountPointOpenApiRFC8040.getMountPointApi(uriInfo, Long.parseLong(instanceNum), module, revision);
+ return Response.ok(stream).build();
}
@Override
- public Response getMountDoc(final String instanceNum, final UriInfo uriInfo) {
+ public Response getMountDoc(final String instanceNum, final UriInfo uriInfo) throws IOException {
final String stringPageNum = uriInfo.getQueryParameters().getFirst(PAGE_NUM);
- final OpenApiObject api = mountPointOpenApiRFC8040.getMountPointApi(uriInfo,
- Long.parseLong(instanceNum), stringPageNum);
- return Response.ok(api).build();
+ final OpenApiInputStream stream =
+ mountPointOpenApiRFC8040.getMountPointApi(uriInfo, Long.parseLong(instanceNum), stringPageNum);
+ return Response.ok(stream).build();
}
}
public PathsStream(final EffectiveModelContext schemaContext, final OpenApiBodyWriter writer,
final JsonGenerator generator, final ByteArrayOutputStream stream, final String deviceName,
- final String urlPrefix, final boolean isForSingleModule, final boolean includeDataStore) {
- iterator = schemaContext.getModules().iterator();
+ final String urlPrefix, final boolean isForSingleModule, final boolean includeDataStore,
+ final Iterator<? extends Module> iterator) {
+ this.iterator = iterator;
this.generator = generator;
this.writer = writer;
this.stream = stream;
private boolean eos;
public SchemasStream(final EffectiveModelContext context, final OpenApiBodyWriter writer,
- final JsonGenerator generator, final ByteArrayOutputStream stream) {
- iterator = context.getModules().iterator();
+ final JsonGenerator generator, final ByteArrayOutputStream stream,
+ final Iterator<? extends Module> iterator) {
+ this.iterator = iterator;
this.context = context;
this.writer = writer;
this.generator = generator;
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.restconf.openapi.jaxrs;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.ext.ContextResolver;
+import javax.ws.rs.ext.Provider;
+
+@Provider
+@Consumes(MediaType.APPLICATION_JSON)
+@Produces(MediaType.APPLICATION_JSON)
+public class JaxbContextResolver implements ContextResolver<ObjectMapper> {
+
+ @Override
+ public ObjectMapper getContext(final Class<?> klass) {
+ return null; // must return null so that JAX-RS can continue context search
+ }
+}
import org.eclipse.jdt.annotation.NonNull;
public final class InfoEntity extends OpenApiEntity {
- private final String version;
private final String title;
- private final String description;
+ private static final String DESCRIPTION = """
+ We are providing full API for configurational data which can be edited (by POST, PUT, PATCH and DELETE).
+ For operational data we only provide GET API.\n
+ For majority of request you can see only config data in examples. That is because we can show only one example
+ per request. The exception when you can see operational data in example is when data are representing
+ operational (config false) container with no config data in it.""";
- public InfoEntity(final String version, final String title, final String description) {
- this.version = version;
+ public InfoEntity(final String title) {
this.title = title;
- this.description = description;
}
@Override
public void generate(@NonNull JsonGenerator generator) throws IOException {
generator.writeObjectFieldStart("info");
- if (version != null) {
- generator.writeStringField("version", version);
- }
+ generator.writeStringField("version", "1.0.0");
if (title != null) {
generator.writeStringField("title", title);
}
- if (description != null) {
- generator.writeStringField("description", description);
- }
+ generator.writeStringField("description", DESCRIPTION);
generator.writeEndObject();
}
}
+++ /dev/null
-/*
- * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.restconf.openapi.model;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonInclude.Include;
-import java.util.List;
-import java.util.Map;
-
-@JsonInclude(Include.NON_NULL)
-public record OpenApiObject(
- String openapi,
- Info info,
- List<Server> servers,
- Map<String, Path> paths,
- Components components,
- List<Map<String, List<String>>> security) {
-}
import static java.util.Objects.requireNonNull;
-import com.fasterxml.jackson.annotation.JsonInclude;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
-@JsonInclude(JsonInclude.Include.NON_NULL)
public record Http(
@NonNull String scheme,
@Nullable String description,
*/
package org.opendaylight.restconf.openapi.model.security;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-@JsonInclude(JsonInclude.Include.NON_NULL)
public interface SecuritySchemeObject {
- @JsonProperty("type")
Type type();
/**
import static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;
-import static org.opendaylight.restconf.openapi.impl.BaseYangOpenApiGenerator.API_VERSION;
import static org.opendaylight.restconf.openapi.impl.BaseYangOpenApiGenerator.BASE_PATH;
-import static org.opendaylight.restconf.openapi.impl.BaseYangOpenApiGenerator.BASIC_AUTH_NAME;
-import static org.opendaylight.restconf.openapi.impl.BaseYangOpenApiGenerator.DESCRIPTION;
-import static org.opendaylight.restconf.openapi.impl.BaseYangOpenApiGenerator.OPEN_API_BASIC_AUTH;
-import static org.opendaylight.restconf.openapi.impl.BaseYangOpenApiGenerator.OPEN_API_VERSION;
import static org.opendaylight.restconf.openapi.impl.BaseYangOpenApiGenerator.SECURITY;
-import static org.opendaylight.restconf.openapi.impl.BaseYangOpenApiGenerator.filterByRange;
-import static org.opendaylight.restconf.openapi.impl.BaseYangOpenApiGenerator.getSortedModules;
-import static org.opendaylight.restconf.openapi.impl.OpenApiServiceImpl.DEFAULT_PAGESIZE;
-import static org.opendaylight.restconf.openapi.model.builder.OperationBuilder.SUMMARY_TEMPLATE;
-import com.google.common.collect.Range;
+import java.io.IOException;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicLong;
-import javax.ws.rs.HttpMethod;
-import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.mdsal.dom.api.DOMMountPointListener;
import org.opendaylight.mdsal.dom.api.DOMMountPointService;
import org.opendaylight.mdsal.dom.api.DOMSchemaService;
import org.opendaylight.restconf.openapi.impl.BaseYangOpenApiGenerator;
-import org.opendaylight.restconf.openapi.impl.DefinitionNames;
-import org.opendaylight.restconf.openapi.model.Components;
-import org.opendaylight.restconf.openapi.model.Info;
-import org.opendaylight.restconf.openapi.model.OpenApiObject;
-import org.opendaylight.restconf.openapi.model.Operation;
-import org.opendaylight.restconf.openapi.model.Path;
-import org.opendaylight.restconf.openapi.model.ResponseObject;
-import org.opendaylight.restconf.openapi.model.Schema;
-import org.opendaylight.restconf.openapi.model.Server;
+import org.opendaylight.restconf.openapi.impl.OpenApiInputStream;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
.orElse(null);
}
- public OpenApiObject getMountPointApi(final UriInfo uriInfo, final Long id, final String module,
- final String revision) {
+ public OpenApiInputStream getMountPointApi(final UriInfo uriInfo, final Long id, final String module,
+ final String revision) throws IOException {
final YangInstanceIdentifier iid = getInstanceId(id);
final EffectiveModelContext context = getSchemaContext(iid);
final String urlPrefix = getYangMountUrl(iid);
- final String deviceName = extractDeviceName(iid);
+ final String deviceName = extractDeviceName(iid);
if (context == null) {
return null;
}
if (DATASTORES_LABEL.equals(module) && DATASTORES_REVISION.equals(revision)) {
- return generateDataStoreOpenApi(uriInfo, urlPrefix, deviceName);
+ return generateDataStoreOpenApi(context, uriInfo, urlPrefix, deviceName);
}
return openApiGenerator.getApiDeclaration(module, revision, uriInfo, context, urlPrefix, deviceName);
}
- public OpenApiObject getMountPointApi(final UriInfo uriInfo, final Long id, final @Nullable String strPageNum) {
+ public OpenApiInputStream getMountPointApi(final UriInfo uriInfo, final Long id, final @Nullable String strPageNum)
+ throws IOException {
final var iid = getInstanceId(id);
final var context = getSchemaContext(iid);
final var urlPrefix = getYangMountUrl(iid);
if (context == null) {
return null;
}
- final var definitionNames = new DefinitionNames();
boolean includeDataStore = true;
- Range<Integer> range = Range.all();
if (strPageNum != null) {
final var pageNum = Integer.parseInt(strPageNum);
- final var end = DEFAULT_PAGESIZE * pageNum - 1;
- int start = end - DEFAULT_PAGESIZE;
- if (pageNum == 1) {
- start++;
- } else {
+ if (pageNum != 1) {
includeDataStore = false;
}
- range = Range.closed(start, end);
}
final var schema = openApiGenerator.createSchemaFromUriInfo(uriInfo);
final var host = openApiGenerator.createHostFromUriInfo(uriInfo);
final var title = deviceName + " modules of RESTCONF";
- final var info = new Info(API_VERSION, title, DESCRIPTION);
- final var servers = List.of(new Server(schema + "://" + host + BASE_PATH));
-
- final var modules = getSortedModules(context);
- final var filteredModules = filterByRange(modules, range);
- final var paths = new HashMap<String, Path>();
- final var schemas = new HashMap<String, Schema>();
- for (final var module : filteredModules) {
- LOG.debug("Working on [{},{}]...", module.getName(), module.getQNameModule().getRevision().orElse(null));
- schemas.putAll(openApiGenerator.getSchemas(module, context, definitionNames, false));
- paths.putAll(openApiGenerator.getPaths(module, urlPrefix, deviceName, context, definitionNames, false));
- }
- final var components = new Components(schemas, Map.of(BASIC_AUTH_NAME, OPEN_API_BASIC_AUTH));
- if (includeDataStore) {
- paths.putAll(getDataStoreApiPaths(urlPrefix, deviceName));
- }
- return new OpenApiObject(OPEN_API_VERSION, info, servers, paths, components, SECURITY);
+ final var url = schema + "://" + host + BASE_PATH;
+ final var modules = context.getModules();
+ return new OpenApiInputStream(context, title, url, SECURITY, deviceName, urlPrefix, false, includeDataStore,
+ modules);
}
private static String extractDeviceName(final YangInstanceIdentifier iid) {
.values().getElement().toString();
}
- private OpenApiObject generateDataStoreOpenApi(final UriInfo uriInfo, final String context,
- final String deviceName) {
- final var info = new Info(API_VERSION, context, DESCRIPTION);
+ private OpenApiInputStream generateDataStoreOpenApi(EffectiveModelContext modelContext,
+ final UriInfo uriInfo, final String urlPrefix, final String deviceName) throws IOException {
final var schema = openApiGenerator.createSchemaFromUriInfo(uriInfo);
final var host = openApiGenerator.createHostFromUriInfo(uriInfo);
- final var servers = List.of(new Server(schema + "://" + host + BASE_PATH));
- final var components = new Components(new HashMap<>(), Map.of(BASIC_AUTH_NAME, OPEN_API_BASIC_AUTH));
- final var paths = getDataStoreApiPaths(context, deviceName);
- return new OpenApiObject(OPEN_API_VERSION, info, servers, paths, components, SECURITY);
- }
-
- private Map<String, Path> getDataStoreApiPaths(final String context, final String deviceName) {
- final var dataBuilder = new Path.Builder();
- dataBuilder.get(createGetPathItem("data",
- "Queries the config (startup) datastore on the mounted hosted.", deviceName));
-
- final var operationsBuilder = new Path.Builder();
- operationsBuilder.get(createGetPathItem("operations",
- "Queries the available operations (RPC calls) on the mounted hosted.", deviceName));
-
- return Map.of(openApiGenerator.getResourcePath("data", context), dataBuilder.build(),
- openApiGenerator.getResourcePath("operations", context), operationsBuilder.build());
- }
-
- private static Operation createGetPathItem(final String resourceType, final String description,
- final String deviceName) {
- final String summary = SUMMARY_TEMPLATE.formatted(HttpMethod.GET, deviceName, "datastore", resourceType);
- final List<String> tags = List.of(deviceName + " GET root");
- final ResponseObject okResponse = new ResponseObject.Builder()
- .description(Response.Status.OK.getReasonPhrase())
- .build();
- return new Operation.Builder()
- .tags(tags)
- .responses(Map.of(String.valueOf(Response.Status.OK.getStatusCode()), okResponse))
- .description(description)
- .summary(summary)
- .build();
+ final var url = schema + "://" + host + BASE_PATH;
+ final var modules = modelContext.getModules();
+ return new OpenApiInputStream(modelContext, urlPrefix, url, SECURITY, deviceName, urlPrefix, true, false,
+ modules);
}
@Override
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
+import java.nio.charset.StandardCharsets;
import java.util.Optional;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
final var getAllController = createMockUriInfo(URI + "single");
final var controllerDocAll = openApiService.getAllModulesDoc(getAllController).getEntity();
- return MAPPER.writeValueAsString(controllerDocAll);
+ return new String(((OpenApiInputStream) controllerDocAll).readAllBytes(),
+ StandardCharsets.UTF_8);
}
protected static String getDocByModule(final String moduleName, final String revision) throws Exception {
final var getModuleController = createMockUriInfo(uri);
final var controllerDocModule = openApiService.getDocByModule(moduleName, revision, getModuleController);
- return MAPPER.writeValueAsString(controllerDocModule.getEntity());
+ return new String(((OpenApiInputStream) controllerDocModule.getEntity()).readAllBytes(),
+ StandardCharsets.UTF_8);
}
when(getAllDevice.getQueryParameters()).thenReturn(ImmutableMultivaluedMap.empty());
final var deviceDocAll = openApiService.getMountDoc("1", getAllDevice);
- return MAPPER.writeValueAsString(deviceDocAll.getEntity());
+ return new String(((OpenApiInputStream) deviceDocAll.getEntity()).readAllBytes(),
+ StandardCharsets.UTF_8);
}
final var getDevice = createMockUriInfo(URI + "mounts/1/" + moduleName);
final var deviceDoc = openApiService.getMountDocByModule("1", moduleName, revision, getDevice);
- return MAPPER.writeValueAsString(deviceDoc.getEntity());
+ return new String(((OpenApiInputStream) deviceDoc.getEntity()).readAllBytes(),
+ StandardCharsets.UTF_8);
}
public static UriInfo createMockUriInfo(final String urlPrefix) throws Exception {