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 af3b6aedbc..0ad84145bf 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 @@ -250,7 +250,7 @@ private void processSchema(Schema property, String file) { ComposedSchema composed = (ComposedSchema) property; final Map refMap = Optional.ofNullable(composed.getDiscriminator()) .map(Discriminator::getMapping).orElse(Collections.emptyMap()).entrySet() - .stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey)); + .stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); Map refCache = (!refMap.isEmpty() && (composed.getAnyOf() != null || composed.getOneOf() != null)) ? Stream.of( composed.getAnyOf(), composed.getOneOf() diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/Issue2222Test.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/Issue2222Test.java new file mode 100644 index 0000000000..a6d2665a48 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/Issue2222Test.java @@ -0,0 +1,33 @@ +package io.swagger.v3.parser.test; + +import io.swagger.v3.core.util.Json; +import io.swagger.v3.oas.models.media.Discriminator; +import io.swagger.v3.oas.models.responses.ApiResponse; +import io.swagger.v3.parser.OpenAPIV3Parser; +import io.swagger.v3.parser.core.models.ParseOptions; +import io.swagger.v3.parser.core.models.SwaggerParseResult; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class Issue2222Test { + + @Test + public void shouldMapSameEntitiesToDifferentDiscriminatorValues() { + ParseOptions options = new ParseOptions(); + options.setResolveFully(true); + SwaggerParseResult result = new OpenAPIV3Parser().readLocation("issue-2222/openapi.yaml", null, options); + + // No error/warning messages should be present, especially Duplicate key ones + assertEquals(0, result.getMessages().size()); + assertEquals(1, result.getOpenAPI().getPaths().size()); + ApiResponse response = result.getOpenAPI().getPaths().get("/mypath").readOperations().get(0).getResponses().get("200"); + Discriminator discriminator = response.getContent().get("application/json").getSchema().getItems().getDiscriminator(); + assertEquals("discriminatorProperty", discriminator.getPropertyName()); + assertEquals("#/components/schemas/TypeA", discriminator.getMapping().get("ONE")); + assertEquals("#/components/schemas/TypeB", discriminator.getMapping().get("TWO")); + assertEquals("#/components/schemas/TypeB", discriminator.getMapping().get("THREE")); + assertEquals("#/components/schemas/TypeB", discriminator.getMapping().get("FOUR")); + assertEquals("#/components/schemas/TypeB", discriminator.getMapping().get("FIVE")); + } +} diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3RefTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3RefTest.java index c8dac007b7..5cfaf6af16 100644 --- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3RefTest.java +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3RefTest.java @@ -83,7 +83,11 @@ public void testDiscriminatorMappingRefsUpdated() { Set allOfs = ((List)reqSchema.getAnyOf()) .stream().map(Schema::get$ref).collect(Collectors.toSet()); assertTrue(allOfs.stream().allMatch(s -> s.contains(COMPONENTS_SCHEMAS_REF)),"Schema mappings are processed"); - assertTrue(allOfs.containsAll(discriminator),"Discriminator mappings are updated"); + Set allOfsNames = allOfs.stream() + .map(of -> of.split("/schemas/")[1]).collect(Collectors.toSet()); + Collection discriminatorNames = discriminator.stream().map(of -> of.split("/schemas/")[1] + .replace(".json","")).collect(Collectors.toSet()); + assertTrue(allOfsNames.containsAll(discriminatorNames),"Discriminator mappings are updated"); } diff --git a/modules/swagger-parser-v3/src/test/resources/issue-2222/mypath.yaml b/modules/swagger-parser-v3/src/test/resources/issue-2222/mypath.yaml new file mode 100644 index 0000000000..d77a77e18b --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/issue-2222/mypath.yaml @@ -0,0 +1,61 @@ + get: + summary: Get all objects + operationId: getObjects + responses: + '200': + description: "List of all the objects." + content: + application/json: + schema: + type: array + items: + oneOf: + - $ref: '#/components/schemas/TypeA' + - $ref: '#/components/schemas/TypeB' + discriminator: + propertyName: discriminatorProperty + mapping: + ONE: '#/components/schemas/TypeA' + TWO: '#/components/schemas/TypeB' + THREE: '#/components/schemas/TypeB' + FOUR: '#/components/schemas/TypeB' + FIVE: '#/components/schemas/TypeB' + + components: + schemas: + BaseType: + type: object + required: + - discriminatorProperty + properties: + discriminatorProperty: + type: string + description: A property used to determine the concrete object type. + enum: [ONE, TWO, THREE, FOUR, FIVE] + id: + type: string + description: Unique identifier for the object. + + TypeA: + allOf: + - $ref: '#/components/schemas/BaseType' + - type: object + properties: + discriminatorProperty: + type: string + enum: [ONE] + name: + type: string + description: A name specific to TypeA. + + TypeB: + allOf: + - $ref: '#/components/schemas/BaseType' + - type: object + properties: + discriminatorProperty: + type: string + enum: [TWO, THREE, FOUR, FIVE] + value: + type: number + description: A numeric value specific to TypeB. \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/issue-2222/openapi.yaml b/modules/swagger-parser-v3/src/test/resources/issue-2222/openapi.yaml new file mode 100644 index 0000000000..a2ecba50c5 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/issue-2222/openapi.yaml @@ -0,0 +1,9 @@ +openapi: 3.0.0 +info: + title: Example API + version: 1.0.0 + description: Example API demonstrating polymorphic response with external schemas. + +paths: + /mypath: + $ref: './mypath.yaml'