Search in sources :

Example 16 with Discriminator

use of io.swagger.v3.oas.models.media.Discriminator in project swagger-parser by swagger-api.

the class OpenAPIDeserializerTest method testDeserializeWithDiscriminator.

@Test
public void testDeserializeWithDiscriminator() {
    String yaml = "openapi: 3.0.0\n" + "servers: []\n" + "info:\n" + "  version: ''\n" + "  title: ''\n" + "paths: {}\n" + "components:\n" + "  schemas:\n" + "    Animal:\n" + "      type: object\n" + "      discriminator:\n" + "        propertyName: petType\n" + "      description: |\n" + "        A basic `Animal` object which can extend to other animal types.\n" + "      required:\n" + "        - commonName\n" + "        - petType\n" + "      properties:\n" + "        commonName:\n" + "          description: the household name of the animal\n" + "          type: string\n" + "        petType:\n" + "          description: |\n" + "            The discriminator for the animal type.  It _must_\n" + "            match one of the concrete schemas by name (i.e. `Cat`)\n" + "            for proper deserialization\n" + "          type: string";
    OpenAPIV3Parser parser = new OpenAPIV3Parser();
    SwaggerParseResult result = parser.readContents(yaml, null, null);
    Set<String> messages = new HashSet<>(result.getMessages());
    assertFalse(messages.contains("attribute definitions.Animal.discriminator is unexpected"));
}
Also used : SwaggerParseResult(io.swagger.v3.parser.core.models.SwaggerParseResult) OpenAPIV3Parser(io.swagger.v3.parser.OpenAPIV3Parser) HashSet(java.util.HashSet) Test(org.testng.annotations.Test)

Example 17 with Discriminator

use of io.swagger.v3.oas.models.media.Discriminator in project swagger-parser by swagger-api.

the class OpenAPIDeserializerTest method testDeserializeWithNumericEnumDiscriminator.

@Test
public void testDeserializeWithNumericEnumDiscriminator() {
    String yaml = "openapi: 3.0.0\n" + "components:\n" + "  schemas:\n" + "    Animal:\n" + "      type: object\n" + "      discriminator:\n" + "        propertyName: petType\n" + "      description: |\n" + "        A basic `Animal` object which can extend to other animal types.\n" + "      required:\n" + "        - commonName\n" + "        - petType\n" + "      properties:\n" + "        commonName:\n" + "          description: the household name of the animal\n" + "          type: string\n" + "        petType:\n" + "          enum:\n" + "            - 1\n" + "            - 2";
    OpenAPIV3Parser parser = new OpenAPIV3Parser();
    SwaggerParseResult result = parser.readContents(yaml, null, null);
    Map<String, Schema> properties = result.getOpenAPI().getComponents().getSchemas().get("Animal").getProperties();
    assertTrue(properties.containsKey("commonName"));
    assertTrue(properties.containsKey("petType"));
    assertEquals(properties.get("petType").getType(), "number");
}
Also used : DateSchema(io.swagger.v3.oas.models.media.DateSchema) ComposedSchema(io.swagger.v3.oas.models.media.ComposedSchema) DateTimeSchema(io.swagger.v3.oas.models.media.DateTimeSchema) ByteArraySchema(io.swagger.v3.oas.models.media.ByteArraySchema) IntegerSchema(io.swagger.v3.oas.models.media.IntegerSchema) StringSchema(io.swagger.v3.oas.models.media.StringSchema) ObjectSchema(io.swagger.v3.oas.models.media.ObjectSchema) ArraySchema(io.swagger.v3.oas.models.media.ArraySchema) Schema(io.swagger.v3.oas.models.media.Schema) MapSchema(io.swagger.v3.oas.models.media.MapSchema) BinarySchema(io.swagger.v3.oas.models.media.BinarySchema) SwaggerParseResult(io.swagger.v3.parser.core.models.SwaggerParseResult) OpenAPIV3Parser(io.swagger.v3.parser.OpenAPIV3Parser) Test(org.testng.annotations.Test)

