From 588a9496bd3ccadc3bbfbe6a2d6d15223078ac85 Mon Sep 17 00:00:00 2001 From: Tom Pantelis Date: Thu, 26 Apr 2018 10:08:55 -0400 Subject: [PATCH 1/1] Convert apidocs to new web API The ApiDocGenerator and MountPointSwagger classes were overloaded to handle draft02 and rfc8040 differences via a 'newDraft' flag. To facilitate elimination of the static instances, the classes were refactored to remove the flag and implement the differences via abstract methods and derived classes. Change-Id: I950dfceac40b0aee1bafb4d8b78d36d1ef67eadc Signed-off-by: Tom Pantelis --- .../rest/doc/maven/StaticDocGenerator.java | 13 ++- restconf/sal-rest-docgen/pom.xml | 21 ++-- .../netconf/sal/rest/doc/DocProvider.java | 49 -------- .../sal/rest/doc/impl/ApiDocGenerator.java | 50 -------- .../rest/doc/impl/ApiDocGeneratorDraftO2.java | 23 ++++ .../rest/doc/impl/ApiDocGeneratorRFC8040.java | 25 ++++ .../sal/rest/doc/impl/ApiDocServiceImpl.java | 44 ++++--- .../doc/impl/BaseYangSwaggerGenerator.java | 110 ++++++++++-------- .../impl/BaseYangSwaggerGeneratorDraft02.java | 44 +++++++ .../impl/BaseYangSwaggerGeneratorRFC8040.java | 63 ++++++++++ .../MountPointSwaggerGeneratorDraft02.java | 39 +++++++ .../MountPointSwaggerGeneratorRFC8040.java | 38 ++++++ .../sal/rest/doc/jaxrs/ApiDocApplication.java | 10 +- .../sal/rest/doc/jaxrs/WebInitializer.java | 45 +++++++ .../doc/mountpoints/MountPointSwagger.java | 108 ++++++----------- .../src/main/resources/WEB-INF/web.xml | 79 ------------- .../org/opendaylight/blueprint/blueprint.xml | 41 ++++++- .../rest/doc/impl/ApiDocGeneratorTest.java | 14 +-- .../rest/doc/impl/MountPointSwaggerTest.java | 51 ++++---- 19 files changed, 488 insertions(+), 379 deletions(-) delete mode 100644 restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/DocProvider.java delete mode 100644 restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocGenerator.java create mode 100644 restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocGeneratorDraftO2.java create mode 100644 restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocGeneratorRFC8040.java create mode 100644 restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGeneratorDraft02.java create mode 100644 restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGeneratorRFC8040.java create mode 100644 restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/MountPointSwaggerGeneratorDraft02.java create mode 100644 restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/MountPointSwaggerGeneratorRFC8040.java create mode 100644 restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/jaxrs/WebInitializer.java delete mode 100644 restconf/sal-rest-docgen/src/main/resources/WEB-INF/web.xml diff --git a/restconf/sal-rest-docgen-maven/src/main/java/org/opendaylight/netconf/sal/rest/doc/maven/StaticDocGenerator.java b/restconf/sal-rest-docgen-maven/src/main/java/org/opendaylight/netconf/sal/rest/doc/maven/StaticDocGenerator.java index e09c73ed4d..4ce00e647a 100644 --- a/restconf/sal-rest-docgen-maven/src/main/java/org/opendaylight/netconf/sal/rest/doc/maven/StaticDocGenerator.java +++ b/restconf/sal-rest-docgen-maven/src/main/java/org/opendaylight/netconf/sal/rest/doc/maven/StaticDocGenerator.java @@ -23,7 +23,7 @@ import java.util.Set; import java.util.function.Function; import javax.ws.rs.core.UriInfo; import org.apache.maven.project.MavenProject; -import org.opendaylight.netconf.sal.rest.doc.impl.ApiDocGenerator; +import org.opendaylight.netconf.sal.rest.doc.impl.BaseYangSwaggerGeneratorDraft02; import org.opendaylight.netconf.sal.rest.doc.swagger.ApiDeclaration; import org.opendaylight.netconf.sal.rest.doc.swagger.Resource; import org.opendaylight.netconf.sal.rest.doc.swagger.ResourceList; @@ -37,12 +37,17 @@ import org.slf4j.LoggerFactory; /** * This class gathers all yang defined {@link Module}s and generates Swagger compliant documentation. */ -public class StaticDocGenerator extends ApiDocGenerator implements BasicCodeGenerator, MavenProjectAware { +public class StaticDocGenerator extends BaseYangSwaggerGeneratorDraft02 + implements BasicCodeGenerator, MavenProjectAware { private static final Logger LOG = LoggerFactory.getLogger(StaticDocGenerator.class); private static final String DEFAULT_OUTPUT_BASE_DIR_PATH = "target" + File.separator + "generated-resources" + File.separator + "swagger-api-documentation"; + public StaticDocGenerator() { + super(Optional.empty()); + } + @Override @SuppressFBWarnings("DM_DEFAULT_ENCODING") public Collection generateSources(final SchemaContext context, final File outputBaseDir, @@ -115,7 +120,7 @@ public class StaticDocGenerator extends ApiDocGenerator implements BasicCodeGene } @Override - protected String generatePath(final UriInfo uriInfo, final String name, final String revision) { + public String generatePath(final UriInfo uriInfo, final String name, final String revision) { if (uriInfo == null) { return name + "(" + revision + ")"; } @@ -123,7 +128,7 @@ public class StaticDocGenerator extends ApiDocGenerator implements BasicCodeGene } @Override - protected String createBasePathFromUriInfo(final UriInfo uriInfo) { + public String createBasePathFromUriInfo(final UriInfo uriInfo) { if (uriInfo == null) { return RESTCONF_CONTEXT_ROOT; } diff --git a/restconf/sal-rest-docgen/pom.xml b/restconf/sal-rest-docgen/pom.xml index a3086cf765..a4a3e1ffd3 100644 --- a/restconf/sal-rest-docgen/pom.xml +++ b/restconf/sal-rest-docgen/pom.xml @@ -104,6 +104,15 @@ aaa-shiro 0.8.0-SNAPSHOT + + org.opendaylight.aaa.web + web-api + 0.8.0-SNAPSHOT + + + com.sun.jersey + jersey-servlet + @@ -117,21 +126,9 @@ MD SAL Rest Api Doc Generator generex, automaton - - - *, - com.sun.jersey.spi.container.servlet, - org.eclipse.jetty.servlets, - org.opendaylight.aaa.shiro.filters, - org.opendaylight.aaa.shiro.realm, - org.opendaylight.aaa.shiro.web.env, - org.apache.shiro.web.env, - org.opendaylight.aaa.api - com.fasterxml.jackson.datatype.* - /apidoc diff --git a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/DocProvider.java b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/DocProvider.java deleted file mode 100644 index ab84e302e1..0000000000 --- a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/DocProvider.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2014, 2017 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.netconf.sal.rest.doc; - -import java.util.LinkedList; -import java.util.List; -import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService; -import org.opendaylight.controller.sal.core.api.model.SchemaService; -import org.opendaylight.controller.sal.core.api.mount.MountProvisionListener; -import org.opendaylight.netconf.sal.rest.doc.impl.ApiDocGenerator; -import org.opendaylight.netconf.sal.rest.doc.mountpoints.MountPointSwagger; -import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class DocProvider { - - private static final Logger LOG = LoggerFactory.getLogger(DocProvider.class); - - private final List toClose = new LinkedList<>(); - - public DocProvider(final SchemaService schemaService, final DOMMountPointService mountService) { - - ApiDocGenerator.getInstance().setSchemaService(schemaService); - - final ListenerRegistration registration = mountService - .registerProvisionListener(MountPointSwagger.getInstance()); - MountPointSwagger.getInstance().setGlobalSchema(schemaService); - synchronized (toClose) { - toClose.add(registration); - } - MountPointSwagger.getInstance().setMountService(mountService); - - LOG.debug("Restconf API Explorer started"); - } - - public void close() throws Exception { - synchronized (toClose) { - for (final AutoCloseable close : toClose) { - close.close(); - } - } - } -} diff --git a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocGenerator.java b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocGenerator.java deleted file mode 100644 index 76030f380c..0000000000 --- a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocGenerator.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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.netconf.sal.rest.doc.impl; - -import com.google.common.base.Preconditions; -import javax.ws.rs.core.UriInfo; -import org.opendaylight.controller.sal.core.api.model.SchemaService; -import org.opendaylight.netconf.sal.rest.doc.swagger.ApiDeclaration; -import org.opendaylight.netconf.sal.rest.doc.swagger.ResourceList; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; - -/** - * This class gathers all YANG-defined {@link org.opendaylight.yangtools.yang.model.api.Module}s and - * generates Swagger compliant documentation. - */ -public class ApiDocGenerator extends BaseYangSwaggerGenerator { - - private static final ApiDocGenerator INSTANCE = new ApiDocGenerator(); - private SchemaService schemaService; - - public ResourceList getResourceListing(final UriInfo uriInfo) { - Preconditions.checkState(schemaService != null); - final SchemaContext schemaContext = schemaService.getGlobalContext(); - Preconditions.checkState(schemaContext != null); - return super.getResourceListing(uriInfo, schemaContext, ""); - } - - public ApiDeclaration getApiDeclaration(final String module, final String revision, final UriInfo uriInfo) { - Preconditions.checkState(schemaService != null); - final SchemaContext schemaContext = schemaService.getGlobalContext(); - Preconditions.checkState(schemaContext != null); - return super.getApiDeclaration(module, revision, uriInfo, schemaContext, ""); - } - - /** - * Returns singleton instance. - */ - public static ApiDocGenerator getInstance() { - return INSTANCE; - } - - public void setSchemaService(final SchemaService schemaService) { - this.schemaService = schemaService; - } -} diff --git a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocGeneratorDraftO2.java b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocGeneratorDraftO2.java new file mode 100644 index 0000000000..5058f7fedc --- /dev/null +++ b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocGeneratorDraftO2.java @@ -0,0 +1,23 @@ +/* + * 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.netconf.sal.rest.doc.impl; + +import java.util.Objects; +import java.util.Optional; +import org.opendaylight.controller.sal.core.api.model.SchemaService; + +/** + * This class gathers all YANG-defined {@link org.opendaylight.yangtools.yang.model.api.Module}s and + * generates Swagger compliant documentation for the bierman draft02 version. + */ +public class ApiDocGeneratorDraftO2 extends BaseYangSwaggerGeneratorDraft02 { + + public ApiDocGeneratorDraftO2(SchemaService schemaService) { + super(Optional.of(Objects.requireNonNull(schemaService))); + } +} diff --git a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocGeneratorRFC8040.java b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocGeneratorRFC8040.java new file mode 100644 index 0000000000..5edb65d5a6 --- /dev/null +++ b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocGeneratorRFC8040.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2018 Inocybe Technologies 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.netconf.sal.rest.doc.impl; + +import java.util.Objects; +import java.util.Optional; +import org.opendaylight.controller.sal.core.api.model.SchemaService; + +/** + * This class gathers all YANG-defined {@link org.opendaylight.yangtools.yang.model.api.Module}s and + * generates Swagger compliant documentation for the RFC 8040 version. + * + * @author Thomas Pantelis + */ +public class ApiDocGeneratorRFC8040 extends BaseYangSwaggerGeneratorRFC8040 { + + public ApiDocGeneratorRFC8040(SchemaService schemaService) { + super(Optional.of(Objects.requireNonNull(schemaService))); + } +} diff --git a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocServiceImpl.java b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocServiceImpl.java index f309982e54..fc84ee54b6 100644 --- a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocServiceImpl.java +++ b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocServiceImpl.java @@ -15,6 +15,7 @@ import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.util.Map.Entry; +import java.util.Objects; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import org.opendaylight.netconf.sal.rest.doc.api.ApiDocService; @@ -37,10 +38,20 @@ import org.opendaylight.netconf.sal.rest.doc.swagger.ResourceList; */ public class ApiDocServiceImpl implements ApiDocService { - private static final ApiDocService INSTANCE = new ApiDocServiceImpl(); + private final MountPointSwagger mountPointSwaggerDraft02; + private final MountPointSwagger mountPointSwaggerRFC8040; + private final ApiDocGeneratorDraftO2 apiDocGeneratorDraft02; + private final ApiDocGeneratorRFC8040 apiDocGeneratorRFC8040; - public static ApiDocService getInstance() { - return INSTANCE; + public ApiDocServiceImpl(MountPointSwaggerGeneratorDraft02 mountPointSwaggerGeneratorDraft02, + MountPointSwaggerGeneratorRFC8040 mountPointSwaggerGeneratorRFC8040, + ApiDocGeneratorDraftO2 apiDocGeneratorDraft02, ApiDocGeneratorRFC8040 apiDocGeneratorRFC8040) { + this.mountPointSwaggerDraft02 = + Objects.requireNonNull(mountPointSwaggerGeneratorDraft02).getMountPointSwagger(); + this.mountPointSwaggerRFC8040 = + Objects.requireNonNull(mountPointSwaggerGeneratorRFC8040).getMountPointSwagger(); + this.apiDocGeneratorDraft02 = Objects.requireNonNull(apiDocGeneratorDraft02); + this.apiDocGeneratorRFC8040 = Objects.requireNonNull(apiDocGeneratorRFC8040); } /** @@ -50,13 +61,12 @@ public class ApiDocServiceImpl implements ApiDocService { */ @Override public synchronized Response getRootDoc(final UriInfo uriInfo) { - final ApiDocGenerator generator = ApiDocGenerator.getInstance(); + final ResourceList rootDoc; if (isNew(uriInfo)) { - generator.setDraft(true); + rootDoc = apiDocGeneratorRFC8040.getResourceListing(uriInfo); } else { - generator.setDraft(false); + rootDoc = apiDocGeneratorDraft02.getResourceListing(uriInfo); } - final ResourceList rootDoc = generator.getResourceListing(uriInfo); return Response.ok(rootDoc).build(); } @@ -66,13 +76,13 @@ public class ApiDocServiceImpl implements ApiDocService { */ @Override public synchronized Response getDocByModule(final String module, final String revision, final UriInfo uriInfo) { - final ApiDocGenerator generator = ApiDocGenerator.getInstance(); + final ApiDeclaration doc; if (isNew(uriInfo)) { - generator.setDraft(true); + doc = apiDocGeneratorRFC8040.getApiDeclaration(module, revision, uriInfo); } else { - generator.setDraft(false); + doc = apiDocGeneratorDraft02.getApiDeclaration(module, revision, uriInfo); } - final ApiDeclaration doc = generator.getApiDeclaration(module, revision, uriInfo); + return Response.ok(doc).build(); } @@ -90,7 +100,7 @@ public class ApiDocServiceImpl implements ApiDocService { try (OutputStreamWriter streamWriter = new OutputStreamWriter(baos, StandardCharsets.UTF_8)) { JsonGenerator writer = new JsonFactory().createGenerator(streamWriter); writer.writeStartArray(); - for (final Entry entry : MountPointSwagger.getInstance().getInstanceIdentifiers() + for (final Entry entry : mountPointSwaggerDraft02.getInstanceIdentifiers() .entrySet()) { writer.writeStartObject(); writer.writeObjectField("instance", entry.getKey()); @@ -115,9 +125,9 @@ public class ApiDocServiceImpl implements ApiDocService { public synchronized Response getMountRootDoc(final String instanceNum, final UriInfo uriInfo) { final ResourceList resourceList; if (isNew(uriInfo)) { - resourceList = MountPointSwagger.getInstanceDraft18().getResourceList(uriInfo, Long.parseLong(instanceNum)); + resourceList = mountPointSwaggerRFC8040.getResourceList(uriInfo, Long.parseLong(instanceNum)); } else { - resourceList = MountPointSwagger.getInstance().getResourceList(uriInfo, Long.parseLong(instanceNum)); + resourceList = mountPointSwaggerDraft02.getResourceList(uriInfo, Long.parseLong(instanceNum)); } return Response.ok(resourceList).build(); } @@ -127,11 +137,9 @@ public class ApiDocServiceImpl implements ApiDocService { final String revision, final UriInfo uriInfo) { final ApiDeclaration api; if (isNew(uriInfo)) { - api = MountPointSwagger.getInstanceDraft18().getMountPointApi(uriInfo, Long.parseLong(instanceNum), module, - revision); + api = mountPointSwaggerRFC8040.getMountPointApi(uriInfo, Long.parseLong(instanceNum), module, revision); } else { - api = MountPointSwagger.getInstance().getMountPointApi(uriInfo, Long.parseLong(instanceNum), module, - revision); + api = mountPointSwaggerDraft02.getMountPointApi(uriInfo, Long.parseLong(instanceNum), module, revision); } return Response.ok(api).build(); } diff --git a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGenerator.java b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGenerator.java index 85462a7678..af13ffe4db 100644 --- a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGenerator.java +++ b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGenerator.java @@ -21,11 +21,13 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map.Entry; import java.util.Optional; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import javax.ws.rs.core.UriInfo; +import org.opendaylight.controller.sal.core.api.model.SchemaService; import org.opendaylight.netconf.sal.rest.doc.model.builder.OperationBuilder; import org.opendaylight.netconf.sal.rest.doc.model.builder.OperationBuilder.Delete; import org.opendaylight.netconf.sal.rest.doc.model.builder.OperationBuilder.Get; @@ -39,6 +41,9 @@ import org.opendaylight.netconf.sal.rest.doc.swagger.Resource; import org.opendaylight.netconf.sal.rest.doc.swagger.ResourceList; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.Revision; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataNodeContainer; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; @@ -49,26 +54,35 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class BaseYangSwaggerGenerator { +public abstract class BaseYangSwaggerGenerator { private static final Logger LOG = LoggerFactory.getLogger(BaseYangSwaggerGenerator.class); protected static final String API_VERSION = "1.0.0"; protected static final String SWAGGER_VERSION = "1.2"; - protected static final String RESTCONF_CONTEXT_ROOT = "restconf"; - private static final String RESTCONF_DRAFT = "18"; static final String MODULE_NAME_SUFFIX = "_module"; private final ModelGenerator jsonConverter = new ModelGenerator(); // private Map MODULE_DOC_CACHE = new HashMap<>() private final ObjectMapper mapper = new ObjectMapper(); - private volatile boolean newDraft; + private final SchemaService schemaService; - protected BaseYangSwaggerGenerator() { + protected BaseYangSwaggerGenerator(Optional schemaService) { + this.schemaService = schemaService.orElse(null); this.mapper.configure(SerializationFeature.INDENT_OUTPUT, true); } + public SchemaService getSchemaService() { + return schemaService; + } + + public ResourceList getResourceListing(final UriInfo uriInfo) { + final SchemaContext schemaContext = schemaService.getGlobalContext(); + Preconditions.checkState(schemaContext != null); + return getResourceListing(uriInfo, schemaContext, ""); + } + /** * Return list of modules converted to swagger compliant resource list. */ @@ -103,18 +117,24 @@ public class BaseYangSwaggerGenerator { return resourceList; } - protected ResourceList createResourceList() { + public ResourceList createResourceList() { final ResourceList resourceList = new ResourceList(); resourceList.setApiVersion(API_VERSION); resourceList.setSwaggerVersion(SWAGGER_VERSION); return resourceList; } - protected String generatePath(final UriInfo uriInfo, final String name, final String revision) { + public String generatePath(final UriInfo uriInfo, final String name, final String revision) { final URI uri = uriInfo.getRequestUriBuilder().path(generateCacheKey(name, revision)).build(); return uri.toASCIIString(); } + public ApiDeclaration getApiDeclaration(final String module, final String revision, final UriInfo uriInfo) { + final SchemaContext schemaContext = schemaService.getGlobalContext(); + Preconditions.checkState(schemaContext != null); + return getApiDeclaration(module, revision, uriInfo, schemaContext, ""); + } + public ApiDeclaration getApiDeclaration(final String moduleName, final String revision, final UriInfo uriInfo, final SchemaContext schemaContext, final String context) { final Optional rev; @@ -143,7 +163,7 @@ public class BaseYangSwaggerGenerator { return null; } - protected String createBasePathFromUriInfo(final UriInfo uriInfo) { + public String createBasePathFromUriInfo(final UriInfo uriInfo) { String portPart = ""; final int port = uriInfo.getBaseUri().getPort(); if (port != -1) { @@ -151,7 +171,7 @@ public class BaseYangSwaggerGenerator { } final String basePath = new StringBuilder(uriInfo.getBaseUri().getScheme()).append("://").append(uriInfo.getBaseUri().getHost()) - .append(portPart).append("/").append(RESTCONF_CONTEXT_ROOT).toString(); + .append(portPart).toString(); return basePath; } @@ -240,7 +260,7 @@ public class BaseYangSwaggerGenerator { } } - protected ApiDeclaration createApiDeclaration(final String basePath) { + public ApiDeclaration createApiDeclaration(final String basePath) { final ApiDeclaration doc = new ApiDeclaration(); doc.setApiVersion(API_VERSION); doc.setSwaggerVersion(SWAGGER_VERSION); @@ -249,16 +269,7 @@ public class BaseYangSwaggerGenerator { return doc; } - protected String getDataStorePath(final String dataStore, final String context) { - if (newDraft) { - if ("config".contains(dataStore) || "operational".contains(dataStore)) { - return "/" + RESTCONF_DRAFT + "/data" + context; - } - return "/" + RESTCONF_DRAFT + "/operations" + context; - } - - return "/" + dataStore + context; - } + public abstract String getDataStorePath(String dataStore, String context); private static String generateCacheKey(final String module, final String revision) { return module + "(" + revision + ")"; @@ -294,19 +305,7 @@ public class BaseYangSwaggerGenerator { } } - protected String getContent(final String dataStore) { - if (newDraft) { - if ("operational".contains(dataStore)) { - return "?content=nonconfig"; - } else if ("config".contains(dataStore)) { - return "?content=config"; - } else { - return ""; - } - } else { - return ""; - } - } + public abstract String getContent(String dataStore); private static boolean containsListOrContainer(final Iterable nodes) { for (final DataSchemaNode child : nodes) { @@ -351,6 +350,8 @@ public class BaseYangSwaggerGenerator { return operations; } + protected abstract ListPathBuilder newListPathBuilder(); + private String createPath(final DataSchemaNode schemaNode, final List pathParams, final SchemaContext schemaContext) { final StringBuilder path = new StringBuilder(); @@ -359,19 +360,11 @@ public class BaseYangSwaggerGenerator { if (schemaNode instanceof ListSchemaNode) { final List listKeys = ((ListSchemaNode) schemaNode).getKeyDefinition(); - StringBuilder keyBuilder = null; - if (newDraft) { - keyBuilder = new StringBuilder("="); - } - for (final QName listKey : listKeys) { + final ListPathBuilder keyBuilder = newListPathBuilder(); final DataSchemaNode dataChildByName = ((DataNodeContainer) schemaNode).getDataChildByName(listKey); - final String pathParamIdentifier; - if (newDraft) { - pathParamIdentifier = keyBuilder.append("{").append(listKey.getLocalName()).append("}").toString(); - } else { - pathParamIdentifier = "/{" + listKey.getLocalName() + "}"; - } + final String pathParamIdentifier = keyBuilder.nextParamIdentifier(listKey.getLocalName()); + path.append(pathParamIdentifier); final Parameter pathParam = new Parameter(); @@ -381,9 +374,6 @@ public class BaseYangSwaggerGenerator { pathParam.setParamType("path"); pathParams.add(pathParam); - if (newDraft) { - keyBuilder = new StringBuilder(","); - } } } return path.toString(); @@ -440,11 +430,29 @@ public class BaseYangSwaggerGenerator { return sortedModules; } - public void setDraft(final boolean draft) { - this.newDraft = draft; + protected abstract void appendPathKeyValue(StringBuilder builder, Object value); + + public String generateUrlPrefixFromInstanceID(final YangInstanceIdentifier key, final String moduleName) { + final StringBuilder builder = new StringBuilder(); + builder.append("/"); + if (moduleName != null) { + builder.append(moduleName).append(':'); + } + for (final PathArgument arg : key.getPathArguments()) { + final String name = arg.getNodeType().getLocalName(); + if (arg instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates) { + final NodeIdentifierWithPredicates nodeId = (NodeIdentifierWithPredicates) arg; + for (final Entry entry : nodeId.getKeyValues().entrySet()) { + appendPathKeyValue(builder, entry.getValue()); + } + } else { + builder.append(name).append('/'); + } + } + return builder.toString(); } - protected boolean isNewDraft() { - return newDraft; + protected interface ListPathBuilder { + String nextParamIdentifier(String key); } } diff --git a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGeneratorDraft02.java b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGeneratorDraft02.java new file mode 100644 index 0000000000..fb4b04addf --- /dev/null +++ b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGeneratorDraft02.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018 Inocybe Technologies 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.netconf.sal.rest.doc.impl; + +import java.util.Optional; +import org.opendaylight.controller.sal.core.api.model.SchemaService; + +/** + * Base class for a bierman draft02 implementation. + * + * @author Thomas Pantelis + */ +public abstract class BaseYangSwaggerGeneratorDraft02 extends BaseYangSwaggerGenerator { + protected static final String RESTCONF_CONTEXT_ROOT = "restconf"; + + protected BaseYangSwaggerGeneratorDraft02(Optional schemaService) { + super(schemaService); + } + + @Override + public String getDataStorePath(final String dataStore, final String context) { + return "/" + RESTCONF_CONTEXT_ROOT + "/" + dataStore + context; + } + + @Override + public String getContent(final String dataStore) { + return ""; + } + + @Override + protected ListPathBuilder newListPathBuilder() { + return key -> "/{" + key + "}"; + } + + @Override + protected void appendPathKeyValue(StringBuilder builder, Object value) { + builder.append(value).append('/'); + } +} diff --git a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGeneratorRFC8040.java b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGeneratorRFC8040.java new file mode 100644 index 0000000000..ddcd8edc4f --- /dev/null +++ b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGeneratorRFC8040.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018 Inocybe Technologies 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.netconf.sal.rest.doc.impl; + +import java.util.Optional; +import org.opendaylight.controller.sal.core.api.model.SchemaService; + +/** + * Base class for an RFC 8040 implementation. + * + * @author Thomas Pantelis + */ +public abstract class BaseYangSwaggerGeneratorRFC8040 extends BaseYangSwaggerGenerator { + + private static final String BASE_PATH = "rests"; + + protected BaseYangSwaggerGeneratorRFC8040(Optional schemaService) { + super(schemaService); + } + + @Override + public String getDataStorePath(final String dataStore, final String context) { + if ("config".contains(dataStore) || "operational".contains(dataStore)) { + return "/" + BASE_PATH + "/data" + context; + } + return "/" + BASE_PATH + "/operations" + context; + } + + @Override + public String getContent(final String dataStore) { + if ("operational".contains(dataStore)) { + return "?content=nonconfig"; + } else if ("config".contains(dataStore)) { + return "?content=config"; + } else { + return ""; + } + } + + @Override + protected ListPathBuilder newListPathBuilder() { + return new ListPathBuilder() { + private String prefix = "="; + + @Override + public String nextParamIdentifier(String key) { + String str = prefix + "{" + key + "}"; + prefix = ","; + return str; + } + }; + } + + @Override + protected void appendPathKeyValue(StringBuilder builder, Object value) { + builder.deleteCharAt(builder.length() - 1).append("=").append(value).append('/'); + } +} diff --git a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/MountPointSwaggerGeneratorDraft02.java b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/MountPointSwaggerGeneratorDraft02.java new file mode 100644 index 0000000000..43f8e8fac5 --- /dev/null +++ b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/MountPointSwaggerGeneratorDraft02.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 Inocybe Technologies 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.netconf.sal.rest.doc.impl; + +import java.util.Objects; +import java.util.Optional; +import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService; +import org.opendaylight.controller.sal.core.api.model.SchemaService; +import org.opendaylight.netconf.sal.rest.doc.mountpoints.MountPointSwagger; + +/** + * MountPoint generator implementation for bierman draft02. + * + * @author Thomas Pantelis + */ +public class MountPointSwaggerGeneratorDraft02 extends BaseYangSwaggerGeneratorDraft02 implements AutoCloseable { + + private final MountPointSwagger mountPointSwagger; + + public MountPointSwaggerGeneratorDraft02(SchemaService schemaService, DOMMountPointService mountService) { + super(Optional.of(Objects.requireNonNull(schemaService))); + mountPointSwagger = new MountPointSwagger(schemaService, mountService, this); + mountPointSwagger.init(); + } + + public MountPointSwagger getMountPointSwagger() { + return mountPointSwagger; + } + + @Override + public void close() { + mountPointSwagger.close(); + } +} diff --git a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/MountPointSwaggerGeneratorRFC8040.java b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/MountPointSwaggerGeneratorRFC8040.java new file mode 100644 index 0000000000..c9d944ffb2 --- /dev/null +++ b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/MountPointSwaggerGeneratorRFC8040.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018 Inocybe Technologies 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.netconf.sal.rest.doc.impl; + +import java.util.Objects; +import java.util.Optional; +import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService; +import org.opendaylight.controller.sal.core.api.model.SchemaService; +import org.opendaylight.netconf.sal.rest.doc.mountpoints.MountPointSwagger; + +/** + * MountPoint generator implementation for RFC 8040. + * + * @author Thomas Pantelis + */ +public class MountPointSwaggerGeneratorRFC8040 extends BaseYangSwaggerGeneratorRFC8040 implements AutoCloseable { + private final MountPointSwagger mountPointSwagger; + + public MountPointSwaggerGeneratorRFC8040(SchemaService schemaService, DOMMountPointService mountService) { + super(Optional.of(Objects.requireNonNull(schemaService))); + mountPointSwagger = new MountPointSwagger(schemaService, mountService, this); + mountPointSwagger.init(); + } + + public MountPointSwagger getMountPointSwagger() { + return mountPointSwagger; + } + + @Override + public void close() { + mountPointSwagger.close(); + } +} diff --git a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/jaxrs/ApiDocApplication.java b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/jaxrs/ApiDocApplication.java index 93291ddd36..af9cdcdd16 100644 --- a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/jaxrs/ApiDocApplication.java +++ b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/jaxrs/ApiDocApplication.java @@ -11,13 +11,19 @@ import java.util.HashSet; import java.util.Set; import javax.ws.rs.core.Application; import org.opendaylight.aaa.provider.GsonProvider; -import org.opendaylight.netconf.sal.rest.doc.impl.ApiDocServiceImpl; +import org.opendaylight.netconf.sal.rest.doc.api.ApiDocService; public class ApiDocApplication extends Application { + private final ApiDocService apiDocService; + + public ApiDocApplication(ApiDocService apiDocService) { + this.apiDocService = apiDocService; + } + @Override public Set getSingletons() { Set singletons = new HashSet<>(); - singletons.add(ApiDocServiceImpl.getInstance()); + singletons.add(apiDocService); singletons.add(new JaxbContextResolver()); singletons.add(new GsonProvider()); return singletons; diff --git a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/jaxrs/WebInitializer.java b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/jaxrs/WebInitializer.java new file mode 100644 index 0000000000..d33524f87d --- /dev/null +++ b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/jaxrs/WebInitializer.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018 Inocybe Technologies 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.netconf.sal.rest.doc.jaxrs; + +import javax.servlet.ServletException; +import javax.ws.rs.core.Application; +import org.opendaylight.aaa.web.ResourceDetails; +import org.opendaylight.aaa.web.ServletDetails; +import org.opendaylight.aaa.web.WebContext; +import org.opendaylight.aaa.web.WebContextBuilder; +import org.opendaylight.aaa.web.WebContextRegistration; +import org.opendaylight.aaa.web.WebContextSecurer; +import org.opendaylight.aaa.web.WebServer; + +/** + * Initializes the wep app. + * + * @author Thomas Pantelis + */ +public class WebInitializer { + private final WebContextRegistration registration; + + public WebInitializer(WebServer webServer, WebContextSecurer webContextSecurer, Application webApp) + throws ServletException { + WebContextBuilder webContextBuilder = WebContext.builder().contextPath("apidoc").supportsSessions(true) + .addServlet(ServletDetails.builder().servlet( + new com.sun.jersey.spi.container.servlet.ServletContainer(webApp)) + .addUrlPattern("/apis/*").addUrlPattern("/18/apis/*").build()) + .addResource(ResourceDetails.builder().name("/explorer").build()) + .addResource(ResourceDetails.builder().name("/18/explorer").build()); + + webContextSecurer.requireAuthentication(webContextBuilder, "/apis/*", "/18/apis/*"); + + registration = webServer.registerWebContext(webContextBuilder.build()); + } + + public void close() { + registration.close(); + } +} diff --git a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/mountpoints/MountPointSwagger.java b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/mountpoints/MountPointSwagger.java index e81d1e5c15..2ba7da6af5 100644 --- a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/mountpoints/MountPointSwagger.java +++ b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/mountpoints/MountPointSwagger.java @@ -15,9 +15,9 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.TreeMap; import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; import javax.ws.rs.core.UriInfo; import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint; import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService; @@ -29,20 +29,20 @@ import org.opendaylight.netconf.sal.rest.doc.swagger.ApiDeclaration; import org.opendaylight.netconf.sal.rest.doc.swagger.Operation; import org.opendaylight.netconf.sal.rest.doc.swagger.Resource; import org.opendaylight.netconf.sal.rest.doc.swagger.ResourceList; -import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; -import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; -public class MountPointSwagger extends BaseYangSwaggerGenerator implements MountProvisionListener { +public class MountPointSwagger implements MountProvisionListener, AutoCloseable { private static final String DATASTORES_REVISION = "-"; private static final String DATASTORES_LABEL = "Datastores"; - private static final AtomicReference SELF_REF = new AtomicReference<>(); - private DOMMountPointService mountService; + private final SchemaService globalSchema; + private final DOMMountPointService mountService; + private final BaseYangSwaggerGenerator swaggerGenerator; private final Map instanceIdToLongId = new TreeMap<>((o1, o2) -> o1.toString().compareToIgnoreCase(o2.toString())); private final Map longIdToInstanceId = new HashMap<>(); @@ -50,25 +50,40 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount private final Object lock = new Object(); private final AtomicLong idKey = new AtomicLong(0); - private SchemaService globalSchema; + + private ListenerRegistration registration; + + public MountPointSwagger(SchemaService globalSchema, DOMMountPointService mountService, + BaseYangSwaggerGenerator swaggerGenerator) { + this.globalSchema = Objects.requireNonNull(globalSchema); + this.mountService = Objects.requireNonNull(mountService); + this.swaggerGenerator = Objects.requireNonNull(swaggerGenerator); + } + + public void init() { + registration = mountService.registerProvisionListener(this); + } + + @Override + public void close() { + if (registration != null) { + registration.close(); + } + } public Map getInstanceIdentifiers() { - Preconditions.checkState(globalSchema != null); final Map urlToId = new HashMap<>(); synchronized (this.lock) { final SchemaContext context = this.globalSchema.getGlobalContext(); for (final Entry entry : this.instanceIdToLongId.entrySet()) { final String modName = findModuleName(entry.getKey(), context); - urlToId.put(generateUrlPrefixFromInstanceID(entry.getKey(), modName), entry.getValue()); + urlToId.put(swaggerGenerator.generateUrlPrefixFromInstanceID(entry.getKey(), modName), + entry.getValue()); } } return urlToId; } - public void setGlobalSchema(final SchemaService globalSchema) { - this.globalSchema = globalSchema; - } - private String findModuleName(final YangInstanceIdentifier id, final SchemaContext context) { final PathArgument rootQName = id.getPathArguments().iterator().next(); for (final Module mod : context.getModules()) { @@ -79,34 +94,9 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount return null; } - private String generateUrlPrefixFromInstanceID(final YangInstanceIdentifier key, final String moduleName) { - final StringBuilder builder = new StringBuilder(); - builder.append("/"); - if (moduleName != null) { - builder.append(moduleName).append(':'); - } - for (final PathArgument arg : key.getPathArguments()) { - final String name = arg.getNodeType().getLocalName(); - if (arg instanceof YangInstanceIdentifier.NodeIdentifierWithPredicates) { - final NodeIdentifierWithPredicates nodeId = (NodeIdentifierWithPredicates) arg; - for (final Entry entry : nodeId.getKeyValues().entrySet()) { - if (isNewDraft()) { - builder.deleteCharAt(builder.length() - 1).append("=").append(entry.getValue()).append('/'); - } else { - builder.append(entry.getValue()).append('/'); - } - } - } else { - builder.append(name).append('/'); - } - } - return builder.toString(); - } - private String getYangMountUrl(final YangInstanceIdentifier key) { - Preconditions.checkState(globalSchema != null); final String modName = findModuleName(key, this.globalSchema.getGlobalContext()); - return generateUrlPrefixFromInstanceID(key, modName) + "yang-ext:mount"; + return swaggerGenerator.generateUrlPrefixFromInstanceID(key, modName) + "yang-ext:mount"; } public ResourceList getResourceList(final UriInfo uriInfo, final Long id) { @@ -116,15 +106,15 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount } final SchemaContext context = getSchemaContext(iid); if (context == null) { - return createResourceList(); + return swaggerGenerator.createResourceList(); } final List resources = new LinkedList<>(); final Resource dataStores = new Resource(); dataStores.setDescription("Provides methods for accessing the data stores."); - dataStores.setPath(generatePath(uriInfo, DATASTORES_LABEL, DATASTORES_REVISION)); + dataStores.setPath(swaggerGenerator.generatePath(uriInfo, DATASTORES_LABEL, DATASTORES_REVISION)); resources.add(dataStores); final String urlPrefix = getYangMountUrl(iid); - final ResourceList list = super.getResourceListing(uriInfo, context, urlPrefix); + final ResourceList list = swaggerGenerator.getResourceListing(uriInfo, context, urlPrefix); resources.addAll(list.getApis()); list.setApis(resources); return list; @@ -169,7 +159,7 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount if (DATASTORES_LABEL.equals(module) && DATASTORES_REVISION.equals(revision)) { return generateDataStoreApiDoc(uriInfo, urlPrefix); } - return super.getApiDeclaration(module, revision, uriInfo, context, urlPrefix); + return swaggerGenerator.getApiDeclaration(module, revision, uriInfo, context, urlPrefix); } private ApiDeclaration generateDataStoreApiDoc(final UriInfo uriInfo, final String context) { @@ -180,7 +170,8 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount apis.add(createGetApi("operations", "Queries the available operations (RPC calls) on the mounted hosted.", context)); - final ApiDeclaration declaration = super.createApiDeclaration(createBasePathFromUriInfo(uriInfo)); + final ApiDeclaration declaration = swaggerGenerator.createApiDeclaration( + swaggerGenerator.createBasePathFromUriInfo(uriInfo)); declaration.setApis(apis); return declaration; @@ -193,16 +184,13 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount getConfig.setNotes(note); final Api api = new Api(); - api.setPath(getDataStorePath(datastore, context).concat(getContent(datastore))); + api.setPath(swaggerGenerator.getDataStorePath(datastore, context).concat( + swaggerGenerator.getContent(datastore))); api.setOperations(Collections.singletonList(getConfig)); return api; } - public void setMountService(final DOMMountPointService mountService) { - this.mountService = mountService; - } - @Override public void onMountPointCreated(final YangInstanceIdentifier path) { synchronized (this.lock) { @@ -219,26 +207,4 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount this.longIdToInstanceId.remove(id); } } - - public static MountPointSwagger getInstance() { - MountPointSwagger swagger = SELF_REF.get(); - if (swagger == null) { - SELF_REF.compareAndSet(null, new MountPointSwagger()); - swagger = SELF_REF.get(); - } - - swagger.setDraft(false); - return swagger; - } - - public static MountPointSwagger getInstanceDraft18() { - MountPointSwagger swagger = SELF_REF.get(); - if (swagger == null) { - SELF_REF.compareAndSet(null, new MountPointSwagger()); - swagger = SELF_REF.get(); - } - - swagger.setDraft(true); - return swagger; - } } diff --git a/restconf/sal-rest-docgen/src/main/resources/WEB-INF/web.xml b/restconf/sal-rest-docgen/src/main/resources/WEB-INF/web.xml deleted file mode 100644 index e0a37261e9..0000000000 --- a/restconf/sal-rest-docgen/src/main/resources/WEB-INF/web.xml +++ /dev/null @@ -1,79 +0,0 @@ - - - - index.html - - - JAXRSApiDoc - com.sun.jersey.spi.container.servlet.ServletContainer - - javax.ws.rs.Application - org.opendaylight.netconf.sal.rest.doc.jaxrs.ApiDocApplication - - 1 - - - - shiroEnvironmentClass - org.opendaylight.aaa.shiro.web.env.KarafIniWebEnvironment - - - - org.apache.shiro.web.env.EnvironmentLoaderListener - - - - ShiroFilter - org.opendaylight.aaa.shiro.filters.AAAFilter - - - - ShiroFilter - /* - - - - JAXRSApiDoc - /apis/* - - - - JAXRSApiDoc - /18/apis/* - - - - cross-origin-api-doc - org.eclipse.jetty.servlets.CrossOriginFilter - - allowedOrigins - * - - - allowedMethods - GET,POST,OPTIONS,DELETE,PUT,HEAD - - - allowedHeaders - origin, content-type, accept, authorization - - - - cross-origin-api-doc - /apis/* - - - cross-origin-api-doc - /18/apis/* - - - - - API Doc - /* - - - - diff --git a/restconf/sal-rest-docgen/src/main/resources/org/opendaylight/blueprint/blueprint.xml b/restconf/sal-rest-docgen/src/main/resources/org/opendaylight/blueprint/blueprint.xml index f6ab472980..f365c1825f 100644 --- a/restconf/sal-rest-docgen/src/main/resources/org/opendaylight/blueprint/blueprint.xml +++ b/restconf/sal-rest-docgen/src/main/resources/org/opendaylight/blueprint/blueprint.xml @@ -11,15 +11,46 @@ and is available at http://www.eclipse.org/legal/epl-v10.html xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0" odl:use-default-for-reference-types="true"> - - - + + + + + + + - + - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocGeneratorTest.java b/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocGeneratorTest.java index 50fe6b6225..4946f633c1 100644 --- a/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocGeneratorTest.java +++ b/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocGeneratorTest.java @@ -26,8 +26,7 @@ import javax.ws.rs.core.UriInfo; import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.opendaylight.controller.sal.core.api.model.SchemaService; -import org.opendaylight.netconf.sal.rest.doc.impl.ApiDocGenerator; +import org.opendaylight.netconf.sal.rest.doc.impl.ApiDocGeneratorDraftO2; import org.opendaylight.netconf.sal.rest.doc.swagger.Api; import org.opendaylight.netconf.sal.rest.doc.swagger.ApiDeclaration; import org.opendaylight.netconf.sal.rest.doc.swagger.Operation; @@ -45,18 +44,18 @@ public class ApiDocGeneratorTest { private static final Date DATE = Date.valueOf(STRING_DATE); private static final String NAMESPACE_2 = "http://netconfcentral.org/ns/toaster"; private static final Date REVISION_2 = Date.valueOf(STRING_DATE); - private ApiDocGenerator generator; + private ApiDocGeneratorDraftO2 generator; private DocGenTestHelper helper; private SchemaContext schemaContext; @Before public void setUp() throws Exception { - this.generator = new ApiDocGenerator(); - generator.setDraft(false); this.helper = new DocGenTestHelper(); this.helper.setUp(); this.schemaContext = this.helper.getSchemaContext(); + + this.generator = new ApiDocGeneratorDraftO2(this.helper.createMockSchemaService(this.schemaContext)); } @After @@ -325,9 +324,6 @@ public class ApiDocGeneratorTest { @Test public void testGetResourceListing() throws Exception { final UriInfo info = this.helper.createMockUriInfo(HTTP_HOST); - final SchemaService mockSchemaService = this.helper.createMockSchemaService(this.schemaContext); - - this.generator.setSchemaService(mockSchemaService); final ResourceList resourceListing = this.generator.getResourceListing(info); @@ -371,4 +367,4 @@ public class ApiDocGeneratorTest { assertNotNull(property + " is missing", concretePropertyObject); } } -} \ No newline at end of file +} diff --git a/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/MountPointSwaggerTest.java b/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/MountPointSwaggerTest.java index 2ee9a90255..9703c2ba5b 100644 --- a/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/MountPointSwaggerTest.java +++ b/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/MountPointSwaggerTest.java @@ -13,7 +13,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import com.google.common.base.Optional; -import java.net.URISyntaxException; import java.util.Arrays; import java.util.List; import java.util.Set; @@ -24,6 +23,7 @@ import org.junit.Test; import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint; import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService; import org.opendaylight.controller.sal.core.api.model.SchemaService; +import org.opendaylight.netconf.sal.rest.doc.impl.MountPointSwaggerGeneratorDraft02; import org.opendaylight.netconf.sal.rest.doc.mountpoints.MountPointSwagger; import org.opendaylight.netconf.sal.rest.doc.swagger.Api; import org.opendaylight.netconf.sal.rest.doc.swagger.ApiDeclaration; @@ -46,12 +46,27 @@ public class MountPointSwaggerTest { private DocGenTestHelper helper; private SchemaContext schemaContext; + @SuppressWarnings("resource") @Before public void setUp() throws Exception { - this.swagger = new MountPointSwagger(); this.helper = new DocGenTestHelper(); this.helper.setUp(); this.schemaContext = this.helper.getSchemaContext(); + + // We are sharing the global schema service and the mount schema service + // in our test. + // OK for testing - real thing would have seperate instances. + final SchemaContext context = this.helper.createMockSchemaContext(); + final SchemaService schemaService = this.helper.createMockSchemaService(context); + + final DOMMountPoint mountPoint = mock(DOMMountPoint.class); + when(mountPoint.getSchemaContext()).thenReturn(context); + + final DOMMountPointService service = mock(DOMMountPointService.class); + when(service.getMountPoint(INSTANCE_ID)).thenReturn(Optional.of(mountPoint)); + + MountPointSwaggerGeneratorDraft02 generator = new MountPointSwaggerGeneratorDraft02(schemaService, service); + this.swagger = generator.getMountPointSwagger(); } @Test() @@ -63,8 +78,6 @@ public class MountPointSwaggerTest { @Test() public void getInstanceIdentifiers() throws Exception { - final UriInfo mockInfo = setUpSwaggerForDocGeneration(); - assertEquals(0, this.swagger.getInstanceIdentifiers().size()); this.swagger.onMountPointCreated(INSTANCE_ID); // add this ID into the list of // mount points @@ -80,7 +93,7 @@ public class MountPointSwaggerTest { @Test public void testGetResourceListGoodId() throws Exception { - final UriInfo mockInfo = setUpSwaggerForDocGeneration(); + final UriInfo mockInfo = this.helper.createMockUriInfo(HTTP_URL); this.swagger.onMountPointCreated(INSTANCE_ID); // add this ID into the list of // mount points final ResourceList resourceList = this.swagger.getResourceList(mockInfo, 1L); @@ -96,7 +109,7 @@ public class MountPointSwaggerTest { @Test public void testGetDataStoreApi() throws Exception { - final UriInfo mockInfo = setUpSwaggerForDocGeneration(); + final UriInfo mockInfo = this.helper.createMockUriInfo(HTTP_URL); this.swagger.onMountPointCreated(INSTANCE_ID); // add this ID into the list of // mount points @@ -116,29 +129,9 @@ public class MountPointSwaggerTest { .getNotes()); } final Set expectedApis = new TreeSet<>(Arrays.asList(new String[] { - "/config" + INSTANCE_URL + "yang-ext:mount", - "/operational" + INSTANCE_URL + "yang-ext:mount", - "/operations" + INSTANCE_URL + "yang-ext:mount",})); + "/restconf/config" + INSTANCE_URL + "yang-ext:mount", + "/restconf/operational" + INSTANCE_URL + "yang-ext:mount", + "/restconf/operations" + INSTANCE_URL + "yang-ext:mount",})); assertEquals(expectedApis, actualApis); } - - protected UriInfo setUpSwaggerForDocGeneration() throws URISyntaxException { - final UriInfo mockInfo = this.helper.createMockUriInfo(HTTP_URL); - // We are sharing the global schema service and the mount schema service - // in our test. - // OK for testing - real thing would have seperate instances. - final SchemaContext context = this.helper.createMockSchemaContext(); - final SchemaService schemaService = this.helper.createMockSchemaService(context); - - final DOMMountPoint mountPoint = mock(DOMMountPoint.class); - when(mountPoint.getSchemaContext()).thenReturn(context); - - final DOMMountPointService service = mock(DOMMountPointService.class); - when(service.getMountPoint(INSTANCE_ID)).thenReturn(Optional.of(mountPoint)); - this.swagger.setMountService(service); - this.swagger.setGlobalSchema(schemaService); - - return mockInfo; - } - } -- 2.36.6