From 96241cb75bea0fa6a6862cea8f326aa7ba46bd63 Mon Sep 17 00:00:00 2001 From: chimmi <3124852+chimmi@users.noreply.github.com> Date: Sat, 30 Mar 2024 15:11:00 +0300 Subject: [PATCH] Issue 2071. Correctly handle external refs in array items composed schemas --- .../processors/ExternalRefProcessor.java | 71 +++++++++++-------- .../processors/ExternalRefProcessorTest.java | 20 ++++++ .../resources/issue-2071/definitions.yaml | 25 +++++++ .../test/resources/issue-2071/openapi.yaml | 21 ++++++ 4 files changed, 106 insertions(+), 31 deletions(-) create mode 100644 modules/swagger-parser-v3/src/test/resources/issue-2071/definitions.yaml create mode 100644 modules/swagger-parser-v3/src/test/resources/issue-2071/openapi.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 c62f5ef771..de955cef71 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 @@ -147,36 +147,7 @@ public String processRefToExternalSchema(String $ref, RefFormat refFormat) { 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{ - processSchema(item, file); - } - } - - }if (composedSchema.getOneOf() != null){ - for(Schema item : composedSchema.getOneOf()){ - if (item.get$ref() != null){ - if (item.get$ref() != null){ - processRefSchema(item,file); - }else{ - processSchema(item, file); - } - } - } - }if (composedSchema.getAnyOf() != null){ - for(Schema item : composedSchema.getAnyOf()){ - if (item.get$ref() != null){ - if (item.get$ref() != null){ - processRefSchema(item,file); - }else{ - processSchema(item, file); - } - } - } - } + processComposedSchema(composedSchema, file); } //Loop the properties and recursively call this method; Map subProps = schema.getProperties(); @@ -212,14 +183,52 @@ public String processRefToExternalSchema(String $ref, RefFormat refFormat) { ArraySchema arraySchema = (ArraySchema) schema; if (StringUtils.isNotBlank(arraySchema.getItems().get$ref())) { processRefSchema(((ArraySchema) schema).getItems(), file); + } else if (arraySchema.getItems() instanceof ComposedSchema) { + ComposedSchema composedSchema = (ComposedSchema) arraySchema.getItems(); + processComposedSchema(composedSchema, file); } else { - processProperties(arraySchema.getItems().getProperties() ,file); + processProperties(arraySchema.getItems().getProperties(), file); } } } return newRef; } + private void processComposedSchema(ComposedSchema composedSchema, String file) { + if (composedSchema.getAllOf() != null) { + for (Schema item : composedSchema.getAllOf()) { + if (item.get$ref() != null) { + processRefSchema(item, file); + } else { + processSchema(item, file); + } + } + + } + if (composedSchema.getOneOf() != null) { + for (Schema item : composedSchema.getOneOf()) { + if (item.get$ref() != null) { + if (item.get$ref() != null) { + processRefSchema(item, file); + } else { + processSchema(item, file); + } + } + } + } + if (composedSchema.getAnyOf() != null) { + for (Schema item : composedSchema.getAnyOf()) { + if (item.get$ref() != null) { + if (item.get$ref() != null) { + processRefSchema(item, file); + } else { + processSchema(item, file); + } + } + } + } + } + private void processSchema(Schema property, String file) { if (property != null) { if (StringUtils.isNotBlank(property.get$ref())) { diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/processors/ExternalRefProcessorTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/processors/ExternalRefProcessorTest.java index 218f97571a..b83feee3e4 100644 --- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/processors/ExternalRefProcessorTest.java +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/processors/ExternalRefProcessorTest.java @@ -5,14 +5,18 @@ import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.media.StringSchema; +import io.swagger.v3.parser.OpenAPIV3Parser; import io.swagger.v3.parser.ResolverCache; import io.swagger.v3.parser.core.models.AuthorizationValue; +import io.swagger.v3.parser.core.models.ParseOptions; +import io.swagger.v3.parser.core.models.SwaggerParseResult; import io.swagger.v3.parser.models.RefFormat; import io.swagger.v3.parser.util.RemoteUrl; import mockit.Expectations; import mockit.Injectable; import mockit.Mocked; import mockit.Expectations; +import org.testng.Assert; import org.testng.annotations.Test; import java.util.ArrayList; @@ -23,6 +27,7 @@ import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import static org.testng.Assert.assertEquals; @@ -206,4 +211,19 @@ public void testRelativeRefIncludingUrlRef() is("./relative-with-url/relative-with-local.yaml#/relative-same-file") ); } + + @Test + public void testHandleComposedSchemasInArrayItems() { + OpenAPIV3Parser openApiParser = new OpenAPIV3Parser(); + ParseOptions options = new ParseOptions(); + options.setResolve(true); + SwaggerParseResult parseResult = openApiParser.readLocation("issue-2071/openapi.yaml", null, options); + OpenAPI openAPI = parseResult.getOpenAPI(); + + assertEquals(openAPI.getComponents().getSchemas().size(), 3); + assertTrue(openAPI.getComponents().getSchemas().containsKey("Response")); + assertTrue(openAPI.getComponents().getSchemas().containsKey("ProductRow")); + assertTrue(openAPI.getComponents().getSchemas().containsKey("ProductsRowType")); + } + } diff --git a/modules/swagger-parser-v3/src/test/resources/issue-2071/definitions.yaml b/modules/swagger-parser-v3/src/test/resources/issue-2071/definitions.yaml new file mode 100644 index 0000000000..25a85f75b5 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/issue-2071/definitions.yaml @@ -0,0 +1,25 @@ +components: + schemas: + Response: + type: array + items: + oneOf: + - $ref: '#/components/schemas/ProductRow' + discriminator: + propertyName: type + mapping: + 'product': '#/components/schemas/ProductRow' + ProductRow: + type: object + additionalProperties: false + required: + - type + properties: + type: + $ref: '#/components/schemas/ProductsRowType' + payload: + type: string + ProductsRowType: + type: string + enum: + - product diff --git a/modules/swagger-parser-v3/src/test/resources/issue-2071/openapi.yaml b/modules/swagger-parser-v3/src/test/resources/issue-2071/openapi.yaml new file mode 100644 index 0000000000..d457a1dd94 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/issue-2071/openapi.yaml @@ -0,0 +1,21 @@ +openapi: 3.0.1 +info: + title: API + description: API + version: LATEST +paths: + /test-path: + post: + requestBody: + required: true + content: + text/plain: + schema: + type: string + responses: + 200: + description: OK + content: + application/json: + schema: + $ref: 'definitions.yaml#/components/schemas/Response'