Convert apidocs to new web API 26/71426/3
authorTom Pantelis <tompantelis@gmail.com>
Thu, 26 Apr 2018 14:08:55 +0000 (10:08 -0400)
committerTom Pantelis <tompantelis@gmail.com>
Mon, 30 Apr 2018 13:53:05 +0000 (09:53 -0400)
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 <tompantelis@gmail.com>
19 files changed:
restconf/sal-rest-docgen-maven/src/main/java/org/opendaylight/netconf/sal/rest/doc/maven/StaticDocGenerator.java
restconf/sal-rest-docgen/pom.xml
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/DocProvider.java [deleted file]
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocGenerator.java [deleted file]
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocGeneratorDraftO2.java [new file with mode: 0644]
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocGeneratorRFC8040.java [new file with mode: 0644]
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocServiceImpl.java
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGenerator.java
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGeneratorDraft02.java [new file with mode: 0644]
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/BaseYangSwaggerGeneratorRFC8040.java [new file with mode: 0644]
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/MountPointSwaggerGeneratorDraft02.java [new file with mode: 0644]
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/MountPointSwaggerGeneratorRFC8040.java [new file with mode: 0644]
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/jaxrs/ApiDocApplication.java
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/jaxrs/WebInitializer.java [new file with mode: 0644]
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/mountpoints/MountPointSwagger.java
restconf/sal-rest-docgen/src/main/resources/WEB-INF/web.xml [deleted file]
restconf/sal-rest-docgen/src/main/resources/org/opendaylight/blueprint/blueprint.xml
restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocGeneratorTest.java
restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/MountPointSwaggerTest.java

index e09c73ed4d8eea896218d625f948285ffe80daf2..4ce00e647afe8ef2886192d9c685b0e9d63626e2 100644 (file)
@@ -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<File> 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;
         }
index a3086cf765f86aa9f3c95f089f99f97a77570082..a4a3e1ffd3be333557fe7a837a1a79b120aa26d9 100644 (file)
       <artifactId>aaa-shiro</artifactId>
       <version>0.8.0-SNAPSHOT</version>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.aaa.web</groupId>
+      <artifactId>web-api</artifactId>
+      <version>0.8.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>com.sun.jersey</groupId>
+      <artifactId>jersey-servlet</artifactId>
+    </dependency>
   </dependencies>
 
   <build>
           <instructions>
             <Bundle-Name>MD SAL Rest Api Doc Generator</Bundle-Name>
             <Embed-Dependency>generex, automaton</Embed-Dependency>
-            <!-- needed for web.xml. Remove once we have Jersey 2 -->
-            <Import-Package>
-              *,
-              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
-            </Import-Package>
             <Export-Package>
               com.fasterxml.jackson.datatype.*
             </Export-Package>
-            <Web-ContextPath>/apidoc</Web-ContextPath>
           </instructions>
 
         </configuration>
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 (file)
index ab84e30..0000000
+++ /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<AutoCloseable> toClose = new LinkedList<>();
-
-    public DocProvider(final SchemaService schemaService, final DOMMountPointService mountService) {
-
-        ApiDocGenerator.getInstance().setSchemaService(schemaService);
-
-        final ListenerRegistration<MountProvisionListener> 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 (file)
index 76030f3..0000000
+++ /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 (file)
index 0000000..5058f7f
--- /dev/null
@@ -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 (file)
index 0000000..5edb65d
--- /dev/null
@@ -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)));
+    }
+}
index f309982e54bceb9a1c0d060ae6ba9c69b949f0d4..fc84ee54b65abcfb8984febfed929ae18d8ca504 100644 (file)
@@ -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<String, Long> entry : MountPointSwagger.getInstance().getInstanceIdentifiers()
+            for (final Entry<String, Long> 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();
     }
index 85462a76781aa3012edd3ca80caefce11ded5803..af13ffe4dbccf37430138d8723a845331e017081 100644 (file)
@@ -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<String, ApiDeclaration> 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> 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<Revision> 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<DataSchemaNode> 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<Parameter> pathParams,
             final SchemaContext schemaContext) {
         final StringBuilder path = new StringBuilder();
@@ -359,19 +360,11 @@ public class BaseYangSwaggerGenerator {
 
         if (schemaNode instanceof ListSchemaNode) {
             final List<QName> 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<QName, Object> 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 (file)
index 0000000..fb4b04a
--- /dev/null
@@ -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> 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 (file)
index 0000000..ddcd8ed
--- /dev/null
@@ -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> 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 (file)
index 0000000..43f8e8f
--- /dev/null
@@ -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 (file)
index 0000000..c9d944f
--- /dev/null
@@ -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();
+    }
+}
index 93291ddd3612039f4bbfa24eb4ebd1a2a193347a..af9cdcdd1674837e6fbeed933d8bbef81b3f21e7 100644 (file)
@@ -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<Object> getSingletons() {
         Set<Object> 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 (file)
index 0000000..d33524f
--- /dev/null
@@ -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();
+    }
+}
index e81d1e5c158c37d56ba25bc6978704e100f7ac17..2ba7da6af5fe14d1c910373fa8dec558dc6024a9 100644 (file)
@@ -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<MountPointSwagger> SELF_REF = new AtomicReference<>();
 
