Bug 6382 - add apidoc for latest restconf draft 48/46948/5
authormiroslav.kovac <miroslav.kovac@pantheon.tech>
Wed, 12 Oct 2016 14:22:30 +0000 (16:22 +0200)
committerMiroslav Kovac <miroslav.kovac@pantheon.tech>
Wed, 2 Nov 2016 12:14:44 +0000 (12:14 +0000)
Create a swagger api explorer for latest ietf-netconf-restconf draft

Change-Id: Id397bbfdb435b8d8f0474657e6a7557e9b1eb838
Signed-off-by: miroslav.kovac <miroslav.kovac@pantheon.tech>
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocGenerator.java
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/mountpoints/MountPointSwagger.java
restconf/sal-rest-docgen/src/main/resources/17/explorer/index.html [new file with mode: 0644]
restconf/sal-rest-docgen/src/main/resources/17/explorer/lib/odl/list_mounts.js [new file with mode: 0644]
restconf/sal-rest-docgen/src/main/resources/17/explorer/static/index.html [new file with mode: 0644]
restconf/sal-rest-docgen/src/main/resources/README.txt
restconf/sal-rest-docgen/src/main/resources/WEB-INF/web.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 f78d61951eeea0d94d3f4a4103e2566016c43c16..1f4b3b52c0e7c66a52d2f1723e5f2e1e2afa316b 100644 (file)
@@ -43,6 +43,10 @@ public class ApiDocGenerator extends BaseYangSwaggerGenerator {
         return INSTANCE;
     }
 
+    public void setDraft(final boolean newDraft) {
+        super.setDraft(newDraft);
+    }
+
     public void setSchemaService(final SchemaService schemaService) {
         this.schemaService = schemaService;
     }
index 026296babad063363a3fac6c4215ede6468b6a2d..db884580081f64fb2e524928ee81ec3403be9564 100644 (file)
@@ -47,6 +47,11 @@ public class ApiDocServiceImpl implements ApiDocService {
     @Override
     public synchronized Response getRootDoc(final UriInfo uriInfo) {
         final ApiDocGenerator generator = ApiDocGenerator.getInstance();
+        if (isNew(uriInfo)) {
+            generator.setDraft(true);
+        } else {
+            generator.setDraft(false);
+        }
         final ResourceList rootDoc = generator.getResourceListing(uriInfo);
 
         return Response.ok(rootDoc).build();
@@ -58,7 +63,11 @@ public class ApiDocServiceImpl implements ApiDocService {
     @Override
     public synchronized Response getDocByModule(final String module, final String revision, final UriInfo uriInfo) {
         final ApiDocGenerator generator = ApiDocGenerator.getInstance();
-
+        if (isNew(uriInfo)) {
+            generator.setDraft(true);
+        } else {
+            generator.setDraft(false);
+        }
         final ApiDeclaration doc = generator.getApiDeclaration(module, revision, uriInfo);
         return Response.ok(doc).build();
     }
@@ -95,17 +104,32 @@ public class ApiDocServiceImpl implements ApiDocService {
 
     @Override
     public synchronized Response getMountRootDoc(final String instanceNum, final UriInfo uriInfo) {
-        final ResourceList resourceList = MountPointSwagger.getInstance().getResourceList(uriInfo,
-                Long.parseLong(instanceNum));
+        final ResourceList resourceList;
+        if (isNew(uriInfo)) {
+            resourceList = MountPointSwagger.getInstanceDraft17().getResourceList(uriInfo,
+                    Long.parseLong(instanceNum));
+        } else {
+            resourceList = MountPointSwagger.getInstance().getResourceList(uriInfo,
+                    Long.parseLong(instanceNum));
+        }
         return Response.ok(resourceList).build();
     }
 
     @Override
     public synchronized Response getMountDocByModule(final String instanceNum, final String module,
                                                      final String revision, final UriInfo uriInfo) {
-        final ApiDeclaration api = MountPointSwagger.getInstance().getMountPointApi(uriInfo,
-                Long.parseLong(instanceNum), module, revision);
+        final ApiDeclaration api;
+        if (isNew(uriInfo)) {
+            api = MountPointSwagger.getInstanceDraft17().getMountPointApi(uriInfo,
+                    Long.parseLong(instanceNum), module, revision);
+        } else {
+            api = MountPointSwagger.getInstance().getMountPointApi(uriInfo,
+                    Long.parseLong(instanceNum), module, revision);
+        }
         return Response.ok(api).build();
     }
 
+    private static boolean isNew(final UriInfo uriInfo) {
+        return uriInfo.getBaseUri().toString().contains("/17/");
+    }
 }
index abf560ea78fe9d44cffa322a12b62f456e295f09..453a9d2da4cd066983c277efbce89d1cb18f34f9 100644 (file)
@@ -62,6 +62,7 @@ public class BaseYangSwaggerGenerator {
     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 = "17";
 
     static final String MODULE_NAME_SUFFIX = "_module";
     protected static final DateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
@@ -69,6 +70,7 @@ public class BaseYangSwaggerGenerator {
 
     // private Map<String, ApiDeclaration> MODULE_DOC_CACHE = new HashMap<>()
     private final ObjectMapper mapper = new ObjectMapper();
+    private static boolean newDraft;
 
     protected BaseYangSwaggerGenerator() {
         mapper.registerModule(new JsonOrgModule());
@@ -189,7 +191,7 @@ public class BaseYangSwaggerGenerator {
                  * are added for this node.
                  */
                 if (node.isConfiguration()) { // This node's config statement is true.
-                    resourcePath = getDataStorePath("/config/", context);
+                    resourcePath = getDataStorePath("config", context);
 
                     /*
                      * When there are two or more top container or list nodes whose config statement is true in module,
@@ -197,22 +199,25 @@ public class BaseYangSwaggerGenerator {
                      */
                     if (!hasAddRootPostLink) {
                         LOG.debug("Has added root post link for module {}", m.getName());
-                        addRootPostLink(m, (DataNodeContainer) node, pathParams, resourcePath, apis);
+                        addRootPostLink(m, (DataNodeContainer) node, pathParams, resourcePath, "config", apis);
+
                         hasAddRootPostLink = true;
                     }
 
-                    addApis(node, apis, resourcePath, pathParams, schemaContext, true, m.getName());
+                    addApis(node, apis, resourcePath, pathParams, schemaContext, true, m.getName(), "config");
                 }
-
                 pathParams = new ArrayList<>();
-                resourcePath = getDataStorePath("/operational/", context);
-                addApis(node, apis, resourcePath, pathParams, schemaContext, false, m.getName());
+                resourcePath = getDataStorePath("operational", context);
+
+                addApis(node, apis, resourcePath, pathParams, schemaContext, false, m.getName(), "operational");
             }
         }
 
         final Set<RpcDefinition> rpcs = m.getRpcs();
         for (final RpcDefinition rpcDefinition : rpcs) {
-            final String resourcePath = getDataStorePath("/operations/", context);
+            final String resourcePath;
+            resourcePath = getDataStorePath("operations", context);
+
             addRpcs(rpcDefinition, apis, resourcePath, schemaContext);
         }
 
@@ -238,10 +243,10 @@ public class BaseYangSwaggerGenerator {
     }
 
     private void addRootPostLink(final Module module, final DataNodeContainer node, final List<Parameter> pathParams,
-                                 final String resourcePath, final List<Api> apis) {
+                                 final String resourcePath, final String dataStore, final List<Api> apis) {
         if (containsListOrContainer(module.getChildNodes())) {
             final Api apiForRootPostUri = new Api();
-            apiForRootPostUri.setPath(resourcePath);
+            apiForRootPostUri.setPath(resourcePath.concat(getContent(dataStore)));
             apiForRootPostUri.setOperations(operationPost(module.getName() + MODULE_NAME_SUFFIX,
                     module.getDescription(), module, pathParams, true, ""));
             apis.add(apiForRootPostUri);
@@ -258,22 +263,29 @@ public class BaseYangSwaggerGenerator {
     }
 
     protected String getDataStorePath(final String dataStore, final String context) {
-        return dataStore + context;
+        if (newDraft) {
+            if ("config".contains(dataStore) || "operational".contains(dataStore)) {
+                return "/" + RESTCONF_DRAFT + "/data" + context;
+            } else {
+                return "/" + RESTCONF_DRAFT + "/operations" + context;
+            }
+        } else {
+            return "/" + dataStore + context;
+        }
     }
 
     private String generateCacheKey(final String module, final String revision) {
         return module + "(" + revision + ")";
     }
 
-    private void addApis(final DataSchemaNode node, final List<Api> apis, final String parentPath, final List<Parameter> parentPathParams, final SchemaContext schemaContext,
-                         final boolean addConfigApi, final String parentName) {
-
+    private void addApis(final DataSchemaNode node, final List<Api> apis, final String parentPath, final List<Parameter> parentPathParams,
+                         final SchemaContext schemaContext, final boolean addConfigApi, final String parentName, final String dataStore) {
         final Api api = new Api();
         final List<Parameter> pathParams = new ArrayList<>(parentPathParams);
 
-        final String resourcePath = parentPath + createPath(node, pathParams, schemaContext) + "/";
+        final String resourcePath = parentPath + "/" + createPath(node, pathParams, schemaContext);
         LOG.debug("Adding path: [{}]", resourcePath);
-        api.setPath(resourcePath);
+        api.setPath(resourcePath.concat(getContent(dataStore)));
 
         Iterable<DataSchemaNode> childSchemaNodes = Collections.<DataSchemaNode>emptySet();
         if ((node instanceof ListSchemaNode) || (node instanceof ContainerSchemaNode)) {
@@ -288,12 +300,25 @@ public class BaseYangSwaggerGenerator {
                 // keep config and operation attributes separate.
                 if (childNode.isConfiguration() == addConfigApi) {
                     final String newParent = parentName + "/" + node.getQName().getLocalName();
-                    addApis(childNode, apis, resourcePath, pathParams, schemaContext, addConfigApi, newParent);
+                    addApis(childNode, apis, resourcePath, pathParams, schemaContext, addConfigApi, newParent, dataStore);
                 }
             }
         }
     }
 
+    protected static 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 "";
+        }
+    }
     private boolean containsListOrContainer(final Iterable<DataSchemaNode> nodes) {
         for (final DataSchemaNode child : nodes) {
             if (child instanceof ListSchemaNode || child instanceof ContainerSchemaNode) {
@@ -343,12 +368,21 @@ 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 DataSchemaNode dataChildByName = ((DataNodeContainer) schemaNode).getDataChildByName(listKey);
                 pathListParams.add(((LeafSchemaNode) dataChildByName));
-
-                final String pathParamIdentifier = new StringBuilder("/{").append(listKey.getLocalName()).append("}")
-                        .toString();
+                final String pathParamIdentifier;
+                if (newDraft) {
+                    pathParamIdentifier = keyBuilder.append("{").append(listKey.getLocalName()).append("}")
+                            .toString();
+                } else {
+                    pathParamIdentifier = "/{" + listKey.getLocalName() + "}";
+                }
                 path.append(pathParamIdentifier);
 
                 final Parameter pathParam = new Parameter();
@@ -358,6 +392,9 @@ public class BaseYangSwaggerGenerator {
                 pathParam.setParamType("path");
 
                 pathParams.add(pathParam);
+                if (newDraft) {
+                    keyBuilder = new StringBuilder(",");
+                }
             }
         }
         return path.toString();
@@ -365,7 +402,7 @@ public class BaseYangSwaggerGenerator {
 
     protected void addRpcs(final RpcDefinition rpcDefn, final List<Api> apis, final String parentPath, final SchemaContext schemaContext) {
         final Api rpc = new Api();
-        final String resourcePath = parentPath + resolvePathArgumentsName(rpcDefn, schemaContext);
+        final String resourcePath = parentPath + "/" + resolvePathArgumentsName(rpcDefn, schemaContext);
         rpc.setPath(resourcePath);
 
         final Operation operationSpec = new Operation();
@@ -415,4 +452,7 @@ public class BaseYangSwaggerGenerator {
         return sortedModules;
     }
 
+    public void setDraft(final boolean draft) {
+        this.newDraft = draft;
+    }
 }
index 98268495b86e5ef8069301a20ed7bdddcf755234..11a4db0cf4da8304d1047647ea82482cb59ef79f 100644 (file)
@@ -39,6 +39,7 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
 
     private static final String DATASTORES_REVISION = "-";
     private static final String DATASTORES_LABEL = "Datastores";
+    private static final String RESTCONF_DRAFT = "17";
 
     private DOMMountPointService mountService;
     private final Map<YangInstanceIdentifier, Long> instanceIdToLongId = new TreeMap<>(
@@ -50,7 +51,7 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
 
     private static final AtomicReference<MountPointSwagger> selfRef = new AtomicReference<>();
     private SchemaService globalSchema;
-
+    private static boolean newDraft;
     public Map<String, Long> getInstanceIdentifiers() {
         final Map<String, Long> urlToId = new HashMap<>();
         synchronized (lock) {
@@ -80,20 +81,29 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
 
     private String generateUrlPrefixFromInstanceID(final YangInstanceIdentifier key, final String moduleName) {
         final StringBuilder builder = new StringBuilder();
+        builder.append("/");
         if (moduleName != null) {
-            builder.append(moduleName);
-            builder.append(':');
+            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()) {
-                    builder.append(entry.getValue()).append('/');
+                    if (newDraft) {
+                        builder.deleteCharAt(builder.length() - 1)
+                                .append("=")
+                                .append(entry.getValue())
+                                .append('/');
+                    } else {
+                        builder.append(entry.getValue())
+                                .append('/');
+                    }
                 }
             } else {
-                builder.append(name);
-                builder.append('/');
+                builder.append(name)
+                        .append('/');
             }
         }
         return builder.toString();
@@ -101,7 +111,7 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
 
     private String getYangMountUrl(final YangInstanceIdentifier key) {
         final String modName = findModuleName(key, globalSchema.getGlobalContext());
-        return generateUrlPrefixFromInstanceID(key, modName) + "yang-ext:mount/";
+        return generateUrlPrefixFromInstanceID(key, modName) + "yang-ext:mount";
     }
 
     public ResourceList getResourceList(final UriInfo uriInfo, final Long id) {
@@ -187,7 +197,7 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
         getConfig.setNotes(note);
 
         final Api api = new Api();
-        api.setPath(getDataStorePath("/" + datastore + "/", context));
+        api.setPath(getDataStorePath(datastore, context).concat(getContent(datastore)));
         api.setOperations(Collections.singletonList(getConfig));
 
         return api;
@@ -220,7 +230,17 @@ public class MountPointSwagger extends BaseYangSwaggerGenerator implements Mount
             selfRef.compareAndSet(null, new MountPointSwagger());
             swagger = selfRef.get();
         }
+        newDraft = false;
         return swagger;
     }
 
+    public static MountPointSwagger getInstanceDraft17() {
+        MountPointSwagger swagger = selfRef.get();
+        if (swagger == null) {
+            selfRef.compareAndSet(null, new MountPointSwagger());
+            swagger = selfRef.get();
+        }
+        newDraft = true;
+        return swagger;
+    }
 }
diff --git a/restconf/sal-rest-docgen/src/main/resources/17/explorer/index.html b/restconf/sal-rest-docgen/src/main/resources/17/explorer/index.html
new file mode 100644 (file)
index 0000000..d5126dd
--- /dev/null
@@ -0,0 +1,127 @@
+<!DOCTYPE html>\r
+<!--\r
+  ~ Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.\r
+  ~\r
+  ~ This program and the accompanying materials are made available under the\r
+  ~ terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+  ~ and is available at http://www.eclipse.org/legal/epl-v10.html\r
+  -->\r
+\r
+<html>\r
+<head>\r
+    <title>RestConf Documentation</title>\r
+    <link href='//fonts.googleapis.com/css?family=Droid+Sans:400,700'\r
+          rel='stylesheet' type='text/css'/>\r
+    <link href='../../explorer/css/highlight.default.css' media='screen' rel='stylesheet'\r
+          type='text/css'/>\r
+    <link href='../../explorer/css/screen.css' media='screen' rel='stylesheet'\r
+          type='text/css'/>\r
+    <link rel="stylesheet" type="text/css" href="../../explorer/css/opendaylight.css">\r
+    <link rel="stylesheet" type="text/css"\r
+          href="../../explorer/css/ui-lightness/jquery-ui-1.10.4.custom.min.css">\r
+    <script type="text/javascript" src="../../explorer/lib/shred.bundle.js"></script>\r
+    <script src='../../explorer/lib/jquery-1.8.0.min.js' type='text/javascript'></script>\r
+    <script src='../../explorer/lib/jquery-ui-1.11.0.min.js' type="text/javascript"></script>\r
+    <script src='../../explorer/lib/jquery.slideto.min.js' type='text/javascript'></script>\r
+    <script src='../../explorer/lib/jquery.wiggle.min.js' type='text/javascript'></script>\r
+    <script src='../../explorer/lib/jquery.ba-bbq.min.js' type='text/javascript'></script>\r
+    <script src='../../explorer/lib/handlebars-1.0.0.js' type='text/javascript'></script>\r
+    <script src='../../explorer/lib/underscore-min.js' type='text/javascript'></script>\r
+    <script src='../../explorer/lib/backbone-min.js' type='text/javascript'></script>\r
+    <script src='../../explorer/lib/swagger.js' type='text/javascript'></script>\r
+    <script src='../../explorer/swagger-ui.js' type='text/javascript'></script>\r
+    <script src='lib/odl/list_mounts.js' type='text/javascript'></script>\r
+    <script src='../../explorer/lib/highlight.7.3.pack.js' type='text/javascript'></script>\r
+    <script src='../../explorer/lib/odl/swagger.js' type='text/javascript'></script>\r
+\r
+    <script type="text/javascript">\r
+       \r
+       //reloads the swagger UI documentation for the specified mount.\r
+       var loadMount = function(mountIndex, mountPath) {\r
+               $("#message").empty();\r
+               $("#message").append( "<p>Loading...</p>" );\r
+               loadSwagger("/apidoc/17/apis/mounts/" + mountIndex,\r
+                               "swagger-ui-container");\r
+               $("#message").empty();\r
+               $("#message").append( "<h2><b>Showing mount points for " + mountPath + "</b></h2>");\r
+       }\r
+\r
+       //clears the swagger UI and adds text prompting use to select a mount point.\r
+    var selectAMount = function(string) {\r
+        $("#swagger-ui-container").empty();\r
+        $("#message").empty();\r
+        $("#message").append("<p>Select a mount point.</p>");\r
+    }\r
+    \r
+       //loads the root swagger documenation (which comes from RestConf)\r
+       var loadRootSwagger = function() {\r
+               $("#message").empty();\r
+               loadSwagger("/apidoc/17/apis", "swagger-ui-container");\r
+       }\r
+\r
+       //main method to initialize the mount list / swagger docs / tabs on page load\r
+       $(function() {\r
+               $("#tabs").tabs();\r
+\r
+               loadMountList($("#mountlist"));\r
+\r
+               loadRootSwagger();\r
+       });\r
+    </script>\r
+</head>\r
+\r
+<body>\r
+<div>\r
+    <!-- style="background-color: #FCA000;" -->\r
+    <div class="swagger-ui-wrap ui-tabs">\r
+        <table>\r
+            <tr>\r
+                <td><img src="../../explorer/images/logo_small.png"/></td>\r
+                <td><h1 width="100%">OpenDaylight RestConf API\r
+                    Documentation</h1></td>\r
+            </tr>\r
+        </table>\r
+    </div>\r
+</div>\r
+\r
+<div class="navbar-inner">\r
+    <div class="brand"></div>\r
+</div>\r
+\r
+<!--  defines the div shells which represent the jquery tabs -->\r
+<div id="tabs" class="swagger-ui-wrap">\r
+    <ul>\r
+        <li><a href="#Controller" onclick="loadRootSwagger()">Controller\r
+            Resources</a></li>\r
+        <li><a href="#Mounts" onclick="selectAMount()">Mounted\r
+            Resources</a></li>\r
+    </ul>\r
+\r
+    <div id="Controller">\r
+        <div>\r
+            <h3>Below are the list of APIs supported by the Controller.</h3>\r
+        </div>\r
+    </div>\r
+    <div id="Mounts">\r
+        <div>\r
+            <h3>Mount Points - Select an API below for details on available\r
+                queries.</h3>\r
+        </div>\r
+        <div id="mountlist"></div>\r
+    </div>\r
+</div>\r
+\r
+<div class="swagger-ui-wrap">\r
+    <hr/>\r
+</div>\r
+\r
+<!-- messages -->\r
+<div id="message" class="swagger-ui-wrap"></div>\r
+\r
+<!-- the swagger is always loaded in this div -->\r
+<div id="swagger-ui-container" class="swagger-ui-wrap"></div>\r
+\r
+<div id="message-bar" class="swagger-ui-wrap">&nbsp;</div>\r
+</body>\r
+\r
+</html>\r
diff --git a/restconf/sal-rest-docgen/src/main/resources/17/explorer/lib/odl/list_mounts.js b/restconf/sal-rest-docgen/src/main/resources/17/explorer/lib/odl/list_mounts.js
new file mode 100644 (file)
index 0000000..b9b4c62
--- /dev/null
@@ -0,0 +1,22 @@
+//constructs a table of mount points via a json response
+//Loads the table into the given dom.
+var loadMountList = function( dom ) {
+    dom.empty();
+    dom.append( "<p>Loading. Please wait...</p>" );
+    $.ajax( {
+        url: "/apidoc/17/apis/mounts",
+        datatype: 'jsonp',
+        success: function( strData ){
+            var myData = strData;
+            var list = $( "<table></table>" );
+            for( var key in myData )
+            {
+                list.append( "<tr><td><a href=\"#\" onclick=\"loadMount(" + 
+                                        myData[key].id + ", '" + myData[key].instance + "')\">" +
+                                        myData[key].instance + "</a></td></tr>");
+            }
+            dom.empty();
+            dom.append( list );
+        }
+    } );
+}
\ No newline at end of file
diff --git a/restconf/sal-rest-docgen/src/main/resources/17/explorer/static/index.html b/restconf/sal-rest-docgen/src/main/resources/17/explorer/static/index.html
new file mode 100644 (file)
index 0000000..4fb8f22
--- /dev/null
@@ -0,0 +1,117 @@
+<!DOCTYPE html>
+<!--
+  ~ Copyright (c) 2016 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
+  -->
+
+<html>
+<head>
+    <title>RestConf Documentation</title>
+    <link href='../../../eplorer/static/fonts.css'
+          rel='stylesheet' type='text/css' />   <!--original location: //fonts.googleapis.com/css?family=Droid+Sans:400,700 -->
+    <link href='../../../explorer/css/highlight.default.css' media='screen' rel='stylesheet'
+          type='text/css' />
+    <link href='../../../explorer/css/screen.css' media='screen' rel='stylesheet'
+          type='text/css' />
+    <link rel="stylesheet" type="text/css" href="../../../eplorer/static/opendaylight.css">
+    <link rel="stylesheet" type="text/css"
+          href="../../../explorer/css/ui-lightness/jquery-ui-1.10.4.custom.min.css">
+    <script type="text/javascript" src="../../../explorer/lib/shred.bundle.js"></script>
+    <script src='../../../explorer/lib/jquery-1.8.0.min.js' type='text/javascript'></script>
+    <script src='../../../explorer/lib/jquery-ui-1.11.0.min.js' type="text/javascript"></script>
+    <script src='../../../explorer/lib/jquery.slideto.min.js' type='text/javascript'></script>
+    <script src='../../../explorer/lib/jquery.wiggle.min.js' type='text/javascript'></script>
+    <script src='../../../explorer/lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
+    <script src='../../../explorer/lib/handlebars-1.0.0.js' type='text/javascript'></script>
+    <script src='../../../explorer/lib/underscore-min.js' type='text/javascript'></script>
+    <script src='../../../explorer/lib/backbone-min.js' type='text/javascript'></script>
+    <script src='../../explorer/swagger.js' type='text/javascript'></script>
+    <script src='../../explorer/swagger-ui.js' type='text/javascript'></script>
+    <script src='../lib/odl/list_mounts.js' type='text/javascript'></script>
+    <script src='../../../explorer/lib/highlight.7.3.pack.js' type='text/javascript'></script>
+    <script src='../../../explorer/lib/odl/swagger.js' type='text/javascript'></script>
+    <script src='resources.js' type='text/javascript'></script>
+
+    <script type="text/javascript">
+
+        //reloads the swagger UI documentation for the specified mount.
+        var loadMount = function(mountIndex, mountPath) {
+            $("#message").empty();
+            $("#message").append( "<p>Loading...</p>" );
+            loadSwagger("/apidoc/apis/mounts/" + mountIndex,
+                    "swagger-ui-container");
+            $("#message").empty();
+            $("#message").append( "<h2><b>Showing mount points for " + mountPath + "</b></h2>");
+        }
+
+        //clears the swagger UI and adds text prompting use to select a mount point.
+        var selectAMount = function(string) {
+            $("#swagger-ui-container").empty();
+            $("#message").empty();
+            $("#message").append("<p>Select a mount point.</p>");
+        }
+
+        //loads the root swagger documenation (which comes from RestConf)
+        var loadRootSwagger = function() {
+            $("#message").empty();
+            loadSwagger("/apidoc/apis", "swagger-ui-container");
+        }
+
+        //main method to initialize the mount list / swagger docs / tabs on page load
+        $(function() {
+            $("#tabs").tabs();
+
+            loadMountList($("#mountlist"));
+
+            loadRootSwagger();
+        });
+    </script>
+</head>
+
+<body>
+<div>
+    <!-- style="background-color: #FCA000;" -->
+    <div class="swagger-ui-wrap ui-tabs">
+        <table>
+            <tr>
+                <td><img src="../../../explorer/images/logo_small.png"/></td>
+                <td><h1 width="100%">OpenDaylight RestConf API
+                    Documentation</h1></td>
+            </tr>
+        </table>
+    </div>
+</div>
+
+<div class="navbar-inner">
+    <div class="brand"></div>
+</div>
+
+<!--  defines the div shells which represent the jquery tabs -->
+<div id="tabs" class="swagger-ui-wrap">
+    <ul>
+        <li><a href="#Controller" onclick="loadRootSwagger()">Controller
+            Resources</a></li>
+    </ul>
+
+    <div id="Controller">
+        <div>
+            <h3>Below are the list of APIs supported by the Controller.</h3>
+        </div>
+    </div>
+</div>
+
+<div class="swagger-ui-wrap"><hr/></div>
+
+<!-- messages -->
+<div id="message" class="swagger-ui-wrap"></div>
+
+<!-- the swagger is always loaded in this div -->
+<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
+
+<div id="message-bar" class="swagger-ui-wrap">&nbsp;</div>
+</body>
+
+</html>
index 7e72e8347c2024c1867f771e0754991cddab5926..0c279a57ace63bc1afdbfd17610c03f2ec3ce610 100644 (file)
@@ -3,6 +3,7 @@ This component offers Swagger documentation of the RestConf APIs.
 This Swagger documentation can be accessed in two ways:
 I. Running server
 Open a browser and go to http://<host>:8181/apidoc/explorer/index.html
+For new restconf draft go to http://<host>:8181/apidoc/17/explorer/index.html
 
 II. Static documentation generation
 By adding a reference to the StaticDocGenerator class in any pom.xml,
index cd267696304312eac072d295aba47b1529b6b343..849e2c90e39d397eb49c19e052e701433248806d 100644 (file)
@@ -1,7 +1,7 @@
 <?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">
+         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>
@@ -16,8 +16,8 @@
     </servlet>
 
     <context-param>
-      <param-name>shiroEnvironmentClass</param-name>
-      <param-value>org.opendaylight.aaa.shiro.web.env.KarafIniWebEnvironment</param-value>
+        <param-name>shiroEnvironmentClass</param-name>
+        <param-value>org.opendaylight.aaa.shiro.web.env.KarafIniWebEnvironment</param-value>
     </context-param>
 
     <listener>
         <url-pattern>/apis/*</url-pattern>
     </servlet-mapping>
 
+    <servlet-mapping>
+        <servlet-name>JAXRSApiDoc</servlet-name>
+        <url-pattern>/17/apis/*</url-pattern>
+    </servlet-mapping>
+
     <filter>
         <filter-name>cross-origin-api-doc</filter-name>
         <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
         <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>/17/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>
+        <web-resource-collection>
+            <web-resource-name>API Doc</web-resource-name>
+            <url-pattern>/*</url-pattern>
+        </web-resource-collection>
     </security-constraint>
 
 </web-app>
index f744da790641a5fd4c68faa4a7b482a1b1f58417..ee1b1eea056a786939a3c055fe847c89b8e49a64 100644 (file)
@@ -52,6 +52,7 @@ public class ApiDocGeneratorTest {
     @Before
     public void setUp() throws Exception {
         this.generator = new ApiDocGenerator();
+        generator.setDraft(false);
         this.helper = new DocGenTestHelper();
         this.helper.setUp();
 
@@ -88,21 +89,21 @@ public class ApiDocGeneratorTest {
      */
     private void validateSwaggerApisForPost(final ApiDeclaration doc) {
         // two POST URI with concrete schema name in summary
-        final Api lstApi = findApi("/config/toaster2:lst/", doc);
-        assertNotNull("Api /config/toaster2:lst/ wasn't found", lstApi);
+        final Api lstApi = findApi("/config/toaster2:lst", doc);
+        assertNotNull("Api /config/toaster2:lst wasn't found", lstApi);
         assertTrue("POST for cont1 in lst is missing",
                 findOperation(lstApi.getOperations(), "POST", "(config)lstPOST", "toaster2/lst(config)lst1-TOP",
                         "toaster2/lst(config)cont1-TOP"));
 
-        final Api cont1Api = findApi("/config/toaster2:lst/cont1/", doc);
-        assertNotNull("Api /config/toaster2:lst/cont1/ wasn't found", cont1Api);
+        final Api cont1Api = findApi("/config/toaster2:lst/cont1", doc);
+        assertNotNull("Api /config/toaster2:lst/cont1 wasn't found", cont1Api);
         assertTrue("POST for cont11 in cont1 is missing",
                 findOperation(cont1Api.getOperations(), "POST", "(config)cont1POST", "toaster2/lst/cont1(config)cont11-TOP",
                         "toaster2/lst/cont1(config)lst11-TOP"));
 
         // no POST URI
-        final Api cont11Api = findApi("/config/toaster2:lst/cont1/cont11/", doc);
-        assertNotNull("Api /config/toaster2:lst/cont1/cont11/ wasn't found", cont11Api);
+        final Api cont11Api = findApi("/config/toaster2:lst/cont1/cont11", doc);
+        assertNotNull("Api /config/toaster2:lst/cont1/cont11 wasn't found", cont11Api);
         assertTrue("POST operation shouldn't be present.", findOperations(cont11Api.getOperations(), "POST").isEmpty());
 
     }
@@ -284,10 +285,10 @@ public class ApiDocGeneratorTest {
      * @throws Exception
      */
     private void validateToaster(final ApiDeclaration doc) throws Exception {
-        final Set<String> expectedUrls = new TreeSet<>(Arrays.asList(new String[] { "/config/toaster2:toaster/",
-                "/operational/toaster2:toaster/", "/operations/toaster2:cancel-toast",
+        final Set<String> expectedUrls = new TreeSet<>(Arrays.asList(new String[]{"/config/toaster2:toaster",
+                "/operational/toaster2:toaster", "/operations/toaster2:cancel-toast",
                 "/operations/toaster2:make-toast", "/operations/toaster2:restock-toaster",
-                "/config/toaster2:toaster/toasterSlot/{slotId}/toaster-augmented:slotInfo/" }));
+                "/config/toaster2:toaster/toasterSlot/{slotId}/toaster-augmented:slotInfo"}));
 
         final Set<String> actualUrls = new TreeSet<>();
 
index 6342d1a780e00eed410c0803e40ce80e914b0fb7..b04064577465679862e4436bcac3c9302bcf5b7e 100644 (file)
@@ -41,7 +41,7 @@ public class MountPointSwaggerTest {
             .node(QName.create("nodes"))
             .node(QName.create("node"))
             .nodeWithKey(QName.create("node"), QName.create("id"), "123").build();
-    private static final String INSTANCE_URL = "nodes/node/123/";
+    private static final String INSTANCE_URL = "/nodes/node/123/";
     private MountPointSwagger swagger;
     private DocGenTestHelper helper;
     private SchemaContext schemaContext;
@@ -99,6 +99,7 @@ public class MountPointSwaggerTest {
         final UriInfo mockInfo = setUpSwaggerForDocGeneration();
         this.swagger.onMountPointCreated(instanceId); // add this ID into the list of
                                                  // mount points
+
         final ApiDeclaration mountPointApi = this.swagger.getMountPointApi(mockInfo, 1L, "Datastores", "-");
         assertNotNull("failed to find Datastore API", mountPointApi);
         final List<Api> apis = mountPointApi.getApis();
@@ -115,9 +116,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/", }));
+                "/config" + INSTANCE_URL + "yang-ext:mount",
+                "/operational" + INSTANCE_URL + "yang-ext:mount",
+                "/operations" + INSTANCE_URL + "yang-ext:mount",}));
         assertEquals(expectedApis, actualApis);
     }