From c84b49449a6811e8e92017720304dcd0c055780d Mon Sep 17 00:00:00 2001 From: andurairaj Date: Wed, 29 May 2024 12:21:17 +0530 Subject: [PATCH] Add ref handling for callbacks Add tests for ref fixes --- .../processors/ExternalRefProcessor.java | 121 +++++--- .../v3/parser/processors/PathsProcessor.java | 7 + .../v3/parser/test/OpenAPIV3RefTest.java | 87 ++++++ .../resources/callbacks-issue/domain.yaml | 13 +- .../post/vaccination_complete.json | 110 +++++++ .../parameter/header/correlation_id.json | 5 + .../header/adopt/correlation_id.json | 15 + .../components/schemas/adoption_request.json | 54 ++++ .../schemas/adoption_request_for_bird.json | 19 ++ .../schemas/adoption_request_for_cat.json | 24 ++ .../schemas/adoption_request_for_dog.json | 24 ++ .../schemas/adoption_request_for_fish.json | 19 ++ .../schemas/adoption_request_for_lizard.json | 24 ++ .../components/schemas/alias_array.json | 15 + .../components/schemas/animal_type.json | 20 ++ .../components/schemas/correlation_id.json | 8 + .../components/schemas/date_no_time.json | 7 + .../components/schemas/error.json | 57 ++++ .../components/schemas/error_details.json | 69 +++++ .../components/schemas/full_name.json | 7 + .../components/schemas/link_description.json | 93 ++++++ .../components/schemas/link_schema.json | 136 ++++++++ .../components/schemas/links.json | 17 + .../components/schemas/vaccination_order.json | 36 +++ .../schemas/vaccination_record.json | 37 +++ .../components/schemas/vaccinations.json | 10 + .../components/schemas/vaccine.json | 45 +++ .../components/schemas/vaccine_id.json | 9 + .../components/schemas/vaccine_name.json | 9 + .../resources/oas3-refs-test/openapi.json | 290 ++++++++++++++++++ .../resources/oas3-refs-test/paths/adopt.json | 171 +++++++++++ 31 files changed, 1508 insertions(+), 50 deletions(-) create mode 100644 modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3RefTest.java create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/callbacks/pets.id.order-vaccination/post/vaccination_complete.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/examples/parameter/header/correlation_id.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/parameters/header/adopt/correlation_id.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request_for_bird.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request_for_cat.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request_for_dog.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request_for_fish.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request_for_lizard.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/alias_array.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/animal_type.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/correlation_id.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/date_no_time.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/error.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/error_details.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/full_name.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/link_description.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/link_schema.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/links.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccination_order.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccination_record.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccinations.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccine.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccine_id.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccine_name.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/openapi.json create mode 100644 modules/swagger-parser-v3/src/test/resources/oas3-refs-test/paths/adopt.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 14005ecae6..8f9c92c77e 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 @@ -34,6 +34,7 @@ import io.swagger.v3.parser.ResolverCache; import io.swagger.v3.parser.models.RefFormat; import io.swagger.v3.parser.models.RefType; + import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.LoggerFactory; @@ -325,71 +326,75 @@ public PathItem processRefToExternalPathItem(String $ref, RefFormat refFormat) { cache.putRenamedRef($ref, newRef); if(pathItem != null) { - if(pathItem.readOperationsMap() != null) { - final Map operationMap = pathItem.readOperationsMap(); - for (PathItem.HttpMethod httpMethod : operationMap.keySet()) { - Operation operation = operationMap.get(httpMethod); - if (operation.getResponses() != null) { - final Map responses = operation.getResponses(); - if (responses != null) { - for (String responseCode : responses.keySet()) { - ApiResponse response = responses.get(responseCode); - if (response != null) { - Schema schema = null; - if (response.getContent() != null) { - Map content = response.getContent(); - for (String mediaName : content.keySet()) { - MediaType mediaType = content.get(mediaName); - if (mediaType.getSchema() != null) { - schema = mediaType.getSchema(); - if (schema != null) { - processRefSchemaObject(mediaType.getSchema(), $ref); - } - if (mediaType.getExamples() != null) { - processRefExamples(mediaType.getExamples(), $ref); - } + processPathItem(pathItem, $ref); + } + + return pathItem; + } + private void processPathItem(PathItem pathItem, String $ref) { + if(pathItem.readOperationsMap() != null) { + final Map operationMap = pathItem.readOperationsMap(); + for (PathItem.HttpMethod httpMethod : operationMap.keySet()) { + Operation operation = operationMap.get(httpMethod); + if (operation.getResponses() != null) { + final Map responses = operation.getResponses(); + if (responses != null) { + for (String responseCode : responses.keySet()) { + ApiResponse response = responses.get(responseCode); + if (response != null) { + Schema schema = null; + if (response.getContent() != null) { + Map content = response.getContent(); + for (String mediaName : content.keySet()) { + MediaType mediaType = content.get(mediaName); + if (mediaType.getSchema() != null) { + schema = mediaType.getSchema(); + if (schema != null) { + processRefSchemaObject(mediaType.getSchema(), $ref); + } + if (mediaType.getExamples() != null) { + processRefExamples(mediaType.getExamples(), $ref); } + } } - if (response.getLinks() != null) { - processRefLinks(response.getLinks(), $ref); - } - if (response.getHeaders() != null) { - processRefHeaders(response.getHeaders(), $ref); - } + } + if (response.getLinks() != null) { + processRefLinks(response.getLinks(), $ref); + } + if (response.getHeaders() != null) { + processRefHeaders(response.getHeaders(), $ref); } } } } - if (operation.getRequestBody() != null) { - RequestBody body = operation.getRequestBody(); - if (body.getContent() != null) { - Schema schema; - Map content = body.getContent(); - for (String mediaName : content.keySet()) { - MediaType mediaType = content.get(mediaName); - if (mediaType.getSchema() != null) { - schema = mediaType.getSchema(); - if (schema != null) { - processRefSchemaObject(mediaType.getSchema(), $ref); - } + } + if (operation.getRequestBody() != null) { + RequestBody body = operation.getRequestBody(); + if (body.getContent() != null) { + Schema schema; + Map content = body.getContent(); + for (String mediaName : content.keySet()) { + MediaType mediaType = content.get(mediaName); + if (mediaType.getSchema() != null) { + schema = mediaType.getSchema(); + if (schema != null) { + processRefSchemaObject(mediaType.getSchema(), $ref); } } } } + } - final List parameters = operation.getParameters(); - if (parameters != null) { - parameters.stream() - .filter(parameter -> parameter.getSchema() != null) - .forEach(parameter -> this.processRefSchemaObject(parameter.getSchema(), $ref)); - } + final List parameters = operation.getParameters(); + if (parameters != null) { + parameters.stream() + .filter(parameter -> parameter.getSchema() != null) + .forEach(parameter -> this.processRefSchemaObject(parameter.getSchema(), $ref)); } } } - - return pathItem; } private void processDiscriminator(Discriminator d, String file) { @@ -927,6 +932,24 @@ public String processRefToExternalCallback(String $ref, RefFormat refFormat) { processRefToExternalCallback(file + callback.get$ref(), RefFormat.RELATIVE); } } + } else { + for (String path : callback.keySet()) { + PathItem pathItem = callback.get(path); + if(pathItem != null) { + if (pathItem.get$ref() != null) { + RefFormat pathRefFormat = computeRefFormat(pathItem.get$ref()); + String path$ref = pathItem.get$ref(); + if (isAnExternalRefFormat(refFormat)) { + pathItem = this.processRefToExternalPathItem(path$ref, pathRefFormat); + } else { + pathItem = cache.loadRef(pathItem.get$ref(), refFormat, PathItem.class); + } + callback.put(path, pathItem); + } else { + this.processPathItem(pathItem, $ref); + } + } + } } } diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/PathsProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/PathsProcessor.java index 91c42e2ef5..94cecd6754 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/PathsProcessor.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/PathsProcessor.java @@ -19,8 +19,12 @@ import io.swagger.v3.parser.models.RefFormat; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.stream.Stream; import static io.swagger.v3.parser.util.RefUtils.computeRefFormat; import static io.swagger.v3.parser.util.RefUtils.isAnExternalRefFormat; @@ -155,6 +159,9 @@ protected void updateRefs(PathItem path, String pathRef) { for (String name : callbacks.keySet()) { Callback callback = callbacks.get(name); if (callback != null) { + if(callback.get$ref() != null) { + callback.set$ref(computeRef(callback.get$ref(), pathRef)); + } for(String callbackName : callback.keySet()) { PathItem pathItem = callback.get(callbackName); updateRefs(pathItem,pathRef); 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 new file mode 100644 index 0000000000..a3737f6345 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3RefTest.java @@ -0,0 +1,87 @@ +package io.swagger.v3.parser.test; + + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import org.junit.Before; +import org.junit.Test; +import org.testng.Assert; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.examples.Example; +import io.swagger.v3.oas.models.media.MediaType; +import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.parser.OpenAPIV3Parser; +import io.swagger.v3.parser.core.models.ParseOptions; + +import static io.swagger.v3.oas.models.Components.COMPONENTS_SCHEMAS_REF; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + + +public class OpenAPIV3RefTest { + private OpenAPI oas; + @Before + public void parseOASSpec() { + ParseOptions options = new ParseOptions(); + options.setResolve(true); + oas = new OpenAPIV3Parser().read("oas3-refs-test/openapi.json", null, options); + } + @Test + public void testParameterExampleRefProcessed() { + String paramName = "correlation_id"; + Map paramExamples = oas.getComponents().getParameters().get(paramName).getExamples(); + Assert.assertEquals(paramExamples.size(), 1, "Parameter has an example"); + Assert.assertTrue(paramExamples.values() + .stream().allMatch(e -> e.get$ref().equalsIgnoreCase("#/components/examples/" + paramName)), + "Examples are referenced"); + Assert.assertEquals(oas.getComponents().getExamples().get(paramName).getValue(), "7758b780aaaca", + "Examples are processed"); + } + + @Test + public void testDiscriminatorMappingRefsUpdated() { + Schema reqSchema = oas.getPaths().values().stream() + .findFirst() + .map(path -> path.getPost().getRequestBody().getContent().getOrDefault("application/json", null)) + .map(MediaType::getSchema) + .orElseThrow(() -> new IllegalStateException("Path not processed!")); + Collection discriminator = reqSchema.getDiscriminator().getMapping().values(); + 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"); + + } + + @Test + public void testCallbackRef() { + assertEquals(oas.getComponents().getCallbacks().size(), 1, "Callbacks processed"); + Operation cbOperation = oas.getComponents().getCallbacks() + .get("vaccination_complete") + .get("{$request.body#/callback_url}/pets/{$request.path.id}/vaccinations").getPut(); + assertNotNull(cbOperation); + assertEquals(cbOperation.getRequestBody().getContent().get("application/json").getSchema().get$ref(), + COMPONENTS_SCHEMAS_REF + "vaccination_record", "Callback Request body processed"); + assertEquals(cbOperation.getResponses().get("400").getContent().get("application/json").getSchema().get$ref(), + COMPONENTS_SCHEMAS_REF + "error" , "Callback responses Processed"); + } + + @Test + public void testComposedArrayItemsRef() { + Schema adoptionRequest = oas.getComponents() + .getSchemas().get("adoption_request"); + assertEquals(adoptionRequest.getTitle(), "Adoption Request", "Processed ref Schemas"); + assertEquals(((Schema) adoptionRequest.getProperties().get("adopter_alias")).get$ref(), + COMPONENTS_SCHEMAS_REF + "alias_array", "Processed ref added to Schemas"); + Schema adopterAlias = ((Schema) oas.getComponents().getSchemas().get("alias_array")); + assertEquals(adopterAlias.getTitle(),"AdopterAlias", "Processed Schemas"); + assertEquals(adopterAlias.getItems().getAllOf().size(), 2, "Processed schemas items"); + } +} diff --git a/modules/swagger-parser-v3/src/test/resources/callbacks-issue/domain.yaml b/modules/swagger-parser-v3/src/test/resources/callbacks-issue/domain.yaml index 4d6c85518c..f4fb27c4bc 100644 --- a/modules/swagger-parser-v3/src/test/resources/callbacks-issue/domain.yaml +++ b/modules/swagger-parser-v3/src/test/resources/callbacks-issue/domain.yaml @@ -31,4 +31,15 @@ components: $ref: '#/components/schemas/WebhookVerification' responses: '202': - description: Your server returns this code if it accepts the message it was sent \ No newline at end of file + description: Your server returns this code if it accepts the message it was sent + schemas: + WebhookVerification: + type: string + parameters: + x-api-key: + name: Correlation-Id + in: header + description: description + required: false + schema: + type: string \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/callbacks/pets.id.order-vaccination/post/vaccination_complete.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/callbacks/pets.id.order-vaccination/post/vaccination_complete.json new file mode 100644 index 0000000000..b3eb3c68eb --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/callbacks/pets.id.order-vaccination/post/vaccination_complete.json @@ -0,0 +1,110 @@ +{ + "{$request.body#/callback_url}/pets/{$request.path.id}/vaccinations": { + "put": { + "summary": "Vaccination record sent on completion", + "description": "New vaccination record for a pet sent after vaccination order is complete.", + "x-slo": { + "response_time_95th_percentile": 100, + "error_rate": 0.001 + }, + "x-visibility": { + "extent": "INTERNAL" + }, + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "../../../schemas/vaccination_record.json" + }, + "examples": { + "vaccination": { + "summary": "Vaccination with ID", + "description": "Vaccination record for pet with vaccination id.", + "value": { + "id": "8ce1edf4-3014-4b5c-b50d-9ed697768ead", + "vaccine_name": "Feline Viral Rhinotracheitis", + "administration_date": "2023-12-20" + } + } + } + } + } + }, + "responses": { + "204": { + "description": "Your server implementation should return this HTTP status code if the data was received successfully." + }, + "400": { + "description": "Your server should return this HTTP status code if the request is malformed.", + "content": { + "application/json": { + "schema": { + "$ref": "../../../schemas/error.json" + }, + "examples": { + "bad_vaccine_name": { + "summary": "Vaccine name is invalid.", + "value": { + "name": "INVALID_REQUEST", + "debug_id": "b1d1f06c7246c", + "message": "Request is not well-formed, syntactically incorrect, or violates schema.", + "details": [ + { + "field": "/vaccine_name", + "location": "body", + "value": "#bad-value#", + "issue": "INVALID_PARAMETER_SYNTAX", + "description": "The value of a field does not conform to the expected format." + } + ] + } + } + } + } + } + }, + "404": { + "description": "Your server should return this HTTP status code if the pet id is not found.", + "content": { + "application/json": { + "schema": { + "$ref": "../../../schemas/error.json" + }, + "examples": { + "generic": { + "summary": "Pet 'Not Found' error.", + "value": { + "name": "RESOURCE_NOT_FOUND", + "debug_id": "b1d1f06c7246c", + "message": "The specified resource does not exist." + } + } + } + } + } + }, + "500": { + "description": "Your server should return this HTTP status code if there is an internal error processing the request.", + "content": { + "application/json": { + "schema": { + "$ref": "../../../schemas/error.json" + }, + "examples": { + "generic": { + "summary": "Generic internal server error.", + "value": { + "name": "INTERNAL_SERVER_ERROR", + "debug_id": "b1d1f06c7246c", + "message": "An internal server error has occurred." + } + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/examples/parameter/header/correlation_id.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/examples/parameter/header/correlation_id.json new file mode 100644 index 0000000000..54e0f4c923 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/examples/parameter/header/correlation_id.json @@ -0,0 +1,5 @@ +{ + "summary": "A correlation id.", + "description": "A correlation-id header with a randomized id value.", + "value": "7758b780aaaca" +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/parameters/header/adopt/correlation_id.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/parameters/header/adopt/correlation_id.json new file mode 100644 index 0000000000..685192f47b --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/parameters/header/adopt/correlation_id.json @@ -0,0 +1,15 @@ +{ + "name": "Correlation-Id", + "in": "header", + "description": "Correlation ID for distributed tracing.", + "required": false, + "schema": { + "$ref": "../../../schemas/correlation_id.json" + }, + "examples": { + "correlation_id": { + "$ref": "../../../examples/parameter/header/correlation_id.json" + } + }, + "x-redacted": true +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request.json new file mode 100644 index 0000000000..4fe8f9acb5 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request.json @@ -0,0 +1,54 @@ +{ + "title": "Adoption Request", + "description": "A pet adoption request.", + "type": "object", + "required": [ + "animal_type", + "pet_id", + "adopter_name", + "adopter_address" + ], + "properties": { + "animal_type": { + "$ref": "./animal_type.json" + }, + "pet_id": { + "allOf": [ + { + "$ref": "correlation_id.json" + }, + { + "title": "Pet Id", + "description": "Unique ID of a pet.", + "x-redacted": true, + "readOnly": true + } + ] + }, + "adopter_name": { + "allOf": [ + { + "$ref": "vaccine_name.json" + }, + { + "description": "The adopter's name.", + "x-redacted": true + } + ] + }, + "adopter_alias" : { + "$ref": "./alias_array.json" + }, + "adopter_address": { + "allOf": [ + { + "$ref": "full_name.json" + }, + { + "description": "The adopter's address.", + "x-redacted": true + } + ] + } + } +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request_for_bird.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request_for_bird.json new file mode 100644 index 0000000000..de82a1aa33 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request_for_bird.json @@ -0,0 +1,19 @@ +{ + "allOf": [ + { + "$ref": "./adoption_request.json" + }, + { + "title": "Adoption Request for Bird", + "description": "A bird adoption request.", + "type": "object", + "properties": { + "have_birdcage": { + "description": "Indicates if the adopter has a birdcage.", + "type": "boolean", + "x-redacted": true + } + } + } + ] +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request_for_cat.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request_for_cat.json new file mode 100644 index 0000000000..86267aacb0 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request_for_cat.json @@ -0,0 +1,24 @@ +{ + "allOf": [ + { + "$ref": "./adoption_request.json" + }, + { + "title": "Adoption Request for Cat", + "description": "A cat adoption request.", + "type": "object", + "properties": { + "have_litter_box": { + "description": "Indicates if the adopter has a litter box.", + "type": "boolean", + "x-redacted": true + }, + "have_scratching_post": { + "description": "Indicates if the adopter has a scratching post.", + "type": "boolean", + "x-redacted": true + } + } + } + ] +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request_for_dog.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request_for_dog.json new file mode 100644 index 0000000000..e645a0257d --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request_for_dog.json @@ -0,0 +1,24 @@ +{ + "allOf": [ + { + "$ref": "./adoption_request.json" + }, + { + "title": "Adoption Request for Dog", + "description": "A dog adoption request.", + "type": "object", + "properties": { + "have_collar": { + "description": "Indicates if the adopter has a dog collar.", + "type": "boolean", + "x-redacted": true + }, + "have_leash": { + "description": "Indicates if the adopter has a dog leash.", + "type": "boolean", + "x-redacted": true + } + } + } + ] +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request_for_fish.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request_for_fish.json new file mode 100644 index 0000000000..84077eb02f --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request_for_fish.json @@ -0,0 +1,19 @@ +{ + "allOf": [ + { + "$ref": "./adoption_request.json" + }, + { + "title": "Adoption Request for Fish", + "description": "A fish adoption request.", + "type": "object", + "properties": { + "have_aquarium": { + "description": "Indicates if the adopter has an aquarium.", + "type": "boolean", + "x-redacted": false + } + } + } + ] +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request_for_lizard.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request_for_lizard.json new file mode 100644 index 0000000000..d55c2b5095 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/adoption_request_for_lizard.json @@ -0,0 +1,24 @@ +{ + "allOf": [ + { + "$ref": "./adoption_request.json" + }, + { + "title": "Adoption Request for Lizard", + "description": "A lizard adoption request.", + "type": "object", + "properties": { + "have_terrarium": { + "description": "Indicates if the adopter has a terrarium.", + "type": "boolean", + "x-redacted": false + }, + "have_heat_lamp": { + "description": "Indicates if the adopter has a heat lamp.", + "type": "boolean", + "x-redacted": true + } + } + } + ] +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/alias_array.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/alias_array.json new file mode 100644 index 0000000000..606a7f7f24 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/alias_array.json @@ -0,0 +1,15 @@ +{ + "type": "array", + "title": "AdopterAlias", + "items": { + "allOf": [ + { + "$ref": "full_name.json" + }, + { + "description": "The adopter's address.", + "x-redacted": true + } + ] + } +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/animal_type.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/animal_type.json new file mode 100644 index 0000000000..13b33d206f --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/animal_type.json @@ -0,0 +1,20 @@ +{ + "title": "Animal Type", + "description": "Type of animal.", + "type": "string", + "enum": [ + "BIRD", + "CAT", + "DOG", + "FISH", + "LIZARD" + ], + "x-enumDescriptions": { + "BIRD": "A warm-blooded egg-laying vertebrate distinguished by the possession of feathers, wings, and a beak and (typically) by being able to fly.", + "CAT": "A small domesticated carnivorous mammal with soft fur, a short snout, and retractable claws.", + "DOG": "A domesticated carnivorous mammal that typically has a long snout, an acute sense of smell, non-retractable claws, and a barking, howling, or whining voice.", + "FISH": "A limbless cold-blooded vertebrate animal with gills and fins and living wholly in water.", + "LIZARD": "A reptile that typically has a long body and tail, four legs, movable eyelids, and a rough, scaly, or spiny skin." + }, + "x-redacted": true +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/correlation_id.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/correlation_id.json new file mode 100644 index 0000000000..56df4a2fe3 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/correlation_id.json @@ -0,0 +1,8 @@ +{ + "title": "Correlation Id", + "description": "A correlation id used for debugging.", + "type": "string", + "minLength": 1, + "maxLength": 100, + "pattern": "^.*$" +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/date_no_time.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/date_no_time.json new file mode 100644 index 0000000000..963cfed256 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/date_no_time.json @@ -0,0 +1,7 @@ +{ + "type": "string", + "description": "The stand-alone date, in [Internet date and time format](https://tools.ietf.org/html/rfc3339#section-5.6). To represent special legal values, such as a date of birth, you should use dates with no associated time or time-zone data. Whenever possible, use the standard `date_time` type. This regular expression does not validate all dates. For example, February 31 is valid and nothing is known about leap years.", + "minLength": 10, + "maxLength": 10, + "pattern": "^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$" +} diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/error.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/error.json new file mode 100644 index 0000000000..95fb091002 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/error.json @@ -0,0 +1,57 @@ +{ + "title": "Error", + "description": "The error details.", + "type": "object", + "required": [ + "name", + "message", + "debug_id" + ], + "properties": { + "name": { + "description": "The human-readable, unique name of the error.", + "type": "string", + "minLength": 0, + "maxLength": 10000, + "pattern": "^.*$", + "x-redacted": false + }, + "message": { + "description": "The message that describes the error.", + "type": "string", + "minLength": 0, + "maxLength": 100000, + "pattern": "^.*$", + "x-redacted": true + }, + "debug_id": { + "allOf": [ + { + "$ref": "correlation_id.json" + }, + { + "description": "Trace ID, used for correlation purposes.", + "x-redacted": true + } + ] + }, + "details": { + "description": "An array of additional details about the error.", + "type": "array", + "minItems": 0, + "maxItems": 10000, + "items": { + "$ref": "error_details.json" + } + }, + "links": { + "description": "An array of request-related [HATEOAS links](/api/rest/responses/#hateoas-links).", + "type": "array", + "minItems": 0, + "maxItems": 10000, + "items": { + "$ref": "./link_description.json" + } + } + } +} diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/error_details.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/error_details.json new file mode 100644 index 0000000000..e70b7bb172 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/error_details.json @@ -0,0 +1,69 @@ +{ + "title": "Error Details", + "description": "The error details. Required for client-side `4XX` errors.", + "type": "object", + "required": [ + "issue" + ], + "properties": { + "field": { + "description": "The field that caused the error. If this field is in the body, set this value to the field's JSON pointer value. Required for client-side errors.", + "type": "string", + "minLength": 0, + "maxLength": 10000, + "pattern": "^.*$", + "x-redacted": true + }, + "value": { + "description": "The value of the field that caused the error.", + "type": "string", + "minLength": 0, + "maxLength": 100000, + "pattern": "^.*$", + "x-redacted": true + }, + "location": { + "description": "The location of the field that caused the error.", + "type": "string", + "default": "body", + "enum": [ + "body", + "header", + "path", + "query" + ], + "x-enumDescriptions": { + "body": "The field is in the request body.", + "header": "The field is a header.", + "path": "The field is a path parameter.", + "query": "The field is a query parameter." + }, + "x-redacted": true + }, + "issue": { + "description": "The unique, fine-grained application-level error code.", + "type": "string", + "minLength": 0, + "maxLength": 100000, + "pattern": "^.*$", + "x-redacted": false + }, + "links": { + "description": "An array of request-related [HATEOAS links](/api/rest/responses/#hateoas-links) that are either relevant to the issue by providing additional information or offering potential resolutions.", + "type": "array", + "minItems": 1, + "maxItems": 4, + "items": { + "$ref": "./link_description.json" + } + }, + "description": { + "description": "The human-readable description for an issue. The description can change over the lifetime of an API, so clients must not depend on this value.", + "type": "string", + "minLength": 0, + "maxLength": 100000, + "pattern": "^.*$", + "x-redacted": false + } + } +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/full_name.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/full_name.json new file mode 100644 index 0000000000..bc1f16c279 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/full_name.json @@ -0,0 +1,7 @@ +{ + "title": "Name", + "description": "Name of the Pet.", + "type": "string", + "minLength": 1, + "maxLength": 100 +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/link_description.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/link_description.json new file mode 100644 index 0000000000..4c05c2de21 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/link_description.json @@ -0,0 +1,93 @@ +{ + "title": "Link Description", + "description": "The request-related [HATEOAS link](/api/rest/responses/#hateoas-links) information.", + "type": "object", + "required": [ + "href", + "rel" + ], + "properties": { + "href": { + "description": "The complete target URL. To make the related call, combine the method with this [URI Template-formatted](https://tools.ietf.org/html/rfc6570) link. For pre-processing, include the `$`, `(`, and `)` characters. The `href` is the key HATEOAS component that links a completed call with a subsequent call.", + "type": "string", + "minLength": 0, + "maxLength": 20000, + "pattern": "^.*$", + "x-redacted": false + }, + "rel": { + "description": "The [link relation type](https://tools.ietf.org/html/rfc5988#section-4), which serves as an ID for a link that unambiguously describes the semantics of the link. See [Link Relations](https://www.iana.org/assignments/link-relations/link-relations.xhtml).", + "type": "string", + "minLength": 0, + "maxLength": 100, + "pattern": "^.*$", + "x-redacted": false + }, + "method": { + "description": "The HTTP method required to make the related call.", + "type": "string", + "enum": [ + "CONNECT", + "DELETE", + "GET", + "HEAD", + "OPTIONS", + "PATCH", + "POST", + "PUT" + ], + "x-redacted": false + }, + "title": { + "description": "The link title.", + "type": "string", + "minLength": 0, + "maxLength": 1000, + "pattern": "^.*$", + "x-redacted": false + }, + "mediaType": { + "description": "The media type, as defined by [RFC 2046](https://www.ietf.org/rfc/rfc2046.txt). Describes the link target.", + "type": "string", + "minLength": 0, + "maxLength": 255, + "pattern": "^[a-zA-Z\\-/\\.0-9\\+]+$", + "x-redacted": true + }, + "encType": { + "description": "The media type in which to submit the request data.", + "type": "string", + "minLength": 0, + "maxLength": 255, + "pattern": "^[a-zA-Z\\-/\\.0-9\\+]+$", + "default": "application/json", + "x-redacted": true + }, + "schema": { + "allOf": [ + { + "$ref": "link_schema.json" + }, + { + "description": "The schema that describes the request data.", + "x-visibility": { + "extent": "INTERNAL" + } + } + ] + }, + "targetSchema": { + "allOf": [ + { + "$ref": "link_schema.json" + }, + { + "description": "The schema that describes the link target.", + "x-visibility": { + "extent": "INTERNAL" + } + } + ] + } + } +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/link_schema.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/link_schema.json new file mode 100644 index 0000000000..da9427b9d4 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/link_schema.json @@ -0,0 +1,136 @@ +{ + "title": "Link Schema", + "description": "The request data or link target.", + "type": "object", + "properties": { + "additionalItems": { + "title": "Additional Items", + "description": "Any additional items.", + "type": "object", + "x-redacted": false + }, + "dependencies": { + "title": "Dependencies", + "description": "The dependencies.", + "type": "object", + "x-redacted": false + }, + "items": { + "title": "Items", + "description": "An item.", + "type": "object", + "x-redacted": false + }, + "definitions": { + "title": "Definitions", + "description": "The definitions.", + "type": "object", + "x-redacted": false + }, + "patternProperties": { + "title": "Pattern Properties", + "description": "The pattern properties.", + "type": "object", + "x-redacted": false + }, + "properties": { + "title": "Properties", + "description": "The properties.", + "type": "object", + "x-redacted": false + }, + "allOf": { + "description": "An array of sub-schemas. The data must validate against all sub-schemas.", + "type": "array", + "minItems": 0, + "maxItems": 10000, + "items": { + "title": "All Of Item", + "description": "A sub-schema against which the data must validate.", + "type": "object", + "x-redacted": true + } + }, + "anyOf": { + "description": "An array of sub-schemas. The data must validate against one or more sub-schemas.", + "type": "array", + "minItems": 0, + "maxItems": 10000, + "items": { + "title": "Any Of Item", + "description": "A sub-schema against which the data must validate.", + "type": "object", + "x-redacted": true + } + }, + "oneOf": { + "description": "An array of sub-schemas. The data must validate against one sub-schema.", + "type": "array", + "minItems": 0, + "maxItems": 10000, + "items": { + "title": "One Of Item", + "description": "A sub-schema against which the data must validate.", + "type": "object", + "x-redacted": false + } + }, + "not": { + "title": "Not", + "description": "Not.", + "type": "object", + "x-redacted": false + }, + "links": { + "description": "An array of links.", + "type": "array", + "minItems": 0, + "maxItems": 10000, + "items": { + "title": "Link", + "description": "A link.", + "type": "object", + "x-redacted": false + } + }, + "fragmentResolution": { + "description": "The fragment resolution.", + "type": "string", + "minLength": 0, + "maxLength": 10000, + "pattern": "^.*$", + "x-redacted": false + }, + "media": { + "title": "Media", + "description": "The media type and context-encoding scheme.", + "type": "object", + "properties": { + "type": { + "description": "The media type. See [Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types](https://tools.ietf.org/html/rfc2046).", + "type": "string", + "minLength": 0, + "maxLength": 255, + "pattern": "^[a-zA-Z\\-/\\.0-9\\+]+$", + "x-redacted": false + }, + "binaryEncoding": { + "description": "The content-encoding scheme. See [Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies](https://tools.ietf.org/html/rfc2045).", + "type": "string", + "minLength": 0, + "maxLength": 255, + "pattern": "^[a-zA-Z\\-/\\.0-9\\+]+$", + "x-redacted": false + } + } + }, + "pathStart": { + "description": "To apply this schema to the instances' URIs, start the URIs with this value.", + "type": "string", + "minLength": 0, + "maxLength": 10000, + "format": "uri", + "x-redacted": true + } + } +} diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/links.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/links.json new file mode 100644 index 0000000000..6674eec595 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/links.json @@ -0,0 +1,17 @@ +{ + "title": "Links", + "description": "Resource links.", + "type": "array", + "minItems": 1, + "maxItems": 100, + "items": { + "allOf": [ + { + "$ref": "../../common_components/v5/schema/json/openapi-3.0/components/schemas/rest/link_description.json" + }, + { + "x-redacted": false + } + ] + } +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccination_order.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccination_order.json new file mode 100644 index 0000000000..ffd0c2c130 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccination_order.json @@ -0,0 +1,36 @@ +{ + "title": "Vaccination Order", + "description": "An order to perform a vaccination.", + "type": "object", + "required": [ + "vaccine_name", + "by_date" + ], + "properties": { + "vaccine_name": { + "$ref": "./vaccine_name.json" + }, + "by_date": { + "allOf": [ + { + "$ref": "../../common_components/v5/schema/json/openapi-3.0/components/schemas/date_time/date_no_time.json" + }, + { + "description": "Date vaccine must be administered by.", + "x-redacted": true + } + ] + }, + "after_date": { + "allOf": [ + { + "$ref": "../../common_components/v5/schema/json/openapi-3.0/components/schemas/date_time/date_no_time.json" + }, + { + "description": "Date vaccine must be administered after.", + "x-redacted": true + } + ] + } + } +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccination_record.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccination_record.json new file mode 100644 index 0000000000..ba3d092f5f --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccination_record.json @@ -0,0 +1,37 @@ +{ + "title": "Vaccination Record", + "description": "Record of an administered vaccination.", + "type": "object", + "required": [ + "id", + "vaccine_name", + "administration_date" + ], + "properties": { + "id": { + "allOf": [ + { + "$ref": "./correlation_id.json" + }, + { + "description": "Unique ID of a vaccination.", + "x-redacted": true + } + ] + }, + "vaccine_name": { + "$ref": "./vaccine_name.json" + }, + "administration_date": { + "allOf": [ + { + "$ref": "./date_no_time.json" + }, + { + "description": "Date vaccine administered.", + "x-redacted": true + } + ] + } + } +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccinations.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccinations.json new file mode 100644 index 0000000000..7da3a9b60d --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccinations.json @@ -0,0 +1,10 @@ +{ + "title": "Vaccinations", + "description": "List of vaccinations.", + "type": "array", + "minItems": 1, + "maxItems": 1000, + "items": { + "$ref": "./vaccination_record.json" + } +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccine.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccine.json new file mode 100644 index 0000000000..1844e59b62 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccine.json @@ -0,0 +1,45 @@ +{ + "title": "Vaccine", + "description": "Information about a vaccine that may be administered. Vaccine information is owned by an outside partner. The information is available in the pet store so that employees may administer available vaccines based on the vaccine information.", + "type": "object", + "required": [ + "id", + "vaccine_name", + "number_of_doses" + ], + "properties": { + "id": { + "$ref": "./vaccine_id.json" + }, + "vaccine_name": { + "$ref": "./vaccine_name.json" + }, + "animal_types": { + "description": "The types of animals that may receive this vaccine.", + "type": "array", + "minItems": 1, + "maxItems": 100, + "items": { + "$ref": "./animal_type.json" + } + }, + "number_of_doses": { + "description": "The number of doses to administer for the vaccine to be effective.", + "type": "integer", + "minimum": 1, + "maximum": 10, + "x-redacted": false + }, + "interval_between_doses": { + "allOf": [ + { + "$ref": "../../common_components/v5/schema/json/openapi-3.0/components/schemas/date_time/time_duration.json" + }, + { + "description": "The time between doses if more than one dose is required.", + "x-redacted": true + } + ] + } + } +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccine_id.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccine_id.json new file mode 100644 index 0000000000..48fe09faba --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccine_id.json @@ -0,0 +1,9 @@ +{ + "title": "Vaccine ID", + "description": "Unique ID of a vaccine as defined by the external partner's system.", + "type": "string", + "minLength": 1, + "maxLength": 5000, + "pattern": "^.*$", + "x-redacted": false +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccine_name.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccine_name.json new file mode 100644 index 0000000000..73f537dc81 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/components/schemas/vaccine_name.json @@ -0,0 +1,9 @@ +{ + "title": "Vaccine Name", + "description": "Name of the vaccine.", + "type": "string", + "minLength": 1, + "maxLength": 1000, + "pattern": "^[A-Za-z0-9 ]+$", + "x-redacted": true +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/openapi.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/openapi.json new file mode 100644 index 0000000000..4f097756d6 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/openapi.json @@ -0,0 +1,290 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "OpenAPI 3.0 Specification Reference", + "description": "This specification demonstrates ref uses.", + "version": "1.1", + "contact": { + "name": "Another OAS 3 User", + "url": "https://example.com/", + "email": "antho93@gmail.com" + } + }, + "servers": [ + { + "url": "https://{host}/v1/demo", + "description": "LIVE", + "variables": { + "host": { + "enum": [ + "api.example.com", + "api-m.example.com" + ], + "default": "api.example.com" + } + } + }, + { + "url": "https://api.sandbox.example.com/v1/demo", + "description": "Sandbox." + } + ], + "tags": [ + { + "name": "adoption", + "description": "Adopt Pets" + } + ], + "paths": { + "/adopt": { + "$ref": "./paths/adopt.json" + } + }, + "components" : { + "schemas": { + "an-object": { + "type": "object", + "properties": { + "an-array": { + "$ref": "./components/schemas/alias_array.json" + } + } + } + }, + "responses": { + "204_response": { + "description": "No Content." + }, + "401_error_response": { + "description": "Unauthorized.", + "content": { + "application/json": { + "schema": { + "$ref": "components/schemas/error.json" + }, + "examples": { + "generic": { + "summary": "Generic 'Unauthorized' error.", + "value": { + "name": "AUTHENTICATION_FAILURE", + "debug_id": "b1d1f06c7246c", + "message": "Authentication failed due to missing Authorization header, or invalid authentication credentials." + } + } + } + } + } + }, + "403_error_response": { + "description": "Forbidden.", + "content": { + "application/json": { + "schema": { + "$ref": "components/schemas/error.json" + }, + "examples": { + "generic": { + "summary": "Generic 'Forbidden' error.", + "value": { + "name": "NOT_AUTHORIZED", + "debug_id": "b1d1f06c7246c", + "message": "Authorization failed due to insufficient permissions." + } + } + } + } + } + }, + "404_error_response": { + "description": "Not Found.", + "content": { + "application/json": { + "schema": { + "$ref": "components/schemas/error.json" + }, + "examples": { + "generic": { + "summary": "Generic 'Not Found' error.", + "value": { + "name": "RESOURCE_NOT_FOUND", + "debug_id": "b1d1f06c7246c", + "message": "The specified resource does not exist." + } + } + } + } + } + }, + "405_error_response": { + "description": "Method Not Allowed.", + "content": { + "application/json": { + "schema": { + "$ref": "components/schemas/error.json" + }, + "examples": { + "generic": { + "summary": "Generic 'Method Not Allowed' error.", + "value": { + "name": "METHOD_NOT_SUPPORTED", + "debug_id": "b1d1f06c7246c", + "message": "The server does not implement the requested HTTP method." + } + } + } + } + } + }, + "406_error_response": { + "description": "Not Acceptable.", + "content": { + "application/json": { + "schema": { + "$ref": "components/schemas/error.json" + }, + "examples": { + "generic": { + "summary": "Generic 'Not Acceptable' error.", + "value": { + "name": "MEDIA_TYPE_NOT_ACCEPTABLE", + "debug_id": "b1d1f06c7246c", + "message": "The server does not implement the media type that would be acceptable to the client." + } + } + } + } + } + }, + "410_error_response": { + "description": "Gone.", + "content": { + "application/json": { + "schema": { + "$ref": "components/schemas/error.json" + }, + "examples": { + "generic": { + "summary": "Generic 'Gone' error.", + "value": { + "name": "RESOURCE_NOT_AVAILABLE", + "debug_id": "b1d1f06c7246c", + "message": "The requested resource is no longer available." + } + } + } + } + } + }, + "413_error_response": { + "description": "Payload Too Large.", + "content": { + "application/json": { + "schema": { + "$ref": "components/schemas/error.json" + }, + "examples": { + "generic": { + "summary": "Generic 'Payload Too Large' error.", + "value": { + "name": "PAYLOAD_TOO_LARGE", + "debug_id": "b1d1f06c7246c", + "message": "The request entity is larger than the size limit defined by the server." + } + } + } + } + } + }, + "415_error_response": { + "description": "Unsupported Media Type.", + "content": { + "application/json": { + "schema": { + "$ref": "components/schemas/error.json" + }, + "examples": { + "generic": { + "summary": "Generic 'Unsupported Media Type' error.", + "value": { + "name": "UNSUPPORTED_MEDIA_TYPE", + "debug_id": "b1d1f06c7246c", + "message": "The server does not support the request payload's media type." + } + } + } + } + } + }, + "429_error_response": { + "description": "Too Many Requests.", + "content": { + "application/json": { + "schema": { + "$ref": "components/schemas/error.json" + }, + "examples": { + "generic": { + "summary": "Generic 'Too Many Requests' error.", + "value": { + "name": "RATE_LIMIT_REACHED", + "debug_id": "b1d1f06c7246c", + "message": "Too many requests. Blocked due to rate limiting." + } + } + } + } + } + }, + "500_error_response": { + "description": "Internal Server Error.", + "content": { + "application/json": { + "schema": { + "$ref": "components/schemas/error.json" + }, + "examples": { + "generic": { + "summary": "Generic internal server error.", + "value": { + "name": "INTERNAL_SERVER_ERROR", + "debug_id": "b1d1f06c7246c", + "message": "An internal server error has occurred." + } + } + } + } + } + }, + "503_error_response": { + "description": "Service Unavailable.", + "content": { + "application/json": { + "schema": { + "$ref": "components/schemas/error.json" + }, + "examples": { + "generic": { + "summary": "Generic 'Service Unavailable' error.", + "value": { + "name": "SERVICE_UNAVAILABLE", + "debug_id": "b1d1f06c7246c", + "message": "Service Unavailable." + } + } + } + } + } + }, + "default_response": { + "description": "Default response.", + "content": { + "application/json": { + "schema": { + "$ref": "components/schemas/error.json" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/paths/adopt.json b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/paths/adopt.json new file mode 100644 index 0000000000..3de7cd2a9d --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/oas3-refs-test/paths/adopt.json @@ -0,0 +1,171 @@ +{ + "post": { + "tags": [ + "pets" + ], + "summary": "Adopt Pet", + "description": "Adopt a pet.", + "operationId": "adopt", + "x-slo": { + "response_time_95th_percentile": 220, + "error_rate": 0.004 + }, + "parameters": [ + { + "$ref": "../components/parameters/header/adopt/correlation_id.json" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "../components/schemas/adoption_request_for_bird.json" + }, + { + "$ref": "../components/schemas/adoption_request_for_cat.json" + }, + { + "$ref": "../components/schemas/adoption_request_for_dog.json" + }, + { + "$ref": "../components/schemas/adoption_request_for_fish.json" + }, + { + "$ref": "../components/schemas/adoption_request_for_lizard.json" + } + ], + "discriminator": { + "propertyName": "animal_type", + "mapping": { + "BIRD": "../components/schemas/adoption_request_for_bird.json", + "CAT": "../components/schemas/adoption_request_for_cat.json", + "DOG": "../components/schemas/adoption_request_for_dog.json", + "FISH": "../components/schemas/adoption_request_for_fish.json", + "LIZARD": "../components/schemas/adoption_request_for_lizard.json" + } + } + }, + "examples": { + "success": { + "summary": "Successful Adoption Request", + "description": "A request for adoption resulting in success.", + "value": { + "pet_id": "d1ef2439-3a70-4d0b-aef0-48a9a485ef95", + "adopter_name": { + "name": "Suzy McGee" + }, + "adopter_alias": [ + "Suzy M" + ], + "adopter_address": { + "address_line_1": "23 Maple Ave", + "address_line_2": "Apt 3", + "admin_area_2": "Bangor", + "admin_area_1": "ME", + "postal_code": "04401", + "country_code": "US" + }, + "animal_type": "CAT", + "have_litter_box": true, + "have_scratching_post": false + } + } + } + } + } + }, + "responses": { + "204": { + "description": "Successful adoption." + }, + "400": { + "description": "Bad request.", + "content": { + "application/json": { + "schema": { + "$ref": "../components/schemas/error.json" + }, + "examples": { + "missing_pet_id": { + "summary": "Missing required parameter, pet_id.", + "value": { + "name": "INVALID_REQUEST", + "debug_id": "b1d1f06c7246c", + "message": "Request is not well-formed, syntactically incorrect, or violates schema.", + "details": [ + { + "field": "/pet_id", + "location": "body", + "issue": "MISSING_REQUIRED_PARAMETER", + "description": "A required field or parameter is missing." + } + ] + } + } + } + } + } + }, + "403": { + "$ref": "../openapi.json#/components/responses/403_error_response" + }, + "422": { + "description": "Unprocessable entity.", + "content": { + "application/json": { + "schema": { + "$ref": "../components/schemas/error.json" + }, + "examples": { + "risk_assessment_deny": { + "summary": "Deny adoption based on risk assessment.", + "value": { + "name": "UNPROCESSABLE_ENTITY", + "debug_id": "b1d1f06c7246c", + "message": "The requested action could not be performed, semantically incorrect, or failed business validation.", + "details": [ + { + "issue": "RISK_ASSESSMENT_DENY", + "description": "Risk assessment determined that the requested action is denied." + } + ] + } + }, + "unknown_pet_id": { + "summary": "Pet with id not found.", + "value": { + "name": "UNPROCESSABLE_ENTITY", + "debug_id": "b1d1f06c7246c", + "message": "The requested action could not be performed, semantically incorrect, or failed business validation.", + "details": [ + { + "field": "/pet_id", + "location": "body", + "value": "d1ef2439-3a70-4d0b-aef0-48a9a485ef97", + "issue": "PET_NOT_FOUND", + "description": "No pet found with the specified id." + } + ] + } + } + } + } + } + }, + "500": { + "$ref": "../openapi.json#/components/responses/500_error_response" + }, + "default": { + "$ref": "../openapi.json#/components/responses/default_response" + } + }, + "callbacks": { + "vaccination_complete": { + "$ref": "../components/callbacks/pets.id.order-vaccination/post/vaccination_complete.json" + } + } + } +} \ No newline at end of file