From f74a044d16e2d4f37f2194230b777dad782dd88d Mon Sep 17 00:00:00 2001 From: gracekarina Date: Mon, 15 Jan 2018 17:29:18 -0500 Subject: [PATCH 1/2] fixing allOf external resolving refs #628 --- .../processors/ExternalRefProcessor.java | 55 ++++++++++++++----- .../v3/parser/test/OpenAPIV3ParserTest.java | 16 ++++++ .../src/test/resources/allOfRef.yaml | 28 ++++++++++ .../src/test/resources/refComponents.yaml | 39 +++++++++++++ 4 files changed, 123 insertions(+), 15 deletions(-) create mode 100644 modules/swagger-parser-v3/src/test/resources/allOfRef.yaml create mode 100644 modules/swagger-parser-v3/src/test/resources/refComponents.yaml 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 17dbed68cd..9989c05a32 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 @@ -8,6 +8,7 @@ import io.swagger.v3.oas.models.headers.Header; import io.swagger.v3.oas.models.links.Link; import io.swagger.v3.oas.models.media.ArraySchema; +import io.swagger.v3.oas.models.media.ComposedSchema; import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.parameters.Parameter; import io.swagger.v3.oas.models.parameters.RequestBody; @@ -83,11 +84,35 @@ public String processRefToExternalSchema(String $ref, RefFormat refFormat) { String file = $ref.split("#/")[0]; if (schema.get$ref() != null) { - RefFormat format = computeRefFormat(schema.get$ref()); - if (isAnExternalRefFormat(format)) { - schema.set$ref(processRefToExternalSchema(schema.get$ref(), format)); - } else { - processRefToExternalSchema(file + schema.get$ref(), RefFormat.RELATIVE); + processRefSchema(schema,file); + } + + if(schema instanceof ComposedSchema){ + ComposedSchema composedSchema = (ComposedSchema) schema; + if (composedSchema.getAllOf() != null){ + for(Schema item : composedSchema.getAllOf()){ + if (item.get$ref() != null){ + processRefSchema(item,file); + } + } + + }else if (composedSchema.getOneOf() != null){ + for(Schema item : composedSchema.getOneOf()){ + if (item.get$ref() != null){ + if (item.get$ref() != null){ + processRefSchema(item,file); + } + } + } + }else if (composedSchema.getAnyOf() != null){ + for(Schema item : composedSchema.getAnyOf()){ + if (item.get$ref() != null){ + if (item.get$ref() != null){ + processRefSchema(item,file); + } + } + } + } } //Loop the properties and recursively call this method; @@ -95,22 +120,22 @@ public String processRefToExternalSchema(String $ref, RefFormat refFormat) { if (subProps != null) { for (Map.Entry prop : subProps.entrySet()) { if (prop.getValue().get$ref() != null) { - processRefProperty(prop.getValue(), file); + processRefSchema(prop.getValue(), file); } else if (prop.getValue() instanceof ArraySchema) { ArraySchema arrayProp = (ArraySchema) prop.getValue(); if (arrayProp.getItems() != null && arrayProp.getItems().get$ref() != null && StringUtils.isNotBlank(arrayProp.get$ref())) { - processRefProperty(arrayProp.getItems(), file); + processRefSchema(arrayProp.getItems(), 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); + processRefSchema(mapProp, file); } else if (mapProp.getAdditionalProperties() instanceof ArraySchema && ((ArraySchema) mapProp).getItems()!= null && ((ArraySchema) mapProp).getItems().get$ref() != null && StringUtils.isNotBlank(((ArraySchema) mapProp).getItems().get$ref())) { - processRefProperty(((ArraySchema) mapProp.getAdditionalProperties()).getItems(), file); + processRefSchema(((ArraySchema) mapProp.getAdditionalProperties()).getItems(), file); } } } @@ -118,29 +143,29 @@ public String processRefToExternalSchema(String $ref, RefFormat refFormat) { if(schema.getAdditionalProperties() != null && schema.getAdditionalProperties() instanceof Schema){ Schema additionalProperty = (Schema) schema.getAdditionalProperties(); if (additionalProperty.get$ref() != null) { - processRefProperty(additionalProperty, file); + processRefSchema(additionalProperty, file); } else if (additionalProperty instanceof ArraySchema) { ArraySchema arrayProp = (ArraySchema) additionalProperty; if (arrayProp.getItems() != null && arrayProp.getItems().get$ref() != null && StringUtils.isNotBlank(arrayProp.get$ref())) { - processRefProperty(arrayProp.getItems(), file); + processRefSchema(arrayProp.getItems(), file); } } else if (additionalProperty.getAdditionalProperties() != null && additionalProperty.getAdditionalProperties() instanceof Schema) { Schema mapProp = (Schema) additionalProperty.getAdditionalProperties(); if (mapProp.get$ref() != null) { - processRefProperty(mapProp, file); + processRefSchema(mapProp, file); } else if (mapProp.getAdditionalProperties() instanceof ArraySchema && ((ArraySchema) mapProp).getItems() != null && ((ArraySchema) mapProp).getItems().get$ref() != null && StringUtils.isNotBlank(((ArraySchema) mapProp).getItems().get$ref())) { - processRefProperty(((ArraySchema) mapProp).getItems(), file); + processRefSchema(((ArraySchema) mapProp).getItems(), file); } } } if (schema instanceof ArraySchema && ((ArraySchema) schema).getItems() != null && ((ArraySchema) schema).getItems().get$ref() != null && StringUtils.isNotBlank(((ArraySchema) schema).getItems().get$ref())) { - processRefProperty(((ArraySchema) schema).getItems(), file); + processRefSchema(((ArraySchema) schema).getItems(), file); } } @@ -614,7 +639,7 @@ public String processRefToExternalCallback(String $ref, RefFormat refFormat) { } - private void processRefProperty(Schema subRef, String externalFile) { + private void processRefSchema(Schema subRef, String externalFile) { RefFormat format = computeRefFormat(subRef.get$ref()); if (isAnExternalRefFormat(format)) { String $ref = constructRef(subRef, externalFile); 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 0383c45a6a..ac6ef7972f 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 @@ -4,6 +4,7 @@ import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.client.WireMock; import com.github.tomakehurst.wiremock.core.WireMockConfiguration; +import io.swagger.v3.core.util.Yaml; import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.media.Schema; @@ -330,6 +331,21 @@ public void testRefAndInlineAllOf(@Injectable final List aut Assert.assertTrue(openAPI.getPaths().get("/refToAllOf").getGet().getResponses().get("200").getContent().get("application/json").getSchema().getProperties().size() == 2); } + @Test + public void testAllOfRef(@Injectable final List auths) throws Exception { + ParseOptions options = new ParseOptions(); + options.setResolve(true); + OpenAPI openAPI = new OpenAPIV3Parser().read("src/test/resources/allOfRef.yaml",auths,options); + + Assert.assertNotNull(openAPI); + + Assert.assertTrue(openAPI.getComponents().getSchemas().size() == 3); + Assert.assertNotNull(openAPI.getComponents().getSchemas().get("Cat")); + Assert.assertNotNull(openAPI.getComponents().getSchemas().get("Dog")); + Assert.assertNotNull(openAPI.getComponents().getSchemas().get("Pet")); + + } + private static int getDynamicPort() { return new Random().ints(10000, 20000).findFirst().getAsInt(); diff --git a/modules/swagger-parser-v3/src/test/resources/allOfRef.yaml b/modules/swagger-parser-v3/src/test/resources/allOfRef.yaml new file mode 100644 index 0000000000..221fb08ca7 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/allOfRef.yaml @@ -0,0 +1,28 @@ +openapi: 3.0.0 +info: + version: 0.0.0 + title: oneOf and anyOf + +paths: + /oneOf: + get: + responses: + '200': + description: One of Cat or Dog + content: + application/json: + schema: + oneOf: + - $ref: './refComponents.yaml#/components/schemas/Cat' + - $ref: './refComponents.yaml#/components/schemas/Dog' + /anyOf: + get: + responses: + '200': + description: Any of Cat or Dog + content: + application/json: + schema: + anyOf: + - $ref: './refComponents.yaml#/components/schemas/Cat' + - $ref: './refComponents.yaml#/components/schemas/Dog' \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/refComponents.yaml b/modules/swagger-parser-v3/src/test/resources/refComponents.yaml new file mode 100644 index 0000000000..c3b63d4c52 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/refComponents.yaml @@ -0,0 +1,39 @@ +openapi: 3.0.0 +info: + version: 0.0.0 + title: apa + +components: + schemas: + Pet: + required: + - name + - petType + properties: + name: + type: string + petType: + type: string + Cat: + allOf: + - $ref: '#/components/schemas/Pet' + - type: object + properties: + huntingSkill: + type: string + default: lazy + enum: + - lazy + - aggressive + required: + - huntingSkill + Dog: + allOf: + - $ref: '#/components/schemas/Pet' + - type: object + properties: + packSize: + description: The size of the pack the dog is from + type: integer + required: + - packSize \ No newline at end of file From 4c52668bf0ed4e5dfa495997693f1f0a2559e35f Mon Sep 17 00:00:00 2001 From: gracekarina Date: Wed, 17 Jan 2018 08:20:56 -0500 Subject: [PATCH 2/2] adding more tests refs swagger-api/swagger-parser#628 --- .../v3/parser/test/OpenAPIV3ParserTest.java | 8 ++++--- .../{allOfRef.yaml => composedSchemaRef.yaml} | 4 +++- .../src/test/resources/refComponents.yaml | 23 +++++++++++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) rename modules/swagger-parser-v3/src/test/resources/{allOfRef.yaml => composedSchemaRef.yaml} (82%) 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 ac6ef7972f..5fad515409 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 @@ -332,17 +332,19 @@ public void testRefAndInlineAllOf(@Injectable final List aut } @Test - public void testAllOfRef(@Injectable final List auths) throws Exception { + public void testComposedRefResolvingIssue628(@Injectable final List auths) throws Exception { ParseOptions options = new ParseOptions(); options.setResolve(true); - OpenAPI openAPI = new OpenAPIV3Parser().read("src/test/resources/allOfRef.yaml",auths,options); + OpenAPI openAPI = new OpenAPIV3Parser().read("src/test/resources/composedSchemaRef.yaml",auths,options); Assert.assertNotNull(openAPI); - Assert.assertTrue(openAPI.getComponents().getSchemas().size() == 3); + Assert.assertTrue(openAPI.getComponents().getSchemas().size() == 5); Assert.assertNotNull(openAPI.getComponents().getSchemas().get("Cat")); Assert.assertNotNull(openAPI.getComponents().getSchemas().get("Dog")); Assert.assertNotNull(openAPI.getComponents().getSchemas().get("Pet")); + Assert.assertNotNull(openAPI.getComponents().getSchemas().get("Lion")); + Assert.assertNotNull(openAPI.getComponents().getSchemas().get("Bear")); } diff --git a/modules/swagger-parser-v3/src/test/resources/allOfRef.yaml b/modules/swagger-parser-v3/src/test/resources/composedSchemaRef.yaml similarity index 82% rename from modules/swagger-parser-v3/src/test/resources/allOfRef.yaml rename to modules/swagger-parser-v3/src/test/resources/composedSchemaRef.yaml index 221fb08ca7..e241088922 100644 --- a/modules/swagger-parser-v3/src/test/resources/allOfRef.yaml +++ b/modules/swagger-parser-v3/src/test/resources/composedSchemaRef.yaml @@ -15,6 +15,7 @@ paths: oneOf: - $ref: './refComponents.yaml#/components/schemas/Cat' - $ref: './refComponents.yaml#/components/schemas/Dog' + - $ref: './refComponents.yaml#/components/schemas/Lion' /anyOf: get: responses: @@ -25,4 +26,5 @@ paths: schema: anyOf: - $ref: './refComponents.yaml#/components/schemas/Cat' - - $ref: './refComponents.yaml#/components/schemas/Dog' \ No newline at end of file + - $ref: './refComponents.yaml#/components/schemas/Dog' + - $ref: './refComponents.yaml#/components/schemas/Bear' \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/refComponents.yaml b/modules/swagger-parser-v3/src/test/resources/refComponents.yaml index c3b63d4c52..e76ddbc8b7 100644 --- a/modules/swagger-parser-v3/src/test/resources/refComponents.yaml +++ b/modules/swagger-parser-v3/src/test/resources/refComponents.yaml @@ -29,6 +29,29 @@ components: - huntingSkill Dog: allOf: + - $ref: '#/components/schemas/Pet' + - type: object + properties: + packSize: + description: The size of the pack the dog is from + type: integer + required: + - packSize + Lion: + oneOf: + - $ref: '#/components/schemas/Pet' + - type: object + properties: + huntingSkill: + type: string + default: lazy + enum: + - lazy + - aggressive + required: + - huntingSkill + Bear: + anyOf: - $ref: '#/components/schemas/Pet' - type: object properties: