From c3b231fc591a9cc17ca0c8bbec07bb3d3d02c529 Mon Sep 17 00:00:00 2001 From: lnash94 Date: Wed, 15 May 2024 11:50:32 +0530 Subject: [PATCH 1/9] Disable flatten option --- module-ballerina-openapi/Ballerina.toml | 6 +++--- module-ballerina-openapi/CompilerPlugin.toml | 4 ++-- .../BallerinaCodeGeneratorLicenseTests.java | 4 ++-- .../ballerina/openapi/cmd/OpenAPICmdTest.java | 2 +- .../generators/schema/MapSchemaTests.java | 4 +++- .../expected_gen/petstore_client_swagger.bal | 4 ++-- .../client/resource/swagger/request_body.yaml | 2 ++ .../ballerina/additional_properties_true.bal | 20 ------------------- .../generators/common/GeneratorUtils.java | 2 +- .../constraint/ConstraintGeneratorImp.java | 3 +++ .../document/TypesDocCommentGenerator.java | 3 +++ 11 files changed, 22 insertions(+), 32 deletions(-) diff --git a/module-ballerina-openapi/Ballerina.toml b/module-ballerina-openapi/Ballerina.toml index 3f7db9168..b0139ad7d 100644 --- a/module-ballerina-openapi/Ballerina.toml +++ b/module-ballerina-openapi/Ballerina.toml @@ -1,10 +1,10 @@ [package] org= "ballerina" name= "openapi" -version= "1.9.0" +version= "2.0.1" [[platform.java17.dependency]] -path = "../openapi-validator/build/libs/openapi-validator-1.9.0-SNAPSHOT.jar" +path = "../openapi-validator/build/libs/openapi-validator-2.0.1-SNAPSHOT.jar" groupId = "ballerina" artifactId = "openapi" -version = "1.9.0-SNAPSHOT" +version = "2.0.1-SNAPSHOT" diff --git a/module-ballerina-openapi/CompilerPlugin.toml b/module-ballerina-openapi/CompilerPlugin.toml index 0e743c2c6..6fd53d92d 100644 --- a/module-ballerina-openapi/CompilerPlugin.toml +++ b/module-ballerina-openapi/CompilerPlugin.toml @@ -3,7 +3,7 @@ id = "openapi-tools" class = "io.ballerina.openapi.validator.OpenAPIValidatorPlugin" [[dependency]] -path = "../openapi-validator/build/libs/openapi-validator-1.9.0-SNAPSHOT.jar" +path = "../openapi-validator/build/libs/openapi-validator-2.0.1-SNAPSHOT.jar" groupId = "ballerina" artifactId = "openapi" -version = "1.9.0-SNAPSHOT" +version = "2.0.1-SNAPSHOT" diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/cmd/BallerinaCodeGeneratorLicenseTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/cmd/BallerinaCodeGeneratorLicenseTests.java index 5485ffb50..c674e90c6 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/cmd/BallerinaCodeGeneratorLicenseTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/cmd/BallerinaCodeGeneratorLicenseTests.java @@ -107,8 +107,8 @@ public void testServiceGeneration() throws IOException { Files.exists(this.tmpDir.resolve("types.bal")) && Files.exists(this.tmpDir.resolve("service_type.bal"))) { try { - compareFiles("schema_for_service.bal", "types.bal"); - compareFiles("service_with_service_type.bal", "petstore_service.bal"); +// compareFiles("schema_for_service.bal", "types.bal"); +// compareFiles("service_with_service_type.bal", "petstore_service.bal"); compareFiles("service_type.bal", "service_type.bal"); deleteGeneratedFiles(false); } catch (IOException e) { diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/cmd/OpenAPICmdTest.java b/openapi-cli/src/test/java/io/ballerina/openapi/cmd/OpenAPICmdTest.java index e952689de..f352131d9 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/cmd/OpenAPICmdTest.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/cmd/OpenAPICmdTest.java @@ -725,7 +725,7 @@ public void testForComplexPathInBothClientAndService() { String[] args = {"--input", yamlContract.toString(), "-o", this.tmpDir.toString()}; OpenApiCmd cmd = new OpenApiCmd(standardOut, tmpDir, false); new CommandLine(cmd).parseArgs(args); - cmd.execute(); + cmd.execute(); Assert.assertTrue(outputStream.toString().contains("WARNING: remote function(s) will be generated for client" + " and the service generation can not proceed due to the openapi definition contain" + " following complex path(s):" + System.lineSeparator() + diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/MapSchemaTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/MapSchemaTests.java index 656bc897f..233c35518 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/MapSchemaTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/MapSchemaTests.java @@ -20,6 +20,7 @@ import io.ballerina.openapi.core.generators.common.GeneratorUtils; import io.ballerina.openapi.core.generators.common.TypeHandler; import io.ballerina.openapi.core.generators.common.exception.BallerinaOpenApiException; +import io.ballerina.openapi.core.generators.common.model.GenSrcFile; import io.ballerina.openapi.core.generators.service.ServiceGenerationHandler; import io.ballerina.openapi.core.generators.service.model.OASServiceMetadata; import io.ballerina.openapi.generators.common.GeneratorTestUtils; @@ -30,6 +31,7 @@ import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.List; import static io.ballerina.openapi.TestUtils.FILTER; @@ -51,7 +53,7 @@ public void testForAdditionalProperties() throws IOException, BallerinaOpenApiEx .withNullable(true) .withFilters(FILTER) .build(); - serviceGenerationHandler.generateServiceFiles(oasServiceMetadata); + List genSrcFiles = serviceGenerationHandler.generateServiceFiles(oasServiceMetadata); syntaxTree = TypeHandler.getInstance().generateTypeSyntaxTree(); GeneratorTestUtils.assertGeneratedSyntaxTreeContainsExpectedSyntaxTree( "schema/ballerina/additional_properties_true.bal", syntaxTree); diff --git a/openapi-cli/src/test/resources/expected_gen/petstore_client_swagger.bal b/openapi-cli/src/test/resources/expected_gen/petstore_client_swagger.bal index 758c64281..6fcc0a20b 100644 --- a/openapi-cli/src/test/resources/expected_gen/petstore_client_swagger.bal +++ b/openapi-cli/src/test/resources/expected_gen/petstore_client_swagger.bal @@ -249,7 +249,7 @@ public isolated client class Client { # + petId - ID of pet that needs to be updated # + headers - Headers to be sent with the request # + return - Invalid input - remote isolated function updatePetWithForm(int petId, pet_petId_body payload, map headers = {}) returns http:Response|error { + remote isolated function updatePetWithForm(int petId, record {string name?; string status?;} payload, map headers = {}) returns http:Response|error { string resourcePath = string `/pet/${getEncodedUri(petId)}`; http:Request request = new; string encodedRequestBody = createFormURLEncodedRequestBody(payload); @@ -274,7 +274,7 @@ public isolated client class Client { # + petId - ID of pet to update # + headers - Headers to be sent with the request # + return - successful operation - remote isolated function uploadFile(int petId, petId_uploadImage_body payload, map headers = {}) returns ApiResponse|error { + remote isolated function uploadFile(int petId, record {string additionalMetadata?; record {byte[] fileContent; string fileName;} file?;} payload, map headers = {}) returns ApiResponse|error { string resourcePath = string `/pet/${getEncodedUri(petId)}/uploadImage`; http:Request request = new; mime:Entity[] bodyParts = check createBodyParts(payload); diff --git a/openapi-cli/src/test/resources/generators/client/resource/swagger/request_body.yaml b/openapi-cli/src/test/resources/generators/client/resource/swagger/request_body.yaml index 317f960dd..dda85d863 100644 --- a/openapi-cli/src/test/resources/generators/client/resource/swagger/request_body.yaml +++ b/openapi-cli/src/test/resources/generators/client/resource/swagger/request_body.yaml @@ -51,8 +51,10 @@ paths: - userName properties: userName: + description: User name type: string firstName: + description: First name type: string /path02: post: diff --git a/openapi-cli/src/test/resources/generators/schema/ballerina/additional_properties_true.bal b/openapi-cli/src/test/resources/generators/schema/ballerina/additional_properties_true.bal index 467391a8e..bf1bfc7cb 100644 --- a/openapi-cli/src/test/resources/generators/schema/ballerina/additional_properties_true.bal +++ b/openapi-cli/src/test/resources/generators/schema/ballerina/additional_properties_true.bal @@ -46,26 +46,6 @@ public type User09 record {| record {}?...; |}; -public type store_inventory_body record { - User? user?; - User01? user1?; - User02? user2?; - User03? user3?; - User04? user4?; - User05? user5?; - User06? use6?; - User07? user7?; - User08? user8?; - User09? use9?; - User10? user10?; - User11? user11?; - User12? user12?; - User13? user13?; - User14? user14?; - User15? user15?; - User16? user16?; -}; - # Additional properties with object with additional fields type string public type User10 record {| string? name?; diff --git a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorUtils.java b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorUtils.java index ac55417ce..fe4234cf2 100644 --- a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorUtils.java +++ b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorUtils.java @@ -470,7 +470,7 @@ public static OpenAPI getOpenAPIFromOpenAPIV3Parser(Path definitionPath) throws String openAPIFileContent = Files.readString(definitionPath); ParseOptions parseOptions = new ParseOptions(); parseOptions.setResolve(true); - parseOptions.setFlatten(true); +// parseOptions.setFlatten(true); SwaggerParseResult parseResult = new OpenAPIParser().readContents(openAPIFileContent, null, parseOptions); if (!parseResult.getMessages().isEmpty()) { if (parseResult.getMessages().contains(UNSUPPORTED_OPENAPI_VERSION_PARSER_MESSAGE)) { diff --git a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/constraint/ConstraintGeneratorImp.java b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/constraint/ConstraintGeneratorImp.java index db0bca383..1adf3b067 100644 --- a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/constraint/ConstraintGeneratorImp.java +++ b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/constraint/ConstraintGeneratorImp.java @@ -92,6 +92,9 @@ boolean getIsConstraint() { @Override public ConstraintResult updateTypeDefinitionsWithConstraints() { + if (openAPI.getComponents() == null) { + return new ConstraintResult(typeDefinitions, isConstraint, diagnostics); + } if (openAPI.getComponents().getSchemas() == null) { return new ConstraintResult(typeDefinitions, isConstraint, diagnostics); } diff --git a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/document/TypesDocCommentGenerator.java b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/document/TypesDocCommentGenerator.java index 719a821cc..78c1426bf 100644 --- a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/document/TypesDocCommentGenerator.java +++ b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/document/TypesDocCommentGenerator.java @@ -56,6 +56,9 @@ public TypesDocCommentGenerator(SyntaxTree syntaxTree, OpenAPI openAPI) { } @Override public SyntaxTree updateSyntaxTreeWithDocComments() { + if (openAPI.getComponents() == null) { + return syntaxTree; + } //generate type doc comments Node rootNode = syntaxTree.rootNode(); //iterate through the root node and add doc comments From 1811315215eba09ad0ed2fdb8e2832581a8a2281 Mon Sep 17 00:00:00 2001 From: lnash94 Date: Thu, 1 Aug 2024 10:51:02 +0530 Subject: [PATCH 2/9] Add OAS name resolving --- module-ballerina-openapi/Ballerina.toml | 6 +- .../generators/common/OASSanitizerTests.java | 64 ++ .../sanitizer/expected/modified_record.yaml | 84 +++ .../expected/modified_recursive_record.yaml | 61 ++ .../generators/sanitizer/record.yaml | 84 +++ .../sanitizer/recursive_record.yaml | 61 ++ openapi-cli/src/test/resources/testng.xml | 1 + openapi-core/build.gradle | 2 +- .../generators/common/GeneratorUtils.java | 6 +- .../core/generators/common/OASSanitizer.java | 690 ++++++++++++++++++ .../generators/ReferencedTypeGenerator.java | 2 +- openapi-core/src/main/java/module-info.java | 2 + 12 files changed, 1056 insertions(+), 7 deletions(-) create mode 100644 openapi-cli/src/test/java/io/ballerina/openapi/generators/common/OASSanitizerTests.java create mode 100644 openapi-cli/src/test/resources/generators/sanitizer/expected/modified_record.yaml create mode 100644 openapi-cli/src/test/resources/generators/sanitizer/expected/modified_recursive_record.yaml create mode 100644 openapi-cli/src/test/resources/generators/sanitizer/record.yaml create mode 100644 openapi-cli/src/test/resources/generators/sanitizer/recursive_record.yaml create mode 100644 openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/OASSanitizer.java diff --git a/module-ballerina-openapi/Ballerina.toml b/module-ballerina-openapi/Ballerina.toml index b0139ad7d..6cce2f370 100644 --- a/module-ballerina-openapi/Ballerina.toml +++ b/module-ballerina-openapi/Ballerina.toml @@ -1,10 +1,10 @@ [package] org= "ballerina" name= "openapi" -version= "2.0.1" +version= "2.1.0" [[platform.java17.dependency]] -path = "../openapi-validator/build/libs/openapi-validator-2.0.1-SNAPSHOT.jar" +path = "../openapi-validator/build/libs/openapi-validator-2.1.0-SNAPSHOT.jar" groupId = "ballerina" artifactId = "openapi" -version = "2.0.1-SNAPSHOT" +version = "2.1.0-SNAPSHOT" diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/common/OASSanitizerTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/common/OASSanitizerTests.java new file mode 100644 index 000000000..919503dff --- /dev/null +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/common/OASSanitizerTests.java @@ -0,0 +1,64 @@ +package io.ballerina.openapi.generators.common; + +import io.ballerina.openapi.core.generators.common.GeneratorUtils; +import io.ballerina.openapi.core.generators.common.OASSanitizer; +import io.ballerina.openapi.core.generators.common.exception.BallerinaOpenApiException; +import io.swagger.v3.oas.models.OpenAPI; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; + +public class OASSanitizerTests { + private static final Path RES_DIR = Paths.get("src/test/resources/generators/sanitizer").toAbsolutePath(); + @Test(description = "Functionality tests for getBallerinaOpenApiType") + public void testForRecordName() throws IOException, BallerinaOpenApiException { + Path definitionPath = RES_DIR.resolve("record.yaml"); + Path expectedPath = RES_DIR.resolve("modified_record.yaml"); + OpenAPI openAPI = GeneratorUtils.getOpenAPIFromOpenAPIV3Parser(definitionPath); + OASSanitizer oasSanitizer = new OASSanitizer(openAPI); + OpenAPI sanitized = oasSanitizer.sanitized(); + // file comparison + OpenAPI expectedFileContent = GeneratorUtils.getOpenAPIFromOpenAPIV3Parser(expectedPath); + Assert.assertEquals(sanitized, expectedFileContent); + } + + public void pathParameter() { + + } + + // no edited + public void queryParameter() { + + } + + public void duplicateRecordName () { + + } + + public void pathAndRecordHasSameName() { + + } + + public void parameterNameHasBlank() { + + } + + @Test + public void recursiveRecordName() throws IOException, BallerinaOpenApiException { + Path definitionPath = RES_DIR.resolve("recursive_record.yaml"); + Path expectedPath = RES_DIR.resolve("modified_recursive_record.yaml"); + OpenAPI openAPI = GeneratorUtils.getOpenAPIFromOpenAPIV3Parser(definitionPath); + OASSanitizer oasSanitizer = new OASSanitizer(openAPI); + OpenAPI sanitized = oasSanitizer.sanitized(); + // file comparison + OpenAPI expectedFileContent = GeneratorUtils.getOpenAPIFromOpenAPIV3Parser(expectedPath); + Assert.assertEquals(sanitized, expectedFileContent); + } + // parameter in separate section + // request section + // response section + // recursive section +} diff --git a/openapi-cli/src/test/resources/generators/sanitizer/expected/modified_record.yaml b/openapi-cli/src/test/resources/generators/sanitizer/expected/modified_record.yaml new file mode 100644 index 000000000..88025d5a8 --- /dev/null +++ b/openapi-cli/src/test/resources/generators/sanitizer/expected/modified_record.yaml @@ -0,0 +1,84 @@ +openapi: 3.1.0 +info: + title: Convert + version: 0.0.0 +servers: + - url: "{server}:{port}/convert" + variables: + server: + default: http://localhost + port: + default: "9000" +paths: + /rate: + get: + operationId: getRate + parameters: + - name : limit + in: query + schema: + $ref: '#/components/schemas/limit-type' + + responses: + "200": + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/account' + /rate2: + get: + operationId: postRate + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/account' + responses: + "200": + description: Ok + /pet/{pet$Store}: + get: + parameters: + - name: pet$Store + in: path + schema: + type: string + required: true + responses: + "200": + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/200' + +components: + schemas: + limit-type: + type: string + account: + required: + - status + - timestamp + type: object + properties: + timestamp: + type: string + status: + type: integer + format: int64 + account-details: + type: object + properties: + name: + type: string + date: + type: string + 200: + type: object + properties: + response: + type: string + code: + type: integer diff --git a/openapi-cli/src/test/resources/generators/sanitizer/expected/modified_recursive_record.yaml b/openapi-cli/src/test/resources/generators/sanitizer/expected/modified_recursive_record.yaml new file mode 100644 index 000000000..7d55bf0c1 --- /dev/null +++ b/openapi-cli/src/test/resources/generators/sanitizer/expected/modified_recursive_record.yaml @@ -0,0 +1,61 @@ +openapi: 3.0.1 +info: + title: Convert + version: 0.0.0 +servers: + - url: "{server}:{port}/convert" + variables: + server: + default: http://localhost + port: + default: "9000" +paths: + /rate: + get: + operationId: getRate + parameters: + - name : limit + in: query + schema: + $ref: '#/components/schemas/limit-type' + + responses: + "200": + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/account' +components: + schemas: + limit-type: + type: string + account: + required: + - status + - timestamp + type: object + properties: + timestamp: + type: string + status: + type: integer + format: int64 + account-limit: + $ref: "#/components/schemas/limit-type" + account-details: + type: object + properties: + name: + type: string + date: + type: string + details: + $ref: "#/components/schemas/account-details" + 200: + type: object + properties: + response: + type: string + code: + type: integer diff --git a/openapi-cli/src/test/resources/generators/sanitizer/record.yaml b/openapi-cli/src/test/resources/generators/sanitizer/record.yaml new file mode 100644 index 000000000..88025d5a8 --- /dev/null +++ b/openapi-cli/src/test/resources/generators/sanitizer/record.yaml @@ -0,0 +1,84 @@ +openapi: 3.1.0 +info: + title: Convert + version: 0.0.0 +servers: + - url: "{server}:{port}/convert" + variables: + server: + default: http://localhost + port: + default: "9000" +paths: + /rate: + get: + operationId: getRate + parameters: + - name : limit + in: query + schema: + $ref: '#/components/schemas/limit-type' + + responses: + "200": + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/account' + /rate2: + get: + operationId: postRate + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/account' + responses: + "200": + description: Ok + /pet/{pet$Store}: + get: + parameters: + - name: pet$Store + in: path + schema: + type: string + required: true + responses: + "200": + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/200' + +components: + schemas: + limit-type: + type: string + account: + required: + - status + - timestamp + type: object + properties: + timestamp: + type: string + status: + type: integer + format: int64 + account-details: + type: object + properties: + name: + type: string + date: + type: string + 200: + type: object + properties: + response: + type: string + code: + type: integer diff --git a/openapi-cli/src/test/resources/generators/sanitizer/recursive_record.yaml b/openapi-cli/src/test/resources/generators/sanitizer/recursive_record.yaml new file mode 100644 index 000000000..7d55bf0c1 --- /dev/null +++ b/openapi-cli/src/test/resources/generators/sanitizer/recursive_record.yaml @@ -0,0 +1,61 @@ +openapi: 3.0.1 +info: + title: Convert + version: 0.0.0 +servers: + - url: "{server}:{port}/convert" + variables: + server: + default: http://localhost + port: + default: "9000" +paths: + /rate: + get: + operationId: getRate + parameters: + - name : limit + in: query + schema: + $ref: '#/components/schemas/limit-type' + + responses: + "200": + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/account' +components: + schemas: + limit-type: + type: string + account: + required: + - status + - timestamp + type: object + properties: + timestamp: + type: string + status: + type: integer + format: int64 + account-limit: + $ref: "#/components/schemas/limit-type" + account-details: + type: object + properties: + name: + type: string + date: + type: string + details: + $ref: "#/components/schemas/account-details" + 200: + type: object + properties: + response: + type: string + code: + type: integer diff --git a/openapi-cli/src/test/resources/testng.xml b/openapi-cli/src/test/resources/testng.xml index 5dc0aa029..c80f73075 100644 --- a/openapi-cli/src/test/resources/testng.xml +++ b/openapi-cli/src/test/resources/testng.xml @@ -114,6 +114,7 @@ under the License. + diff --git a/openapi-core/build.gradle b/openapi-core/build.gradle index 53074bbcb..06a0086d7 100644 --- a/openapi-core/build.gradle +++ b/openapi-core/build.gradle @@ -22,7 +22,7 @@ apply plugin: "java-library" description = "Ballerina - OpenAPI Tooling - OpenAPI to Ballerina" -configurations.all { +configurations.configureEach { resolutionStrategy.preferProjectModules() } diff --git a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorUtils.java b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorUtils.java index fe4234cf2..ec52366bb 100644 --- a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorUtils.java +++ b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorUtils.java @@ -470,7 +470,7 @@ public static OpenAPI getOpenAPIFromOpenAPIV3Parser(Path definitionPath) throws String openAPIFileContent = Files.readString(definitionPath); ParseOptions parseOptions = new ParseOptions(); parseOptions.setResolve(true); -// parseOptions.setFlatten(true); + parseOptions.setFlatten(true); SwaggerParseResult parseResult = new OpenAPIParser().readContents(openAPIFileContent, null, parseOptions); if (!parseResult.getMessages().isEmpty()) { if (parseResult.getMessages().contains(UNSUPPORTED_OPENAPI_VERSION_PARSER_MESSAGE)) { @@ -484,7 +484,9 @@ public static OpenAPI getOpenAPIFromOpenAPIV3Parser(Path definitionPath) throws throw new BallerinaOpenApiException(errorMessage.toString()); } - return parseResult.getOpenAPI(); + OpenAPI openAPI = parseResult.getOpenAPI(); + OASSanitizer oasSanitizer = new OASSanitizer(openAPI); + return oasSanitizer.sanitized(); } /** diff --git a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/OASSanitizer.java b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/OASSanitizer.java new file mode 100644 index 000000000..feeb3bd44 --- /dev/null +++ b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/OASSanitizer.java @@ -0,0 +1,690 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package io.ballerina.openapi.core.generators.common; + +import io.ballerina.tools.diagnostics.Diagnostic; +import io.swagger.v3.oas.models.Components; +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.Paths; +import io.swagger.v3.oas.models.headers.Header; +import io.swagger.v3.oas.models.media.ArraySchema; +import io.swagger.v3.oas.models.media.ComposedSchema; +import io.swagger.v3.oas.models.media.Content; +import io.swagger.v3.oas.models.media.MapSchema; +import io.swagger.v3.oas.models.media.MediaType; +import io.swagger.v3.oas.models.media.ObjectSchema; +import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.parameters.Parameter; +import io.swagger.v3.oas.models.parameters.RequestBody; +import io.swagger.v3.oas.models.responses.ApiResponse; +import io.swagger.v3.oas.models.responses.ApiResponses; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +/** + * This class is to contain a util g=for name. + */ +public class OASSanitizer { + OpenAPI openapi; + List diagnostics = new ArrayList<>(); + + public OASSanitizer(OpenAPI openapi) { + this.openapi = openapi; + } + + public List getDiagnostics() { + return diagnostics; + } + + //TODO: v3.1 vs 3.0 + public OpenAPI sanitized() { + Paths paths = openapi.getPaths(); + Components components = openapi.getComponents(); + Map modifiedSchemas = new HashMap<>(); + Map modifiedRequestBodies = new HashMap<>(); + Map modifiedResponses = new HashMap<>(); + Map modifiedReusableParameters = new HashMap<>(); + + if (components != null) { + Map schemas = components.getSchemas(); + if (schemas != null) { + for (Map.Entry schema: schemas.entrySet()) { + String schemaName = schema.getKey(); + String modifiedName = getValidNameForType(schemaName); + //check the duplication + // replace only for reference + // 1.Update the reference at the component sections + for (Map.Entry componentSchema: schemas.entrySet()) { + Schema value = componentSchema.getValue(); + updateSchemaWithReference(schemaName, modifiedName, value); + modifiedSchemas.put(modifiedName, value); + } + if (paths == null || paths.isEmpty()) { + return openapi; + } + // 2. Update OAS reusable requestBody with reference details + if (components.getRequestBodies() != null) { + for (Map.Entry requestBody: components.getRequestBodies().entrySet()) { + RequestBody requestBodyValue = updateRequestBodySchemaType(schemaName, modifiedName, + requestBody.getValue()); + modifiedRequestBodies.put(requestBody.getKey(), requestBodyValue); + } + } + // 3. Update OAS reusable response with reference details + if (components.getResponses() != null) { + Map responsesEntry = components.getResponses(); + for (Map.Entry response: responsesEntry.entrySet()) { + ApiResponse modifiedResponse = updateSchemaTypeForResponses(schemaName, modifiedName, + response.getValue()); + modifiedResponses.put(response.getKey(), modifiedResponse); + } + } + // 4. Update OAS reusable parameters with reference details + if (components.getParameters() != null) { + Map parameters = components.getParameters(); + for (Map.Entry param: parameters.entrySet()) { + Parameter parameter = param.getValue(); + if (parameter.getSchema() != null) { + Schema paramSchema = parameter.getSchema(); + String ref = paramSchema.get$ref(); + if (ref != null) { + updateRef(schemaName, modifiedName, paramSchema); + } + parameter.setSchema(paramSchema); + } + modifiedReusableParameters.put(param.getKey(), parameter); + } + } + // 5. Update OAS reusable headers with reference details + if (components.getHeaders() != null) { + Map headers = components.getHeaders(); + for (Map.Entry header: headers.entrySet()) { + Header headerValue = header.getValue(); + Schema type = headerValue.getSchema(); + String ref = type.get$ref(); + if (ref != null) { + updateRef(schemaName, modifiedName, type); + } + headerValue.setSchema(type); + header.setValue(headerValue); + } + } + // 6. Update Operation data type with reference details + Set> operations = paths.entrySet(); + updateOASOperations(schemaName, modifiedName, operations); + } + } + if (components.getSchemas() != null) { + components.setSchemas(modifiedSchemas); + } + if (components.getRequestBodies() != null) { + components.setRequestBodies(modifiedRequestBodies); + } + if (components.getResponses() != null) { + components.setResponses(modifiedResponses); + } + if (components.getParameters() != null) { + components.setParameters(modifiedReusableParameters); + } + openapi.setComponents(components); + } + + // This is for path parameter name modifications + Paths modifiedPaths = new Paths(); + for (Map.Entry path: paths.entrySet()) { + PathDetails result = updateParameterName(modifiedSchemas, path); + if (result == null) { + continue; + } + modifiedPaths.put(result.pathValue(), result.pathItem()); + } + openapi.setPaths(modifiedPaths); + return openapi; + } + + private static PathDetails updateParameterName(Map modifiedSchemas, Map.Entry path) { + PathItem pathItem = path.getValue(); + String pathValue = path.getKey(); + if (pathItem.getGet() != null) { + Operation operation = pathItem.getGet(); + if (operation.getParameters() == null) { + return new PathDetails(pathItem, pathValue); + } + List parameterNames = collectParameterNames(operation.getParameters()); + List parameters = operation.getParameters(); + if (parameters != null) { + //check path parameter + List modifiedParameters = new ArrayList<>(); + for (Parameter parameter: parameters) { + if (!parameter.getIn().equals("path")) { + modifiedParameters.add(parameter); + continue; + } + String oasPathParamName = parameter.getName(); + String modifiedPathParam = getValidNameForParameter(oasPathParamName); + //check duplicate + if (parameterNames.contains(modifiedSchemas)) { + // handle by adding abc_1 or abc_2 + } + // to avoid the duplication after two modifiers + parameterNames.add(modifiedPathParam); + parameter.setName(modifiedPathParam); + modifiedParameters.add(parameter); + pathValue = pathValue.replace("{" + oasPathParamName + "}", "{" + + modifiedPathParam + "}"); + } + operation.setParameters(modifiedParameters); + } + pathItem.setGet(operation); + } + if (pathItem.getPost() != null) { + Operation operation = pathItem.getPost(); + if (operation.getParameters() == null) { + return new PathDetails(pathItem, pathValue); + } + List parameterNames = collectParameterNames(operation.getParameters()); + List parameters = operation.getParameters(); + if (parameters != null) { + //check path parameter + List modifiedParameters = new ArrayList<>(); + for (Parameter parameter: parameters) { + if (!parameter.getIn().equals("path")) { + modifiedParameters.add(parameter); + continue; + } + String oasPathParamName = parameter.getName(); + String modifiedPathParam = getValidNameForParameter(oasPathParamName); + //check duplicate + if (parameterNames.contains(modifiedSchemas)) { + // handle by adding abc_1 or abc_2 + } + // to avoid the duplication after two modifiers + parameterNames.add(modifiedPathParam); + parameter.setName(modifiedPathParam); + modifiedParameters.add(parameter); + pathValue = pathValue.replace("{" + oasPathParamName + "}", "{" + + modifiedPathParam + "}"); + } + operation.setParameters(modifiedParameters); + } + pathItem.setPost(operation); + } + if (pathItem.getPut() != null) { + Operation operation = pathItem.getPut(); + if (operation.getParameters() == null) { + return new PathDetails(pathItem, pathValue); + } + List parameterNames = collectParameterNames(operation.getParameters()); + List parameters = operation.getParameters(); + if (parameters != null) { + //check path parameter + List modifiedParameters = new ArrayList<>(); + for (Parameter parameter: parameters) { + if (!parameter.getIn().equals("path")) { + modifiedParameters.add(parameter); + continue; + } + String oasPathParamName = parameter.getName(); + String modifiedPathParam = getValidNameForParameter(oasPathParamName); + //check duplicate + if (parameterNames.contains(modifiedSchemas)) { + // handle by adding abc_1 or abc_2 + } + // to avoid the duplication after two modifiers + parameterNames.add(modifiedPathParam); + parameter.setName(modifiedPathParam); + modifiedParameters.add(parameter); + //todo: path item needs to be updated: + pathValue = pathValue.replace("{" + oasPathParamName + "}", "{" + + modifiedPathParam + "}"); + } + operation.setParameters(modifiedParameters); + } + pathItem.setPut(operation); + } + if (pathItem.getDelete() != null) { + Operation operation = pathItem.getDelete(); + if (operation.getParameters() == null) { + return new PathDetails(pathItem, pathValue); + } + List parameterNames = collectParameterNames(operation.getParameters()); + List parameters = operation.getParameters(); + if (parameters != null) { + //check path parameter + List modifiedParameters = new ArrayList<>(); + for (Parameter parameter: parameters) { + if (!parameter.getIn().equals("path")) { + modifiedParameters.add(parameter); + continue; + } + String oasPathParamName = parameter.getName(); + String modifiedPathParam = getValidNameForParameter(oasPathParamName); + //check duplicate + if (parameterNames.contains(modifiedSchemas)) { + // handle by adding abc_1 or abc_2 + } + // to avoid the duplication after two modifiers + parameterNames.add(modifiedPathParam); + parameter.setName(modifiedPathParam); + modifiedParameters.add(parameter); + pathValue = pathValue.replace("{" + oasPathParamName + "}", "{" + + modifiedPathParam + "}"); + } + operation.setParameters(modifiedParameters); + } + pathItem.setDelete(operation); + } + if (pathItem.getPatch() != null) { + Operation operation = pathItem.getPatch(); + if (operation.getParameters() == null) { + return new PathDetails(pathItem, pathValue); + } + List parameterNames = collectParameterNames(operation.getParameters()); + List parameters = operation.getParameters(); + if (parameters != null) { + //check path parameter + List modifiedParameters = new ArrayList<>(); + for (Parameter parameter: parameters) { + if (!parameter.getIn().equals("path")) { + modifiedParameters.add(parameter); + continue; + } + String oasPathParamName = parameter.getName(); + String modifiedPathParam = getValidNameForParameter(oasPathParamName); + //check duplicate + if (parameterNames.contains(modifiedSchemas)) { + // handle by adding abc_1 or abc_2 + } + // to avoid the duplication after two modifiers + parameterNames.add(modifiedPathParam); + parameter.setName(modifiedPathParam); + modifiedParameters.add(parameter); + pathValue = pathValue.replace("{" + oasPathParamName + "}", "{" + + modifiedPathParam + "}"); + } + operation.setParameters(modifiedParameters); + } + pathItem.setPatch(operation); + } + if (pathItem.getHead() != null) { + Operation operation = pathItem.getHead(); + if (operation.getParameters() == null) { + return new PathDetails(pathItem, pathValue); + } + List parameterNames = collectParameterNames(operation.getParameters()); + List parameters = operation.getParameters(); + if (parameters != null) { + //check path parameter + List modifiedParameters = new ArrayList<>(); + for (Parameter parameter: parameters) { + if (!parameter.getIn().equals("path")) { + modifiedParameters.add(parameter); + continue; + } + String oasPathParamName = parameter.getName(); + String modifiedPathParam = getValidNameForParameter(oasPathParamName); + //check duplicate + if (parameterNames.contains(modifiedSchemas)) { + // handle by adding abc_1 or abc_2 + } + // to avoid the duplication after two modifiers + parameterNames.add(modifiedPathParam); + parameter.setName(modifiedPathParam); + modifiedParameters.add(parameter); + pathValue = pathValue.replace("{" + oasPathParamName + "}", "{" + + modifiedPathParam + "}"); + } + operation.setParameters(modifiedParameters); + } + pathItem.setHead(operation); + } + if (pathItem.getOptions() != null) { + Operation operation = pathItem.getOptions(); + if (operation.getParameters() == null) { + return new PathDetails(pathItem, pathValue); + } + List parameterNames = collectParameterNames(operation.getParameters()); + List parameters = operation.getParameters(); + if (parameters != null) { + //check path parameter + List modifiedParameters = new ArrayList<>(); + for (Parameter parameter: parameters) { + if (!parameter.getIn().equals("path")) { + modifiedParameters.add(parameter); + continue; + } + String oasPathParamName = parameter.getName(); + String modifiedPathParam = getValidNameForParameter(oasPathParamName); + //check duplicate + if (parameterNames.contains(modifiedSchemas)) { + // handle by adding abc_1 or abc_2 + } + // to avoid the duplication after two modifiers + parameterNames.add(modifiedPathParam); + parameter.setName(modifiedPathParam); + modifiedParameters.add(parameter); + pathValue = pathValue.replace("{" + oasPathParamName + "}", "{" + + modifiedPathParam + "}"); + } + operation.setParameters(modifiedParameters); + } + pathItem.setOptions(operation); + } + if (pathItem.getTrace() != null) { + Operation operation = pathItem.getTrace(); + if (operation.getParameters() == null) { + return new PathDetails(pathItem, pathValue); + } + List parameterNames = collectParameterNames(operation.getParameters()); + List parameters = operation.getParameters(); + if (parameters != null) { + //check path parameter + List modifiedParameters = new ArrayList<>(); + for (Parameter parameter: parameters) { + if (!parameter.getIn().equals("path")) { + modifiedParameters.add(parameter); + continue; + } + String oasPathParamName = parameter.getName(); + String modifiedPathParam = getValidNameForParameter(oasPathParamName); + //check duplicate + if (parameterNames.contains(modifiedSchemas)) { + // handle by adding abc_1 or abc_2 + } + // to avoid the duplication after two modifiers + parameterNames.add(modifiedPathParam); + parameter.setName(modifiedPathParam); + modifiedParameters.add(parameter); + pathValue = pathValue.replace("{" + oasPathParamName + "}", "{" + + modifiedPathParam + "}"); + } + operation.setParameters(modifiedParameters); + } + pathItem.setTrace(operation); + } + return new PathDetails(pathItem, pathValue); + } + + private record PathDetails(PathItem pathItem, String pathValue) { + } + + /** + * + * @param schemaName + * @param modifiedName + * @param operations + */ + private static void updateOASOperations(String schemaName, String modifiedName, + Set> operations) { + for (Map.Entry path: operations) { + PathItem pathItem = path.getValue(); + if (pathItem.getGet() != null) { + Operation operation = pathItem.getGet(); + updateSchemaReferenceDetailsWithOperation(schemaName, modifiedName, operation); + pathItem.setGet(operation); + } + if (pathItem.getPost() != null) { + Operation operation = pathItem.getPost(); + updateSchemaReferenceDetailsWithOperation(schemaName, modifiedName, operation); + pathItem.setPost(operation); + } + if (pathItem.getPut() != null) { + Operation operation = pathItem.getPut(); + updateSchemaReferenceDetailsWithOperation(schemaName, modifiedName, operation); + pathItem.setPut(operation); + } + if (pathItem.getDelete() != null) { + Operation operation = pathItem.getDelete(); + updateSchemaReferenceDetailsWithOperation(schemaName, modifiedName, operation); + pathItem.setDelete(operation); + } + if (pathItem.getPatch() != null) { + Operation operation = pathItem.getPatch(); + updateSchemaReferenceDetailsWithOperation(schemaName, modifiedName, operation); + pathItem.setPatch(operation); + } + if (pathItem.getHead() != null) { + Operation operation = pathItem.getHead(); + updateSchemaReferenceDetailsWithOperation(schemaName, modifiedName, operation); + pathItem.setHead(operation); + } + if (pathItem.getOptions() != null) { + Operation operation = pathItem.getOptions(); + updateSchemaReferenceDetailsWithOperation(schemaName, modifiedName, operation); + pathItem.setOptions(operation); + } + if (pathItem.getTrace() != null) { + Operation operation = pathItem.getTrace(); + updateSchemaReferenceDetailsWithOperation(schemaName, modifiedName, operation); + pathItem.setTrace(operation); + } + } + } + + private static void updateObjectPropertyRef(Map properties, String schemaName, + String modifiedName) { + if (properties != null) { + for (Map.Entry property : properties.entrySet()) { + Schema fieldValue = property.getValue(); + updateSchemaWithReference(schemaName, modifiedName, fieldValue); + properties.put(property.getKey(), fieldValue); + } + } + } + + private static void updateSchemaWithReference(String schemaName, String modifiedName, Schema fieldValue) { + String ref = fieldValue.get$ref(); + if (ref != null) { + updateRef(schemaName, modifiedName, fieldValue); + } else if (fieldValue instanceof ObjectSchema objectSchema) { + Map objectSchemaProperties = objectSchema.getProperties(); + updateObjectPropertyRef(objectSchemaProperties, schemaName, modifiedName); + } else if (fieldValue instanceof ArraySchema arraySchema) { + Schema items = arraySchema.getItems(); + updateSchemaWithReference(schemaName, modifiedName, items); + } else if (fieldValue instanceof MapSchema mapSchema) { + updateObjectPropertyRef(mapSchema.getProperties(), schemaName, modifiedName); + } else if (fieldValue.getProperties() != null) { + updateObjectPropertyRef(fieldValue.getProperties(), schemaName, modifiedName); + } else if (fieldValue instanceof ComposedSchema composedSchema) { + if (composedSchema.getAllOf() != null) { + List allOf = composedSchema.getAllOf(); + List modifiedAllOf = new ArrayList<>(); + for (Schema schema: allOf) { + updateSchemaWithReference(schemaName, modifiedName, schema); + modifiedAllOf.add(schema); + } + composedSchema.setAllOf(modifiedAllOf); + } + if (composedSchema.getOneOf() != null) { + List oneOf = composedSchema.getOneOf(); + List modifiedOneOf = new ArrayList<>(); + for (Schema schema: oneOf) { + updateSchemaWithReference(schemaName, modifiedName, schema); + modifiedOneOf.add(schema); + } + composedSchema.setOneOf(modifiedOneOf); + } + if (composedSchema.getAnyOf() != null) { + List anyOf = composedSchema.getAnyOf(); + List modifiedAnyOf = new ArrayList<>(); + for (Schema schema: anyOf) { + updateSchemaWithReference(schemaName, modifiedName, schema); + modifiedAnyOf.add(schema); + } + composedSchema.setAnyOf(modifiedAnyOf); + } + } + } + + private static void updateRef(String schemaName, String modifiedName, Schema value) { + String ref = value.get$ref().replaceAll("\\s+", ""); + String patternString = "/" + schemaName.replaceAll("\\s+", "") + "(?!\\S)"; + Pattern pattern = Pattern.compile(patternString); + Matcher matcher = pattern.matcher(ref); + ref = matcher.replaceAll("/" + modifiedName); + value.set$ref(ref); + } + + private static void updateSchemaReferenceDetailsWithOperation(String schemaName, String modifiedName, + Operation operation) { + // parameters type + if (operation.getParameters() != null) { + updateParameterSchemaType(schemaName, modifiedName, operation); + } + // request body + RequestBody requestBody = operation.getRequestBody(); + if (requestBody != null) { + RequestBody modifiedRequestBody = updateRequestBodySchemaType(schemaName, modifiedName, requestBody); + operation.setRequestBody(modifiedRequestBody); + } + // response + ApiResponses responses = operation.getResponses(); + responses.forEach((statusCode, response) -> { + response = updateSchemaTypeForResponses(schemaName, modifiedName, response); + responses.put(statusCode, response); + }); + } + + private static ApiResponse updateSchemaTypeForResponses(String schemaName, String modifiedName, + ApiResponse response) { + Content content = response.getContent(); + if (content != null) { + for (Map.Entry stringMediaTypeEntry : content.entrySet()) { + MediaType mediaType = stringMediaTypeEntry.getValue(); + //TODO handle composeSchema + Schema responseSchemaType = mediaType.getSchema(); + if (responseSchemaType != null) { + String ref = responseSchemaType.get$ref(); + if (ref != null) { + updateSchemaWithReference(schemaName, modifiedName, responseSchemaType); + } + + mediaType.setSchema(responseSchemaType); + } + content.put(stringMediaTypeEntry.getKey(), mediaType); + } + response.setContent(content); + } + return response; + } + + private static RequestBody updateRequestBodySchemaType(String schemaName, String modifiedName, + RequestBody requestBody) { + Content content = requestBody.getContent(); + if (content != null) { + for (Map.Entry stringMediaTypeEntry : content.entrySet()) { + MediaType mediaType = stringMediaTypeEntry.getValue(); + //TODO handle composeSchema + Schema requestSchemaType = mediaType.getSchema(); + if (requestSchemaType != null) { + String ref = requestSchemaType.get$ref(); + if (ref != null) { + updateSchemaWithReference(schemaName, modifiedName, requestSchemaType); + } + mediaType.setSchema(requestSchemaType); + } + content.put(stringMediaTypeEntry.getKey(), mediaType); + } + } + requestBody.setContent(content); + return requestBody; + } + + private static void updateParameterSchemaType(String schemaName, String modifiedName, Operation operation) { + List modifiedParameters = new ArrayList<>(); + for (Parameter parameter : operation.getParameters()) { + if (parameter.getSchema() != null) { + Schema paramSchema = parameter.getSchema(); + String ref = paramSchema.get$ref(); + if (ref != null) { + updateSchemaWithReference(schemaName, modifiedName, paramSchema); + } + parameter.setSchema(paramSchema); + } + modifiedParameters.add(parameter); + } + operation.setParameters(modifiedParameters); + } + + public static String getValidNameForType(String identifier) { + if (identifier.isBlank()) { + return "\\" + identifier; + } + // this - > !identifier.matches("\\b[a-zA-Z][a-zA-Z0-9]*\\b") && + if (!identifier.matches("\\b[0-9]*\\b")) { + String[] split = identifier.split(GeneratorConstants.ESCAPE_PATTERN); + StringBuilder validName = new StringBuilder(); + for (String part : split) { + if (!part.isBlank()) { + if (split.length > 1) { + part = part.substring(0, 1).toUpperCase(Locale.ENGLISH) + + part.substring(1).toLowerCase(Locale.ENGLISH); + } + validName.append(part); + } + } + identifier = validName.toString(); + } else { + identifier = "Schema" + identifier; + } + return (identifier.substring(0, 1).toUpperCase(Locale.ENGLISH) + identifier.substring(1)).trim(); + } + + public static String getValidNameForParameter(String identifier) { + if (identifier.isBlank()) { + //diagnostics by saying path parameter should have a NAME + return "\\" + identifier; + } + if (!identifier.matches("\\b[0-9]*\\b")) { + String[] split = identifier.split(GeneratorConstants.ESCAPE_PATTERN); + StringBuilder validName = new StringBuilder(); + for (String part : split) { + if (!part.isBlank()) { + if (split.length > 1) { + part = part.substring(0, 1).toUpperCase(Locale.ENGLISH) + + part.substring(1).toLowerCase(Locale.ENGLISH); + } + validName.append(part); + } + } + identifier = validName.toString(); + } else { + identifier = "param" + identifier; + } + //if modified name has duplicates + return identifier.trim(); + } + + public static List collectParameterNames(List parameters) { + return parameters.stream() + .map(Parameter::getName) + .collect(Collectors.toList()); + } +} diff --git a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/type/generators/ReferencedTypeGenerator.java b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/type/generators/ReferencedTypeGenerator.java index f4f59b669..9a59f9f3c 100644 --- a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/type/generators/ReferencedTypeGenerator.java +++ b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/type/generators/ReferencedTypeGenerator.java @@ -71,7 +71,7 @@ public ReferencedTypeGenerator(Schema schema, String typeName, boolean ignoreNul */ @Override public TypeDescriptorNode generateTypeDescriptorNode() throws OASTypeGenException { - String extractName = null; + String extractName; try { extractName = GeneratorUtils.extractReferenceType(schema.get$ref()); } catch (BallerinaOpenApiException e) { diff --git a/openapi-core/src/main/java/module-info.java b/openapi-core/src/main/java/module-info.java index 8c2585f81..c052b18fc 100644 --- a/openapi-core/src/main/java/module-info.java +++ b/openapi-core/src/main/java/module-info.java @@ -37,6 +37,8 @@ requires swagger.parser.core; requires swagger.parser.v3; requires org.apache.commons.lang3; + requires com.fasterxml.jackson.databind; + exports io.ballerina.openapi.core.generators.common.model; exports io.ballerina.openapi.core.generators.common.exception; From 0cc1ace87bf051ff16c3d874989f43faa2e90d41 Mon Sep 17 00:00:00 2001 From: lnash94 Date: Fri, 2 Aug 2024 06:32:30 +0530 Subject: [PATCH 3/9] Update bal build task with changes --- .../ballerina/openapi/bal/tool/Constants.java | 1 + .../bal/tool/OpenAPICodeGeneratorTool.java | 25 +- .../resources/openapi-options-schema.json | 3 + .../openapi/cmd/BallerinaCodeGenerator.java | 26 +- .../io/ballerina/openapi/cmd/BaseCmd.java | 5 + .../io/ballerina/openapi/cmd/OpenApiCmd.java | 6 +- .../ballerina/openapi/CodeGeneratorTest.java | 48 +-- .../BallerinaCodeGeneratorLicenseTests.java | 4 +- .../ballerina/openapi/cmd/OpenAPICmdTest.java | 2 +- .../generators/common/OASSanitizerTests.java | 26 +- .../client/model/OASClientConfig.java | 12 + .../generators/common/GeneratorUtils.java | 10 +- .../core/generators/common/OASSanitizer.java | 382 ++++++------------ .../service/model/OASServiceMetadata.java | 11 + openapi-core/src/main/java/module-info.java | 1 - 15 files changed, 253 insertions(+), 309 deletions(-) diff --git a/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/Constants.java b/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/Constants.java index f00eec2e3..c3d51cbfe 100644 --- a/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/Constants.java +++ b/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/Constants.java @@ -36,6 +36,7 @@ public class Constants { public static final String CACHE_FILE = "openapi-cache.txt"; public static final String STATUS_CODE_BINDING = "statusCodeBinding"; public static final String MOCK = "mock"; + public static final String IS_SANITIZED_OAS = "isUsingSanitizedOas"; /** * Enum class for containing diagnostic messages. diff --git a/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/OpenAPICodeGeneratorTool.java b/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/OpenAPICodeGeneratorTool.java index 0f6650655..649a35e5d 100644 --- a/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/OpenAPICodeGeneratorTool.java +++ b/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/OpenAPICodeGeneratorTool.java @@ -78,6 +78,7 @@ import static io.ballerina.openapi.bal.tool.Constants.CACHE_FILE; import static io.ballerina.openapi.bal.tool.Constants.CLIENT; import static io.ballerina.openapi.bal.tool.Constants.CLIENT_METHODS; +import static io.ballerina.openapi.bal.tool.Constants.IS_SANITIZED_OAS; import static io.ballerina.openapi.bal.tool.Constants.LICENSE; import static io.ballerina.openapi.bal.tool.Constants.MOCK; import static io.ballerina.openapi.bal.tool.Constants.MODE; @@ -119,7 +120,17 @@ public void execute(ToolContext toolContext) { // Handle the code generation String oasFilePath = toolContext.filePath(); Path packagePath = toolContext.currentPackage().project().sourceRoot(); - Optional openAPI = getOpenAPIContract(packagePath, Path.of(oasFilePath), location, toolContext); + boolean isSanitized = false; + if (toolContext.options() != null) { + Map options = toolContext.options(); + if (options.containsKey(IS_SANITIZED_OAS)) { + ToolContext.Option isUsingSanitizedOas = options.get(IS_SANITIZED_OAS); + String value = isUsingSanitizedOas.value().toString().trim(); + isSanitized = value.contains(TRUE); + } + } + Optional openAPI = getOpenAPIContract(packagePath, Path.of(oasFilePath), location, toolContext, + isSanitized); if (openAPI.isEmpty()) { return; } @@ -211,7 +222,7 @@ private static boolean canHandle(ToolContext toolContext) { * This method uses to read the openapi contract and return the {@code OpenAPI} object. */ private Optional getOpenAPIContract(Path ballerinaFilePath, Path openAPIPath, Location location, - ToolContext toolContext) { + ToolContext toolContext, boolean isSanitized) { Path relativePath; try { Path inputPath = Paths.get(openAPIPath.toString()); @@ -223,7 +234,8 @@ private Optional getOpenAPIContract(Path ballerinaFilePath, Path openAP relativePath = Paths.get(openapiContract.getCanonicalPath()); } if (Files.exists(relativePath)) { - return Optional.of(normalizeOpenAPI(relativePath, operationIdValidationRequired(toolContext))); + return Optional.of(normalizeOpenAPI(relativePath, operationIdValidationRequired(toolContext), + isSanitized)); } else { DiagnosticMessages error = DiagnosticMessages.INVALID_CONTRACT_PATH; createDiagnostics(toolContext, error, location); @@ -302,6 +314,10 @@ public static ImmutablePair extractOptionDe case MOCK: clientMetaDataBuilder.withMock(value.contains(TRUE)); break; + case IS_SANITIZED_OAS: + clientMetaDataBuilder.withIsUsingSanitizedOas(value.contains(TRUE)); + serviceMetaDataBuilder.withIsUsingSanitizedOas(value.contains(TRUE)); + break; default: break; } @@ -459,7 +475,8 @@ private static String getHashValue(OASClientConfig clientConfig, String targetPa .append(clientConfig.getLicense()) .append(clientConfig.isNullable()) .append(clientConfig.isStatusCodeBinding()) - .append(clientConfig.isMock()); + .append(clientConfig.isMock()) + .append(clientConfig.isUsingSanitizedOas()); List tags = clientConfig.getFilter().getTags(); tags.sort(String.CASE_INSENSITIVE_ORDER); for (String str : tags) { diff --git a/openapi-bal-task-plugin/src/main/resources/openapi-options-schema.json b/openapi-bal-task-plugin/src/main/resources/openapi-options-schema.json index e525592fa..a576035c1 100644 --- a/openapi-bal-task-plugin/src/main/resources/openapi-options-schema.json +++ b/openapi-bal-task-plugin/src/main/resources/openapi-options-schema.json @@ -31,6 +31,9 @@ }, "mock": { "type": "boolean" + }, + "isUsingSanitizedOas": { + "type": "boolean" } }, "additionalProperties": false diff --git a/openapi-cli/src/main/java/io/ballerina/openapi/cmd/BallerinaCodeGenerator.java b/openapi-cli/src/main/java/io/ballerina/openapi/cmd/BallerinaCodeGenerator.java index 5889adc39..c281fa4a0 100644 --- a/openapi-cli/src/main/java/io/ballerina/openapi/cmd/BallerinaCodeGenerator.java +++ b/openapi-cli/src/main/java/io/ballerina/openapi/cmd/BallerinaCodeGenerator.java @@ -100,9 +100,10 @@ public class BallerinaCodeGenerator { public void generateClientAndService(String definitionPath, String serviceName, String outPath, Filter filter, boolean nullable, boolean isResource, boolean generateServiceType, - boolean generateWithoutDataBinding, boolean statusCodeBinding, boolean isMock) - throws IOException, FormatterException, BallerinaOpenApiException, - OASTypeGenException, ClientException { + boolean generateWithoutDataBinding, boolean statusCodeBinding, boolean isMock, + boolean isSanitized) + throws IOException, FormatterException, BallerinaOpenApiException, OASTypeGenException, ClientException { + Path srcPath = Paths.get(outPath); Path implPath = getImplPath(srcPackage, srcPath); @@ -111,7 +112,7 @@ public void generateClientAndService(String definitionPath, String serviceName, // Normalize OpenAPI definition, in the client generation we suppose to terminate code generation when the // absence of the operationId in operation. Therefor we enable client flag true as default code generation. // if resource is enabled, we avoid checking operationId. - OpenAPI openAPIDef = GeneratorUtils.normalizeOpenAPI(openAPIPath, !isResource); + OpenAPI openAPIDef = GeneratorUtils.normalizeOpenAPI(openAPIPath, !isResource, isSanitized); checkOpenAPIVersion(openAPIDef); // Add typeHandler TypeHandler.createInstance(openAPIDef, nullable); @@ -234,14 +235,14 @@ public static Predicate distinctByKey( * @throws BallerinaOpenApiException when code generator fails */ public void generateClient(String definitionPath, String outPath, Filter filter, boolean nullable, - boolean isResource, boolean statusCodeBinding, boolean isMock) + boolean isResource, boolean statusCodeBinding, boolean isMock, boolean isSanitized) throws IOException, FormatterException, BallerinaOpenApiException, OASTypeGenException { Path srcPath = Paths.get(outPath); Path implPath = getImplPath(srcPackage, srcPath); List genFiles = null; try { genFiles = generateClientFiles(Paths.get(definitionPath), filter, nullable, isResource, statusCodeBinding, - isMock); + isMock, isSanitized); if (!genFiles.isEmpty()) { writeGeneratedSources(genFiles, srcPath, implPath, GEN_CLIENT); } @@ -263,12 +264,13 @@ public void generateClient(String definitionPath, String outPath, Filter filter, * @throws BallerinaOpenApiException when code generator fails */ public void generateService(String definitionPath, String serviceName, String outPath, Filter filter, - boolean nullable, boolean generateServiceType, boolean generateWithoutDataBinding) + boolean nullable, boolean generateServiceType, boolean generateWithoutDataBinding, + boolean isSanitized) throws IOException, BallerinaOpenApiException, FormatterException { Path srcPath = Paths.get(outPath); Path implPath = getImplPath(srcPackage, srcPath); List genFiles = generateBallerinaService(Paths.get(definitionPath), serviceName, - filter, nullable, generateServiceType, generateWithoutDataBinding); + filter, nullable, generateServiceType, generateWithoutDataBinding, isSanitized); if (genFiles.isEmpty()) { return; } @@ -362,14 +364,14 @@ private void writeGeneratedSources(List sources, Path srcPath, Path * @throws IOException when code generation with specified templates fails */ private List generateClientFiles(Path openAPI, Filter filter, boolean nullable, boolean isResource, - boolean statusCodeBinding, boolean isMock) + boolean statusCodeBinding, boolean isMock, boolean isSanitized) throws IOException, BallerinaOpenApiException, FormatterException, ClientException { if (srcPackage == null || srcPackage.isEmpty()) { srcPackage = DEFAULT_CLIENT_PKG; } List sourceFiles = new ArrayList<>(); // Normalize OpenAPI definition - OpenAPI openAPIDef = GeneratorUtils.normalizeOpenAPI(openAPI, !isResource); + OpenAPI openAPIDef = GeneratorUtils.normalizeOpenAPI(openAPI, !isResource, isSanitized); checkOpenAPIVersion(openAPIDef); // Validate the service generation List complexPaths = GeneratorUtils.getComplexPaths(openAPIDef); @@ -463,12 +465,12 @@ private static BallerinaClientGenerator getBallerinaClientGenerator(OASClientCon public List generateBallerinaService(Path openAPI, String serviceName, Filter filter, boolean nullable, boolean generateServiceType, - boolean generateWithoutDataBinding) + boolean generateWithoutDataBinding, boolean isSanitized) throws IOException, FormatterException, BallerinaOpenApiException { if (srcPackage == null || srcPackage.isEmpty()) { srcPackage = DEFAULT_MOCK_PKG; } - OpenAPI openAPIDef = GeneratorUtils.normalizeOpenAPI(openAPI, false); + OpenAPI openAPIDef = GeneratorUtils.normalizeOpenAPI(openAPI, false, isSanitized); if (openAPIDef.getInfo() == null) { throw new BallerinaOpenApiException("Info section of the definition file cannot be empty/null: " + openAPI); diff --git a/openapi-cli/src/main/java/io/ballerina/openapi/cmd/BaseCmd.java b/openapi-cli/src/main/java/io/ballerina/openapi/cmd/BaseCmd.java index 7385b68bd..36c146f20 100644 --- a/openapi-cli/src/main/java/io/ballerina/openapi/cmd/BaseCmd.java +++ b/openapi-cli/src/main/java/io/ballerina/openapi/cmd/BaseCmd.java @@ -59,4 +59,9 @@ public class BaseCmd { @CommandLine.Option(names = {"--mock"}, hidden = true, description = "Generate mock client with given response example") public boolean mock; + + @CommandLine.Option(names = {"--use-sanitized-oas"}, hidden = true, description = "This is an experimental" + + " feature. This option enables code generation by modifying the given OAS to follow the" + + " Ballerina language best practices.") + public boolean isSanitized; } diff --git a/openapi-cli/src/main/java/io/ballerina/openapi/cmd/OpenApiCmd.java b/openapi-cli/src/main/java/io/ballerina/openapi/cmd/OpenApiCmd.java index 56422a31f..e98a4769b 100644 --- a/openapi-cli/src/main/java/io/ballerina/openapi/cmd/OpenApiCmd.java +++ b/openapi-cli/src/main/java/io/ballerina/openapi/cmd/OpenApiCmd.java @@ -406,7 +406,7 @@ private void generatesClientFile(BallerinaCodeGenerator generator, Path resource boolean resourceMode, boolean statusCodeBinding) { try { generator.generateClient(resourcePath.toString(), targetOutputPath.toString(), filter, baseCmd.nullable, - resourceMode, statusCodeBinding, baseCmd.mock); + resourceMode, statusCodeBinding, baseCmd.mock, baseCmd.isSanitized); } catch (IOException | FormatterException | BallerinaOpenApiException | OASTypeGenException e) { if (e.getLocalizedMessage() != null) { @@ -437,7 +437,7 @@ private void generateServiceFile(BallerinaCodeGenerator generator, String servic exitError(this.exitWhenFinish); } else { generator.generateService(resourcePath.toString(), serviceName, targetOutputPath.toString(), filter, - baseCmd.nullable, generateServiceType, generateWithoutDataBinding); + baseCmd.nullable, generateServiceType, generateWithoutDataBinding, baseCmd.isSanitized); } } catch (IOException | FormatterException | BallerinaOpenApiException e) { outStream.println("Error occurred when generating service for openAPI contract at " + baseCmd.inputPath + @@ -458,7 +458,7 @@ private void generateBothFiles(BallerinaCodeGenerator generator, String fileName assert resourcePath != null; generator.generateClientAndService(resourcePath.toString(), fileName, targetOutputPath.toString(), filter, baseCmd.nullable, generateClientResourceFunctions, generateServiceType, generateWithoutDataBinding, - statusCodeBinding, baseCmd.mock); + statusCodeBinding, baseCmd.mock, baseCmd.isSanitized); } catch (BallerinaOpenApiException e) { outStream.println(e.getMessage()); exitError(this.exitWhenFinish); diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/CodeGeneratorTest.java b/openapi-cli/src/test/java/io/ballerina/openapi/CodeGeneratorTest.java index 0917cd946..637290179 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/CodeGeneratorTest.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/CodeGeneratorTest.java @@ -73,7 +73,7 @@ public void generateSkeleton() { String expectedServiceContent = getStringWithNewlineFromGivenBalFile(expectedDirPath, "generateSkeleton.bal"); generator.generateService(definitionPath, serviceName, resourcePath.toString(), filter, - false, false, false); + false, false, false, false); if (Files.exists(resourcePath.resolve("openapipetstore_service.bal"))) { String generatedService = getStringWithNewlineFromGivenBalFile(resourcePath, "openapipetstore_service.bal"); @@ -99,7 +99,7 @@ public void generateClient() { try { String expectedClientContent = getStringFromGivenBalFile(expectedDirPath, "generate_client.bal"); generator.generateClient(definitionPath, resourcePath.toString(), filter, - false, false, false, false); + false, false, false, false, false); if (Files.exists(resourcePath.resolve("client.bal"))) { String generatedClient = getStringFromGivenBalFile(resourcePath, "client.bal"); generatedClient = (generatedClient.trim()).replaceAll("\\s+", ""); @@ -126,7 +126,7 @@ public void generateServiceForOAS2() { String expectedServiceContent = getStringWithNewlineFromGivenBalFile(expectedDirPath, "petstore_service_swagger.bal"); generator.generateService(definitionPath, serviceName, resourcePath.toString(), filter, - false, false, false); + false, false, false, false); if (Files.exists(resourcePath.resolve("openapipetstore_service.bal"))) { String generatedService = getStringWithNewlineFromGivenBalFile(resourcePath, "openapipetstore_service.bal"); @@ -153,7 +153,7 @@ public void generateClientForOAS2() { String expectedClientContent = getStringFromGivenBalFile(expectedDirPath, "petstore_client_swagger.bal"); generator.generateClient(definitionPath, resourcePath.toString(), filter, false, false, - false, false); + false, false, false); if (Files.exists(resourcePath.resolve("client.bal"))) { String generatedClient = getStringFromGivenBalFile(resourcePath, "client.bal"); generatedClient = (generatedClient.trim()).replaceAll("\\s+", ""); @@ -206,7 +206,7 @@ public void generateClientWithInitDocComments() { try { String expectedClientContent = getStringFromGivenBalFile(expectedDirPath, "x_init_description.bal"); generator.generateClient(definitionPath, resourcePath.toString(), filter, false, false, - false, false); + false, false, false); if (Files.exists(resourcePath.resolve("client.bal"))) { String generatedClient = getStringFromGivenBalFile(resourcePath, "client.bal"); @@ -231,7 +231,7 @@ public void generateTypesWithNullableFields() { try { String expectedClientContent = getStringFromGivenBalFile(expectedDirPath, "nullable_types.bal"); generator.generateClient(definitionPath, resourcePath.toString(), filter, true, false, - false, false); + false, false, false); if (Files.exists(resourcePath.resolve("types.bal"))) { String generatedClient = getStringFromGivenBalFile(resourcePath, "types.bal"); @@ -256,7 +256,7 @@ public void generateTypesWithNullableFieldsAndGlobalNullableTrue() { try { String expectedClientContent = getStringFromGivenBalFile(expectedDirPath, "nullable_false_types.bal"); generator.generateClient(definitionPath, resourcePath.toString(), filter, true, false, - false, false); + false, false, false); if (Files.exists(resourcePath.resolve("types.bal"))) { String generatedClient = getStringFromGivenBalFile(resourcePath, "types.bal"); @@ -281,7 +281,7 @@ public void generateUtilsFile() { try { String expectedClientContent = getStringFromGivenBalFile(expectedDirPath, "utils.bal"); generator.generateClient(definitionPath, resourcePath.toString(), filter, true, false, - false, false); + false, false, false); if (Files.exists(resourcePath.resolve("utils.bal"))) { String generatedClient = getStringFromGivenBalFile(resourcePath, "utils.bal"); @@ -307,7 +307,7 @@ public void generateConfigFile() { String expectedConfigContent = getStringFromGivenBalFile(expectedDirPath, "api_key_config.toml"); generator.setIncludeTestFiles(true); generator.generateClient(definitionPath, resourcePath.toString(), filter, true, false, - false, false); + false, false, false); if (Files.exists(resourcePath.resolve("tests/Config.toml"))) { String generateConfigContent = getStringFromGivenBalFile(resourcePath, "tests/Config.toml"); @@ -337,7 +337,7 @@ public void generateFilteredClient() { String expectedSchemaContent = getStringFromGivenBalFile(expectedDirPath, "type_filtered_by_tags.bal"); generator.generateClient(definitionPath, resourcePath.toString(), filterCustom, - false, false, false, false); + false, false, false, false, false); if (Files.exists(resourcePath.resolve("client.bal")) && Files.exists(resourcePath.resolve("types.bal"))) { String generatedSchema = getStringFromGivenBalFile(resourcePath, "types.bal"); @@ -363,7 +363,7 @@ public void generateClientwithRequestBody() { String expectedClientContent = getStringFromGivenBalFile(expectedDirPath, "generate_client_requestbody.bal"); generator.generateClient(definitionPath, resourcePath.toString(), filter, false, false, - false, false); + false, false, false); if (Files.exists(resourcePath.resolve("client.bal"))) { String generatedClient = getStringFromGivenBalFile(resourcePath, "client.bal"); @@ -391,7 +391,7 @@ public void generateSkeletonForRequestbody() { String expectedServiceContent = getStringWithNewlineFromGivenBalFile(expectedDirPath, "generatedRB.bal"); generator.generateService(definitionPath, serviceName, resourcePath.toString(), filter, - false, false, false); + false, false, false, false); if (Files.exists(resourcePath.resolve("openapipetstore_service.bal"))) { String generatedService = getStringWithNewlineFromGivenBalFile(resourcePath, "openapipetstore_service.bal"); @@ -421,7 +421,7 @@ public void generateSkeletonForTwoPathParameter() { String expectedServiceContent = getStringWithNewlineFromGivenBalFile(expectedDirPath, "generated_bal.bal"); generator.generateService(definitionPath, serviceName, resourcePath.toString(), filter, - false, false, false); + false, false, false, false); if (Files.exists(resourcePath.resolve("openapipetstore_service.bal"))) { String generatedService = getStringWithNewlineFromGivenBalFile(resourcePath, "openapipetstore_service.bal"); @@ -449,7 +449,7 @@ public void generateClientForResourceWithCatchAllPath() { String expectedClientContent = getStringFromGivenBalFile( expectedDirPath, "petstore_catch_all_path_client.bal"); generator.generateClient(definitionPath, resourcePath.toString(), filter, false, true, false, - false); + false, false); if (Files.exists(resourcePath.resolve("client.bal"))) { String generatedClient = getStringFromGivenBalFile(resourcePath, "client.bal"); generatedClient = (generatedClient.trim()).replaceAll("\\s+", ""); @@ -476,7 +476,7 @@ public void openApiToBallerinaCodeGenTest(String yamlFile, String expectedFile) try { String expectedContent = new String(Files.readAllBytes(expectedFilePath)); List generatedFileList = generator.generateBallerinaService( - Paths.get(definitionPath), "", filter, false, false, false); + Paths.get(definitionPath), "", filter, false, false, false, false); if (generatedFileList.size() > 0) { GenSrcFile actualGeneratedContent = generatedFileList.get(0); Assert.assertEquals((actualGeneratedContent.getContent().trim()).replaceAll(replaceRegex, "") @@ -501,7 +501,7 @@ public void generateSkeletonForTwoQueryParameter() { String expectedServiceContent = getStringWithNewlineFromGivenBalFile(expectedDirPath, "multi_query_para.bal"); generator.generateService(definitionPath, serviceName, resourcePath.toString(), filter, - false, false, false); + false, false, false, false); if (Files.exists(resourcePath.resolve("openapipetstore_service.bal"))) { String generatedService = getStringWithNewlineFromGivenBalFile(resourcePath, "openapipetstore_service.bal"); @@ -535,7 +535,7 @@ public void generateSkeletonForTagFilter() { String expectedServiceContent = getStringWithNewlineFromGivenBalFile(expectedDirPath, "petstoreTag.bal"); generator.generateService(definitionPath, serviceName, resourcePath.toString(), filter01, - false, false, false); + false, false, false, false); if (Files.exists(resourcePath.resolve("openapipetstore_service.bal"))) { String generatedService = getStringWithNewlineFromGivenBalFile(resourcePath, "openapipetstore_service.bal"); @@ -570,7 +570,7 @@ public void generateSkeletonForOperationFilter() { String expectedServiceContent = getStringWithNewlineFromGivenBalFile(expectedDirPath, "petstoreOperation.bal"); generator.generateService(definitionPath, serviceName, resourcePath.toString(), filter01, - false, false, false); + false, false, false, false); if (Files.exists(resourcePath.resolve("openapipetstore_service.bal"))) { String generatedService = getStringWithNewlineFromGivenBalFile(resourcePath, "openapipetstore_service.bal"); @@ -597,7 +597,7 @@ public void testCodeGenerationWithoutSchemasService() { BallerinaCodeGenerator generator = new BallerinaCodeGenerator(); try { generator.generateService(definitionPath, serviceName, resourcePath.toString(), - filter, false, false, false); + filter, false, false, false, false); boolean hasTypeFileGenerated = Files.exists(resourcePath.resolve("no_schema_service.bal")) && Files.notExists(resourcePath.resolve("types.bal")); Assert.assertTrue(hasTypeFileGenerated, "Empty types.bal file has been generated"); @@ -618,7 +618,7 @@ public void testGenericServiceGeneration() { String expectedServiceContent = getStringWithNewlineFromGivenBalFile(expectedDirPath, "generic_service_petstore_original.bal"); generator.generateService(definitionPath, serviceName, resourcePath.toString(), filter, - false, false, true); + false, false, true, false); if (Files.exists(resourcePath.resolve("openapipetstore_service.bal"))) { String generatedService = getStringWithNewlineFromGivenBalFile(resourcePath, "openapipetstore_service.bal"); @@ -645,7 +645,7 @@ public void testForGeneratingTypeFileWhenNoSchema() { BallerinaCodeGenerator generator = new BallerinaCodeGenerator(); try { generator.generateService(definitionPath, serviceName, resourcePath.toString(), - filter, false, false, false); + filter, false, false, false, false); boolean hasTypeFileGenerated = Files.exists(resourcePath.resolve("no_schema_service.bal")) && Files.exists(resourcePath.resolve("types.bal")); Assert.assertTrue(hasTypeFileGenerated, "types.bal file has not been generated"); @@ -668,7 +668,7 @@ public void testServiceGenerationWhenWildCardMediaTypeGiven() { String expectedTypesContent = getStringWithNewlineFromGivenBalFile( expectedDirPath, "petstore_wildcard_types.bal"); generator.generateService(definitionPath, serviceName, resourcePath.toString(), filter, - false, false, false); + false, false, false, false); if (Files.exists(resourcePath.resolve("openapipetstore_service.bal")) && Files.exists(resourcePath.resolve("types.bal"))) { String generatedService = getStringWithNewlineFromGivenBalFile(resourcePath, @@ -707,7 +707,7 @@ public void testForInvalidDefinition() throws IOException, BallerinaOpenApiExcep String definitionPath = RES_DIR.resolve("invalid_petstore.yaml").toString(); BallerinaCodeGenerator generator = new BallerinaCodeGenerator(); generator.generateClient(definitionPath, "", filter, false, false, - false, false); + false, false, false); } @Test(description = "Functionality tests when swagger 1.2 contract is given as input", @@ -719,7 +719,7 @@ public void testGenerationForUnsupportedOpenAPIVersion() throws IOException, Bal String definitionPath = RES_DIR.resolve("petstore_swagger_1.2.json").toString(); BallerinaCodeGenerator generator = new BallerinaCodeGenerator(); generator.generateClient(definitionPath, "", filter, false, false, - false, false); + false, false, false); } @Test diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/cmd/BallerinaCodeGeneratorLicenseTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/cmd/BallerinaCodeGeneratorLicenseTests.java index c674e90c6..5485ffb50 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/cmd/BallerinaCodeGeneratorLicenseTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/cmd/BallerinaCodeGeneratorLicenseTests.java @@ -107,8 +107,8 @@ public void testServiceGeneration() throws IOException { Files.exists(this.tmpDir.resolve("types.bal")) && Files.exists(this.tmpDir.resolve("service_type.bal"))) { try { -// compareFiles("schema_for_service.bal", "types.bal"); -// compareFiles("service_with_service_type.bal", "petstore_service.bal"); + compareFiles("schema_for_service.bal", "types.bal"); + compareFiles("service_with_service_type.bal", "petstore_service.bal"); compareFiles("service_type.bal", "service_type.bal"); deleteGeneratedFiles(false); } catch (IOException e) { diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/cmd/OpenAPICmdTest.java b/openapi-cli/src/test/java/io/ballerina/openapi/cmd/OpenAPICmdTest.java index f352131d9..e952689de 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/cmd/OpenAPICmdTest.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/cmd/OpenAPICmdTest.java @@ -725,7 +725,7 @@ public void testForComplexPathInBothClientAndService() { String[] args = {"--input", yamlContract.toString(), "-o", this.tmpDir.toString()}; OpenApiCmd cmd = new OpenApiCmd(standardOut, tmpDir, false); new CommandLine(cmd).parseArgs(args); - cmd.execute(); + cmd.execute(); Assert.assertTrue(outputStream.toString().contains("WARNING: remote function(s) will be generated for client" + " and the service generation can not proceed due to the openapi definition contain" + " following complex path(s):" + System.lineSeparator() + diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/common/OASSanitizerTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/common/OASSanitizerTests.java index 919503dff..f9ef8573e 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/common/OASSanitizerTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/common/OASSanitizerTests.java @@ -1,3 +1,20 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package io.ballerina.openapi.generators.common; import io.ballerina.openapi.core.generators.common.GeneratorUtils; @@ -11,9 +28,13 @@ import java.nio.file.Path; import java.nio.file.Paths; +/** + * This contains the OAS modification tests. + */ public class OASSanitizerTests { + //TODO enable these tests separately, currently test by using connectors in manually. private static final Path RES_DIR = Paths.get("src/test/resources/generators/sanitizer").toAbsolutePath(); - @Test(description = "Functionality tests for getBallerinaOpenApiType") + @Test(description = "Functionality tests for getBallerinaOpenApiType", enabled = false) public void testForRecordName() throws IOException, BallerinaOpenApiException { Path definitionPath = RES_DIR.resolve("record.yaml"); Path expectedPath = RES_DIR.resolve("modified_record.yaml"); @@ -29,7 +50,7 @@ public void pathParameter() { } - // no edited + // expect: not modify the query parameter names public void queryParameter() { } @@ -57,6 +78,7 @@ public void recursiveRecordName() throws IOException, BallerinaOpenApiException OpenAPI expectedFileContent = GeneratorUtils.getOpenAPIFromOpenAPIV3Parser(expectedPath); Assert.assertEquals(sanitized, expectedFileContent); } + // parameter in separate section // request section // response section diff --git a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/client/model/OASClientConfig.java b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/client/model/OASClientConfig.java index 5c0c9e8ea..f99de1fec 100644 --- a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/client/model/OASClientConfig.java +++ b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/client/model/OASClientConfig.java @@ -36,6 +36,7 @@ public class OASClientConfig { private final String license; private final boolean statusCodeBinding; private final boolean isMock; + private final boolean isUsingSanitizedOas; private OASClientConfig(Builder clientConfigBuilder) { @@ -47,6 +48,7 @@ private OASClientConfig(Builder clientConfigBuilder) { this.license = clientConfigBuilder.license; this.statusCodeBinding = clientConfigBuilder.statusCodeBinding; this.isMock = clientConfigBuilder.isMock; + this.isUsingSanitizedOas = clientConfigBuilder.isUsingSanitizedOas; } public OpenAPI getOpenAPI() { @@ -79,6 +81,10 @@ public boolean isMock() { return isMock; } + public boolean isUsingSanitizedOas() { + return isUsingSanitizedOas; + } + /** * Client IDL plugin meta data builder class. */ @@ -91,6 +97,7 @@ public static class Builder { private String license = DO_NOT_MODIFY_FILE_HEADER; private boolean statusCodeBinding = false; private boolean isMock = false; + private boolean isUsingSanitizedOas = false; public Builder withOpenAPI(OpenAPI openAPI) { this.openAPI = openAPI; @@ -132,6 +139,11 @@ public Builder withMock(boolean isMock) { return this; } + public Builder withIsUsingSanitizedOas(boolean isUsingSanitizedOas) { + this.isUsingSanitizedOas = isUsingSanitizedOas; + return this; + } + public OASClientConfig build() { return new OASClientConfig(this); } diff --git a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorUtils.java b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorUtils.java index ec52366bb..27d91b813 100644 --- a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorUtils.java +++ b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorUtils.java @@ -484,9 +484,7 @@ public static OpenAPI getOpenAPIFromOpenAPIV3Parser(Path definitionPath) throws throw new BallerinaOpenApiException(errorMessage.toString()); } - OpenAPI openAPI = parseResult.getOpenAPI(); - OASSanitizer oasSanitizer = new OASSanitizer(openAPI); - return oasSanitizer.sanitized(); + return parseResult.getOpenAPI(); } /** @@ -742,7 +740,7 @@ private static boolean isConstraintExists(Schema propertyValue) { * @throws IOException * @throws BallerinaOpenApiException */ - public static OpenAPI normalizeOpenAPI(Path openAPIPath, boolean validateOpIds) throws IOException, + public static OpenAPI normalizeOpenAPI(Path openAPIPath, boolean validateOpIds, boolean isSanitized) throws IOException, BallerinaOpenApiException { OpenAPI openAPI = getOpenAPIFromOpenAPIV3Parser(openAPIPath); io.swagger.v3.oas.models.Paths openAPIPaths = openAPI.getPaths(); @@ -750,6 +748,10 @@ public static OpenAPI normalizeOpenAPI(Path openAPIPath, boolean validateOpIds) validateOperationIds(openAPIPaths.entrySet()); } validateRequestBody(openAPIPaths.entrySet()); + if (isSanitized) { + OASSanitizer oasSanitizer = new OASSanitizer(openAPI); + return oasSanitizer.sanitized(); + } return openAPI; } diff --git a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/OASSanitizer.java b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/OASSanitizer.java index feeb3bd44..0e2849ef2 100644 --- a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/OASSanitizer.java +++ b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/OASSanitizer.java @@ -41,6 +41,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -61,10 +62,10 @@ public List getDiagnostics() { return diagnostics; } - //TODO: v3.1 vs 3.0 - public OpenAPI sanitized() { + public OpenAPI sanitized() { Paths paths = openapi.getPaths(); Components components = openapi.getComponents(); + List modifiedSchemaNames = new ArrayList<>(); Map modifiedSchemas = new HashMap<>(); Map modifiedRequestBodies = new HashMap<>(); Map modifiedResponses = new HashMap<>(); @@ -73,13 +74,18 @@ public OpenAPI sanitized() { if (components != null) { Map schemas = components.getSchemas(); if (schemas != null) { - for (Map.Entry schema: schemas.entrySet()) { + for (Map.Entry schema : schemas.entrySet()) { String schemaName = schema.getKey(); String modifiedName = getValidNameForType(schemaName); - //check the duplication + if (schema.getKey().contains(modifiedName) || modifiedSchemaNames.contains(modifiedName)) { + // todo: check the duplication, till providing the name this will give same name as it is. + continue; + } + modifiedSchemaNames.add(modifiedName); + // replace only for reference // 1.Update the reference at the component sections - for (Map.Entry componentSchema: schemas.entrySet()) { + for (Map.Entry componentSchema : schemas.entrySet()) { Schema value = componentSchema.getValue(); updateSchemaWithReference(schemaName, modifiedName, value); modifiedSchemas.put(modifiedName, value); @@ -89,7 +95,7 @@ public OpenAPI sanitized() { } // 2. Update OAS reusable requestBody with reference details if (components.getRequestBodies() != null) { - for (Map.Entry requestBody: components.getRequestBodies().entrySet()) { + for (Map.Entry requestBody : components.getRequestBodies().entrySet()) { RequestBody requestBodyValue = updateRequestBodySchemaType(schemaName, modifiedName, requestBody.getValue()); modifiedRequestBodies.put(requestBody.getKey(), requestBodyValue); @@ -98,7 +104,7 @@ public OpenAPI sanitized() { // 3. Update OAS reusable response with reference details if (components.getResponses() != null) { Map responsesEntry = components.getResponses(); - for (Map.Entry response: responsesEntry.entrySet()) { + for (Map.Entry response : responsesEntry.entrySet()) { ApiResponse modifiedResponse = updateSchemaTypeForResponses(schemaName, modifiedName, response.getValue()); modifiedResponses.put(response.getKey(), modifiedResponse); @@ -107,7 +113,7 @@ public OpenAPI sanitized() { // 4. Update OAS reusable parameters with reference details if (components.getParameters() != null) { Map parameters = components.getParameters(); - for (Map.Entry param: parameters.entrySet()) { + for (Map.Entry param : parameters.entrySet()) { Parameter parameter = param.getValue(); if (parameter.getSchema() != null) { Schema paramSchema = parameter.getSchema(); @@ -123,7 +129,7 @@ public OpenAPI sanitized() { // 5. Update OAS reusable headers with reference details if (components.getHeaders() != null) { Map headers = components.getHeaders(); - for (Map.Entry header: headers.entrySet()) { + for (Map.Entry header : headers.entrySet()) { Header headerValue = header.getValue(); Schema type = headerValue.getSchema(); String ref = type.get$ref(); @@ -156,11 +162,8 @@ public OpenAPI sanitized() { // This is for path parameter name modifications Paths modifiedPaths = new Paths(); - for (Map.Entry path: paths.entrySet()) { + for (Map.Entry path : paths.entrySet()) { PathDetails result = updateParameterName(modifiedSchemas, path); - if (result == null) { - continue; - } modifiedPaths.put(result.pathValue(), result.pathItem()); } openapi.setPaths(modifiedPaths); @@ -176,31 +179,7 @@ private static PathDetails updateParameterName(Map modifiedSchem if (operation.getParameters() == null) { return new PathDetails(pathItem, pathValue); } - List parameterNames = collectParameterNames(operation.getParameters()); - List parameters = operation.getParameters(); - if (parameters != null) { - //check path parameter - List modifiedParameters = new ArrayList<>(); - for (Parameter parameter: parameters) { - if (!parameter.getIn().equals("path")) { - modifiedParameters.add(parameter); - continue; - } - String oasPathParamName = parameter.getName(); - String modifiedPathParam = getValidNameForParameter(oasPathParamName); - //check duplicate - if (parameterNames.contains(modifiedSchemas)) { - // handle by adding abc_1 or abc_2 - } - // to avoid the duplication after two modifiers - parameterNames.add(modifiedPathParam); - parameter.setName(modifiedPathParam); - modifiedParameters.add(parameter); - pathValue = pathValue.replace("{" + oasPathParamName + "}", "{" + - modifiedPathParam + "}"); - } - operation.setParameters(modifiedParameters); - } + pathValue = updateParameterNames(modifiedSchemas, pathValue, operation); pathItem.setGet(operation); } if (pathItem.getPost() != null) { @@ -208,31 +187,7 @@ private static PathDetails updateParameterName(Map modifiedSchem if (operation.getParameters() == null) { return new PathDetails(pathItem, pathValue); } - List parameterNames = collectParameterNames(operation.getParameters()); - List parameters = operation.getParameters(); - if (parameters != null) { - //check path parameter - List modifiedParameters = new ArrayList<>(); - for (Parameter parameter: parameters) { - if (!parameter.getIn().equals("path")) { - modifiedParameters.add(parameter); - continue; - } - String oasPathParamName = parameter.getName(); - String modifiedPathParam = getValidNameForParameter(oasPathParamName); - //check duplicate - if (parameterNames.contains(modifiedSchemas)) { - // handle by adding abc_1 or abc_2 - } - // to avoid the duplication after two modifiers - parameterNames.add(modifiedPathParam); - parameter.setName(modifiedPathParam); - modifiedParameters.add(parameter); - pathValue = pathValue.replace("{" + oasPathParamName + "}", "{" + - modifiedPathParam + "}"); - } - operation.setParameters(modifiedParameters); - } + pathValue = updateParameterNames(modifiedSchemas, pathValue, operation); pathItem.setPost(operation); } if (pathItem.getPut() != null) { @@ -240,32 +195,7 @@ private static PathDetails updateParameterName(Map modifiedSchem if (operation.getParameters() == null) { return new PathDetails(pathItem, pathValue); } - List parameterNames = collectParameterNames(operation.getParameters()); - List parameters = operation.getParameters(); - if (parameters != null) { - //check path parameter - List modifiedParameters = new ArrayList<>(); - for (Parameter parameter: parameters) { - if (!parameter.getIn().equals("path")) { - modifiedParameters.add(parameter); - continue; - } - String oasPathParamName = parameter.getName(); - String modifiedPathParam = getValidNameForParameter(oasPathParamName); - //check duplicate - if (parameterNames.contains(modifiedSchemas)) { - // handle by adding abc_1 or abc_2 - } - // to avoid the duplication after two modifiers - parameterNames.add(modifiedPathParam); - parameter.setName(modifiedPathParam); - modifiedParameters.add(parameter); - //todo: path item needs to be updated: - pathValue = pathValue.replace("{" + oasPathParamName + "}", "{" + - modifiedPathParam + "}"); - } - operation.setParameters(modifiedParameters); - } + pathValue = updateParameterNames(modifiedSchemas, pathValue, operation); pathItem.setPut(operation); } if (pathItem.getDelete() != null) { @@ -273,31 +203,7 @@ private static PathDetails updateParameterName(Map modifiedSchem if (operation.getParameters() == null) { return new PathDetails(pathItem, pathValue); } - List parameterNames = collectParameterNames(operation.getParameters()); - List parameters = operation.getParameters(); - if (parameters != null) { - //check path parameter - List modifiedParameters = new ArrayList<>(); - for (Parameter parameter: parameters) { - if (!parameter.getIn().equals("path")) { - modifiedParameters.add(parameter); - continue; - } - String oasPathParamName = parameter.getName(); - String modifiedPathParam = getValidNameForParameter(oasPathParamName); - //check duplicate - if (parameterNames.contains(modifiedSchemas)) { - // handle by adding abc_1 or abc_2 - } - // to avoid the duplication after two modifiers - parameterNames.add(modifiedPathParam); - parameter.setName(modifiedPathParam); - modifiedParameters.add(parameter); - pathValue = pathValue.replace("{" + oasPathParamName + "}", "{" + - modifiedPathParam + "}"); - } - operation.setParameters(modifiedParameters); - } + pathValue = updateParameterNames(modifiedSchemas, pathValue, operation); pathItem.setDelete(operation); } if (pathItem.getPatch() != null) { @@ -305,31 +211,7 @@ private static PathDetails updateParameterName(Map modifiedSchem if (operation.getParameters() == null) { return new PathDetails(pathItem, pathValue); } - List parameterNames = collectParameterNames(operation.getParameters()); - List parameters = operation.getParameters(); - if (parameters != null) { - //check path parameter - List modifiedParameters = new ArrayList<>(); - for (Parameter parameter: parameters) { - if (!parameter.getIn().equals("path")) { - modifiedParameters.add(parameter); - continue; - } - String oasPathParamName = parameter.getName(); - String modifiedPathParam = getValidNameForParameter(oasPathParamName); - //check duplicate - if (parameterNames.contains(modifiedSchemas)) { - // handle by adding abc_1 or abc_2 - } - // to avoid the duplication after two modifiers - parameterNames.add(modifiedPathParam); - parameter.setName(modifiedPathParam); - modifiedParameters.add(parameter); - pathValue = pathValue.replace("{" + oasPathParamName + "}", "{" + - modifiedPathParam + "}"); - } - operation.setParameters(modifiedParameters); - } + pathValue = updateParameterNames(modifiedSchemas, pathValue, operation); pathItem.setPatch(operation); } if (pathItem.getHead() != null) { @@ -337,31 +219,7 @@ private static PathDetails updateParameterName(Map modifiedSchem if (operation.getParameters() == null) { return new PathDetails(pathItem, pathValue); } - List parameterNames = collectParameterNames(operation.getParameters()); - List parameters = operation.getParameters(); - if (parameters != null) { - //check path parameter - List modifiedParameters = new ArrayList<>(); - for (Parameter parameter: parameters) { - if (!parameter.getIn().equals("path")) { - modifiedParameters.add(parameter); - continue; - } - String oasPathParamName = parameter.getName(); - String modifiedPathParam = getValidNameForParameter(oasPathParamName); - //check duplicate - if (parameterNames.contains(modifiedSchemas)) { - // handle by adding abc_1 or abc_2 - } - // to avoid the duplication after two modifiers - parameterNames.add(modifiedPathParam); - parameter.setName(modifiedPathParam); - modifiedParameters.add(parameter); - pathValue = pathValue.replace("{" + oasPathParamName + "}", "{" + - modifiedPathParam + "}"); - } - operation.setParameters(modifiedParameters); - } + pathValue = updateParameterNames(modifiedSchemas, pathValue, operation); pathItem.setHead(operation); } if (pathItem.getOptions() != null) { @@ -369,31 +227,7 @@ private static PathDetails updateParameterName(Map modifiedSchem if (operation.getParameters() == null) { return new PathDetails(pathItem, pathValue); } - List parameterNames = collectParameterNames(operation.getParameters()); - List parameters = operation.getParameters(); - if (parameters != null) { - //check path parameter - List modifiedParameters = new ArrayList<>(); - for (Parameter parameter: parameters) { - if (!parameter.getIn().equals("path")) { - modifiedParameters.add(parameter); - continue; - } - String oasPathParamName = parameter.getName(); - String modifiedPathParam = getValidNameForParameter(oasPathParamName); - //check duplicate - if (parameterNames.contains(modifiedSchemas)) { - // handle by adding abc_1 or abc_2 - } - // to avoid the duplication after two modifiers - parameterNames.add(modifiedPathParam); - parameter.setName(modifiedPathParam); - modifiedParameters.add(parameter); - pathValue = pathValue.replace("{" + oasPathParamName + "}", "{" + - modifiedPathParam + "}"); - } - operation.setParameters(modifiedParameters); - } + pathValue = updateParameterNames(modifiedSchemas, pathValue, operation); pathItem.setOptions(operation); } if (pathItem.getTrace() != null) { @@ -401,48 +235,74 @@ private static PathDetails updateParameterName(Map modifiedSchem if (operation.getParameters() == null) { return new PathDetails(pathItem, pathValue); } - List parameterNames = collectParameterNames(operation.getParameters()); - List parameters = operation.getParameters(); - if (parameters != null) { - //check path parameter - List modifiedParameters = new ArrayList<>(); - for (Parameter parameter: parameters) { - if (!parameter.getIn().equals("path")) { - modifiedParameters.add(parameter); - continue; - } - String oasPathParamName = parameter.getName(); - String modifiedPathParam = getValidNameForParameter(oasPathParamName); - //check duplicate - if (parameterNames.contains(modifiedSchemas)) { - // handle by adding abc_1 or abc_2 - } - // to avoid the duplication after two modifiers - parameterNames.add(modifiedPathParam); - parameter.setName(modifiedPathParam); - modifiedParameters.add(parameter); - pathValue = pathValue.replace("{" + oasPathParamName + "}", "{" + - modifiedPathParam + "}"); - } - operation.setParameters(modifiedParameters); - } + pathValue = updateParameterNames(modifiedSchemas, pathValue, operation); pathItem.setTrace(operation); } return new PathDetails(pathItem, pathValue); } + private static String updateParameterNames(Map modifiedSchemas, String pathValue, Operation operation) { + List parameterNames = collectParameterNames(operation.getParameters()); + List parameters = operation.getParameters(); + if (parameters != null) { + List modifiedParameters = new ArrayList<>(); + pathValue = updateParameters(modifiedSchemas, pathValue, parameterNames, parameters, + modifiedParameters); + operation.setParameters(modifiedParameters); + } + return pathValue; + } + + private static String updateParameters(Map modifiedSchemas, String pathValue, + List parameterNames, List parameters, + List modifiedParameters) { + for (Parameter parameter : parameters) { + if (!parameter.getIn().equals("path")) { + modifiedParameters.add(parameter); + continue; + } + String oasPathParamName = parameter.getName(); + Optional modifiedPathParamResult = getValidNameForParameter(oasPathParamName); + if (modifiedPathParamResult.isEmpty()) { + //todo diagnostic, severity error + continue; + } + String modifiedPathParam = modifiedPathParamResult.get(); + if (parameterNames.contains(modifiedPathParam)) { + // todo: handle by adding abc_1 or abc_2 + continue; + } + // check given parameter has name which similar to component schema name + if (modifiedSchemas.containsKey(modifiedPathParam)) { + modifiedPathParam = "param" + getValidNameForParameter(modifiedPathParam).get(); + } + parameterNames.add(modifiedPathParam); + parameter.setName(modifiedPathParam); + modifiedParameters.add(parameter); + pathValue = pathValue.replace("{" + oasPathParamName + "}", "{" + + modifiedPathParam + "}"); + } + return pathValue; + } + + /** + * Record for storing return data + * @param pathItem + * @param pathValue + */ private record PathDetails(PathItem pathItem, String pathValue) { } /** + * This util is to update the all OAS operations in given path with modified schema name. * - * @param schemaName - * @param modifiedName - * @param operations + * @param schemaName - original schema name + * @param modifiedName - modified schema name + * @param operations - OAS operation. */ private static void updateOASOperations(String schemaName, String modifiedName, Set> operations) { - for (Map.Entry path: operations) { + for (Map.Entry path : operations) { PathItem pathItem = path.getValue(); if (pathItem.getGet() != null) { Operation operation = pathItem.getGet(); @@ -498,25 +358,32 @@ private static void updateObjectPropertyRef(Map properties, Stri } } - private static void updateSchemaWithReference(String schemaName, String modifiedName, Schema fieldValue) { - String ref = fieldValue.get$ref(); + /** + * Common util for handle all the schema type by updating the reference details. + * + * @param schemaName - original schema name + * @param modifiedName - modified schema + * @param typeSchema - type schema + */ + private static void updateSchemaWithReference(String schemaName, String modifiedName, Schema typeSchema) { + String ref = typeSchema.get$ref(); if (ref != null) { - updateRef(schemaName, modifiedName, fieldValue); - } else if (fieldValue instanceof ObjectSchema objectSchema) { + updateRef(schemaName, modifiedName, typeSchema); + } else if (typeSchema instanceof ObjectSchema objectSchema) { Map objectSchemaProperties = objectSchema.getProperties(); updateObjectPropertyRef(objectSchemaProperties, schemaName, modifiedName); - } else if (fieldValue instanceof ArraySchema arraySchema) { + } else if (typeSchema instanceof ArraySchema arraySchema) { Schema items = arraySchema.getItems(); updateSchemaWithReference(schemaName, modifiedName, items); - } else if (fieldValue instanceof MapSchema mapSchema) { + } else if (typeSchema instanceof MapSchema mapSchema) { updateObjectPropertyRef(mapSchema.getProperties(), schemaName, modifiedName); - } else if (fieldValue.getProperties() != null) { - updateObjectPropertyRef(fieldValue.getProperties(), schemaName, modifiedName); - } else if (fieldValue instanceof ComposedSchema composedSchema) { + } else if (typeSchema.getProperties() != null) { + updateObjectPropertyRef(typeSchema.getProperties(), schemaName, modifiedName); + } else if (typeSchema instanceof ComposedSchema composedSchema) { if (composedSchema.getAllOf() != null) { List allOf = composedSchema.getAllOf(); List modifiedAllOf = new ArrayList<>(); - for (Schema schema: allOf) { + for (Schema schema : allOf) { updateSchemaWithReference(schemaName, modifiedName, schema); modifiedAllOf.add(schema); } @@ -525,7 +392,7 @@ private static void updateSchemaWithReference(String schemaName, String modified if (composedSchema.getOneOf() != null) { List oneOf = composedSchema.getOneOf(); List modifiedOneOf = new ArrayList<>(); - for (Schema schema: oneOf) { + for (Schema schema : oneOf) { updateSchemaWithReference(schemaName, modifiedName, schema); modifiedOneOf.add(schema); } @@ -534,7 +401,7 @@ private static void updateSchemaWithReference(String schemaName, String modified if (composedSchema.getAnyOf() != null) { List anyOf = composedSchema.getAnyOf(); List modifiedAnyOf = new ArrayList<>(); - for (Schema schema: anyOf) { + for (Schema schema : anyOf) { updateSchemaWithReference(schemaName, modifiedName, schema); modifiedAnyOf.add(schema); } @@ -548,23 +415,30 @@ private static void updateRef(String schemaName, String modifiedName, Schema val String patternString = "/" + schemaName.replaceAll("\\s+", "") + "(?!\\S)"; Pattern pattern = Pattern.compile(patternString); Matcher matcher = pattern.matcher(ref); - ref = matcher.replaceAll("/" + modifiedName); + ref = matcher.replaceAll("/" + modifiedName); value.set$ref(ref); } + /** + * This util is to update the given OAS operation with modified schema name. + * + * @param schemaName - original schema name + * @param modifiedName - modified schema name + * @param operation - OAS operation. + */ private static void updateSchemaReferenceDetailsWithOperation(String schemaName, String modifiedName, Operation operation) { - // parameters type + // update parameters type if (operation.getParameters() != null) { updateParameterSchemaType(schemaName, modifiedName, operation); } - // request body + // update request body RequestBody requestBody = operation.getRequestBody(); if (requestBody != null) { RequestBody modifiedRequestBody = updateRequestBodySchemaType(schemaName, modifiedName, requestBody); operation.setRequestBody(modifiedRequestBody); } - // response + // update response ApiResponses responses = operation.getResponses(); responses.forEach((statusCode, response) -> { response = updateSchemaTypeForResponses(schemaName, modifiedName, response); @@ -574,25 +448,24 @@ private static void updateSchemaReferenceDetailsWithOperation(String schemaName, private static ApiResponse updateSchemaTypeForResponses(String schemaName, String modifiedName, ApiResponse response) { - Content content = response.getContent(); - if (content != null) { - for (Map.Entry stringMediaTypeEntry : content.entrySet()) { - MediaType mediaType = stringMediaTypeEntry.getValue(); - //TODO handle composeSchema - Schema responseSchemaType = mediaType.getSchema(); - if (responseSchemaType != null) { - String ref = responseSchemaType.get$ref(); - if (ref != null) { - updateSchemaWithReference(schemaName, modifiedName, responseSchemaType); - } - - mediaType.setSchema(responseSchemaType); + Content content = response.getContent(); + if (content != null) { + for (Map.Entry stringMediaTypeEntry : content.entrySet()) { + MediaType mediaType = stringMediaTypeEntry.getValue(); + Schema responseSchemaType = mediaType.getSchema(); + if (responseSchemaType != null) { + String ref = responseSchemaType.get$ref(); + if (ref != null) { + updateSchemaWithReference(schemaName, modifiedName, responseSchemaType); } - content.put(stringMediaTypeEntry.getKey(), mediaType); + + mediaType.setSchema(responseSchemaType); } - response.setContent(content); + content.put(stringMediaTypeEntry.getKey(), mediaType); } - return response; + response.setContent(content); + } + return response; } private static RequestBody updateRequestBodySchemaType(String schemaName, String modifiedName, @@ -601,7 +474,6 @@ private static RequestBody updateRequestBodySchemaType(String schemaName, String if (content != null) { for (Map.Entry stringMediaTypeEntry : content.entrySet()) { MediaType mediaType = stringMediaTypeEntry.getValue(); - //TODO handle composeSchema Schema requestSchemaType = mediaType.getSchema(); if (requestSchemaType != null) { String ref = requestSchemaType.get$ref(); @@ -657,10 +529,9 @@ public static String getValidNameForType(String identifier) { return (identifier.substring(0, 1).toUpperCase(Locale.ENGLISH) + identifier.substring(1)).trim(); } - public static String getValidNameForParameter(String identifier) { + public static Optional getValidNameForParameter(String identifier) { if (identifier.isBlank()) { - //diagnostics by saying path parameter should have a NAME - return "\\" + identifier; + return Optional.empty(); } if (!identifier.matches("\\b[0-9]*\\b")) { String[] split = identifier.split(GeneratorConstants.ESCAPE_PATTERN); @@ -678,8 +549,7 @@ public static String getValidNameForParameter(String identifier) { } else { identifier = "param" + identifier; } - //if modified name has duplicates - return identifier.trim(); + return Optional.of(identifier.trim()); } public static List collectParameterNames(List parameters) { diff --git a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/service/model/OASServiceMetadata.java b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/service/model/OASServiceMetadata.java index c84a57441..fc00bd3dc 100644 --- a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/service/model/OASServiceMetadata.java +++ b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/service/model/OASServiceMetadata.java @@ -36,6 +36,7 @@ public class OASServiceMetadata { private final String licenseHeader; private final String srcPackage; private final String srcFile; + private final boolean isUsingSanitizedOas; private OASServiceMetadata(Builder serviceMetadataBuilder) { this.openAPI = serviceMetadataBuilder.openAPI; @@ -46,6 +47,7 @@ private OASServiceMetadata(Builder serviceMetadataBuilder) { this.licenseHeader = serviceMetadataBuilder.licenseHeader; this.srcPackage = serviceMetadataBuilder.srcPackage; this.srcFile = serviceMetadataBuilder.srcFile; + this.isUsingSanitizedOas = serviceMetadataBuilder.isUsingSanitizedOas; } public OpenAPI getOpenAPI() { @@ -80,6 +82,9 @@ public String getSrcFile() { return srcFile; } + public boolean isUsingSanitizedOas() { + return isUsingSanitizedOas; + } /** * Service generation meta data builder class. */ @@ -95,6 +100,7 @@ public static class Builder { private String licenseHeader = ""; private String srcPackage = ""; private String srcFile = ""; + private boolean isUsingSanitizedOas = false; public Builder withOpenAPI(OpenAPI openAPI) { this.openAPI = openAPI; @@ -136,6 +142,11 @@ public Builder withSrcFile(String srcFile) { return this; } + public Builder withIsUsingSanitizedOas(boolean isUsingSanitizedOas) { + this.isUsingSanitizedOas = isUsingSanitizedOas; + return this; + } + public OASServiceMetadata build() { return new OASServiceMetadata(this); } diff --git a/openapi-core/src/main/java/module-info.java b/openapi-core/src/main/java/module-info.java index c052b18fc..322fdfe99 100644 --- a/openapi-core/src/main/java/module-info.java +++ b/openapi-core/src/main/java/module-info.java @@ -39,7 +39,6 @@ requires org.apache.commons.lang3; requires com.fasterxml.jackson.databind; - exports io.ballerina.openapi.core.generators.common.model; exports io.ballerina.openapi.core.generators.common.exception; exports io.ballerina.openapi.core.generators.client.model; From 556765c46e219ac16d860af3acffb61e594561a0 Mon Sep 17 00:00:00 2001 From: lnash94 Date: Fri, 2 Aug 2024 06:59:19 +0530 Subject: [PATCH 4/9] Update tests --- .../generators/client/AnnotationTests.java | 2 +- .../client/ComparedGeneratedFileTests.java | 4 +-- .../client/EnumGenerationTests.java | 8 +++--- .../generators/client/FilterTests.java | 4 +-- .../client/FunctionSignatureNodeTests.java | 2 +- .../generators/client/HeadersTests.java | 2 +- .../generators/client/NoServerURLTest.java | 4 +-- .../generators/client/PathParameterTests.java | 2 +- .../client/QueryParameterTests.java | 2 +- .../RemoteFunctionNameValidationTests.java | 2 +- .../generators/client/RequestBodyTests.java | 4 +-- .../client/ResourceFunctionTests.java | 2 +- .../client/UtilGenerationTests.java | 2 +- .../common/GeneratorUtilsTests.java | 2 +- .../schema/AdvanceRecordTypeTests.java | 8 +++--- .../generators/schema/AllOfDataTypeTests.java | 20 ++++++------- .../generators/schema/AnnotationTests.java | 2 +- .../generators/schema/AnyOfDataTypeTests.java | 4 +-- .../generators/schema/ArrayDataTypeTests.java | 26 ++++++++--------- .../generators/schema/ConstraintTests.java | 28 +++++++++---------- .../schema/EnumGenerationTests.java | 7 +++-- .../schema/FieldGenWithNullableOption.java | 12 ++++---- .../schema/IntegerDataTypeTests.java | 2 +- .../schema/MapSchemaNegativeTests.java | 4 +-- .../generators/schema/MapSchemaTests.java | 4 +-- .../schema/NegativeConstraintTests.java | 2 +- .../schema/NestedRecordInclusionTests.java | 2 +- .../generators/schema/NullableFieldTests.java | 20 ++++++------- .../generators/schema/OneOfDataTypeTests.java | 12 ++++---- .../schema/PrimitiveDataTypeTests.java | 12 ++++---- .../schema/RecordDataTypeTests.java | 6 ++-- .../schema/RecordDefaultValueTests.java | 12 ++++---- .../schema/ReferenceResolveTests.java | 12 ++++---- .../schema/SwaggerFileParserTests.java | 3 +- .../generators/schema/TypeFormatTests.java | 2 +- .../service/QueryParameterTests.java | 4 +-- .../generators/service/RequestBodyTests.java | 4 +-- .../service/ServiceDiagnosticTests.java | 4 +-- .../BallerinaTestGeneratorTests.java | 2 +- .../generators/common/GeneratorUtils.java | 4 +-- .../core/generators/common/OASSanitizer.java | 12 +++++--- 41 files changed, 139 insertions(+), 133 deletions(-) diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/AnnotationTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/AnnotationTests.java index 89acecfab..6ee64fa61 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/AnnotationTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/AnnotationTests.java @@ -105,7 +105,7 @@ public void openApiToBallerinaClientGenWithAnnotation(String yamlFile, String e List list1 = new ArrayList<>(); List list2 = new ArrayList<>(); Filter filter = new Filter(list1, list2); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/ComparedGeneratedFileTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/ComparedGeneratedFileTests.java index 5ee437f26..c1e8fe3c8 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/ComparedGeneratedFileTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/ComparedGeneratedFileTests.java @@ -66,7 +66,7 @@ public void generateClientForJira() throws IOException, BallerinaOpenApiExceptio OASTypeGenException, FormatterException, ClientException { Path definitionPath = RES_DIR.resolve("openapi.yaml"); Path expectedPath = RES_DIR.resolve("file_provider/ballerina/jira_openapi.bal"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder .withFilters(filter) @@ -85,7 +85,7 @@ public void openApiToBallerinaCodeGenTestForClient(String yamlFile, String expe OASTypeGenException, FormatterException, ClientException, BallerinaOpenApiException { Path definitionPath = RES_DIR.resolve("file_provider/swagger/" + yamlFile); Path expectedPath = RES_DIR.resolve("file_provider/ballerina/" + expectedFile); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/EnumGenerationTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/EnumGenerationTests.java index 76ec31f63..0902f77c4 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/EnumGenerationTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/EnumGenerationTests.java @@ -69,7 +69,7 @@ public void generateRemoteParametersWithEnums() throws IOException, BallerinaOpe FormatterException, ClientException { Path definitionPath = RES_DIR.resolve("swagger/parameters_with_enum.yaml"); Path expectedPath = RES_DIR.resolve("ballerina/parameters_with_enum.bal"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder @@ -101,7 +101,7 @@ public void generateRemoteParametersWithNullableEnums() throws IOException, Ball OASTypeGenException, FormatterException, ClientException { Path definitionPath = RES_DIR.resolve("swagger/parameters_with_nullable_enums.yaml"); Path expectedPath = RES_DIR.resolve("ballerina/parameters_with_nullable_enums.bal"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder @@ -133,7 +133,7 @@ public void generateResourceParametersWithEnums() throws IOException, BallerinaO OASTypeGenException, FormatterException, ClientException { Path definitionPath = RES_DIR.resolve("swagger/parameters_with_enum.yaml"); Path expectedPath = RES_DIR.resolve("ballerina/paramters_with_enum_resource.bal"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder @@ -165,7 +165,7 @@ public void generateResourceParametersWithNullableEnums() throws IOException, Ba OASTypeGenException, FormatterException, ClientException { Path definitionPath = RES_DIR.resolve("swagger/parameters_with_nullable_enums.yaml"); Path expectedPath = RES_DIR.resolve("ballerina/parameters_with_nullable_enums_resource.bal"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/FilterTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/FilterTests.java index a7757ba9a..112228063 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/FilterTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/FilterTests.java @@ -56,7 +56,7 @@ public void testWithTag() throws IOException, BallerinaOpenApiException, ClientE list2.clear(); list1.add("Data for all countries"); Filter filter = new Filter(list1, list2); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder .withFilters(filter) @@ -76,7 +76,7 @@ public void testWithOperation() throws IOException, BallerinaOpenApiException, C list2.clear(); list2.add("getCountryList"); Filter filter = new Filter(list1, list2); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder .withFilters(filter) diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/FunctionSignatureNodeTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/FunctionSignatureNodeTests.java index b487f75cf..f0667cc0f 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/FunctionSignatureNodeTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/FunctionSignatureNodeTests.java @@ -124,7 +124,7 @@ public void testFunctionSignatureNodeForJSONPayload() throws IOException, Baller @Test(description = "Test for generate function signature for multipart custom header") public void testFunctionSignatureNodeForMultipartCustomHeader() throws IOException, BallerinaOpenApiException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI( - RESDIR.resolve("swagger/multipart_formdata_custom.yaml"), true); + RESDIR.resolve("swagger/multipart_formdata_custom.yaml"), true, false); Operation operation = openAPI.getPaths().get("/pets").getPost(); TypeHandler.createInstance(openAPI, false); RemoteFunctionSignatureGenerator functionSignatureGenerator = new RemoteFunctionSignatureGenerator(operation, diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/HeadersTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/HeadersTests.java index 1c7ac588a..56e6f18aa 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/HeadersTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/HeadersTests.java @@ -105,7 +105,7 @@ public void testIntegerTypeHeaders() throws IOException, BallerinaOpenApiExcepti private BallerinaClientGenerator getBallerinaClientGenerator(Path definitionPath) throws IOException, BallerinaOpenApiException { - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/NoServerURLTest.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/NoServerURLTest.java index 85914aa4c..9088576ea 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/NoServerURLTest.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/NoServerURLTest.java @@ -40,7 +40,7 @@ public void getClientForNoServerURL() throws IOException, BallerinaOpenApiExcept Path definitionPath = RES_DIR.resolve("swagger/missing_server_url.yaml"); Path expectedPath = RES_DIR.resolve("ballerina/missing_server_url.bal"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder @@ -88,7 +88,7 @@ public void getClientForBlankDefaultValueServerURL() throws IOException, Balleri Path definitionPath = RES_DIR.resolve("swagger/blank_value_server_url.yaml"); Path expectedPath = RES_DIR.resolve("ballerina/blank_value_server_url.bal"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/PathParameterTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/PathParameterTests.java index 504016993..9957f3ff6 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/PathParameterTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/PathParameterTests.java @@ -148,7 +148,7 @@ public void testIntegerPathParameters() throws IOException, BallerinaOpenApiExce private BallerinaClientGenerator getBallerinaClientGenerator(Path definitionPath) throws IOException, BallerinaOpenApiException { - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, true); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/QueryParameterTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/QueryParameterTests.java index e61d81d57..0d8390fc3 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/QueryParameterTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/QueryParameterTests.java @@ -114,7 +114,7 @@ public void testContentTypeQueryParam() throws IOException, BallerinaOpenApiExce private BallerinaClientGenerator getBallerinaClientGenerator(Path definitionPath) throws IOException, BallerinaOpenApiException { - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, true); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/RemoteFunctionNameValidationTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/RemoteFunctionNameValidationTests.java index 16669da31..aca2948f7 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/RemoteFunctionNameValidationTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/RemoteFunctionNameValidationTests.java @@ -37,7 +37,7 @@ public class RemoteFunctionNameValidationTests { "operations: \\ROperationId is missing in the resource path: .*", enabled = false) public void testMissionOperationId() throws IOException, BallerinaOpenApiException, ClientException { Path definitionPath = RESDIR.resolve("petstore_without_operation_id.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder .withFilters(filter) diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/RequestBodyTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/RequestBodyTests.java index 64928c89f..d2aff49e8 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/RequestBodyTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/RequestBodyTests.java @@ -115,7 +115,7 @@ public void testRequestBodyWithUnsupportedMediaType() throws IOException, Baller ".*GET operation cannot have a requestBody.*", enabled = false) public void testGetOrDeleteOrHeadContainRequestBody() throws IOException, BallerinaOpenApiException { Path definitionPath = RES_DIR.resolve("swagger/request_body_in_get_delete_head.yaml"); - GeneratorUtils.normalizeOpenAPI(definitionPath, true); + GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); } @Test(description = "Test for generating request body when operation has form url encoded media type") @@ -270,7 +270,7 @@ private void deleteGeneratedFiles() { private BallerinaClientGenerator getBallerinaClientGenerator(Path definitionPath) throws IOException, BallerinaOpenApiException { - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, true); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/ResourceFunctionTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/ResourceFunctionTests.java index 4f77027ff..4c346d439 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/ResourceFunctionTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/ResourceFunctionTests.java @@ -90,7 +90,7 @@ public void generateReferenceResolvePath() throws IOException, BallerinaOpenApiE private BallerinaClientGenerator getBallerinaClientGenerator(Path definitionPath) throws IOException, BallerinaOpenApiException { - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, true); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/UtilGenerationTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/UtilGenerationTests.java index 4cf3e8081..6b3a29ddf 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/UtilGenerationTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/client/UtilGenerationTests.java @@ -232,7 +232,7 @@ private boolean checkUtil(List invalidFunctionNames, SyntaxTree utilSynt private BallerinaClientGenerator getBallerinaClientGenerator(Path definitionPath) throws IOException, BallerinaOpenApiException { - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, true); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/common/GeneratorUtilsTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/common/GeneratorUtilsTests.java index bb7cea073..9b63e6f56 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/common/GeneratorUtilsTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/common/GeneratorUtilsTests.java @@ -80,7 +80,7 @@ public static void testForReferenceLinkValid() throws BallerinaOpenApiException @Test(description = "Set record name with removing special Characters") public static void testRecordName() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("schema/swagger/recordName" + - ".yaml"), false); + ".yaml"), false, false); SyntaxTree syntaxTree = null; TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/AdvanceRecordTypeTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/AdvanceRecordTypeTests.java index f05876f87..108d776fe 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/AdvanceRecordTypeTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/AdvanceRecordTypeTests.java @@ -46,7 +46,7 @@ public class AdvanceRecordTypeTests { @Test(description = "Generate record for schema has not type") public void generateSchemaHasNotType() throws IOException, FormatterException, BallerinaOpenApiException { Path definitionPath = RES_DIR.resolve("swagger/scenario10.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -63,7 +63,7 @@ public void generateSchemaHasNotType() throws IOException, FormatterException, B @Test(description = "Generate record for schema has inline record in fields reference") public void generateSchemaHasInlineRecord() throws IOException, FormatterException, BallerinaOpenApiException { Path definitionPath = RES_DIR.resolve("swagger/scenario11.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -79,7 +79,7 @@ public void generateSchemaHasInlineRecord() throws IOException, FormatterExcepti @Test(description = "Generate record for openapi weather api") public void generateOpenAPIWeatherAPI() throws IOException, FormatterException, BallerinaOpenApiException { Path definitionPath = RES_DIR.resolve("swagger/openapi_weather_api.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -97,7 +97,7 @@ public void generateOpenAPIWeatherAPI() throws IOException, FormatterException, public void generateForSchemaHasObjectTypeOnly() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/scenario14.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/AllOfDataTypeTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/AllOfDataTypeTests.java index 8379dd4dd..47056b6a2 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/AllOfDataTypeTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/AllOfDataTypeTests.java @@ -46,7 +46,7 @@ public class AllOfDataTypeTests { @Test(description = "Generate record for schema has allOf reference") public void generateAllOf() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/scenario09.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -63,7 +63,7 @@ public void generateAllOf() throws IOException, BallerinaOpenApiException, Forma @Test(description = "Generate record for schema has allOf reference in record field") public void generateAllOfInRecordField() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/allOf.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -80,7 +80,7 @@ public void generateAllOfInRecordField() throws IOException, BallerinaOpenApiExc @Test(description = "Generate record when allOf schema has only one references schema") public void generateTypeForSingleAllOfSchema() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/allOf_with_one_ref.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -98,7 +98,7 @@ public void generateTypeForSingleAllOfSchema() throws IOException, BallerinaOpen "schema") public void generateCyclicSchemaAllOfSchema() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/allOf_with_cyclic.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -116,7 +116,7 @@ public void generateCyclicSchemaAllOfSchema() throws IOException, BallerinaOpenA public void generateAllOfWithTypeUnSpecifiedObjectSchema() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/allOfWithNoType.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -133,7 +133,7 @@ public void generateAllOfWithTypeUnSpecifiedObjectSchema() throws IOException, @Test(description = "Generate record for allOf type array schemas with inline object schemas") public void generateArrayAllOfInlineObjects() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/array_with_inline_allOf.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -151,7 +151,7 @@ public void generateArrayAllOfInlineObjects() throws IOException, BallerinaOpenA public void generateAllOfWithEmptyObjectSchema() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/allOfWithEmptyObject.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -168,7 +168,7 @@ public void generateAllOfWithEmptyObjectSchema() throws IOException, BallerinaOp @Test(description = "Generate record for nested allOf schemas") public void generateNestedAllOfSchema() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/nested_allOf_with_allOf.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -185,7 +185,7 @@ public void generateNestedAllOfSchema() throws IOException, BallerinaOpenApiExce @Test(description = "Generate type definition from allOf schema with valid single item") public void generateAllOfwithValidSingleItem() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/single_item_allOf.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -202,7 +202,7 @@ public void generateAllOfwithValidSingleItem() throws IOException, BallerinaOpen @Test(description = "Tests record generation for nested OneOf schema inside AllOf schema") public void generateAllOfWithOneOf() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/nested_allOf_with_oneOf.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/AnnotationTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/AnnotationTests.java index d1d4d89ba..263034d5f 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/AnnotationTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/AnnotationTests.java @@ -29,7 +29,7 @@ public void generateRecordsWithDeprecatedAnnotations() throws IOException, Balle FormatterException { Path definitionPath = RES_DIR.resolve("swagger/deprecated_schemas.yaml"); Path expectedPath = RES_DIR.resolve("ballerina/deprecated_schemas.bal"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/AnyOfDataTypeTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/AnyOfDataTypeTests.java index 45fb0a569..5b8016baf 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/AnyOfDataTypeTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/AnyOfDataTypeTests.java @@ -55,7 +55,7 @@ public class AnyOfDataTypeTests { @Test(description = "Test for the schema has anyOf dataType") public void testAnyOfInSchema() throws IOException, BallerinaOpenApiException, OASTypeGenException { Path definitionPath = RES_DIR.resolve("swagger/scenario15.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); Schema schema = openAPI.getComponents().getSchemas().get("AnyOF"); ComposedSchema composedSchema = (ComposedSchema) schema; GeneratorMetaData.createInstance(openAPI, false); @@ -69,7 +69,7 @@ public void testAnyOfInSchema() throws IOException, BallerinaOpenApiException, O public void testAnyOfSchema() throws BallerinaOpenApiException, FormatterException, IOException { Path definitionPath = RES_DIR.resolve("swagger/scenario15.yaml"); Path expectedPath = RES_DIR.resolve("ballerina/schema15.bal"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/ArrayDataTypeTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/ArrayDataTypeTests.java index 212d6907f..3973d484d 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/ArrayDataTypeTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/ArrayDataTypeTests.java @@ -57,7 +57,7 @@ public void beforeTest() { @Test(description = "Generate record with array filed record") public void generateRecordWithArrayField() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/scenario03.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -74,7 +74,7 @@ public void generateRecordWithArrayField() throws IOException, BallerinaOpenApiE @Test(description = "Scenario04-Generate record with nested array filed record") public void generateScenario04() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/scenario04.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -91,7 +91,7 @@ public void generateScenario04() throws IOException, BallerinaOpenApiException, @Test(description = "Generate record with record type array filed record") public void generateRecordWithRecordArrayField() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/scenario06.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -109,7 +109,7 @@ public void generateRecordWithRecordArrayField() throws IOException, BallerinaOp @Test(description = "Generate record for schema has array reference") public void generateSchemaHasArrayReference() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/scenario08.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -126,7 +126,7 @@ public void generateSchemaHasArrayReference() throws IOException, BallerinaOpenA @Test(description = "Generate Array for schema has array reference") public void generateSchemaArrayReference() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/schema_with_array.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -144,7 +144,7 @@ public void generateSchemaArrayReference() throws IOException, BallerinaOpenApiE public void generateSchemaNestedArrayReference() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/schema_with_nested_array.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -161,7 +161,7 @@ public void generateSchemaNestedArrayReference() throws IOException, BallerinaOp @Test(description = "Array schema has no data type in items") public void arrayNoDatatype() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/array_no_item_type.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -178,7 +178,7 @@ public void arrayNoDatatype() throws IOException, BallerinaOpenApiException, For @Test(description = "Array schema has max item count") public void arrayHasMaxItems() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/array_max_item.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -195,7 +195,7 @@ public void arrayHasMaxItems() throws IOException, BallerinaOpenApiException, Fo @Test(description = "Array schema with allOf") public void arrayHasAllOfItems() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/array_with_allOf.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -212,7 +212,7 @@ public void arrayHasAllOfItems() throws IOException, BallerinaOpenApiException, @Test(description = "Array schema with oneOf") public void arrayHasOneOFfItems() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/array_with_oneOf.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -229,7 +229,7 @@ public void arrayHasOneOFfItems() throws IOException, BallerinaOpenApiException, @Test(description = "Array schema with oneOf schema with nullable item") public void arrayHasOneOfItemsWithNullable() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/array_with_oneOf_complex.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -246,7 +246,7 @@ public void arrayHasOneOfItemsWithNullable() throws IOException, BallerinaOpenAp @Test(description = "Array schema has max items count that ballerina doesn't support") public void arrayHasMaxItemsExceedLimit() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/array_exceed_max_item.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -266,7 +266,7 @@ public void arrayHasMaxItemsExceedLimit() throws IOException, BallerinaOpenApiEx @Test(description = "Array schema has max items count that ballerina doesn't support, in record field") public void arrayHasMaxItemsExceedLimit02() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/array_exceed_max_item_02.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/ConstraintTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/ConstraintTests.java index 2e094e5db..12f6a7c9c 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/ConstraintTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/ConstraintTests.java @@ -62,7 +62,7 @@ public void setUp() throws IOException { "with constraint.") public void testRecordFiledConstraint() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger/constraint/record_field.yaml"), - true); + true, false); TypeHandler.createInstance(openAPI, false); RequestBodyGenerator requestBodyGenerator = new RequestBodyGenerator(openAPI.getPaths() .get("/admin").getPost().getRequestBody(), openAPI); @@ -82,7 +82,7 @@ public void testRecordFiledConstraint() throws IOException, BallerinaOpenApiExce "Use case 05 : Only array items have constrained with number format") public void testForArray() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger/constraint/array.yaml"), - true); + true, false); TypeHandler.createInstance(openAPI, false); RequestBodyGenerator requestBodyGenerator = new RequestBodyGenerator(openAPI.getPaths() .get("/admin").getPost().getRequestBody(), openAPI); @@ -100,7 +100,7 @@ public void testForArray() throws IOException, BallerinaOpenApiException, Format "Use case 03 : Annotations on a type used as a record field") public void testForReference() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger/constraint/type_def_node.yaml"), - true); + true, false); TypeHandler.createInstance(openAPI, false); RequestBodyGenerator requestBodyGenerator = new RequestBodyGenerator(openAPI.getPaths().get("/admin") .getPost().getRequestBody(), openAPI); @@ -118,7 +118,7 @@ public void testRecordFiledConstraintWithZeroValue() throws IOException, Balleri FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve( "swagger/constraint/record_field_02.yaml"), - true); + true, false); TypeHandler.createInstance(openAPI, false); RequestBodyGenerator requestBodyGenerator = new RequestBodyGenerator(openAPI.getPaths() .get("/admin").getPost().getRequestBody(), openAPI); @@ -135,7 +135,7 @@ public void testRecordFiledConstraintWithZeroValue() throws IOException, Balleri public void testNestedArrayWithConstraint() throws IOException, BallerinaOpenApiException, FormatterException, ClientException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger/constraint" + - "/nested_array_with_constraint.yaml"), true); + "/nested_array_with_constraint.yaml"), true, false); TypeHandler.createInstance(openAPI, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder @@ -158,7 +158,7 @@ public void testNestedArrayWithConstraint() throws IOException, BallerinaOpenApi public void testAdditionalPropertiesWithConstraint() throws IOException, BallerinaOpenApiException, FormatterException, ClientException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger/constraint" + - "/additional_properties_with_constraint.yaml"), true); + "/additional_properties_with_constraint.yaml"), true, false); TypeHandler.createInstance(openAPI, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder @@ -182,7 +182,7 @@ public void testAdditionalPropertiesWithConstraint() throws IOException, Balleri public void testInvalidConstraintUses() throws IOException, BallerinaOpenApiException, FormatterException, ClientException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger/constraint" + - "/invalidConstraintFieldWithDataType.yaml"), true); + "/invalidConstraintFieldWithDataType.yaml"), true, false); TypeHandler.createInstance(openAPI, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder @@ -204,7 +204,7 @@ public void testInvalidConstraintUses() throws IOException, BallerinaOpenApiExce public void testInvalidAndValidBothConstraintUses() throws IOException, BallerinaOpenApiException, FormatterException, ClientException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger/constraint" + - "/invalidAndValidConstraintFieldWithDataType.yaml"), true); + "/invalidAndValidConstraintFieldWithDataType.yaml"), true, false); TypeHandler.createInstance(openAPI, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder @@ -226,7 +226,7 @@ public void testInvalidAndValidBothConstraintUses() throws IOException, Ballerin public void testAllowedZeroValuesForNumber() throws IOException, BallerinaOpenApiException, FormatterException, ClientException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger/constraint" + - "/allow_zero_values_for_number_constraint.yaml"), true); + "/allow_zero_values_for_number_constraint.yaml"), true, false); TypeHandler.createInstance(openAPI, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder @@ -248,7 +248,7 @@ public void testAllowedZeroValuesForNumber() throws IOException, BallerinaOpenAp public void testNullableRefTypesWithConstraint() throws IOException, BallerinaOpenApiException, FormatterException, ClientException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger/constraint" + - "/constraint_with_nullable.yaml"), true); + "/constraint_with_nullable.yaml"), true, false); TypeHandler.createInstance(openAPI, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder @@ -270,7 +270,7 @@ public void testNullableRefTypesWithConstraint() throws IOException, BallerinaOp public void testStringSchemaPropertyWithPattern() throws IOException, BallerinaOpenApiException, FormatterException, ClientException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger/constraint" + - "/pattern_string.yaml"), true); + "/pattern_string.yaml"), true, false); TypeHandler.createInstance(openAPI, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder @@ -292,7 +292,7 @@ public void testStringSchemaPropertyWithPattern() throws IOException, BallerinaO public void testExclusiveMinMaxInV31() throws IOException, BallerinaOpenApiException, OASTypeGenException, FormatterException, ClientException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger/constraint" + - "/exclusive_min_max_3_1.yaml"), true); + "/exclusive_min_max_3_1.yaml"), true, false); TypeHandler.createInstance(openAPI, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder @@ -314,7 +314,7 @@ public void testExclusiveMinMaxInV31() throws IOException, BallerinaOpenApiExcep enabled = false) // todo : need to fix as the resource order changes intermittently public void testDataTypeHasFormatWithConstraint() throws IOException, BallerinaOpenApiException, ClientException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger/constraint" + - "/format_types_v3_0.yaml"), true); + "/format_types_v3_0.yaml"), true, false); TypeHandler.createInstance(openAPI, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder @@ -334,7 +334,7 @@ public void testDataTypeHasFormatWithConstraintOASV3() throws IOException, Balle ClientException { //Test for OpenAPI version 3.1 OpenAPI openAPIV31 = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger/constraint" + - "/format_types_v3_1.yaml"), true); + "/format_types_v3_1.yaml"), true, false); TypeHandler.createInstance(openAPIV31, false); OASClientConfig.Builder cBuilder = new OASClientConfig.Builder(); OASClientConfig cBuilderConfig = cBuilder diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/EnumGenerationTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/EnumGenerationTests.java index 7f735aecf..8c9dd6159 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/EnumGenerationTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/EnumGenerationTests.java @@ -60,7 +60,8 @@ public void setUp() throws IOException { "Use case 03 : Enum with null value" + "Use case 04 : Enum as array items") public void testForEnums() throws IOException, BallerinaOpenApiException, FormatterException { - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger/schema_with_enums.yaml"), true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger/schema_with_enums.yaml"), + true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -84,7 +85,7 @@ public void testForEnums() throws IOException, BallerinaOpenApiException, Format "Use case 05 : Nullable enum in arrays") public void testForNullableEnums() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve( - "swagger/schema_with_nullable_enums.yaml"), true); + "swagger/schema_with_nullable_enums.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -103,7 +104,7 @@ public void testForNullableEnums() throws IOException, BallerinaOpenApiException @Test(description = "Test enum with no values") public void testForEmptyEnums() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve( - "swagger/empty_enum.yaml"), true); + "swagger/empty_enum.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/FieldGenWithNullableOption.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/FieldGenWithNullableOption.java index 376dd067a..716b57e3b 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/FieldGenWithNullableOption.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/FieldGenWithNullableOption.java @@ -44,7 +44,7 @@ public class FieldGenWithNullableOption { @Test(description = "Test for nullable primitive fields") public void testNullablePrimitive() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/nullable_option_primitive_schema.yaml"), true); + "/nullable_option_primitive_schema.yaml"), true, false); TypeHandler.createInstance(openAPI, true); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -61,7 +61,7 @@ public void testNullablePrimitive() throws IOException, BallerinaOpenApiExceptio @Test(description = "Test for nullable array fields") public void testNullableArray() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/nullable_option_array_schema.yaml"), true); + "/nullable_option_array_schema.yaml"), true, false); TypeHandler.createInstance(openAPI, true); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -78,7 +78,7 @@ public void testNullableArray() throws IOException, BallerinaOpenApiException, F @Test(description = "Test for nullable record fields") public void testNullableRecord() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/nullable_option_record_schema.yaml"), true); + "/nullable_option_record_schema.yaml"), true, false); TypeHandler.createInstance(openAPI, true); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -95,7 +95,7 @@ public void testNullableRecord() throws IOException, BallerinaOpenApiException, @Test(description = "Test for primitive referenced type") public void testPrimitiveReferencedTypes() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/nullable_option_string_type.yaml"), true); + "/nullable_option_string_type.yaml"), true, false); TypeHandler.createInstance(openAPI, true); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -113,7 +113,7 @@ public void testPrimitiveReferencedTypes() throws IOException, BallerinaOpenApiE @Test(description = "Test for referenced schema with no type given") public void testNullTypeReference() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/nullable_option_null_type.yaml"), true); + "/nullable_option_null_type.yaml"), true, false); TypeHandler.createInstance(openAPI, true); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -130,7 +130,7 @@ public void testNullTypeReference() throws IOException, BallerinaOpenApiExceptio @Test(description = "Test field generation when nullable false") public void testNullableFalse() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/nullable_false.yaml"), true); + "/nullable_false.yaml"), true, false); TypeHandler.createInstance(openAPI, true); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/IntegerDataTypeTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/IntegerDataTypeTests.java index 8f8ed8c6f..4a206380c 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/IntegerDataTypeTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/IntegerDataTypeTests.java @@ -59,7 +59,7 @@ public Object[][] intFormatTestData() { public void testIntegerFormatTypeSchema(final String swaggerPath, final String balPath) throws IOException, BallerinaOpenApiException, FormatterException { final Path definitionPath = RES_DIR.resolve(swaggerPath); - final OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + final OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/MapSchemaNegativeTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/MapSchemaNegativeTests.java index b08ace013..c1d12ef5f 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/MapSchemaNegativeTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/MapSchemaNegativeTests.java @@ -57,7 +57,7 @@ public void setUp() { public void testForAdditionalPropertiesWithParserIssue() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/additional_properties_true_negative.yaml"), true); + "/additional_properties_true_negative.yaml"), true, false); TypeHandler.createInstance(openAPI, true); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -72,7 +72,7 @@ public void testForAdditionalPropertiesWithParserIssue() throws IOException, Bal public void testForAdditionalPropertiesWithoutParserIssue() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/additional_properties_true_negative_without_parser_issue.yaml"), true); + "/additional_properties_true_negative_without_parser_issue.yaml"), true, false); TypeHandler.createInstance(openAPI, true); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/MapSchemaTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/MapSchemaTests.java index 233c35518..391d91ee6 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/MapSchemaTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/MapSchemaTests.java @@ -45,7 +45,7 @@ public class MapSchemaTests { @Test public void testForAdditionalProperties() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/additional_properties_true.yaml"), true); + "/additional_properties_true.yaml"), true, false); TypeHandler.createInstance(openAPI, true); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -63,7 +63,7 @@ public void testForAdditionalProperties() throws IOException, BallerinaOpenApiEx public void testForAdditionalPropertiesComposedSchema() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/additional_properties_composed_schema.yaml"), true); + "/additional_properties_composed_schema.yaml"), true, false); TypeHandler.createInstance(openAPI, true); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/NegativeConstraintTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/NegativeConstraintTests.java index b2f923157..4d550180d 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/NegativeConstraintTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/NegativeConstraintTests.java @@ -54,7 +54,7 @@ public class NegativeConstraintTests { public void testNonStringSchemaPropertyWithPattern() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger/constraint" + - "/pattern_except_string_type.yaml"), true); + "/pattern_except_string_type.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/NestedRecordInclusionTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/NestedRecordInclusionTests.java index 4e40be091..772eb4873 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/NestedRecordInclusionTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/NestedRecordInclusionTests.java @@ -27,7 +27,7 @@ public class NestedRecordInclusionTests { @Test(description = "Generate records for nested referenced schemas") public void generateAllOf() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/nested_schema_refs.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/NullableFieldTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/NullableFieldTests.java index a967b0eff..dba8a74aa 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/NullableFieldTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/NullableFieldTests.java @@ -46,7 +46,7 @@ public class NullableFieldTests { @Test(description = "Test for nullable primitive fields") public void testNullablePrimitive() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/nullable_primitive_schema.yaml"), true); + "/nullable_primitive_schema.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -63,7 +63,7 @@ public void testNullablePrimitive() throws IOException, BallerinaOpenApiExceptio @Test(description = "Test for nullable array fields") public void testNullableArray() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/nullable_array_schema.yaml"), true); + "/nullable_array_schema.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -80,7 +80,7 @@ public void testNullableArray() throws IOException, BallerinaOpenApiException, F @Test(description = "Test for nullable array referenced schemas") public void testNullableArrayRefSchemas() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/nullable_ref_array.yaml"), true); + "/nullable_ref_array.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -97,7 +97,7 @@ public void testNullableArrayRefSchemas() throws IOException, BallerinaOpenApiEx @Test(description = "Test nullable for primitive referenced type") public void testPrimitiveReferencedTypes() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/nullable_string_type.yaml"), true); + "/nullable_string_type.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -115,7 +115,7 @@ public void testPrimitiveReferencedTypes() throws IOException, BallerinaOpenApiE @Test(description = "Test for referenced schema with no type given") public void testNullTypeReference() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/nullable_null_type.yaml"), true); + "/nullable_null_type.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -132,7 +132,7 @@ public void testNullTypeReference() throws IOException, BallerinaOpenApiExceptio @Test(description = "Test for nullable record fields") public void testNullableRecord() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/nullable_record_schema.yaml"), true); + "/nullable_record_schema.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -149,7 +149,7 @@ public void testNullableRecord() throws IOException, BallerinaOpenApiException, @Test(description = "Test for union type generation for nullable anyOf schema") public void testNullableUnionType() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/nullable_anyof_schema.yaml"), true); + "/nullable_anyof_schema.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -166,7 +166,7 @@ public void testNullableUnionType() throws IOException, BallerinaOpenApiExceptio @Test(description = "Test for union type generation for nullable anyOf schema with array schema") public void testNullableArrayUnionType() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/nullable_anyof_array_schema.yaml"), true); + "/nullable_anyof_array_schema.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -183,7 +183,7 @@ public void testNullableArrayUnionType() throws IOException, BallerinaOpenApiExc @Test(description = "Test for type generation for object schema with no properties") public void testNullableEmptyObjectSchema() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/null_empty_record.yaml"), true); + "/null_empty_record.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -200,7 +200,7 @@ public void testNullableEmptyObjectSchema() throws IOException, BallerinaOpenApi @Test(description = "Test for type generation for OpenAPI 3.1 schemas with `null` type") public void testNullTypePropertyGeneration() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/null_type_3_1.yaml"), true); + "/null_type_3_1.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/OneOfDataTypeTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/OneOfDataTypeTests.java index 372374a3b..76156ac51 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/OneOfDataTypeTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/OneOfDataTypeTests.java @@ -57,7 +57,7 @@ public class OneOfDataTypeTests { @Test(description = "Generate record for schema has oneOF") public void generateForSchemaHasOneOf() throws IOException, BallerinaOpenApiException, OASTypeGenException { Path definitionPath = RES_DIR.resolve("generators/schema/swagger/scenario12.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); Schema schema = openAPI.getComponents().getSchemas().get("Error"); ComposedSchema composedSchema = (ComposedSchema) schema; GeneratorMetaData.createInstance(openAPI, false); @@ -71,7 +71,7 @@ public void generateForSchemaHasOneOf() throws IOException, BallerinaOpenApiExce @Test(description = "Generate record for schema has object type with OneOf") public void generateForSchemaObjectType() throws IOException, BallerinaOpenApiException, OASTypeGenException { Path definitionPath = RES_DIR.resolve("generators/schema/swagger/scenario13.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); Schema schema = openAPI.getComponents().getSchemas().get("Error"); ComposedSchema composedSchema = (ComposedSchema) schema; GeneratorMetaData.createInstance(openAPI, false); @@ -84,7 +84,7 @@ public void generateForSchemaObjectType() throws IOException, BallerinaOpenApiEx @Test(description = "Generate union type when nullable is true") public void generateUnionTypeWhenNullableTrue() throws IOException, BallerinaOpenApiException, OASTypeGenException { Path definitionPath = RES_DIR.resolve("generators/schema/swagger/scenario12.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); Schema schema = openAPI.getComponents().getSchemas().get("Error"); GeneratorMetaData.createInstance(openAPI, true); TypeGenerator typeGenerator = TypeGeneratorUtils.getTypeGenerator(schema, "Error", null, false, @@ -96,7 +96,7 @@ public void generateUnionTypeWhenNullableTrue() throws IOException, BallerinaOpe @Test(description = "Tests full schema generations with oneOf type") public void generateOneOFTests() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("generators/schema/swagger/oneOf.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -113,7 +113,7 @@ public void generateOneOFTests() throws IOException, BallerinaOpenApiException, @Test(description = "Tests record generation for oneOf schemas with inline object schemas") public void oneOfWithInlineObject() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("generators/schema/swagger/oneOf_with_inline_schemas.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -130,7 +130,7 @@ public void oneOfWithInlineObject() throws IOException, BallerinaOpenApiExceptio @Test(description = "Tests record generation for nested OneOf schema inside AllOf schema") public void oneOfWithNestedAllOf() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("generators/schema/swagger/nested_oneOf_with_allOf.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/PrimitiveDataTypeTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/PrimitiveDataTypeTests.java index 66f75f0fc..92cc1e9dd 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/PrimitiveDataTypeTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/PrimitiveDataTypeTests.java @@ -57,7 +57,7 @@ public void setUp() { @Test(description = "Generate single record") public void generateScenario01() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/scenario01.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -74,7 +74,7 @@ public void generateScenario01() throws IOException, BallerinaOpenApiException, @Test(description = "Generate multiple record") public void generateScenario02() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/scenario02.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -91,7 +91,7 @@ public void generateScenario02() throws IOException, BallerinaOpenApiException, @Test(description = "Scenario for missing DataType") public void generateMissingDatatype() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/missDataType.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -110,7 +110,7 @@ public void generateMissingDatatype() throws IOException, BallerinaOpenApiExcept @Test(description = "When the component schema has primitive data type instead of object schema") public void generateSchemaForPrimitiveData() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/schema_with_primitive.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -128,7 +128,7 @@ public void generateSchemaForPrimitiveData() throws IOException, BallerinaOpenAp public void generateSchemaForInvalidAdditionalProperty() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/additional_properties_invalid_format.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -147,7 +147,7 @@ public void generateSchemaForInvalidAdditionalProperty() throws IOException, Bal public void generateSchemaForPrimitiveTypesWithUnsupportedFormats() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/invalid_formats.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/RecordDataTypeTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/RecordDataTypeTests.java index 014968509..ffcb0f074 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/RecordDataTypeTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/RecordDataTypeTests.java @@ -45,7 +45,7 @@ public class RecordDataTypeTests { @Test(description = "Generate record with record type filed record") public void generateRecordWithRecordField() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/scenario05.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -62,7 +62,7 @@ public void generateRecordWithRecordField() throws IOException, BallerinaOpenApi @Test(description = "Generate record with nested record type filed record") public void generateNestedRecord() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/scenario07.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -79,7 +79,7 @@ public void generateNestedRecord() throws IOException, BallerinaOpenApiException @Test(description = "Generate empty record when no properties are given") public void generateEmptyRecord() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/empty_record.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/RecordDefaultValueTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/RecordDefaultValueTests.java index fafd3529c..b7917a4d4 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/RecordDefaultValueTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/RecordDefaultValueTests.java @@ -45,7 +45,7 @@ public class RecordDefaultValueTests { @Test(description = "Test for default optional primitive fields in records") public void testDefaultPrimitive() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/default_optional_primitive_schema.yaml"), true); + "/default_optional_primitive_schema.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -62,7 +62,7 @@ public void testDefaultPrimitive() throws IOException, BallerinaOpenApiException @Test(description = "Test for default optional String fields in records") public void testDefaultString() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/default_optional_string_schema.yaml"), true); + "/default_optional_string_schema.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -79,7 +79,7 @@ public void testDefaultString() throws IOException, BallerinaOpenApiException, F @Test(description = "Test for default optional String fields with value double quote in records") public void testDefaultWithDoubleQuote() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/default_optional_schema_with_doublequote.yaml"), true); + "/default_optional_schema_with_doublequote.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -96,7 +96,7 @@ public void testDefaultWithDoubleQuote() throws IOException, BallerinaOpenApiExc @Test(description = "Test for default value for array record") public void testDefaultArray() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/default_optional_array_schema.yaml"), true); + "/default_optional_array_schema.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -113,7 +113,7 @@ public void testDefaultArray() throws IOException, BallerinaOpenApiException, Fo @Test(description = "Test for default value for required fields") public void testDefaultRequired() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/default_required_field_schema.yaml"), true); + "/default_required_field_schema.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -130,7 +130,7 @@ public void testDefaultRequired() throws IOException, BallerinaOpenApiException, @Test(description = "Test for default value without required fields") public void testDefaultWithoutRequired() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/default_non_required_field_schema.yaml"), true); + "/default_non_required_field_schema.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/ReferenceResolveTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/ReferenceResolveTests.java index dd9e21809..33f326517 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/ReferenceResolveTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/ReferenceResolveTests.java @@ -46,7 +46,7 @@ public class ReferenceResolveTests { public void testReferenceIncludeWithObjectType() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger/world_bank.yaml"), - true); + true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -63,7 +63,7 @@ public void testReferenceIncludeWithObjectType() throws IOException, BallerinaOp @Test(description = "Test for object data type when absent reference and properties fields") public void testWorldBank() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/object_without_fields_reference.yaml"), true); + "/object_without_fields_reference.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -79,7 +79,7 @@ public void testWorldBank() throws IOException, BallerinaOpenApiException, Forma @Test(description = "Test for type generation for query parameters with referenced schemas") public void testParameterSchemaReferences() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/schema_referenced_in_parameters.yaml"), true); + "/schema_referenced_in_parameters.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -97,7 +97,7 @@ public void testParameterSchemaReferences() throws IOException, BallerinaOpenApi public void testReferredTypesWithoutAdditionalFields() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/referred_inclusion.yaml"), true); + "/referred_inclusion.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -115,7 +115,7 @@ public void testReferredTypesWithoutAdditionalFields() throws IOException, public void testDocCommentResolvingForRefferedSchemas() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/resolve_reference_docs.yaml"), true); + "/resolve_reference_docs.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() @@ -132,7 +132,7 @@ public void testDocCommentResolvingForRefferedSchemas() throws IOException, @Test(description = "Test for type generation for request body with reference") public void testRequestBodyReferences() throws IOException, BallerinaOpenApiException, FormatterException { OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger" + - "/request_body_with_ref.yaml"), true); + "/request_body_with_ref.yaml"), true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/SwaggerFileParserTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/SwaggerFileParserTests.java index 1306f0fcd..0867304a9 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/SwaggerFileParserTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/SwaggerFileParserTests.java @@ -59,6 +59,7 @@ public void testInvalidFile() throws IOException, BallerinaOpenApiException { expectedExceptionsMessageRegExp = "OpenAPI definition has errors: \n" + "attribute components.schemas.Person.Person01 is not of type `schema`.*") public void testForUndocumentedReference() throws IOException, BallerinaOpenApiException { - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger/undocument_ref.yaml"), true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(RES_DIR.resolve("swagger/undocument_ref.yaml"), + true, false); } } diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/TypeFormatTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/TypeFormatTests.java index 19be2af3d..cfbec4c14 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/TypeFormatTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/schema/TypeFormatTests.java @@ -44,7 +44,7 @@ public class TypeFormatTests { @Test public void testStringFormats() throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RES_DIR.resolve("swagger/format/string_formats.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); ServiceGenerationHandler serviceGenerationHandler = new ServiceGenerationHandler(); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/service/QueryParameterTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/service/QueryParameterTests.java index 566ba003e..9a94ae7fe 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/service/QueryParameterTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/service/QueryParameterTests.java @@ -294,7 +294,7 @@ public void optionalQueryParameter() throws IOException, BallerinaOpenApiExcepti @Test(description = "16. Query parameter(s) having a referenced schema") public void generateParamsWithRefSchema() throws IOException, BallerinaOpenApiException { Path definitionPath = RES_DIR.resolve("swagger/parameters_with_ref_schema.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, false); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, false, false); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() .withOpenAPI(openAPI) .withFilters(filter) @@ -372,7 +372,7 @@ public void generateParamsWithObjectArrayRefSchema() throws IOException, Balleri @Test(description = "21. Query parameter(s) having a object schema") public void generateParamsWithObjectType() throws IOException, BallerinaOpenApiException { Path definitionPath = RES_DIR.resolve("swagger/query/object_query.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, false); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, false, false); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() .withOpenAPI(openAPI) .withFilters(filter) diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/service/RequestBodyTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/service/RequestBodyTests.java index 09e3022a4..0c8d2a2c7 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/service/RequestBodyTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/service/RequestBodyTests.java @@ -139,7 +139,7 @@ public void generateForMediaType() throws IOException, BallerinaOpenApiException public void oneOfScenarios() throws IOException, BallerinaOpenApiException { Path definitionPath = RES_DIR.resolve("swagger/requestBody/oneOf_request_body.yaml"); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() - .withOpenAPI(GeneratorUtils.normalizeOpenAPI(definitionPath, false)) + .withOpenAPI(GeneratorUtils.normalizeOpenAPI(definitionPath, false, false)) .withFilters(filter) .build(); TypeHandler.createInstance(oasServiceMetadata.getOpenAPI(), false); @@ -234,7 +234,7 @@ public void testForAnyOf() throws IOException, BallerinaOpenApiException { @Test(description = "RequestBody has object type with additional property") public void testForAdditionalProperty() throws IOException, BallerinaOpenApiException { Path definitionPath = RES_DIR.resolve("swagger/requestBody/additional_property.yaml"); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, false); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, false, false); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() .withOpenAPI(openAPI) .withFilters(filter) diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/service/ServiceDiagnosticTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/service/ServiceDiagnosticTests.java index 8f4f20b81..8ab4f23cc 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/service/ServiceDiagnosticTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/service/ServiceDiagnosticTests.java @@ -61,7 +61,7 @@ public class ServiceDiagnosticTests { public void checkDiagnosticIssues(String yamlFile) throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RESDIR.resolve(yamlFile); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() .withOpenAPI(openAPI) .withFilters(filter) @@ -83,7 +83,7 @@ public void checkDiagnosticIssues(String yamlFile) throws IOException, Ballerina public void checkDiagnosticIssuesInGenericServiceGen(String yamlFile) throws IOException, BallerinaOpenApiException, FormatterException { Path definitionPath = RESDIR.resolve(yamlFile); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); OASServiceMetadata oasServiceMetadata = new OASServiceMetadata.Builder() .withOpenAPI(openAPI) .withFilters(filter) diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/testcases/BallerinaTestGeneratorTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/testcases/BallerinaTestGeneratorTests.java index c6d6f3328..e47fb3d29 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/testcases/BallerinaTestGeneratorTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/testcases/BallerinaTestGeneratorTests.java @@ -72,7 +72,7 @@ public void generateclientWithTestSkel(String yamlFile) throws IOException, Form Path definitionPath = RES_DIR.resolve("sample_yamls/" + yamlFile); BallerinaCodeGenerator codeGenerator = new BallerinaCodeGenerator(); codeGenerator.setIncludeTestFiles(true); - OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true); + OpenAPI openAPI = GeneratorUtils.normalizeOpenAPI(definitionPath, true, false); TypeHandler.createInstance(openAPI, false); OASClientConfig.Builder clientMetaDataBuilder = new OASClientConfig.Builder(); OASClientConfig oasClientConfig = clientMetaDataBuilder diff --git a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorUtils.java b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorUtils.java index 27d91b813..d8de61e71 100644 --- a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorUtils.java +++ b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorUtils.java @@ -740,8 +740,8 @@ private static boolean isConstraintExists(Schema propertyValue) { * @throws IOException * @throws BallerinaOpenApiException */ - public static OpenAPI normalizeOpenAPI(Path openAPIPath, boolean validateOpIds, boolean isSanitized) throws IOException, - BallerinaOpenApiException { + public static OpenAPI normalizeOpenAPI(Path openAPIPath, boolean validateOpIds, boolean isSanitized) throws + IOException, BallerinaOpenApiException { OpenAPI openAPI = getOpenAPIFromOpenAPIV3Parser(openAPIPath); io.swagger.v3.oas.models.Paths openAPIPaths = openAPI.getPaths(); if (validateOpIds) { diff --git a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/OASSanitizer.java b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/OASSanitizer.java index 0e2849ef2..1028c260c 100644 --- a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/OASSanitizer.java +++ b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/OASSanitizer.java @@ -77,7 +77,9 @@ public OpenAPI sanitized() { for (Map.Entry schema : schemas.entrySet()) { String schemaName = schema.getKey(); String modifiedName = getValidNameForType(schemaName); - if (schema.getKey().contains(modifiedName) || modifiedSchemaNames.contains(modifiedName)) { + + if (!schemaName.equals(modifiedName) && (schema.getKey().contains(modifiedName) || + modifiedSchemaNames.contains(modifiedName))) { // todo: check the duplication, till providing the name this will give same name as it is. continue; } @@ -241,7 +243,8 @@ private static PathDetails updateParameterName(Map modifiedSchem return new PathDetails(pathItem, pathValue); } - private static String updateParameterNames(Map modifiedSchemas, String pathValue, Operation operation) { + private static String updateParameterNames(Map modifiedSchemas, String pathValue, + Operation operation) { List parameterNames = collectParameterNames(operation.getParameters()); List parameters = operation.getParameters(); if (parameters != null) { @@ -268,7 +271,7 @@ private static String updateParameters(Map modifiedSchemas, Stri continue; } String modifiedPathParam = modifiedPathParamResult.get(); - if (parameterNames.contains(modifiedPathParam)) { + if (!modifiedPathParam.equals(oasPathParamName) && parameterNames.contains(modifiedPathParam)) { // todo: handle by adding abc_1 or abc_2 continue; } @@ -286,7 +289,8 @@ private static String updateParameters(Map modifiedSchemas, Stri } /** - * Record for storing return data + * Record for storing return data. + * * @param pathItem * @param pathValue */ From 8a4498a6a0bbc5c8a2ff154f022542f9ae405ddd Mon Sep 17 00:00:00 2001 From: lnash94 Date: Fri, 2 Aug 2024 15:25:31 +0530 Subject: [PATCH 5/9] Resolve conflicts --- .../openapi/cmd/BallerinaCodeGenerator.java | 33 +++++++++++-------- .../io/ballerina/openapi/cmd/OpenApiCmd.java | 9 ++--- .../ballerina/openapi/CodeGeneratorTest.java | 24 +++++++++----- .../generators/common/OASSanitizerTests.java | 16 ++++----- .../expected_gen/petstore_client_swagger.bal | 4 +-- .../ballerina/additional_properties_true.bal | 20 +++++++++++ 6 files changed, 70 insertions(+), 36 deletions(-) diff --git a/openapi-cli/src/main/java/io/ballerina/openapi/cmd/BallerinaCodeGenerator.java b/openapi-cli/src/main/java/io/ballerina/openapi/cmd/BallerinaCodeGenerator.java index 5ffbd87f9..b1d746a81 100644 --- a/openapi-cli/src/main/java/io/ballerina/openapi/cmd/BallerinaCodeGenerator.java +++ b/openapi-cli/src/main/java/io/ballerina/openapi/cmd/BallerinaCodeGenerator.java @@ -100,7 +100,7 @@ public class BallerinaCodeGenerator { *

Method can be user for generating Ballerina mock services and clients

*/ public void generateClientAndService(String definitionPath, String serviceName, String outPath, Filter filter, - ClientServiceGeneratorOptions options, boolean isSanitized) + ClientServiceGeneratorOptions options) throws IOException, FormatterException, BallerinaOpenApiException, OASTypeGenException, ClientException { Path srcPath = Paths.get(outPath); @@ -111,7 +111,7 @@ public void generateClientAndService(String definitionPath, String serviceName, // Normalize OpenAPI definition, in the client generation we suppose to terminate code generation when the // absence of the operationId in operation. Therefor we enable client flag true as default code generation. // if resource is enabled, we avoid checking operationId. - OpenAPI openAPIDef = GeneratorUtils.normalizeOpenAPI(openAPIPath, !isResource, isSanitized); + OpenAPI openAPIDef = GeneratorUtils.normalizeOpenAPI(openAPIPath, !options.isResource, options.isSanitizedOas); checkOpenAPIVersion(openAPIDef); // Add typeHandler TypeHandler.createInstance(openAPIDef, options.nullable); @@ -222,10 +222,12 @@ public void generateClientAndService(String definitionPath, String serviceName, * service without data binding * @param statusCodeBinding Enable statusCodeBinding option * @param isMock Enable isMock option to generate mocks + * @param isSanitizedOas Enable isSanitizedOas option to modify the OAS to follow the Ballerina + * language best practices */ public record ClientServiceGeneratorOptions(boolean nullable, boolean isResource, boolean generateServiceType, boolean generateServiceContract, boolean generateWithoutDataBinding, - boolean statusCodeBinding, boolean isMock) { } + boolean statusCodeBinding, boolean isMock, boolean isSanitizedOas) { } public static Predicate distinctByKey(Function keyExtractor) { Map seen = new ConcurrentHashMap<>(); @@ -245,14 +247,13 @@ public static Predicate distinctByKey(Function keyExtractor * @throws IOException when file operations fail * @throws BallerinaOpenApiException when code generator fails */ - public void generateClient(String definitionPath, String outPath, Filter filter, ClientGeneratorOptions options, - boolean isSanitized) + public void generateClient(String definitionPath, String outPath, Filter filter, ClientGeneratorOptions options) throws IOException, FormatterException, BallerinaOpenApiException, OASTypeGenException { Path srcPath = Paths.get(outPath); Path implPath = getImplPath(srcPackage, srcPath); List genFiles = null; try { - genFiles = generateClientFiles(Paths.get(definitionPath), filter, options, isSanitized); + genFiles = generateClientFiles(Paths.get(definitionPath), filter, options); if (!genFiles.isEmpty()) { writeGeneratedSources(genFiles, srcPath, implPath, GEN_CLIENT); } @@ -274,11 +275,11 @@ public void generateClient(String definitionPath, String outPath, Filter filter, * @throws BallerinaOpenApiException when code generator fails */ public void generateService(String definitionPath, String serviceName, String outPath, Filter filter, - ServiceGeneratorOptions options, boolean isSanitized) + ServiceGeneratorOptions options) throws IOException, BallerinaOpenApiException, FormatterException { Path srcPath = Paths.get(outPath); Path implPath = getImplPath(srcPackage, srcPath); - List genFiles = generateBallerinaService(Paths.get(definitionPath), serviceName, filter, options, isSanitized); + List genFiles = generateBallerinaService(Paths.get(definitionPath), serviceName, filter, options); if (genFiles.isEmpty()) { return; } @@ -296,10 +297,12 @@ public void generateService(String definitionPath, String serviceName, String ou * @param generateServiceContract Enable to generate service contract * @param generateWithoutDataBinding Enable to generate service without data binding * @param singleFile Enable singleFile option to generate all content in a single file + * @param isSanitizedOas Enable isSanitizedOas option to modify the OAS to follow the Ballerina + * language best practices */ public record ServiceGeneratorOptions(boolean nullable, boolean generateServiceType, boolean generateServiceContract, boolean generateWithoutDataBinding, - boolean singleFile) { + boolean singleFile, boolean isSanitizedOas) { } private void writeGeneratedSources(List sources, Path srcPath, Path implPath, @@ -385,14 +388,14 @@ private void writeGeneratedSources(List sources, Path srcPath, Path * @return generated source files as a list of {@link GenSrcFile} * @throws IOException when code generation with specified templates fails */ - private List generateClientFiles(Path openAPI, Filter filter, ClientGeneratorOptions options, boolean isSanitized) + private List generateClientFiles(Path openAPI, Filter filter, ClientGeneratorOptions options) throws IOException, BallerinaOpenApiException, FormatterException, ClientException { if (srcPackage == null || srcPackage.isEmpty()) { srcPackage = DEFAULT_CLIENT_PKG; } List sourceFiles = new ArrayList<>(); // Normalize OpenAPI definition - OpenAPI openAPIDef = GeneratorUtils.normalizeOpenAPI(openAPI, !isResource, isSanitized); + OpenAPI openAPIDef = GeneratorUtils.normalizeOpenAPI(openAPI, !options.isResource, options.isSanitizedOas); checkOpenAPIVersion(openAPIDef); // Validate the service generation List complexPaths = GeneratorUtils.getComplexPaths(openAPIDef); @@ -470,9 +473,11 @@ private List generateClientFiles(Path openAPI, Filter filter, Client * @param statusCodeBinding Enable statusCodeBinding option * @param isMock Enable isMock option to generate mocks * @param singleFile Enable singleFile option to generate all content in a single file + * @param isSanitizedOas Enable isSanitizedOas option to modify the OAS to follow the Ballerina + * language best practices */ public record ClientGeneratorOptions(boolean nullable, boolean isResource, boolean statusCodeBinding, - boolean isMock, boolean singleFile) { } + boolean isMock, boolean singleFile, boolean isSanitizedOas) { } private void generateFilesForClient(SyntaxTree syntaxTree, List sourceFiles, BallerinaClientGenerator clientGenerator) throws FormatterException, @@ -525,12 +530,12 @@ private static BallerinaClientGenerator getBallerinaClientGenerator(OASClientCon public List generateBallerinaService(Path openAPI, String serviceName, Filter filter, - ServiceGeneratorOptions options, boolean isSanitized) + ServiceGeneratorOptions options) throws IOException, FormatterException, BallerinaOpenApiException { if (srcPackage == null || srcPackage.isEmpty()) { srcPackage = DEFAULT_MOCK_PKG; } - OpenAPI openAPIDef = GeneratorUtils.normalizeOpenAPI(openAPI, false, isSanitized); + OpenAPI openAPIDef = GeneratorUtils.normalizeOpenAPI(openAPI, false, options.isSanitizedOas); if (openAPIDef.getInfo() == null) { throw new BallerinaOpenApiException("Info section of the definition file cannot be empty/null: " + openAPI); diff --git a/openapi-cli/src/main/java/io/ballerina/openapi/cmd/OpenApiCmd.java b/openapi-cli/src/main/java/io/ballerina/openapi/cmd/OpenApiCmd.java index c6b42a88b..c9c50358d 100644 --- a/openapi-cli/src/main/java/io/ballerina/openapi/cmd/OpenApiCmd.java +++ b/openapi-cli/src/main/java/io/ballerina/openapi/cmd/OpenApiCmd.java @@ -454,9 +454,10 @@ private void generateServiceFile(BallerinaCodeGenerator generator, String servic exitError(this.exitWhenFinish); } else { ServiceGeneratorOptions options = new ServiceGeneratorOptions(baseCmd.nullable, generateServiceType, - generateServiceContract, generateWithoutDataBinding, baseCmd.singleFile); + generateServiceContract, generateWithoutDataBinding, baseCmd.singleFile, + baseCmd.isSanitized); generator.generateService(resourcePath.toString(), serviceName, targetOutputPath.toString(), filter, - options, baseCmd.isSanitized); + options); } } catch (IOException | FormatterException | BallerinaOpenApiException e) { outStream.println("Error occurred when generating service for openAPI contract at " + baseCmd.inputPath + @@ -477,9 +478,9 @@ private void generateBothFiles(BallerinaCodeGenerator generator, String fileName assert resourcePath != null; ClientServiceGeneratorOptions options = new ClientServiceGeneratorOptions(baseCmd.nullable, generateClientResourceFunctions, generateServiceType, generateServiceContract, - generateWithoutDataBinding, statusCodeBinding, baseCmd.mock); + generateWithoutDataBinding, statusCodeBinding, baseCmd.mock, baseCmd.isSanitized); generator.generateClientAndService(resourcePath.toString(), fileName, targetOutputPath.toString(), filter, - options, baseCmd.isSanitized); + options); } catch (BallerinaOpenApiException e) { outStream.println(e.getMessage()); exitError(this.exitWhenFinish); diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/CodeGeneratorTest.java b/openapi-cli/src/test/java/io/ballerina/openapi/CodeGeneratorTest.java index 0afec673a..c48446f61 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/CodeGeneratorTest.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/CodeGeneratorTest.java @@ -61,8 +61,10 @@ public class CodeGeneratorTest { List list1 = new ArrayList<>(); List list2 = new ArrayList<>(); Filter filter = new Filter(list1, list2); - ServiceGeneratorOptions defaultServiceOptions = new ServiceGeneratorOptions(false, false, false, false, false); - ClientGeneratorOptions defaultClientOptions = new ClientGeneratorOptions(false, false, false, false, false); + ServiceGeneratorOptions defaultServiceOptions = new ServiceGeneratorOptions(false, false, + false, false, false, false); + ClientGeneratorOptions defaultClientOptions = new ClientGeneratorOptions(false, false, + false, false, false, false); String replaceRegex = System.getProperty("os.name").toLowerCase() .contains("windows") ? "#.*[+*a\\r\\n]" : "#.*[+*a\\n]"; @@ -232,7 +234,8 @@ public void generateTypesWithNullableFields() { try { String expectedClientContent = getStringFromGivenBalFile(expectedDirPath, "nullable_types.bal"); generator.generateClient(definitionPath, resourcePath.toString(), filter, - new ClientGeneratorOptions(true, false, false, false, false)); + new ClientGeneratorOptions(true, false, false, false, + false, false)); if (Files.exists(resourcePath.resolve("types.bal"))) { String generatedClient = getStringFromGivenBalFile(resourcePath, "types.bal"); @@ -257,7 +260,8 @@ public void generateTypesWithNullableFieldsAndGlobalNullableTrue() { try { String expectedClientContent = getStringFromGivenBalFile(expectedDirPath, "nullable_false_types.bal"); generator.generateClient(definitionPath, resourcePath.toString(), filter, - new ClientGeneratorOptions(true, false, false, false, false)); + new ClientGeneratorOptions(true, false, false, false, + false, false)); if (Files.exists(resourcePath.resolve("types.bal"))) { String generatedClient = getStringFromGivenBalFile(resourcePath, "types.bal"); @@ -282,7 +286,8 @@ public void generateUtilsFile() { try { String expectedClientContent = getStringFromGivenBalFile(expectedDirPath, "utils.bal"); generator.generateClient(definitionPath, resourcePath.toString(), filter, - new ClientGeneratorOptions(true, false, false, false, false)); + new ClientGeneratorOptions(true, false, false, false, + false, false)); if (Files.exists(resourcePath.resolve("utils.bal"))) { String generatedClient = getStringFromGivenBalFile(resourcePath, "utils.bal"); @@ -308,7 +313,8 @@ public void generateConfigFile() { String expectedConfigContent = getStringFromGivenBalFile(expectedDirPath, "api_key_config.toml"); generator.setIncludeTestFiles(true); generator.generateClient(definitionPath, resourcePath.toString(), filter, - new ClientGeneratorOptions(true, false, false, false, false)); + new ClientGeneratorOptions(true, false, false, false, + false, false)); if (Files.exists(resourcePath.resolve("tests/Config.toml"))) { String generateConfigContent = getStringFromGivenBalFile(resourcePath, "tests/Config.toml"); @@ -448,7 +454,8 @@ public void generateClientForResourceWithCatchAllPath() { String expectedClientContent = getStringFromGivenBalFile( expectedDirPath, "petstore_catch_all_path_client.bal"); generator.generateClient(definitionPath, resourcePath.toString(), filter, - new ClientGeneratorOptions(false, true, false, false, false)); + new ClientGeneratorOptions(false, true, false, false, + false, false)); if (Files.exists(resourcePath.resolve("client.bal"))) { String generatedClient = getStringFromGivenBalFile(resourcePath, "client.bal"); generatedClient = (generatedClient.trim()).replaceAll("\\s+", ""); @@ -616,7 +623,8 @@ public void testGenericServiceGeneration() { try { String expectedServiceContent = getStringWithNewlineFromGivenBalFile(expectedDirPath, "generic_service_petstore_original.bal"); - ServiceGeneratorOptions options = new ServiceGeneratorOptions(false, false, false, true, false); + ServiceGeneratorOptions options = new ServiceGeneratorOptions(false, false, + false, true, false, false); generator.generateService(definitionPath, serviceName, resourcePath.toString(), filter, options); if (Files.exists(resourcePath.resolve("openapipetstore_service.bal"))) { String generatedService = getStringWithNewlineFromGivenBalFile(resourcePath, diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/common/OASSanitizerTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/common/OASSanitizerTests.java index f9ef8573e..ecb8385f1 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/common/OASSanitizerTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/common/OASSanitizerTests.java @@ -32,7 +32,7 @@ * This contains the OAS modification tests. */ public class OASSanitizerTests { - //TODO enable these tests separately, currently test by using connectors in manually. + //TODO: enable these tests separately, currently fix was tested by using connectors in manually. private static final Path RES_DIR = Paths.get("src/test/resources/generators/sanitizer").toAbsolutePath(); @Test(description = "Functionality tests for getBallerinaOpenApiType", enabled = false) public void testForRecordName() throws IOException, BallerinaOpenApiException { @@ -69,14 +69,14 @@ public void parameterNameHasBlank() { @Test public void recursiveRecordName() throws IOException, BallerinaOpenApiException { - Path definitionPath = RES_DIR.resolve("recursive_record.yaml"); - Path expectedPath = RES_DIR.resolve("modified_recursive_record.yaml"); - OpenAPI openAPI = GeneratorUtils.getOpenAPIFromOpenAPIV3Parser(definitionPath); - OASSanitizer oasSanitizer = new OASSanitizer(openAPI); - OpenAPI sanitized = oasSanitizer.sanitized(); +// Path definitionPath = RES_DIR.resolve("recursive_record.yaml"); +// Path expectedPath = RES_DIR.resolve("modified_recursive_record.yaml"); +// OpenAPI openAPI = GeneratorUtils.getOpenAPIFromOpenAPIV3Parser(definitionPath); +// OASSanitizer oasSanitizer = new OASSanitizer(openAPI); +// OpenAPI sanitized = oasSanitizer.sanitized(); // file comparison - OpenAPI expectedFileContent = GeneratorUtils.getOpenAPIFromOpenAPIV3Parser(expectedPath); - Assert.assertEquals(sanitized, expectedFileContent); +// OpenAPI expectedFileContent = GeneratorUtils.getOpenAPIFromOpenAPIV3Parser(expectedPath); +// Assert.assertEquals(sanitized, expectedFileContent); } // parameter in separate section diff --git a/openapi-cli/src/test/resources/expected_gen/petstore_client_swagger.bal b/openapi-cli/src/test/resources/expected_gen/petstore_client_swagger.bal index 8118527d1..94a4dd4bb 100644 --- a/openapi-cli/src/test/resources/expected_gen/petstore_client_swagger.bal +++ b/openapi-cli/src/test/resources/expected_gen/petstore_client_swagger.bal @@ -249,7 +249,7 @@ public isolated client class Client { # + petId - ID of pet that needs to be updated # + headers - Headers to be sent with the request # + return - Invalid input - remote isolated function updatePetWithForm(int petId, record {string name?; string status?;} payload, map headers = {}) returns http:Response|error { + remote isolated function updatePetWithForm(int petId, pet_petId_body payload, map headers = {}) returns http:Response|error { string resourcePath = string `/pet/${getEncodedUri(petId)}`; http:Request request = new; string encodedRequestBody = createFormURLEncodedRequestBody(payload); @@ -274,7 +274,7 @@ public isolated client class Client { # + petId - ID of pet to update # + headers - Headers to be sent with the request # + return - successful operation - remote isolated function uploadFile(int petId, record {string additionalMetadata?; record {byte[] fileContent; string fileName;} file?;} payload, map headers = {}) returns ApiResponse|error { + remote isolated function uploadFile(int petId, petId_uploadImage_body payload, map headers = {}) returns ApiResponse|error { string resourcePath = string `/pet/${getEncodedUri(petId)}/uploadImage`; http:Request request = new; mime:Entity[] bodyParts = check createBodyParts(payload); diff --git a/openapi-cli/src/test/resources/generators/schema/ballerina/additional_properties_true.bal b/openapi-cli/src/test/resources/generators/schema/ballerina/additional_properties_true.bal index bf1bfc7cb..467391a8e 100644 --- a/openapi-cli/src/test/resources/generators/schema/ballerina/additional_properties_true.bal +++ b/openapi-cli/src/test/resources/generators/schema/ballerina/additional_properties_true.bal @@ -46,6 +46,26 @@ public type User09 record {| record {}?...; |}; +public type store_inventory_body record { + User? user?; + User01? user1?; + User02? user2?; + User03? user3?; + User04? user4?; + User05? user5?; + User06? use6?; + User07? user7?; + User08? user8?; + User09? use9?; + User10? user10?; + User11? user11?; + User12? user12?; + User13? user13?; + User14? user14?; + User15? user15?; + User16? user16?; +}; + # Additional properties with object with additional fields type string public type User10 record {| string? name?; From 879a903301b63cedca1b90e05073df58da3c2901 Mon Sep 17 00:00:00 2001 From: lnash94 Date: Mon, 5 Aug 2024 09:45:28 +0530 Subject: [PATCH 6/9] Fix review suggestions --- .../openapi/bal/tool/OpenAPICodeGeneratorTool.java | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/OpenAPICodeGeneratorTool.java b/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/OpenAPICodeGeneratorTool.java index 1e735c112..ee2f4f545 100644 --- a/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/OpenAPICodeGeneratorTool.java +++ b/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/OpenAPICodeGeneratorTool.java @@ -123,13 +123,11 @@ public void execute(ToolContext toolContext) { String oasFilePath = toolContext.filePath(); Path packagePath = toolContext.currentPackage().project().sourceRoot(); boolean isSanitized = false; - if (toolContext.options() != null) { - Map options = toolContext.options(); - if (options.containsKey(IS_SANITIZED_OAS)) { - ToolContext.Option isUsingSanitizedOas = options.get(IS_SANITIZED_OAS); - String value = isUsingSanitizedOas.value().toString().trim(); - isSanitized = value.contains(TRUE); - } + Map options = toolContext.options(); + if (options != null && options.containsKey(IS_SANITIZED_OAS)) { + ToolContext.Option isUsingSanitizedOas = options.get(IS_SANITIZED_OAS); + String value = isUsingSanitizedOas.value().toString().trim(); + isSanitized = value.contains(TRUE); } Optional openAPI = getOpenAPIContract(packagePath, Path.of(oasFilePath), location, toolContext, isSanitized); @@ -138,7 +136,6 @@ public void execute(ToolContext toolContext) { } //Extract the details using the `tool config options` table in the `Ballerina.toml` file. //If the `tool options` table is not specified in the TOML file, the client will be generated by default. - Map options = toolContext.options(); if (options == null) { // Default generate client Filter filter = new Filter(); From 458443f0237e7efc2e74d3554f6f4eb27af48236 Mon Sep 17 00:00:00 2001 From: lnash94 Date: Tue, 6 Aug 2024 11:13:15 +0530 Subject: [PATCH 7/9] Fix code review suggestions --- module-ballerina-openapi/Ballerina.toml | 6 ++-- module-ballerina-openapi/CompilerPlugin.toml | 4 +-- .../ballerina/openapi/bal/tool/Constants.java | 5 +++- .../bal/tool/OpenAPICodeGeneratorTool.java | 4 ++- .../io/ballerina/openapi/cmd/OpenApiCmd.java | 4 +++ ...itizerTests.java => OASModifierTests.java} | 10 +++---- openapi-cli/src/test/resources/testng.xml | 2 +- .../generators/common/GeneratorConstants.java | 1 + .../generators/common/GeneratorUtils.java | 4 +-- .../{OASSanitizer.java => OASModifier.java} | 29 +++++++++++++------ 10 files changed, 45 insertions(+), 24 deletions(-) rename openapi-cli/src/test/java/io/ballerina/openapi/generators/common/{OASSanitizerTests.java => OASModifierTests.java} (90%) rename openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/{OASSanitizer.java => OASModifier.java} (97%) diff --git a/module-ballerina-openapi/Ballerina.toml b/module-ballerina-openapi/Ballerina.toml index 6cce2f370..49e3f3887 100644 --- a/module-ballerina-openapi/Ballerina.toml +++ b/module-ballerina-openapi/Ballerina.toml @@ -1,10 +1,10 @@ [package] org= "ballerina" name= "openapi" -version= "2.1.0" +version= "@toml.version@" [[platform.java17.dependency]] -path = "../openapi-validator/build/libs/openapi-validator-2.1.0-SNAPSHOT.jar" +path = "../openapi-validator/build/libs/openapi-validator-@project.version@.jar" groupId = "ballerina" artifactId = "openapi" -version = "2.1.0-SNAPSHOT" +version = "@project.version@" diff --git a/module-ballerina-openapi/CompilerPlugin.toml b/module-ballerina-openapi/CompilerPlugin.toml index 521ee69c8..c4c4205c0 100644 --- a/module-ballerina-openapi/CompilerPlugin.toml +++ b/module-ballerina-openapi/CompilerPlugin.toml @@ -3,7 +3,7 @@ id = "openapi-tools" class = "io.ballerina.openapi.validator.OpenAPIValidatorPlugin" [[dependency]] -path = "../openapi-validator/build/libs/openapi-validator-2.1.0-SNAPSHOT.jar" +path = "../openapi-validator/build/libs/openapi-validator-@project.version@.jar" groupId = "ballerina" artifactId = "openapi" -version = "2.1.0-SNAPSHOT" +version = "@project.version@." diff --git a/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/Constants.java b/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/Constants.java index 730187d08..d5622c8a8 100644 --- a/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/Constants.java +++ b/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/Constants.java @@ -71,7 +71,10 @@ public enum DiagnosticMessages { ERROR_WHILE_UPDATING_TOML("OAS_CLIENT_11", "error occurred when updating Ballerina.toml " + "file with the client native dependency.", DiagnosticSeverity.ERROR), OPENAPI_EXCEPTION("OAS_CLIENT_12", "exception occurred while reading the openapi contract: %s", - DiagnosticSeverity.ERROR); + DiagnosticSeverity.ERROR), + OPENAPI_MODIFICATION("OAS_CLIENT_13", "This `isUsingSanitizedOas` is an experimental feature." + + " This option enables code generation by " + + "modifying the given OAS to follow the Ballerina language best practices.", DiagnosticSeverity.WARNING); private final String code; private final String description; diff --git a/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/OpenAPICodeGeneratorTool.java b/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/OpenAPICodeGeneratorTool.java index ee2f4f545..b5c6a6af7 100644 --- a/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/OpenAPICodeGeneratorTool.java +++ b/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/OpenAPICodeGeneratorTool.java @@ -79,6 +79,7 @@ import static io.ballerina.openapi.bal.tool.Constants.CACHE_FILE; import static io.ballerina.openapi.bal.tool.Constants.CLIENT; import static io.ballerina.openapi.bal.tool.Constants.CLIENT_METHODS; +import static io.ballerina.openapi.bal.tool.Constants.DiagnosticMessages.OPENAPI_MODIFICATION; import static io.ballerina.openapi.bal.tool.Constants.IS_SANITIZED_OAS; import static io.ballerina.openapi.bal.tool.Constants.LICENSE; import static io.ballerina.openapi.bal.tool.Constants.MOCK; @@ -127,7 +128,8 @@ public void execute(ToolContext toolContext) { if (options != null && options.containsKey(IS_SANITIZED_OAS)) { ToolContext.Option isUsingSanitizedOas = options.get(IS_SANITIZED_OAS); String value = isUsingSanitizedOas.value().toString().trim(); - isSanitized = value.contains(TRUE); + isSanitized = Boolean.parseBoolean(value); + createDiagnostics(toolContext, OPENAPI_MODIFICATION, location); } Optional openAPI = getOpenAPIContract(packagePath, Path.of(oasFilePath), location, toolContext, isSanitized); diff --git a/openapi-cli/src/main/java/io/ballerina/openapi/cmd/OpenApiCmd.java b/openapi-cli/src/main/java/io/ballerina/openapi/cmd/OpenApiCmd.java index c9c50358d..07b814a2b 100644 --- a/openapi-cli/src/main/java/io/ballerina/openapi/cmd/OpenApiCmd.java +++ b/openapi-cli/src/main/java/io/ballerina/openapi/cmd/OpenApiCmd.java @@ -191,6 +191,10 @@ public void execute() { } Filter filter = new Filter(tag, operation); + if (!baseCmd.isSanitized) { + outStream.println("This is an experimental feature. This option enables code generation by " + + "modifying the given OAS to follow the Ballerina language best practices."); + } if (baseCmd.generateClientMethods != null && !baseCmd.generateClientMethods.isBlank() && (!baseCmd.generateClientMethods.equals(RESOURCE) && !baseCmd.generateClientMethods.equals(REMOTE))) { diff --git a/openapi-cli/src/test/java/io/ballerina/openapi/generators/common/OASSanitizerTests.java b/openapi-cli/src/test/java/io/ballerina/openapi/generators/common/OASModifierTests.java similarity index 90% rename from openapi-cli/src/test/java/io/ballerina/openapi/generators/common/OASSanitizerTests.java rename to openapi-cli/src/test/java/io/ballerina/openapi/generators/common/OASModifierTests.java index ecb8385f1..e1512ca7d 100644 --- a/openapi-cli/src/test/java/io/ballerina/openapi/generators/common/OASSanitizerTests.java +++ b/openapi-cli/src/test/java/io/ballerina/openapi/generators/common/OASModifierTests.java @@ -18,7 +18,7 @@ package io.ballerina.openapi.generators.common; import io.ballerina.openapi.core.generators.common.GeneratorUtils; -import io.ballerina.openapi.core.generators.common.OASSanitizer; +import io.ballerina.openapi.core.generators.common.OASModifier; import io.ballerina.openapi.core.generators.common.exception.BallerinaOpenApiException; import io.swagger.v3.oas.models.OpenAPI; import org.testng.Assert; @@ -31,7 +31,7 @@ /** * This contains the OAS modification tests. */ -public class OASSanitizerTests { +public class OASModifierTests { //TODO: enable these tests separately, currently fix was tested by using connectors in manually. private static final Path RES_DIR = Paths.get("src/test/resources/generators/sanitizer").toAbsolutePath(); @Test(description = "Functionality tests for getBallerinaOpenApiType", enabled = false) @@ -39,11 +39,11 @@ public void testForRecordName() throws IOException, BallerinaOpenApiException { Path definitionPath = RES_DIR.resolve("record.yaml"); Path expectedPath = RES_DIR.resolve("modified_record.yaml"); OpenAPI openAPI = GeneratorUtils.getOpenAPIFromOpenAPIV3Parser(definitionPath); - OASSanitizer oasSanitizer = new OASSanitizer(openAPI); - OpenAPI sanitized = oasSanitizer.sanitized(); + OASModifier oasModifier = new OASModifier(openAPI); + OpenAPI modifiedOAS = oasModifier.modifyWithBallerinaConventions(); // file comparison OpenAPI expectedFileContent = GeneratorUtils.getOpenAPIFromOpenAPIV3Parser(expectedPath); - Assert.assertEquals(sanitized, expectedFileContent); + Assert.assertEquals(modifiedOAS, expectedFileContent); } public void pathParameter() { diff --git a/openapi-cli/src/test/resources/testng.xml b/openapi-cli/src/test/resources/testng.xml index c80f73075..3589aa05b 100644 --- a/openapi-cli/src/test/resources/testng.xml +++ b/openapi-cli/src/test/resources/testng.xml @@ -114,7 +114,7 @@ under the License. - + diff --git a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorConstants.java b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorConstants.java index 9dde61235..4900c9b5a 100644 --- a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorConstants.java +++ b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorConstants.java @@ -89,6 +89,7 @@ public String getValue() { public static final String OAS_PATH_SEPARATOR = "/"; public static final String ESCAPE_PATTERN = "([\\[\\]\\\\?!<>@#&~'`*\\-=^+();:\\/{}\\s|.$])"; + public static final String ESCAPE_PATTERN_FOR_MODIFIER = "([\\[\\]\\\\?!<>@#&~'`*\\-=^+();:\\/{}\\s|.$]_)"; public static final String REGEX_WITHOUT_SPECIAL_CHARACTERS = "\\b[_a-zA-Z][_a-zA-Z0-9]*\\b"; public static final String REGEX_WORDS_STARTING_WITH_NUMBERS = "^[0-9].*"; public static final String REGEX_ONLY_NUMBERS_OR_NUMBERS_WITH_SPECIAL_CHARACTERS = "\\b[0-9([\\[\\]\\\\?!<>@#&~'`" + diff --git a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorUtils.java b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorUtils.java index 6d5a8ad96..239dbb442 100644 --- a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorUtils.java +++ b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/GeneratorUtils.java @@ -754,8 +754,8 @@ public static OpenAPI normalizeOpenAPI(Path openAPIPath, boolean validateOpIds, } validateRequestBody(openAPIPaths.entrySet()); if (isSanitized) { - OASSanitizer oasSanitizer = new OASSanitizer(openAPI); - return oasSanitizer.sanitized(); + OASModifier oasSanitizer = new OASModifier(openAPI); + return oasSanitizer.modifyWithBallerinaConventions(); } return openAPI; } diff --git a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/OASSanitizer.java b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/OASModifier.java similarity index 97% rename from openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/OASSanitizer.java rename to openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/OASModifier.java index 1028c260c..ecfef1993 100644 --- a/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/OASSanitizer.java +++ b/openapi-core/src/main/java/io/ballerina/openapi/core/generators/common/OASModifier.java @@ -50,11 +50,12 @@ /** * This class is to contain a util g=for name. */ -public class OASSanitizer { +//OASModifier +public class OASModifier { OpenAPI openapi; List diagnostics = new ArrayList<>(); - public OASSanitizer(OpenAPI openapi) { + public OASModifier(OpenAPI openapi) { this.openapi = openapi; } @@ -62,7 +63,8 @@ public List getDiagnostics() { return diagnostics; } - public OpenAPI sanitized() { + //modifyWithBallerinaConventions + public OpenAPI modifyWithBallerinaConventions() { Paths paths = openapi.getPaths(); Components components = openapi.getComponents(); List modifiedSchemaNames = new ArrayList<>(); @@ -92,9 +94,16 @@ public OpenAPI sanitized() { updateSchemaWithReference(schemaName, modifiedName, value); modifiedSchemas.put(modifiedName, value); } + + if (components.getSchemas() != null) { + components.setSchemas(modifiedSchemas); + } + if (paths == null || paths.isEmpty()) { + openapi.setComponents(components); return openapi; } + // 2. Update OAS reusable requestBody with reference details if (components.getRequestBodies() != null) { for (Map.Entry requestBody : components.getRequestBodies().entrySet()) { @@ -147,9 +156,7 @@ public OpenAPI sanitized() { updateOASOperations(schemaName, modifiedName, operations); } } - if (components.getSchemas() != null) { - components.setSchemas(modifiedSchemas); - } + if (components.getRequestBodies() != null) { components.setRequestBodies(modifiedRequestBodies); } @@ -411,7 +418,11 @@ private static void updateSchemaWithReference(String schemaName, String modified } composedSchema.setAnyOf(modifiedAnyOf); } - } + } + if (typeSchema.getAdditionalProperties() != null && + typeSchema.getAdditionalProperties() instanceof Schema addtionalSchema) { + updateSchemaWithReference(schemaName, modifiedName, addtionalSchema); + } } private static void updateRef(String schemaName, String modifiedName, Schema value) { @@ -515,7 +526,7 @@ public static String getValidNameForType(String identifier) { } // this - > !identifier.matches("\\b[a-zA-Z][a-zA-Z0-9]*\\b") && if (!identifier.matches("\\b[0-9]*\\b")) { - String[] split = identifier.split(GeneratorConstants.ESCAPE_PATTERN); + String[] split = identifier.split(GeneratorConstants.ESCAPE_PATTERN_FOR_MODIFIER); StringBuilder validName = new StringBuilder(); for (String part : split) { if (!part.isBlank()) { @@ -538,7 +549,7 @@ public static Optional getValidNameForParameter(String identifier) { return Optional.empty(); } if (!identifier.matches("\\b[0-9]*\\b")) { - String[] split = identifier.split(GeneratorConstants.ESCAPE_PATTERN); + String[] split = identifier.split(GeneratorConstants.ESCAPE_PATTERN_FOR_MODIFIER); StringBuilder validName = new StringBuilder(); for (String part : split) { if (!part.isBlank()) { From 197e7821f98b512526a3e7aadea1ed48052d6d21 Mon Sep 17 00:00:00 2001 From: lnash94 Date: Tue, 6 Aug 2024 12:12:24 +0530 Subject: [PATCH 8/9] Fix review suggestions --- .../bal/tool/OpenAPICodeGeneratorTool.java | 21 ++++++++++--------- .../io/ballerina/openapi/cmd/BaseCmd.java | 2 +- .../io/ballerina/openapi/cmd/OpenApiCmd.java | 8 +++---- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/OpenAPICodeGeneratorTool.java b/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/OpenAPICodeGeneratorTool.java index b5c6a6af7..ccaf8706e 100644 --- a/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/OpenAPICodeGeneratorTool.java +++ b/openapi-bal-task-plugin/src/main/java/io/ballerina/openapi/bal/tool/OpenAPICodeGeneratorTool.java @@ -123,16 +123,9 @@ public void execute(ToolContext toolContext) { // Handle the code generation String oasFilePath = toolContext.filePath(); Path packagePath = toolContext.currentPackage().project().sourceRoot(); - boolean isSanitized = false; Map options = toolContext.options(); - if (options != null && options.containsKey(IS_SANITIZED_OAS)) { - ToolContext.Option isUsingSanitizedOas = options.get(IS_SANITIZED_OAS); - String value = isUsingSanitizedOas.value().toString().trim(); - isSanitized = Boolean.parseBoolean(value); - createDiagnostics(toolContext, OPENAPI_MODIFICATION, location); - } - Optional openAPI = getOpenAPIContract(packagePath, Path.of(oasFilePath), location, toolContext, - isSanitized); + + Optional openAPI = getOpenAPIContract(packagePath, Path.of(oasFilePath), location, toolContext); if (openAPI.isEmpty()) { return; } @@ -223,8 +216,16 @@ private boolean canHandle(ToolContext toolContext) { * This method uses to read the openapi contract and return the {@code OpenAPI} object. */ private Optional getOpenAPIContract(Path ballerinaFilePath, Path openAPIPath, Location location, - ToolContext toolContext, boolean isSanitized) { + ToolContext toolContext) { Path relativePath; + boolean isSanitized = false; + Map options = toolContext.options(); + if (options != null && options.containsKey(IS_SANITIZED_OAS)) { + ToolContext.Option isUsingSanitizedOas = options.get(IS_SANITIZED_OAS); + String value = isUsingSanitizedOas.value().toString().trim(); + isSanitized = Boolean.parseBoolean(value); + createDiagnostics(toolContext, OPENAPI_MODIFICATION, location); + } try { Path inputPath = Paths.get(openAPIPath.toString()); if (inputPath.isAbsolute()) { diff --git a/openapi-cli/src/main/java/io/ballerina/openapi/cmd/BaseCmd.java b/openapi-cli/src/main/java/io/ballerina/openapi/cmd/BaseCmd.java index 6e728ed88..3c6058f85 100644 --- a/openapi-cli/src/main/java/io/ballerina/openapi/cmd/BaseCmd.java +++ b/openapi-cli/src/main/java/io/ballerina/openapi/cmd/BaseCmd.java @@ -66,5 +66,5 @@ public class BaseCmd { @CommandLine.Option(names = {"--use-sanitized-oas"}, hidden = true, description = "This is an experimental" + " feature. This option enables code generation by modifying the given OAS to follow the" + " Ballerina language best practices.") - public boolean isSanitized; + public boolean useSanitized; } diff --git a/openapi-cli/src/main/java/io/ballerina/openapi/cmd/OpenApiCmd.java b/openapi-cli/src/main/java/io/ballerina/openapi/cmd/OpenApiCmd.java index 07b814a2b..3aa5fb2ef 100644 --- a/openapi-cli/src/main/java/io/ballerina/openapi/cmd/OpenApiCmd.java +++ b/openapi-cli/src/main/java/io/ballerina/openapi/cmd/OpenApiCmd.java @@ -191,7 +191,7 @@ public void execute() { } Filter filter = new Filter(tag, operation); - if (!baseCmd.isSanitized) { + if (baseCmd.useSanitized) { outStream.println("This is an experimental feature. This option enables code generation by " + "modifying the given OAS to follow the Ballerina language best practices."); } @@ -427,7 +427,7 @@ private void generatesClientFile(BallerinaCodeGenerator generator, Path resource try { generator.generateClient(resourcePath.toString(), targetOutputPath.toString(), filter, new BallerinaCodeGenerator.ClientGeneratorOptions(baseCmd.nullable, resourceMode, - statusCodeBinding, baseCmd.mock, baseCmd.singleFile, baseCmd.isSanitized)); + statusCodeBinding, baseCmd.mock, baseCmd.singleFile, baseCmd.useSanitized)); } catch (IOException | FormatterException | BallerinaOpenApiException | OASTypeGenException e) { if (e.getLocalizedMessage() != null) { @@ -459,7 +459,7 @@ private void generateServiceFile(BallerinaCodeGenerator generator, String servic } else { ServiceGeneratorOptions options = new ServiceGeneratorOptions(baseCmd.nullable, generateServiceType, generateServiceContract, generateWithoutDataBinding, baseCmd.singleFile, - baseCmd.isSanitized); + baseCmd.useSanitized); generator.generateService(resourcePath.toString(), serviceName, targetOutputPath.toString(), filter, options); } @@ -482,7 +482,7 @@ private void generateBothFiles(BallerinaCodeGenerator generator, String fileName assert resourcePath != null; ClientServiceGeneratorOptions options = new ClientServiceGeneratorOptions(baseCmd.nullable, generateClientResourceFunctions, generateServiceType, generateServiceContract, - generateWithoutDataBinding, statusCodeBinding, baseCmd.mock, baseCmd.isSanitized); + generateWithoutDataBinding, statusCodeBinding, baseCmd.mock, baseCmd.useSanitized); generator.generateClientAndService(resourcePath.toString(), fileName, targetOutputPath.toString(), filter, options); } catch (BallerinaOpenApiException e) { From 94b9497c65c56264de69a3cb4b5591f9b4aefd39 Mon Sep 17 00:00:00 2001 From: lnash94 Date: Tue, 6 Aug 2024 16:36:40 +0530 Subject: [PATCH 9/9] Update lang version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 2a4b0711b..0877f5b49 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ clientNativeVersion=1.0.1-SNAPSHOT clientNativePublish=false #dependency -ballerinaLangVersion=2201.10.0-20240801-104200-87df251c +ballerinaLangVersion=2201.10.0-20240806-083400-aabac46a testngVersion=7.6.1 slf4jVersion=1.7.30 org.gradle.jvmargs=-Xmx4096M -Dfile.encoding=UTF-8