diff --git a/modules/swagger-parser-v2-converter/pom.xml b/modules/swagger-parser-v2-converter/pom.xml index ce3eab30d1..a0d8a2e43e 100644 --- a/modules/swagger-parser-v2-converter/pom.xml +++ b/modules/swagger-parser-v2-converter/pom.xml @@ -32,6 +32,11 @@ swagger-parser-core ${parent.version} + + io.swagger.parser.v3 + swagger-parser-v3 + ${parent.version} + org.apache.commons commons-lang3 diff --git a/modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java b/modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java index ef88aa4155..8e5dc66b62 100644 --- a/modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java +++ b/modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java @@ -22,6 +22,7 @@ import io.swagger.models.parameters.SerializableParameter; import io.swagger.models.properties.AbstractNumericProperty; import io.swagger.models.properties.ArrayProperty; +import io.swagger.models.properties.FileProperty; import io.swagger.models.properties.MapProperty; import io.swagger.models.properties.ObjectProperty; import io.swagger.models.properties.Property; @@ -29,7 +30,7 @@ import io.swagger.parser.SwaggerParser; import io.swagger.parser.SwaggerResolver; import io.swagger.parser.util.SwaggerDeserializationResult; -import io.swagger.util.Json; +import io.swagger.v3.core.util.Json; import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.ExternalDocumentation; import io.swagger.v3.oas.models.OpenAPI; @@ -63,6 +64,7 @@ import io.swagger.v3.parser.core.models.SwaggerParseResult; import org.apache.commons.lang3.StringUtils; + import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; @@ -837,7 +839,11 @@ private Schema convert(Property schema) { result = arraySchema; - } else { + } else if (schema instanceof FileProperty) { + FileSchema fileSchema = Json.mapper().convertValue(schema, FileSchema.class); + result = fileSchema; + + }else { result = Json.mapper().convertValue(schema, Schema.class); result.setExample(schema.getExample()); @@ -1071,3 +1077,4 @@ public Schema convert(io.swagger.models.Model v2Model) { return result; } } + diff --git a/modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java b/modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java index 9c521fa3f7..214faa43f5 100644 --- a/modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java +++ b/modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java @@ -144,8 +144,8 @@ public class V2ConverterTest { private static final int NUMBER_VALUE_TWENTY = 20; private static final double MULTIPLE_OF_VALUE = 0.01D; private static final long DEFAULT_VALUE = 11L; - private static final long EXAMPLE_8_NUMBER = 8L; - private static final long EXAMPLE_42_NUMBER = 42L; + private static final int EXAMPLE_8_NUMBER = 8; + private static final int EXAMPLE_42_NUMBER = 42; @Test public void testConvertPetstore() throws Exception { @@ -372,11 +372,12 @@ public void testIssue22() throws Exception { assertNotNull(oas); } - @Test(description = "$ref not updated in components (aditional properties)") + @Test(description = "$ref not updated in components (additional properties)") public void testIssue23() throws Exception { OpenAPI oas = getConvertedOpenAPIFromJsonFile(ISSUE_23_JSON); - assertEquals(OBJECT_REF, oas.getComponents().getSchemas() - .get(MAP_OBJECTS_MODEL).getAdditionalProperties().get$ref()); + assertTrue(oas.getComponents().getSchemas().get(MAP_OBJECTS_MODEL).getAdditionalProperties() instanceof Schema); + Schema additionalProperties = (Schema) oas.getComponents().getSchemas().get(MAP_OBJECTS_MODEL).getAdditionalProperties(); + assertEquals(OBJECT_REF,additionalProperties.get$ref()); } @Test(description = "Covert path item $refs") diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java index e43735368d..17dbed68cd 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ExternalRefProcessor.java @@ -102,21 +102,21 @@ public String processRefToExternalSchema(String $ref, RefFormat refFormat) { StringUtils.isNotBlank(arrayProp.get$ref())) { processRefProperty(arrayProp.getItems(), file); } - } else if (prop.getValue().getAdditionalProperties() != null) { - Schema mapProp = prop.getValue(); - if (mapProp.getAdditionalProperties().get$ref() != null) { - processRefProperty(mapProp.getAdditionalProperties(), file); + } else if (prop.getValue().getAdditionalProperties() != null && prop.getValue().getAdditionalProperties() instanceof Schema) { + Schema mapProp = (Schema) prop.getValue().getAdditionalProperties(); + if (mapProp.get$ref() != null) { + processRefProperty(mapProp, file); } else if (mapProp.getAdditionalProperties() instanceof ArraySchema && - ((ArraySchema) mapProp.getAdditionalProperties()).getItems()!= null && - ((ArraySchema) mapProp.getAdditionalProperties()).getItems().get$ref() != null - && StringUtils.isNotBlank(((ArraySchema) mapProp.getAdditionalProperties()).getItems().get$ref())) { + ((ArraySchema) mapProp).getItems()!= null && + ((ArraySchema) mapProp).getItems().get$ref() != null + && StringUtils.isNotBlank(((ArraySchema) mapProp).getItems().get$ref())) { processRefProperty(((ArraySchema) mapProp.getAdditionalProperties()).getItems(), file); } } } } - if(schema.getAdditionalProperties() != null){ - Schema additionalProperty = schema.getAdditionalProperties(); + if(schema.getAdditionalProperties() != null && schema.getAdditionalProperties() instanceof Schema){ + Schema additionalProperty = (Schema) schema.getAdditionalProperties(); if (additionalProperty.get$ref() != null) { processRefProperty(additionalProperty, file); } else if (additionalProperty instanceof ArraySchema) { @@ -125,15 +125,15 @@ public String processRefToExternalSchema(String $ref, RefFormat refFormat) { StringUtils.isNotBlank(arrayProp.get$ref())) { processRefProperty(arrayProp.getItems(), file); } - } else if (additionalProperty.getAdditionalProperties() != null) { - Schema mapProp = additionalProperty; - if (mapProp.getAdditionalProperties().get$ref() != null) { - processRefProperty(mapProp.getAdditionalProperties(), file); + } else if (additionalProperty.getAdditionalProperties() != null && additionalProperty.getAdditionalProperties() instanceof Schema) { + Schema mapProp = (Schema) additionalProperty.getAdditionalProperties(); + if (mapProp.get$ref() != null) { + processRefProperty(mapProp, file); } else if (mapProp.getAdditionalProperties() instanceof ArraySchema && - ((ArraySchema) mapProp.getAdditionalProperties()).getItems() != null && - ((ArraySchema) mapProp.getAdditionalProperties()).getItems().get$ref() != null - && StringUtils.isNotBlank(((ArraySchema) mapProp.getAdditionalProperties()).getItems().get$ref())) { - processRefProperty(((ArraySchema) mapProp.getAdditionalProperties()).getItems(), file); + ((ArraySchema) mapProp).getItems() != null && + ((ArraySchema) mapProp).getItems().get$ref() != null + && StringUtils.isNotBlank(((ArraySchema) mapProp).getItems().get$ref())) { + processRefProperty(((ArraySchema) mapProp).getItems(), file); } } diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java index 4075ef9259..21b9c4867f 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java @@ -59,13 +59,17 @@ public void processSchemaType(Schema schema){ } - private void processAdditionalProperties(Schema schema) { - - if (schema.getAdditionalProperties() != null){ - if(schema.getAdditionalProperties().get$ref() != null){ - processReferenceSchema(schema.getAdditionalProperties()); - }else{ - processSchemaType(schema.getAdditionalProperties()); + private void processAdditionalProperties(Object additionalProperties) { + + if (additionalProperties instanceof Schema) { + Schema schema = (Schema) additionalProperties; + if (schema.getAdditionalProperties() != null && schema.getAdditionalProperties() instanceof Schema) { + Schema additionalPropertiesSchema = (Schema) schema.getAdditionalProperties(); + if (additionalPropertiesSchema.get$ref() != null) { + processReferenceSchema(additionalPropertiesSchema); + } else { + processSchemaType(additionalPropertiesSchema); + } } } } diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/InlineModelResolver.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/InlineModelResolver.java index 3e15efd19d..be93c1d425 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/InlineModelResolver.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/InlineModelResolver.java @@ -180,9 +180,9 @@ public void flatten(OpenAPI openAPI) { } } } - } else if (property.getAdditionalProperties() != null) { + } else if (property.getAdditionalProperties() != null && property.getAdditionalProperties() instanceof Schema) { - Schema innerProperty = property.getAdditionalProperties(); + Schema innerProperty = (Schema) property.getAdditionalProperties(); if (innerProperty instanceof ObjectSchema) { ObjectSchema op = (ObjectSchema) innerProperty; if (op.getProperties() != null && op.getProperties().size() > 0) { @@ -365,8 +365,8 @@ public void flattenProperties(Map properties, String path) { } } } - } else if (property.getAdditionalProperties() != null) { - Schema inner = property.getAdditionalProperties(); + } else if (property.getAdditionalProperties() != null && property.getAdditionalProperties() instanceof Schema) { + Schema inner = (Schema) property.getAdditionalProperties(); if (inner instanceof ObjectSchema) { ObjectSchema op = (ObjectSchema) inner; @@ -454,11 +454,13 @@ public Schema modelFromProperty(Schema object, @SuppressWarnings("unused") Strin if (obj != null) { example = obj.toString(); } - ArraySchema model = new ArraySchema(); model.setDescription(description); model.setExample(example); - model.setItems(object.getAdditionalProperties()); + if (object.getAdditionalProperties() != null && object.getAdditionalProperties() instanceof Schema) { + model.setItems((Schema) object.getAdditionalProperties()); + } + return model; } 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 fc97af5443..609c687162 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 @@ -1983,11 +1983,22 @@ public Schema getSchema(ObjectNode node, String location, ParseResult result){ schema.setProperties(properties); } - ObjectNode additionalPropertiesObj = getObject("additionalProperties", node, false, location, result); - if(additionalPropertiesObj != null) { - Schema additionalProperties = getSchema(additionalPropertiesObj, location, result); - if(additionalProperties != null) { - schema.setAdditionalProperties(additionalProperties); + + if (node.get("additionalProperties") != null) { + if (node.get("additionalProperties").getNodeType().equals(JsonNodeType.OBJECT)) { + ObjectNode additionalPropertiesObj = getObject("additionalProperties", node, false, location, result); + if (additionalPropertiesObj != null) { + Schema additionalProperties = getSchema(additionalPropertiesObj, location, result); + if (additionalProperties != null) { + schema.setAdditionalProperties(additionalProperties); + } + } + } else if (node.get("additionalProperties").getNodeType().equals(JsonNodeType.BOOLEAN)) { + Boolean additionalProperties = getBoolean("additionalProperties", node, false, location, result); + if (additionalProperties != null) { + schema.setAdditionalProperties(additionalProperties); + } + } } value = getString("description",node,false,location,result); diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java index b503cac72e..9b97986fcc 100644 --- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java @@ -198,7 +198,9 @@ public void componentsResolver(@Injectable final List auths) assertEquals(schemas.get("OrderRef").getNot().get$ref(), "#/components/schemas/Category"); //Schema additionalProperties - assertEquals(schemas.get("OrderRef").getAdditionalProperties().get$ref(), "#/components/schemas/User_3"); + assertTrue(schemas.get("OrderRef").getAdditionalProperties() instanceof Schema); + Schema additionalProperties = (Schema) schemas.get("OrderRef").getAdditionalProperties(); + assertEquals(additionalProperties.get$ref(), "#/components/schemas/User_3"); //AllOfSchema ComposedSchema extended = (ComposedSchema) schemas.get("ExtendedErrorModel"); diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java index eb23d07c69..0383c45a6a 100644 --- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java @@ -26,12 +26,14 @@ import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Random; +import java.util.stream.Collectors; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.get; import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching; -import static org.testng.AssertJUnit.assertNotNull; -import static org.testng.AssertJUnit.assertTrue; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; public class OpenAPIV3ParserTest { @@ -169,8 +171,8 @@ public void test30(@Injectable final List auths) throws Exce Assert.assertNotNull(result); Assert.assertNotNull(result.getOpenAPI()); - Assert.assertEquals(result.getOpenAPI().getOpenapi(), "3.0.1"); - Assert.assertEquals(result.getOpenAPI().getComponents().getSchemas().get("OrderRef").getType(),"object"); + assertEquals(result.getOpenAPI().getOpenapi(), "3.0.1"); + assertEquals(result.getOpenAPI().getComponents().getSchemas().get("OrderRef").getType(),"object"); } @Test @@ -187,8 +189,8 @@ public void testResolveFully(@Injectable final List auths) t Assert.assertNotNull(result); Assert.assertNotNull(result.getOpenAPI()); - Assert.assertEquals(result.getOpenAPI().getOpenapi(), "3.0.1"); - Assert.assertEquals(result.getOpenAPI().getComponents().getSchemas().get("OrderRef").getType(),"object"); + assertEquals(result.getOpenAPI().getOpenapi(), "3.0.1"); + assertEquals(result.getOpenAPI().getComponents().getSchemas().get("OrderRef").getType(),"object"); } @Test @@ -219,8 +221,8 @@ public void testResolveFullyExample(@Injectable final List a Assert.assertNotNull(result.getOpenAPI()); Components components = result.getOpenAPI().getComponents(); ApiResponse response = result.getOpenAPI().getPaths().get("/mockResponses/objectMultipleExamples").getGet().getResponses().get("200"); - Assert.assertEquals(response.getContent().get("application/json").getExamples().get("ArthurDent"), components.getExamples().get("Arthur")); - Assert.assertEquals(response.getContent().get("application/xml").getExamples().get("Trillian"), components.getExamples().get("Trillian")); + assertEquals(response.getContent().get("application/json").getExamples().get("ArthurDent"), components.getExamples().get("Arthur")); + assertEquals(response.getContent().get("application/xml").getExamples().get("Trillian"), components.getExamples().get("Trillian")); } @Test @@ -262,8 +264,8 @@ public void test30NoOptions(@Injectable final List auths) th Assert.assertNotNull(result); Assert.assertNotNull(result.getOpenAPI()); - Assert.assertEquals(result.getOpenAPI().getOpenapi(), "3.0.1"); - Assert.assertEquals(result.getOpenAPI().getComponents().getSchemas().get("OrderRef").getType(),"object"); + assertEquals(result.getOpenAPI().getOpenapi(), "3.0.1"); + assertEquals(result.getOpenAPI().getComponents().getSchemas().get("OrderRef").getType(),"object"); } @Test @@ -274,7 +276,7 @@ public void testShellMethod(@Injectable final List auths){ OpenAPI openAPI = new OpenAPIV3Parser().read(url); Assert.assertNotNull(openAPI); - Assert.assertEquals(openAPI.getOpenapi(), "3.0.1"); + assertEquals(openAPI.getOpenapi(), "3.0.1"); } @Test diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/InlineModelResolverTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/InlineModelResolverTest.java index 2b14575a23..88759a8560 100644 --- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/InlineModelResolverTest.java +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/util/InlineModelResolverTest.java @@ -1107,8 +1107,9 @@ public void testArbitraryObjectResponseMapInline() { Schema property = response.getContent().get("*/*").getSchema(); assertTrue(property.getAdditionalProperties() != null); + assertTrue(property.getAdditionalProperties() instanceof Schema); assertTrue(openAPI.getComponents().getSchemas() == null); - Schema inlineProp = property.getAdditionalProperties(); + Schema inlineProp = (Schema)property.getAdditionalProperties(); assertTrue(inlineProp instanceof ObjectSchema); ObjectSchema op = (ObjectSchema) inlineProp; assertNull(op.getProperties()); 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 a370c64665..f7931dcf4f 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 @@ -1164,7 +1164,9 @@ public void readComponentsObject(JsonNode rootNode) throws Exception { Assert.assertEquals(component.getSchemas().get("ApiResponse").getRequired().get(0),"name"); Assert.assertEquals(component.getSchemas().get("Order").getType(),"object"); Assert.assertEquals(component.getSchemas().get("Order").getNot().getType(),"integer"); - Assert.assertEquals(component.getSchemas().get("Order").getAdditionalProperties().getType(),"integer"); + assertTrue(component.getSchemas().get("Order").getAdditionalProperties() instanceof Schema); + Schema additionalProperties = (Schema) component.getSchemas().get("Order").getAdditionalProperties(); + Assert.assertEquals(additionalProperties.getType(),"integer"); Schema schema = (Schema) component.getSchemas().get("Order").getProperties().get("status"); diff --git a/modules/swagger-parser-v3/src/test/resources/booleanAdditionalProperties.json b/modules/swagger-parser-v3/src/test/resources/booleanAdditionalProperties.json new file mode 100644 index 0000000000..76ff9e9048 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/booleanAdditionalProperties.json @@ -0,0 +1,71 @@ +{"openapi": "3.0.0", + "info": { + "version": "1.0.0", + "title": "Boolean `additionProperties` example" + }, + "paths": { + "/someResource": { + "get": { + "responses": { + "200": { + "description": "Fetching of some resource successful", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/someObject" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "someObject": { + "type": "object", + "required": [ + "innerObject" + ], + "additionalProperties": { + "type": "string" + }, + "properties": { + "innerObject": { + "type": "object", + "additionalProperties": false, + "properties": { + "stringProperty": { + "type": "string" + }, + "objectProperty": { + "type": "object", + "additionalProperties": false, + "properties": { + "firstPossibleProperty": { + "type": "integer" + }, + "secondPossibleProperty": { + "type": "string" + } + } + }, + "objectAdditionalProperties": { + "type": "object", + "properties": { + "integerProperty": { + "type": "integer" + } + }, + "additionalProperties": { + "type": "string" + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 266499aafc..8c85472272 100644 --- a/pom.xml +++ b/pom.xml @@ -261,6 +261,5 @@ 3.2.1 2.9.1 - - +