From 3e03257748d0777f792332afbf9c5a75b5db0646 Mon Sep 17 00:00:00 2001 From: Daniel Kmiecik Date: Fri, 21 Nov 2025 15:58:21 +0100 Subject: [PATCH] fix: same name and different location in param + small refactor --- .../processors/ExternalRefProcessor.java | 3 +- .../parser/processors/ParameterProcessor.java | 184 +++++++++--------- .../v3/parser/test/OpenAPIV3ParserTest.java | 142 ++++++++------ .../test/resources/issue-2102/openapi.json | 35 ++++ 4 files changed, 207 insertions(+), 157 deletions(-) create mode 100644 modules/swagger-parser-v3/src/test/resources/issue-2102/openapi.json 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 0ad84145bf..4320f43208 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 @@ -96,8 +96,7 @@ public String processRefToExternalSchema(String $ref, RefFormat refFormat) { if(schema == null) { // stop! There's a problem. retain the original ref - LOGGER.warn("unable to load model reference from `" + $ref + "`. It may not be available " + - "or the reference isn't a valid model schema"); + LOGGER.warn("unable to load model reference from `{}`. It may not be available or the reference isn't a valid model schema", $ref); return $ref; } String newRef; diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ParameterProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ParameterProcessor.java index efdace6d93..6da973943c 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ParameterProcessor.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/ParameterProcessor.java @@ -1,18 +1,17 @@ package io.swagger.v3.parser.processors; - +import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.examples.Example; -import io.swagger.v3.oas.models.media.Content; import io.swagger.v3.oas.models.media.MediaType; import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.parameters.Parameter; -import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.parser.ResolverCache; import io.swagger.v3.parser.models.RefFormat; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Optional; import static io.swagger.v3.parser.util.RefUtils.computeRefFormat; import static io.swagger.v3.parser.util.RefUtils.isAnExternalRefFormat; @@ -33,137 +32,140 @@ public ParameterProcessor(ResolverCache cache, OpenAPI openAPI) { public ParameterProcessor(ResolverCache cache, OpenAPI openAPI, boolean openapi31) { this.cache = cache; this.openAPI = openAPI; - this.schemaProcessor = new SchemaProcessor(cache,openAPI, openapi31); - this.exampleProcessor = new ExampleProcessor(cache,openAPI); + this.schemaProcessor = new SchemaProcessor(cache, openAPI, openapi31); + this.exampleProcessor = new ExampleProcessor(cache, openAPI); this.externalRefProcessor = new ExternalRefProcessor(cache, openAPI); } public void processParameter(Parameter parameter) { - String $ref = parameter.get$ref(); - if($ref != null){ + processRefToExternalParameter(parameter, parameter.get$ref()); + if (parameter.getSchema() != null) { + schemaProcessor.processSchema(parameter.getSchema()); + } + processParameterExamples(parameter); + processParameterMediaTypeSchema(parameter); + } + + private void processRefToExternalParameter(Parameter parameter, String referencePath) { + if (referencePath != null) { RefFormat refFormat = computeRefFormat(parameter.get$ref()); - if (isAnExternalRefFormat(refFormat)){ - String newRef = externalRefProcessor.processRefToExternalParameter($ref, refFormat); + if (isAnExternalRefFormat(refFormat)) { + String newRef = externalRefProcessor.processRefToExternalParameter(referencePath, refFormat); if (newRef != null) { newRef = "#/components/parameters/" + newRef; parameter.set$ref(newRef); } } } - if (parameter.getSchema() != null){ - schemaProcessor.processSchema(parameter.getSchema()); - } - if (parameter.getExamples() != null){ - Map examples = parameter.getExamples(); - for(String exampleName: examples.keySet()){ - final Example example = examples.get(exampleName); - exampleProcessor.processExample(example); - } + } + + private void processParameterExamples(Parameter parameter) { + Map examples = parameter.getExamples(); + if (examples != null) { + examples.values().forEach(exampleProcessor::processExample); } - Schema schema = null; - if(parameter.getContent() != null) { - Map content = parameter.getContent(); - for( String mediaName : content.keySet()) { + } + + private void processParameterMediaTypeSchema(Parameter parameter) { + if (parameter.getContent() != null) { + Map content = parameter.getContent(); + for (String mediaName : content.keySet()) { MediaType mediaType = content.get(mediaName); - if(mediaType.getSchema()!= null) { - schema = mediaType.getSchema(); - if (schema != null) { - schemaProcessor.processSchema(schema); - } + if (mediaType.getSchema() != null) { + Optional schema = Optional.ofNullable(mediaType.getSchema()); + schema.ifPresent(schemaProcessor::processSchema); } } } } - public List processParameters(List parameters) { + public List processParameters(List parameters) { if (parameters == null) { return null; } - final List processedPathLevelParameters = new ArrayList<>(); final List refParameters = new ArrayList<>(); + final List processedPathLevelParameters = processPathLevelParams(parameters, refParameters); + + for (Parameter resolvedParameter : refParameters) { + int pos = 0; + for (Parameter param : processedPathLevelParameters) { + if (param.getName().equals(resolvedParameter.getName())) { + // ref param wins + processedPathLevelParameters.set(pos, resolvedParameter); + break; + } + pos++; + } + + } + processedPathLevelParameters.forEach(parameter -> { + if (parameter.getSchema() != null) { + schemaProcessor.processSchema(parameter.getSchema()); + } else if (parameter.getContent() != null) { + Map content = parameter.getContent(); + content.values().forEach(mediaType -> { + if (mediaType.getSchema() != null) { + schemaProcessor.processSchema(mediaType.getSchema()); + } + if (mediaType.getExamples() != null) { + mediaType.getExamples().values().forEach(exampleProcessor::processExample); + } + }); + + } + }); + + return processedPathLevelParameters; + } + + private List processPathLevelParams(List parameters, List refParameters) { + final List processedPathLevelParameters = new ArrayList<>(); for (Parameter parameter : parameters) { if (parameter.get$ref() != null) { RefFormat refFormat = computeRefFormat(parameter.get$ref()); final Parameter resolvedParameter = cache.loadRef(parameter.get$ref(), refFormat, Parameter.class); - if (parameter.get$ref().startsWith("#") && parameter.get$ref().indexOf("#/components/parameters") <= -1) { + if (parameter.get$ref().startsWith("#") && !parameter.get$ref().contains("#/components/parameters")) { //TODO: Not possible to add warning during resolve doesn't accept result as an input. Hence commented below line. //result.warning(location, "The parameter should use Reference Object to link to parameters that are defined at the OpenAPI Object's components/parameters."); continue; } - if(resolvedParameter == null) { + if (resolvedParameter == null) { // can't resolve it! processedPathLevelParameters.add(parameter); continue; } - // if the parameter exists, replace it - boolean matched = false; - for(Parameter param : processedPathLevelParameters) { - if(param != null && param.getName() != null && param.getName().equals(resolvedParameter.getName())) { - // ref param wins - matched = true; - break; - } - } - for(Parameter param : parameters) { - if(param.getName() != null) { - if (param.getName().equals(resolvedParameter.getName())) { - // ref param wins - matched = true; - break; - } - } - } + boolean matched = isParameterExist(parameters, processedPathLevelParameters, resolvedParameter); - if(matched) { + if (matched) { refParameters.add(resolvedParameter); - } - else { + } else { processedPathLevelParameters.add(resolvedParameter); } - } - else { + } else { processedPathLevelParameters.add(parameter); } } + return processedPathLevelParameters; + } - for(Parameter resolvedParameter : refParameters) { - int pos = 0; - for(Parameter param : processedPathLevelParameters) { - if(param.getName().equals(resolvedParameter.getName())) { - // ref param wins - processedPathLevelParameters.set(pos, resolvedParameter); - break; - } - pos++; - } - - } - - for (Parameter parameter : processedPathLevelParameters) { - Schema schema = parameter.getSchema(); - if(schema != null){ - schemaProcessor.processSchema(schema); - }else if(parameter.getContent() != null){ - Map content = parameter.getContent(); - for( String mediaName : content.keySet()) { - MediaType mediaType = content.get(mediaName); - if(mediaType.getSchema()!= null) { - schema = mediaType.getSchema(); - if (schema != null) { - schemaProcessor.processSchema(schema); - } - } - if(mediaType.getExamples() != null) { - for(Example ex: mediaType.getExamples().values()){ - exampleProcessor.processExample(ex); - } - } - } - - } + private static boolean isParameterExist(List parameters, List processedPathLevelParameters, Parameter resolvedParameter) { + // verify if the parameter exists, if yes, then replace it when name and location are the same + boolean matched = processedPathLevelParameters.stream() + .anyMatch(param -> param != null + && param.getName() != null + && param.getIn() != null + && param.getName().equals(resolvedParameter.getName()) + && param.getIn().equals(resolvedParameter.getIn())); + + if (!matched) { + matched = parameters.stream() + .anyMatch(param -> param != null + && param.getName() != null + && param.getIn() != null + && param.getName().equals(resolvedParameter.getName()) + && param.getIn().equals(resolvedParameter.getIn())); } - - return processedPathLevelParameters; + return matched; } } 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 cba66fb1b1..14870ad377 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 @@ -29,6 +29,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.math.BigDecimal; +import java.net.MalformedURLException; import java.net.URL; import java.util.*; @@ -112,7 +113,7 @@ public void testIssue1621() { } @Test - public void testIssue1865() throws Exception { + public void testIssue1865() { ParseOptions options = new ParseOptions(); options.setResolve(true); SwaggerParseResult result = new OpenAPIV3Parser().readLocation("src/test/resources/issue-1865/openapi30.yaml", null, options); @@ -174,7 +175,7 @@ public void testIssue1780() { } @Test - public void testParametersAndResponsesAsNumbers() throws Exception { + public void testParametersAndResponsesAsNumbers() { ParseOptions options = new ParseOptions(); options.setResolve(true); options.setResolveResponses(true); @@ -187,7 +188,7 @@ public void testParametersAndResponsesAsNumbers() throws Exception { } @Test - public void testIssue1758() throws Exception{ + public void testIssue1758() { ParseOptions options = new ParseOptions(); SwaggerParseResult result = new OpenAPIV3Parser().readLocation("src/test/resources/issue1758.yaml", null, options); @@ -310,7 +311,7 @@ public void testIssue1637_StyleAndContent() throws IOException { } @Test - public void testIssue1643_True() throws Exception{ + public void testIssue1643_True() { ParseOptions options = new ParseOptions(); String issue1643 = "openapi: \"3.0.0\"\n" + "info:\n" + @@ -353,7 +354,7 @@ public void testIssue1643_True() throws Exception{ } @Test - public void testIssue1643_False() throws Exception{ + public void testIssue1643_False() { ParseOptions options = new ParseOptions(); options.setValidateInternalRefs(false); String issue1643 = "openapi: \"3.0.0\"\n" + @@ -397,7 +398,7 @@ public void testIssue1643_False() throws Exception{ } @Test - public void testExampleFormatByte() throws Exception{ + public void testExampleFormatByte() { ParseOptions options = new ParseOptions(); SwaggerParseResult result = new OpenAPIV3Parser().readLocation("src/test/resources/issue1630.yaml", null, options); @@ -423,7 +424,7 @@ public void testExampleFormatByte() throws Exception{ } @Test - public void testIssue1658() throws Exception{ + public void testIssue1658() { ParseOptions options = new ParseOptions(); options.setResolve(true); SwaggerParseResult result = new OpenAPIV3Parser().readLocation("src/test/resources/issue-1658/issue1658.yaml", null, options); @@ -440,7 +441,7 @@ public void testIssue1658() throws Exception{ } @Test - public void testIssue1644_NullValue() throws Exception{ + public void testIssue1644_NullValue() { ParseOptions options = new ParseOptions(); String issue1644 = "openapi: 3.0.0\n" + "info:\n" + @@ -466,7 +467,7 @@ public void testIssue1644_NullValue() throws Exception{ } @Test - public void testIssue1644_EmptyValue() throws Exception{ + public void testIssue1644_EmptyValue() { ParseOptions options = new ParseOptions(); String issue1644 = "openapi: 3.0.0\n" + "info:\n" + @@ -493,7 +494,7 @@ public void testIssue1644_EmptyValue() throws Exception{ @Test - public void testEmptyStrings_False() throws Exception{ + public void testEmptyStrings_False() { ParseOptions options = new ParseOptions(); options.setAllowEmptyString(false); SwaggerParseResult result = new OpenAPIV3Parser().readLocation("src/test/resources/empty-strings.yaml", null, options); @@ -510,7 +511,7 @@ public void testEmptyStrings_False() throws Exception{ @Test - public void testEmptyStrings_True() throws Exception{ + public void testEmptyStrings_True() { ParseOptions options = new ParseOptions(); options.setAllowEmptyString(true); SwaggerParseResult result = new OpenAPIV3Parser().readLocation("src/test/resources/empty-strings.yaml", null, options); @@ -994,7 +995,7 @@ public void testIssue1169noSplit() { @Test - public void testIssue339() throws Exception { + public void testIssue339() { OpenAPIV3Parser openAPIV3Parser = new OpenAPIV3Parser(); OpenAPI api = openAPIV3Parser.read("issue-339.yaml"); assertNotNull(api); @@ -1023,7 +1024,7 @@ public void testIssue1108() { } @Test - public void testRemoteParameterIssue1094() throws Exception{ + public void testRemoteParameterIssue1094() { OpenAPI result = new OpenAPIV3Parser().read("issue-1094/swagger.yaml"); Assert.assertNotNull(result); Assert.assertNotNull(result.getComponents().getSchemas().get("PlmnId")); @@ -1271,7 +1272,7 @@ public void testIssue719() { } @Test - public void issue682() throws Exception { + public void issue682() { OpenAPIV3Parser parser = new OpenAPIV3Parser(); ParseOptions options = new ParseOptions(); options.setResolve(true); @@ -1283,7 +1284,7 @@ public void issue682() throws Exception { } @Test - public void issue941() throws Exception { + public void issue941() { OpenAPIV3Parser parser = new OpenAPIV3Parser(); final OpenAPI result = parser.read("src/test/resources/sample/SwaggerPetstore.yaml"); @@ -1292,7 +1293,7 @@ public void issue941() throws Exception { } @Test - public void issueRelativeRefs2() throws Exception { + public void issueRelativeRefs2() { OpenAPIV3Parser parser = new OpenAPIV3Parser(); ParseOptions options = new ParseOptions(); options.setResolve(true); @@ -1313,7 +1314,7 @@ public void testPattern() { } @Test - public void testResolveEmpty() throws Exception{ + public void testResolveEmpty() throws IOException{ String pathFile = FileUtils.readFileToString(new File("src/test/resources/empty-oas.yaml")); ParseOptions options = new ParseOptions(); options.setResolveFully(true); @@ -1328,7 +1329,7 @@ public void testResolveEmpty() throws Exception{ @Test - public void testRemotePathItemIssue1103() throws Exception{ + public void testRemotePathItemIssue1103() { OpenAPI result = new OpenAPIV3Parser().read("issue-1103/remote-pathItem-swagger.yaml"); Assert.assertNotNull(result); Assert.assertNotNull(result.getPaths().get("/Translation/{lang}")); @@ -1336,21 +1337,21 @@ public void testRemotePathItemIssue1103() throws Exception{ } @Test - public void testRemoteParameterIssue1103() throws Exception{ + public void testRemoteParameterIssue1103() { OpenAPI result = new OpenAPIV3Parser().read("issue-1103/remote-parameter-swagger.yaml"); Assert.assertNotNull(result); Assert.assertEquals(result.getPaths().get("/Translation/{lang}").getPut().getParameters().get(0).getName(), "lang"); } @Test - public void testIssue1105() throws Exception { + public void testIssue1105() { OpenAPI openAPI = new OpenAPIV3Parser().read("issue-1105/swagger-api.yaml"); Assert.assertNotNull(openAPI); Assert.assertNotNull(openAPI.getComponents().getSchemas().get("ErrorCodeDescription")); } @Test - public void testRefAdditionalProperties() throws Exception { + public void testRefAdditionalProperties() { OpenAPI openAPI = new OpenAPIV3Parser().read("src/test/resources/relative/additionalProperties.yaml"); Assert.assertNotNull(openAPI); @@ -1361,7 +1362,7 @@ public void testRefAdditionalProperties() throws Exception { } @Test - public void testRefAndInlineAllOf() throws Exception { + public void testRefAndInlineAllOf() { ParseOptions options = new ParseOptions(); options.setResolve(true); options.setResolveFully(true); @@ -1375,7 +1376,7 @@ public void testRefAndInlineAllOf() throws Exception { } @Test - public void testComposedRefResolvingIssue628() throws Exception { + public void testComposedRefResolvingIssue628() { ParseOptions options = new ParseOptions(); options.setResolve(true); OpenAPI openAPI = new OpenAPIV3Parser().read("src/test/resources/composedSchemaRef.yaml", auths, options); @@ -1391,7 +1392,7 @@ public void testComposedRefResolvingIssue628() throws Exception { } @Test - public void testComposedSchemaAdjacent() throws Exception { + public void testComposedSchemaAdjacent() { ParseOptions options = new ParseOptions(); options.setResolve(true); OpenAPI openAPI = new OpenAPIV3Parser().read("src/test/resources/composedSchemaRef.yaml", auths, options); @@ -1406,7 +1407,7 @@ public void testComposedSchemaAdjacent() throws Exception { } @Test - public void testOneOfExternalRefConflictName() throws Exception { + public void testOneOfExternalRefConflictName() { OpenAPI openAPI = new OpenAPIV3Parser().read("./oneof_name_conflict/oneOf-external-ref-name-conflict.yaml"); Assert.assertNotNull(openAPI); Schema pet = openAPI.getComponents().getSchemas().get("Pet"); @@ -1416,14 +1417,14 @@ public void testOneOfExternalRefConflictName() throws Exception { } @Test - public void int64ExampleWithoutOverflow() throws Exception { + public void int64ExampleWithoutOverflow() { OpenAPI openAPI = new OpenAPIV3Parser().read("src/test/resources/int64example.yaml"); IntegerSchema date = ((IntegerSchema) openAPI.getPaths().get("/foo").getGet().getResponses().get("200").getContent().get("application/json").getSchema().getProperties().get("date")); Assert.assertEquals("1516042231144", date.getExample().toString()); } @Test - public void testRefPaths() throws Exception { + public void testRefPaths() { String yaml = "openapi: '3.0.0'\n" + "info:\n" + " version: 0.0.0\n" + @@ -1443,7 +1444,7 @@ public void testRefPaths() throws Exception { } @Test - public void testModelParameters() throws Exception { + public void testModelParameters() { String yaml = "openapi: '2.0'\n" + "info:\n" + " version: \"0.0.0\"\n" + @@ -1469,7 +1470,7 @@ public void testModelParameters() throws Exception { } @Test - public void testParseSharedPathParameters() throws Exception { + public void testParseSharedPathParameters() { String yaml = "openapi: '3.0.0'\n" + "info:\n" + @@ -1507,7 +1508,7 @@ public void testParseSharedPathParameters() throws Exception { } @Test - public void testParseRefPathParameters() throws Exception { + public void testParseRefPathParameters() { String yaml = "openAPI: '2.0'\n" + "info:\n" + @@ -1549,7 +1550,7 @@ public void testParseRefPathParameters() throws Exception { } @Test - public void testUniqueParameters() throws Exception { + public void testUniqueParameters() { String yaml = "openapi: 3.0.0\n" + "servers: []\n" + @@ -1609,12 +1610,12 @@ public void testUniqueParameters() throws Exception { } @Test - public void testLoadRelativeFileTree_Json() throws Exception { + public void testLoadRelativeFileTree_Json() { final OpenAPI openAPI = doRelativeFileTest("src/test/resources/relative-file-references/json/parent.json"); } @Test - public void testLoadExternalNestedDefinitions() throws Exception { + public void testLoadExternalNestedDefinitions() { OpenAPIV3Parser parser = new OpenAPIV3Parser(); final OpenAPI openAPI = parser.read("src/test/resources/nested-references/b.yaml"); @@ -1627,7 +1628,7 @@ public void testLoadExternalNestedDefinitions() throws Exception { } @Test - public void testLoadExternalNestedDefinitionsWithReferenceWithinSubfolder() throws Exception { + public void testLoadExternalNestedDefinitionsWithReferenceWithinSubfolder() { OpenAPIV3Parser parser = new OpenAPIV3Parser(); final OpenAPI openAPI = parser.read("src/test/resources/nested-references-2/main.yaml"); @@ -1648,7 +1649,7 @@ public void testLoadExternalNestedDefinitionsWithReferenceWithinSubfolder() thro } @Test - public void testLoadExternalNestedDefinitionsWithReferenceWithinSameFolder() throws Exception { + public void testLoadExternalNestedDefinitionsWithReferenceWithinSameFolder() { OpenAPIV3Parser parser = new OpenAPIV3Parser(); final OpenAPI openAPI = parser.read("src/test/resources/nested-references-3/main.yaml"); @@ -1669,7 +1670,7 @@ public void testLoadExternalNestedDefinitionsWithReferenceWithinSameFolder() thr } @Test - public void testLoadExternalNestedDefinitionsWithReferenceOnDifferentFolderLevels() throws Exception { + public void testLoadExternalNestedDefinitionsWithReferenceOnDifferentFolderLevels() { OpenAPIV3Parser parser = new OpenAPIV3Parser(); final OpenAPI openAPI = parser.read("src/test/resources/nested-references-4/main.yaml"); @@ -1690,7 +1691,7 @@ public void testLoadExternalNestedDefinitionsWithReferenceOnDifferentFolderLevel } @Test - public void testPetstore() throws Exception { + public void testPetstore() { OpenAPIV3Parser parser = new OpenAPIV3Parser(); ParseOptions options = new ParseOptions(); options.setResolve(true); @@ -1728,7 +1729,7 @@ public void testPetstore() throws Exception { } @Test - public void testFileReferenceWithVendorExt() throws Exception { + public void testFileReferenceWithVendorExt() { OpenAPIV3Parser parser = new OpenAPIV3Parser(); final OpenAPI openAPI = parser.read("src/test/resources/file-reference-with-vendor-ext/b.yaml"); Map definitions = openAPI.getComponents().getSchemas(); @@ -1739,13 +1740,13 @@ public void testFileReferenceWithVendorExt() throws Exception { } @Test - public void testTroublesomeFile() throws Exception { + public void testTroublesomeFile() { OpenAPIV3Parser parser = new OpenAPIV3Parser(); final OpenAPI openAPI = parser.read("src/test/resources/troublesome.yaml"); } @Test - public void testLoadRelativeFileTree_Yaml() throws Exception { + public void testLoadRelativeFileTree_Yaml() throws IOException { JsonToYamlFileDuplicator.duplicateFilesInYamlFormat("src/test/resources/relative-file-references/json", "src/test/resources/relative-file-references/yaml"); final OpenAPI openAPI = doRelativeFileTest("src/test/resources/relative-file-references/yaml/parent.yaml"); @@ -1754,7 +1755,7 @@ public void testLoadRelativeFileTree_Yaml() throws Exception { } @Test - public void testLoadRecursiveExternalDef() throws Exception { + public void testLoadRecursiveExternalDef() { OpenAPIV3Parser parser = new OpenAPIV3Parser(); final OpenAPI openAPI = parser.read("src/test/resources/file-reference-to-recursive-defs/b.yaml"); @@ -2090,7 +2091,7 @@ public void testCodegenPetstore() { } @Test - public void testCodegenIssue4555() throws Exception { + public void testCodegenIssue4555() { OpenAPIV3Parser parser = new OpenAPIV3Parser(); String yaml = "openapi: 3.0.0\n" + "info:\n" + @@ -2126,7 +2127,7 @@ public void testCodegenIssue4555() throws Exception { } @Test - public void testConverterIssue17() throws Exception { + public void testConverterIssue17() { String yaml = "openapi: 3.0.0\n" + "info:\n" + " version: 0.0.0\n" + @@ -2449,7 +2450,7 @@ public void checkAllOfWithRelativeReferencesIssue604() { } @Test(description = "A string example should not be over quoted when parsing a yaml string") - public void readingSpecStringShouldNotOverQuotingStringExample() throws Exception { + public void readingSpecStringShouldNotOverQuotingStringExample() { OpenAPIV3Parser parser = new OpenAPIV3Parser(); ParseOptions options = new ParseOptions(); options.setResolve(false); @@ -2460,7 +2461,7 @@ public void readingSpecStringShouldNotOverQuotingStringExample() throws Exceptio } @Test(description = "A string example should not be over quoted when parsing a yaml node") - public void readingSpecNodeShouldNotOverQuotingStringExample() throws Exception { + public void readingSpecNodeShouldNotOverQuotingStringExample() throws IOException { String yaml = Files.readFile(new FileInputStream("src/test/resources/over-quoted-example.yaml")); JsonNode rootNode = Yaml.mapper().readValue(yaml, JsonNode.class); OpenAPIV3Parser parser = new OpenAPIV3Parser(); @@ -2949,7 +2950,7 @@ public void testDuplicateHttpStatusCodesYaml() { @Test - public void testDiscriminatorSingleFileNoMapping() throws Exception { + public void testDiscriminatorSingleFileNoMapping() { OpenAPI openAPI = new OpenAPIV3Parser().read("./discriminator-mapping-resolution/single-file-no-mapping.yaml"); Assert.assertNotNull(openAPI); Schema cat = openAPI.getComponents().getSchemas().get("Cat"); @@ -2957,7 +2958,7 @@ public void testDiscriminatorSingleFileNoMapping() throws Exception { } @Test - public void testDiscriminatorSeparateFileNoMapping() throws Exception { + public void testDiscriminatorSeparateFileNoMapping() { OpenAPI openAPI = new OpenAPIV3Parser().read("./discriminator-mapping-resolution/main-no-mapping.yaml"); Assert.assertNotNull(openAPI); Schema cat = openAPI.getComponents().getSchemas().get("Cat"); @@ -2965,7 +2966,7 @@ public void testDiscriminatorSeparateFileNoMapping() throws Exception { } @Test - public void testDiscriminatorSingleFilePlainMapping() throws Exception { + public void testDiscriminatorSingleFilePlainMapping() { OpenAPI openAPI = new OpenAPIV3Parser().read("./discriminator-mapping-resolution/single-file-plain-mapping.yaml"); Assert.assertNotNull(openAPI); Schema cat = openAPI.getComponents().getSchemas().get("Cat"); @@ -2973,7 +2974,7 @@ public void testDiscriminatorSingleFilePlainMapping() throws Exception { } @Test - public void testDiscriminatorSeparateFilePlainMapping() throws Exception { + public void testDiscriminatorSeparateFilePlainMapping() { OpenAPI openAPI = new OpenAPIV3Parser().read("./discriminator-mapping-resolution/main-plain-mapping.yaml"); Assert.assertNotNull(openAPI); Schema cat = openAPI.getComponents().getSchemas().get("Cat"); @@ -2981,7 +2982,7 @@ public void testDiscriminatorSeparateFilePlainMapping() throws Exception { } @Test - public void testDiscriminatorSingleFileInternalMapping() throws Exception { + public void testDiscriminatorSingleFileInternalMapping() { OpenAPI openAPI = new OpenAPIV3Parser().read("./discriminator-mapping-resolution/single-file-internal-mapping.yaml"); Assert.assertNotNull(openAPI); Schema cat = openAPI.getComponents().getSchemas().get("Cat"); @@ -2989,7 +2990,7 @@ public void testDiscriminatorSingleFileInternalMapping() throws Exception { } @Test - public void testDiscriminatorSeparateFileInternalMapping() throws Exception { + public void testDiscriminatorSeparateFileInternalMapping() { OpenAPI openAPI = new OpenAPIV3Parser().read("./discriminator-mapping-resolution/main-internal-mapping.yaml"); Assert.assertNotNull(openAPI); Schema cat = openAPI.getComponents().getSchemas().get("Cat"); @@ -2997,7 +2998,7 @@ public void testDiscriminatorSeparateFileInternalMapping() throws Exception { } @Test - public void testDiscriminatorSameFileExternalMapping() throws Exception { + public void testDiscriminatorSameFileExternalMapping() { OpenAPI openAPI = new OpenAPIV3Parser().read("./discriminator-mapping-resolution/main-external-mapping.yaml"); Assert.assertNotNull(openAPI); Schema cat = openAPI.getComponents().getSchemas().get("Cat"); @@ -3005,7 +3006,7 @@ public void testDiscriminatorSameFileExternalMapping() throws Exception { } @Test - public void testDiscriminatorSeparateFileExternalMapping() throws Exception { + public void testDiscriminatorSeparateFileExternalMapping() { OpenAPI openAPI = new OpenAPIV3Parser().read("./discriminator-mapping-resolution/main-external-mapping-3files.yaml"); Assert.assertNotNull(openAPI); Schema cat = openAPI.getComponents().getSchemas().get("Cat"); @@ -3020,7 +3021,7 @@ public void testRelativePathIssue1543() { ParseOptions options = new ParseOptions(); options.setResolveFully(true); options.setResolve(true); - SwaggerParseResult readResult = parser.readLocation("src/test/resources/issue-1543/openapi.yaml", null, options); + SwaggerParseResult readResult = parser.readLocation("src/test/resources/issue-1543/openapi.json", null, options); if (readResult.getMessages().size() > 0) { Assert.assertFalse(readResult.getMessages().get(0).contains("end -1")); @@ -3028,7 +3029,7 @@ public void testRelativePathIssue1543() { } @Test - public void testIssue1540() throws Exception{ + public void testIssue1540() { OpenAPI openAPI = new OpenAPIV3Parser().read("./issue-1540/a.json"); Assert.assertNotNull(openAPI); Map extensions = openAPI.getExtensions(); @@ -3043,7 +3044,7 @@ public void testIssue1540() throws Exception{ } @Test - public void testIssue1592() throws Exception { + public void testIssue1592() throws MalformedURLException { File file = new File("src/test/resources/issue-1592.jar"); URL url = new URL("jar:" + file.toURI() + "!/test.yaml"); ParseOptions options = new ParseOptions(); @@ -3054,7 +3055,7 @@ public void testIssue1592() throws Exception { } @Test - public void testIssue1266() throws Exception{ + public void testIssue1266() throws IOException{ String yamlString = FileUtils.readFileToString(new File("src/test/resources/issue-1266/issue-1266.yaml"), "UTF-8"); String yamlStringResolved = FileUtils.readFileToString(new File("src/test/resources/issue-1266/issue-1266-resolved.yaml"), "UTF-8"); ParseOptions options = new ParseOptions(); @@ -3116,8 +3117,8 @@ public void testIssue1891() { Schema typesModel = openAPI.getComponents().getSchemas().get("TypesModel"); Schema sharedModel = openAPI.getComponents().getSchemas().get("SharedModel"); - assertEquals("#/components/schemas/TypesModel", localModel.getProperties().get("sharedModelField").get$ref()); - assertEquals("#/components/schemas/SharedModel", typesModel.get$ref()); + assertEquals(localModel.getProperties().get("sharedModelField").get$ref(), "#/components/schemas/TypesModel"); + assertEquals(typesModel.get$ref(), "#/components/schemas/SharedModel"); assertNotNull(sharedModel); } @@ -3147,7 +3148,7 @@ public void testValidateExternalRefsFalse() { } @Test - public void testNullExample() throws Exception{ + public void testNullExample() throws IOException { String yamlString = FileUtils.readFileToString(new File("src/test/resources/null-full-example.yaml"), "UTF-8"); String yamlStringResolved = FileUtils.readFileToString(new File("src/test/resources/null-full-example-resolved.yaml"), "UTF-8"); ParseOptions options = new ParseOptions(); @@ -3159,7 +3160,7 @@ public void testNullExample() throws Exception{ } @Test - public void testInternalRefsValidation() throws Exception { + public void testInternalRefsValidation() throws IOException { String yamlString = FileUtils.readFileToString(new File("src/test/resources/internal-refs.yaml"), "UTF-8"); ParseOptions options = new ParseOptions(); SwaggerParseResult parseResult = new OpenAPIV3Parser().readContents(yamlString, null, options); @@ -3214,7 +3215,7 @@ public void test31SafeURLResolvingWithBlockedURL() { parseOptions.setResolveFully(true); parseOptions.setSafelyResolveURL(true); List allowList = Collections.emptyList(); - List blockList = Arrays.asList("petstore3.swagger.io"); + List blockList = Collections.singletonList("petstore3.swagger.io"); parseOptions.setRemoteRefAllowList(allowList); parseOptions.setRemoteRefBlockList(blockList); @@ -3235,7 +3236,7 @@ public void test31SafeURLResolvingWithTurnedOffSafeResolving() { parseOptions.setResolveFully(true); parseOptions.setSafelyResolveURL(false); List allowList = Collections.emptyList(); - List blockList = Arrays.asList("petstore3.swagger.io"); + List blockList = Collections.singletonList("petstore3.swagger.io"); parseOptions.setRemoteRefAllowList(allowList); parseOptions.setRemoteRefBlockList(blockList); @@ -3268,7 +3269,7 @@ public void test31SafeURLResolvingWithLocalhost() { ParseOptions parseOptions = new ParseOptions(); parseOptions.setResolveFully(true); parseOptions.setSafelyResolveURL(true); - List blockList = Arrays.asList("petstore.swagger.io"); + List blockList = Collections.singletonList("petstore.swagger.io"); parseOptions.setRemoteRefBlockList(blockList); String error = "URL is part of the explicit denylist. URL [https://petstore.swagger.io/v2/swagger.json]"; @@ -3436,4 +3437,17 @@ public void testVersion(){ SwaggerParseResult parseResult = openApiParser.readLocation("version-missing.yaml", null, options); assertEquals(parseResult.getMessages().get(0), "attribute info.version is missing"); } + + @Test(description = "Duplicated parameter name with different locations") + public void testDuplicatedParameterNameFromRef() { + OpenAPIV3Parser openApiParser = new OpenAPIV3Parser(); + ParseOptions options = new ParseOptions(); + options.setResolve(true); + options.setFlatten(true); + OpenAPI openAPI = openApiParser.read("issue-2102/openapi.json", null, options); + + assertEquals(openAPI.getPaths().get("/myoperation").getGet().getParameters().size(), 2); + assertEquals((int) openAPI.getPaths().get("/myoperation").getGet().getParameters().stream().filter(param -> param.getName().equals("myParam")).count(), 2); + + } } diff --git a/modules/swagger-parser-v3/src/test/resources/issue-2102/openapi.json b/modules/swagger-parser-v3/src/test/resources/issue-2102/openapi.json new file mode 100644 index 0000000000..6a921b73bb --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/issue-2102/openapi.json @@ -0,0 +1,35 @@ +{ + "openapi": "3.0.0", + "paths": { + "/myoperation": { + "get": { + "parameters": [ + {"$ref": "#/components/parameters/schemaParam1"}, + {"$ref": "#/components/parameters/schemaParam2"} + ], + "responses": { + "200": { + "description": "OK", + "content": { + "text/plain": { + "schema": { + "type": "string" + } + }}}}}}}, + "components": { + "parameters": { + "schemaParam1": { + "name": "myParam", + "in": "query", + "schema": { + "type": "string" + } + }, + "schemaParam2": { + "name": "myParam", + "in": "header", + "schema": { + "type": "string" + } + }}} +} \ No newline at end of file