X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-rest-docgen%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Frest%2Fdoc%2Fimpl%2FBaseYangSwaggerGenerator.java;h=5d0f3612e4f3c931c39199a0f180461b8430e0f8;hp=68d31de8da35688737e927689d5f55a9085de2e9;hb=30faeb35260541c273a81b8f126b40da94daa825;hpb=0bdf3307bc17f562c84cceeacd29f42409bfff34 diff --git a/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/impl/BaseYangSwaggerGenerator.java b/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/impl/BaseYangSwaggerGenerator.java index 68d31de8da..5d0f3612e4 100644 --- a/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/impl/BaseYangSwaggerGenerator.java +++ b/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/impl/BaseYangSwaggerGenerator.java @@ -7,6 +7,12 @@ */ package org.opendaylight.controller.sal.rest.doc.impl; +import static org.opendaylight.controller.sal.rest.doc.util.RestDocgenUtil.resolvePathArgumentsName; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule; +import com.google.common.base.Preconditions; import java.io.IOException; import java.net.URI; import java.text.DateFormat; @@ -14,6 +20,7 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Date; @@ -21,9 +28,7 @@ import java.util.List; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; - import javax.ws.rs.core.UriInfo; - import org.json.JSONException; import org.json.JSONObject; import org.opendaylight.controller.sal.rest.doc.model.builder.OperationBuilder; @@ -45,11 +50,6 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule; -import com.google.common.base.Preconditions; - public class BaseYangSwaggerGenerator { private static Logger _logger = LoggerFactory.getLogger(BaseYangSwaggerGenerator.class); @@ -57,6 +57,8 @@ 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"; + + static final String MODULE_NAME_SUFFIX = "_module"; protected final DateFormat SIMPLE_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); private final ModelGenerator jsonConverter = new ModelGenerator(); @@ -74,8 +76,7 @@ public class BaseYangSwaggerGenerator { * @param operType * @return list of modules converted to swagger compliant resource list. */ - public ResourceList getResourceListing(UriInfo uriInfo, SchemaContext schemaContext, - String context) { + public ResourceList getResourceListing(UriInfo uriInfo, SchemaContext schemaContext, String context) { ResourceList resourceList = createResourceList(); @@ -87,11 +88,9 @@ public class BaseYangSwaggerGenerator { for (Module module : modules) { String revisionString = SIMPLE_DATE_FORMAT.format(module.getRevision()); - Resource resource = new Resource(); _logger.debug("Working on [{},{}]...", module.getName(), revisionString); - ApiDeclaration doc = getApiDeclaration(module.getName(), revisionString, uriInfo, - schemaContext, context); + ApiDeclaration doc = getApiDeclaration(module.getName(), revisionString, uriInfo, schemaContext, context); if (doc != null) { resource.setPath(generatePath(uriInfo, module.getName(), revisionString)); @@ -118,8 +117,7 @@ public class BaseYangSwaggerGenerator { return uri.toASCIIString(); } - public ApiDeclaration getApiDeclaration(String module, String revision, UriInfo uriInfo, - SchemaContext schemaContext, String context) { + public ApiDeclaration getApiDeclaration(String module, String revision, UriInfo uriInfo, SchemaContext schemaContext, String context) { Date rev = null; try { rev = SIMPLE_DATE_FORMAT.parse(revision); @@ -127,17 +125,15 @@ public class BaseYangSwaggerGenerator { throw new IllegalArgumentException(e); } Module m = schemaContext.findModuleByName(module, rev); - Preconditions.checkArgument(m != null, "Could not find module by name,revision: " + module - + "," + revision); + Preconditions.checkArgument(m != null, "Could not find module by name,revision: " + module + "," + revision); - return getApiDeclaration(m, rev, uriInfo, schemaContext, context); + return getApiDeclaration(m, rev, uriInfo, context, schemaContext); } - public ApiDeclaration getApiDeclaration(Module module, Date revision, UriInfo uriInfo, - SchemaContext schemaContext, String context) { + public ApiDeclaration getApiDeclaration(Module module, Date revision, UriInfo uriInfo, String context, SchemaContext schemaContext) { String basePath = createBasePathFromUriInfo(uriInfo); - ApiDeclaration doc = getSwaggerDocSpec(module, basePath, context); + ApiDeclaration doc = getSwaggerDocSpec(module, basePath, context, schemaContext); if (doc != null) { return doc; } @@ -151,37 +147,37 @@ public class BaseYangSwaggerGenerator { portPart = ":" + port; } String basePath = new StringBuilder(uriInfo.getBaseUri().getScheme()).append("://") - .append(uriInfo.getBaseUri().getHost()).append(portPart).append("/") - .append(RESTCONF_CONTEXT_ROOT).toString(); + .append(uriInfo.getBaseUri().getHost()).append(portPart).append("/").append(RESTCONF_CONTEXT_ROOT) + .toString(); return basePath; } - public ApiDeclaration getSwaggerDocSpec(Module m, String basePath, String context) { + public ApiDeclaration getSwaggerDocSpec(Module m, String basePath, String context, SchemaContext schemaContext) { ApiDeclaration doc = createApiDeclaration(basePath); List apis = new ArrayList(); - Set dataSchemaNodes = m.getChildNodes(); + Collection dataSchemaNodes = m.getChildNodes(); _logger.debug("child nodes size [{}]", dataSchemaNodes.size()); for (DataSchemaNode node : dataSchemaNodes) { if ((node instanceof ListSchemaNode) || (node instanceof ContainerSchemaNode)) { - _logger.debug("Is Configuration node [{}] [{}]", node.isConfiguration(), node - .getQName().getLocalName()); + _logger.debug("Is Configuration node [{}] [{}]", node.isConfiguration(), node.getQName().getLocalName()); List pathParams = new ArrayList(); - String resourcePath = getDataStorePath("/config/", context) + m.getName() + ":"; - addApis(node, apis, resourcePath, pathParams, true); + String resourcePath = getDataStorePath("/config/", context); + addRootPostLink(m, (DataNodeContainer) node, pathParams, resourcePath, apis); + addApis(node, apis, resourcePath, pathParams, schemaContext, true); pathParams = new ArrayList(); - resourcePath = getDataStorePath("/operational/", context) + m.getName() + ":"; - addApis(node, apis, resourcePath, pathParams, false); + resourcePath = getDataStorePath("/operational/", context); + addApis(node, apis, resourcePath, pathParams, schemaContext, false); } Set rpcs = m.getRpcs(); for (RpcDefinition rpcDefinition : rpcs) { - String resourcePath = getDataStorePath("/operations/", context) + m.getName() + ":"; - addRpcs(rpcDefinition, apis, resourcePath); + String resourcePath = getDataStorePath("/operations/", context); + addRpcs(rpcDefinition, apis, resourcePath, schemaContext); } } @@ -192,7 +188,7 @@ public class BaseYangSwaggerGenerator { JSONObject models = null; try { - models = jsonConverter.convertToJsonSchema(m); + models = jsonConverter.convertToJsonSchema(m, schemaContext); doc.setModels(models); if (_logger.isDebugEnabled()) { _logger.debug(mapper.writeValueAsString(doc)); @@ -206,6 +202,16 @@ public class BaseYangSwaggerGenerator { return null; } + private void addRootPostLink(final Module m, final DataNodeContainer node, final List pathParams, + final String resourcePath, final List apis) { + if (containsListOrContainer(m.getChildNodes())) { + final Api apiForRootPostUri = new Api(); + apiForRootPostUri.setPath(resourcePath); + apiForRootPostUri.setOperations(operationPost(m.getName()+MODULE_NAME_SUFFIX, m.getDescription(), m, pathParams, true)); + apis.add(apiForRootPostUri); + } + } + protected ApiDeclaration createApiDeclaration(String basePath) { ApiDeclaration doc = new ApiDeclaration(); doc.setApiVersion(API_VERSION); @@ -227,95 +233,116 @@ public class BaseYangSwaggerGenerator { return module + "(" + revision + ")"; } - private void addApis(DataSchemaNode node, List apis, String parentPath, - List parentPathParams, boolean addConfigApi) { + private void addApis(DataSchemaNode node, List apis, String parentPath, List parentPathParams, SchemaContext schemaContext, + boolean addConfigApi) { Api api = new Api(); List pathParams = new ArrayList(parentPathParams); - String resourcePath = parentPath + createPath(node, pathParams) + "/"; + String resourcePath = parentPath + createPath(node, pathParams, schemaContext) + "/"; _logger.debug("Adding path: [{}]", resourcePath); api.setPath(resourcePath); - api.setOperations(operations(node, pathParams, addConfigApi)); - apis.add(api); + + Iterable childSchemaNodes = Collections. emptySet(); if ((node instanceof ListSchemaNode) || (node instanceof ContainerSchemaNode)) { - DataNodeContainer schemaNode = (DataNodeContainer) node; - Set dataSchemaNodes = schemaNode.getChildNodes(); - - for (DataSchemaNode childNode : dataSchemaNodes) { - // We don't support going to leaf nodes today. Only lists and - // containers. - if (childNode instanceof ListSchemaNode || childNode instanceof ContainerSchemaNode) { - // keep config and operation attributes separate. - if (childNode.isConfiguration() == addConfigApi) { - addApis(childNode, apis, resourcePath, pathParams, addConfigApi); - } + DataNodeContainer dataNodeContainer = (DataNodeContainer) node; + childSchemaNodes = dataNodeContainer.getChildNodes(); + } + api.setOperations(operation(node, pathParams, addConfigApi, childSchemaNodes)); + apis.add(api); + + for (DataSchemaNode childNode : childSchemaNodes) { + if (childNode instanceof ListSchemaNode || childNode instanceof ContainerSchemaNode) { + // keep config and operation attributes separate. + if (childNode.isConfiguration() == addConfigApi) { + addApis(childNode, apis, resourcePath, pathParams, schemaContext, addConfigApi); } } } } + private boolean containsListOrContainer(final Iterable nodes) { + for (DataSchemaNode child : nodes) { + if (child instanceof ListSchemaNode || child instanceof ContainerSchemaNode) { + return true; + } + } + return false; + } + /** * @param node * @param pathParams * @return */ - private List operations(DataSchemaNode node, List pathParams, - boolean isConfig) { + private List operation(DataSchemaNode node, List pathParams, boolean isConfig, Iterable childSchemaNodes) { List operations = new ArrayList<>(); OperationBuilder.Get getBuilder = new OperationBuilder.Get(node, isConfig); operations.add(getBuilder.pathParams(pathParams).build()); if (isConfig) { - OperationBuilder.Post postBuilder = new OperationBuilder.Post(node); - operations.add(postBuilder.pathParams(pathParams).build()); - - OperationBuilder.Put putBuilder = new OperationBuilder.Put(node); + OperationBuilder.Put putBuilder = new OperationBuilder.Put(node.getQName().getLocalName(), + node.getDescription()); operations.add(putBuilder.pathParams(pathParams).build()); OperationBuilder.Delete deleteBuilder = new OperationBuilder.Delete(node); operations.add(deleteBuilder.pathParams(pathParams).build()); + + if (containsListOrContainer(childSchemaNodes)) { + operations.addAll(operationPost(node.getQName().getLocalName(), node.getDescription(), (DataNodeContainer) node, + pathParams, isConfig)); + } } return operations; } - private String createPath(final DataSchemaNode schemaNode, List pathParams) { + /** + * @param node + * @param pathParams + * @return + */ + private List operationPost(final String name, final String description, final DataNodeContainer dataNodeContainer, List pathParams, boolean isConfig) { + List operations = new ArrayList<>(); + if (isConfig) { + OperationBuilder.Post postBuilder = new OperationBuilder.Post(name, description, dataNodeContainer); + operations.add(postBuilder.pathParams(pathParams).build()); + } + return operations; + } + + private String createPath(final DataSchemaNode schemaNode, List pathParams, SchemaContext schemaContext) { ArrayList pathListParams = new ArrayList(); StringBuilder path = new StringBuilder(); - QName _qName = schemaNode.getQName(); - String localName = _qName.getLocalName(); + String localName = resolvePathArgumentsName(schemaNode, schemaContext); path.append(localName); if ((schemaNode instanceof ListSchemaNode)) { final List listKeys = ((ListSchemaNode) schemaNode).getKeyDefinition(); for (final QName listKey : listKeys) { - { - DataSchemaNode _dataChildByName = ((DataNodeContainer) schemaNode) - .getDataChildByName(listKey); - pathListParams.add(((LeafSchemaNode) _dataChildByName)); - - String pathParamIdentifier = new StringBuilder("/{") - .append(listKey.getLocalName()).append("}").toString(); - path.append(pathParamIdentifier); - - Parameter pathParam = new Parameter(); - pathParam.setName(listKey.getLocalName()); - pathParam.setDescription(_dataChildByName.getDescription()); - pathParam.setType("string"); - pathParam.setParamType("path"); - - pathParams.add(pathParam); - } + DataSchemaNode _dataChildByName = ((DataNodeContainer) schemaNode).getDataChildByName(listKey); + pathListParams.add(((LeafSchemaNode) _dataChildByName)); + + String pathParamIdentifier = new StringBuilder("/{").append(listKey.getLocalName()).append("}") + .toString(); + path.append(pathParamIdentifier); + + Parameter pathParam = new Parameter(); + pathParam.setName(listKey.getLocalName()); + pathParam.setDescription(_dataChildByName.getDescription()); + pathParam.setType("string"); + pathParam.setParamType("path"); + + pathParams.add(pathParam); } } return path.toString(); } - protected void addRpcs(RpcDefinition rpcDefn, List apis, String parentPath) { + protected void addRpcs(RpcDefinition rpcDefn, List apis, String parentPath, SchemaContext schemaContext) { Api rpc = new Api(); - String resourcePath = parentPath + rpcDefn.getQName().getLocalName(); + String resourcePath = parentPath + resolvePathArgumentsName(rpcDefn, schemaContext); rpc.setPath(resourcePath); Operation operationSpec = new Operation(); @@ -364,4 +391,5 @@ public class BaseYangSwaggerGenerator { } return sortedModules; } + }