-    private DOMMountPointService mountService;
+    private final SchemaService globalSchema;
+    private final DOMMountPointService mountService;
+    private final BaseYangSwaggerGenerator swaggerGenerator;
     private final Map<YangInstanceIdentifier, Long> instanceIdToLongId =
             new TreeMap<>((o1, o2) -> o1.toString().compareToIgnoreCase(o2.toString()));
     private final Map<Long, YangInstanceIdentifier> 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<MountProvisionListener> 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<String, Long> getInstanceIdentifiers() {
-        Preconditions.checkState(globalSchema != null);
         final Map<String, Long> urlToId = new HashMap<>();
         synchronized (this.lock) {
             final SchemaContext context = this.globalSchema.getGlobalContext();
             for (final Entry<YangInstanceIdentifier, Long> 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<QName, Object> 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<Resource> 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 (file)
index e0a3726..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
-         version="3.0">
-    <welcome-file-list>
-        <welcome-file>index.html</welcome-file>
-    </welcome-file-list>
-    <servlet>
-        <servlet-name>JAXRSApiDoc</servlet-name>
-        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
-        <init-param>
-            <param-name>javax.ws.rs.Application</param-name>
-            <param-value>org.opendaylight.netconf.sal.rest.doc.jaxrs.ApiDocApplication</param-value>
-        </init-param>
-        <load-on-startup>1</load-on-startup>
-    </servlet>
-
-    <context-param>
-        <param-name>shiroEnvironmentClass</param-name>
-        <param-value>org.opendaylight.aaa.shiro.web.env.KarafIniWebEnvironment</param-value>
-    </context-param>
-
-    <listener>
-        <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
-    </listener>
-
-    <filter>
-        <filter-name>ShiroFilter</filter-name>
-        <filter-class>org.opendaylight.aaa.shiro.filters.AAAFilter</filter-class>
-    </filter>
-
-    <filter-mapping>
-        <filter-name>ShiroFilter</filter-name>
-        <url-pattern>/*</url-pattern>
-    </filter-mapping>
-
-    <servlet-mapping>
-        <servlet-name>JAXRSApiDoc</servlet-name>
-        <url-pattern>/apis/*</url-pattern>
-    </servlet-mapping>
-
-    <servlet-mapping>
-        <servlet-name>JAXRSApiDoc</servlet-name>
-        <url-pattern>/18/apis/*</url-pattern>
-    </servlet-mapping>
-
-    <filter>
-        <filter-name>cross-origin-api-doc</filter-name>
-        <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
-        <init-param>
-            <param-name>allowedOrigins</param-name>
-            <param-value>*</param-value>
-        </init-param>
-        <init-param>
-            <param-name>allowedMethods</param-name>
-            <param-value>GET,POST,OPTIONS,DELETE,PUT,HEAD</param-value>
-        </init-param>
-        <init-param>
-            <param-name>allowedHeaders</param-name>
-            <param-value>origin, content-type, accept, authorization</param-value>
-        </init-param>
-    </filter>
-    <filter-mapping>
-        <filter-name>cross-origin-api-doc</filter-name>
-        <url-pattern>/apis/*</url-pattern>
-    </filter-mapping>
-    <filter-mapping>
-        <filter-name>cross-origin-api-doc</filter-name>
-        <url-pattern>/18/apis/*</url-pattern>
-    </filter-mapping>
-
-    <security-constraint>
-        <web-resource-collection>
-            <web-resource-name>API Doc</web-resource-name>
-            <url-pattern>/*</url-pattern>
-        </web-resource-collection>
-    </security-constraint>
-
-</web-app>
index f6ab4729808265cbddfb9a2123e1af0529255953..f365c1825f88247e472d9aebe7dbcf7c3b631d57 100644 (file)
@@ -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">
 
-    <!-- AAAService is used in web.xml and is needed here -->
-    <reference id="aaaService" interface="org.opendaylight.aaa.api.AAAService" />
-
     <reference id="schemaService" interface="org.opendaylight.controller.sal.core.api.model.SchemaService"/>
     <reference id="domMountPointService" interface="org.opendaylight.controller.md.sal.dom.api.DOMMountPointService"/>
+    <reference id="webServer" interface="org.opendaylight.aaa.web.WebServer"/>
+    <reference id="webContextSecurer" interface="org.opendaylight.aaa.web.WebContextSecurer"/>
+
+    <bean id="mountPointDraft02" class="org.opendaylight.netconf.sal.rest.doc.impl.MountPointSwaggerGeneratorDraft02"
+            destroy-method="close">
+        <argument ref="schemaService" />
+        <argument ref="domMountPointService" />
+    </bean>
 
-    <bean id="provider" class="org.opendaylight.netconf.sal.rest.doc.DocProvider" destroy-method="close">
+    <bean id="mountPointRFC8040" class="org.opendaylight.netconf.sal.rest.doc.impl.MountPointSwaggerGeneratorRFC8040"
+            destroy-method="close">
         <argument ref="schemaService" />
         <argument ref="domMountPointService" />
     </bean>
 
-</blueprint>
\ No newline at end of file
+    <bean id="apiDocDraftO2" class="org.opendaylight.netconf.sal.rest.doc.impl.ApiDocGeneratorDraftO2">
+        <argument ref="schemaService" />
+    </bean>
+
+    <bean id="apiDocRFC8040" class="org.opendaylight.netconf.sal.rest.doc.impl.ApiDocGeneratorRFC8040">
+        <argument ref="schemaService" />
+    </bean>
+
+    <bean id="apiDocService" class="org.opendaylight.netconf.sal.rest.doc.impl.ApiDocServiceImpl">
+        <argument ref="mountPointDraft02" />
+        <argument ref="mountPointRFC8040" />
+        <argument ref="apiDocDraftO2" />
+        <argument ref="apiDocRFC8040" />
+    </bean>
+
+    <bean id="apiDocApplication" class="org.opendaylight.netconf.sal.rest.doc.jaxrs.ApiDocApplication">
+        <argument ref="apiDocService" />
+    </bean>
+
+    <bean id="webInitializer" class="org.opendaylight.netconf.sal.rest.doc.jaxrs.WebInitializer"
+            destroy-method="close">
+        <argument ref="webServer"/>
+        <argument ref="webContextSecurer"/>
+        <argument ref="apiDocApplication"/>
+  </bean>
+</blueprint>
index 50fe6b62254d757172a0404103c652b888e88e8c..4946f633c160be274791ce9b41e943a281466923 100644 (file)
@@ -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
+}
index 2ee9a9025587f00e09b9fb6fb67eab40eaae6dc8..9703c2ba5b0c61bdb3637d67f329530bc73231f3 100644 (file)
@@ -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<String> 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;
-    }
-
 }