From de210108cfbf5000b29090ea7a23fa64ae5456af Mon Sep 17 00:00:00 2001 From: gracekarina Date: Thu, 4 Jun 2020 13:39:34 -0500 Subject: [PATCH] fix for issue #1385 --- .../v3/parser/util/InlineModelResolver.java | 146 +++++++++--------- .../v3/parser/test/OpenAPIV3ParserTest.java | 21 +++ .../parser/util/InlineModelResolverTest.java | 2 +- .../additionalPropertiesFlatten.yaml | 29 ++++ .../src/test/resources/flattenArrayItems.yaml | 20 +++ 5 files changed, 140 insertions(+), 78 deletions(-) create mode 100644 modules/swagger-parser-v3/src/test/resources/additionalPropertiesFlatten.yaml 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 c45597549a..a8c704c3ce 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 @@ -96,7 +96,6 @@ public void flatten(OpenAPI openAPI) { } else if (model instanceof ArraySchema) { ArraySchema am = (ArraySchema) model; Schema inner = am.getItems(); - if (isObjectSchema(inner)) { if (inner.getProperties() != null && inner.getProperties().size() > 0) { flattenProperties(inner.getProperties(), pathname); @@ -186,7 +185,7 @@ public void flatten(OpenAPI openAPI) { if (media.getSchema() != null) { Schema mediaSchema = media.getSchema(); if (isObjectSchema(mediaSchema)) { - if (mediaSchema.getProperties() != null && mediaSchema.getProperties().size() > 0) { + if (mediaSchema.getProperties() != null && mediaSchema.getProperties().size() > 0 || mediaSchema instanceof ComposedSchema) { String modelName = resolveModelName(mediaSchema.getTitle(), "inline_response_" + key); String existing = matchGenerated(mediaSchema); if (existing != null) { @@ -196,63 +195,31 @@ public void flatten(OpenAPI openAPI) { addGenerated(modelName, mediaSchema); openAPI.getComponents().addSchemas(modelName, mediaSchema); } - }else if (mediaSchema instanceof ComposedSchema) { - String modelName = resolveModelName(mediaSchema.getTitle(), "inline_response_" + key); - String existing = matchGenerated(mediaSchema); - if (existing != null) { - media.setSchema(this.makeRefProperty(existing, mediaSchema)); - } else { - media.setSchema(this.makeRefProperty(modelName, mediaSchema)); - addGenerated(modelName, mediaSchema); - openAPI.getComponents().addSchemas(modelName, mediaSchema); + }else if (mediaSchema.getAdditionalProperties() != null && !(mediaSchema.getAdditionalProperties() instanceof Boolean)) { + Schema innerProperty = (Schema) mediaSchema.getAdditionalProperties(); + if (isObjectSchema(innerProperty)) { + key = "inline_response_map" + key; + flattenMapSchema(innerProperty, key, pathname, mediaSchema); + } else if (innerProperty instanceof ArraySchema) { + ArraySchema arraySchema = (ArraySchema) innerProperty; + Schema inner = arraySchema.getItems(); + if (isObjectSchema(inner)) { + key = "inline_response_map_items" + key; + flattenMapSchema(inner,key,pathname,mediaSchema); + } } } - }else if (mediaSchema instanceof ArraySchema) { ArraySchema ap = (ArraySchema) mediaSchema; Schema inner = ap.getItems(); - if (isObjectSchema(inner)) { - if (inner.getProperties() != null && inner.getProperties().size() > 0) { - flattenProperties(inner.getProperties(), pathname); - String modelName = resolveModelName(inner.getTitle(), - "inline_response_" + key); - String existing = matchGenerated(inner); - if (existing != null) { - ap.setItems(this.makeRefProperty(existing, inner)); - } else { - ap.setItems(this.makeRefProperty(modelName, inner)); - addGenerated(modelName, inner); - openAPI.getComponents().addSchemas(modelName, inner); - } - }else if (inner instanceof ComposedSchema && this.flattenComposedSchemas){ - flattenComposedSchema(inner,key); - if (inner.get$ref() == null) { - String modelName = resolveModelName(inner.getTitle(), "inline_response_items" + key); - ap.setItems(this.makeRefProperty(modelName, inner)); - addGenerated(modelName, inner); - openAPI.getComponents().addSchemas(modelName, inner); - } - } + flattenArraySchema(inner, key, pathname, ap); } - - } else if (mediaSchema.getAdditionalProperties() != null && mediaSchema.getAdditionalProperties() instanceof Schema) { - + } else if (mediaSchema.getAdditionalProperties() != null && !(mediaSchema.getAdditionalProperties() instanceof Boolean)) { Schema innerProperty = (Schema) mediaSchema.getAdditionalProperties(); if (isObjectSchema(innerProperty)) { - if (innerProperty.getProperties() != null && innerProperty.getProperties().size() > 0) { - flattenProperties(innerProperty.getProperties(), pathname); - String modelName = resolveModelName(innerProperty.getTitle(), - "inline_response_" + key); - String existing = matchGenerated(innerProperty); - if (existing != null) { - mediaSchema.setAdditionalProperties(new Schema().$ref(existing)); - } else { - mediaSchema.setAdditionalProperties(new Schema().$ref(modelName)); - addGenerated(modelName, innerProperty); - openAPI.getComponents().addSchemas(modelName, innerProperty); - } - } + key = "inline_response_map" + key; + flattenMapSchema(innerProperty, key, pathname, mediaSchema); } } } @@ -301,7 +268,6 @@ public void flatten(OpenAPI openAPI) { } else if (model instanceof ComposedSchema) { ComposedSchema composedSchema = (ComposedSchema) model; String inlineModelName = ""; - List list = null; if (composedSchema.getAllOf() != null) { list = composedSchema.getAllOf(); @@ -334,6 +300,54 @@ public void flatten(OpenAPI openAPI) { } } + private void flattenArraySchema(Schema inner, String key, String pathname, ArraySchema ap) { + if (inner.getProperties() != null && inner.getProperties().size() > 0) { + flattenProperties(inner.getProperties(), pathname); + key = "inline_response_" + key; + String modelName = resolveModelName(inner.getTitle(), key); + String existing = matchGenerated(inner); + if (existing != null) { + ap.setItems(this.makeRefProperty(existing, inner)); + } else { + ap.setItems(this.makeRefProperty(modelName, inner)); + addGenerated(modelName, inner); + openAPI.getComponents().addSchemas(modelName, inner); + } + }else if (inner instanceof ComposedSchema && this.flattenComposedSchemas){ + flattenComposedSchema(inner,key); + if (inner.get$ref() == null) { + key = "inline_response_items" + key; + String modelName = resolveModelName(inner.getTitle(), key ); + ap.setItems(this.makeRefProperty(modelName, inner)); + addGenerated(modelName, inner); + openAPI.getComponents().addSchemas(modelName, inner); + } + } + } + + + private void flattenMapSchema(Schema innerProperty, String key, String pathname, Schema mediaSchema) { + if (innerProperty.getProperties() != null && innerProperty.getProperties().size() > 0) { + flattenProperties(innerProperty.getProperties(), pathname); + String modelName = resolveModelName(innerProperty.getTitle(), key); + String existing = matchGenerated(innerProperty); + if (existing != null) { + mediaSchema.setAdditionalProperties(new Schema().$ref(existing)); + } else { + mediaSchema.setAdditionalProperties(new Schema().$ref(modelName)); + addGenerated(modelName, innerProperty); + openAPI.getComponents().addSchemas(modelName, innerProperty); + } + }else if (innerProperty instanceof ComposedSchema && this.flattenComposedSchemas){ + flattenComposedSchema(innerProperty,key); + if (innerProperty.get$ref() == null) { + String modelName = resolveModelName(innerProperty.getTitle(), key); + mediaSchema.setAdditionalProperties(new Schema().$ref(modelName)); + addGenerated(modelName, innerProperty); + openAPI.getComponents().addSchemas(modelName, innerProperty); + } + } + } /** @@ -418,12 +432,9 @@ public void flattenProperties(Map properties, String path) { for (String key : properties.keySet()) { Schema property = properties.get(key); if (isObjectSchema(property) && property.getProperties() != null && property.getProperties().size() > 0) { - String modelName = resolveModelName(property.getTitle(), path + "_" + key); Schema model = createModelFromProperty(property, modelName); - String existing = matchGenerated(model); - if (existing != null) { propsToUpdate.put(key, new Schema().$ref(existing)); } else { @@ -435,7 +446,6 @@ public void flattenProperties(Map properties, String path) { } else if (property instanceof ArraySchema) { ArraySchema ap = (ArraySchema) property; Schema inner = ap.getItems(); - if (isObjectSchema(inner)) { if (inner.getProperties() != null && inner.getProperties().size() > 0) { flattenProperties(inner.getProperties(), path); @@ -449,23 +459,9 @@ public void flattenProperties(Map properties, String path) { addGenerated(modelName, innerModel); openAPI.getComponents().addSchemas(modelName, innerModel); } - }else if (inner instanceof ComposedSchema && this.flattenComposedSchemas){ - ComposedSchema composedSchema = (ComposedSchema) inner; + }else if (inner instanceof ComposedSchema && this.flattenComposedSchemas) { + flattenComposedSchema(inner,key); String modelName = resolveModelName(inner.getTitle(), path + "_" + key); - List list = null; - if (composedSchema.getAllOf() != null) { - list = composedSchema.getAllOf(); - }else if (composedSchema.getAnyOf() != null) { - list = composedSchema.getAnyOf(); - }else if (composedSchema.getOneOf() != null) { - list = composedSchema.getOneOf(); - } - for(int i= 0; i properties, String path) { openAPI.getComponents().addSchemas(modelName, innerModel); } } - } - } else if (property.getAdditionalProperties() != null && property.getAdditionalProperties() instanceof Schema) { + } else if (property.getAdditionalProperties() != null && !(property.getAdditionalProperties() instanceof Boolean)) { Schema inner = (Schema) property.getAdditionalProperties(); - if (isObjectSchema(inner)) { if (inner.getProperties() != null && inner.getProperties().size() > 0) { flattenProperties(inner.getProperties(), path); @@ -623,11 +617,9 @@ public Schema modelFromProperty(Schema object, @SuppressWarnings("unused") Strin ArraySchema model = new ArraySchema(); model.setDescription(description); model.setExample(example); - if (object.getAdditionalProperties() != null && object.getAdditionalProperties() instanceof Schema) { + if (object.getAdditionalProperties() != null && !(object.getAdditionalProperties() instanceof Boolean)) { model.setItems((Schema) object.getAdditionalProperties()); } - - return model; } 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 2843327e2b..2b780b7c63 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 @@ -82,6 +82,27 @@ public class OpenAPIV3ParserTest { protected int serverPort = getDynamicPort(); protected WireMockServer wireMockServer; + + @Test + public void testIssueFlattenAdditionalPropertiesSchemaInlineModelTrue() { + OpenAPIV3Parser openApiParser = new OpenAPIV3Parser(); + ParseOptions options = new ParseOptions(); + options.setResolve(true); + options.setFlatten(true); + options.setFlattenComposedSchemas(true); + options.setCamelCaseFlattenNaming(true); + SwaggerParseResult parseResult = openApiParser.readLocation("additionalPropertiesFlatten.yaml", null, options); + OpenAPI openAPI = parseResult.getOpenAPI(); + + //responses + assertNotNull(openAPI.getComponents().getSchemas().get("Inline_response_map200")); + assertEquals(((ComposedSchema)openAPI.getComponents().getSchemas().get("Inline_response_map200")).getOneOf().get(0).get$ref(),"#/components/schemas/Macaw1"); + assertNotNull(openAPI.getComponents().getSchemas().get("Inline_response_map_items404")); + assertEquals(((ComposedSchema)openAPI.getComponents().getSchemas().get("Inline_response_map_items404")).getAnyOf().get(0).get$ref(),"#/components/schemas/Macaw2"); + + } + + @Test public void testIssueFlattenArraySchemaItemsInlineModelFalse() { OpenAPIV3Parser openApiParser = new OpenAPIV3Parser(); 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 0004b675e2..f306114f2a 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 @@ -951,7 +951,7 @@ public void testInlineMapResponseWithObjectSchema() throws Exception { assertEquals("ext-prop", property.getExtensions().get("x-ext")); assertTrue(openAPI.getComponents().getSchemas().size() == 1); - Schema inline = openAPI.getComponents().getSchemas().get("inline_response_200"); + Schema inline = openAPI.getComponents().getSchemas().get("inline_response_map200"); assertTrue(inline instanceof Schema); assertNotNull(inline.getProperties().get("name")); assertTrue(inline.getProperties().get("name") instanceof StringSchema); diff --git a/modules/swagger-parser-v3/src/test/resources/additionalPropertiesFlatten.yaml b/modules/swagger-parser-v3/src/test/resources/additionalPropertiesFlatten.yaml new file mode 100644 index 0000000000..c1157656e0 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/additionalPropertiesFlatten.yaml @@ -0,0 +1,29 @@ +openapi: 3.0.2 +info: + title: test - OAS3 + version: 1.0.0 +paths: + /responses: + get: + responses: + '200': + description: it works! + content: + application/json: + schema: + additionalProperties: + oneOf: + - "$ref": "#/components/schemas/Macaw1" + - "$ref": "#/components/schemas/Parakeet1" + '404': + description: it works! + content: + application/json: + schema: + additionalProperties: + type: array + items: + anyOf: + - "$ref": "#/components/schemas/Macaw2" + - "$ref": "#/components/schemas/Parakeet2" + diff --git a/modules/swagger-parser-v3/src/test/resources/flattenArrayItems.yaml b/modules/swagger-parser-v3/src/test/resources/flattenArrayItems.yaml index f40156b4b2..5063fa5bdf 100644 --- a/modules/swagger-parser-v3/src/test/resources/flattenArrayItems.yaml +++ b/modules/swagger-parser-v3/src/test/resources/flattenArrayItems.yaml @@ -42,6 +42,26 @@ paths: anyOf: - "$ref": "#/components/schemas/Macaw3" - "$ref": "#/components/schemas/Parakeet3" + '404': + description: it works! + content: + application/json: + schema: + additionalProperties: + oneOf: + - "$ref": "#/components/schemas/Macaw4" + - "$ref": "#/components/schemas/Parakeet4" + '500': + description: it works! + content: + application/json: + schema: + additionalProperties: + type: array + items: + anyOf: + - "$ref": "#/components/schemas/Macaw5" + - "$ref": "#/components/schemas/Parakeet5" /requestBodies: post: requestBody: