From 080dfba8043e2e30ddbca67b70c4d2c0cede69fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Enrique=20Garc=C3=ADa=20Maci=C3=B1eiras?= Date: Mon, 13 Nov 2023 10:28:47 +0100 Subject: [PATCH 1/6] 303 Fix support for referenced Request Bodies. --- multiapi-engine/pom.xml | 2 +- .../plugin/common/tools/ApiTool.java | 7 + .../exception/GeneratorTemplateException.java | 6 + .../plugin/openapi/OpenApiGenerator.java | 3 +- .../plugin/openapi/model/GlobalObject.java | 7 + .../plugin/openapi/utils/MapperPathUtil.java | 21 +- .../plugin/openapi/utils/OpenApiUtil.java | 3 +- .../openapi/OpenApiGeneratorFixtures.java | 47 ++ .../plugin/openapi/OpenApiGeneratorTest.java | 4 +- .../testSimpleBuild/api-rest.yaml | 595 ++++++++++++++++++ .../testSimpleBuild/assets/V1Api.java | 213 +++++++ .../assets/model/ActivatePolicyDTO.java | 22 + .../assets/model/AddressDTO.java | 38 ++ .../assets/model/CompanyDTO.java | 34 + .../assets/model/ContactDTO.java | 43 ++ .../assets/model/CreditLimitDTO.java | 26 + .../assets/model/DocumentDTO.java | 26 + .../assets/model/ErrorResponseDTO.java | 26 + .../assets/model/InsuredCreditObjectDTO.java | 30 + .../assets/model/PolicyActivationDTO.java | 50 ++ .../assets/model/PolicyClaimDTO.java | 42 ++ .../assets/model/PolicySettlementDTO.java | 26 + .../assets/model/QuoteRequestDTO.java | 42 ++ .../assets/model/QuoteResponseDTO.java | 42 ++ .../assets/model/QuoteUpdateResponseDTO.java | 34 + .../assets/model/UpdateQuoteDTO.java | 33 + scs-multiapi-gradle-plugin/build.gradle | 4 +- scs-multiapi-maven-plugin/pom.xml | 4 +- 28 files changed, 1417 insertions(+), 13 deletions(-) create mode 100644 multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/api-rest.yaml create mode 100644 multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/V1Api.java create mode 100644 multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/ActivatePolicyDTO.java create mode 100644 multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/AddressDTO.java create mode 100644 multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/CompanyDTO.java create mode 100644 multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/ContactDTO.java create mode 100644 multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/CreditLimitDTO.java create mode 100644 multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/DocumentDTO.java create mode 100644 multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/ErrorResponseDTO.java create mode 100644 multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/InsuredCreditObjectDTO.java create mode 100644 multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/PolicyActivationDTO.java create mode 100644 multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/PolicyClaimDTO.java create mode 100644 multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/PolicySettlementDTO.java create mode 100644 multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/QuoteRequestDTO.java create mode 100644 multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/QuoteResponseDTO.java create mode 100644 multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/QuoteUpdateResponseDTO.java create mode 100644 multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/UpdateQuoteDTO.java diff --git a/multiapi-engine/pom.xml b/multiapi-engine/pom.xml index d0e3f849..2183ed1e 100644 --- a/multiapi-engine/pom.xml +++ b/multiapi-engine/pom.xml @@ -4,7 +4,7 @@ com.sngular multiapi-engine - 5.0.2 + 5.0.3 jar diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ApiTool.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ApiTool.java index a6e0f472..564d1dd3 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ApiTool.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ApiTool.java @@ -12,6 +12,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Objects; + import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; @@ -43,6 +44,8 @@ public final class ApiTool { public static final String RESPONSES = "responses"; + public static final String REQUEST_BODIES = "requestBodies"; + private static final String PACKAGE_SEPARATOR_STR = "."; private ApiTool() { @@ -126,6 +129,10 @@ public static Map getResponseSchemas(final JsonNode openApi) { return getComponentSchemasByType(openApi, RESPONSES); } + public static Map getRequestBodySchemas(final JsonNode openApi) { + return getComponentSchemasByType(openApi, REQUEST_BODIES); + } + private static Map getComponentSchemasByType(final JsonNode openApi, final String schemaType) { final var schemasMap = new HashMap(); diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/exception/GeneratorTemplateException.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/exception/GeneratorTemplateException.java index 4f2772a0..aa99e30e 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/exception/GeneratorTemplateException.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/exception/GeneratorTemplateException.java @@ -4,7 +4,13 @@ public class GeneratorTemplateException extends RuntimeException { private static final String ERROR_MESSAGE = "A Template Factory error has been occurred: %s"; + private static final String ERROR_MESSAGE_FOR_FILE = "A Template Factory error has been occurred working with the file %s error description: %s"; + public GeneratorTemplateException(final String message, final Throwable cause) { super(String.format(ERROR_MESSAGE, message), cause); } + + public GeneratorTemplateException(final String message, final String filePath, final Throwable cause) { + super(String.format(ERROR_MESSAGE_FOR_FILE, filePath, message), cause); + } } diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/OpenApiGenerator.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/OpenApiGenerator.java index 3b194a73..e2e3a1f6 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/OpenApiGenerator.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/OpenApiGenerator.java @@ -18,6 +18,7 @@ import java.util.Objects; import java.util.Set; import java.util.regex.Pattern; + import com.fasterxml.jackson.databind.JsonNode; import com.sngular.api.generator.plugin.PluginConstants; import com.sngular.api.generator.plugin.common.tools.ApiTool; @@ -175,7 +176,7 @@ private GlobalObject createApiTemplate(final SpecFile specFile, final String fil try { templateFactory.fillTemplate(filePathToSave, specFile, javaFileName, pathObjects, authObject); } catch (IOException | TemplateException e) { - throw new GeneratorTemplateException("Error filling the template", e); + throw new GeneratorTemplateException("Error filling the template", specFile.getFilePath(), e); } if (Boolean.TRUE.equals(specFile.isCallMode())) { diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/GlobalObject.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/GlobalObject.java index a8d07d3a..a5109e00 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/GlobalObject.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/model/GlobalObject.java @@ -11,6 +11,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; + import com.fasterxml.jackson.databind.JsonNode; import lombok.AllArgsConstructor; import lombok.Builder; @@ -37,6 +38,8 @@ public class GlobalObject { private Map responseMap; + private Map requestBodyMap; + public Optional getSchemaNode(final String schemaName) { return Optional.ofNullable(schemaMap.get(schemaName)); } @@ -49,6 +52,10 @@ public Optional getParameterNode(final String schemaName) { return Optional.ofNullable(parameterMap.get(schemaName)); } + public Optional getRequestBodyNode(final String schemaName) { + return Optional.ofNullable(requestBodyMap.get(schemaName)); + } + public static class GlobalObjectBuilder { private final List serverUrl = new ArrayList<>(); diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/MapperPathUtil.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/MapperPathUtil.java index 2ea7c71f..7a7a8cbe 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/MapperPathUtil.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/MapperPathUtil.java @@ -16,6 +16,7 @@ import java.util.Map.Entry; import java.util.Objects; import java.util.function.BiConsumer; + import com.fasterxml.jackson.databind.JsonNode; import com.sngular.api.generator.plugin.common.tools.ApiTool; import com.sngular.api.generator.plugin.openapi.exception.DuplicatedOperationException; @@ -59,6 +60,7 @@ public static GlobalObject mapOpenApiObjectToOurModels(final JsonNode openAPI, f globalObject.schemaMap(ApiTool.getComponentSchemas(openAPI)); globalObject.parameterMap(ApiTool.getParameterSchemas(openAPI)); globalObject.responseMap(ApiTool.getResponseSchemas(openAPI)); + globalObject.requestBodyMap(ApiTool.getRequestBodySchemas(openAPI)); } else { globalObject.schemaMap(new HashMap<>()); } @@ -206,11 +208,20 @@ private static List mapRequestObject( final String operationIdWithCap = operationId.substring(0, 1).toUpperCase() + operationId.substring(1); if (ApiTool.hasNode(operation, REQUEST_BODY)) { final var requestBody = ApiTool.getNode(operation, REQUEST_BODY); - requestObjects.add(RequestObject.builder() - .required(ApiTool.hasNode(requestBody, REQUIRED)) - .contentObjects(mapContentObject(specFile, ApiTool.getNode(requestBody, CONTENT), - "InlineObject" + operationIdWithCap, globalObject, baseDir)) - .build()); + if (!ApiTool.hasRef(requestBody)) { + requestObjects.add(RequestObject.builder() + .required(ApiTool.hasNode(requestBody, REQUIRED)) + .contentObjects(mapContentObject(specFile, ApiTool.getNode(requestBody, CONTENT), + "InlineObject" + operationIdWithCap, globalObject, baseDir)) + .build()); + } else { + final var requestBodyNode = globalObject.getRequestBodyNode(MapperUtil.getRefSchemaName(requestBody)).orElseThrow(); + requestObjects.add(RequestObject.builder() + .required(ApiTool.hasNode(requestBody, REQUIRED)) + .contentObjects(mapContentObject(specFile, ApiTool.getNode(requestBodyNode, CONTENT), + operationIdWithCap, globalObject, baseDir)) + .build()); + } } return requestObjects; } diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/OpenApiUtil.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/OpenApiUtil.java index 494d3c59..e39b779b 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/OpenApiUtil.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/OpenApiUtil.java @@ -21,6 +21,7 @@ import java.util.Map.Entry; import java.util.Objects; import java.util.Set; + import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.JsonNodeFactory; @@ -156,7 +157,7 @@ private static void processRequestBody(final HashMap basicJson if (ApiTool.hasNode(operation, "requestBody") && !operation.at("/requestBody/content").isMissingNode()) { final var content = operation.at("/requestBody/content"); final var schema = content.findValue("schema"); - if (ApiTool.hasRef(schema)) { + if (!ApiTool.hasRef(schema)) { basicJsonNodeMap.put("InlineObject" + StringUtils.capitalize(getOperationId(operation)), schema); } else if (ApiTool.hasItems(schema)) { basicJsonNodeMap.put("InlineObject" + StringUtils.capitalize(ApiTool.getNodeAsString(operation, "operationId")), ApiTool.getItems(schema)); diff --git a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorFixtures.java b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorFixtures.java index d2ec035d..eec77782 100644 --- a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorFixtures.java +++ b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorFixtures.java @@ -331,6 +331,18 @@ public final class OpenApiGeneratorFixtures { .build() ); + static final List TEST_SIMPLE_BUILD = List.of( + SpecFile + .builder() + .filePath("openapigenerator/testSimpleBuild/api-rest.yaml") + .apiPackage("com.sngular.multifileplugin.testsimplebuild") + .modelPackage("com.sngular.multifileplugin.testsimplebuild.model") + .clientPackage("com.sngular.multifileplugin.testsimplebuild.client") + .modelNameSuffix("DTO") + .useLombokModelAnnotation(true) + .build() + ); + final static List TEST_VALIDATION_ANNOTATIONS = List.of( SpecFile .builder() @@ -1132,6 +1144,41 @@ static Function validateRestrictionsSchema() { return (path) -> commonTest(path, expectedTestApiFile, expectedTestApiModelFiles, DEFAULT_TARGET_API, DEFAULT_MODEL_API, expectedExceptionFiles, DEFAULT_EXCEPTION_API); } +static Function validateSimpleBuild() { + + final String DEFAULT_TARGET_API = "generated/com/sngular/multifileplugin/testsimplebuild"; + + final String DEFAULT_MODEL_API = "generated/com/sngular/multifileplugin/testsimplebuild/model"; + + final String COMMON_PATH = "openapigenerator/testsimplebuild/"; + + final String ASSETS_PATH = COMMON_PATH + "assets/"; + + final List expectedTestApiFile = List.of( + ASSETS_PATH + "V1Api.java" + ); + + final List expectedTestApiModelFiles = List.of( + ASSETS_PATH + "model/ActivatePolicyDTO.java", + ASSETS_PATH + "model/AddressDTO.java", + ASSETS_PATH + "model/CompanyDTO.java", + ASSETS_PATH + "model/ContactDTO.java", + ASSETS_PATH + "model/CreditLimitDTO.java", + ASSETS_PATH + "model/DocumentDTO.java", + ASSETS_PATH + "model/ErrorResponseDTO.java", + ASSETS_PATH + "model/InsuredCreditObjectDTO.java", + ASSETS_PATH + "model/PolicyActivationDTO.java", + ASSETS_PATH + "model/PolicyClaimDTO.java", + ASSETS_PATH + "model/PolicySettlementDTO.java", + ASSETS_PATH + "model/QuoteRequestDTO.java", + ASSETS_PATH + "model/QuoteResponseDTO.java", + ASSETS_PATH + "model/QuoteUpdateResponseDTO.java", + ASSETS_PATH + "model/UpdateQuoteDTO.java" + ); + + return (path) -> commonTest(path, expectedTestApiFile, expectedTestApiModelFiles, DEFAULT_TARGET_API, DEFAULT_MODEL_API, Collections.emptyList(), null); + } + static Function validateValidationAnnotations(int springBootVersion) { final String DEFAULT_TARGET_API = "generated/com/sngular/multifileplugin/testapi"; diff --git a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorTest.java b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorTest.java index 9d454250..c4bf53c5 100644 --- a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorTest.java +++ b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorTest.java @@ -115,7 +115,9 @@ static Stream fileSpecToProcess() { Arguments.of("testApiWithNoComponents", OpenApiGeneratorFixtures.TEST_API_WITH_NO_COMPONENTS, OpenApiGeneratorFixtures.validateApiWithNoComponents()), Arguments.of("testRestrictionSchema", OpenApiGeneratorFixtures.TEST_RESTRICTION_SCHEMA, - OpenApiGeneratorFixtures.validateRestrictionsSchema()) + OpenApiGeneratorFixtures.validateRestrictionsSchema()), + Arguments.of("testSimpleBuild", OpenApiGeneratorFixtures.TEST_SIMPLE_BUILD, + OpenApiGeneratorFixtures.validateSimpleBuild()) ); } diff --git a/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/api-rest.yaml b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/api-rest.yaml new file mode 100644 index 00000000..deece974 --- /dev/null +++ b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/api-rest.yaml @@ -0,0 +1,595 @@ +openapi: 3.0.0 +info: + title: Operation Authorization Service + description: | + This service provides the set of operations needed to make a decision on whether a certain operation should be financed. + It will rely on a number of providers, but initially we will only be using Allianz Trade (AZT). + contact: + name: BNPL Support Team + email: payments.m3a.1@gmail.com + version: 0.1.0 +servers: + - url: http://localhost:8087 + description: Localhost +tags: + - name: Company + description: Gather info about a company + - name: Insurance + description: Run insurance operations +paths: + /v1/company/{companyId}/info: + get: + tags: + - Company + summary: Retrieve info from a company + description: | + Gather info about a company of a certain country, provided its VAT code, countryCode and database identifier. + operationId: getCompanyInfo + parameters: + - name: countryCode + in: query + description: Country code according to ISO 3166 + required: true + schema: + type: string + - name: vatCode + in: query + description: The unique VAT code that identifies the company + required: true + schema: + type: string + - name: companyId + in: path + description: The company database identifier + required: true + schema: + type: integer + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Company' + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + /v1/company/{companyId}/creditLimit: + post: + tags: + - Company + summary: Compute the credit limits for a company + description: Gather info about the credit limits that certain providers allow for a specific company. + operationId: getCompanyCreditLimit + parameters: + - name: companyId + in: path + description: Company database identifier + required: true + schema: + type: integer + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/CreditLimit' + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + /v1/insurance: + post: + tags: + - Insurance + summary: Request a quote to insure an invoice + description: Request a quote for the insurance of an invoice from a number of insurance providers + operationId: obtainInsuranceQuote + requestBody: + $ref: '#/components/requestBodies/QuoteRequest' + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/QuoteResponse' + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + /v1/insurance/update/{quoteId}: + put: + tags: + - Insurance + summary: Update the invoice number and invoice date for a certain quote + description: + Normally, at the time of sale, there is not an invoice number as the invoice has not yet been issued. + Therefore, we need to update the invoice number and date for a certain quote before activating it. + operationId: updateInvoiceNumberAndDateForInsurance + parameters: + - name: quoteId + in: path + required: true + schema: + type: integer + requestBody: + content: + application/json: + schema: + $ref: '#/components/requestBodies/UpdateQuote' + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/QuoteUpdateResponse' + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + /v1/insurance/activate/{quoteId}: + post: + tags: + - Insurance + summary: Activate a quote to insure an invoice + description: We activate a policy that has already the correct invoice number and date, for an + accepted sale (for which we have the dispatch info and invoice on file) + operationId: activate + parameters: + - name: quoteId + in: path + required: true + schema: + type: integer + requestBody: + content: + application/json: + schema: + $ref: '#/components/requestBodies/ActivatePolicy' + responses: + '200': + description: Successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/PolicyActivation' + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + /v1/insurance/settle/{policyId}: + post: + tags: + - Insurance + summary: Settle a policy that was previously activated + description: Once the debtor has paid for the insurance, we settle it using this endpoint. + operationId: settle + requestBody: + content: + application/json: + schema: + $ref: '#/components/requestBodies/PolicySettlement' + parameters: + - name: policyIdInProvider + in: path + description: ID of the policy for the specific insurance provider + required: true + schema: + type: string + example: 1 + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/PolicySettlement' + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + /v1/insurance/claim/{policyId}: + post: + tags: + - Insurance + summary: Claim a policy that was unpaid + description: If the policy was unpaid, we make a claim to the insurance company. + operationId: claim + parameters: + - name: operationId + in: query + description: ID of the operation in our own records, for reconciliation purposes + required: true + style: form + explode: true + schema: + type: integer + example: 12345678 + - name: provider + in: query + description: Name of the insurance provider + required: false + style: form + explode: true + schema: + type: string + example: AZT + - name: policyId + in: path + description: ID of the policy for the specific insurance provider + required: true + schema: + type: string + example: 1 + - name: claimDate + in: query + description: Date that we start the claim + required: true + style: form + explode: true + schema: + type: string + format: datetime + example: 2023-11-06T14:00:00Z + requestBody: + $ref: '#/components/requestBodies/ClaimRequest' + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/PolicySettlement' + '400': + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Not found + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' +components: + schemas: + ErrorResponse: + type: object + properties: + status: + type: string + description: Error status + message: + type: string + description: Error message + Company: + type: object + properties: + name: + type: string + example: Sngular + isActive: + type: boolean + example: true + isInsurable: + type: boolean + example: true + fiscalAddress: + $ref: '#/components/schemas/Address' + Address: + type: object + properties: + street: + type: string + example: Calle Sor Joaquina + number: + type: integer + example: 6 + postcode: + type: integer + example: 15002 + city: + type: string + example: A Coruña + country: + type: string + example: ES + Contact: + type: object + required: + - lastName + - officePhoneNumber + - phoneNumber + - email + properties: + firstName: + type: string + example: John + lastName: + type: integer + officePhoneNumber: + type: integer + example: 34600111222 + phoneNumber: + type: integer + example: 34600111222 + email: + type: string + example: john@doe.com + CreditLimit: + type: object + properties: + isFundable: + type: boolean + example: true + insuredCreditLimit: + $ref: '#/components/schemas/InsuredCreditObject' + InsuredCreditObject: + type: object + properties: + providerName: + type: string + example: AZT + creditLimitInCents: + type: integer + example: 1000000 + creditAvailableInCents: + type: integer + example: 800000 + QuoteRequest: + type: object + properties: + totalAmountInCents: + type: integer + format: int64 + example: 10000 + currency: + type: string + example: EUR + saleDate: + type: string + description: + Is the date the sale is made. + Initially, we assume the date of invoice will be the date of sale. + format: datetime + example: 2023-10-31T14:00:00Z + paymentDueDate: + type: string + description: + Is the date the invoice must be paid. As of now, 60 days from saleDate. + format: datetime + example: 2023-12-30T14:00:00Z + debtorId: + type: integer + example: 1 + merchantId: + type: integer + example: 2 + QuoteResponse: + type: object + properties: + isInsurable: + type: boolean + example: true + quoteId: + type: string + example: 1 + description: Quote adapter database identifier + estimatedCostInCents: + type: integer + example: 242 + currency: + type: string + example: EUR + activateBeforeDate: + type: string + format: datetime + example: 2023-11-06T14:00:00Z + claimBeforeDate: + type: string + format: datetime + example: 2024-03-10T14:00:00Z + QuoteUpdateResponse: + type: object + properties: + isInsurable: + type: boolean + example: true + estimatedCostInCents: + type: integer + example: 242 + activateBeforeDate: + type: string + format: datetime + example: 2023-11-06T14:00:00Z + claimBeforeDate: + type: string + format: datetime + example: 2024-03-10T14:00:00Z + PolicyActivation: + type: object + properties: + isActive: + type: boolean + example: true + insuranceProvider: + type: string + example: AZT + policyId: + type: string + example: 1 + description: Policy identifier in adapter database + netCostInCents: + type: integer + example: 200 + totalCostInCents: + type: integer + example: 242 + currency: + type: string + example: EUR + claimBeforeDate: + type: string + format: datetime + example: 2024-03-10T14:00:00Z + coveredAmountInCents: + type: integer + example: 10000 + PolicySettlement: + type: object + properties: + provider: + type: string + example: AZT + settlementDate: + type: string + format: datetime + example: 2023-11-06T14:00:00Z + PolicyClaim: + type: object + properties: + claimKind: + type: string + example: Dispute + claimDocument: + $ref: '#/components/schemas/Document' + invoiceDocument: + $ref: '#/components/schemas/Document' + proofOfDeliveryDocument: + $ref: '#/components/schemas/Document' + debtorContactDetails: + $ref: '#/components/schemas/Contact' + merchantContactDetails: + $ref: '#/components/schemas/Contact' + Document: + type: object + properties: + document: + type: string + format: binary + example: invoice01234.pdf + description: + type: string + example: Invoice for the sale 01234 + UpdateQuote: + type: object + required: + - invoiceNumber + - invoiceDate + properties: + provider: + type: string + example: AZT + invoiceNumber: + type: string + description: Invoice number + example: INV/2023/00234 + invoiceDate: + type: string + format: datetime + example: 2024-03-10T14:00:00Z + ActivatePolicy: + type: object + properties: + provider: + type: string + example: AZT + requestBodies: + PolicySettlement: + description: Data needed to settle a policy + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/PolicySettlement' + ActivatePolicy: + description: Data needed to activate a policy + required: false + content: + application/json: + schema: + $ref: '#/components/schemas/ActivatePolicy' + UpdateQuote: + description: Data needed to update the invoice number and date for a certain quote + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateQuote' + QuoteRequest: + description: Data needed to obtain a quote + content: + application/json: + schema: + $ref: '#/components/schemas/QuoteRequest' + required: true + ClaimRequest: + description: Data needed to make a claim + content: + application/json: + schema: + $ref: '#/components/schemas/PolicyClaim' + required: true diff --git a/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/V1Api.java b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/V1Api.java new file mode 100644 index 00000000..f554c83a --- /dev/null +++ b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/V1Api.java @@ -0,0 +1,213 @@ +package com.sngular.multifileplugin.testsimplebuild; + +import java.util.Optional; +import java.util.List; +import java.util.Map; +import javax.validation.Valid; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import org.springframework.http.MediaType; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.request.NativeWebRequest; + +import com.sngular.multifileplugin.testsimplebuild.model.CompanyDTO; +import com.sngular.multifileplugin.testsimplebuild.model.ErrorResponseDTO; +import com.sngular.multifileplugin.testsimplebuild.model.CreditLimitDTO; +import com.sngular.multifileplugin.testsimplebuild.model.QuoteRequestDTO; +import com.sngular.multifileplugin.testsimplebuild.model.QuoteResponseDTO; +import com.sngular.multifileplugin.testsimplebuild.model.UpdateQuoteDTO; +import com.sngular.multifileplugin.testsimplebuild.model.QuoteUpdateResponseDTO; +import com.sngular.multifileplugin.testsimplebuild.model.ActivatePolicyDTO; +import com.sngular.multifileplugin.testsimplebuild.model.PolicyActivationDTO; +import com.sngular.multifileplugin.testsimplebuild.model.PolicySettlementDTO; +import com.sngular.multifileplugin.testsimplebuild.model.PolicyClaimDTO; + +public interface V1Api { + + /** + * GET /v1/company/{companyId}/info: Retrieve info from a company + * @param countryCode Country code according to ISO 3166 true @param vatCode The unique VAT code that identifies the company true @param companyId The company database identifier true + * @return Successful operation; (status code 200) Bad request; (status code 400) Not found; (status code 404) + */ + + @Operation( + operationId = "getCompanyInfo", + summary = "Retrieve info from a company", + tags = {"Company"}, + responses = { + @ApiResponse(responseCode = "200", description = "Successful operation", content = @Content(mediaType = "application/json", schema = @Schema(implementation = List.class))), + @ApiResponse(responseCode = "400", description = "Bad request", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponseDTO.class))), + @ApiResponse(responseCode = "404", description = "Not found", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponseDTO.class))) + } + ) + @RequestMapping( + method = RequestMethod.GET, + value = "/v1/company/{companyId}/info", + produces = {"application/json"} + ) + + default ResponseEntity> getCompanyInfo(@Parameter(name = "countryCode", description = "Country code according to ISO 3166", required = true, schema = @Schema(description = "")) @RequestParam(required = true) String countryCode , @Parameter(name = "vatCode", description = "The unique VAT code that identifies the company", required = true, schema = @Schema(description = "")) @RequestParam(required = true) String vatCode , @Parameter(name = "companyId", description = "The company database identifier", required = true, schema = @Schema(description = "")) @PathVariable("companyId") Integer companyId) { + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } + /** + * POST /v1/company/{companyId}/creditLimit: Compute the credit limits for a company + * @param companyId Company database identifier true + * @return Successful operation; (status code 200) Bad request; (status code 400) Not found; (status code 404) + */ + + @Operation( + operationId = "getCompanyCreditLimit", + summary = "Compute the credit limits for a company", + tags = {"Company"}, + responses = { + @ApiResponse(responseCode = "200", description = "Successful operation", content = @Content(mediaType = "application/json", schema = @Schema(implementation = List.class))), + @ApiResponse(responseCode = "400", description = "Bad request", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponseDTO.class))), + @ApiResponse(responseCode = "404", description = "Not found", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponseDTO.class))) + } + ) + @RequestMapping( + method = RequestMethod.POST, + value = "/v1/company/{companyId}/creditLimit", + produces = {"application/json"} + ) + + default ResponseEntity> getCompanyCreditLimit(@Parameter(name = "companyId", description = "Company database identifier", required = true, schema = @Schema(description = "")) @PathVariable("companyId") Integer companyId) { + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } + /** + * POST /v1/insurance: Request a quote to insure an invoice + * @param quoteRequestDTO + * @return successful operation; (status code 200) Bad request; (status code 400) Not found; (status code 404) + */ + + @Operation( + operationId = "obtainInsuranceQuote", + summary = "Request a quote to insure an invoice", + tags = {"Insurance"}, + responses = { + @ApiResponse(responseCode = "200", description = "successful operation", content = @Content(mediaType = "application/json", schema = @Schema(implementation = List.class))), + @ApiResponse(responseCode = "400", description = "Bad request", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponseDTO.class))), + @ApiResponse(responseCode = "404", description = "Not found", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponseDTO.class))) + } + ) + @RequestMapping( + method = RequestMethod.POST, + value = "/v1/insurance", + produces = {"application/json"} + ) + + default ResponseEntity> obtainInsuranceQuote(@Parameter(name = "quoteRequestDTO", description = "", required = false, schema = @Schema(description = "")) @Valid @RequestBody QuoteRequestDTO quoteRequestDTO) { + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } + /** + * PUT /v1/insurance/update/{quoteId}: Update the invoice number and invoice date for a certain quote + * @param quoteId true + * @param updateQuoteDTO + * @return Successful operation; (status code 200) Bad request; (status code 400) Not found; (status code 404) + */ + + @Operation( + operationId = "updateInvoiceNumberAndDateForInsurance", + summary = "Update the invoice number and invoice date for a certain quote", + tags = {"Insurance"}, + responses = { + @ApiResponse(responseCode = "200", description = "Successful operation", content = @Content(mediaType = "application/json", schema = @Schema(implementation = QuoteUpdateResponseDTO.class))), + @ApiResponse(responseCode = "400", description = "Bad request", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponseDTO.class))), + @ApiResponse(responseCode = "404", description = "Not found", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponseDTO.class))) + } + ) + @RequestMapping( + method = RequestMethod.PUT, + value = "/v1/insurance/update/{quoteId}", + produces = {"application/json"} + ) + + default ResponseEntity updateInvoiceNumberAndDateForInsurance(@Parameter(name = "quoteId", required = true, schema = @Schema(description = "")) @PathVariable("quoteId") Integer quoteId , @Parameter(name = "updateQuoteDTO", description = "", required = false, schema = @Schema(description = "")) @Valid @RequestBody UpdateQuoteDTO updateQuoteDTO) { + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } + /** + * POST /v1/insurance/activate/{quoteId}: Activate a quote to insure an invoice + * @param quoteId true + * @param activatePolicyDTO + * @return Successful operation; (status code 200) Bad request; (status code 400) Not found; (status code 404) + */ + + @Operation( + operationId = "activate", + summary = "Activate a quote to insure an invoice", + tags = {"Insurance"}, + responses = { + @ApiResponse(responseCode = "200", description = "Successful operation", content = @Content(mediaType = "application/json", schema = @Schema(implementation = PolicyActivationDTO.class))), + @ApiResponse(responseCode = "400", description = "Bad request", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponseDTO.class))), + @ApiResponse(responseCode = "404", description = "Not found", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponseDTO.class))) + } + ) + @RequestMapping( + method = RequestMethod.POST, + value = "/v1/insurance/activate/{quoteId}", + produces = {"application/json"} + ) + + default ResponseEntity activate(@Parameter(name = "quoteId", required = true, schema = @Schema(description = "")) @PathVariable("quoteId") Integer quoteId , @Parameter(name = "activatePolicyDTO", description = "", required = false, schema = @Schema(description = "")) @Valid @RequestBody ActivatePolicyDTO activatePolicyDTO) { + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } + /** + * POST /v1/insurance/settle/{policyId}: Settle a policy that was previously activated + * @param policyIdInProvider ID of the policy for the specific insurance provider true + * @param policySettlementDTO + * @return successful operation; (status code 200) Bad request; (status code 400) Not found; (status code 404) + */ + + @Operation( + operationId = "settle", + summary = "Settle a policy that was previously activated", + tags = {"Insurance"}, + responses = { + @ApiResponse(responseCode = "200", description = "successful operation", content = @Content(mediaType = "application/json", schema = @Schema(implementation = List.class))), + @ApiResponse(responseCode = "400", description = "Bad request", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponseDTO.class))), + @ApiResponse(responseCode = "404", description = "Not found", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponseDTO.class))) + } + ) + @RequestMapping( + method = RequestMethod.POST, + value = "/v1/insurance/settle/{policyId}", + produces = {"application/json"} + ) + + default ResponseEntity> settle(@Parameter(name = "policyIdInProvider", description = "ID of the policy for the specific insurance provider", required = true, schema = @Schema(description = "")) @PathVariable("policyIdInProvider") String policyIdInProvider , @Parameter(name = "policySettlementDTO", description = "", required = false, schema = @Schema(description = "")) @Valid @RequestBody PolicySettlementDTO policySettlementDTO) { + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } + /** + * POST /v1/insurance/claim/{policyId}: Claim a policy that was unpaid + * @param operationId ID of the operation in our own records, for reconciliation purposes true @param provider Name of the insurance provider false @param policyId ID of the policy for the specific insurance provider true @param claimDate Date that we start the claim true + * @param policyClaimDTO + * @return successful operation; (status code 200) Bad request; (status code 400) Not found; (status code 404) + */ + + @Operation( + operationId = "claim", + summary = "Claim a policy that was unpaid", + tags = {"Insurance"}, + responses = { + @ApiResponse(responseCode = "200", description = "successful operation", content = @Content(mediaType = "application/json", schema = @Schema(implementation = List.class))), + @ApiResponse(responseCode = "400", description = "Bad request", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponseDTO.class))), + @ApiResponse(responseCode = "404", description = "Not found", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponseDTO.class))) + } + ) + @RequestMapping( + method = RequestMethod.POST, + value = "/v1/insurance/claim/{policyId}", + produces = {"application/json"} + ) + + default ResponseEntity> claim(@Parameter(name = "operationId", description = "ID of the operation in our own records, for reconciliation purposes", required = true, schema = @Schema(description = "")) @RequestParam(required = true) Integer operationId , @Parameter(name = "provider", description = "Name of the insurance provider", required = false, schema = @Schema(description = "")) @RequestParam(required = false) String provider , @Parameter(name = "policyId", description = "ID of the policy for the specific insurance provider", required = true, schema = @Schema(description = "")) @PathVariable("policyId") String policyId , @Parameter(name = "claimDate", description = "Date that we start the claim", required = true, schema = @Schema(description = "")) @RequestParam(required = true) String claimDate , @Parameter(name = "policyClaimDTO", description = "", required = false, schema = @Schema(description = "")) @Valid @RequestBody PolicyClaimDTO policyClaimDTO) { + return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED); + } + +} diff --git a/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/ActivatePolicyDTO.java b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/ActivatePolicyDTO.java new file mode 100644 index 00000000..87ac7eec --- /dev/null +++ b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/ActivatePolicyDTO.java @@ -0,0 +1,22 @@ +package com.sngular.multifileplugin.testsimplebuild.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.extern.jackson.Jacksonized; + +@Data +public class ActivatePolicyDTO { + + @JsonProperty(value ="provider") + private String provider; + + + @Builder + @Jacksonized + private ActivatePolicyDTO(String provider) { + this.provider = provider; + + } + +} diff --git a/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/AddressDTO.java b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/AddressDTO.java new file mode 100644 index 00000000..b6b4473c --- /dev/null +++ b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/AddressDTO.java @@ -0,0 +1,38 @@ +package com.sngular.multifileplugin.testsimplebuild.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.extern.jackson.Jacksonized; + +@Data +public class AddressDTO { + + @JsonProperty(value ="country") + private String country; + + @JsonProperty(value ="city") + private String city; + + @JsonProperty(value ="street") + private String street; + + @JsonProperty(value ="number") + private Integer number; + + @JsonProperty(value ="postcode") + private Integer postcode; + + + @Builder + @Jacksonized + private AddressDTO(String country, String city, String street, Integer number, Integer postcode) { + this.country = country; + this.city = city; + this.street = street; + this.number = number; + this.postcode = postcode; + + } + +} diff --git a/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/CompanyDTO.java b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/CompanyDTO.java new file mode 100644 index 00000000..3df90876 --- /dev/null +++ b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/CompanyDTO.java @@ -0,0 +1,34 @@ +package com.sngular.multifileplugin.testsimplebuild.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.extern.jackson.Jacksonized; + +@Data +public class CompanyDTO { + + @JsonProperty(value ="fiscalAddress") + private AddressDTO fiscalAddress; + + @JsonProperty(value ="isInsurable") + private Boolean isInsurable; + + @JsonProperty(value ="name") + private String name; + + @JsonProperty(value ="isActive") + private Boolean isActive; + + + @Builder + @Jacksonized + private CompanyDTO(AddressDTO fiscalAddress, Boolean isInsurable, String name, Boolean isActive) { + this.fiscalAddress = fiscalAddress; + this.isInsurable = isInsurable; + this.name = name; + this.isActive = isActive; + + } + +} diff --git a/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/ContactDTO.java b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/ContactDTO.java new file mode 100644 index 00000000..babcdd36 --- /dev/null +++ b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/ContactDTO.java @@ -0,0 +1,43 @@ +package com.sngular.multifileplugin.testsimplebuild.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.NonNull; +import lombok.extern.jackson.Jacksonized; + +@Data +public class ContactDTO { + + @JsonProperty(value ="email") + @NonNull + private String email; + + @JsonProperty(value ="phoneNumber") + @NonNull + private Integer phoneNumber; + + @JsonProperty(value ="firstName") + private String firstName; + + @JsonProperty(value ="lastName") + @NonNull + private Integer lastName; + + @JsonProperty(value ="officePhoneNumber") + @NonNull + private Integer officePhoneNumber; + + + @Builder + @Jacksonized + private ContactDTO(@NonNull String email, @NonNull Integer phoneNumber, String firstName, @NonNull Integer lastName, @NonNull Integer officePhoneNumber) { + this.email = email; + this.phoneNumber = phoneNumber; + this.firstName = firstName; + this.lastName = lastName; + this.officePhoneNumber = officePhoneNumber; + + } + +} diff --git a/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/CreditLimitDTO.java b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/CreditLimitDTO.java new file mode 100644 index 00000000..3bb0204b --- /dev/null +++ b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/CreditLimitDTO.java @@ -0,0 +1,26 @@ +package com.sngular.multifileplugin.testsimplebuild.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.extern.jackson.Jacksonized; + +@Data +public class CreditLimitDTO { + + @JsonProperty(value ="insuredCreditLimit") + private InsuredCreditObjectDTO insuredCreditLimit; + + @JsonProperty(value ="isFundable") + private Boolean isFundable; + + + @Builder + @Jacksonized + private CreditLimitDTO(InsuredCreditObjectDTO insuredCreditLimit, Boolean isFundable) { + this.insuredCreditLimit = insuredCreditLimit; + this.isFundable = isFundable; + + } + +} diff --git a/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/DocumentDTO.java b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/DocumentDTO.java new file mode 100644 index 00000000..f90ed4bd --- /dev/null +++ b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/DocumentDTO.java @@ -0,0 +1,26 @@ +package com.sngular.multifileplugin.testsimplebuild.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.extern.jackson.Jacksonized; + +@Data +public class DocumentDTO { + + @JsonProperty(value ="description") + private String description; + + @JsonProperty(value ="document") + private String document; + + + @Builder + @Jacksonized + private DocumentDTO(String description, String document) { + this.description = description; + this.document = document; + + } + +} diff --git a/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/ErrorResponseDTO.java b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/ErrorResponseDTO.java new file mode 100644 index 00000000..a10d1e45 --- /dev/null +++ b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/ErrorResponseDTO.java @@ -0,0 +1,26 @@ +package com.sngular.multifileplugin.testsimplebuild.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.extern.jackson.Jacksonized; + +@Data +public class ErrorResponseDTO { + + @JsonProperty(value ="status") + private String status; + + @JsonProperty(value ="message") + private String message; + + + @Builder + @Jacksonized + private ErrorResponseDTO(String status, String message) { + this.status = status; + this.message = message; + + } + +} diff --git a/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/InsuredCreditObjectDTO.java b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/InsuredCreditObjectDTO.java new file mode 100644 index 00000000..846edb36 --- /dev/null +++ b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/InsuredCreditObjectDTO.java @@ -0,0 +1,30 @@ +package com.sngular.multifileplugin.testsimplebuild.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.extern.jackson.Jacksonized; + +@Data +public class InsuredCreditObjectDTO { + + @JsonProperty(value ="creditLimitInCents") + private Integer creditLimitInCents; + + @JsonProperty(value ="providerName") + private String providerName; + + @JsonProperty(value ="creditAvailableInCents") + private Integer creditAvailableInCents; + + + @Builder + @Jacksonized + private InsuredCreditObjectDTO(Integer creditLimitInCents, String providerName, Integer creditAvailableInCents) { + this.creditLimitInCents = creditLimitInCents; + this.providerName = providerName; + this.creditAvailableInCents = creditAvailableInCents; + + } + +} diff --git a/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/PolicyActivationDTO.java b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/PolicyActivationDTO.java new file mode 100644 index 00000000..0b990552 --- /dev/null +++ b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/PolicyActivationDTO.java @@ -0,0 +1,50 @@ +package com.sngular.multifileplugin.testsimplebuild.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.extern.jackson.Jacksonized; + +@Data +public class PolicyActivationDTO { + + @JsonProperty(value ="policyId") + private String policyId; + + @JsonProperty(value ="claimBeforeDate") + private String claimBeforeDate; + + @JsonProperty(value ="netCostInCents") + private Integer netCostInCents; + + @JsonProperty(value ="totalCostInCents") + private Integer totalCostInCents; + + @JsonProperty(value ="isActive") + private Boolean isActive; + + @JsonProperty(value ="currency") + private String currency; + + @JsonProperty(value ="coveredAmountInCents") + private Integer coveredAmountInCents; + + @JsonProperty(value ="insuranceProvider") + private String insuranceProvider; + + + @Builder + @Jacksonized + private PolicyActivationDTO(String policyId, String claimBeforeDate, Integer netCostInCents, Integer totalCostInCents, Boolean isActive, String currency, Integer coveredAmountInCents, String insuranceProvider) { + this.policyId = policyId; + this.claimBeforeDate = claimBeforeDate; + this.netCostInCents = netCostInCents; + this.totalCostInCents = totalCostInCents; + this.isActive = isActive; + this.currency = currency; + this.coveredAmountInCents = coveredAmountInCents; + this.insuranceProvider = insuranceProvider; + + } + +} diff --git a/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/PolicyClaimDTO.java b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/PolicyClaimDTO.java new file mode 100644 index 00000000..0f41c680 --- /dev/null +++ b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/PolicyClaimDTO.java @@ -0,0 +1,42 @@ +package com.sngular.multifileplugin.testsimplebuild.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.extern.jackson.Jacksonized; + +@Data +public class PolicyClaimDTO { + + @JsonProperty(value ="proofOfDeliveryDocument") + private DocumentDTO proofOfDeliveryDocument; + + @JsonProperty(value ="invoiceDocument") + private DocumentDTO invoiceDocument; + + @JsonProperty(value ="claimKind") + private String claimKind; + + @JsonProperty(value ="merchantContactDetails") + private ContactDTO merchantContactDetails; + + @JsonProperty(value ="claimDocument") + private DocumentDTO claimDocument; + + @JsonProperty(value ="debtorContactDetails") + private ContactDTO debtorContactDetails; + + + @Builder + @Jacksonized + private PolicyClaimDTO(DocumentDTO proofOfDeliveryDocument, DocumentDTO invoiceDocument, String claimKind, ContactDTO merchantContactDetails, DocumentDTO claimDocument, ContactDTO debtorContactDetails) { + this.proofOfDeliveryDocument = proofOfDeliveryDocument; + this.invoiceDocument = invoiceDocument; + this.claimKind = claimKind; + this.merchantContactDetails = merchantContactDetails; + this.claimDocument = claimDocument; + this.debtorContactDetails = debtorContactDetails; + + } + +} diff --git a/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/PolicySettlementDTO.java b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/PolicySettlementDTO.java new file mode 100644 index 00000000..c2db1325 --- /dev/null +++ b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/PolicySettlementDTO.java @@ -0,0 +1,26 @@ +package com.sngular.multifileplugin.testsimplebuild.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.extern.jackson.Jacksonized; + +@Data +public class PolicySettlementDTO { + + @JsonProperty(value ="provider") + private String provider; + + @JsonProperty(value ="settlementDate") + private String settlementDate; + + + @Builder + @Jacksonized + private PolicySettlementDTO(String provider, String settlementDate) { + this.provider = provider; + this.settlementDate = settlementDate; + + } + +} diff --git a/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/QuoteRequestDTO.java b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/QuoteRequestDTO.java new file mode 100644 index 00000000..ef4452fe --- /dev/null +++ b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/QuoteRequestDTO.java @@ -0,0 +1,42 @@ +package com.sngular.multifileplugin.testsimplebuild.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.extern.jackson.Jacksonized; + +@Data +public class QuoteRequestDTO { + + @JsonProperty(value ="debtorId") + private Integer debtorId; + + @JsonProperty(value ="currency") + private String currency; + + @JsonProperty(value ="merchantId") + private Integer merchantId; + + @JsonProperty(value ="totalAmountInCents") + private Long totalAmountInCents; + + @JsonProperty(value ="paymentDueDate") + private String paymentDueDate; + + @JsonProperty(value ="saleDate") + private String saleDate; + + + @Builder + @Jacksonized + private QuoteRequestDTO(Integer debtorId, String currency, Integer merchantId, Long totalAmountInCents, String paymentDueDate, String saleDate) { + this.debtorId = debtorId; + this.currency = currency; + this.merchantId = merchantId; + this.totalAmountInCents = totalAmountInCents; + this.paymentDueDate = paymentDueDate; + this.saleDate = saleDate; + + } + +} diff --git a/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/QuoteResponseDTO.java b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/QuoteResponseDTO.java new file mode 100644 index 00000000..bebe901a --- /dev/null +++ b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/QuoteResponseDTO.java @@ -0,0 +1,42 @@ +package com.sngular.multifileplugin.testsimplebuild.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.extern.jackson.Jacksonized; + +@Data +public class QuoteResponseDTO { + + @JsonProperty(value ="activateBeforeDate") + private String activateBeforeDate; + + @JsonProperty(value ="isInsurable") + private Boolean isInsurable; + + @JsonProperty(value ="claimBeforeDate") + private String claimBeforeDate; + + @JsonProperty(value ="currency") + private String currency; + + @JsonProperty(value ="estimatedCostInCents") + private Integer estimatedCostInCents; + + @JsonProperty(value ="quoteId") + private String quoteId; + + + @Builder + @Jacksonized + private QuoteResponseDTO(String activateBeforeDate, Boolean isInsurable, String claimBeforeDate, String currency, Integer estimatedCostInCents, String quoteId) { + this.activateBeforeDate = activateBeforeDate; + this.isInsurable = isInsurable; + this.claimBeforeDate = claimBeforeDate; + this.currency = currency; + this.estimatedCostInCents = estimatedCostInCents; + this.quoteId = quoteId; + + } + +} diff --git a/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/QuoteUpdateResponseDTO.java b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/QuoteUpdateResponseDTO.java new file mode 100644 index 00000000..5a804fa0 --- /dev/null +++ b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/QuoteUpdateResponseDTO.java @@ -0,0 +1,34 @@ +package com.sngular.multifileplugin.testsimplebuild.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.extern.jackson.Jacksonized; + +@Data +public class QuoteUpdateResponseDTO { + + @JsonProperty(value ="activateBeforeDate") + private String activateBeforeDate; + + @JsonProperty(value ="isInsurable") + private Boolean isInsurable; + + @JsonProperty(value ="claimBeforeDate") + private String claimBeforeDate; + + @JsonProperty(value ="estimatedCostInCents") + private Integer estimatedCostInCents; + + + @Builder + @Jacksonized + private QuoteUpdateResponseDTO(String activateBeforeDate, Boolean isInsurable, String claimBeforeDate, Integer estimatedCostInCents) { + this.activateBeforeDate = activateBeforeDate; + this.isInsurable = isInsurable; + this.claimBeforeDate = claimBeforeDate; + this.estimatedCostInCents = estimatedCostInCents; + + } + +} diff --git a/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/UpdateQuoteDTO.java b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/UpdateQuoteDTO.java new file mode 100644 index 00000000..dad05559 --- /dev/null +++ b/multiapi-engine/src/test/resources/openapigenerator/testSimpleBuild/assets/model/UpdateQuoteDTO.java @@ -0,0 +1,33 @@ +package com.sngular.multifileplugin.testsimplebuild.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Builder; +import lombok.Data; +import lombok.NonNull; +import lombok.extern.jackson.Jacksonized; + +@Data +public class UpdateQuoteDTO { + + @JsonProperty(value ="invoiceDate") + @NonNull + private String invoiceDate; + + @JsonProperty(value ="provider") + private String provider; + + @JsonProperty(value ="invoiceNumber") + @NonNull + private String invoiceNumber; + + + @Builder + @Jacksonized + private UpdateQuoteDTO(@NonNull String invoiceDate, String provider, @NonNull String invoiceNumber) { + this.invoiceDate = invoiceDate; + this.provider = provider; + this.invoiceNumber = invoiceNumber; + + } + +} diff --git a/scs-multiapi-gradle-plugin/build.gradle b/scs-multiapi-gradle-plugin/build.gradle index 7a90ad62..ae34ab6b 100644 --- a/scs-multiapi-gradle-plugin/build.gradle +++ b/scs-multiapi-gradle-plugin/build.gradle @@ -20,7 +20,7 @@ repositories { } group = 'com.sngular' -version = '5.0.2' +version = '5.0.3' def SCSMultiApiPluginGroupId = group def SCSMultiApiPluginVersion = version @@ -98,7 +98,7 @@ testing { integrationTest(JvmTestSuite) { dependencies { - implementation 'com.sngular:scs-multiapi-gradle-plugin:5.0.2' + implementation 'com.sngular:scs-multiapi-gradle-plugin:5.0.3' implementation 'org.assertj:assertj-core:3.24.2' } diff --git a/scs-multiapi-maven-plugin/pom.xml b/scs-multiapi-maven-plugin/pom.xml index 8a2f62e3..e8de6c21 100644 --- a/scs-multiapi-maven-plugin/pom.xml +++ b/scs-multiapi-maven-plugin/pom.xml @@ -4,7 +4,7 @@ com.sngular scs-multiapi-maven-plugin - 5.0.2 + 5.0.3 maven-plugin AsyncApi - OpenApi Code Generator Maven Plugin @@ -243,7 +243,7 @@ com.sngular multiapi-engine - 5.0.2 + 5.0.3 org.apache.maven From 4e43f9533c41d27a117ff6eaad148bc979e7a218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Enrique=20Garc=C3=ADa=20Maci=C3=B1eiras?= Date: Mon, 13 Nov 2023 22:11:31 +0100 Subject: [PATCH 2/6] 303 Fix support for referenced Request Bodies. --- .../plugin/openapi/OpenApiGenerator.java | 29 +++-- .../openapi/utils/MapperContentUtil.java | 103 ++++++++-------- .../assets/ApiDefaultItemDTO.java | 110 +++++++++++++++++- 3 files changed, 177 insertions(+), 65 deletions(-) diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/OpenApiGenerator.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/OpenApiGenerator.java index e2e3a1f6..2132bd45 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/OpenApiGenerator.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/OpenApiGenerator.java @@ -250,24 +250,29 @@ private String convertPackageToTargetPath(final String fileSpecPackage, final bo return FilenameUtils.concat(processedGeneratedSourcesFolder, PACKAGE_SEPARATOR.matcher(toMatch).replaceAll("/")); } - @SuppressWarnings("checkstyle:LambdaBodyLength") private void processModels( final SpecFile specFile, final String fileModelToSave, final String modelPackage, final Map basicSchemaMap, final boolean overwrite) { final Map builtSchemasMap = new HashMap<>(); - basicSchemaMap.forEach((schemaName, basicSchema) -> { - if (!overwrite && !overwriteModelList.add(schemaName + modelPackage)) { - throw new DuplicateModelClassException(schemaName, modelPackage); - } + basicSchemaMap.forEach((schemaName, basicSchema) -> + getModel(specFile, fileModelToSave, modelPackage, basicSchemaMap, overwrite, schemaName, basicSchema, builtSchemasMap) + ); - if (ApiTool.hasRef(basicSchema)) { - final var refSchema = MapperUtil.getRefSchemaName(basicSchema); - builtSchemasMap.putAll(writeModel(specFile, fileModelToSave, refSchema, basicSchemaMap.get(refSchema), basicSchemaMap, builtSchemasMap)); - } else if (!ApiTool.isArray(basicSchema) && !TypeConstants.STRING.equalsIgnoreCase(ApiTool.getType(basicSchema))) { - builtSchemasMap.putAll(writeModel(specFile, fileModelToSave, schemaName, basicSchema, basicSchemaMap, builtSchemasMap)); - } - }); + } + private void getModel( + final SpecFile specFile, final String fileModelToSave, final String modelPackage, final Map basicSchemaMap, final boolean overwrite, + final String schemaName, final JsonNode basicSchema, final Map builtSchemasMap) { + if (!overwrite && !overwriteModelList.add(schemaName + modelPackage)) { + throw new DuplicateModelClassException(schemaName, modelPackage); + } + + if (ApiTool.hasRef(basicSchema)) { + final var refSchema = MapperUtil.getRefSchemaName(basicSchema); + builtSchemasMap.putAll(writeModel(specFile, fileModelToSave, refSchema, basicSchemaMap.get(refSchema), basicSchemaMap, builtSchemasMap)); + } else if (!ApiTool.isArray(basicSchema) && !TypeConstants.STRING.equalsIgnoreCase(ApiTool.getType(basicSchema))) { + builtSchemasMap.putAll(writeModel(specFile, fileModelToSave, schemaName, basicSchema, basicSchemaMap, builtSchemasMap)); + } } private Map writeModel( diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/MapperContentUtil.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/MapperContentUtil.java index f7eb28d1..dedf06f4 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/MapperContentUtil.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/utils/MapperContentUtil.java @@ -16,6 +16,7 @@ import java.util.Objects; import java.util.Set; import java.util.function.Consumer; + import com.fasterxml.jackson.databind.JsonNode; import com.sngular.api.generator.plugin.common.tools.ApiTool; import com.sngular.api.generator.plugin.openapi.exception.BadDefinedEnumException; @@ -46,15 +47,15 @@ public static Map mapComponentToSchemaObject( final Map totalSchemas, final Map compositedSchemas, final JsonNode schema, final String schemaName, final SpecFile specFile, final Path baseDir) { - return mapComponentToSchemaObject(totalSchemas, compositedSchemas, new ArrayList<>(), schema, - StringUtils.defaultIfEmpty(ApiTool.getNodeAsString(schema, "name"), schemaName), specFile, baseDir); + return mapComponentToSchemaObject(totalSchemas, compositedSchemas, new HashSet<>(), schema, + StringUtils.defaultIfEmpty(ApiTool.getName(schema), schemaName), specFile, baseDir); } private static Map mapComponentToSchemaObject( final Map totalSchemas, final Map compositedSchemas, - final List antiLoopList, final JsonNode schema, final String schemaName, final SpecFile specFile, + final Set antiLoopList, final JsonNode schema, final String schemaName, final SpecFile specFile, final Path baseDir) { - final var name = StringUtils.defaultIfBlank(ApiTool.getNodeAsString(schema, "name"), schemaName); + final var name = StringUtils.defaultIfBlank(ApiTool.getName(schema), schemaName); if (!compositedSchemas.containsKey(name)) { compositedSchemas .put(name, toSchemaObject(name, totalSchemas, compositedSchemas, antiLoopList, schema, schemaName, specFile, baseDir)); @@ -65,12 +66,12 @@ private static Map mapComponentToSchemaObject( @SuppressWarnings("checkstyle:ParameterNumber") private static SchemaObject toSchemaObject( final String name, final Map totalSchemas, final Map compositedSchemas, - final List antiLoopList, final JsonNode schema, final String schemaName, final SpecFile specFile, + final Set antiLoopList, final JsonNode schema, final String schemaName, final SpecFile specFile, final Path baseDir) { antiLoopList.add(schemaName); - final var listSchema = getFields(totalSchemas, schema, specFile, compositedSchemas, antiLoopList, schemaName, baseDir); + final var listSchema = getFields(null, totalSchemas, schema, specFile, compositedSchemas, antiLoopList, schemaName, baseDir); String schemaCombinatorType = ""; if (ApiTool.isAllOf(schema)) { @@ -154,20 +155,20 @@ private static void getTypeImports( } } - private static Set getFields( + private static Set getFields(final String buildingSchema, final Map totalSchemas, final JsonNode schema, final SpecFile specFile, - final Map compositedSchemas, final List antiLoopList, final String nameSchema, + final Map compositedSchemas, final Set antiLoopList, final String nameSchema, final Path baseDir) { final Set fieldObjectArrayList = new HashSet<>(); if (ApiTool.hasProperties(schema)) { if (ApiTool.hasAdditionalProperties(schema)) { - ApiTool.getProperties(schema) - .forEachRemaining(processProperties(totalSchemas, compositedSchemas, fieldObjectArrayList, specFile, schema, antiLoopList, baseDir)); - fieldObjectArrayList.addAll( - processAdditionalProperties(ADDITIONAL_PROPERTIES, schema, specFile, totalSchemas, compositedSchemas, antiLoopList, nameSchema, baseDir)); + ApiTool.getProperties(schema).forEachRemaining(processProperties(buildingSchema, totalSchemas, compositedSchemas, fieldObjectArrayList, specFile, schema, antiLoopList, + baseDir)); + fieldObjectArrayList.addAll(processAdditionalProperties(ADDITIONAL_PROPERTIES, schema, specFile, totalSchemas, compositedSchemas, antiLoopList, nameSchema, baseDir)); } else { - ApiTool.getProperties(schema).forEachRemaining(processProperties(totalSchemas, compositedSchemas, fieldObjectArrayList, specFile, schema, antiLoopList, baseDir)); + ApiTool.getProperties(schema).forEachRemaining(processProperties(buildingSchema, totalSchemas, compositedSchemas, fieldObjectArrayList, specFile, schema, antiLoopList, + baseDir)); } } else if (TypeConstants.ARRAY.equalsIgnoreCase(ApiTool.getType(schema))) { final String itemType = ApiTool.hasRef(ApiTool.getItems(schema)) ? MapperUtil.getRef(ApiTool.getItems(schema), specFile) : ApiTool.getType(ApiTool.getItems(schema)); @@ -178,14 +179,15 @@ private static Set getFields( } else if (ApiTool.isAllOf(schema)) { fieldObjectArrayList.addAll(processAllOf(totalSchemas, ApiTool.getAllOf(schema), specFile, compositedSchemas, antiLoopList, baseDir)); } else if (ApiTool.isAnyOf(schema)) { - fieldObjectArrayList.addAll(processAnyOfOneOf(totalSchemas, ApiTool.getAnyOf(schema), specFile, compositedSchemas, antiLoopList, baseDir)); + fieldObjectArrayList.addAll(processAnyOfOneOf(buildingSchema, totalSchemas, ApiTool.getAnyOf(schema), specFile, compositedSchemas, antiLoopList, baseDir)); } else if (ApiTool.isOneOf(schema)) { - fieldObjectArrayList.addAll(processAnyOfOneOf(totalSchemas, ApiTool.getOneOf(schema), specFile, compositedSchemas, antiLoopList, baseDir)); + fieldObjectArrayList.addAll(processAnyOfOneOf(buildingSchema, totalSchemas, ApiTool.getOneOf(schema), specFile, compositedSchemas, antiLoopList, baseDir)); } else if (ApiTool.isEnum(schema)) { fieldObjectArrayList.add(processEnumField(ApiTool.getName(schema), schema, specFile, ApiTool.getEnumValues(schema), schema)); } else if (ApiTool.hasRef(schema)) { final var refSchema = totalSchemas.get(MapperUtil.getRefSchemaName(schema)); - ApiTool.getProperties(refSchema).forEachRemaining(processProperties(totalSchemas, compositedSchemas, fieldObjectArrayList, specFile, schema, antiLoopList, baseDir)); + ApiTool.getProperties(refSchema).forEachRemaining(processProperties(buildingSchema, totalSchemas, compositedSchemas, fieldObjectArrayList, specFile, schema, antiLoopList, + baseDir)); } else { fieldObjectArrayList.add(SchemaFieldObject.builder() .baseName(ApiTool.getName(schema)) @@ -198,14 +200,14 @@ private static Set getFields( private static Set processAllOf( final Map totalSchemas, final JsonNode schemaList, final SpecFile specFile, - final Map compositedSchemas, final List antiLoopList, final Path baseDir) { + final Map compositedSchemas, final Set antiLoopList, final Path baseDir) { final Set fieldObjectArrayList = new HashSet<>(); for (JsonNode ref : schemaList) { if (ApiTool.hasRef(ref)) { final String schemaName = MapperUtil.getRefSchemaName(ref); final var schemaToProcess = totalSchemas.get(schemaName); - ApiTool.getProperties(schemaToProcess).forEachRemaining(processProperties(totalSchemas, compositedSchemas, fieldObjectArrayList, specFile, ref, antiLoopList, baseDir)); + ApiTool.getProperties(schemaToProcess).forEachRemaining(processProperties("", totalSchemas, compositedSchemas, fieldObjectArrayList, specFile, ref, antiLoopList, baseDir)); for (var fieldObject : fieldObjectArrayList) { fieldObject.setRequired(true); } @@ -214,9 +216,9 @@ private static Set processAllOf( return fieldObjectArrayList; } - private static Set processAnyOfOneOf( + private static Set processAnyOfOneOf(final String buildingSchema, final Map totalSchemas, final JsonNode schemaList, final SpecFile specFile, - final Map compositedSchemas, final List antiLoopList, final Path baseDir) { + final Map compositedSchemas, final Set antiLoopList, final Path baseDir) { final Set fieldObjectArrayList = new HashSet<>(); for (JsonNode internalSchema : schemaList) { @@ -228,16 +230,17 @@ private static Set processAnyOfOneOf( fieldObjectArrayList.addAll(compositedSchemas.get(schemaName).getFieldObjectList()); } else { final var schemaObject = solveRef(internalSchema, totalSchemas, compositedSchemas, antiLoopList, specFile, baseDir); - fieldObjectArrayList.addAll(schemaObject.getFieldObjectList()); + compositedSchemas.put(schemaName, schemaObject); antiLoopList.add(schemaName); + fieldObjectArrayList.addAll(schemaObject.getFieldObjectList()); } - } else { - if (compositedSchemas.containsKey(schemaName)) { - fieldObjectArrayList.addAll(compositedSchemas.get(schemaName).getFieldObjectList()); - } + } else if (compositedSchemas.containsKey(schemaName)) { + fieldObjectArrayList.addAll(compositedSchemas.get(schemaName).getFieldObjectList()); + } else if (!schemaName.equalsIgnoreCase(buildingSchema)) { + fieldObjectArrayList.addAll(getFields(schemaName, totalSchemas, internalSchema, specFile, compositedSchemas, antiLoopList, ApiTool.getName(internalSchema), baseDir)); } } else { - fieldObjectArrayList.addAll(getFields(totalSchemas, internalSchema, specFile, compositedSchemas, antiLoopList, ApiTool.getName(internalSchema), baseDir)); + fieldObjectArrayList.addAll(getFields(buildingSchema, totalSchemas, internalSchema, specFile, compositedSchemas, antiLoopList, ApiTool.getName(internalSchema), baseDir)); for (var fieldObject : fieldObjectArrayList) { if (ApiTool.checkIfRequired(internalSchema, fieldObject.getBaseName())) { fieldObject.setRequired(true); @@ -249,9 +252,9 @@ private static Set processAnyOfOneOf( } @SuppressWarnings("checkstyle:CyclomaticComplexity") - private static List processFieldObjectList( + private static List processFieldObjectList(final String buildingSchema, final String fieldName, final String className, final JsonNode schema, final SpecFile specFile, final Map totalSchemas, - final Map compositedSchemas, final List antiLoopList, final Path baseDir) { + final Map compositedSchemas, final Set antiLoopList, final Path baseDir) { final var fieldObjectArrayList = new ArrayList(); if (TypeConstants.ARRAY.equalsIgnoreCase(ApiTool.getType(schema))) { @@ -281,7 +284,7 @@ private static List processFieldObjectList( final var composedSchemaName = StringUtils.defaultIfBlank(className, fieldName); var schemaObjectComposed = compositedSchemas.get(composedSchemaName); if (Objects.isNull(schemaObjectComposed)) { - schemaObjectComposed = createComposedSchema(StringUtils.defaultIfBlank(className, fieldName), schema, specFile, + schemaObjectComposed = createComposedSchema(buildingSchema, StringUtils.defaultIfBlank(className, fieldName), schema, specFile, totalSchemas, compositedSchemas, antiLoopList, baseDir); compositedSchemas.put(composedSchemaName, schemaObjectComposed); } @@ -299,7 +302,7 @@ private static List processFieldObjectList( private static SchemaFieldObject processRef( final String fieldName, final JsonNode schema, final SchemaFieldObjectType dataType, final Map totalSchemas, final Map compositedSchemas, - final List antiLoopList, final SpecFile specFile, final Path baseDir) { + final Set antiLoopList, final SpecFile specFile, final Path baseDir) { final var field = SchemaFieldObject.builder() .baseName(fieldName) .dataType(dataType) @@ -316,7 +319,7 @@ private static SchemaFieldObject processRef( private static SchemaObject solveRef( final JsonNode schema, final Map totalSchemas, - final Map compositedSchemas, final List antiLoopList, final SpecFile specFile, + final Map compositedSchemas, final Set antiLoopList, final SpecFile specFile, final Path baseDir) { final var referredSchema = OpenApiUtil.solveRef(ApiTool.getRefValue(schema), totalSchemas, baseDir.resolve(specFile.getFilePath()).getParent()); @@ -329,24 +332,24 @@ private static SchemaObject solveRef( return schemaObject; } - private static Consumer> processProperties( + private static Consumer> processProperties(final String buildingSchema, final Map totalSchemas, final Map compositedSchemas, final Set fieldObjectArrayList, final SpecFile specFile, - final JsonNode schema, final List antiLoopList, final Path baseDir) { + final JsonNode schema, final Set antiLoopList, final Path baseDir) { return field -> { final var nodeName = field.getKey(); final var nodeValue = field.getValue(); if (ApiTool.isEnum(field.getValue())) { fieldObjectArrayList.add(processEnumField(nodeName, nodeValue, specFile, ApiTool.getEnumValues(nodeValue), schema)); } else { - fieldObjectArrayList.addAll(processObjectProperty(totalSchemas, nodeName, nodeValue, compositedSchemas, specFile, schema, antiLoopList, baseDir)); + fieldObjectArrayList.addAll(processObjectProperty(buildingSchema, totalSchemas, nodeName, nodeValue, compositedSchemas, specFile, schema, antiLoopList, baseDir)); } }; } @SuppressWarnings({"checkstyle:CyclomaticComplexity", "checkstyle:ParameterNumber"}) - private static List processObjectProperty( + private static List processObjectProperty(final String buildingSchema, final Map totalSchemas, final String fieldName, final JsonNode fieldBody, final Map compositedSchemas, final SpecFile specFile, - final JsonNode schema, final List antiLoopList, final Path baseDir) { + final JsonNode schema, final Set antiLoopList, final Path baseDir) { final List fieldObjectArrayList = new LinkedList<>(); final var isRequired = ApiTool.checkIfRequired(fieldBody, fieldName); final SchemaFieldObject field; @@ -356,7 +359,8 @@ private static List processObjectProperty( if (!antiLoopList.contains(typeName) && totalSchemas.containsKey(typeName) && ApiTool.hasType(refSchema) && ApiTool.hasItems(refSchema) || ApiTool.getRefValue(fieldBody).contains(fieldName)) { antiLoopList.add(typeName); - fieldObjectArrayList.addAll(processFieldObjectList(fieldName, typeName, totalSchemas.get(typeName), specFile, totalSchemas, compositedSchemas, antiLoopList, baseDir)); + fieldObjectArrayList.addAll(processFieldObjectList(buildingSchema, fieldName, typeName, totalSchemas.get(typeName), specFile, totalSchemas, compositedSchemas, + antiLoopList, baseDir)); } else if (ApiTool.isEnum(refSchema)) { fieldObjectArrayList.add(processEnumField(fieldName, refSchema, specFile, ApiTool.getEnumValues(refSchema), schema)); } else { @@ -385,7 +389,7 @@ private static List processObjectProperty( setFieldType(field, fieldBody, schema, specFile, fieldName); fieldObjectArrayList.add(field); } else { - fieldObjectArrayList.addAll(processFieldObjectList(fieldName, fieldName, fieldBody, specFile, totalSchemas, compositedSchemas, antiLoopList, baseDir)); + fieldObjectArrayList.addAll(processFieldObjectList(buildingSchema, fieldName, fieldName, fieldBody, specFile, totalSchemas, compositedSchemas, antiLoopList, baseDir)); } return fieldObjectArrayList; } @@ -451,7 +455,7 @@ private static void addPropertiesToFieldObject(final SchemaFieldObject fieldObje @SuppressWarnings("checkstyle:ParameterNumber") private static List processArray( final String fieldName, final String className, final JsonNode schema, final SpecFile specFile, final Map totalSchemas, - final Map compositedSchemas, final List antiLoopList, final Path baseDir) { + final Map compositedSchemas, final Set antiLoopList, final Path baseDir) { final List fieldObjectArrayList = new LinkedList<>(); if (!ApiTool.hasItems(schema)) { @@ -470,7 +474,7 @@ private static List processArray( final String composedSchemaName = StringUtils.defaultIfBlank(className, fieldName); SchemaObject schemaObjectComposed = compositedSchemas.get(composedSchemaName); if (Objects.isNull(schemaObjectComposed)) { - schemaObjectComposed = createComposedSchema(StringUtils.defaultIfBlank(className, fieldName), items, specFile, + schemaObjectComposed = createComposedSchema("", StringUtils.defaultIfBlank(className, fieldName), items, specFile, totalSchemas, compositedSchemas, antiLoopList, baseDir); compositedSchemas.put(composedSchemaName, schemaObjectComposed); } @@ -506,12 +510,12 @@ private static List processArray( private static Set processObject( final String fieldName, final String className, final JsonNode schema, final SpecFile specFile, final Map totalSchemas, final Map compositedSchemas, - final List antiLoopList, final Path baseDir) { + final Set antiLoopList, final Path baseDir) { final Set fieldObjectArrayList = new HashSet<>(); if (ObjectUtils.allNull(className, fieldName)) { ApiTool.getProperties(schema).forEachRemaining( - processProperties(totalSchemas, compositedSchemas, fieldObjectArrayList, specFile, schema, antiLoopList, baseDir)); + processProperties("", totalSchemas, compositedSchemas, fieldObjectArrayList, specFile, schema, antiLoopList, baseDir)); } else if (antiLoopList.contains(className)) { fieldObjectArrayList .add(SchemaFieldObject @@ -544,12 +548,12 @@ private static Set processObject( private static Set processMap( final String fieldName, final JsonNode schema, final SpecFile specFile, final Map totalSchemas, - final Map compositedSchemas, final List antiLoopList, final Path baseDir) { + final Map compositedSchemas, final Set antiLoopList, final Path baseDir) { final Set fieldObjectArrayList = new HashSet<>(); if (TypeConstants.OBJECT.equalsIgnoreCase(ApiTool.getType(schema)) && ApiTool.hasProperties(schema)) { ApiTool.getProperties(schema).forEachRemaining( - processProperties(totalSchemas, compositedSchemas, fieldObjectArrayList, specFile, schema, antiLoopList, baseDir)); + processProperties("", totalSchemas, compositedSchemas, fieldObjectArrayList, specFile, schema, antiLoopList, baseDir)); } if (ApiTool.hasAdditionalProperties(schema)) { @@ -562,7 +566,7 @@ private static Set processMap( private static List processAdditionalProperties( final String fieldName, final JsonNode schema, final SpecFile specFile, final Map totalSchemas, - final Map compositedSchemas, final List antiLoopList, final String nameSchema, + final Map compositedSchemas, final Set antiLoopList, final String nameSchema, final Path baseDir) { final var fieldObjectArrayList = new ArrayList(); @@ -616,10 +620,9 @@ private static boolean isBasicType(final JsonNode value) { || ApiTool.hasAdditionalProperties(value)); } - private static SchemaObject createComposedSchema( + private static SchemaObject createComposedSchema(final String buildingSchema, final String fieldName, final JsonNode schema, final SpecFile specFile, final Map totalSchemas, - final Map compositedSchemas, - final List antiLoopList, final Path baseDir) { + final Map compositedSchemas, final Set antiLoopList, final Path baseDir) { final Set fieldObjectArrayList = new HashSet<>(); String schemaCombinatorType = ""; if (ApiTool.isAllOf(schema)) { @@ -628,11 +631,11 @@ private static SchemaObject createComposedSchema( schemaCombinatorType = ALL_OF_COMBINATOR; } else if (ApiTool.isAnyOf(schema)) { fieldObjectArrayList.addAll( - processAnyOfOneOf(totalSchemas, ApiTool.getAnyOf(schema), specFile, compositedSchemas, antiLoopList, baseDir)); + processAnyOfOneOf(buildingSchema, totalSchemas, ApiTool.getAnyOf(schema), specFile, compositedSchemas, antiLoopList, baseDir)); schemaCombinatorType = ANY_OF_COMBINATOR; } else if (ApiTool.isOneOf(schema)) { fieldObjectArrayList.addAll( - processAnyOfOneOf(totalSchemas, ApiTool.getOneOf(schema), specFile, compositedSchemas, antiLoopList, baseDir)); + processAnyOfOneOf(buildingSchema, totalSchemas, ApiTool.getOneOf(schema), specFile, compositedSchemas, antiLoopList, baseDir)); schemaCombinatorType = ONE_OF_COMBINATOR; } diff --git a/multiapi-engine/src/test/resources/openapigenerator/testComplexAnyOf/assets/ApiDefaultItemDTO.java b/multiapi-engine/src/test/resources/openapigenerator/testComplexAnyOf/assets/ApiDefaultItemDTO.java index a353d51f..7a188df5 100644 --- a/multiapi-engine/src/test/resources/openapigenerator/testComplexAnyOf/assets/ApiDefaultItemDTO.java +++ b/multiapi-engine/src/test/resources/openapigenerator/testComplexAnyOf/assets/ApiDefaultItemDTO.java @@ -16,6 +16,8 @@ public class ApiDefaultItemDTO { @JsonProperty(value ="precision") private Integer precision; + @JsonProperty(value ="defaultItem") + private ApiDefaultItemDTO defaultItem; @JsonProperty(value ="maximum") private Integer maximum; @JsonProperty(value ="type") @@ -30,6 +32,8 @@ public class ApiDefaultItemDTO { private String keyType; @JsonProperty(value ="requiredValues") private List requiredValues = new ArrayList(); + @JsonProperty(value ="optionalUnion") + private Boolean optionalUnion; @JsonProperty(value ="initialValue") private String initialValue; @JsonProperty(value ="flagExclusiveMinimum") @@ -44,6 +48,29 @@ public class ApiDefaultItemDTO { private List properties = new ArrayList(); @JsonProperty(value ="defaultValues") private List defaultValues = new ArrayList(); + @JsonProperty(value ="unionEnum") + private UnionEnum unionEnum; + public enum UnionEnum { + ONEOF("oneof"), + ANYOF("anyof"), + ALLOF("allof"); + + private String value; + + UnionEnum(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + } @JsonProperty(value ="seqEnum") private SeqEnum seqEnum; public enum SeqEnum { @@ -80,6 +107,8 @@ public String toString() { private List mapTypes = new ArrayList(); @JsonProperty(value ="format") private Integer format; + @JsonProperty(value ="generatedFlag") + private Boolean generatedFlag; @JsonProperty(value ="maxLength") private Integer maxLength; @JsonProperty(value ="uniqueItems") @@ -121,8 +150,9 @@ public String toString() { @JsonProperty(value ="valueLength") private Integer valueLength; - private ApiDefaultItemDTO(Integer precision, Integer maximum, String type, Integer scale, Integer minLength, Integer increment, String keyType, List requiredValues, String initialValue, Boolean flagExclusiveMinimum, Boolean flagExclusiveMaximum, Boolean defaultValue, List enumValues, List properties, List defaultValues, SeqEnum seqEnum, Integer arraySize, Integer multipleOf, Integer mapSize, List mapTypes, Integer format, Integer maxLength, Boolean uniqueItems, Integer elements, String name, String regex, Integer minItems, List values, Integer minimum, NumberEnum numberEnum, Integer valueLength) { + private ApiDefaultItemDTO(Integer precision, ApiDefaultItemDTO defaultItem, Integer maximum, String type, Integer scale, Integer minLength, Integer increment, String keyType, List requiredValues, Boolean optionalUnion, String initialValue, Boolean flagExclusiveMinimum, Boolean flagExclusiveMaximum, Boolean defaultValue, List enumValues, List properties, List defaultValues, UnionEnum unionEnum, SeqEnum seqEnum, Integer arraySize, Integer multipleOf, Integer mapSize, List mapTypes, Integer format, Boolean generatedFlag, Integer maxLength, Boolean uniqueItems, Integer elements, String name, String regex, Integer minItems, List values, Integer minimum, NumberEnum numberEnum, Integer valueLength) { this.precision = precision; + this.defaultItem = defaultItem; this.maximum = maximum; this.type = type; this.scale = scale; @@ -130,6 +160,7 @@ private ApiDefaultItemDTO(Integer precision, Integer maximum, String type, Integ this.increment = increment; this.keyType = keyType; this.requiredValues = requiredValues; + this.optionalUnion = optionalUnion; this.initialValue = initialValue; this.flagExclusiveMinimum = flagExclusiveMinimum; this.flagExclusiveMaximum = flagExclusiveMaximum; @@ -137,12 +168,14 @@ private ApiDefaultItemDTO(Integer precision, Integer maximum, String type, Integ this.enumValues = enumValues; this.properties = properties; this.defaultValues = defaultValues; + this.unionEnum = unionEnum; this.seqEnum = seqEnum; this.arraySize = arraySize; this.multipleOf = multipleOf; this.mapSize = mapSize; this.mapTypes = mapTypes; this.format = format; + this.generatedFlag = generatedFlag; this.maxLength = maxLength; this.uniqueItems = uniqueItems; this.elements = elements; @@ -159,6 +192,7 @@ private ApiDefaultItemDTO(Integer precision, Integer maximum, String type, Integ private ApiDefaultItemDTO(ApiDefaultItemDTOBuilder builder) { this.precision = builder.precision; + this.defaultItem = builder.defaultItem; this.maximum = builder.maximum; this.type = builder.type; this.scale = builder.scale; @@ -166,6 +200,7 @@ private ApiDefaultItemDTO(ApiDefaultItemDTOBuilder builder) { this.increment = builder.increment; this.keyType = builder.keyType; this.requiredValues = builder.requiredValues; + this.optionalUnion = builder.optionalUnion; this.initialValue = builder.initialValue; this.flagExclusiveMinimum = builder.flagExclusiveMinimum; this.flagExclusiveMaximum = builder.flagExclusiveMaximum; @@ -173,12 +208,14 @@ private ApiDefaultItemDTO(ApiDefaultItemDTOBuilder builder) { this.enumValues = builder.enumValues; this.properties = builder.properties; this.defaultValues = builder.defaultValues; + this.unionEnum = builder.unionEnum; this.seqEnum = builder.seqEnum; this.arraySize = builder.arraySize; this.multipleOf = builder.multipleOf; this.mapSize = builder.mapSize; this.mapTypes = builder.mapTypes; this.format = builder.format; + this.generatedFlag = builder.generatedFlag; this.maxLength = builder.maxLength; this.uniqueItems = builder.uniqueItems; this.elements = builder.elements; @@ -201,6 +238,7 @@ public static ApiDefaultItemDTO.ApiDefaultItemDTOBuilder builder() { public static class ApiDefaultItemDTOBuilder { private Integer precision; + private ApiDefaultItemDTO defaultItem; private Integer maximum; private String type; private Integer scale; @@ -208,6 +246,7 @@ public static class ApiDefaultItemDTOBuilder { private Integer increment; private String keyType; private List requiredValues = new ArrayList(); + private Boolean optionalUnion; private String initialValue; private Boolean flagExclusiveMinimum; private Boolean flagExclusiveMaximum; @@ -215,12 +254,14 @@ public static class ApiDefaultItemDTOBuilder { private List enumValues = new ArrayList(); private List properties = new ArrayList(); private List defaultValues = new ArrayList(); + private UnionEnum unionEnum; private SeqEnum seqEnum; private Integer arraySize; private Integer multipleOf; private Integer mapSize; private List mapTypes = new ArrayList(); private Integer format; + private Boolean generatedFlag; private Integer maxLength; private Boolean uniqueItems; private Integer elements; @@ -237,6 +278,11 @@ public ApiDefaultItemDTO.ApiDefaultItemDTOBuilder precision(Integer precision) { return this; } + public ApiDefaultItemDTO.ApiDefaultItemDTOBuilder defaultItem(ApiDefaultItemDTO defaultItem) { + this.defaultItem = defaultItem; + return this; + } + public ApiDefaultItemDTO.ApiDefaultItemDTOBuilder maximum(Integer maximum) { this.maximum = maximum; return this; @@ -280,6 +326,11 @@ public ApiDefaultItemDTO.ApiDefaultItemDTOBuilder requiredValue(String requiredV return this; } + public ApiDefaultItemDTO.ApiDefaultItemDTOBuilder optionalUnion(Boolean optionalUnion) { + this.optionalUnion = optionalUnion; + return this; + } + public ApiDefaultItemDTO.ApiDefaultItemDTOBuilder initialValue(String initialValue) { this.initialValue = initialValue; return this; @@ -338,6 +389,10 @@ public ApiDefaultItemDTO.ApiDefaultItemDTOBuilder defaultValue(String defaultVal } return this; } + public ApiDefaultItemDTO.ApiDefaultItemDTOBuilder unionEnum(UnionEnum unionEnum) { + this.unionEnum = unionEnum; + return this; + } public ApiDefaultItemDTO.ApiDefaultItemDTOBuilder seqEnum(SeqEnum seqEnum) { this.seqEnum = seqEnum; return this; @@ -376,6 +431,11 @@ public ApiDefaultItemDTO.ApiDefaultItemDTOBuilder format(Integer format) { return this; } + public ApiDefaultItemDTO.ApiDefaultItemDTOBuilder generatedFlag(Boolean generatedFlag) { + this.generatedFlag = generatedFlag; + return this; + } + public ApiDefaultItemDTO.ApiDefaultItemDTOBuilder maxLength(Integer maxLength) { this.maxLength = maxLength; return this; @@ -447,6 +507,14 @@ public void setPrecision(Integer precision) { this.precision = precision; } + @Schema(name = "defaultItem", required = false) + public ApiDefaultItemDTO getDefaultItem() { + return defaultItem; + } + public void setDefaultItem(ApiDefaultItemDTO defaultItem) { + this.defaultItem = defaultItem; + } + @Schema(name = "maximum", required = false) public Integer getMaximum() { return maximum; @@ -503,6 +571,14 @@ public void setRequiredValues(List requiredValues) { this.requiredValues = requiredValues; } + @Schema(name = "optionalUnion", required = false) + public Boolean getOptionalUnion() { + return optionalUnion; + } + public void setOptionalUnion(Boolean optionalUnion) { + this.optionalUnion = optionalUnion; + } + @Schema(name = "initialValue", required = false) public String getInitialValue() { return initialValue; @@ -559,6 +635,14 @@ public void setDefaultValues(List defaultValues) { this.defaultValues = defaultValues; } + @Schema(name = "unionEnum", required = false) + public UnionEnum getUnionEnum() { + return unionEnum; + } + public void setUnionEnum(UnionEnum unionEnum) { + this.unionEnum = unionEnum; + } + @Schema(name = "seqEnum", required = false) public SeqEnum getSeqEnum() { return seqEnum; @@ -607,6 +691,14 @@ public void setFormat(Integer format) { this.format = format; } + @Schema(name = "generatedFlag", required = false) + public Boolean getGeneratedFlag() { + return generatedFlag; + } + public void setGeneratedFlag(Boolean generatedFlag) { + this.generatedFlag = generatedFlag; + } + @Schema(name = "maxLength", required = false) public Integer getMaxLength() { return maxLength; @@ -696,12 +788,12 @@ public boolean equals(Object o) { return false; } ApiDefaultItemDTO apiDefaultItemDTO = (ApiDefaultItemDTO) o; - return Objects.equals(this.precision, apiDefaultItemDTO.precision) && Objects.equals(this.maximum, apiDefaultItemDTO.maximum) && Objects.equals(this.type, apiDefaultItemDTO.type) && Objects.equals(this.scale, apiDefaultItemDTO.scale) && Objects.equals(this.minLength, apiDefaultItemDTO.minLength) && Objects.equals(this.increment, apiDefaultItemDTO.increment) && Objects.equals(this.keyType, apiDefaultItemDTO.keyType) && Objects.equals(this.requiredValues, apiDefaultItemDTO.requiredValues) && Objects.equals(this.initialValue, apiDefaultItemDTO.initialValue) && Objects.equals(this.flagExclusiveMinimum, apiDefaultItemDTO.flagExclusiveMinimum) && Objects.equals(this.flagExclusiveMaximum, apiDefaultItemDTO.flagExclusiveMaximum) && Objects.equals(this.defaultValue, apiDefaultItemDTO.defaultValue) && Objects.equals(this.enumValues, apiDefaultItemDTO.enumValues) && Objects.equals(this.properties, apiDefaultItemDTO.properties) && Objects.equals(this.defaultValues, apiDefaultItemDTO.defaultValues) && Objects.equals(this.seqEnum, apiDefaultItemDTO.seqEnum) && Objects.equals(this.arraySize, apiDefaultItemDTO.arraySize) && Objects.equals(this.multipleOf, apiDefaultItemDTO.multipleOf) && Objects.equals(this.mapSize, apiDefaultItemDTO.mapSize) && Objects.equals(this.mapTypes, apiDefaultItemDTO.mapTypes) && Objects.equals(this.format, apiDefaultItemDTO.format) && Objects.equals(this.maxLength, apiDefaultItemDTO.maxLength) && Objects.equals(this.uniqueItems, apiDefaultItemDTO.uniqueItems) && Objects.equals(this.elements, apiDefaultItemDTO.elements) && Objects.equals(this.name, apiDefaultItemDTO.name) && Objects.equals(this.regex, apiDefaultItemDTO.regex) && Objects.equals(this.minItems, apiDefaultItemDTO.minItems) && Objects.equals(this.values, apiDefaultItemDTO.values) && Objects.equals(this.minimum, apiDefaultItemDTO.minimum) && Objects.equals(this.numberEnum, apiDefaultItemDTO.numberEnum) && Objects.equals(this.valueLength, apiDefaultItemDTO.valueLength); + return Objects.equals(this.precision, apiDefaultItemDTO.precision) && Objects.equals(this.defaultItem, apiDefaultItemDTO.defaultItem) && Objects.equals(this.maximum, apiDefaultItemDTO.maximum) && Objects.equals(this.type, apiDefaultItemDTO.type) && Objects.equals(this.scale, apiDefaultItemDTO.scale) && Objects.equals(this.minLength, apiDefaultItemDTO.minLength) && Objects.equals(this.increment, apiDefaultItemDTO.increment) && Objects.equals(this.keyType, apiDefaultItemDTO.keyType) && Objects.equals(this.requiredValues, apiDefaultItemDTO.requiredValues) && Objects.equals(this.optionalUnion, apiDefaultItemDTO.optionalUnion) && Objects.equals(this.initialValue, apiDefaultItemDTO.initialValue) && Objects.equals(this.flagExclusiveMinimum, apiDefaultItemDTO.flagExclusiveMinimum) && Objects.equals(this.flagExclusiveMaximum, apiDefaultItemDTO.flagExclusiveMaximum) && Objects.equals(this.defaultValue, apiDefaultItemDTO.defaultValue) && Objects.equals(this.enumValues, apiDefaultItemDTO.enumValues) && Objects.equals(this.properties, apiDefaultItemDTO.properties) && Objects.equals(this.defaultValues, apiDefaultItemDTO.defaultValues) && Objects.equals(this.unionEnum, apiDefaultItemDTO.unionEnum) && Objects.equals(this.seqEnum, apiDefaultItemDTO.seqEnum) && Objects.equals(this.arraySize, apiDefaultItemDTO.arraySize) && Objects.equals(this.multipleOf, apiDefaultItemDTO.multipleOf) && Objects.equals(this.mapSize, apiDefaultItemDTO.mapSize) && Objects.equals(this.mapTypes, apiDefaultItemDTO.mapTypes) && Objects.equals(this.format, apiDefaultItemDTO.format) && Objects.equals(this.generatedFlag, apiDefaultItemDTO.generatedFlag) && Objects.equals(this.maxLength, apiDefaultItemDTO.maxLength) && Objects.equals(this.uniqueItems, apiDefaultItemDTO.uniqueItems) && Objects.equals(this.elements, apiDefaultItemDTO.elements) && Objects.equals(this.name, apiDefaultItemDTO.name) && Objects.equals(this.regex, apiDefaultItemDTO.regex) && Objects.equals(this.minItems, apiDefaultItemDTO.minItems) && Objects.equals(this.values, apiDefaultItemDTO.values) && Objects.equals(this.minimum, apiDefaultItemDTO.minimum) && Objects.equals(this.numberEnum, apiDefaultItemDTO.numberEnum) && Objects.equals(this.valueLength, apiDefaultItemDTO.valueLength); } @Override public int hashCode() { - return Objects.hash(precision, maximum, type, scale, minLength, increment, keyType, requiredValues, initialValue, flagExclusiveMinimum, flagExclusiveMaximum, defaultValue, enumValues, properties, defaultValues, seqEnum, arraySize, multipleOf, mapSize, mapTypes, format, maxLength, uniqueItems, elements, name, regex, minItems, values, minimum, numberEnum, valueLength); + return Objects.hash(precision, defaultItem, maximum, type, scale, minLength, increment, keyType, requiredValues, optionalUnion, initialValue, flagExclusiveMinimum, flagExclusiveMaximum, defaultValue, enumValues, properties, defaultValues, unionEnum, seqEnum, arraySize, multipleOf, mapSize, mapTypes, format, generatedFlag, maxLength, uniqueItems, elements, name, regex, minItems, values, minimum, numberEnum, valueLength); } @Override @@ -709,6 +801,7 @@ public String toString() { StringBuilder sb = new StringBuilder(); sb.append("ApiDefaultItemDTO{"); sb.append(" precision:").append(precision).append(","); + sb.append(" defaultItem:").append(defaultItem).append(","); sb.append(" maximum:").append(maximum).append(","); sb.append(" type:").append(type).append(","); sb.append(" scale:").append(scale).append(","); @@ -716,6 +809,7 @@ public String toString() { sb.append(" increment:").append(increment).append(","); sb.append(" keyType:").append(keyType).append(","); sb.append(" requiredValues:").append(requiredValues).append(","); + sb.append(" optionalUnion:").append(optionalUnion).append(","); sb.append(" initialValue:").append(initialValue).append(","); sb.append(" flagExclusiveMinimum:").append(flagExclusiveMinimum).append(","); sb.append(" flagExclusiveMaximum:").append(flagExclusiveMaximum).append(","); @@ -723,12 +817,14 @@ public String toString() { sb.append(" enumValues:").append(enumValues).append(","); sb.append(" properties:").append(properties).append(","); sb.append(" defaultValues:").append(defaultValues).append(","); + sb.append(" unionEnum:").append(unionEnum).append(","); sb.append(" seqEnum:").append(seqEnum).append(","); sb.append(" arraySize:").append(arraySize).append(","); sb.append(" multipleOf:").append(multipleOf).append(","); sb.append(" mapSize:").append(mapSize).append(","); sb.append(" mapTypes:").append(mapTypes).append(","); sb.append(" format:").append(format).append(","); + sb.append(" generatedFlag:").append(generatedFlag).append(","); sb.append(" maxLength:").append(maxLength).append(","); sb.append(" uniqueItems:").append(uniqueItems).append(","); sb.append(" elements:").append(elements).append(","); @@ -748,6 +844,8 @@ private void validatePartialCombinations() { if (Objects.nonNull(this.precision)) { satisfiedCondition = true; + } else if (Objects.nonNull(this.defaultItem)) { + satisfiedCondition = true; } else if (Objects.nonNull(this.maximum)) { satisfiedCondition = true; } else if (Objects.nonNull(this.type)) { @@ -762,6 +860,8 @@ private void validatePartialCombinations() { satisfiedCondition = true; } else if (Objects.nonNull(this.requiredValues)) { satisfiedCondition = true; + } else if (Objects.nonNull(this.optionalUnion)) { + satisfiedCondition = true; } else if (Objects.nonNull(this.initialValue)) { satisfiedCondition = true; } else if (Objects.nonNull(this.flagExclusiveMinimum)) { @@ -776,6 +876,8 @@ private void validatePartialCombinations() { satisfiedCondition = true; } else if (Objects.nonNull(this.defaultValues)) { satisfiedCondition = true; + } else if (Objects.nonNull(this.unionEnum)) { + satisfiedCondition = true; } else if (Objects.nonNull(this.seqEnum)) { satisfiedCondition = true; } else if (Objects.nonNull(this.arraySize)) { @@ -788,6 +890,8 @@ private void validatePartialCombinations() { satisfiedCondition = true; } else if (Objects.nonNull(this.format)) { satisfiedCondition = true; + } else if (Objects.nonNull(this.generatedFlag)) { + satisfiedCondition = true; } else if (Objects.nonNull(this.maxLength)) { satisfiedCondition = true; } else if (Objects.nonNull(this.uniqueItems)) { From e80df9dcb6ef2d9908d44081c8fb99c990f00100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Enrique=20Garc=C3=ADa=20Maci=C3=B1eiras?= Date: Mon, 13 Nov 2023 22:22:35 +0100 Subject: [PATCH 3/6] 303 Fix support for referenced Request Bodies. --- .../sngular/api/generator/plugin/openapi/OpenApiGenerator.java | 1 + 1 file changed, 1 insertion(+) diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/OpenApiGenerator.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/OpenApiGenerator.java index 2132bd45..59dbef67 100644 --- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/OpenApiGenerator.java +++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/openapi/OpenApiGenerator.java @@ -260,6 +260,7 @@ private void processModels( } + @SuppressWarnings("checkstyle:ParameterNumber") private void getModel( final SpecFile specFile, final String fileModelToSave, final String modelPackage, final Map basicSchemaMap, final boolean overwrite, final String schemaName, final JsonNode basicSchema, final Map builtSchemasMap) { From 99eda6a7ca341988fb1e310fe17a627cf1d1a024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Enrique=20Garc=C3=ADa=20Maci=C3=B1eiras?= Date: Wed, 15 Nov 2023 00:50:07 +0100 Subject: [PATCH 4/6] 303 Fix case problem in test --- .../api/generator/plugin/openapi/OpenApiGeneratorFixtures.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorFixtures.java b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorFixtures.java index eec77782..5a9e53b6 100644 --- a/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorFixtures.java +++ b/multiapi-engine/src/test/java/com/sngular/api/generator/plugin/openapi/OpenApiGeneratorFixtures.java @@ -1150,7 +1150,7 @@ static Function validateSimpleBuild() { final String DEFAULT_MODEL_API = "generated/com/sngular/multifileplugin/testsimplebuild/model"; - final String COMMON_PATH = "openapigenerator/testsimplebuild/"; + final String COMMON_PATH = "openapigenerator/testSimpleBuild/"; final String ASSETS_PATH = COMMON_PATH + "assets/"; From 4c9499630c7722f4875ac9c6986d41a4b90ea122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Enrique=20Garc=C3=ADa=20Maci=C3=B1eiras?= Date: Wed, 15 Nov 2023 00:57:46 +0100 Subject: [PATCH 5/6] 303 Fix Gradle build --- scs-multiapi-gradle-plugin/build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scs-multiapi-gradle-plugin/build.gradle b/scs-multiapi-gradle-plugin/build.gradle index ae34ab6b..5b8acb85 100644 --- a/scs-multiapi-gradle-plugin/build.gradle +++ b/scs-multiapi-gradle-plugin/build.gradle @@ -30,9 +30,9 @@ dependencies { shadow localGroovy() shadow gradleApi() - implementation 'com.sngular:multiapi-engine:5.0.2' + implementation 'com.sngular:multiapi-engine:5.0.3' testImplementation 'org.assertj:assertj-core:3.24.2' - testImplementation 'com.puppycrawl.tools:checkstyle:10.9.1' + testImplementation 'com.puppycrawl.tools:checkstyle:10.12.3' } jar { @@ -86,7 +86,7 @@ gradlePlugin { } checkstyle { - toolVersion "10.9.1" + toolVersion "10.12.3" configFile = file("../checkstyle.xml") } From 9153644a7441276a16432c81267b68ef63505d29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Enrique=20Garc=C3=ADa=20Maci=C3=B1eiras?= Date: Tue, 21 Nov 2023 12:42:34 +0100 Subject: [PATCH 6/6] 303 Merge with Master --- multiapi-engine/pom.xml | 2 +- scs-multiapi-gradle-plugin/build.gradle | 6 +++--- scs-multiapi-maven-plugin/pom.xml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/multiapi-engine/pom.xml b/multiapi-engine/pom.xml index cf1ef1ad..7e8c65fb 100644 --- a/multiapi-engine/pom.xml +++ b/multiapi-engine/pom.xml @@ -4,7 +4,7 @@ com.sngular multiapi-engine - 5.1.0 + 5.1.1 jar diff --git a/scs-multiapi-gradle-plugin/build.gradle b/scs-multiapi-gradle-plugin/build.gradle index b6c9f55a..04a1caae 100644 --- a/scs-multiapi-gradle-plugin/build.gradle +++ b/scs-multiapi-gradle-plugin/build.gradle @@ -20,7 +20,7 @@ repositories { } group = 'com.sngular' -version = '5.1.0' +version = '5.1.1' def SCSMultiApiPluginGroupId = group def SCSMultiApiPluginVersion = version @@ -30,7 +30,7 @@ dependencies { shadow localGroovy() shadow gradleApi() - implementation 'com.sngular:multiapi-engine:5.1.0' + implementation 'com.sngular:multiapi-engine:5.1.1' testImplementation 'org.assertj:assertj-core:3.24.2' testImplementation 'com.puppycrawl.tools:checkstyle:10.12.3' } @@ -98,7 +98,7 @@ testing { integrationTest(JvmTestSuite) { dependencies { - implementation 'com.sngular:scs-multiapi-gradle-plugin:5.1.0' + implementation 'com.sngular:scs-multiapi-gradle-plugin:5.1.1' implementation 'org.assertj:assertj-core:3.24.2' } diff --git a/scs-multiapi-maven-plugin/pom.xml b/scs-multiapi-maven-plugin/pom.xml index 0c301471..5fc4f47a 100644 --- a/scs-multiapi-maven-plugin/pom.xml +++ b/scs-multiapi-maven-plugin/pom.xml @@ -4,7 +4,7 @@ com.sngular scs-multiapi-maven-plugin - 5.1.0 + 5.1.1 maven-plugin AsyncApi - OpenApi Code Generator Maven Plugin @@ -243,7 +243,7 @@ com.sngular multiapi-engine - 5.1.0 + 5.1.1 org.apache.maven