Example 18 with Discriminator

use of io.swagger.v3.oas.models.media.Discriminator in project swagger-parser by swagger-api.

the class OpenAPIDeserializer method getSchema.

public Schema getSchema(ObjectNode node, String location, ParseResult result) {
    if (node == null) {
        return null;
    }
    // Added to handle NPE from ResolverCache when Trying to dereference a schema
    if (result == null) {
        result = new ParseResult();
        result.setAllowEmptyStrings(true);
    }
    Schema schema = null;
    ArrayNode oneOfArray = getArray("oneOf", node, false, location, result);
    ArrayNode allOfArray = getArray("allOf", node, false, location, result);
    ArrayNode anyOfArray = getArray("anyOf", node, false, location, result);
    ObjectNode itemsNode = getObject("items", node, false, location, result);
    if ((allOfArray != null) || (anyOfArray != null) || (oneOfArray != null)) {
        ComposedSchema composedSchema = new ComposedSchema();
        if (allOfArray != null) {
            for (JsonNode n : allOfArray) {
                if (n.isObject()) {
                    schema = getSchema((ObjectNode) n, location, result);
                    composedSchema.addAllOfItem(schema);
                }
            }
            schema = composedSchema;
        }
        if (anyOfArray != null) {
            for (JsonNode n : anyOfArray) {
                if (n.isObject()) {
                    schema = getSchema((ObjectNode) n, location, result);
                    composedSchema.addAnyOfItem(schema);
                }
            }
            schema = composedSchema;
        }
        if (oneOfArray != null) {
            for (JsonNode n : oneOfArray) {
                if (n.isObject()) {
                    schema = getSchema((ObjectNode) n, location, result);
                    composedSchema.addOneOfItem(schema);
                }
            }
            schema = composedSchema;
        }
    }
    if (itemsNode != null) {
        ArraySchema items = new ArraySchema();
        if (itemsNode.getNodeType().equals(JsonNodeType.OBJECT)) {
            items.setItems(getSchema(itemsNode, location, result));
        } else if (itemsNode.getNodeType().equals(JsonNodeType.ARRAY)) {
            for (JsonNode n : itemsNode) {
                if (n.isValueNode()) {
                    items.setItems(getSchema(itemsNode, location, result));
                }
            }
        }
        schema = items;
    }
    Boolean additionalPropertiesBoolean = getBoolean("additionalProperties", node, false, location, result);
    ObjectNode additionalPropertiesObject = additionalPropertiesBoolean == null ? getObject("additionalProperties", node, false, location, result) : null;
    Object additionalProperties = additionalPropertiesObject != null ? getSchema(additionalPropertiesObject, location, result) : additionalPropertiesBoolean;
    if (additionalProperties != null) {
        if (schema == null) {
            schema = additionalProperties.equals(Boolean.FALSE) ? new ObjectSchema() : new MapSchema();
        }
        schema.setAdditionalProperties(additionalProperties);
    }
    if (schema == null) {
        schema = SchemaTypeUtil.createSchemaByType(node);
    }
    JsonNode ref = node.get("$ref");
    if (ref != null) {
        if (ref.getNodeType().equals(JsonNodeType.STRING)) {
            if (location.startsWith("paths")) {
                try {
                    String[] components = ref.asText().split("#/components");
                    if ((ref.asText().startsWith("#/components")) && (components.length > 1)) {
                        String[] childComponents = components[1].split("/");
                        String[] newChildComponents = Arrays.copyOfRange(childComponents, 1, childComponents.length);
                        boolean isValidComponent = ReferenceValidator.valueOf(newChildComponents[0]).validateComponent(this.components, newChildComponents[1]);
                        if (!isValidComponent) {
                            result.missing(location, ref.asText());
                        }
                    }
                } catch (Exception e) {
                    result.missing(location, ref.asText());
                }
            }
            String mungedRef = mungedRef(ref.textValue());
            if (mungedRef != null) {
                schema.set$ref(mungedRef);
            } else {
                schema.set$ref(ref.asText());
            }
            return schema;
        } else {
            result.invalidType(location, "$ref", "string", node);
            return null;
        }
    }
    String value = getString("title", node, false, location, result);
    if ((result.isAllowEmptyStrings() && value != null) || (!result.isAllowEmptyStrings() && !StringUtils.isBlank(value))) {
        schema.setTitle(value);
    }
    ObjectNode discriminatorNode = getObject("discriminator", node, false, location, result);
    if (discriminatorNode != null) {
        schema.setDiscriminator(getDiscriminator(discriminatorNode, location, result));
    }
    BigDecimal bigDecimal = getBigDecimal("multipleOf", node, false, location, result);
    if (bigDecimal != null) {
        if (bigDecimal.compareTo(BigDecimal.ZERO) > 0) {
            schema.setMultipleOf(bigDecimal);
        } else {
            result.warning(location, "multipleOf value must be > 0");
        }
    }
    bigDecimal = getBigDecimal("maximum", node, false, location, result);
    if (bigDecimal != null) {
        schema.setMaximum(bigDecimal);
    }
    Boolean bool = getBoolean("exclusiveMaximum", node, false, location, result);
    if (bool != null) {
        schema.setExclusiveMaximum(bool);
    }
    bigDecimal = getBigDecimal("minimum", node, false, location, result);
    if (bigDecimal != null) {
        schema.setMinimum(bigDecimal);
    }
    bool = getBoolean("exclusiveMinimum", node, false, location, result);
    if (bool != null) {
        schema.setExclusiveMinimum(bool);
    }
    Integer integer = getInteger("minLength", node, false, location, result);
    if (integer != null) {
        schema.setMinLength(integer);
    }
    integer = getInteger("maxLength", node, false, location, result);
    if (integer != null) {
        schema.setMaxLength(integer);
    }
    String pattern = getString("pattern", node, false, location, result);
    if (result.isAllowEmptyStrings() && pattern != null) {
        schema.setPattern(pattern);
    }
    integer = getInteger("maxItems", node, false, location, result);
    if (integer != null) {
        schema.setMaxItems(integer);
    }
    integer = getInteger("minItems", node, false, location, result);
    if (integer != null) {
        schema.setMinItems(integer);
    }
    bool = getBoolean("uniqueItems", node, false, location, result);
    if (bool != null) {
        schema.setUniqueItems(bool);
    }
    integer = getInteger("maxProperties", node, false, location, result);
    if (integer != null) {
        schema.setMaxProperties(integer);
    }
    integer = getInteger("minProperties", node, false, location, result);
    if (integer != null) {
        schema.setMinProperties(integer);
    }
    ArrayNode required = getArray("required", node, false, location, result);
    if (required != null) {
        List<String> requiredList = new ArrayList<>();
        for (JsonNode n : required) {
            if (n.getNodeType().equals(JsonNodeType.STRING)) {
                requiredList.add(((TextNode) n).textValue());
            } else {
                result.invalidType(location, "required", "string", n);
            }
        }
        if (requiredList.size() > 0) {
            schema.setRequired(requiredList);
        }
    }
    ArrayNode enumArray = getArray("enum", node, false, location, result);
    if (enumArray != null) {
        for (JsonNode n : enumArray) {
            if (n.isNumber()) {
                schema.addEnumItemObject(n.numberValue());
            } else if (n.isBoolean()) {
                schema.addEnumItemObject(n.booleanValue());
            } else if (n.isValueNode()) {
                try {
                    schema.addEnumItemObject(getDecodedObject(schema, n.asText(null)));
                } catch (ParseException e) {
                    result.invalidType(location, String.format("enum=`%s`", e.getMessage()), schema.getFormat(), n);
                }
            } else if (n.isContainerNode()) {
                schema.addEnumItemObject(n.isNull() ? null : n);
            } else {
                result.invalidType(location, "enum", "value", n);
            }
        }
    }
    value = getString("type", node, false, location, result);
    if (StringUtils.isBlank(schema.getType())) {
        if ((result.isAllowEmptyStrings() && value != null) || (!result.isAllowEmptyStrings() && !StringUtils.isBlank(value))) {
            schema.setType(value);
        } else {
            // may have an enum where type can be inferred
            JsonNode enumNode = node.get("enum");
            if (enumNode != null && enumNode.isArray()) {
                String type = inferTypeFromArray((ArrayNode) enumNode);
                schema.setType(type);
            }
        }
        if ("array".equals(schema.getType()) && !(schema instanceof ArraySchema && ((ArraySchema) schema).getItems() != null)) {
            result.missing(location, "items");
        }
    }
    ObjectNode notObj = getObject("not", node, false, location, result);
    if (notObj != null) {
        Schema not = getSchema(notObj, location, result);
        if (not != null) {
            schema.setNot(not);
        }
    }
    Map<String, Schema> properties = new LinkedHashMap<>();
    ObjectNode propertiesObj = getObject("properties", node, false, location, result);
    Schema property = null;
    Set<String> keys = getKeys(propertiesObj);
    for (String name : keys) {
        JsonNode propertyValue = propertiesObj.get(name);
        if (!propertyValue.getNodeType().equals(JsonNodeType.OBJECT)) {
            result.invalidType(location, "properties", "object", propertyValue);
        } else {
            if (propertiesObj != null) {
                property = getSchema((ObjectNode) propertyValue, location, result);
                if (property != null) {
                    properties.put(name, property);
                }
            }
        }
    }
    if (propertiesObj != null) {
        schema.setProperties(properties);
    }
    value = getString("description", node, false, location, result);
    if ((result.isAllowEmptyStrings() && value != null) || (!result.isAllowEmptyStrings() && !StringUtils.isBlank(value))) {
        schema.setDescription(value);
    }
    value = getString("format", node, false, location, result);
    if ((result.isAllowEmptyStrings() && value != null) || (!result.isAllowEmptyStrings() && !StringUtils.isBlank(value))) {
        schema.setFormat(value);
    }
    // sets default value according to the schema type
    if (node.get("default") != null) {
        if (!StringUtils.isBlank(schema.getType())) {
            if (schema.getType().equals("array")) {
                ArrayNode array = getArray("default", node, false, location, result);
                if (array != null) {
                    schema.setDefault(array);
                }
            } else if (schema.getType().equals("string")) {
                value = getString("default", node, false, location, result);
                if ((result.isAllowEmptyStrings() && value != null) || (!result.isAllowEmptyStrings() && !StringUtils.isBlank(value))) {
                    try {
                        schema.setDefault(getDecodedObject(schema, value));
                    } catch (ParseException e) {
                        result.invalidType(location, String.format("default=`%s`", e.getMessage()), schema.getFormat(), node);
                    }
                }
            } else if (schema.getType().equals("boolean")) {
                bool = getBoolean("default", node, false, location, result);
                if (bool != null) {
                    schema.setDefault(bool);
                }
            } else if (schema.getType().equals("object")) {
                Object object = getObject("default", node, false, location, result);
                if (object != null) {
                    schema.setDefault(object);
                }
            } else if (schema.getType().equals("integer")) {
                Integer number = getInteger("default", node, false, location, result);
                if (number != null) {
                    schema.setDefault(number);
                }
            } else if (schema.getType().equals("number")) {
                BigDecimal number = getBigDecimal("default", node, false, location, result);
                if (number != null) {
                    schema.setDefault(number);
                }
            }
        }
    }
    bool = getBoolean("nullable", node, false, location, result);
    if (bool != null) {
        schema.setNullable(bool);
    }
    bool = getBoolean("readOnly", node, false, location, result);
    if (bool != null) {
        schema.setReadOnly(bool);
    }
    bool = getBoolean("writeOnly", node, false, location, result);
    if (bool != null) {
        schema.setWriteOnly(bool);
    }
    bool = Optional.ofNullable(getBoolean("writeOnly", node, false, location, result)).orElse(false) && Optional.ofNullable(getBoolean("readOnly", node, false, location, result)).orElse(false);
    if (bool == true) {
        result.warning(location, " writeOnly and readOnly are both present");
    }
    ObjectNode xmlNode = getObject("xml", node, false, location, result);
    if (xmlNode != null) {
        XML xml = getXml(xmlNode, location, result);
        if (xml != null) {
            schema.setXml(xml);
        }
    }
    ObjectNode externalDocs = getObject("externalDocs", node, false, location, result);
    if (externalDocs != null) {
        ExternalDocumentation docs = getExternalDocs(externalDocs, location, result);
        if (docs != null) {
            schema.setExternalDocs(docs);
        }
    }
    Object example = getAnyExample("example", node, location, result);
    if (example != null) {
        schema.setExample(example instanceof NullNode ? null : example);
    }
    bool = getBoolean("deprecated", node, false, location, result);
    if (bool != null) {
        schema.setDeprecated(bool);
    }
    Map<String, Object> extensions = getExtensions(node);
    if (extensions != null && extensions.size() > 0) {
        schema.setExtensions(extensions);
    }
    Set<String> schemaKeys = getKeys(node);
    for (String key : schemaKeys) {
        if (!SCHEMA_KEYS.contains(key) && !key.startsWith("x-")) {
            result.extra(location, key, node.get(key));
        }
    }
    return schema;
}
Also used : DateSchema(io.swagger.v3.oas.models.media.DateSchema) ComposedSchema(io.swagger.v3.oas.models.media.ComposedSchema) DateTimeSchema(io.swagger.v3.oas.models.media.DateTimeSchema) ByteArraySchema(io.swagger.v3.oas.models.media.ByteArraySchema) ObjectSchema(io.swagger.v3.oas.models.media.ObjectSchema) ArraySchema(io.swagger.v3.oas.models.media.ArraySchema) Schema(io.swagger.v3.oas.models.media.Schema) MapSchema(io.swagger.v3.oas.models.media.MapSchema) JsonNode(com.fasterxml.jackson.databind.JsonNode) ByteArraySchema(io.swagger.v3.oas.models.media.ByteArraySchema) ArraySchema(io.swagger.v3.oas.models.media.ArraySchema) ExternalDocumentation(io.swagger.v3.oas.models.ExternalDocumentation) ObjectSchema(io.swagger.v3.oas.models.media.ObjectSchema) MapSchema(io.swagger.v3.oas.models.media.MapSchema) ArrayNode(com.fasterxml.jackson.databind.node.ArrayNode) ComposedSchema(io.swagger.v3.oas.models.media.ComposedSchema) SwaggerParseResult(io.swagger.v3.parser.core.models.SwaggerParseResult) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) URISyntaxException(java.net.URISyntaxException) ParseException(java.text.ParseException) BigDecimal(java.math.BigDecimal) XML(io.swagger.v3.oas.models.media.XML) ParseException(java.text.ParseException) NullNode(com.fasterxml.jackson.databind.node.NullNode)

