From: Devin Avery Date: Mon, 11 Aug 2014 14:05:57 +0000 (+0000) Subject: Merge "BUG 907 distinguish augmented nodes" X-Git-Tag: release/helium~315 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=c911a187bdcd6160c1929e53466cd9de681c2098;hp=4ffcfb707d6db0ee833185aba9f2ab268c51a62e;p=controller.git Merge "BUG 907 distinguish augmented nodes" --- diff --git a/opendaylight/md-sal/sal-rest-docgen/pom.xml b/opendaylight/md-sal/sal-rest-docgen/pom.xml index 0c8b4d5a2a..1141e1d72e 100644 --- a/opendaylight/md-sal/sal-rest-docgen/pom.xml +++ b/opendaylight/md-sal/sal-rest-docgen/pom.xml @@ -96,6 +96,10 @@ mockito-all test + + org.opendaylight.yangtools + yang-data-api + diff --git a/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocGenerator.java b/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocGenerator.java index 82409d2e40..633d419fa9 100644 --- a/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocGenerator.java +++ b/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocGenerator.java @@ -7,8 +7,8 @@ */ package org.opendaylight.controller.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.controller.sal.rest.doc.swagger.ApiDeclaration; import org.opendaylight.controller.sal.rest.doc.swagger.ResourceList; @@ -16,11 +16,8 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Preconditions; - /** - * This class gathers all yang defined {@link Module}s and generates Swagger - * compliant documentation. + * This class gathers all yang defined {@link Module}s and generates Swagger compliant documentation. */ public class ApiDocGenerator extends BaseYangSwaggerGenerator { 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 5ba8b26bc1..1b27182514 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; @@ -22,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; @@ -46,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); @@ -75,8 +74,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(); @@ -88,11 +86,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)); @@ -119,8 +115,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); @@ -128,17 +123,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; } @@ -152,12 +145,12 @@ 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(); @@ -167,22 +160,21 @@ public class BaseYangSwaggerGenerator { 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); + 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); } } @@ -193,7 +185,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)); @@ -228,13 +220,13 @@ 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)); @@ -248,7 +240,7 @@ public class BaseYangSwaggerGenerator { if (childNode instanceof ListSchemaNode || childNode instanceof ContainerSchemaNode) { // keep config and operation attributes separate. if (childNode.isConfiguration() == addConfigApi) { - addApis(childNode, apis, resourcePath, pathParams, addConfigApi); + addApis(childNode, apis, resourcePath, pathParams, schemaContext, addConfigApi); } } } @@ -261,8 +253,7 @@ public class BaseYangSwaggerGenerator { * @param pathParams * @return */ - private List operations(DataSchemaNode node, List pathParams, - boolean isConfig) { + private List operations(DataSchemaNode node, List pathParams, boolean isConfig) { List operations = new ArrayList<>(); OperationBuilder.Get getBuilder = new OperationBuilder.Get(node, isConfig); @@ -281,41 +272,37 @@ public class BaseYangSwaggerGenerator { return operations; } - private String createPath(final DataSchemaNode schemaNode, List pathParams) { + 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 +351,5 @@ public class BaseYangSwaggerGenerator { } return sortedModules; } + } diff --git a/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/impl/ModelGenerator.java b/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/impl/ModelGenerator.java index 95bb1a0943..819892f647 100644 --- a/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/impl/ModelGenerator.java +++ b/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/impl/ModelGenerator.java @@ -7,6 +7,8 @@ */ package org.opendaylight.controller.sal.rest.doc.impl; +import static org.opendaylight.controller.sal.rest.doc.util.RestDocgenUtil.resolveNodesName; + import java.io.IOException; import java.util.ArrayList; import java.util.Collections; @@ -19,6 +21,7 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.opendaylight.controller.sal.rest.doc.model.builder.OperationBuilder; +import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode; import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode; import org.opendaylight.yangtools.yang.model.api.ChoiceNode; @@ -31,6 +34,7 @@ import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.RpcDefinition; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition; import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition; @@ -86,8 +90,8 @@ public class ModelGenerator { private static final String NUMBER = "number"; private static final String BOOLEAN = "boolean"; private static final String STRING = "string"; - private static final String ID_KEY = "id"; - private static final String SUB_TYPES_KEY = "subTypes"; + private static final String ID_KEY = "id"; + private static final String SUB_TYPES_KEY = "subTypes"; private static final Map>, String> YANG_TYPE_TO_JSON_TYPE_MAPPING; @@ -111,18 +115,21 @@ public class ModelGenerator { YANG_TYPE_TO_JSON_TYPE_MAPPING = Collections.unmodifiableMap(tempMap1); } + private Module topLevelModule; + public ModelGenerator() { } - public JSONObject convertToJsonSchema(Module module) throws IOException, JSONException { + public JSONObject convertToJsonSchema(Module module, SchemaContext schemaContext) throws IOException, JSONException { JSONObject models = new JSONObject(); - processContainers(module, models); - processRPCs(module, models); - processIdentities(module, models); + topLevelModule = module; + processContainers(module, models, schemaContext); + processRPCs(module, models, schemaContext); + processIdentities(module, models); return models; } - private void processContainers(Module module, JSONObject models) throws IOException, + private void processContainers(Module module, JSONObject models, SchemaContext schemaContext) throws IOException, JSONException { String moduleName = module.getName(); @@ -136,10 +143,10 @@ public class ModelGenerator { * For every container in the module */ if (childNode instanceof ContainerSchemaNode) { - configModuleJSON = processContainer((ContainerSchemaNode) childNode, moduleName, - true, models, true); - operationalModuleJSON = processContainer((ContainerSchemaNode) childNode, - moduleName, true, models, false); + configModuleJSON = processContainer((ContainerSchemaNode) childNode, moduleName, true, models, true, + schemaContext); + operationalModuleJSON = processContainer((ContainerSchemaNode) childNode, moduleName, true, models, + false, schemaContext); } if (configModuleJSON != null) { @@ -157,15 +164,15 @@ public class ModelGenerator { } /** - * Process the RPCs for a Module Spits out a file each of the name - * -input.json and -output.json for each RPC that contains - * input & output elements + * Process the RPCs for a Module Spits out a file each of the name -input.json and -output.json + * for each RPC that contains input & output elements * * @param module * @throws JSONException * @throws IOException */ - private void processRPCs(Module module, JSONObject models) throws JSONException, IOException { + private void processRPCs(Module module, JSONObject models, SchemaContext schemaContext) throws JSONException, + IOException { Set rpcs = module.getRpcs(); String moduleName = module.getName(); @@ -173,7 +180,7 @@ public class ModelGenerator { ContainerSchemaNode input = rpc.getInput(); if (input != null) { - JSONObject inputJSON = processContainer(input, moduleName, true, models); + JSONObject inputJSON = processContainer(input, moduleName, true, models, schemaContext); String filename = "(" + rpc.getQName().getLocalName() + ")input"; inputJSON.put("id", filename); // writeToFile(filename, inputJSON.toString(2), moduleName); @@ -182,7 +189,7 @@ public class ModelGenerator { ContainerSchemaNode output = rpc.getOutput(); if (output != null) { - JSONObject outputJSON = processContainer(output, moduleName, true, models); + JSONObject outputJSON = processContainer(output, moduleName, true, models, schemaContext); String filename = "(" + rpc.getQName().getLocalName() + ")output"; outputJSON.put("id", filename); models.put(filename, outputJSON); @@ -190,58 +197,59 @@ public class ModelGenerator { } } - /** - * Processes the 'identity' statement in a yang model - * and maps it to a 'model' in the Swagger JSON spec. - * - * @param module The module from which the identity stmt will be processed - * @param models The JSONObject in which the parsed identity will be put as a 'model' obj - * @throws JSONException - */ - private void processIdentities(Module module, JSONObject models) throws JSONException { - - String moduleName = module.getName(); - Set idNodes = module.getIdentities(); - _logger.debug("Processing Identities for module {} . Found {} identity statements", moduleName, idNodes.size()); - - for(IdentitySchemaNode idNode : idNodes){ - JSONObject identityObj=new JSONObject(); - String identityName = idNode.getQName().getLocalName(); - _logger.debug("Processing Identity: {}", identityName); - - identityObj.put(ID_KEY, identityName); - identityObj.put(DESCRIPTION_KEY, idNode.getDescription()); - - JSONObject props = new JSONObject(); - IdentitySchemaNode baseId = idNode.getBaseIdentity(); + /** + * Processes the 'identity' statement in a yang model and maps it to a 'model' in the Swagger JSON spec. + * + * @param module + * The module from which the identity stmt will be processed + * @param models + * The JSONObject in which the parsed identity will be put as a 'model' obj + * @throws JSONException + */ + private void processIdentities(Module module, JSONObject models) throws JSONException { + String moduleName = module.getName(); + Set idNodes = module.getIdentities(); + _logger.debug("Processing Identities for module {} . Found {} identity statements", moduleName, idNodes.size()); + + for (IdentitySchemaNode idNode : idNodes) { + JSONObject identityObj = new JSONObject(); + String identityName = idNode.getQName().getLocalName(); + _logger.debug("Processing Identity: {}", identityName); + + identityObj.put(ID_KEY, identityName); + identityObj.put(DESCRIPTION_KEY, idNode.getDescription()); + + JSONObject props = new JSONObject(); + IdentitySchemaNode baseId = idNode.getBaseIdentity(); + + if (baseId == null) { + /** + * This is a base identity. So lets see if it has sub types. If it does, then add them to the model + * definition. + */ + Set derivedIds = idNode.getDerivedIdentities(); + + if (derivedIds != null) { + JSONArray subTypes = new JSONArray(); + for (IdentitySchemaNode derivedId : derivedIds) { + subTypes.put(derivedId.getQName().getLocalName()); + } + identityObj.put(SUB_TYPES_KEY, subTypes); + } + } else { + /** + * This is a derived entity. Add it's base type & move on. + */ + props.put(TYPE_KEY, baseId.getQName().getLocalName()); + } - if(baseId==null) { - /** - * This is a base identity. So lets see if - * it has sub types. If it does, then add them to the model definition. - */ - Set derivedIds = idNode.getDerivedIdentities(); - - if(derivedIds != null) { - JSONArray subTypes = new JSONArray(); - for(IdentitySchemaNode derivedId : derivedIds){ - subTypes.put(derivedId.getQName().getLocalName()); - } - identityObj.put(SUB_TYPES_KEY, subTypes); + // Add the properties. For a base type, this will be an empty object as required by the Swagger spec. + identityObj.put(PROPERTIES_KEY, props); + models.put(identityName, identityObj); } - } else { - /** - * This is a derived entity. Add it's base type & move on. - */ - props.put(TYPE_KEY, baseId.getQName().getLocalName()); - } - - //Add the properties. For a base type, this will be an empty object as required by the Swagger spec. - identityObj.put(PROPERTIES_KEY, props); - models.put(identityName, identityObj); } - } + /** * Processes the container node and populates the moduleJSON * @@ -251,14 +259,13 @@ public class ModelGenerator { * @throws JSONException * @throws IOException */ - private JSONObject processContainer(ContainerSchemaNode container, String moduleName, - boolean addSchemaStmt, JSONObject models) throws JSONException, IOException { - return processContainer(container, moduleName, addSchemaStmt, models, (Boolean) null); + private JSONObject processContainer(ContainerSchemaNode container, String moduleName, boolean addSchemaStmt, + JSONObject models, SchemaContext schemaContext) throws JSONException, IOException { + return processContainer(container, moduleName, addSchemaStmt, models, (Boolean) null, schemaContext); } - private JSONObject processContainer(ContainerSchemaNode container, String moduleName, - boolean addSchemaStmt, JSONObject models, Boolean isConfig) throws JSONException, - IOException { + private JSONObject processContainer(ContainerSchemaNode container, String moduleName, boolean addSchemaStmt, + JSONObject models, Boolean isConfig, SchemaContext schemaContext) throws JSONException, IOException { JSONObject moduleJSON = getSchemaTemplate(); if (addSchemaStmt) { moduleJSON = getSchemaTemplate(); @@ -270,57 +277,58 @@ public class ModelGenerator { String containerDescription = container.getDescription(); moduleJSON.put(DESCRIPTION_KEY, containerDescription); - JSONObject properties = processChildren(container.getChildNodes(), moduleName, models, isConfig); + JSONObject properties = processChildren(container.getChildNodes(), container.getQName(), moduleName, models, + isConfig, schemaContext); moduleJSON.put(PROPERTIES_KEY, properties); return moduleJSON; } - private JSONObject processChildren(Iterable nodes, String moduleName, - JSONObject models) throws JSONException, IOException { - return processChildren(nodes, moduleName, models, null); + private JSONObject processChildren(Iterable nodes, QName parentQName, String moduleName, + JSONObject models, SchemaContext schemaContext) throws JSONException, IOException { + return processChildren(nodes, parentQName, moduleName, models, null, schemaContext); } /** * Processes the nodes * * @param nodes + * @param parentQName * @param moduleName * @param isConfig * @return * @throws JSONException * @throws IOException */ - private JSONObject processChildren(Iterable nodes, String moduleName, - JSONObject models, Boolean isConfig) throws JSONException, IOException { + private JSONObject processChildren(Iterable nodes, QName parentQName, String moduleName, + JSONObject models, Boolean isConfig, SchemaContext schemaContext) throws JSONException, IOException { JSONObject properties = new JSONObject(); for (DataSchemaNode node : nodes) { if (isConfig == null || node.isConfiguration() == isConfig) { - String name = node.getQName().getLocalName(); + String name = resolveNodesName(node, topLevelModule, schemaContext); JSONObject property = null; if (node instanceof LeafSchemaNode) { property = processLeafNode((LeafSchemaNode) node); } else if (node instanceof ListSchemaNode) { - property = processListSchemaNode((ListSchemaNode) node, moduleName, models, isConfig); + property = processListSchemaNode((ListSchemaNode) node, moduleName, models, isConfig, schemaContext); } else if (node instanceof LeafListSchemaNode) { property = processLeafListNode((LeafListSchemaNode) node); } else if (node instanceof ChoiceNode) { - property = processChoiceNode((ChoiceNode) node, moduleName, models); + property = processChoiceNode((ChoiceNode) node, moduleName, models, schemaContext); } else if (node instanceof AnyXmlSchemaNode) { property = processAnyXMLNode((AnyXmlSchemaNode) node); } else if (node instanceof ContainerSchemaNode) { - property = processContainer((ContainerSchemaNode) node, moduleName, false, - models, isConfig); + property = processContainer((ContainerSchemaNode) node, moduleName, false, models, isConfig, + schemaContext); } else { - throw new IllegalArgumentException("Unknown DataSchemaNode type: " - + node.getClass()); + throw new IllegalArgumentException("Unknown DataSchemaNode type: " + node.getClass()); } property.putOpt(DESCRIPTION_KEY, node.getDescription()); @@ -356,15 +364,16 @@ public class ModelGenerator { * @throws JSONException * @throws IOException */ - private JSONObject processChoiceNode(ChoiceNode choiceNode, String moduleName, JSONObject models) - throws JSONException, IOException { + private JSONObject processChoiceNode(ChoiceNode choiceNode, String moduleName, JSONObject models, + SchemaContext schemaContext) throws JSONException, IOException { Set cases = choiceNode.getCases(); JSONArray choiceProps = new JSONArray(); for (ChoiceCaseNode choiceCase : cases) { String choiceName = choiceCase.getQName().getLocalName(); - JSONObject choiceProp = processChildren(choiceCase.getChildNodes(), moduleName, models); + JSONObject choiceProp = processChildren(choiceCase.getChildNodes(), choiceCase.getQName(), moduleName, + models, schemaContext); JSONObject choiceObj = new JSONObject(); choiceObj.put(choiceName, choiceProp); choiceObj.put(TYPE_KEY, OBJECT_TYPE); @@ -384,8 +393,7 @@ public class ModelGenerator { * @param props * @throws JSONException */ - private void processConstraints(ConstraintDefinition constraints, JSONObject props) - throws JSONException { + private void processConstraints(ConstraintDefinition constraints, JSONObject props) throws JSONException { boolean isMandatory = constraints.isMandatory(); props.put(REQUIRED_KEY, isMandatory); @@ -402,9 +410,8 @@ public class ModelGenerator { /** * Parses a ListSchema node. * - * Due to a limitation of the RAML--->JAX-RS tool, sub-properties must be in - * a separate JSON schema file. Hence, we have to write some properties to a - * new file, while continuing to process the rest. + * Due to a limitation of the RAML--->JAX-RS tool, sub-properties must be in a separate JSON schema file. Hence, we + * have to write some properties to a new file, while continuing to process the rest. * * @param listNode * @param moduleName @@ -413,21 +420,21 @@ public class ModelGenerator { * @throws JSONException * @throws IOException */ - private JSONObject processListSchemaNode(ListSchemaNode listNode, String moduleName, - JSONObject models, Boolean isConfig) throws JSONException, IOException { + private JSONObject processListSchemaNode(ListSchemaNode listNode, String moduleName, JSONObject models, + Boolean isConfig, SchemaContext schemaContext) throws JSONException, IOException { - String fileName = (BooleanUtils.isNotFalse(isConfig)?OperationBuilder.CONFIG:OperationBuilder.OPERATIONAL) + - listNode.getQName().getLocalName(); + String fileName = (BooleanUtils.isNotFalse(isConfig) ? OperationBuilder.CONFIG : OperationBuilder.OPERATIONAL) + + listNode.getQName().getLocalName(); - JSONObject childSchemaProperties = processChildren(listNode.getChildNodes(), moduleName, models); + JSONObject childSchemaProperties = processChildren(listNode.getChildNodes(), listNode.getQName(), moduleName, + models, schemaContext); JSONObject childSchema = getSchemaTemplate(); childSchema.put(TYPE_KEY, OBJECT_TYPE); childSchema.put(PROPERTIES_KEY, childSchemaProperties); /* - * Due to a limitation of the RAML--->JAX-RS tool, sub-properties must - * be in a separate JSON schema file. Hence, we have to write some - * properties to a new file, while continuing to process the rest. + * Due to a limitation of the RAML--->JAX-RS tool, sub-properties must be in a separate JSON schema file. Hence, + * we have to write some properties to a new file, while continuing to process the rest. */ // writeToFile(fileName, childSchema.toString(2), moduleName); childSchema.put("id", fileName); @@ -483,8 +490,7 @@ public class ModelGenerator { * @param property * @throws JSONException */ - private void processTypeDef(TypeDefinition leafTypeDef, JSONObject property) - throws JSONException { + private void processTypeDef(TypeDefinition leafTypeDef, JSONObject property) throws JSONException { if (leafTypeDef instanceof ExtendedType) { processExtendedType(leafTypeDef, property); @@ -498,7 +504,7 @@ public class ModelGenerator { processUnionType((UnionTypeDefinition) leafTypeDef, property); } else if (leafTypeDef instanceof IdentityrefTypeDefinition) { - property.putOpt(TYPE_KEY, ((IdentityrefTypeDefinition) leafTypeDef).getIdentity().getQName().getLocalName()); + property.putOpt(TYPE_KEY, ((IdentityrefTypeDefinition) leafTypeDef).getIdentity().getQName().getLocalName()); } else if (leafTypeDef instanceof BinaryTypeDefinition) { processBinaryType((BinaryTypeDefinition) leafTypeDef, property); } else { @@ -517,15 +523,13 @@ public class ModelGenerator { * @param property * @throws JSONException */ - private void processExtendedType(TypeDefinition leafTypeDef, JSONObject property) - throws JSONException { + private void processExtendedType(TypeDefinition leafTypeDef, JSONObject property) throws JSONException { Object leafBaseType = leafTypeDef.getBaseType(); if (leafBaseType instanceof ExtendedType) { // recursively process an extended type until we hit a base type processExtendedType((TypeDefinition) leafBaseType, property); } else { - List lengthConstraints = ((ExtendedType) leafTypeDef) - .getLengthConstraints(); + List lengthConstraints = ((ExtendedType) leafTypeDef).getLengthConstraints(); for (LengthConstraint lengthConstraint : lengthConstraints) { Number min = lengthConstraint.getMin(); Number max = lengthConstraint.getMax(); @@ -541,8 +545,7 @@ public class ModelGenerator { /* * */ - private void processBinaryType(BinaryTypeDefinition binaryType, JSONObject property) - throws JSONException { + private void processBinaryType(BinaryTypeDefinition binaryType, JSONObject property) throws JSONException { property.put(TYPE_KEY, STRING); JSONObject media = new JSONObject(); media.put(BINARY_ENCODING_KEY, BASE_64); @@ -555,8 +558,7 @@ public class ModelGenerator { * @param property * @throws JSONException */ - private void processEnumType(EnumerationType enumLeafType, JSONObject property) - throws JSONException { + private void processEnumType(EnumerationType enumLeafType, JSONObject property) throws JSONException { List enumPairs = enumLeafType.getValues(); List enumNames = new ArrayList(); for (EnumPair enumPair : enumPairs) { @@ -571,8 +573,7 @@ public class ModelGenerator { * @param property * @throws JSONException */ - private void processBitsType(BitsTypeDefinition bitsType, JSONObject property) - throws JSONException { + private void processBitsType(BitsTypeDefinition bitsType, JSONObject property) throws JSONException { property.put(TYPE_KEY, ARRAY_TYPE); property.put(MIN_ITEMS, 0); property.put(UNIQUE_ITEMS_KEY, true); @@ -593,18 +594,17 @@ public class ModelGenerator { * @param property * @throws JSONException */ - private void processUnionType(UnionTypeDefinition unionType, JSONObject property) - throws JSONException { + private void processUnionType(UnionTypeDefinition unionType, JSONObject property) throws JSONException { StringBuilder type = new StringBuilder(); - for (TypeDefinition typeDef : unionType.getTypes() ) { - if( type.length() > 0 ){ - type.append( " or " ); + for (TypeDefinition typeDef : unionType.getTypes()) { + if (type.length() > 0) { + type.append(" or "); } type.append(YANG_TYPE_TO_JSON_TYPE_MAPPING.get(typeDef.getClass())); } - property.put(TYPE_KEY, type ); + property.put(TYPE_KEY, type); } /** @@ -619,4 +619,5 @@ public class ModelGenerator { return schemaJSON; } + } diff --git a/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/mountpoints/MountPointSwagger.java b/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/mountpoints/MountPointSwagger.java index 29ada12c6f..7e8707110f 100644 --- a/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/mountpoints/MountPointSwagger.java +++ b/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/mountpoints/MountPointSwagger.java @@ -17,9 +17,7 @@ import java.util.Map.Entry; 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.sal.core.api.model.SchemaService; import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance; import org.opendaylight.controller.sal.core.api.mount.MountProvisionService; diff --git a/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/util/RestDocgenUtil.java b/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/util/RestDocgenUtil.java new file mode 100644 index 0000000000..9e1d82ae05 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-docgen/src/main/java/org/opendaylight/controller/sal/rest/doc/util/RestDocgenUtil.java @@ -0,0 +1,90 @@ +/* + * 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.controller.sal.rest.doc.util; + +import java.net.URI; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.api.SchemaNode; + +public class RestDocgenUtil { + + private RestDocgenUtil() { + } + + private static Map> namespaceAndRevisionToModule = new HashMap>(); + + /** + * Resolve path argument name for {@code node}. + * + * The name can contain also prefix which consists of module name followed by colon. The module prefix is presented + * if namespace of {@code node} and its parent is different. In other cases only name of {@code node} is returned. + * + * @return name of {@code node} + */ + public static String resolvePathArgumentsName(final SchemaNode node, final SchemaContext schemaContext) { + Iterable schemaPath = node.getPath().getPathTowardsRoot(); + Iterator it = schemaPath.iterator(); + QName nodeQName = it.next(); + + QName parentQName = null; + if (it.hasNext()) { + parentQName = it.next(); + } + if (isEqualNamespaceAndRevision(parentQName, nodeQName)) { + return node.getQName().getLocalName(); + } else { + return resolveFullNameFromNode(node, schemaContext); + } + } + + private synchronized static String resolveFullNameFromNode(final SchemaNode node, final SchemaContext schemaContext) { + final URI namespace = node.getQName().getNamespace(); + final Date revision = node.getQName().getRevision(); + + Map revisionToModule = namespaceAndRevisionToModule.get(namespace); + if (revisionToModule == null) { + revisionToModule = new HashMap<>(); + namespaceAndRevisionToModule.put(namespace, revisionToModule); + } + Module module = revisionToModule.get(revision); + if (module == null) { + module = schemaContext.findModuleByNamespaceAndRevision(namespace, revision); + revisionToModule.put(revision, module); + } + if (module != null) { + return module.getName() + ":" + node.getQName().getLocalName(); + } + return node.getQName().getLocalName(); + } + + public static String resolveNodesName(final SchemaNode node, final Module module, final SchemaContext schemaContext) { + if (node.getQName().getNamespace().equals(module.getQNameModule().getNamespace()) + && node.getQName().getRevision().equals(module.getQNameModule().getRevision())) { + return node.getQName().getLocalName(); + } else { + return resolveFullNameFromNode(node, schemaContext); + } + } + + private static boolean isEqualNamespaceAndRevision(QName parentQName, QName nodeQName) { + if (parentQName == null) { + if (nodeQName == null) { + return true; + } + return false; + } + return parentQName.getNamespace().equals(nodeQName.getNamespace()) + && parentQName.getRevision().equals(nodeQName.getRevision()); + } +} diff --git a/opendaylight/md-sal/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocGeneratorTest.java b/opendaylight/md-sal/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocGeneratorTest.java index 07c9378439..19f82b5386 100644 --- a/opendaylight/md-sal/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocGeneratorTest.java +++ b/opendaylight/md-sal/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocGeneratorTest.java @@ -5,16 +5,17 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.common.base.Preconditions; import java.io.File; import java.util.Arrays; +import java.util.HashSet; import java.util.Map.Entry; import java.util.Set; import java.util.TreeSet; - import javax.ws.rs.core.UriInfo; - import junit.framework.Assert; - +import org.json.JSONException; +import org.json.JSONObject; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -25,8 +26,8 @@ import org.opendaylight.controller.sal.rest.doc.swagger.Operation; import org.opendaylight.controller.sal.rest.doc.swagger.Resource; import org.opendaylight.controller.sal.rest.doc.swagger.ResourceList; import org.opendaylight.yangtools.yang.model.api.Module; - -import com.google.common.base.Preconditions; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; /** * @@ -36,12 +37,14 @@ public class ApiDocGeneratorTest { public static final String HTTP_HOST = "http://host"; private ApiDocGenerator generator; private DocGenTestHelper helper; + private SchemaContext schemaContext; @Before public void setUp() throws Exception { generator = new ApiDocGenerator(); helper = new DocGenTestHelper(); helper.setUp(); + schemaContext = new YangParserImpl().resolveSchemaContext(new HashSet(helper.getModules().values())); } @After @@ -59,8 +62,9 @@ public class ApiDocGeneratorTest { for (Entry m : helper.getModules().entrySet()) { if (m.getKey().getAbsolutePath().endsWith("toaster_short.yang")) { ApiDeclaration doc = generator.getSwaggerDocSpec(m.getValue(), - "http://localhost:8080/restconf", ""); + "http://localhost:8080/restconf", "",schemaContext); validateToaster(doc); + validateTosterDocContainsModulePrefixes(doc); Assert.assertNotNull(doc); } } @@ -73,7 +77,7 @@ public class ApiDocGeneratorTest { for (Entry m : helper.getModules().entrySet()) { if (m.getKey().getAbsolutePath().endsWith("toaster.yang")) { ApiDeclaration doc = generator.getSwaggerDocSpec(m.getValue(), - "http://localhost:8080/restconf", ""); + "http://localhost:8080/restconf", "",schemaContext); Assert.assertNotNull(doc); //testing bugs.opendaylight.org bug 1290. UnionType model type. @@ -84,11 +88,21 @@ public class ApiDocGeneratorTest { } } + /** + * Tests whether from yang files are generated all required paths for HTTP operations (GET, DELETE, PUT, POST) + * + * If container | list is augmented then in path there should be specified module name followed with collon (e. g. + * "/config/module1:element1/element2/module2:element3") + * + * @param doc + * @throws Exception + */ private void validateToaster(ApiDeclaration doc) throws Exception { Set 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" })); + "/operations/toaster2:restock-toaster", + "/config/toaster2:toaster/toasterSlot/{slotId}/toaster-augmented:slotInfo/" })); Set actualUrls = new TreeSet<>(); @@ -130,7 +144,7 @@ public class ApiDocGeneratorTest { @Test public void testGetResourceListing() throws Exception { UriInfo info = helper.createMockUriInfo(HTTP_HOST); - SchemaService mockSchemaService = helper.createMockSchemaService(); + SchemaService mockSchemaService = helper.createMockSchemaService(schemaContext); generator.setSchemaService(mockSchemaService); @@ -154,4 +168,30 @@ public class ApiDocGeneratorTest { assertEquals(HTTP_HOST + "/toaster2(2009-11-20)", toaster2.getPath()); } + private void validateTosterDocContainsModulePrefixes(ApiDeclaration doc) { + JSONObject topLevelJson = doc.getModels(); + try { + JSONObject configToaster = topLevelJson.getJSONObject("(config)toaster"); + assertNotNull("(config)toaster JSON object missing", configToaster); + //without module prefix + containsProperties(configToaster, "toasterSlot"); + + JSONObject toasterSlot = topLevelJson.getJSONObject("(config)toasterSlot"); + assertNotNull("(config)toasterSlot JSON object missing", toasterSlot); + //with module prefix + containsProperties(toasterSlot, "toaster-augmented:slotInfo"); + + } catch (JSONException e) { + fail("Json exception while reading JSON object. Original message "+e.getMessage()); + } + } + + private void containsProperties(final JSONObject jsonObject,final String...properties) throws JSONException { + for (String property : properties) { + JSONObject propertiesObject = jsonObject.getJSONObject("properties"); + assertNotNull("Properties object missing in ", propertiesObject); + JSONObject concretePropertyObject = propertiesObject.getJSONObject(property); + assertNotNull(property + " is missing",concretePropertyObject); + } + } } diff --git a/opendaylight/md-sal/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/DocGenTestHelper.java b/opendaylight/md-sal/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/DocGenTestHelper.java index 0f15d00e79..7701d2a735 100644 --- a/opendaylight/md-sal/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/DocGenTestHelper.java +++ b/opendaylight/md-sal/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/DocGenTestHelper.java @@ -10,6 +10,9 @@ package org.opendaylight.controller.sal.rest.doc.impl; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule; import java.io.File; import java.io.FileNotFoundException; import java.net.URI; @@ -19,23 +22,17 @@ import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Map; - import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo; - import org.mockito.ArgumentCaptor; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.opendaylight.controller.sal.core.api.model.SchemaService; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.model.parser.api.YangModelParser; +import org.opendaylight.yangtools.yang.model.parser.api.YangContextParser; import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.datatype.jsonorg.JsonOrgModule; - public class DocGenTestHelper { private Map modules; @@ -45,7 +42,7 @@ public class DocGenTestHelper { URISyntaxException { URI resourceDirUri = getClass().getResource(resourceDirectory).toURI(); - final YangModelParser parser = new YangParserImpl(); + final YangContextParser parser = new YangParserImpl(); final File testDir = new File(resourceDirUri); final String[] fileList = testDir.list(); final List testFiles = new ArrayList<>(); @@ -90,6 +87,7 @@ public class DocGenTestHelper { final ArgumentCaptor moduleCapture = ArgumentCaptor.forClass(String.class); final ArgumentCaptor dateCapture = ArgumentCaptor.forClass(Date.class); + final ArgumentCaptor namespaceCapture = ArgumentCaptor.forClass(URI.class); when(mockContext.findModuleByName(moduleCapture.capture(), dateCapture.capture())).then( new Answer() { @Override @@ -104,6 +102,20 @@ public class DocGenTestHelper { return null; } }); + when(mockContext.findModuleByNamespaceAndRevision(namespaceCapture.capture(), dateCapture.capture())).then( + new Answer() { + @Override + public Module answer(InvocationOnMock invocation) throws Throwable { + URI namespace = namespaceCapture.getValue(); + Date date = dateCapture.getValue(); + for (Module m : modules.values()) { + if (m.getNamespace().equals(namespace) && m.getRevision().equals(date)) { + return m; + } + } + return null; + } + }); return mockContext; } diff --git a/opendaylight/md-sal/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/MountPointSwaggerTest.java b/opendaylight/md-sal/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/MountPointSwaggerTest.java index bba8ed9ca6..940b99fd99 100644 --- a/opendaylight/md-sal/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/MountPointSwaggerTest.java +++ b/opendaylight/md-sal/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/MountPointSwaggerTest.java @@ -14,12 +14,11 @@ import static org.mockito.Mockito.when; import java.net.URISyntaxException; import java.util.Arrays; +import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.TreeSet; - import javax.ws.rs.core.UriInfo; - import org.junit.Before; import org.junit.Test; import org.opendaylight.controller.sal.core.api.model.SchemaService; @@ -33,7 +32,9 @@ import org.opendaylight.controller.sal.rest.doc.swagger.Resource; import org.opendaylight.controller.sal.rest.doc.swagger.ResourceList; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; public class MountPointSwaggerTest { @@ -44,12 +45,14 @@ public class MountPointSwaggerTest { private static final String INSTANCE_URL = "nodes/node/123/"; private MountPointSwagger swagger; private DocGenTestHelper helper; + private SchemaContext schemaContext; @Before public void setUp() throws Exception { swagger = new MountPointSwagger(); helper = new DocGenTestHelper(); helper.setUp(); + schemaContext = new YangParserImpl().resolveSchemaContext(new HashSet(helper.getModules().values())); } @Test() diff --git a/opendaylight/md-sal/sal-rest-docgen/src/test/resources/yang/toaster_augmented.yang b/opendaylight/md-sal/sal-rest-docgen/src/test/resources/yang/toaster_augmented.yang new file mode 100644 index 0000000000..4db7897a99 --- /dev/null +++ b/opendaylight/md-sal/sal-rest-docgen/src/test/resources/yang/toaster_augmented.yang @@ -0,0 +1,21 @@ +module toaster-augmented { + + yang-version 1; + + namespace + "http://netconfcentral.org/ns/toaster/augmented"; + + prefix toast; + import toaster2 {prefix tst; revision-date 2009-11-20;} + + revision "2014-7-14" { + } + + augment "/tst:toaster/tst:toasterSlot" { + container slotInfo { + leaf numberOfToastPrepared { + type uint32; + } + } + } +} \ No newline at end of file diff --git a/opendaylight/md-sal/sal-rest-docgen/src/test/resources/yang/toaster_short.yang b/opendaylight/md-sal/sal-rest-docgen/src/test/resources/yang/toaster_short.yang index a1d5ab0a12..6884076d5d 100644 --- a/opendaylight/md-sal/sal-rest-docgen/src/test/resources/yang/toaster_short.yang +++ b/opendaylight/md-sal/sal-rest-docgen/src/test/resources/yang/toaster_short.yang @@ -83,6 +83,13 @@ Microsoft Toaster."; } + list toasterSlot { + key "slotId"; + leaf slotId { + type string; + } + } + leaf toasterModelNumber { type DisplayString; config false;