From b01b182af681b4aa2e0d7e0f4b150ffb9506e6f1 Mon Sep 17 00:00:00 2001 From: Alexis Couvreur Date: Fri, 12 Jan 2024 22:33:36 -0500 Subject: [PATCH] fix: DefaultCodegen now generates an exemple for each status codes (#17603) The DefaultCodegen now iterates through all api operations. This allows to access different examples based on the response per status code and content type. --- .../openapitools/codegen/DefaultCodegen.java | 41 +++++++++++++------ .../codegen/DefaultCodegenTest.java | 30 ++++++++++++++ .../src/test/resources/3_0/examples.yaml | 32 +++++++++++++++ 3 files changed, 91 insertions(+), 12 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index f2bc4bbd8eaf..0eb4fa5c55d5 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -4452,18 +4452,6 @@ protected void handleMethodResponse(Operation operation, } } - // check skipOperationExample, which can be set to true to avoid out of memory errors for large spec - if (!isSkipOperationExample()) { - // generate examples - String exampleStatusCode = "200"; - for (String key : operation.getResponses().keySet()) { - if (operation.getResponses().get(key) == methodResponse && !key.equals("default")) { - exampleStatusCode = key; - } - } - op.examples = new ExampleGenerator(schemas, this.openAPI).generateFromResponseSchema(exampleStatusCode, responseSchema, getProducesInfo(this.openAPI, operation)); - } - op.defaultResponse = toDefaultValue(responseSchema); op.returnType = cm.dataType; op.returnFormat = cm.dataFormat; @@ -4642,6 +4630,35 @@ public CodegenOperation fromOperation(String path, } } + // check skipOperationExample, which can be set to true to avoid out of memory errors for large spec + if (!isSkipOperationExample() && operation.getResponses() != null) { + // generate examples + ExampleGenerator generator = new ExampleGenerator(schemas, this.openAPI); + List> examples = new ArrayList<>(); + + for (String statusCode : operation.getResponses().keySet()) { + ApiResponse apiResponse = operation.getResponses().get(statusCode); + Schema schema = unaliasSchema(ModelUtils.getSchemaFromResponse(openAPI, apiResponse)); + if (schema == null) { + continue; + } + + if (apiResponse.getContent() != null) { + Set producesInfo = new ConcurrentSkipListSet<>(apiResponse.getContent().keySet()); + + String exampleStatusCode = statusCode; + if (exampleStatusCode.equals("default")) { + exampleStatusCode = "200"; + } + List> examplesForResponse = generator.generateFromResponseSchema(exampleStatusCode, schema, producesInfo); + if (examplesForResponse != null) { + examples.addAll(examplesForResponse); + } + } + } + op.examples = examples; + } + if (operation.getCallbacks() != null && !operation.getCallbacks().isEmpty()) { operation.getCallbacks().forEach((name, callback) -> { CodegenCallback c = fromCallback(name, callback, servers); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java index 96662023eb20..c750dbabed7d 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java @@ -988,6 +988,36 @@ public void testExample4() { Assert.assertEquals(codegenParameter2.example, "An example4 value"); } + @Test + public void testExample5MultipleResponses() { + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/examples.yaml"); + final DefaultCodegen codegen = new DefaultCodegen(); + codegen.setOpenAPI(openAPI); + String path = "/example5/multiple_responses"; + + Operation operation = openAPI.getPaths().get(path).getGet(); + CodegenOperation codegenOperation = codegen.fromOperation(path, "GET", operation, null); + List> examples = codegenOperation.examples; + + Assert.assertEquals(examples.size(), 4); + // 200 response example + Assert.assertEquals(examples.get(0).get("contentType"), "application/json"); + Assert.assertEquals(examples.get(0).get("example"), "\"a successful response example\""); + Assert.assertEquals(examples.get(0).get("statusCode"), "200"); + // 301 response example + Assert.assertEquals(examples.get(1).get("contentType"), "application/json"); + Assert.assertEquals(examples.get(1).get("example"), "\"a redirect response example\""); + Assert.assertEquals(examples.get(1).get("statusCode"), "301"); + // 404 response example + Assert.assertEquals(examples.get(2).get("contentType"), "application/json"); + Assert.assertEquals(examples.get(2).get("example"), "\"a not found response example\""); + Assert.assertEquals(examples.get(2).get("statusCode"), "404"); + // 500 response example + Assert.assertEquals(examples.get(3).get("contentType"), "application/json"); + Assert.assertEquals(examples.get(3).get("example"), "\"an internal server error response example\""); + Assert.assertEquals(examples.get(3).get("statusCode"), "500"); + } + @Test public void testDiscriminator() { final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml"); diff --git a/modules/openapi-generator/src/test/resources/3_0/examples.yaml b/modules/openapi-generator/src/test/resources/3_0/examples.yaml index 3a1037830cb6..e9dc245330f5 100644 --- a/modules/openapi-generator/src/test/resources/3_0/examples.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/examples.yaml @@ -107,6 +107,38 @@ paths: responses: '200': description: successful operation + /example5/multiple_responses: + get: + operationId: generateFromResponseSchemaWithOneOfModel + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: string + example: a successful response example + '301': + description: permanent redirect + content: + application/json: + schema: + type: string + example: a redirect response example + '404': + description: not found + content: + application/json: + schema: + type: string + example: a not found response example + '500': + description: internal server error + content: + application/json: + schema: + type: string + example: an internal server error response example components: schemas: User: