diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/ResolverFully.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/ResolverFully.java index 4f47781423..18f0b0aa81 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/ResolverFully.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/util/ResolverFully.java @@ -5,6 +5,7 @@ import io.swagger.v3.oas.models.PathItem; import io.swagger.v3.oas.models.callbacks.Callback; import io.swagger.v3.oas.models.examples.Example; +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.MediaType; @@ -13,6 +14,7 @@ import io.swagger.v3.oas.models.parameters.Parameter; import io.swagger.v3.oas.models.parameters.RequestBody; import io.swagger.v3.oas.models.responses.ApiResponse; +import io.swagger.v3.oas.models.responses.ApiResponses; import io.swagger.v3.parser.models.RefFormat; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,7 +50,7 @@ public ResolverFully(boolean aggregateCombinators) { private Map resolvedModels = new HashMap<>(); private Map examples; private Map requestBodies; - + private Map links; public void resolveFully(OpenAPI openAPI) { if (openAPI.getComponents() != null && openAPI.getComponents().getRequestBodies() != null) { @@ -72,6 +74,13 @@ public void resolveFully(OpenAPI openAPI) { } } + if (openAPI.getComponents() != null && openAPI.getComponents().getLinks() != null) { + links = openAPI.getComponents().getLinks(); + if (links == null) { + links = new HashMap<>(); + } + } + if(openAPI.getPaths() != null) { for (String pathname : openAPI.getPaths().keySet()) { PathItem pathItem = openAPI.getPaths().get(pathname); @@ -138,9 +147,10 @@ public void resolvePath(PathItem pathItem){ } } // responses - if(op.getResponses() != null) { - for(String code : op.getResponses().keySet()) { - ApiResponse response = op.getResponses().get(code); + ApiResponses responses = op.getResponses(); + if(responses != null) { + for(String code : responses.keySet()) { + ApiResponse response = responses.get(code); if (response.getContent() != null) { Map content = response.getContent(); for(String mediaType: content.keySet()){ @@ -155,11 +165,31 @@ public void resolvePath(PathItem pathItem){ } } } + Map links = response.getLinks(); + if (links != null) { + for (Map.Entry link : links.entrySet()) { + Link value = link.getValue(); + Link resolvedValue = value.get$ref() != null ? resolveLink(value) : value; + link.setValue(resolvedValue); + } + } } } } } + public Link resolveLink(Link link){ + RefFormat refFormat = computeRefFormat(link.get$ref()); + String $ref = link.get$ref(); + if (!isAnExternalRefFormat(refFormat)){ + if (links != null && !links.isEmpty()) { + String referenceKey = computeDefinitionName($ref); + return links.getOrDefault(referenceKey, link); + } + } + return link; + } + public RequestBody resolveRequestBody(RequestBody requestBody){ RefFormat refFormat = computeRefFormat(requestBody.get$ref()); String $ref = requestBody.get$ref(); 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 85e1c915c3..07855c1228 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 @@ -1538,6 +1538,15 @@ public void shouldParseRequestBody() { assertEquals(actualPathContent, actualComponentContent); } + @Test + public void testIssue884() { + ParseOptions parseOptions = new ParseOptions(); + parseOptions.setResolveFully(true); + OpenAPI openAPI = new OpenAPIV3Parser().read("src/test/resources/issue_884.yaml", null, parseOptions); + Map links = openAPI.getPaths().get("/2.0/repositories/{username}").getGet().getResponses().get("200").getLinks(); + String operationId = links.get("userRepository").getOperationId(); + assertEquals(operationId, "getRepository"); + } @Test public void testLinkIssue() { ParseOptions parseOptions = new ParseOptions(); @@ -1549,6 +1558,7 @@ public void testLinkIssue() { } + private static int getDynamicPort() { return new Random().ints(10000, 20000).findFirst().getAsInt(); } diff --git a/modules/swagger-parser-v3/src/test/resources/issue_884.yaml b/modules/swagger-parser-v3/src/test/resources/issue_884.yaml new file mode 100644 index 0000000000..fc72545d9f --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/issue_884.yaml @@ -0,0 +1,78 @@ +openapi: 3.0.0 +info: + title: Link Example + version: 1.0.0 +paths: + /2.0/repositories/{username}: + get: + operationId: getRepositoriesByOwner + parameters: + - name: username + in: path + required: true + schema: + type: string + responses: + '200': + description: repositories owned by the supplied user + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/repository' + links: + userRepository: + $ref: '#/components/links/userRepository' + /2.0/repositories/{username}/{slug}: + get: + operationId: getRepository + parameters: + - name: username + in: path + required: true + schema: + type: string + - name: slug + in: path + required: true + schema: + type: string + responses: + '200': + description: The repository + content: + application/json: + schema: + $ref: '#/components/schemas/repository' +components: + links: + userRepository: + operationId: getRepository + requestBody: '$response.body#/slug' + schemas: + user: + type: object + properties: + username: + type: string + uuid: + type: string + repository: + type: object + properties: + slug: + type: string + owner: + $ref: '#/components/schemas/user' + pullrequest: + type: object + properties: + id: + type: integer + title: + type: string + repository: + $ref: '#/components/schemas/repository' + author: + $ref: '#/components/schemas/user' \ No newline at end of file