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 0413f79312..b6b5642edb 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 @@ -29,6 +29,8 @@ import io.swagger.v3.parser.ResolverCache; import io.swagger.v3.parser.models.RefFormat; import io.swagger.v3.parser.models.RefType; +import io.swagger.v3.parser.util.RefUtils; + import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.LoggerFactory; @@ -86,6 +88,18 @@ public String processRefToExternalSchema(String $ref, RefFormat refFormat) { return renamedRef; } + RefFormat format = computeRefFormat($ref); + if (format.equals(RefFormat.RELATIVE)) { + String normalizedRef = Paths.get($ref).normalize().toString(); + System.out.println("Normalized " + $ref + " to " + normalizedRef); + renamedRef = cache.getRenamedRef($ref); + if (renamedRef != null) { + return renamedRef; + } else { + $ref = normalizedRef; + } + } + final Schema schema = cache.loadRef($ref, refFormat, Schema.class); if(schema == null) { 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 997f1c23bd..2553babbcf 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 @@ -1953,6 +1953,21 @@ public void testRelativePath2() { Assert.assertEquals(readResult.getOpenAPI().getPaths().get("/pet/findByTags").getGet().getResponses().get("default").getContent().get("application/json").getSchema().get$ref(), "#/components/schemas/ErrorModel"); } + @Test + public void testExternalRefsNormalization() throws Exception { + ParseOptions options = new ParseOptions(); + options.setResolve(true); + SwaggerParseResult result = new OpenAPIV3Parser() + .readLocation("src/test/resources/oas3.fetched/openapi3.yaml", null, options); + + OpenAPI openAPI = result.getOpenAPI(); + Schema originalModel = openAPI.getComponents().getSchemas().get("Event"); + Schema duplicateModel = openAPI.getComponents().getSchemas().get("Event_1"); + System.out.println("component schemas found: " + openAPI.getComponents().getSchemas().keySet()); + assertNull(duplicateModel); + assertNotNull(originalModel); + } + private OpenAPI doRelativeFileTest(String location) { OpenAPIV3Parser parser = new OpenAPIV3Parser(); ParseOptions options = new ParseOptions(); @@ -3298,4 +3313,4 @@ public void testIssue2081() { assertEquals(openAPI.getComponents().getSchemas().get("PetCreate").getRequired().size(), 1); assertEquals(openAPI.getComponents().getSchemas().get("PetCreate").getProperties().size(), 2); } -} \ No newline at end of file +} diff --git a/modules/swagger-parser-v3/src/test/resources/oas3.fetched/components/schemas/Error.yaml b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/components/schemas/Error.yaml new file mode 100644 index 0000000000..f940b13db2 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/components/schemas/Error.yaml @@ -0,0 +1,13 @@ +description: Error responses are included with 4xx and 5xx HTTP responses from the + API service. Either "error" or "errors" will be set. +properties: + error: + description: A description of the error that caused the request to fail. + type: string + errors: + description: A list of errors that contributed to the request failing. + items: + description: An error message that contributed to the request failing. + type: string + type: array +type: object diff --git a/modules/swagger-parser-v3/src/test/resources/oas3.fetched/components/schemas/Event.yaml b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/components/schemas/Event.yaml new file mode 100644 index 0000000000..9f4effd2e3 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/components/schemas/Event.yaml @@ -0,0 +1,26 @@ +properties: + body: + type: string + created_at: + format: date-time + type: string + href: + type: string + id: + format: uuid + type: string + interpolated: + type: string + relationships: + items: + $ref: './Href.yaml' + type: array + state: + type: string + type: + type: string + modified_by: + type: object + ip: + type: string +type: object diff --git a/modules/swagger-parser-v3/src/test/resources/oas3.fetched/components/schemas/EventList.yaml b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/components/schemas/EventList.yaml new file mode 100644 index 0000000000..75b2d4c509 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/components/schemas/EventList.yaml @@ -0,0 +1,8 @@ +properties: + events: + items: + $ref: './Event.yaml' + type: array + meta: + $ref: './Meta.yaml' +type: object diff --git a/modules/swagger-parser-v3/src/test/resources/oas3.fetched/components/schemas/Href.yaml b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/components/schemas/Href.yaml new file mode 100644 index 0000000000..bbe7e22053 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/components/schemas/Href.yaml @@ -0,0 +1,6 @@ +properties: + href: + type: string +required: +- href +type: object diff --git a/modules/swagger-parser-v3/src/test/resources/oas3.fetched/components/schemas/Meta.yaml b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/components/schemas/Meta.yaml new file mode 100644 index 0000000000..88a52dc17b --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/components/schemas/Meta.yaml @@ -0,0 +1,18 @@ +properties: + first: + $ref: './Href.yaml' + last: + $ref: './Href.yaml' + next: + $ref: './Href.yaml' + previous: + $ref: './Href.yaml' + self: + $ref: './Href.yaml' + total: + type: integer + current_page: + type: integer + last_page: + type: integer +type: object diff --git a/modules/swagger-parser-v3/src/test/resources/oas3.fetched/openapi3.yaml b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/openapi3.yaml new file mode 100644 index 0000000000..1397f45487 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/openapi3.yaml @@ -0,0 +1,40 @@ +openapi: 3.0.0 +info: + version: 1.0.0 + title: Example Duplicate Refs API + contact: + email: support@example.com + name: Example API Team + description: | + Sample API spec to validate handling of different file paths that reference the same file + license: + name: Equinix Metal + url: https://metal.equinix.com/legal/ + termsOfService: https://metal.equinix.com/legal/ +servers: + - url: https://api.example.com/duplicateRefs +components: + schemas: + Error: + $ref: "./components/schemas/Error.yaml" + Event: + $ref: "./components/schemas/Event.yaml" + EventList: + $ref: "./components/schemas/EventList.yaml" +paths: + /connections/{connection_id}/ports/{id}/events: + $ref: ./paths/connections/connection_id/ports/id/events.yaml + /devices/{id}/events: + $ref: ./paths/devices/id/events.yaml + /events: + $ref: ./paths/events.yaml + /events/{id}: + $ref: ./paths/events/id.yaml + /organizations/{id}/events: + $ref: ./paths/organizations/id/events.yaml + /projects/{id}/events: + $ref: ./paths/projects/id/events.yaml + /routes/{id}/events: + $ref: ./paths/routes/id/events.yaml + /virtual-circuits/{id}/events: + $ref: ./paths/virtual-circuits/id/events.yaml diff --git a/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/connections/connection_id/events.yaml b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/connections/connection_id/events.yaml new file mode 100644 index 0000000000..e684f0cf10 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/connections/connection_id/events.yaml @@ -0,0 +1,39 @@ +get: + description: Returns a list of the interconnection events + operationId: findInterconnectionEvents + parameters: + - description: Interconnection UUID + in: path + name: connection_id + required: true + schema: + format: uuid + type: string + responses: + "200": + content: + application/json: + schema: + $ref: "../../../components/schemas/EventList.yaml" + description: ok + "401": + content: + application/json: + schema: + $ref: "../../../components/schemas/Error.yaml" + description: unauthorized + "403": + content: + application/json: + schema: + $ref: "../../../components/schemas/Error.yaml" + description: forbidden + "404": + content: + application/json: + schema: + $ref: "../../../components/schemas/Error.yaml" + description: not found + summary: Retrieve interconnection events + tags: + - Events diff --git a/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/connections/connection_id/ports/id/events.yaml b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/connections/connection_id/ports/id/events.yaml new file mode 100644 index 0000000000..b96b25ac29 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/connections/connection_id/ports/id/events.yaml @@ -0,0 +1,46 @@ +get: + description: Returns a list of the interconnection port events + operationId: findInterconnectionPortEvents + parameters: + - description: Interconnection UUID + in: path + name: connection_id + required: true + schema: + format: uuid + type: string + - description: Interconnection Port UUID + in: path + name: id + required: true + schema: + format: uuid + type: string + responses: + "200": + content: + application/json: + schema: + $ref: "../../../../../components/schemas/Event.yaml" + description: ok + "401": + content: + application/json: + schema: + $ref: "../../../../../components/schemas/Error.yaml" + description: unauthorized + "403": + content: + application/json: + schema: + $ref: "../../../../../components/schemas/Error.yaml" + description: forbidden + "404": + content: + application/json: + schema: + $ref: "../../../../../components/schemas/Error.yaml" + description: not found + summary: Retrieve interconnection port events + tags: + - Events diff --git a/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/devices/id/events.yaml b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/devices/id/events.yaml new file mode 100644 index 0000000000..3f56542376 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/devices/id/events.yaml @@ -0,0 +1,39 @@ +get: + description: Returns a list of events pertaining to a specific device + operationId: findDeviceEvents + parameters: + - description: Device UUID + in: path + name: id + required: true + schema: + format: uuid + type: string + responses: + "200": + content: + application/json: + schema: + $ref: "../../../components/schemas/EventList.yaml" + description: ok + "401": + content: + application/json: + schema: + $ref: "../../../components/schemas/Error.yaml" + description: unauthorized + "403": + content: + application/json: + schema: + $ref: "../../../components/schemas/Error.yaml" + description: forbidden + "404": + content: + application/json: + schema: + $ref: "../../../components/schemas/Error.yaml" + description: not found + summary: Retrieve device's events + tags: + - Events diff --git a/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/events.yaml b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/events.yaml new file mode 100644 index 0000000000..fd119be3ea --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/events.yaml @@ -0,0 +1,20 @@ +get: + description: Returns a list of the current user’s events + operationId: findEvents + parameters: + responses: + "200": + content: + application/json: + schema: + $ref: "../components/schemas/EventList.yaml" + description: ok + "401": + content: + application/json: + schema: + $ref: "../components/schemas/Error.yaml" + description: unauthorized + summary: Retrieve current user's events + tags: + - Events diff --git a/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/events/id.yaml b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/events/id.yaml new file mode 100644 index 0000000000..ab793220d1 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/events/id.yaml @@ -0,0 +1,39 @@ +get: + description: Returns a single event if the user has access + operationId: findEventById + parameters: + - description: Event UUID + in: path + name: id + required: true + schema: + format: uuid + type: string + responses: + "200": + content: + application/json: + schema: + $ref: "../../components/schemas/Event.yaml" + description: ok + "401": + content: + application/json: + schema: + $ref: "../../components/schemas/Error.yaml" + description: unauthorized + "403": + content: + application/json: + schema: + $ref: "../../components/schemas/Error.yaml" + description: forbidden + "404": + content: + application/json: + schema: + $ref: "../../components/schemas/Error.yaml" + description: not found + summary: Retrieve an event + tags: + - Events diff --git a/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/organizations/id/events.yaml b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/organizations/id/events.yaml new file mode 100644 index 0000000000..b778851f9f --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/organizations/id/events.yaml @@ -0,0 +1,39 @@ +get: + description: Returns a list of events for a single organization + operationId: findOrganizationEvents + parameters: + - description: Organization UUID + in: path + name: id + required: true + schema: + format: uuid + type: string + responses: + "200": + content: + application/json: + schema: + $ref: "../../../components/schemas/EventList.yaml" + description: ok + "401": + content: + application/json: + schema: + $ref: "../../../components/schemas/Error.yaml" + description: unauthorized + "403": + content: + application/json: + schema: + $ref: "../../../components/schemas/Error.yaml" + description: forbidden + "404": + content: + application/json: + schema: + $ref: "../../../components/schemas/Error.yaml" + description: not found + summary: Retrieve organization's events + tags: + - Events diff --git a/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/projects/id/events.yaml b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/projects/id/events.yaml new file mode 100644 index 0000000000..93828fb412 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/projects/id/events.yaml @@ -0,0 +1,39 @@ +get: + description: Returns a list of events for a single project + operationId: findProjectEvents + parameters: + - description: Project UUID + in: path + name: id + required: true + schema: + format: uuid + type: string + responses: + "200": + content: + application/json: + schema: + $ref: "../../../components/schemas/EventList.yaml" + description: ok + "401": + content: + application/json: + schema: + $ref: "../../../components/schemas/Error.yaml" + description: unauthorized + "403": + content: + application/json: + schema: + $ref: "../../../components/schemas/Error.yaml" + description: forbidden + "404": + content: + application/json: + schema: + $ref: "../../../components/schemas/Error.yaml" + description: not found + summary: Retrieve project's events + tags: + - Events diff --git a/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/routes/id/events.yaml b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/routes/id/events.yaml new file mode 100644 index 0000000000..8cb492b933 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/routes/id/events.yaml @@ -0,0 +1,39 @@ +get: + description: Returns a list of the VRF route events + operationId: findVrfRouteEvents + parameters: + - description: VRF Route UUID + in: path + name: id + required: true + schema: + format: uuid + type: string + responses: + "200": + content: + application/json: + schema: + $ref: "../../../components/schemas/Event.yaml" + description: ok + "401": + content: + application/json: + schema: + $ref: "../../../components/schemas/Error.yaml" + description: unauthorized + "403": + content: + application/json: + schema: + $ref: "../../../components/schemas/Error.yaml" + description: forbidden + "404": + content: + application/json: + schema: + $ref: "../../../components/schemas/Error.yaml" + description: not found + summary: Retrieve VRF route events + tags: + - Events diff --git a/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/virtual-circuits/id/events.yaml b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/virtual-circuits/id/events.yaml new file mode 100644 index 0000000000..c3b46da5c8 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3.fetched/paths/virtual-circuits/id/events.yaml @@ -0,0 +1,39 @@ +get: + description: Returns a list of the virtual circuit events + operationId: findVirtualCircuitEvents + parameters: + - description: Virtual Circuit UUID + in: path + name: id + required: true + schema: + format: uuid + type: string + responses: + "200": + content: + application/json: + schema: + $ref: "../../../components/schemas/Event.yaml" + description: ok + "401": + content: + application/json: + schema: + $ref: "../../../components/schemas/Error.yaml" + description: unauthorized + "403": + content: + application/json: + schema: + $ref: "../../../components/schemas/Error.yaml" + description: forbidden + "404": + content: + application/json: + schema: + $ref: "../../../components/schemas/Error.yaml" + description: not found + summary: Retrieve virtual circuit events + tags: + - Events