import java.io.IOException;
import java.math.BigDecimal;
import java.util.Collection;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
+import org.opendaylight.restconf.openapi.model.Schema;
import org.opendaylight.yangtools.yang.common.Decimal64;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.ActionDefinition;
private static final String MIN_ITEMS = "minItems";
private static final String MAX_LENGTH_KEY = "maxLength";
private static final String MIN_LENGTH_KEY = "minLength";
- private static final String REQUIRED_KEY = "required";
private static final String REF_KEY = "$ref";
private static final String ITEMS_KEY = "items";
private static final String TYPE_KEY = "type";
- private static final String PROPERTIES_KEY = "properties";
private static final String DESCRIPTION_KEY = "description";
private static final String ARRAY_TYPE = "array";
private static final String ENUM_KEY = "enum";
*/
- public ObjectNode convertToJsonSchema(final Module module, final EffectiveModelContext schemaContext,
- final ObjectNode definitions, final DefinitionNames definitionNames, final boolean isForSingleModule)
- throws IOException {
+ public Map<String, Schema> convertToJsonSchema(final Module module, final EffectiveModelContext schemaContext,
+ final Map<String, Schema> definitions, final DefinitionNames definitionNames,
+ final boolean isForSingleModule) throws IOException {
topLevelModule = module;
processIdentities(module, definitions, definitionNames, schemaContext);
return definitions;
}
- public ObjectNode convertToJsonSchema(final Module module, final EffectiveModelContext schemaContext,
+ public Map<String, Schema> convertToJsonSchema(final Module module, final EffectiveModelContext schemaContext,
final DefinitionNames definitionNames, final boolean isForSingleModule)
throws IOException {
- final ObjectNode definitions = JsonNodeFactory.instance.objectNode();
+ final Map<String, Schema> definitions = new HashMap<>();
if (isForSingleModule) {
definitionNames.addUnlinkedName(module.getName() + MODULE_NAME_SUFFIX);
}
return convertToJsonSchema(module, schemaContext, definitions, definitionNames, isForSingleModule);
}
- private void processModule(final Module module, final ObjectNode definitions, final DefinitionNames definitionNames,
- final EffectiveModelContext schemaContext) {
- final ObjectNode definition = JsonNodeFactory.instance.objectNode();
+ private void processModule(final Module module, final Map<String, Schema> definitions,
+ final DefinitionNames definitionNames, final EffectiveModelContext schemaContext) {
+ final Schema definition = new Schema();
final ObjectNode properties = JsonNodeFactory.instance.objectNode();
final ArrayNode required = JsonNodeFactory.instance.arrayNode();
final String moduleName = module.getName();
}
stack.exit();
}
- definition.put(TITLE_KEY, definitionName);
- definition.put(TYPE_KEY, OBJECT_TYPE);
- definition.set(PROPERTIES_KEY, properties);
- definition.put(DESCRIPTION_KEY, module.getDescription().orElse(""));
+ definition.setTitle(definitionName);
+ definition.setType(OBJECT_TYPE);
+ definition.setProperties(properties);
+ definition.setDescription(module.getDescription().orElse(""));
setRequiredIfNotEmpty(definition, required);
- definitions.set(definitionName, definition);
+ definitions.put(definitionName, definition);
}
- private void processContainersAndLists(final Module module, final ObjectNode definitions,
+ private void processContainersAndLists(final Module module, final Map<String, Schema> definitions,
final DefinitionNames definitionNames, final EffectiveModelContext schemaContext) throws IOException {
final String moduleName = module.getName();
final SchemaInferenceStack stack = SchemaInferenceStack.of(schemaContext);
}
private void processActionNodeContainer(final DataSchemaNode childNode, final String moduleName,
- final ObjectNode definitions, final DefinitionNames definitionNames, final SchemaInferenceStack stack)
- throws IOException {
+ final Map<String, Schema> definitions, final DefinitionNames definitionNames,
+ final SchemaInferenceStack stack) throws IOException {
for (final ActionDefinition actionDef : ((ActionNodeContainer) childNode).getActions()) {
stack.enterSchemaTree(actionDef.getQName());
processOperations(actionDef, moduleName, definitions, definitionNames, stack);
}
}
- private void processRPCs(final Module module, final ObjectNode definitions, final DefinitionNames definitionNames,
- final EffectiveModelContext schemaContext) throws IOException {
+ private void processRPCs(final Module module, final Map<String, Schema> definitions,
+ final DefinitionNames definitionNames, final EffectiveModelContext schemaContext) throws IOException {
final String moduleName = module.getName();
final SchemaInferenceStack stack = SchemaInferenceStack.of(schemaContext);
for (final RpcDefinition rpcDefinition : module.getRpcs()) {
}
private void processOperations(final OperationDefinition operationDef, final String parentName,
- final ObjectNode definitions, final DefinitionNames definitionNames, final SchemaInferenceStack stack)
- throws IOException {
+ final Map<String, Schema> definitions, final DefinitionNames definitionNames,
+ final SchemaInferenceStack stack) throws IOException {
final String operationName = operationDef.getQName().getLocalName();
processOperationInputOutput(operationDef.getInput(), operationName, parentName, true, definitions,
definitionNames, stack);
}
private void processOperationInputOutput(final ContainerLike container, final String operationName,
- final String parentName, final boolean isInput, final ObjectNode definitions,
+ final String parentName, final boolean isInput, final Map<String, Schema> definitions,
final DefinitionNames definitionNames, final SchemaInferenceStack stack)
throws IOException {
stack.enterSchemaTree(container.getQName());
if (!container.getChildNodes().isEmpty()) {
final String filename = parentName + "_" + operationName + (isInput ? INPUT_SUFFIX : OUTPUT_SUFFIX);
- final ObjectNode childSchema = JsonNodeFactory.instance.objectNode();
+ final Schema childSchema = new Schema();
processChildren(childSchema, container.getChildNodes(), parentName, definitions, definitionNames,
false, stack);
- childSchema.put(TYPE_KEY, OBJECT_TYPE);
+ childSchema.setType(OBJECT_TYPE);
final ObjectNode xml = JsonNodeFactory.instance.objectNode();
xml.put(NAME_KEY, isInput ? INPUT : OUTPUT);
- childSchema.set(XML_KEY, xml);
- childSchema.put(TITLE_KEY, filename);
+ childSchema.setXml(xml);
+ childSchema.setTitle(filename);
final String discriminator =
definitionNames.pickDiscriminator(container, List.of(filename, filename + TOP));
- definitions.set(filename + discriminator, childSchema);
+ definitions.put(filename + discriminator, childSchema);
processTopData(filename, discriminator, definitions, container);
}
}
private static ObjectNode processTopData(final String filename, final String discriminator,
- final ObjectNode definitions, final SchemaNode schemaNode) {
+ final Map<String, Schema> definitions, final SchemaNode schemaNode) {
final ObjectNode dataNodeProperties = JsonNodeFactory.instance.objectNode();
final String name = filename + discriminator;
final String ref = COMPONENTS_PREFIX + name;
use RestDocGenUtil#resolveNodesName for creating property name
*/
properties.set(schemaNode.getQName().getLocalName(), dataNodeProperties);
- final ObjectNode finalChildSchema = JsonNodeFactory.instance.objectNode();
- finalChildSchema.put(TYPE_KEY, OBJECT_TYPE);
- finalChildSchema.set(PROPERTIES_KEY, properties);
- finalChildSchema.put(TITLE_KEY, topName);
+ final Schema finalChildSchema = new Schema();
+ finalChildSchema.setType(OBJECT_TYPE);
+ finalChildSchema.setProperties(properties);
+ finalChildSchema.setTitle(topName);
- definitions.set(topName + discriminator, finalChildSchema);
+ definitions.put(topName + discriminator, finalChildSchema);
return dataNodeProperties;
}
* @param definitions The ObjectNode in which the parsed identity will be put as a 'model' obj
* @param definitionNames Store for definition names
*/
- private static void processIdentities(final Module module, final ObjectNode definitions,
+ private static void processIdentities(final Module module, final Map<String, Schema> definitions,
final DefinitionNames definitionNames, final EffectiveModelContext context) {
final String moduleName = module.getName();
final Collection<? extends IdentitySchemaNode> idNodes = module.getIdentities();
LOG.debug("Processing Identities for module {} . Found {} identity statements", moduleName, idNodes.size());
for (final IdentitySchemaNode idNode : idNodes) {
- final ObjectNode identityObj = buildIdentityObject(idNode, context);
+ final Schema identityObj = buildIdentityObject(idNode, context);
final String idName = idNode.getQName().getLocalName();
final String discriminator = definitionNames.pickDiscriminator(idNode, List.of(idName));
final String name = idName + discriminator;
- definitions.set(name, identityObj);
+ definitions.put(name, identityObj);
}
}
}
private ObjectNode processDataNodeContainer(final DataNodeContainer dataNode, final String parentName,
- final ObjectNode definitions, final DefinitionNames definitionNames, final boolean isConfig,
+ final Map<String, Schema> definitions, final DefinitionNames definitionNames, final boolean isConfig,
final SchemaInferenceStack stack) throws IOException {
if (dataNode instanceof ListSchemaNode || dataNode instanceof ContainerSchemaNode) {
final Collection<? extends DataSchemaNode> containerChildren = dataNode.getChildNodes();
final SchemaNode schemaNode = (SchemaNode) dataNode;
final String localName = schemaNode.getQName().getLocalName();
- final ObjectNode childSchema = JsonNodeFactory.instance.objectNode();
+ final Schema childSchema = new Schema();
final String nameAsParent = parentName + "_" + localName;
final ObjectNode properties =
processChildren(childSchema, containerChildren, parentName + "_" + localName, definitions,
}
if (isConfig) {
- final ObjectNode postSchema = createPostJsonSchema(schemaNode, properties, postNodeName, description);
+ final Schema postSchema = createPostJsonSchema(schemaNode, properties, postNodeName, description);
String truePostNodeName = postNodeName + discriminator;
- definitions.set(truePostNodeName, postSchema);
+ definitions.put(truePostNodeName, postSchema);
- final ObjectNode postXmlSchema = JsonNodeFactory.instance.objectNode();
- postXmlSchema.put(REF_KEY, COMPONENTS_PREFIX + truePostNodeName);
- definitions.set(postXmlNodeName + discriminator, postXmlSchema);
+ final Schema postXmlSchema = new Schema();
+ postXmlSchema.setRef(COMPONENTS_PREFIX + truePostNodeName);
+ definitions.put(postXmlNodeName + discriminator, postXmlSchema);
}
- childSchema.put(TYPE_KEY, OBJECT_TYPE);
- childSchema.set(PROPERTIES_KEY, properties);
- childSchema.put(TITLE_KEY, nodeName);
- childSchema.put(DESCRIPTION_KEY, description);
+ childSchema.setType(OBJECT_TYPE);
+ childSchema.setProperties(properties);
+ childSchema.setTitle(nodeName);
+ childSchema.setDescription(description);
final String defName = nodeName + discriminator;
- childSchema.set(XML_KEY, buildXmlParameter(schemaNode));
- definitions.set(defName, childSchema);
+ childSchema.setXml(buildXmlParameter(schemaNode));
+ definitions.put(defName, childSchema);
return processTopData(nodeName, discriminator, definitions, schemaNode);
}
return null;
}
- private static ObjectNode createPostJsonSchema(final SchemaNode dataNode, final ObjectNode properties,
+ private static Schema createPostJsonSchema(final SchemaNode dataNode, final ObjectNode properties,
final String postNodeName, final String description) {
- final ObjectNode postSchema = JsonNodeFactory.instance.objectNode();
+ final Schema postSchema = new Schema();
final ObjectNode postItemProperties;
if (dataNode instanceof ListSchemaNode) {
postItemProperties = createListItemProperties(properties, (ListSchemaNode) dataNode);
} else {
postItemProperties = properties.deepCopy();
}
- postSchema.put(TYPE_KEY, OBJECT_TYPE);
- postSchema.set(PROPERTIES_KEY, postItemProperties);
- postSchema.put(TITLE_KEY, postNodeName);
- postSchema.put(DESCRIPTION_KEY, description);
- postSchema.set(XML_KEY, buildXmlParameter(dataNode));
+ postSchema.setType(OBJECT_TYPE);
+ postSchema.setProperties(postItemProperties);
+ postSchema.setTitle(postNodeName);
+ postSchema.setDescription(description);
+ postSchema.setXml(buildXmlParameter(dataNode));
return postSchema;
}
/**
* Processes the nodes.
*/
- private ObjectNode processChildren(final ObjectNode parentNode, final Collection<? extends DataSchemaNode> nodes,
- final String parentName, final ObjectNode definitions, final DefinitionNames definitionNames,
+ private ObjectNode processChildren(final Schema parentNode, final Collection<? extends DataSchemaNode> nodes,
+ final String parentName, final Map<String, Schema> definitions, final DefinitionNames definitionNames,
final boolean isConfig, final SchemaInferenceStack stack) throws IOException {
final ObjectNode properties = JsonNodeFactory.instance.objectNode();
final ArrayNode required = JsonNodeFactory.instance.arrayNode();
processChildNode(node, parentName, definitions, definitionNames, isConfig, stack, properties);
}
}
- parentNode.set(PROPERTIES_KEY, properties);
+ parentNode.setProperties(properties);
setRequiredIfNotEmpty(parentNode, required);
return properties;
}
- private void processChildNode(final DataSchemaNode node, final String parentName, final ObjectNode definitions,
- final DefinitionNames definitionNames, final boolean isConfig, final SchemaInferenceStack stack,
- final ObjectNode properties) throws IOException {
+ private void processChildNode(final DataSchemaNode node, final String parentName,
+ final Map<String, Schema> definitions, final DefinitionNames definitionNames, final boolean isConfig,
+ final SchemaInferenceStack stack, final ObjectNode properties) throws IOException {
stack.enterSchemaTree(node.getQName());
}
private ObjectNode processLeafListNode(final LeafListSchemaNode listNode, final SchemaInferenceStack stack,
- final ObjectNode definitions, final DefinitionNames definitionNames) {
+ final Map<String, Schema> definitions, final DefinitionNames definitionNames) {
final ObjectNode props = JsonNodeFactory.instance.objectNode();
props.put(TYPE_KEY, ARRAY_TYPE);
private ObjectNode processLeafNode(final LeafSchemaNode leafNode, final String jsonLeafName,
final ObjectNode properties, final ArrayNode required, final SchemaInferenceStack stack,
- final ObjectNode definitions, final DefinitionNames definitionNames) {
+ final Map<String, Schema> definitions, final DefinitionNames definitionNames) {
final ObjectNode property = JsonNodeFactory.instance.objectNode();
final String leafDescription = leafNode.getDescription().orElse("");
}
private String processTypeDef(final TypeDefinition<?> leafTypeDef, final DataSchemaNode node,
- final ObjectNode property, final SchemaInferenceStack stack, final ObjectNode definitions,
+ final ObjectNode property, final SchemaInferenceStack stack, final Map<String, Schema> definitions,
final DefinitionNames definitionNames) {
final String jsonType;
if (leafTypeDef instanceof BinaryTypeDefinition) {
}
private String processIdentityRefType(final IdentityrefTypeDefinition leafTypeDef, final ObjectNode property,
- final ObjectNode definitions, final DefinitionNames definitionNames,
+ final Map<String, Schema> definitions, final DefinitionNames definitionNames,
final EffectiveModelContext schemaContext) {
final String definitionName;
if (isImported(leafTypeDef)) {
}
private static String addImportedIdentity(final IdentityrefTypeDefinition leafTypeDef,
- final ObjectNode definitions, final DefinitionNames definitionNames, final EffectiveModelContext context) {
+ final Map<String, Schema> definitions, final DefinitionNames definitionNames,
+ final EffectiveModelContext context) {
final IdentitySchemaNode idNode = leafTypeDef.getIdentities().iterator().next();
final String identityName = idNode.getQName().getLocalName();
if (!definitionNames.isListedNode(idNode)) {
- final ObjectNode identityObj = buildIdentityObject(idNode, context);
+ final Schema identityObj = buildIdentityObject(idNode, context);
final String discriminator = definitionNames.pickDiscriminator(idNode, List.of(identityName));
final String name = identityName + discriminator;
- definitions.set(name, identityObj);
+ definitions.put(name, identityObj);
return name;
} else {
return identityName + definitionNames.getDiscriminator(idNode);
}
}
- private static ObjectNode buildIdentityObject(final IdentitySchemaNode idNode,
+ private static Schema buildIdentityObject(final IdentitySchemaNode idNode,
final EffectiveModelContext context) {
- final ObjectNode identityObj = JsonNodeFactory.instance.objectNode();
+ final Schema identityObj = new Schema();
final String identityName = idNode.getQName().getLocalName();
LOG.debug("Processing Identity: {}", identityName);
- identityObj.put(TITLE_KEY, identityName);
- identityObj.put(DESCRIPTION_KEY, idNode.getDescription().orElse(""));
+ identityObj.setTitle(identityName);
+ identityObj.setDescription(idNode.getDescription().orElse(""));
final Collection<? extends IdentitySchemaNode> derivedIds = context.getDerivedIdentities(idNode);
final ArrayNode enumPayload = JsonNodeFactory.instance.arrayNode();
enumPayload.add(identityName);
populateEnumWithDerived(derivedIds, enumPayload, context);
- identityObj.set(ENUM_KEY, enumPayload);
- identityObj.put(TYPE_KEY, STRING_TYPE);
+ identityObj.setEnum(enumPayload);
+ identityObj.setType(STRING_TYPE);
return identityObj;
}
}
}
- private static void setRequiredIfNotEmpty(final ObjectNode node, final ArrayNode required) {
+ private static void setRequiredIfNotEmpty(final Schema node, final ArrayNode required) {
if (required.size() > 0) {
- node.set(REQUIRED_KEY, required);
+ node.setRequired(required);
}
}
import static org.junit.Assert.assertTrue;
import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.junit.Test;
import org.opendaylight.restconf.openapi.AbstractOpenApiTest;
import org.opendaylight.restconf.openapi.DocGenTestHelper;
import org.opendaylight.restconf.openapi.model.OpenApiObject;
import org.opendaylight.restconf.openapi.model.Path;
+import org.opendaylight.restconf.openapi.model.Schema;
import org.opendaylight.yangtools.yang.common.Revision;
public final class OpenApiGeneratorRFC8040Test extends AbstractOpenApiTest {
private static final String NAME_2 = "toaster";
private static final String REVISION_DATE_2 = "2009-11-20";
private static final String CHOICE_TEST_MODULE = "choice-test";
- private static final String PROPERTIES = "properties";
+
private final OpenApiGeneratorRFC8040 generator = new OpenApiGeneratorRFC8040(SCHEMA_SERVICE);
/**
final var module = CONTEXT.findModule(NAME, Revision.of(REVISION_DATE)).orElseThrow();
final OpenApiObject doc = generator.getOpenApiSpec(module, "http", "localhost:8181", "/", "", CONTEXT);
- final ObjectNode schemas = doc.getComponents().getSchemas();
+ final Map<String, Schema> schemas = doc.getComponents().getSchemas();
assertNotNull(schemas);
- final JsonNode configLstTop = schemas.get("toaster2_config_lst_TOP");
+ final Schema configLstTop = schemas.get("toaster2_config_lst_TOP");
assertNotNull(configLstTop);
DocGenTestHelper.containsReferences(configLstTop, "lst", "#/components/schemas/toaster2_config_lst");
- final JsonNode configLst = schemas.get("toaster2_config_lst");
+ final Schema configLst = schemas.get("toaster2_config_lst");
assertNotNull(configLst);
DocGenTestHelper.containsReferences(configLst, "lst1", "#/components/schemas/toaster2_lst_config_lst1");
DocGenTestHelper.containsReferences(configLst, "cont1", "#/components/schemas/toaster2_lst_config_cont1");
- final JsonNode configLst1Top = schemas.get("toaster2_lst_config_lst1_TOP");
+ final Schema configLst1Top = schemas.get("toaster2_lst_config_lst1_TOP");
assertNotNull(configLst1Top);
DocGenTestHelper.containsReferences(configLst1Top, "lst1", "#/components/schemas/toaster2_lst_config_lst1");
- final JsonNode configLst1 = schemas.get("toaster2_lst_config_lst1");
+ final Schema configLst1 = schemas.get("toaster2_lst_config_lst1");
assertNotNull(configLst1);
- final JsonNode configCont1Top = schemas.get("toaster2_lst_config_cont1_TOP");
+ final Schema configCont1Top = schemas.get("toaster2_lst_config_cont1_TOP");
assertNotNull(configCont1Top);
DocGenTestHelper.containsReferences(configCont1Top, "cont1", "#/components/schemas/toaster2_lst_config_cont1");
- final JsonNode configCont1 = schemas.get("toaster2_lst_config_cont1");
+ final Schema configCont1 = schemas.get("toaster2_lst_config_cont1");
assertNotNull(configCont1);
DocGenTestHelper.containsReferences(configCont1, "cont11",
"#/components/schemas/toaster2_lst_cont1_config_cont11");
DocGenTestHelper.containsReferences(configCont1, "lst11",
"#/components/schemas/toaster2_lst_cont1_config_lst11");
- final JsonNode configCont11Top = schemas.get("toaster2_lst_cont1_config_cont11_TOP");
+ final Schema configCont11Top = schemas.get("toaster2_lst_cont1_config_cont11_TOP");
assertNotNull(configCont11Top);
DocGenTestHelper.containsReferences(configCont11Top,
"cont11", "#/components/schemas/toaster2_lst_cont1_config_cont11");
- final JsonNode configCont11 = schemas.get("toaster2_lst_cont1_config_cont11");
+ final Schema configCont11 = schemas.get("toaster2_lst_cont1_config_cont11");
assertNotNull(configCont11);
- final JsonNode configLst11Top = schemas.get("toaster2_lst_cont1_config_lst11_TOP");
+ final Schema configLst11Top = schemas.get("toaster2_lst_cont1_config_lst11_TOP");
assertNotNull(configLst11Top);
DocGenTestHelper.containsReferences(configLst11Top, "lst11",
"#/components/schemas/toaster2_lst_cont1_config_lst11");
- final JsonNode configLst11 = schemas.get("toaster2_lst_cont1_config_lst11");
+ final Schema configLst11 = schemas.get("toaster2_lst_cont1_config_lst11");
assertNotNull(configLst11);
}
final OpenApiObject doc = generator.getOpenApiSpec(module, "http", "localhost:8181", "/", "", CONTEXT);
assertNotNull(doc);
- final ObjectNode schemas = doc.getComponents().getSchemas();
- final JsonNode inputTop = schemas.get("toaster_make-toast_input_TOP");
+ final Map<String, Schema> schemas = doc.getComponents().getSchemas();
+ final Schema inputTop = schemas.get("toaster_make-toast_input_TOP");
assertNotNull(inputTop);
final String testString = "{\"input\":{\"$ref\":\"#/components/schemas/toaster_make-toast_input\"}}";
- assertEquals(testString, inputTop.get("properties").toString());
- final JsonNode input = schemas.get("toaster_make-toast_input");
- final JsonNode properties = input.get("properties");
+ assertEquals(testString, inputTop.getProperties().toString());
+ final Schema input = schemas.get("toaster_make-toast_input");
+ final JsonNode properties = input.getProperties();
assertTrue(properties.has("toasterDoneness"));
assertTrue(properties.has("toasterToastType"));
}
assertNotNull(doc);
final var schemas = doc.getComponents().getSchemas();
- JsonNode firstContainer = schemas.get("choice-test_first-container");
+ final Schema firstContainer = schemas.get("choice-test_first-container");
assertEquals("default-value",
- firstContainer.get(PROPERTIES).get("leaf-default").get("default").asText());
- assertFalse(firstContainer.get(PROPERTIES).has("leaf-non-default"));
+ firstContainer.getProperties().get("leaf-default").get("default").asText());
+ assertFalse(firstContainer.getProperties().has("leaf-non-default"));
- JsonNode secondContainer = schemas.get("choice-test_second-container");
- assertTrue(secondContainer.get(PROPERTIES).has("leaf-first-case"));
- assertFalse(secondContainer.get(PROPERTIES).has("leaf-second-case"));
+ final Schema secondContainer = schemas.get("choice-test_second-container");
+ assertTrue(secondContainer.getProperties().has("leaf-first-case"));
+ assertFalse(secondContainer.getProperties().has("leaf-second-case"));
}
}