diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java index fd0c604b3b..2db5d0ee4c 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/OpenAPIDeserializer.java @@ -49,9 +49,11 @@ import io.swagger.v3.oas.models.servers.ServerVariables; import io.swagger.v3.parser.core.models.SwaggerParseResult; import io.swagger.v3.core.util.Json; -import io.swagger.v3.core.util.RefUtils; +import org.apache.commons.lang3.ObjectUtils; +import io.swagger.v3.core.util.RefUtils; import org.apache.commons.lang3.StringUtils; +import org.slf4j.LoggerFactory; import static io.swagger.v3.core.util.RefUtils.extractSimpleName; @@ -69,7 +71,8 @@ public class OpenAPIDeserializer { - + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(OpenAPIDeserializer.class); + private static final String DEFAULT_KEY = "default"; protected static Set ROOT_KEYS = new LinkedHashSet<>(Arrays.asList("openapi", "info", "servers", "paths", "components", "security", "tags", "externalDocs")); protected static Set INFO_KEYS = new LinkedHashSet<>(Arrays.asList("title", "description", "termsOfService", "contact", "license", "version")); protected static Set CONTACT_KEYS = new LinkedHashSet<>(Arrays.asList("name", "url", "email")); @@ -2296,45 +2299,11 @@ public Schema getSchema(ObjectNode node, String location, ParseResult result){ } //sets default value according to the schema type - if(node.get("default")!= null) { - 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 (value != null) { - 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); - } - } - } + String schemaType = schema.getType(); + if (ObjectUtils.allNotNull(schemaType, node.get("default"))){ + schema.setDefault(getDefaultValueFromType(node, location, result, schemaType)); + } bool = getBoolean("nullable", node, false, location, result); if(bool != null) { @@ -2997,6 +2966,26 @@ else if(!"number".equals(type)) { return type; } + private Object getDefaultValueFromType(ObjectNode node, String location, ParseResult result, final String schemaType) { + + switch (schemaType) { + case "array": + return getArray(DEFAULT_KEY, node, false, location, result); + case "string": + return getString(DEFAULT_KEY, node, false, location, result); + case "boolean": + return getBoolean(DEFAULT_KEY, node, false, location, result); + case "object": + return getObject(DEFAULT_KEY, node, false, location, result); + case "integer": + return getInteger(DEFAULT_KEY, node, false, location, result); + case "number": + return getBigDecimal(DEFAULT_KEY, node, false, location, result); + default: + LOGGER.warn("Schema type is undefined for {} ", node.toString()); + return null; + } + } protected static class ParseResult { private boolean valid = true; diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/OpenAPIDeserializerTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/OpenAPIDeserializerTest.java index dca3900b56..44d63ad522 100644 --- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/OpenAPIDeserializerTest.java +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/OpenAPIDeserializerTest.java @@ -42,11 +42,15 @@ import io.swagger.v3.parser.core.models.SwaggerParseResult; import io.swagger.v3.parser.OpenAPIV3Parser; import mockit.Injectable; +import org.apache.commons.io.FileUtils; import org.testng.Assert; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import java.io.File; +import java.io.IOException; import java.math.BigDecimal; +import java.net.URISyntaxException; import java.nio.file.Files; import java.util.Arrays; import java.util.Calendar; @@ -720,6 +724,44 @@ public void testDeserializeBinaryString() { assertTrue(resolved.getPaths().get("/test").getPost().getRequestBody().getContent().get("application/json").getSchema() instanceof BinarySchema); } + @Test + public void testDefaultValueWhenUnknownType() throws URISyntaxException, IOException { + final ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + final JsonNode rootNode = mapper.readTree(Files.readAllBytes(java.nio.file.Paths.get(getClass().getResource("/issue-1072/spec.yaml").toURI()))); + + final OpenAPIDeserializer deserializer = new OpenAPIDeserializer(); + final SwaggerParseResult result = deserializer.deserialize(rootNode); + + OpenAPI openAPI = result.getOpenAPI(); + Assert.assertNotNull(openAPI); + Map schemas = openAPI.getComponents().getSchemas(); + Assert.assertNotNull(schemas); + + ComposedSchema componentA = (ComposedSchema)schemas.get("ComponentA"); + Assert.assertNotNull(componentA.getAllOf()); + Assert.assertEquals(componentA.getAllOf().size(), 1); + Schema subSchema = componentA.getAllOf().get(0); + Assert.assertNotNull(subSchema); + + Map properties = subSchema.getProperties(); + Assert.assertNotNull(properties); + + ComposedSchema attributeWithoutType = (ComposedSchema)properties.get("attributeWithoutType"); + Assert.assertNotNull(attributeWithoutType); + Assert.assertNull(attributeWithoutType.getType()); + Assert.assertNull(attributeWithoutType.getDefault()); + + ComposedSchema attributeWithWrongType = (ComposedSchema)properties.get("attributeWithWrongType"); + Assert.assertNotNull(attributeWithWrongType); + Assert.assertEquals(attributeWithWrongType.getType(), "object"); + Assert.assertNull(attributeWithWrongType.getDefault()); + + ComposedSchema correctAttribute = (ComposedSchema)properties.get("correctAttribute"); + Assert.assertNotNull(correctAttribute); + Assert.assertEquals(correctAttribute.getType(), "string"); + Assert.assertEquals(correctAttribute.getDefault(), "coucou"); + } + @Test public void testDeserializeEnum() { String yaml = "openapi: 3.0.0\n" + diff --git a/modules/swagger-parser-v3/src/test/resources/issue-1072/spec.yaml b/modules/swagger-parser-v3/src/test/resources/issue-1072/spec.yaml new file mode 100644 index 0000000000..fc0994ee1a --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/issue-1072/spec.yaml @@ -0,0 +1,41 @@ +openapi: 3.0.0 +info: + title: Test + version: 1.0.0 + +paths: + /value: + get: + operationId: getValues + responses: + 200: + description: Successful response + content: + application/json: + schema: + $ref: '#/components/schemas/ComponentA' +components: + schemas: + ComponentA: + description: Component A + type: object + allOf: + - type: object + properties: + attributeWithoutType: + allOf: + - $ref: '#/components/schemas/ComponentB' + default: "coucou" + attributeWithWrongType: + type: object + allOf: + - $ref: '#/components/schemas/ComponentB' + default: "coucou" + correctAttribute: + type: string + allOf: + - $ref: '#/components/schemas/ComponentB' + default: "coucou" + ComponentB: + description: Component B + type: string