Example 19 with Discriminator

use of io.swagger.v3.oas.models.media.Discriminator in project swagger-parser by swagger-api.

the class OpenAPIV3ParserTest method testDiscriminatorSingleFileInternalMapping.

@Test
public void testDiscriminatorSingleFileInternalMapping() throws Exception {
    OpenAPI openAPI = new OpenAPIV3Parser().read("./discriminator-mapping-resolution/single-file-internal-mapping.yaml");
    Assert.assertNotNull(openAPI);
    Schema cat = openAPI.getComponents().getSchemas().get("Cat");
    Assert.assertNotNull(cat);
}
Also used : ComposedSchema(io.swagger.v3.oas.models.media.ComposedSchema) ByteArraySchema(io.swagger.v3.oas.models.media.ByteArraySchema) IntegerSchema(io.swagger.v3.oas.models.media.IntegerSchema) StringSchema(io.swagger.v3.oas.models.media.StringSchema) ObjectSchema(io.swagger.v3.oas.models.media.ObjectSchema) ArraySchema(io.swagger.v3.oas.models.media.ArraySchema) Schema(io.swagger.v3.oas.models.media.Schema) MapSchema(io.swagger.v3.oas.models.media.MapSchema) OpenAPIV3Parser(io.swagger.v3.parser.OpenAPIV3Parser) OpenAPI(io.swagger.v3.oas.models.OpenAPI) Test(org.testng.annotations.Test)

Example 20 with Discriminator

use of io.swagger.v3.oas.models.media.Discriminator in project swagger-parser by swagger-api.

the class OpenAPIV3ParserTest method testDiscriminatorSingleFileNoMapping.

@Test
public void testDiscriminatorSingleFileNoMapping() throws Exception {
    OpenAPI openAPI = new OpenAPIV3Parser().read("./discriminator-mapping-resolution/single-file-no-mapping.yaml");
    Assert.assertNotNull(openAPI);
    Schema cat = openAPI.getComponents().getSchemas().get("Cat");
    Assert.assertNotNull(cat);
}
Also used : ComposedSchema(io.swagger.v3.oas.models.media.ComposedSchema) ByteArraySchema(io.swagger.v3.oas.models.media.ByteArraySchema) IntegerSchema(io.swagger.v3.oas.models.media.IntegerSchema) StringSchema(io.swagger.v3.oas.models.media.StringSchema) ObjectSchema(io.swagger.v3.oas.models.media.ObjectSchema) ArraySchema(io.swagger.v3.oas.models.media.ArraySchema) Schema(io.swagger.v3.oas.models.media.Schema) MapSchema(io.swagger.v3.oas.models.media.MapSchema) OpenAPIV3Parser(io.swagger.v3.parser.OpenAPIV3Parser) OpenAPI(io.swagger.v3.oas.models.OpenAPI) Test(org.testng.annotations.Test)

Aggregations

Schema (io.swagger.v3.oas.models.media.Schema)19 Test (org.testng.annotations.Test)19 ArraySchema (io.swagger.v3.oas.models.media.ArraySchema)15 ComposedSchema (io.swagger.v3.oas.models.media.ComposedSchema)15 ObjectSchema (io.swagger.v3.oas.models.media.ObjectSchema)15 MapSchema (io.swagger.v3.oas.models.media.MapSchema)14 StringSchema (io.swagger.v3.oas.models.media.StringSchema)14 IntegerSchema (io.swagger.v3.oas.models.media.IntegerSchema)13 OpenAPIV3Parser (io.swagger.v3.parser.OpenAPIV3Parser)13 ByteArraySchema (io.swagger.v3.oas.models.media.ByteArraySchema)12 OpenAPI (io.swagger.v3.oas.models.OpenAPI)11 AnnotatedType (io.swagger.v3.core.converter.AnnotatedType)6 SwaggerParseResult (io.swagger.v3.parser.core.models.SwaggerParseResult)6 Discriminator (io.swagger.v3.oas.models.media.Discriminator)5 DateSchema (io.swagger.v3.oas.models.media.DateSchema)4 DateTimeSchema (io.swagger.v3.oas.models.media.DateTimeSchema)4 BinarySchema (io.swagger.v3.oas.models.media.BinarySchema)3 HashSet (java.util.HashSet)3 JsonTypeInfo (com.fasterxml.jackson.annotation.JsonTypeInfo)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)2