From e622284ebabf7359115de79909e78acf237b8d00 Mon Sep 17 00:00:00 2001 From: Jasper Linschoten Date: Thu, 26 Aug 2021 14:46:13 +0200 Subject: [PATCH 1/4] Resolve references to other path operations' examples (as created by swagger-cli) --- .../oss/codegen/doc/BoatExampleUtils.java | 118 ++++++++++++++++-- .../oss/codegen/doc/BoatDocsTest.java | 5 + .../oas-examples/petstore-example-refs.yaml | 116 +++++++++++++++++ 3 files changed, 226 insertions(+), 13 deletions(-) create mode 100644 boat-scaffold/src/test/resources/oas-examples/petstore-example-refs.yaml diff --git a/boat-scaffold/src/main/java/com/backbase/oss/codegen/doc/BoatExampleUtils.java b/boat-scaffold/src/main/java/com/backbase/oss/codegen/doc/BoatExampleUtils.java index 131f3fa92..46f03e3da 100644 --- a/boat-scaffold/src/main/java/com/backbase/oss/codegen/doc/BoatExampleUtils.java +++ b/boat-scaffold/src/main/java/com/backbase/oss/codegen/doc/BoatExampleUtils.java @@ -1,11 +1,16 @@ package com.backbase.oss.codegen.doc; +import com.backbase.oss.boat.transformers.OpenApiStreamUtil; import com.fasterxml.jackson.databind.node.ObjectNode; import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.PathItem; import io.swagger.v3.oas.models.examples.Example; import io.swagger.v3.oas.models.media.ArraySchema; +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 java.util.Arrays; import java.util.List; import lombok.experimental.UtilityClass; import lombok.extern.slf4j.Slf4j; @@ -16,6 +21,10 @@ @SuppressWarnings("java:S3740") public class BoatExampleUtils { + private static final String PATHS_REF_PREFIX = "#/paths"; + private static final String COMPONENTS_EXAMPLES_REF_PREFIX = "#/components/examples/"; + + public static void convertExamples(OpenAPI openAPI, MediaType mediaType, String responseCode, String contentType, List examples) { if (mediaType.getExample() != null) { Object example = mediaType.getExample(); @@ -66,23 +75,106 @@ public static void inlineExamples(String name, List examples, OpenA .filter(boatExample -> boatExample.getExample().get$ref() != null) .forEach(boatExample -> { String ref = boatExample.getExample().get$ref(); - if (ref.startsWith("#/components/examples")) { - ref = StringUtils.substringAfterLast(ref, "/"); - if (openAPI.getComponents() != null && openAPI.getComponents().getExamples() != null) { - Example example = openAPI.getComponents().getExamples().get(ref); - if (example == null) { - log.warn("Example ref: {} used in: {} refers to an example that does not exist", ref, name); - } else { - log.debug("Replacing Example ref: {} used in: {} with example from components: {}", ref, name, example); - boatExample.setExample(example); - } - } else { - log.warn("Example ref: {} used in: {} refers to an example that does not exist", ref, name); - } + if (ref.startsWith(COMPONENTS_EXAMPLES_REF_PREFIX)) { + resolveComponentsExamples(name, openAPI, boatExample, ref); + } else if (ref.startsWith(PATHS_REF_PREFIX)) { + resolvePathsExamples(name, openAPI, boatExample, ref); } else { log.warn("Example ref: {} used in: {} refers to an example that does not exist", ref, name); } }); } + private static void resolveComponentsExamples( + String name, OpenAPI openAPI, BoatExample boatExample, String ref) { + String exampleName = ref.replace(COMPONENTS_EXAMPLES_REF_PREFIX, ""); + if (openAPI.getComponents() == null || openAPI.getComponents().getExamples() == null) { + log.warn("Example ref: {} used in: {} refers to an example that does not exist", ref, name); + return; + } + Example example = openAPI.getComponents().getExamples().get(exampleName); + if (example == null) { + log.warn("Example ref: {} used in: {} refers to an example that does not exist", ref, name); + return; + } + log.debug("Replacing Example ref: {} used in: {} with example from components: {}", ref, name, example); + boatExample.setExample(example); + } + + private static void resolvePathsExamples( + String name, OpenAPI openAPI, BoatExample boatExample, String ref) { + + // #/paths/ + // ~1client-api~1v2~1accounts~1balance-history~1%7BarrangementIds%7D/ + // get/ + // responses/ + // 200/ + // content/ + // text~1csv/ + // example + if (openAPI.getPaths() == null) { + log.warn("Example ref: {} refers to '/paths' but it is not there.", ref); + return; + } + String[] refParts = Arrays.stream(ref.replace(PATHS_REF_PREFIX, "").split("/")) + .map(s -> s.replace("~1", "/")) + .toArray(String[]::new); + + String pathName = refParts[1]; + PathItem pathItem = openAPI.getPaths().get(pathName); + if (pathItem == null) { + log.warn("Example ref: {} refers to path {} but it is not defined.", ref, pathName); + return; + } + + String operationName = refParts[2]; + Operation operation = findOperation(pathItem, operationName); + if (operation == null) { + log.warn("Example ref: {} refers to operation {} but it is not defined.", ref, operationName); + return; + } + + Content content = null; + String mediaTypeName = null; + if ("requestBody".equals(refParts[3])) { + content = operation.getRequestBody().getContent(); + mediaTypeName = refParts[5]; + } else { + content = operation.getResponses().get(refParts[4]).getContent(); + mediaTypeName = refParts[6]; + } + if (content == null) { + log.warn("Example ref: {} refers to content that is not defined.", ref); + return; + } + + MediaType mediaType = content.get(mediaTypeName); + if (mediaType == null) { + log.warn("Example ref: {} refers to mediaType {} that is not defined.", ref, mediaTypeName); + return; + } + + Example example = new Example().value(mediaType.getExample()); + log.debug("Replacing Example ref: {} used in: {} with example from components: {}", ref, name, example); + boatExample.setExample(example); + } + + private static Operation findOperation(PathItem pathItem, String operationName) { + String o = operationName.toLowerCase(); + switch (o) { + case "get": + return pathItem.getGet(); + case "post": + return pathItem.getPost(); + case "put": + return pathItem.getPut(); + case "patch": + return pathItem.getPatch(); + case "delete": + return pathItem.getDelete(); + default: + throw new IllegalArgumentException("Unsupported operationName " + o); + } + } + } diff --git a/boat-scaffold/src/test/java/com/backbase/oss/codegen/doc/BoatDocsTest.java b/boat-scaffold/src/test/java/com/backbase/oss/codegen/doc/BoatDocsTest.java index e84020e72..f31326839 100644 --- a/boat-scaffold/src/test/java/com/backbase/oss/codegen/doc/BoatDocsTest.java +++ b/boat-scaffold/src/test/java/com/backbase/oss/codegen/doc/BoatDocsTest.java @@ -34,6 +34,11 @@ void testOpenAPiWithExamples() throws OpenAPILoaderException { assertDoesNotThrow(() -> generateDocs(getFile("/openapi-with-examples/openapi.yaml"))); } + @Test + public void testGenerateDocsExampleRefs() { + assertDoesNotThrow(() -> generateDocs(getFile("/oas-examples/petstore-example-refs.yaml"))); + } + @Test void testGenerateDocs() throws IOException { generateDocs(getFile("/openapi-with-examples/openapi-with-json.yaml")); diff --git a/boat-scaffold/src/test/resources/oas-examples/petstore-example-refs.yaml b/boat-scaffold/src/test/resources/oas-examples/petstore-example-refs.yaml new file mode 100644 index 000000000..23adb755a --- /dev/null +++ b/boat-scaffold/src/test/resources/oas-examples/petstore-example-refs.yaml @@ -0,0 +1,116 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore + license: + name: MIT +servers: + - url: http://petstore.swagger.io/v1 +paths: + /pets: + get: + summary: List all pets + operationId: listPets + tags: + - pets + parameters: + - name: limit + in: query + description: How many items to return at one time (max 100) + required: false + schema: + type: integer + format: int32 + responses: + '200': + description: A paged array of pets + headers: + x-next: + description: A link to the next page of responses + schema: + type: string + content: + application/json: + schema: + $ref: "#/components/schemas/Pets" + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + example: + code: 43 + message: "Overshot" + post: + summary: Create a pet + operationId: createPets + tags: + - pets + responses: + '201': + description: Null response + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + example: + $ref: "#/paths/~1pets/get/responses/default/content/application~1json/example" + /pets/{petId}: + get: + summary: Info for a specific pet + operationId: showPetById + tags: + - pets + parameters: + - name: petId + in: path + required: true + description: The id of the pet to retrieve + schema: + type: string + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: "#/components/schemas/Pet" + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" +components: + schemas: + Pet: + type: object + required: + - id + - name + properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string + Pets: + type: array + items: + $ref: "#/components/schemas/Pet" + Error: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string \ No newline at end of file From d59e6080fb54e064c7b1431de1eec2c1a94de925 Mon Sep 17 00:00:00 2001 From: Bart Veenstra Date: Mon, 30 Aug 2021 09:51:43 +0200 Subject: [PATCH 2/4] Always show warning when transforming invalid references to examples. Code quality improvements --- .../oss/boat/transformers/Decomposer.java | 2 +- .../boat/GenerateFromDirectoryDocMojo.java | 92 ++++++++++--------- .../com/backbase/oss/boat/GenerateMojo.java | 8 +- .../oss/codegen/doc/BoatExampleUtils.java | 8 +- 4 files changed, 56 insertions(+), 54 deletions(-) diff --git a/boat-engine/src/main/java/com/backbase/oss/boat/transformers/Decomposer.java b/boat-engine/src/main/java/com/backbase/oss/boat/transformers/Decomposer.java index 2df3ca91d..c1cb2cd7a 100644 --- a/boat-engine/src/main/java/com/backbase/oss/boat/transformers/Decomposer.java +++ b/boat-engine/src/main/java/com/backbase/oss/boat/transformers/Decomposer.java @@ -18,7 +18,7 @@ public class Decomposer implements Transformer { public OpenAPI transform(OpenAPI openAPI, Map options) { List composedSchemas = openAPI.getComponents().getSchemas().values().stream() - .filter(schema -> schema instanceof ComposedSchema) + .filter(ComposedSchema.class::isInstance) .collect(Collectors.toList()); composedSchemas.forEach(composedSchema -> mergeComposedSchema(openAPI, composedSchema)); diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateFromDirectoryDocMojo.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateFromDirectoryDocMojo.java index e61e648a0..3620312e4 100644 --- a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateFromDirectoryDocMojo.java +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateFromDirectoryDocMojo.java @@ -51,62 +51,66 @@ private void fileInputExecute(File inputSpecFile) throws MojoExecutionException, inputSpecs = findAllOpenApiSpecs(inputSpecFile); if (inputSpecs.length == 0) { - throw new MojoExecutionException("No OpenAPI specs found in: " + inputSpec); - } + log.warn("No OpenAPI specs found in: " + inputSpec); + } else { - List success = new ArrayList<>(); - List failed = new ArrayList<>(); - for (File f : inputSpecs) { - inputSpec = f.getPath(); - output = new File(outPutDirectory.getPath(), f.getName().substring(0, f.getName().lastIndexOf("."))); - - if (!output.exists()) { - try { - Files.createDirectory(output.toPath()); - } catch (IOException e) { - log.error("Failed to create output directory", e); - } + List success = new ArrayList<>(); + List failed = new ArrayList<>(); + for (File inputSpec : inputSpecs) { + executeInputFile(outPutDirectory, success, failed, inputSpec); } + writeMarkers(success, failed); + } + } else { + log.info("inputSpec being read as a single file"); + super.execute(); + } + } - log.info(" Generating docs for spec {} in directory", f.getName()); - try { - super.execute(); - success.add(f); - } catch (MojoExecutionException | MojoFailureException e) { - log.error("Failed to generate doc for spec: {}", inputSpec); - failed.add(f); + private void writeMarkers(List success, List failed) throws MojoExecutionException { + if (markersDirectory != null) { + try { + if (!markersDirectory.exists()) { + Files.createDirectory(markersDirectory.toPath()); } - } - if (markersDirectory != null) { - try { - if (!markersDirectory.exists()) { - Files.createDirectory(markersDirectory.toPath()); - } - - Files.write(new File(markersDirectory, "success.lst").toPath(), - listOfFilesToString(success).getBytes(StandardCharsets.UTF_8), - StandardOpenOption.CREATE, - StandardOpenOption.APPEND); - Files.write(new File(markersDirectory, "failed.lst").toPath(), - listOfFilesToString(failed).getBytes(StandardCharsets.UTF_8), - StandardOpenOption.CREATE, - StandardOpenOption.APPEND); - - } catch (IOException e) { - log.error("Failed to write BOAT markers to: {}", markersDirectory, e); - throw new MojoExecutionException("Failed to write BOAT markers", e); + Files.write(new File(markersDirectory, "success.lst").toPath(), + listOfFilesToString(success).getBytes(StandardCharsets.UTF_8), + StandardOpenOption.CREATE, + StandardOpenOption.APPEND); + Files.write(new File(markersDirectory, "failed.lst").toPath(), + listOfFilesToString(failed).getBytes(StandardCharsets.UTF_8), + StandardOpenOption.CREATE, + StandardOpenOption.APPEND); - } + } catch (IOException e) { + log.error("Failed to write BOAT markers to: {}", markersDirectory, e); + throw new MojoExecutionException("Failed to write BOAT markers", e); } + } + } - } else { + private void executeInputFile(File outPutDirectory, List success, List failed, File f) { + inputSpec = f.getPath(); + output = new File(outPutDirectory.getPath(), f.getName().substring(0, f.getName().lastIndexOf("."))); - log.info("inputSpec being read as a single file"); - super.execute(); + if (!output.exists()) { + try { + Files.createDirectory(output.toPath()); + } catch (IOException e) { + log.error("Failed to create output directory", e); + } + } + log.info(" Generating docs for spec {} in directory", f.getName()); + try { + super.execute(); + success.add(f); + } catch (MojoExecutionException | MojoFailureException e) { + log.error("Failed to generate doc for spec: {}", inputSpec); + failed.add(f); } } diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateMojo.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateMojo.java index d3193be90..dc2009bf2 100644 --- a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateMojo.java +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/GenerateMojo.java @@ -509,9 +509,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { default: String message = format("Input spec %s matches more than one single file", inputSpec); getLog().error(message); - Stream.of(files).forEach(f -> { - getLog().error(format(" %s", f)); - }); + Stream.of(files).forEach(f -> getLog().error(format(" %s", f))); throw new MojoExecutionException( format("Input spec %s matches more than one single file", inputSpec)); } @@ -966,7 +964,7 @@ private URL inputSpecRemoteUrl() { /** * Get specification hash file. * - * @param inputSpecFile - Openapi specification input file to calculate it's hash. + * @param inputSpecFile - Openapi specification input file to calculate it's hash. * Does not taken into account if input spec is hosted on remote resource * @return a file with previously calculated hash */ @@ -1044,7 +1042,7 @@ private void adjustAdditionalProperties(final CodegenConfig config) { private static boolean isValidURI(String urlString) { try { - URI uri = new URI(urlString); + new URI(urlString); return true; } catch (Exception exception) { return false; diff --git a/boat-scaffold/src/main/java/com/backbase/oss/codegen/doc/BoatExampleUtils.java b/boat-scaffold/src/main/java/com/backbase/oss/codegen/doc/BoatExampleUtils.java index 46f03e3da..33d56626a 100644 --- a/boat-scaffold/src/main/java/com/backbase/oss/codegen/doc/BoatExampleUtils.java +++ b/boat-scaffold/src/main/java/com/backbase/oss/codegen/doc/BoatExampleUtils.java @@ -1,6 +1,5 @@ package com.backbase.oss.codegen.doc; -import com.backbase.oss.boat.transformers.OpenApiStreamUtil; import com.fasterxml.jackson.databind.node.ObjectNode; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; @@ -10,12 +9,13 @@ 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 java.util.Arrays; -import java.util.List; import lombok.experimental.UtilityClass; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import java.util.Arrays; +import java.util.List; + @Slf4j @UtilityClass @SuppressWarnings("java:S3740") @@ -155,7 +155,7 @@ private static void resolvePathsExamples( } Example example = new Example().value(mediaType.getExample()); - log.debug("Replacing Example ref: {} used in: {} with example from components: {}", ref, name, example); + log.warn("Incorrect example reference found! Replacing Example ref: {} used in: {} with example from components: {}", ref, name, example); boatExample.setExample(example); } From be451a2adb5c321bcf5cf308db944f482d37956f Mon Sep 17 00:00:00 2001 From: Bart Veenstra Date: Mon, 30 Aug 2021 11:10:25 +0200 Subject: [PATCH 3/4] Improve code coverage --- .../oss/codegen/doc/BoatExampleUtils.java | 52 ++++++++++----- boat-scaffold/src/test/resources/logback.xml | 2 + .../oas-examples/petstore-example-refs.yaml | 64 ++++++++++++++++++- 3 files changed, 98 insertions(+), 20 deletions(-) diff --git a/boat-scaffold/src/main/java/com/backbase/oss/codegen/doc/BoatExampleUtils.java b/boat-scaffold/src/main/java/com/backbase/oss/codegen/doc/BoatExampleUtils.java index 33d56626a..40a4b6b25 100644 --- a/boat-scaffold/src/main/java/com/backbase/oss/codegen/doc/BoatExampleUtils.java +++ b/boat-scaffold/src/main/java/com/backbase/oss/codegen/doc/BoatExampleUtils.java @@ -9,10 +9,12 @@ 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.responses.ApiResponse; import lombok.experimental.UtilityClass; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -71,22 +73,33 @@ private static boolean isJson(String contentType) { } public static void inlineExamples(String name, List examples, OpenAPI openAPI) { + List nonExistingExamples = new ArrayList<>(); + examples.stream() - .filter(boatExample -> boatExample.getExample().get$ref() != null) - .forEach(boatExample -> { - String ref = boatExample.getExample().get$ref(); - if (ref.startsWith(COMPONENTS_EXAMPLES_REF_PREFIX)) { - resolveComponentsExamples(name, openAPI, boatExample, ref); - } else if (ref.startsWith(PATHS_REF_PREFIX)) { - resolvePathsExamples(name, openAPI, boatExample, ref); - } else { - log.warn("Example ref: {} used in: {} refers to an example that does not exist", ref, name); - } - }); + .filter(boatExample -> { + Example example = boatExample.getExample(); + if (example == null) { + log.warn("Example :{} refers to an example that does not exist", boatExample.getKey()); + nonExistingExamples.add(boatExample); + } + return example != null && example.get$ref() != null; + }) + .forEach(boatExample -> { + String ref = boatExample.getExample().get$ref(); + if (ref.startsWith(COMPONENTS_EXAMPLES_REF_PREFIX)) { + resolveComponentsExamples(name, openAPI, boatExample, ref); + } else if (ref.startsWith(PATHS_REF_PREFIX)) { + resolvePathsExamples(name, openAPI, boatExample, ref); + } else { + log.warn("Example ref: {} used in: {} refers to an example that does not exist", ref, name); + } + }); + // Ensure non existing examples are removed to prevent further errors down the road + examples.removeAll(nonExistingExamples); } private static void resolveComponentsExamples( - String name, OpenAPI openAPI, BoatExample boatExample, String ref) { + String name, OpenAPI openAPI, BoatExample boatExample, String ref) { String exampleName = ref.replace(COMPONENTS_EXAMPLES_REF_PREFIX, ""); if (openAPI.getComponents() == null || openAPI.getComponents().getExamples() == null) { log.warn("Example ref: {} used in: {} refers to an example that does not exist", ref, name); @@ -102,7 +115,7 @@ private static void resolveComponentsExamples( } private static void resolvePathsExamples( - String name, OpenAPI openAPI, BoatExample boatExample, String ref) { + String name, OpenAPI openAPI, BoatExample boatExample, String ref) { // #/paths/ // ~1client-api~1v2~1accounts~1balance-history~1%7BarrangementIds%7D/ @@ -117,8 +130,8 @@ private static void resolvePathsExamples( return; } String[] refParts = Arrays.stream(ref.replace(PATHS_REF_PREFIX, "").split("/")) - .map(s -> s.replace("~1", "/")) - .toArray(String[]::new); + .map(s -> s.replace("~1", "/")) + .toArray(String[]::new); String pathName = refParts[1]; PathItem pathItem = openAPI.getPaths().get(pathName); @@ -140,7 +153,12 @@ private static void resolvePathsExamples( content = operation.getRequestBody().getContent(); mediaTypeName = refParts[5]; } else { - content = operation.getResponses().get(refParts[4]).getContent(); + ApiResponse apiResponse = operation.getResponses().get(refParts[4]); + if (apiResponse == null) { + log.warn("Example ref: {} refers to response that is not defined.", ref); + return; + } + content = apiResponse.getContent(); mediaTypeName = refParts[6]; } if (content == null) { @@ -155,7 +173,7 @@ private static void resolvePathsExamples( } Example example = new Example().value(mediaType.getExample()); - log.warn("Incorrect example reference found! Replacing Example ref: {} used in: {} with example from components: {}", ref, name, example); + log.warn("Incorrect example reference found! Replacing Example ref: {} used in: {} with example from components", ref, name); boatExample.setExample(example); } diff --git a/boat-scaffold/src/test/resources/logback.xml b/boat-scaffold/src/test/resources/logback.xml index 575b81d2c..c39bccbe8 100644 --- a/boat-scaffold/src/test/resources/logback.xml +++ b/boat-scaffold/src/test/resources/logback.xml @@ -1,4 +1,6 @@ + + %highlight([%level]) [%logger{10}] %msg%n diff --git a/boat-scaffold/src/test/resources/oas-examples/petstore-example-refs.yaml b/boat-scaffold/src/test/resources/oas-examples/petstore-example-refs.yaml index 23adb755a..5a3daf3ac 100644 --- a/boat-scaffold/src/test/resources/oas-examples/petstore-example-refs.yaml +++ b/boat-scaffold/src/test/resources/oas-examples/petstore-example-refs.yaml @@ -33,6 +33,9 @@ paths: application/json: schema: $ref: "#/components/schemas/Pets" + example: + $ref: "#/paths/~1pets/get/responses/invalid/content/application~1json/example" + default: description: unexpected error content: @@ -40,8 +43,8 @@ paths: schema: $ref: "#/components/schemas/Error" example: - code: 43 - message: "Overshot" + $ref: "#/paths/~1pets/get/responses/default/content/application~2json/example" + post: summary: Create a pet operationId: createPets @@ -50,6 +53,22 @@ paths: responses: '201': description: Null response + '401': + description: BadRequestError + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + example: + $ref: "#/components/examples/BadRequestError" + '500': + description: InternalServerError + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + example: + $ref: "#/components/examples/InternalServerError" default: description: unexpected error content: @@ -58,6 +77,7 @@ paths: $ref: "#/components/schemas/Error" example: $ref: "#/paths/~1pets/get/responses/default/content/application~1json/example" + /pets/{petId}: get: summary: Info for a specific pet @@ -78,12 +98,39 @@ paths: application/json: schema: $ref: "#/components/schemas/Pet" + example: + $ref: "#/paths/~1pets/get/responses/default/content/application~1json/example" + '500': + description: InternalServerError + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + examples: + InternalServerError: + $ref: "#/components/examples/BadRequestError" + OtherError: + $ref: "#/components/examples/BadRequestError" + '404': + description: InternalServerError + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + examples: + InternalServerError: + $ref: "#/components/examples/BadRequestError" + OtherError: + $ref: "#/components/examples/InvalidReference" default: description: unexpected error content: application/json: schema: $ref: "#/components/schemas/Error" + example: + $ref: "#/paths/~1pets/post/responses/default/content/application~1json/example" + components: schemas: Pet: @@ -113,4 +160,15 @@ components: type: integer format: int32 message: - type: string \ No newline at end of file + type: string + examples: + BadRequestError: + summary: BadRequestError + value: + message: Bad Request + errors: + - message: "Value Exceeded. Must be between {min} and {max}." + key: common.api.shoesize + context: + max: "50" + min: "1" \ No newline at end of file From 00a3f8f6c9860da893fc292037d52739df5cf40b Mon Sep 17 00:00:00 2001 From: Bart Veenstra Date: Mon, 30 Aug 2021 11:40:18 +0200 Subject: [PATCH 4/4] More coverage input. --- .../oas-examples/petstore-example-refs.yaml | 84 ++++++++++++++++++- 1 file changed, 82 insertions(+), 2 deletions(-) diff --git a/boat-scaffold/src/test/resources/oas-examples/petstore-example-refs.yaml b/boat-scaffold/src/test/resources/oas-examples/petstore-example-refs.yaml index 5a3daf3ac..e3f1cbe80 100644 --- a/boat-scaffold/src/test/resources/oas-examples/petstore-example-refs.yaml +++ b/boat-scaffold/src/test/resources/oas-examples/petstore-example-refs.yaml @@ -44,7 +44,6 @@ paths: $ref: "#/components/schemas/Error" example: $ref: "#/paths/~1pets/get/responses/default/content/application~2json/example" - post: summary: Create a pet operationId: createPets @@ -77,7 +76,6 @@ paths: $ref: "#/components/schemas/Error" example: $ref: "#/paths/~1pets/get/responses/default/content/application~1json/example" - /pets/{petId}: get: summary: Info for a specific pet @@ -130,6 +128,88 @@ paths: $ref: "#/components/schemas/Error" example: $ref: "#/paths/~1pets/post/responses/default/content/application~1json/example" + put: + summary: Update pet + operationId: updatePet + tags: + - pets + parameters: + - name: petId + in: path + required: true + description: The id of the pet to retrieve + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/Pet" + example: + id: 1 + name: "Joep" + tag: "Gun dog" + responses: + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + example: + $ref: "#/paths/~1pets/put/responses/default/content/application~1json/example" + patch: + summary: Update pet + operationId: patchPet + tags: + - pets + parameters: + - name: petId + in: path + required: true + description: The id of the pet to patch + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/Pet" + example: + id: 1 + name: "Joep" + tag: "Gun dog" + responses: + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + example: + $ref: "#/paths/~1pets/patch/responses/default/content/application~1json/example" + delete: + summary: Delete pet + operationId: deletePet + tags: + - pets + parameters: + - name: petId + in: path + required: true + description: The id of the pet to delete + schema: + type: string + responses: + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + example: + $ref: "#/paths/~1pets/delete/responses/default/content/application~1json/example" + components: schemas: