diff --git a/test-api-generator/citrus-test-api-generator-core/src/main/java/org/citrusframework/openapi/generator/JavaCitrusCodegen.java b/test-api-generator/citrus-test-api-generator-core/src/main/java/org/citrusframework/openapi/generator/JavaCitrusCodegen.java index c624c885f6..2e5c73d6dd 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/main/java/org/citrusframework/openapi/generator/JavaCitrusCodegen.java +++ b/test-api-generator/citrus-test-api-generator-core/src/main/java/org/citrusframework/openapi/generator/JavaCitrusCodegen.java @@ -192,7 +192,6 @@ public void processOpts() { additionalProperties.put(API_ENDPOINT, httpClient); if (additionalProperties.containsKey(GENERATED_SCHEMA_FOLDER)) { - this.setGeneratedSchemaFolder(additionalProperties.get(GENERATED_SCHEMA_FOLDER).toString()); } additionalProperties.put(GENERATED_SCHEMA_FOLDER, generatedSchemaFolder); @@ -229,14 +228,11 @@ public void processOpts() { additionalProperties.put(RESOURCE_FOLDER, resourceFolder); if (additionalProperties.containsKey(TARGET_XMLNS_NAMESPACE)) { - this.setTargetXmlnsNamespace(additionalProperties.get(TARGET_XMLNS_NAMESPACE).toString()); } else { - this.targetXmlnsNamespace = format("http://www.citrusframework.org/citrus-test-schema/%s-api", apiPrefix.toLowerCase()); } additionalProperties.put(TARGET_XMLNS_NAMESPACE, targetXmlnsNamespace); // define different folders where the files will be emitted - final String invokerFolder = (sourceFolder + File.separator + invokerPackage).replace(".", File.separator); final String citrusFolder = invokerFolder + File.separator + "citrus"; final String extensionFolder = citrusFolder + File.separator + "extension"; final String springFolder = invokerFolder + File.separator + "spring"; @@ -248,7 +244,6 @@ public void processOpts() { } else if (API_TYPE_SOAP.equals(apiType)) { addSoapSupportingFiles(citrusFolder, schemaFolder); } else { - throw new IllegalArgumentException(format("Unknown API_TYPE: '%s'", apiType)); } addDefaultSupportingFiles(citrusFolder, extensionFolder, springFolder); @@ -264,12 +259,67 @@ public void preprocessOpenAPI(OpenAPI openAPI) { additionalProperties.putAll(extensions); Map infoExtensions = extensions.entrySet().stream() - .filter(entry -> entry.getKey().toUpperCase().startsWith("X-")) .collect(toMap(Entry::getKey, Entry::getValue)); additionalProperties.put("infoExtensions", infoExtensions); } } + public void setApiPrefix(String apiPrefix) { + this.apiPrefix = apiPrefix; + } + + public String getHttpClient() { + return httpClient; + } + + public void setHttpClient(String httpClient) { + this.httpClient = httpClient; + } + + public String getHttpPathPrefix() { + return httpPathPrefix; + } + + public void setHttpPathPrefix(String httpPathPrefix) { + this.httpPathPrefix = httpPathPrefix; + } + + public String getOpenapiSchema() { + return openapiSchema; + } + + public void setOpenapiSchema(String openapiSchema) { + this.openapiSchema = openapiSchema; + } + + public String getResourceFolder() { + return resourceFolder; + } + + public void setResourceFolder(String resourceFolder) { + this.resourceFolder = resourceFolder; + } + + public String getGeneratedSchemaFolder() { + return generatedSchemaFolder; + } + + public void setGeneratedSchemaFolder(String generatedSchemaFolder) { + this.generatedSchemaFolder = generatedSchemaFolder; + } + + public String getTargetXmlnsNamespace() { + return targetXmlnsNamespace; + } + + public void setTargetXmlnsNamespace(String targetXmlnsNamespace) { + this.targetXmlnsNamespace = targetXmlnsNamespace; + } + + public String getApiPrefix() { + return apiPrefix; + } + private void addRestSupportingFiles(final String citrusFolder, String schemaFolder) { supportingFiles.add(new SupportingFile("schema.mustache", schemaFolder, apiPrefix.toLowerCase() + "-api.xsd")); supportingFiles.add(new SupportingFile("test_base.mustache", citrusFolder, apiPrefix + ABSTRACT_TEST_REQUEST_JAVA)); @@ -291,4 +341,5 @@ private void addDefaultSupportingFiles(final String citrusFolder, final String e supportingFiles.add(new SupportingFile("namespace_handler.mustache", extensionFolder, apiPrefix + "NamespaceHandler.java")); supportingFiles.add(new SupportingFile("api-model.mustache", resourceFolder, apiPrefix.toLowerCase() + "-api-model.csv")); } + } diff --git a/test-api-generator/citrus-test-api-generator-core/src/main/java/org/citrusframework/openapi/generator/SimpleWsdlToOpenApiTransformer.java b/test-api-generator/citrus-test-api-generator-core/src/main/java/org/citrusframework/openapi/generator/SimpleWsdlToOpenApiTransformer.java index 8243be5aa8..fef2086994 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/main/java/org/citrusframework/openapi/generator/SimpleWsdlToOpenApiTransformer.java +++ b/test-api-generator/citrus-test-api-generator-core/src/main/java/org/citrusframework/openapi/generator/SimpleWsdlToOpenApiTransformer.java @@ -86,6 +86,9 @@ public String transformToOpenApi() throws WsdlToOpenApiTransformationException { /** * Performs the actual transformation from bindings into OpenApi operations. + * + * @param bindings + * @return */ private OpenAPI transformToOpenApi(Map bindings) { OpenAPI openAPI = new OpenAPI(); diff --git a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/api.mustache b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/api.mustache index a023345fb7..9ab227ab6b 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/api.mustache +++ b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/api.mustache @@ -2,6 +2,7 @@ package {{package}}; +import jakarta.annotation.Generated; import org.citrusframework.testapi.GeneratedApi; import org.citrusframework.testapi.GeneratedApiRequest; import jakarta.servlet.http.Cookie; diff --git a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/model.mustache b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/model.mustache new file mode 100644 index 0000000000..d5341fea2c --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/model.mustache @@ -0,0 +1 @@ +// not in use diff --git a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/model_doc.mustache b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/model_doc.mustache new file mode 100644 index 0000000000..f8737ed4d9 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/model_doc.mustache @@ -0,0 +1 @@ +# not in use diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/GetPetByIdTest.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/GetPetByIdTest.java new file mode 100644 index 0000000000..6421cee946 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/GetPetByIdTest.java @@ -0,0 +1,254 @@ +package org.citrusframework.openapi.generator; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.citrusframework.container.Assert.Builder.assertException; +import static org.citrusframework.util.FileUtils.readToString; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Map; +import org.citrusframework.TestCaseRunner; +import org.citrusframework.annotations.CitrusResource; +import org.citrusframework.annotations.CitrusTest; +import org.citrusframework.config.CitrusSpringConfig; +import org.citrusframework.context.TestContext; +import org.citrusframework.endpoint.EndpointConfiguration; +import org.citrusframework.http.client.HttpClient; +import org.citrusframework.http.client.HttpEndpointConfiguration; +import org.citrusframework.junit.jupiter.spring.CitrusSpringExtension; +import org.citrusframework.message.DefaultMessage; +import org.citrusframework.message.Message; +import org.citrusframework.messaging.Producer; +import org.citrusframework.messaging.SelectiveConsumer; +import org.citrusframework.openapi.generator.GetPetByIdTest.Config; +import org.citrusframework.openapi.generator.rest.petstore.request.PetApi.GetPetByIdRequest; +import org.citrusframework.openapi.generator.rest.petstore.spring.PetStoreBeanConfiguration; +import org.citrusframework.spi.Resources; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.http.HttpStatus; + +@ExtendWith(CitrusSpringExtension.class) +@SpringBootTest(classes = {PetStoreBeanConfiguration.class, CitrusSpringConfig.class, Config.class}) +class GetPetByIdTest { + + @Autowired + private GetPetByIdRequest getPetByIdRequest; + + @Autowired + @Qualifier("petStoreEndpoint") + private HttpClient httpClient; + + private String defaultResponse; + + @BeforeEach + public void beforeTest() throws IOException { + defaultResponse = readToString(Resources.create( + "org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetByIdControlMessage1.json"), + StandardCharsets.UTF_8) ; + + mockProducer(); + mockConsumer(); + } + + /** + * TODO #1161 - Improve with builder pattern + */ + @Test + @CitrusTest + void testByJsonPath(@CitrusResource TestCaseRunner runner) { + + // Given + getPetByIdRequest.setPetId("1234"); + + // Then + getPetByIdRequest.setResponseStatus(HttpStatus.OK.value()); + getPetByIdRequest.setResponseReasonPhrase(HttpStatus.OK.getReasonPhrase()); + + // Assert body by json path + getPetByIdRequest.setResponseValue(Map.of("$.name", "Snoopy")); + + // When + runner.$(getPetByIdRequest); + } + + /** + * TODO #1161 - Improve with builder pattern + */ + @Test + @CitrusTest + void testValidationFailureByJsonPath(@CitrusResource TestCaseRunner runner) { + + // Given + getPetByIdRequest.setPetId("1234"); + + // Then + getPetByIdRequest.setResponseStatus(HttpStatus.OK.value()); + getPetByIdRequest.setResponseReasonPhrase(HttpStatus.OK.getReasonPhrase()); + + // Assert body by json path + getPetByIdRequest.setResponseValue(Map.of("$.name", "Garfield")); + + // When + runner.$(assertException() + .exception(org.citrusframework.exceptions.CitrusRuntimeException.class) + .message("Values not equal for element '$.name', expected 'Garfield' but was 'Snoopy'") + .when( + getPetByIdRequest + ) + ); + // When + + } + + /** + * TODO #1161 - Improve with builder pattern + */ + @Test + @CitrusTest + void testByResource(@CitrusResource TestCaseRunner runner) { + + // Given + getPetByIdRequest.setPetId("1234"); + + // Then + getPetByIdRequest.setResponseStatus(HttpStatus.OK.value()); + getPetByIdRequest.setResponseReasonPhrase(HttpStatus.OK.getReasonPhrase()); + // Assert body by resource + getPetByIdRequest.setResource( + "org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetByIdControlMessage1.json"); + + // When + runner.$(getPetByIdRequest); + } + + /** + * TODO #1161 - Improve with builder pattern + */ + @Test + @CitrusTest + void testValidationFailureByResource(@CitrusResource TestCaseRunner runner) { + + // Given + getPetByIdRequest.setPetId("1234"); + + // Then + getPetByIdRequest.setResponseStatus(HttpStatus.OK.value()); + getPetByIdRequest.setResponseReasonPhrase(HttpStatus.OK.getReasonPhrase()); + // Assert body by resource + getPetByIdRequest.setResource( + "org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetByIdControlMessage2.json"); + + // When + runner.$(assertException() + .exception(org.citrusframework.exceptions.CitrusRuntimeException.class) + .message("Values not equal for entry: '$['name']', expected 'Garfield' but was 'Snoopy'") + .when( + getPetByIdRequest + ) + ); + } + + /** + * TODO #1161 - Improve with builder pattern + */ + @Test + @CitrusTest + void validateByVariable(@CitrusResource TestContext testContext, + @CitrusResource TestCaseRunner runner) { + + // Given + getPetByIdRequest.setPetId("1234"); + + // Then + getPetByIdRequest.setResponseStatus(HttpStatus.OK.value()); + getPetByIdRequest.setResponseReasonPhrase(HttpStatus.OK.getReasonPhrase()); + + // Assert load data into variables + getPetByIdRequest.setResponseVariable(Map.of("$", "RESPONSE", "$.id", "ID")); + + // When + runner.$(getPetByIdRequest); + + // Then + assertThat(testContext) + .satisfies( + c -> assertThat(c.getVariable("RESPONSE")) + .isNotNull(), + c -> assertThat(c.getVariable("ID")) + .isNotNull() + .isEqualTo("12") + ); + } + + /** + * TODO #1161 - Improve with builder pattern + */ + @Test + @CitrusTest + void validateReceivedResponse(@CitrusResource TestContext testContext) { + + // Given + getPetByIdRequest.setPetId("1234"); + + // When + getPetByIdRequest.sendRequest(testContext); + + // Then + Message receiveResponse = getPetByIdRequest.receiveResponse(testContext); + assertThat(receiveResponse) + .isNotNull() + .extracting(Message::getPayload) + .asString() + .isEqualToIgnoringWhitespace(defaultResponse); + assertThat(receiveResponse.getHeaders()) + .containsEntry("citrus_http_status_code", 200) + .containsEntry("citrus_http_reason_phrase", "OK"); + } + + private void mockProducer() { + Producer producerMock = mock(); + when(httpClient.createProducer()).thenReturn(producerMock); + } + + private void mockConsumer() { + Message receiveMessage = createReceiveMessage(); + + SelectiveConsumer consumer = mock(SelectiveConsumer.class); + when(httpClient.createConsumer()).thenReturn(consumer); + when(consumer.receive(any(), eq(5000L))).thenReturn(receiveMessage); + } + + private Message createReceiveMessage() { + Message receiveMessage = new DefaultMessage(); + receiveMessage.setPayload(defaultResponse); + receiveMessage.getHeaders().put("citrus_http_reason_phrase", "OK"); + receiveMessage.getHeaders().put("citrus_http_version", "HTTP/1.1"); + receiveMessage.getHeaders().put("Content-Type", 200); + receiveMessage.getHeaders().put("citrus_http_status_code", 200); + return receiveMessage; + } + + @TestConfiguration + public static class Config { + + @Bean(name = {"applicationServiceClient", "petStoreEndpoint"}) + public HttpClient applicationServiceClient() { + HttpClient client = mock(HttpClient.class); + EndpointConfiguration endpointConfiguration = mock(EndpointConfiguration.class); + when(client.getEndpointConfiguration()).thenReturn(new HttpEndpointConfiguration()); + when(endpointConfiguration.getTimeout()).thenReturn(5000L); + return client; + } + } +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/JavaCitrusCodegenIT.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/JavaCitrusCodegenIT.java index 1d205f9400..2c8f88d331 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/JavaCitrusCodegenIT.java +++ b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/JavaCitrusCodegenIT.java @@ -11,6 +11,7 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.util.List; import java.util.stream.Stream; import org.apache.commons.lang3.stream.Streams; import org.citrusframework.exceptions.CitrusRuntimeException; @@ -85,8 +86,6 @@ void testGeneratedSoapFiles(Resource resource) throws IOException { File classFile = resource.getFile(); String absolutePath = classFile.getAbsolutePath(); - String javaFilePath = absolutePath - .replace("test-classes", "generated-test-sources") .replace(".class", ".java"); assertFileContent(new File(javaFilePath), "soap"); @@ -94,39 +93,29 @@ void testGeneratedSoapFiles(Resource resource) throws IOException { private static Stream geClassResourcesIgnoringInnerClasses(String path) throws IOException { - return Streams.of( - new PathMatchingResourcePatternResolver().getResources(path + "/**/*.class")) - .filter(resource -> { - try { - return !resource.getURI().toString().contains("$"); - } catch (Exception e) { - throw new CitrusRuntimeException("Unable to retrieve URL from resource!"); - } - } - ).map(Arguments::arguments); + return Streams.of(new PathMatchingResourcePatternResolver().getResources( + path + "/**/*.class")).filter(resource -> { + try { + return !resource.getURI().toString().contains("$"); + } catch (Exception e) { + throw new CitrusRuntimeException("Unable to retrieve URL from resource!"); + } + }).map(Arguments::arguments); } - /* - * NOTE: when changes have been performed to mustache templates, the expected files need to be updated. - * Be aware that file content may change according to IDE formatting rules if the files are copied via IDE. - * Files should therefore be copied using a file explorer which ensures that content of files does not change. - */ private void assertFileContent(File file, String apiDir) throws IOException { assertThat(file).exists(); + String expectedFilePath = + "org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/" + + file.getAbsolutePath().substring(file.getAbsolutePath().indexOf(apiDir)); - String expectedFilePath = BASE_PACKAGE + "/JavaCitrusCodegenIT/expectedgen/" + file.getAbsolutePath().substring(file.getAbsolutePath().indexOf(apiDir)); ClassPathResource classPathResource = new ClassPathResource(expectedFilePath); - String actualContent = readString(file.toPath()); - String expectedContent = readString(classPathResource.getFile().toPath()); - - // Replace "Generated" with a placeholder - String generatedAnnotationPattern = "@jakarta\\.annotation\\.Generated\\(.*?\\)"; - String placeholder = "@jakarta.annotation.Generated(value = \"org.citrusframework.openapi.generator.JavaCitrusCodegen\", date = \"TIMESTAMP\", comments = \"Generator version: VERSION\")"; - - actualContent = actualContent.replaceAll(generatedAnnotationPattern, placeholder); - expectedContent = expectedContent.replaceAll(generatedAnnotationPattern, placeholder); - - assertThat(actualContent).isEqualTo(expectedContent); + /* + * NOTE: when changes have been performed to mustache templates, the expected files need to be updated. + * Be aware that file content may change according to IDE formatting rules if the files are copied via IDE. + * Files should therefore be copied using a file explorer which ensures that content of files does not change. + */ + assertThat(file).hasSameTextualContentAs(classPathResource.getFile()); } } diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/JavaCitrusCodegenTest.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/JavaCitrusCodegenTest.java index f3860de3b4..e6c91baa06 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/JavaCitrusCodegenTest.java +++ b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/JavaCitrusCodegenTest.java @@ -196,11 +196,9 @@ void areBasicAuthFieldsPresent() throws IOException { List lines = Files.readAllLines(file.get().toPath(), StandardCharsets.UTF_8); // "name" is a reserved word, so it should be escaped with an underline for the second parameter - assertThat( - lines.stream() - .filter(x -> x.contains("@Value(\"${\" + \"apiEndpoint.basic.username:#{null}}\")")) - .count()) - .isEqualTo(1L); + assertThat(lines.stream() + .filter(x -> x.contains("@Value(\"${\" + \"apiEndpoint.basic.username:#{null}}\")")) + .count()).isEqualTo(1L); assertThat( lines.stream() .filter(x -> x.contains("private String basicUsername;")) diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/ServiceLoaderTest.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/ServiceLoaderTest.java index 419cea9ade..274ff8c9d9 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/ServiceLoaderTest.java +++ b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/ServiceLoaderTest.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.ServiceLoader; import java.util.ServiceLoader.Provider; +import org.citrusframework.testapi.ApiActionBuilderCustomizerService; import org.citrusframework.openapi.generator.util.TestApiActionBuilderCustomizer; import org.citrusframework.testapi.ApiActionBuilderCustomizerService; import org.junit.jupiter.api.Test; diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/SpringBeanConfigurationIT.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/SpringBeanConfigurationIT.java index 15dfb85dc3..3da000e800 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/SpringBeanConfigurationIT.java +++ b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/SpringBeanConfigurationIT.java @@ -13,6 +13,7 @@ import org.citrusframework.openapi.generator.rest.petstore.request.PetApi.AddPetRequest; import org.citrusframework.openapi.generator.rest.petstore.spring.PetStoreBeanConfiguration; import org.junit.jupiter.api.Test; +import org.citrusframework.openapi.generator.SpringBeanConfigurationIT.ClientConfiguration; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.ApplicationContext; diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/util/TestApiActionBuilderCustomizer.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/util/TestApiActionBuilderCustomizer.java index 1b0b8824a7..0aaa9761ab 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/util/TestApiActionBuilderCustomizer.java +++ b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/util/TestApiActionBuilderCustomizer.java @@ -1,6 +1,7 @@ package org.citrusframework.openapi.generator.util; import org.citrusframework.TestAction; +import org.citrusframework.TestActionBuilder; import org.citrusframework.actions.SendMessageAction.SendMessageActionBuilder; import org.citrusframework.context.TestContext; import org.citrusframework.testapi.ApiActionBuilderCustomizerService; diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/citrus/MultipartTestAbstractTestRequest.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/citrus/MultipartTestAbstractTestRequest.java new file mode 100644 index 0000000000..d35d8934bf --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/citrus/MultipartTestAbstractTestRequest.java @@ -0,0 +1,245 @@ +/** + * ================================================== + * GENERATED CLASS, ALL CHANGES WILL BE LOST + * ================================================== + */ + +package org.citrusframework.openapi.generator.rest.multiparttest.citrus; + + +import static org.springframework.util.CollectionUtils.isEmpty; + +import jakarta.annotation.Generated; +import jakarta.annotation.Nullable; +import java.util.List; +import java.util.Map; +import java.util.ServiceLoader; +import javax.sql.DataSource; +import org.citrusframework.actions.AbstractTestAction; +import org.citrusframework.actions.ReceiveMessageAction; +import org.citrusframework.context.TestContext; +import org.citrusframework.http.actions.HttpActionBuilder; +import org.citrusframework.http.actions.HttpClientRequestActionBuilder; +import org.citrusframework.http.actions.HttpClientResponseActionBuilder; +import org.citrusframework.http.actions.HttpClientResponseActionBuilder.HttpMessageBuilderSupport; +import org.citrusframework.http.client.HttpClient; +import org.citrusframework.message.Message; +import org.citrusframework.testapi.ApiActionBuilderCustomizerService; +import org.citrusframework.testapi.GeneratedApi; +import org.citrusframework.spi.Resources; +import org.citrusframework.validation.DelegatingPayloadVariableExtractor; +import org.citrusframework.validation.PathExpressionValidationContext; +import org.citrusframework.validation.json.JsonMessageValidationContext; +import org.citrusframework.validation.script.ScriptValidationContext; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +@Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen") +public abstract class MultipartTestAbstractTestRequest extends AbstractTestAction { + + protected final Marker coverageMarker = MarkerFactory.getMarker("MULTIPARTTEST-API-COVERAGE"); + + @Autowired + @Qualifier("multipartTestEndpoint") + protected HttpClient httpClient; + + @Autowired(required = false) + protected DataSource dataSource; + + @Autowired(required = false) + private List actionBuilderCustomizerServices; + + // attributes of differentNodes + protected boolean schemaValidation; + protected String schema; + protected String bodyContentType; + protected String bodyLiteralContentType; + protected String bodyFile; + protected String bodyLiteral; + protected String responseAcceptType = "*/*"; + protected String responseType = "json"; + protected int responseStatus = 200; + protected String responseReasonPhrase = "OK"; + protected String responseVersion = "HTTP/1.1"; + + // children of response element + protected String resource; + protected Map responseVariable; // Contains the 'JSON-PATH' as key and the 'VARIABLE NAME' as value + protected Map responseValue; // Contains the 'JSON-PATH' as key and the 'VALUE TO BE VALIDATED' as value + protected Map cookies; + protected Map headers; + protected String script; + protected String type; // default script type is groovy - supported types see com.consol.citrus.script.ScriptTypes + + @Override + public void doExecute(TestContext context) { + sendRequest(context); + recieveResponse(context); + } + + /** + * This method receives the HTTP-Response. + * + * @deprecated use {@link MultipartTestAbstractTestRequest#receiveResponse(TestContext)} instead. + */ + public ReceiveMessageAction recieveResponse(TestContext context) { + + HttpClientResponseActionBuilder httpClientResponseActionBuilder = new HttpActionBuilder().client(httpClient).receive().response(); + HttpMessageBuilderSupport messageBuilderSupport = httpClientResponseActionBuilder.getMessageBuilderSupport(); + + messageBuilderSupport + .statusCode(responseStatus) + .reasonPhrase(responseReasonPhrase) + .version(responseVersion) + .validate(new JsonMessageValidationContext.Builder().schemaValidation(schemaValidation).schema(schema)); + + if (resource != null) { + messageBuilderSupport.body(Resources.create(resource)); + } + + if (!isEmpty(responseVariable)) { + DelegatingPayloadVariableExtractor.Builder extractorBuilder = new DelegatingPayloadVariableExtractor.Builder(); + responseVariable.forEach(extractorBuilder::expression); + messageBuilderSupport.extract(extractorBuilder); + } + + if (!isEmpty(responseValue)) { + PathExpressionValidationContext.Builder validationContextBuilder = new PathExpressionValidationContext.Builder(); + responseValue.forEach(validationContextBuilder::expression); + messageBuilderSupport.validate(validationContextBuilder); + } + + if (script != null) { + ScriptValidationContext.Builder scriptValidationContextBuilder = new ScriptValidationContext.Builder(); + if (type != null) { + scriptValidationContextBuilder.scriptType(type); + } + scriptValidationContextBuilder.script(script); + messageBuilderSupport.validate(scriptValidationContextBuilder); + } + + messageBuilderSupport.type(responseType); + httpClientResponseActionBuilder.withReferenceResolver(context.getReferenceResolver()); + var responseAction = httpClientResponseActionBuilder.build(); + + responseAction.execute(context); + + return responseAction; + } + + public @Nullable Message receiveResponse(TestContext context) { + var responseAction = recieveResponse(context); + + var messageStore = context.getMessageStore(); + return messageStore.getMessage(messageStore.constructMessageName(responseAction, httpClient)); + } + + public abstract void sendRequest(TestContext context); + + public void setSchemaValidation(boolean schemaValidation) { + this.schemaValidation = schemaValidation; + } + + public void setSchema(String schema) { + this.schema = schema; + } + + public void setBodyLiteral(String bodyLiteral) { + this.bodyLiteral = bodyLiteral; + } + + public void setBodyContentType(String bodyContentType) { + this.bodyContentType = bodyContentType; + } + + public void setBodyLiteralContentType(String bodyLiteralContentType) { + this.bodyLiteralContentType = bodyLiteralContentType; + } + + public void setResponseAcceptType(String responseAcceptType) { + this.responseAcceptType = responseAcceptType; + } + + public void setCookie(Map cookies) { + this.cookies = cookies; + } + + public void setHeader(Map headers) { + this.headers = headers; + } + + public void setBodyFile(String bodyFile) { + this.bodyFile = bodyFile; + } + + public void setResponseType(String responseType) { + this.responseType = responseType; + } + + public void setResponseStatus(int responseStatus) { + this.responseStatus = responseStatus; + } + + public void setResponseReasonPhrase(String responseReasonPhrase) { + this.responseReasonPhrase = responseReasonPhrase; + } + + public void setResponseVersion(String responseVersion) { + this.responseVersion = responseVersion; + } + + public void setResource(String resource) { + this.resource = resource; + } + + public void setResponseVariable(Map responseVariable) { + this.responseVariable = responseVariable; + } + + public void setResponseValue(Map responseValue) { + this.responseValue = responseValue; + } + + public void setScript(String script) { + this.script = script; + } + + public void setType(String type) { + this.type = type; + } + + protected HttpClientRequestActionBuilder customizeBuilder(GeneratedApi generatedApi, + TestContext context, HttpClientRequestActionBuilder httpClientRequestActionBuilder) { + + httpClientRequestActionBuilder = customizeByBeans(generatedApi, context, + httpClientRequestActionBuilder); + + httpClientRequestActionBuilder = customizeBySpi(generatedApi, context, httpClientRequestActionBuilder); + + return httpClientRequestActionBuilder; + } + + private HttpClientRequestActionBuilder customizeBySpi(GeneratedApi generatedApi, TestContext context, + HttpClientRequestActionBuilder httpClientRequestActionBuilder) { + ServiceLoader serviceLoader = ServiceLoader.load( + ApiActionBuilderCustomizerService.class, ApiActionBuilderCustomizerService.class.getClassLoader()); + for (ApiActionBuilderCustomizerService service :serviceLoader) { + httpClientRequestActionBuilder = service.build(generatedApi, this, context, httpClientRequestActionBuilder); + } + return httpClientRequestActionBuilder; + } + + private HttpClientRequestActionBuilder customizeByBeans( + GeneratedApi generatedApi, TestContext context, + HttpClientRequestActionBuilder httpClientRequestActionBuilder) { + if (actionBuilderCustomizerServices != null) { + for (ApiActionBuilderCustomizerService apiActionBuilderCustomizer : actionBuilderCustomizerServices) { + httpClientRequestActionBuilder = apiActionBuilderCustomizer.build(generatedApi, this, + context, httpClientRequestActionBuilder); + } + } + return httpClientRequestActionBuilder; + } +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/citrus/MultipartTestBeanDefinitionParser.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/citrus/MultipartTestBeanDefinitionParser.java new file mode 100644 index 0000000000..d9730d0d42 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/citrus/MultipartTestBeanDefinitionParser.java @@ -0,0 +1,215 @@ +/** + * ================================================== + * GENERATED CLASS, ALL CHANGES WILL BE LOST + * ================================================== + */ + +package org.citrusframework.openapi.generator.rest.multiparttest.citrus; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.annotation.processing.Generated; + +import org.citrusframework.exceptions.CitrusRuntimeException; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.core.Conventions; +import org.springframework.util.Assert; +import org.apache.commons.lang3.StringUtils; +import org.springframework.util.xml.DomUtils; +import org.w3c.dom.Attr; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; + + +@Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen") +public class MultipartTestBeanDefinitionParser implements BeanDefinitionParser { + + private static final String COOKIE = "cookie"; + private static final String HEADER = "header"; + private static final String SOAP_HEADER = "soapHeader"; + private static final String MIME_HEADER = "mimeHeader"; + private static final String NAME = "name"; + private static final String REQUEST_BODY = "body"; + private static final String REQUEST_BODY_LITERAL = "bodyLiteral"; + private static final String MULTIPART_BODY = "multipartBody"; + private static final String RESPONSE = "response"; + private static final String RESPONSE_JSONPATH = "json-path"; + private static final String RESPONSE_XPATH = "xpath"; + private static final String EXPRESSION = "expression"; + private static final String VALUE = "value"; + private static final String RESPONSE_RESOURCE = "resource"; + private static final String FILE = "file"; + private static final String RESPONSE_VARIABLE = "responseVariable"; + private static final String RESPONSE_VALUE = "responseValue"; + private static final String SCRIPT = "script"; + private static final String TYPE = "type"; + private static final String SQL = "sql"; + private static final String COLUMN = "column"; + private static final String VARIABLE = "variable"; + // new + private static final String SCHEMA = "schema"; + // new + private static final String SCHEMA_VALIDATION = "schemaValidation"; + + private final Class beanClass; + + public MultipartTestBeanDefinitionParser(Class beanClass) { + this.beanClass = beanClass; + } + + public BeanDefinition parse(Element element) { + return parse(element, null); + } + + /** + * Note: The {@link MultipartTestBeanDefinitionParser#parse(Element element)} allows access direct + * access without the {@link org.springframework.beans.factory.xml.ParserContext} for convenience. + */ + @Override + public BeanDefinition parse(Element element, ParserContext parserContext) { + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(beanClass); + retrieveRootNodeAttributes(element, builder); + retrieveOptionalNodeAttributes(element, REQUEST_BODY, builder); + retrieveTextContentAndNodeAttributes(element, REQUEST_BODY_LITERAL, builder); + retrieveOptionalNodeAttributes(element, RESPONSE, builder); + retrieveParamNodeData(element, builder, COOKIE); + retrieveParamNodeData(element, builder, HEADER); + retrieveParamNodeData(element, builder, SOAP_HEADER); + retrieveParamNodeData(element, builder, MIME_HEADER); + retrieveOptionalNodeAttributes(element, SCHEMA, builder); + retrieveOptionalNodeAttributes(element, SCHEMA_VALIDATION, builder); + retrieveOptionalMultipartElements(element, builder); + retrieveResponseNodeData(element, builder); + builder.addPropertyValue("name", element.getTagName()); + return builder.getBeanDefinition(); + } + + private void retrieveOptionalMultipartElements(Element element, BeanDefinitionBuilder builder) { + var multipartBodyElement = DomUtils.getChildElementByTagName(element, MULTIPART_BODY); + if (multipartBodyElement != null) { + var multipartBodyChildElements = DomUtils.getChildElements(multipartBodyElement); + for(int i = 0; i < multipartBodyChildElements.size(); i++){ + var multipartBodyChildElement = multipartBodyChildElements.get(i); + String propertyName = Conventions.attributeNameToPropertyName(multipartBodyChildElement.getLocalName()); + builder.addPropertyValue(propertyName, multipartBodyChildElement.getTextContent()); + } + } + } + + private void retrieveRootNodeAttributes(Element element, BeanDefinitionBuilder builder) { + NamedNodeMap attributes = element.getAttributes(); + for (int x = 0; x < attributes.getLength(); x++) { + Attr attribute = (Attr) attributes.item(x); + String propertyName = Conventions.attributeNameToPropertyName(attribute.getLocalName()); + Assert.state(StringUtils.isNotBlank(propertyName), "Illegal property name returned, it must not be null or empty."); + builder.addPropertyValue(propertyName, attribute.getValue()); + } + } + + private void retrieveOptionalNodeAttributes(Element element, String elementName, BeanDefinitionBuilder builder) { + if (!DomUtils.getChildElementsByTagName(element, elementName).isEmpty()) { + Element el = DomUtils.getChildElementsByTagName(element, elementName).get(0); + NamedNodeMap attributes = el.getAttributes(); + for (int x = 0; x < attributes.getLength(); x++) { + Attr attribute = (Attr) attributes.item(x); + String propertyName = Conventions.attributeNameToPropertyName(attribute.getLocalName()); + Assert.state(StringUtils.isNotBlank(propertyName), "Illegal property name returned, it must not be null or empty."); + String variableName = el.getLocalName() + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1); + builder.addPropertyValue(variableName, attribute.getValue()); + } + } + } + + private void retrieveTextContentAndNodeAttributes(Element element, String elementName, BeanDefinitionBuilder builder) { + if (!DomUtils.getChildElementsByTagName(element, elementName).isEmpty()) { + Element el1 = DomUtils.getChildElementsByTagName(element, elementName).get(0); + NamedNodeMap attributes = el1.getAttributes(); + for (int x = 0; x < attributes.getLength(); x++) { + Attr attribute = (Attr) attributes.item(x); + String propertyName1 = Conventions.attributeNameToPropertyName(attribute.getLocalName()); + Assert.state(StringUtils.isNotBlank(propertyName1), "Illegal property name returned, it must not be null or empty."); + String variableName = el1.getLocalName() + propertyName1.substring(0, 1).toUpperCase() + propertyName1.substring(1); + builder.addPropertyValue(variableName, attribute.getValue()); + } + Element el = DomUtils.getChildElementsByTagName(element, elementName).get(0); + builder.addPropertyValue(elementName, el.getTextContent()); + } + } + + private void retrieveParamNodeData(Element element, BeanDefinitionBuilder builder, String paramType) { + if (!DomUtils.getChildElementsByTagName(element, paramType).isEmpty()) { + Map params = new HashMap<>(); + List elements = DomUtils.getChildElementsByTagName(element, paramType); + elements.forEach(e -> { + String name = e.getAttribute(NAME); + String value = e.getAttribute(VALUE); + + Assert.state(StringUtils.isNotBlank(name), "Illegal attribute value returned. The 'name' attribute must not be null or empty."); + Assert.state(StringUtils.isNotBlank(value), "Illegal attribute value returned. The 'value' attribute must not be null or empty."); + + params.put(name, value); + }); + builder.addPropertyValue(paramType, params); + } + } + + private void retrieveResponseNodeData(Element element, BeanDefinitionBuilder builder) { + + if (!DomUtils.getChildElementsByTagName(element, RESPONSE).isEmpty()) { + Element response = DomUtils.getChildElementsByTagName(element, RESPONSE).get(0); + List elements = DomUtils.getChildElements(response); + + Map responseVariable = new HashMap<>(); + Map responseValue = new HashMap<>(); + + for (int i = 0; i < elements.size(); i++) { + Element e = elements.get(i); + + if (e.getTagName().contains(RESPONSE_JSONPATH) || e.getTagName().contains(RESPONSE_XPATH)) { + String expression = e.getAttribute(EXPRESSION); + String value = e.getAttribute(VALUE); + + Assert.state(StringUtils.isNotBlank(expression), "Illegal attribute value returned. The 'expression' attribute must not be null or empty."); + Assert.state(StringUtils.isNotBlank(value), "Illegal attribute value returned. The 'value' attribute must not be null or empty."); + + // variable to save @variable('ebid')@ else value to validate + if (value.matches("\\@variable\\('.*'\\)\\@")) { + Matcher match = Pattern.compile("\\'(.*?)\\'").matcher(value); + if (match.find()) { + responseVariable.put(expression, value.substring(match.start() + 1, match.end() - 1)); + } + } else { + responseValue.put(expression, value); + } + } else if (e.getTagName().contains(SCRIPT)) { + String script = e.getTextContent(); + Assert.state(StringUtils.isNotBlank(script), "Illegal attribute value returned. The 'script' attribute must not be null or empty."); + builder.addPropertyValue(SCRIPT, script); + + if (!e.getAttribute(TYPE).isEmpty()) { + String type = e.getAttribute(TYPE); + Assert.state(StringUtils.isNotBlank(type), "Illegal attribute value returned. The 'type' attribute must not be null or empty."); + builder.addPropertyValue(TYPE, type); + } + } else if (e.getTagName().contains(RESPONSE_RESOURCE)) { + String filePath = e.getAttribute(FILE); + Assert.state(StringUtils.isNotBlank(filePath), "Illegal attribute value returned. The 'file' attribute must not be null or empty."); + builder.addPropertyValue(RESPONSE_RESOURCE, filePath); + } + + } + + builder.addPropertyValue(RESPONSE_VARIABLE, responseVariable); + builder.addPropertyValue(RESPONSE_VALUE, responseValue); + } + } +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/citrus/extension/MultipartTestNamespaceHandler.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/citrus/extension/MultipartTestNamespaceHandler.java new file mode 100644 index 0000000000..0d81b2d521 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/citrus/extension/MultipartTestNamespaceHandler.java @@ -0,0 +1,29 @@ +/** + * ================================================== + * GENERATED CLASS, ALL CHANGES WILL BE LOST + * ================================================== + */ + +package org.citrusframework.openapi.generator.rest.multiparttest.citrus.extension; + +import org.citrusframework.openapi.generator.rest.multiparttest.request.MultiparttestControllerApi; +import org.citrusframework.openapi.generator.rest.multiparttest.citrus.MultipartTestBeanDefinitionParser; + +import javax.annotation.processing.Generated; + +import org.springframework.beans.factory.xml.NamespaceHandlerSupport; + + +@Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen") +public class MultipartTestNamespaceHandler extends NamespaceHandlerSupport { + + @Override + public void init() { + registerBeanDefinitionParser("deleteObjectRequest", new MultipartTestBeanDefinitionParser(MultiparttestControllerApi.DeleteObjectRequest.class)); + registerBeanDefinitionParser("fileExistsRequest", new MultipartTestBeanDefinitionParser(MultiparttestControllerApi.FileExistsRequest.class)); + registerBeanDefinitionParser("generateReportRequest", new MultipartTestBeanDefinitionParser(MultiparttestControllerApi.GenerateReportRequest.class)); + registerBeanDefinitionParser("multipleDatatypesRequest", new MultipartTestBeanDefinitionParser(MultiparttestControllerApi.MultipleDatatypesRequest.class)); + registerBeanDefinitionParser("postFileRequest", new MultipartTestBeanDefinitionParser(MultiparttestControllerApi.PostFileRequest.class)); + registerBeanDefinitionParser("postRandomRequest", new MultipartTestBeanDefinitionParser(MultiparttestControllerApi.PostRandomRequest.class)); + } +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/model/Metadata.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/model/Metadata.java new file mode 100644 index 0000000000..d5341fea2c --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/model/Metadata.java @@ -0,0 +1 @@ +// not in use diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/model/PutObjectResult.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/model/PutObjectResult.java new file mode 100644 index 0000000000..d5341fea2c --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/model/PutObjectResult.java @@ -0,0 +1 @@ +// not in use diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/request/MultiparttestControllerApi.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/request/MultiparttestControllerApi.java new file mode 100644 index 0000000000..36d2bca5f4 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/request/MultiparttestControllerApi.java @@ -0,0 +1,750 @@ +/** + * ================================================== + * GENERATED CLASS, ALL CHANGES WILL BE LOST + * ================================================== + */ + +package org.citrusframework.openapi.generator.rest.multiparttest.request; + +import jakarta.annotation.Generated; +import org.citrusframework.testapi.GeneratedApi; +import org.citrusframework.testapi.GeneratedApiRequest; +import jakarta.servlet.http.Cookie; +import org.apache.commons.lang3.StringUtils; +import org.citrusframework.context.TestContext; +import org.citrusframework.exceptions.CitrusRuntimeException; +import org.citrusframework.spi.Resources; +import org.citrusframework.http.actions.HttpActionBuilder; +import org.citrusframework.http.actions.HttpClientRequestActionBuilder; +import org.citrusframework.http.actions.HttpClientRequestActionBuilder.HttpMessageBuilderSupport; +import org.citrusframework.util.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.MediaType; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import org.citrusframework.openapi.generator.rest.multiparttest.citrus.MultipartTestAbstractTestRequest; + +import java.io.IOException; +import java.util.Base64; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + + +@Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen") +public class MultiparttestControllerApi implements GeneratedApi +{ + + public static final MultiparttestControllerApi INSTANCE = new MultiparttestControllerApi(); + + public String getApiTitle() { + return "multiparttest API"; + } + + public String getApiVersion() { + return "2.0.0"; + } + + public String getApiPrefix() { + return "MultipartTest"; + } + + public Map getApiInfoExtensions() { + Map infoExtensionMap = new HashMap<>(); + infoExtensionMap.put("x-citrus-api-name", "multiparttest-rest-resource"); + infoExtensionMap.put("x-citrus-app", "MPT"); + return infoExtensionMap; + } + + /** deleteObject (DELETE /api/v2/multitest-file/{bucket}/{filename}) + Delete file. + + **/ + public static class DeleteObjectRequest extends MultipartTestAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/api/v2/multitest-file/{bucket}/{filename}"; + private final Logger coverageLogger = LoggerFactory.getLogger(DeleteObjectRequest.class); + + private String bucket; + + private String filename; + + + public DeleteObjectRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("MultipartTest".toLowerCase() + ":deleteObjectRequestType"); + } + + public String getOperationName() { + return "deleteObject"; + } + + public String getMethod() { + return "DELETE"; + } + + public String getPath() { + return "/api/v2/multitest-file/{bucket}/{filename}"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .delete(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "deleteObject;DELETE;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + public void setBucket(String bucket) { + this.bucket = bucket; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + private String replacePathParams(String endpoint) { + endpoint = endpoint.replace("{" + "bucket" + "}", bucket);endpoint = endpoint.replace("{" + "filename" + "}", filename); + return endpoint; + } + } + /** fileExists (GET /api/v2/multitest-file/{bucket}/{filename}/exists) + Checks if file exist. + + **/ + public static class FileExistsRequest extends MultipartTestAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/api/v2/multitest-file/{bucket}/{filename}/exists"; + private final Logger coverageLogger = LoggerFactory.getLogger(FileExistsRequest.class); + + private String bucket; + + private String filename; + + + public FileExistsRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("MultipartTest".toLowerCase() + ":fileExistsRequestType"); + } + + public String getOperationName() { + return "fileExists"; + } + + public String getMethod() { + return "GET"; + } + + public String getPath() { + return "/api/v2/multitest-file/{bucket}/{filename}/exists"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .get(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "fileExists;GET;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + public void setBucket(String bucket) { + this.bucket = bucket; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + private String replacePathParams(String endpoint) { + endpoint = endpoint.replace("{" + "bucket" + "}", bucket);endpoint = endpoint.replace("{" + "filename" + "}", filename); + return endpoint; + } + } + /** generateReport (POST /api/v2/multitest-reportgeneration) + summary + + **/ + public static class GenerateReportRequest extends MultipartTestAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/api/v2/multitest-reportgeneration"; + private final Logger coverageLogger = LoggerFactory.getLogger(GenerateReportRequest.class); + + private String template; + + private String additionalData; + + private String _schema; + + + public GenerateReportRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("MultipartTest".toLowerCase() + ":generateReportRequestType"); + } + + public String getOperationName() { + return "generateReport"; + } + + public String getMethod() { + return "POST"; + } + + public String getPath() { + return "/api/v2/multitest-reportgeneration"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .post(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + MultiValueMap multiValues = new LinkedMultiValueMap<>(); + if(StringUtils.isBlank(template)) { + throw new CitrusRuntimeException(String.format("Required attribute '%s' is not specified", "template")); + } + if (StringUtils.isNotBlank(template)) { + // first try to load from resource + ClassPathResource resource = null; + try { + resource = new ClassPathResource(template); + } + catch(Exception ignore) { + // Use plain text instead of resource + } + + if(resource != null && resource.exists()){ + multiValues.add("template", resource); + } else { + multiValues.add("template", template); + } + bodyLog += template.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") +","; + } + if (StringUtils.isNotBlank(additionalData)) { + // first try to load from resource + ClassPathResource resource = null; + try { + resource = new ClassPathResource(additionalData); + } + catch(Exception ignore) { + // Use plain text instead of resource + } + + if(resource != null && resource.exists()){ + multiValues.add("additionalData", resource); + } else { + multiValues.add("additionalData", additionalData); + } + bodyLog += additionalData.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") +","; + } + if (StringUtils.isNotBlank(_schema)) { + // first try to load from resource + ClassPathResource resource = null; + try { + resource = new ClassPathResource(_schema); + } + catch(Exception ignore) { + // Use plain text instead of resource + } + + if(resource != null && resource.exists()){ + multiValues.add("_schema", resource); + } else { + multiValues.add("_schema", _schema); + } + bodyLog += _schema.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") +","; + } + + bodyLog += "\";\"" + MediaType.MULTIPART_FORM_DATA_VALUE + "\""; + messageBuilderSupport.contentType(MediaType.MULTIPART_FORM_DATA_VALUE) + .body(multiValues); + + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "generateReport;POST;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + public void setTemplate(String template) { + this.template = template; + } + + public void setAdditionalData(String additionalData) { + this.additionalData = additionalData; + } + + public void set_schema(String _schema) { + this._schema = _schema; + } + + private String replacePathParams(String endpoint) { + + return endpoint; + } + } + /** multipleDatatypes (POST /api/v2/multitest-multipledatatypes) + summary + + **/ + public static class MultipleDatatypesRequest extends MultipartTestAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/api/v2/multitest-multipledatatypes"; + private final Logger coverageLogger = LoggerFactory.getLogger(MultipleDatatypesRequest.class); + + private String stringData; + + private String booleanData; + + private String integerData; + + + public MultipleDatatypesRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("MultipartTest".toLowerCase() + ":multipleDatatypesRequestType"); + } + + public String getOperationName() { + return "multipleDatatypes"; + } + + public String getMethod() { + return "POST"; + } + + public String getPath() { + return "/api/v2/multitest-multipledatatypes"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .post(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + MultiValueMap multiValues = new LinkedMultiValueMap<>(); + if (StringUtils.isNotBlank(stringData)) { + // first try to load from resource + ClassPathResource resource = null; + try { + resource = new ClassPathResource(stringData); + } + catch(Exception ignore) { + // Use plain text instead of resource + } + + if(resource != null && resource.exists()){ + multiValues.add("stringData", resource); + } else { + multiValues.add("stringData", stringData); + } + bodyLog += stringData.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") +","; + } + if (StringUtils.isNotBlank(booleanData)) { + // first try to load from resource + ClassPathResource resource = null; + try { + resource = new ClassPathResource(booleanData); + } + catch(Exception ignore) { + // Use plain text instead of resource + } + + if(resource != null && resource.exists()){ + multiValues.add("booleanData", resource); + } else { + multiValues.add("booleanData", booleanData); + } + bodyLog += booleanData.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") +","; + } + if (StringUtils.isNotBlank(integerData)) { + // first try to load from resource + ClassPathResource resource = null; + try { + resource = new ClassPathResource(integerData); + } + catch(Exception ignore) { + // Use plain text instead of resource + } + + if(resource != null && resource.exists()){ + multiValues.add("integerData", resource); + } else { + multiValues.add("integerData", integerData); + } + bodyLog += integerData.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") +","; + } + + bodyLog += "\";\"" + MediaType.MULTIPART_FORM_DATA_VALUE + "\""; + messageBuilderSupport.contentType(MediaType.MULTIPART_FORM_DATA_VALUE) + .body(multiValues); + + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "multipleDatatypes;POST;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + public void setStringData(String stringData) { + this.stringData = stringData; + } + + public void setBooleanData(String booleanData) { + this.booleanData = booleanData; + } + + public void setIntegerData(String integerData) { + this.integerData = integerData; + } + + private String replacePathParams(String endpoint) { + + return endpoint; + } + } + /** postFile (POST /api/v2/multitest-file/{bucket}/{filename}) + Uploads file. + + **/ + public static class PostFileRequest extends MultipartTestAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/api/v2/multitest-file/{bucket}/{filename}"; + private final Logger coverageLogger = LoggerFactory.getLogger(PostFileRequest.class); + + private String bucket; + + private String filename; + + private String multipartFile; + + + public PostFileRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("MultipartTest".toLowerCase() + ":postFileRequestType"); + } + + public String getOperationName() { + return "postFile"; + } + + public String getMethod() { + return "POST"; + } + + public String getPath() { + return "/api/v2/multitest-file/{bucket}/{filename}"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .post(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + MultiValueMap multiValues = new LinkedMultiValueMap<>(); + if (StringUtils.isNotBlank(multipartFile)) { + multiValues.add("multipartFile", new ClassPathResource(multipartFile)); + bodyLog += multipartFile.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") +","; + } + + bodyLog += "\";\"" + MediaType.MULTIPART_FORM_DATA_VALUE + "\""; + messageBuilderSupport.contentType(MediaType.MULTIPART_FORM_DATA_VALUE) + .body(multiValues); + + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "postFile;POST;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + public void setBucket(String bucket) { + this.bucket = bucket; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + public void setMultipartFile(String multipartFile) { + this.multipartFile = multipartFile; + } + + private String replacePathParams(String endpoint) { + endpoint = endpoint.replace("{" + "bucket" + "}", bucket);endpoint = endpoint.replace("{" + "filename" + "}", filename); + return endpoint; + } + } + /** postRandom (POST /api/v2/multitest-file/{bucket}/{filename}/random) + Uploads random file. + + **/ + public static class PostRandomRequest extends MultipartTestAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/api/v2/multitest-file/{bucket}/{filename}/random"; + private final Logger coverageLogger = LoggerFactory.getLogger(PostRandomRequest.class); + + private String bucket; + + private String filename; + + + public PostRandomRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("MultipartTest".toLowerCase() + ":postRandomRequestType"); + } + + public String getOperationName() { + return "postRandom"; + } + + public String getMethod() { + return "POST"; + } + + public String getPath() { + return "/api/v2/multitest-file/{bucket}/{filename}/random"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .post(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "postRandom;POST;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + public void setBucket(String bucket) { + this.bucket = bucket; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + private String replacePathParams(String endpoint) { + endpoint = endpoint.replace("{" + "bucket" + "}", bucket);endpoint = endpoint.replace("{" + "filename" + "}", filename); + return endpoint; + } + } +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/spring/MultipartTestBeanConfiguration.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/spring/MultipartTestBeanConfiguration.java new file mode 100644 index 0000000000..090a9bfb7e --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/multiparttest/spring/MultipartTestBeanConfiguration.java @@ -0,0 +1,56 @@ +/** + * ================================================== + * GENERATED CLASS, ALL CHANGES WILL BE LOST + * ================================================== + */ + +package org.citrusframework.openapi.generator.rest.multiparttest.spring; + +import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE; + +import org.citrusframework.openapi.generator.rest.multiparttest.request.MultiparttestControllerApi; +import javax.annotation.processing.Generated; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; + +@Configuration +@Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen") +public class MultipartTestBeanConfiguration { + + @Bean + @Scope(SCOPE_PROTOTYPE) + public MultiparttestControllerApi.DeleteObjectRequest deleteObjectRequest() { + return new MultiparttestControllerApi.DeleteObjectRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public MultiparttestControllerApi.FileExistsRequest fileExistsRequest() { + return new MultiparttestControllerApi.FileExistsRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public MultiparttestControllerApi.GenerateReportRequest generateReportRequest() { + return new MultiparttestControllerApi.GenerateReportRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public MultiparttestControllerApi.MultipleDatatypesRequest multipleDatatypesRequest() { + return new MultiparttestControllerApi.MultipleDatatypesRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public MultiparttestControllerApi.PostFileRequest postFileRequest() { + return new MultiparttestControllerApi.PostFileRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public MultiparttestControllerApi.PostRandomRequest postRandomRequest() { + return new MultiparttestControllerApi.PostRandomRequest(); + } +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/citrus/PetStoreAbstractTestRequest.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/citrus/PetStoreAbstractTestRequest.java new file mode 100644 index 0000000000..9ff2150d21 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/citrus/PetStoreAbstractTestRequest.java @@ -0,0 +1,245 @@ +/** + * ================================================== + * GENERATED CLASS, ALL CHANGES WILL BE LOST + * ================================================== + */ + +package org.citrusframework.openapi.generator.rest.petstore.citrus; + + +import static org.springframework.util.CollectionUtils.isEmpty; + +import jakarta.annotation.Generated; +import jakarta.annotation.Nullable; +import java.util.List; +import java.util.Map; +import java.util.ServiceLoader; +import javax.sql.DataSource; +import org.citrusframework.actions.AbstractTestAction; +import org.citrusframework.actions.ReceiveMessageAction; +import org.citrusframework.context.TestContext; +import org.citrusframework.http.actions.HttpActionBuilder; +import org.citrusframework.http.actions.HttpClientRequestActionBuilder; +import org.citrusframework.http.actions.HttpClientResponseActionBuilder; +import org.citrusframework.http.actions.HttpClientResponseActionBuilder.HttpMessageBuilderSupport; +import org.citrusframework.http.client.HttpClient; +import org.citrusframework.message.Message; +import org.citrusframework.testapi.ApiActionBuilderCustomizerService; +import org.citrusframework.testapi.GeneratedApi; +import org.citrusframework.spi.Resources; +import org.citrusframework.validation.DelegatingPayloadVariableExtractor; +import org.citrusframework.validation.PathExpressionValidationContext; +import org.citrusframework.validation.json.JsonMessageValidationContext; +import org.citrusframework.validation.script.ScriptValidationContext; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +@Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen") +public abstract class PetStoreAbstractTestRequest extends AbstractTestAction { + + protected final Marker coverageMarker = MarkerFactory.getMarker("PETSTORE-API-COVERAGE"); + + @Autowired + @Qualifier("petStoreEndpoint") + protected HttpClient httpClient; + + @Autowired(required = false) + protected DataSource dataSource; + + @Autowired(required = false) + private List actionBuilderCustomizerServices; + + // attributes of differentNodes + protected boolean schemaValidation; + protected String schema; + protected String bodyContentType; + protected String bodyLiteralContentType; + protected String bodyFile; + protected String bodyLiteral; + protected String responseAcceptType = "*/*"; + protected String responseType = "json"; + protected int responseStatus = 200; + protected String responseReasonPhrase = "OK"; + protected String responseVersion = "HTTP/1.1"; + + // children of response element + protected String resource; + protected Map responseVariable; // Contains the 'JSON-PATH' as key and the 'VARIABLE NAME' as value + protected Map responseValue; // Contains the 'JSON-PATH' as key and the 'VALUE TO BE VALIDATED' as value + protected Map cookies; + protected Map headers; + protected String script; + protected String type; // default script type is groovy - supported types see com.consol.citrus.script.ScriptTypes + + @Override + public void doExecute(TestContext context) { + sendRequest(context); + recieveResponse(context); + } + + /** + * This method receives the HTTP-Response. + * + * @deprecated use {@link PetStoreAbstractTestRequest#receiveResponse(TestContext)} instead. + */ + public ReceiveMessageAction recieveResponse(TestContext context) { + + HttpClientResponseActionBuilder httpClientResponseActionBuilder = new HttpActionBuilder().client(httpClient).receive().response(); + HttpMessageBuilderSupport messageBuilderSupport = httpClientResponseActionBuilder.getMessageBuilderSupport(); + + messageBuilderSupport + .statusCode(responseStatus) + .reasonPhrase(responseReasonPhrase) + .version(responseVersion) + .validate(new JsonMessageValidationContext.Builder().schemaValidation(schemaValidation).schema(schema)); + + if (resource != null) { + messageBuilderSupport.body(Resources.create(resource)); + } + + if (!isEmpty(responseVariable)) { + DelegatingPayloadVariableExtractor.Builder extractorBuilder = new DelegatingPayloadVariableExtractor.Builder(); + responseVariable.forEach(extractorBuilder::expression); + messageBuilderSupport.extract(extractorBuilder); + } + + if (!isEmpty(responseValue)) { + PathExpressionValidationContext.Builder validationContextBuilder = new PathExpressionValidationContext.Builder(); + responseValue.forEach(validationContextBuilder::expression); + messageBuilderSupport.validate(validationContextBuilder); + } + + if (script != null) { + ScriptValidationContext.Builder scriptValidationContextBuilder = new ScriptValidationContext.Builder(); + if (type != null) { + scriptValidationContextBuilder.scriptType(type); + } + scriptValidationContextBuilder.script(script); + messageBuilderSupport.validate(scriptValidationContextBuilder); + } + + messageBuilderSupport.type(responseType); + httpClientResponseActionBuilder.withReferenceResolver(context.getReferenceResolver()); + var responseAction = httpClientResponseActionBuilder.build(); + + responseAction.execute(context); + + return responseAction; + } + + public @Nullable Message receiveResponse(TestContext context) { + var responseAction = recieveResponse(context); + + var messageStore = context.getMessageStore(); + return messageStore.getMessage(messageStore.constructMessageName(responseAction, httpClient)); + } + + public abstract void sendRequest(TestContext context); + + public void setSchemaValidation(boolean schemaValidation) { + this.schemaValidation = schemaValidation; + } + + public void setSchema(String schema) { + this.schema = schema; + } + + public void setBodyLiteral(String bodyLiteral) { + this.bodyLiteral = bodyLiteral; + } + + public void setBodyContentType(String bodyContentType) { + this.bodyContentType = bodyContentType; + } + + public void setBodyLiteralContentType(String bodyLiteralContentType) { + this.bodyLiteralContentType = bodyLiteralContentType; + } + + public void setResponseAcceptType(String responseAcceptType) { + this.responseAcceptType = responseAcceptType; + } + + public void setCookie(Map cookies) { + this.cookies = cookies; + } + + public void setHeader(Map headers) { + this.headers = headers; + } + + public void setBodyFile(String bodyFile) { + this.bodyFile = bodyFile; + } + + public void setResponseType(String responseType) { + this.responseType = responseType; + } + + public void setResponseStatus(int responseStatus) { + this.responseStatus = responseStatus; + } + + public void setResponseReasonPhrase(String responseReasonPhrase) { + this.responseReasonPhrase = responseReasonPhrase; + } + + public void setResponseVersion(String responseVersion) { + this.responseVersion = responseVersion; + } + + public void setResource(String resource) { + this.resource = resource; + } + + public void setResponseVariable(Map responseVariable) { + this.responseVariable = responseVariable; + } + + public void setResponseValue(Map responseValue) { + this.responseValue = responseValue; + } + + public void setScript(String script) { + this.script = script; + } + + public void setType(String type) { + this.type = type; + } + + protected HttpClientRequestActionBuilder customizeBuilder(GeneratedApi generatedApi, + TestContext context, HttpClientRequestActionBuilder httpClientRequestActionBuilder) { + + httpClientRequestActionBuilder = customizeByBeans(generatedApi, context, + httpClientRequestActionBuilder); + + httpClientRequestActionBuilder = customizeBySpi(generatedApi, context, httpClientRequestActionBuilder); + + return httpClientRequestActionBuilder; + } + + private HttpClientRequestActionBuilder customizeBySpi(GeneratedApi generatedApi, TestContext context, + HttpClientRequestActionBuilder httpClientRequestActionBuilder) { + ServiceLoader serviceLoader = ServiceLoader.load( + ApiActionBuilderCustomizerService.class, ApiActionBuilderCustomizerService.class.getClassLoader()); + for (ApiActionBuilderCustomizerService service :serviceLoader) { + httpClientRequestActionBuilder = service.build(generatedApi, this, context, httpClientRequestActionBuilder); + } + return httpClientRequestActionBuilder; + } + + private HttpClientRequestActionBuilder customizeByBeans( + GeneratedApi generatedApi, TestContext context, + HttpClientRequestActionBuilder httpClientRequestActionBuilder) { + if (actionBuilderCustomizerServices != null) { + for (ApiActionBuilderCustomizerService apiActionBuilderCustomizer : actionBuilderCustomizerServices) { + httpClientRequestActionBuilder = apiActionBuilderCustomizer.build(generatedApi, this, + context, httpClientRequestActionBuilder); + } + } + return httpClientRequestActionBuilder; + } +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/citrus/PetStoreBeanDefinitionParser.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/citrus/PetStoreBeanDefinitionParser.java new file mode 100644 index 0000000000..32920fb8ef --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/citrus/PetStoreBeanDefinitionParser.java @@ -0,0 +1,215 @@ +/** + * ================================================== + * GENERATED CLASS, ALL CHANGES WILL BE LOST + * ================================================== + */ + +package org.citrusframework.openapi.generator.rest.petstore.citrus; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.annotation.processing.Generated; + +import org.citrusframework.exceptions.CitrusRuntimeException; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.core.Conventions; +import org.springframework.util.Assert; +import org.apache.commons.lang3.StringUtils; +import org.springframework.util.xml.DomUtils; +import org.w3c.dom.Attr; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; + + +@Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen") +public class PetStoreBeanDefinitionParser implements BeanDefinitionParser { + + private static final String COOKIE = "cookie"; + private static final String HEADER = "header"; + private static final String SOAP_HEADER = "soapHeader"; + private static final String MIME_HEADER = "mimeHeader"; + private static final String NAME = "name"; + private static final String REQUEST_BODY = "body"; + private static final String REQUEST_BODY_LITERAL = "bodyLiteral"; + private static final String MULTIPART_BODY = "multipartBody"; + private static final String RESPONSE = "response"; + private static final String RESPONSE_JSONPATH = "json-path"; + private static final String RESPONSE_XPATH = "xpath"; + private static final String EXPRESSION = "expression"; + private static final String VALUE = "value"; + private static final String RESPONSE_RESOURCE = "resource"; + private static final String FILE = "file"; + private static final String RESPONSE_VARIABLE = "responseVariable"; + private static final String RESPONSE_VALUE = "responseValue"; + private static final String SCRIPT = "script"; + private static final String TYPE = "type"; + private static final String SQL = "sql"; + private static final String COLUMN = "column"; + private static final String VARIABLE = "variable"; + // new + private static final String SCHEMA = "schema"; + // new + private static final String SCHEMA_VALIDATION = "schemaValidation"; + + private final Class beanClass; + + public PetStoreBeanDefinitionParser(Class beanClass) { + this.beanClass = beanClass; + } + + public BeanDefinition parse(Element element) { + return parse(element, null); + } + + /** + * Note: The {@link PetStoreBeanDefinitionParser#parse(Element element)} allows access direct + * access without the {@link org.springframework.beans.factory.xml.ParserContext} for convenience. + */ + @Override + public BeanDefinition parse(Element element, ParserContext parserContext) { + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(beanClass); + retrieveRootNodeAttributes(element, builder); + retrieveOptionalNodeAttributes(element, REQUEST_BODY, builder); + retrieveTextContentAndNodeAttributes(element, REQUEST_BODY_LITERAL, builder); + retrieveOptionalNodeAttributes(element, RESPONSE, builder); + retrieveParamNodeData(element, builder, COOKIE); + retrieveParamNodeData(element, builder, HEADER); + retrieveParamNodeData(element, builder, SOAP_HEADER); + retrieveParamNodeData(element, builder, MIME_HEADER); + retrieveOptionalNodeAttributes(element, SCHEMA, builder); + retrieveOptionalNodeAttributes(element, SCHEMA_VALIDATION, builder); + retrieveOptionalMultipartElements(element, builder); + retrieveResponseNodeData(element, builder); + builder.addPropertyValue("name", element.getTagName()); + return builder.getBeanDefinition(); + } + + private void retrieveOptionalMultipartElements(Element element, BeanDefinitionBuilder builder) { + var multipartBodyElement = DomUtils.getChildElementByTagName(element, MULTIPART_BODY); + if (multipartBodyElement != null) { + var multipartBodyChildElements = DomUtils.getChildElements(multipartBodyElement); + for(int i = 0; i < multipartBodyChildElements.size(); i++){ + var multipartBodyChildElement = multipartBodyChildElements.get(i); + String propertyName = Conventions.attributeNameToPropertyName(multipartBodyChildElement.getLocalName()); + builder.addPropertyValue(propertyName, multipartBodyChildElement.getTextContent()); + } + } + } + + private void retrieveRootNodeAttributes(Element element, BeanDefinitionBuilder builder) { + NamedNodeMap attributes = element.getAttributes(); + for (int x = 0; x < attributes.getLength(); x++) { + Attr attribute = (Attr) attributes.item(x); + String propertyName = Conventions.attributeNameToPropertyName(attribute.getLocalName()); + Assert.state(StringUtils.isNotBlank(propertyName), "Illegal property name returned, it must not be null or empty."); + builder.addPropertyValue(propertyName, attribute.getValue()); + } + } + + private void retrieveOptionalNodeAttributes(Element element, String elementName, BeanDefinitionBuilder builder) { + if (!DomUtils.getChildElementsByTagName(element, elementName).isEmpty()) { + Element el = DomUtils.getChildElementsByTagName(element, elementName).get(0); + NamedNodeMap attributes = el.getAttributes(); + for (int x = 0; x < attributes.getLength(); x++) { + Attr attribute = (Attr) attributes.item(x); + String propertyName = Conventions.attributeNameToPropertyName(attribute.getLocalName()); + Assert.state(StringUtils.isNotBlank(propertyName), "Illegal property name returned, it must not be null or empty."); + String variableName = el.getLocalName() + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1); + builder.addPropertyValue(variableName, attribute.getValue()); + } + } + } + + private void retrieveTextContentAndNodeAttributes(Element element, String elementName, BeanDefinitionBuilder builder) { + if (!DomUtils.getChildElementsByTagName(element, elementName).isEmpty()) { + Element el1 = DomUtils.getChildElementsByTagName(element, elementName).get(0); + NamedNodeMap attributes = el1.getAttributes(); + for (int x = 0; x < attributes.getLength(); x++) { + Attr attribute = (Attr) attributes.item(x); + String propertyName1 = Conventions.attributeNameToPropertyName(attribute.getLocalName()); + Assert.state(StringUtils.isNotBlank(propertyName1), "Illegal property name returned, it must not be null or empty."); + String variableName = el1.getLocalName() + propertyName1.substring(0, 1).toUpperCase() + propertyName1.substring(1); + builder.addPropertyValue(variableName, attribute.getValue()); + } + Element el = DomUtils.getChildElementsByTagName(element, elementName).get(0); + builder.addPropertyValue(elementName, el.getTextContent()); + } + } + + private void retrieveParamNodeData(Element element, BeanDefinitionBuilder builder, String paramType) { + if (!DomUtils.getChildElementsByTagName(element, paramType).isEmpty()) { + Map params = new HashMap<>(); + List elements = DomUtils.getChildElementsByTagName(element, paramType); + elements.forEach(e -> { + String name = e.getAttribute(NAME); + String value = e.getAttribute(VALUE); + + Assert.state(StringUtils.isNotBlank(name), "Illegal attribute value returned. The 'name' attribute must not be null or empty."); + Assert.state(StringUtils.isNotBlank(value), "Illegal attribute value returned. The 'value' attribute must not be null or empty."); + + params.put(name, value); + }); + builder.addPropertyValue(paramType, params); + } + } + + private void retrieveResponseNodeData(Element element, BeanDefinitionBuilder builder) { + + if (!DomUtils.getChildElementsByTagName(element, RESPONSE).isEmpty()) { + Element response = DomUtils.getChildElementsByTagName(element, RESPONSE).get(0); + List elements = DomUtils.getChildElements(response); + + Map responseVariable = new HashMap<>(); + Map responseValue = new HashMap<>(); + + for (int i = 0; i < elements.size(); i++) { + Element e = elements.get(i); + + if (e.getTagName().contains(RESPONSE_JSONPATH) || e.getTagName().contains(RESPONSE_XPATH)) { + String expression = e.getAttribute(EXPRESSION); + String value = e.getAttribute(VALUE); + + Assert.state(StringUtils.isNotBlank(expression), "Illegal attribute value returned. The 'expression' attribute must not be null or empty."); + Assert.state(StringUtils.isNotBlank(value), "Illegal attribute value returned. The 'value' attribute must not be null or empty."); + + // variable to save @variable('ebid')@ else value to validate + if (value.matches("\\@variable\\('.*'\\)\\@")) { + Matcher match = Pattern.compile("\\'(.*?)\\'").matcher(value); + if (match.find()) { + responseVariable.put(expression, value.substring(match.start() + 1, match.end() - 1)); + } + } else { + responseValue.put(expression, value); + } + } else if (e.getTagName().contains(SCRIPT)) { + String script = e.getTextContent(); + Assert.state(StringUtils.isNotBlank(script), "Illegal attribute value returned. The 'script' attribute must not be null or empty."); + builder.addPropertyValue(SCRIPT, script); + + if (!e.getAttribute(TYPE).isEmpty()) { + String type = e.getAttribute(TYPE); + Assert.state(StringUtils.isNotBlank(type), "Illegal attribute value returned. The 'type' attribute must not be null or empty."); + builder.addPropertyValue(TYPE, type); + } + } else if (e.getTagName().contains(RESPONSE_RESOURCE)) { + String filePath = e.getAttribute(FILE); + Assert.state(StringUtils.isNotBlank(filePath), "Illegal attribute value returned. The 'file' attribute must not be null or empty."); + builder.addPropertyValue(RESPONSE_RESOURCE, filePath); + } + + } + + builder.addPropertyValue(RESPONSE_VARIABLE, responseVariable); + builder.addPropertyValue(RESPONSE_VALUE, responseValue); + } + } +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/citrus/extension/PetStoreNamespaceHandler.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/citrus/extension/PetStoreNamespaceHandler.java new file mode 100644 index 0000000000..af5b731084 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/citrus/extension/PetStoreNamespaceHandler.java @@ -0,0 +1,45 @@ +/** + * ================================================== + * GENERATED CLASS, ALL CHANGES WILL BE LOST + * ================================================== + */ + +package org.citrusframework.openapi.generator.rest.petstore.citrus.extension; + +import org.citrusframework.openapi.generator.rest.petstore.request.PetApi; +import org.citrusframework.openapi.generator.rest.petstore.request.StoreApi; +import org.citrusframework.openapi.generator.rest.petstore.request.UserApi; +import org.citrusframework.openapi.generator.rest.petstore.citrus.PetStoreBeanDefinitionParser; + +import javax.annotation.processing.Generated; + +import org.springframework.beans.factory.xml.NamespaceHandlerSupport; + + +@Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen") +public class PetStoreNamespaceHandler extends NamespaceHandlerSupport { + + @Override + public void init() { + registerBeanDefinitionParser("addPetRequest", new PetStoreBeanDefinitionParser(PetApi.AddPetRequest.class)); + registerBeanDefinitionParser("deletePetRequest", new PetStoreBeanDefinitionParser(PetApi.DeletePetRequest.class)); + registerBeanDefinitionParser("findPetsByStatusRequest", new PetStoreBeanDefinitionParser(PetApi.FindPetsByStatusRequest.class)); + registerBeanDefinitionParser("findPetsByTagsRequest", new PetStoreBeanDefinitionParser(PetApi.FindPetsByTagsRequest.class)); + registerBeanDefinitionParser("getPetByIdRequest", new PetStoreBeanDefinitionParser(PetApi.GetPetByIdRequest.class)); + registerBeanDefinitionParser("updatePetRequest", new PetStoreBeanDefinitionParser(PetApi.UpdatePetRequest.class)); + registerBeanDefinitionParser("updatePetWithFormRequest", new PetStoreBeanDefinitionParser(PetApi.UpdatePetWithFormRequest.class)); + registerBeanDefinitionParser("uploadFileRequest", new PetStoreBeanDefinitionParser(PetApi.UploadFileRequest.class)); + registerBeanDefinitionParser("deleteOrderRequest", new PetStoreBeanDefinitionParser(StoreApi.DeleteOrderRequest.class)); + registerBeanDefinitionParser("getInventoryRequest", new PetStoreBeanDefinitionParser(StoreApi.GetInventoryRequest.class)); + registerBeanDefinitionParser("getOrderByIdRequest", new PetStoreBeanDefinitionParser(StoreApi.GetOrderByIdRequest.class)); + registerBeanDefinitionParser("placeOrderRequest", new PetStoreBeanDefinitionParser(StoreApi.PlaceOrderRequest.class)); + registerBeanDefinitionParser("createUserRequest", new PetStoreBeanDefinitionParser(UserApi.CreateUserRequest.class)); + registerBeanDefinitionParser("createUsersWithArrayInputRequest", new PetStoreBeanDefinitionParser(UserApi.CreateUsersWithArrayInputRequest.class)); + registerBeanDefinitionParser("createUsersWithListInputRequest", new PetStoreBeanDefinitionParser(UserApi.CreateUsersWithListInputRequest.class)); + registerBeanDefinitionParser("deleteUserRequest", new PetStoreBeanDefinitionParser(UserApi.DeleteUserRequest.class)); + registerBeanDefinitionParser("getUserByNameRequest", new PetStoreBeanDefinitionParser(UserApi.GetUserByNameRequest.class)); + registerBeanDefinitionParser("loginUserRequest", new PetStoreBeanDefinitionParser(UserApi.LoginUserRequest.class)); + registerBeanDefinitionParser("logoutUserRequest", new PetStoreBeanDefinitionParser(UserApi.LogoutUserRequest.class)); + registerBeanDefinitionParser("updateUserRequest", new PetStoreBeanDefinitionParser(UserApi.UpdateUserRequest.class)); + } +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/model/Category.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/model/Category.java new file mode 100644 index 0000000000..d5341fea2c --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/model/Category.java @@ -0,0 +1 @@ +// not in use diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/model/ModelApiResponse.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/model/ModelApiResponse.java new file mode 100644 index 0000000000..d5341fea2c --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/model/ModelApiResponse.java @@ -0,0 +1 @@ +// not in use diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/model/Order.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/model/Order.java new file mode 100644 index 0000000000..d5341fea2c --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/model/Order.java @@ -0,0 +1 @@ +// not in use diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/model/Pet.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/model/Pet.java new file mode 100644 index 0000000000..d5341fea2c --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/model/Pet.java @@ -0,0 +1 @@ +// not in use diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/model/Tag.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/model/Tag.java new file mode 100644 index 0000000000..d5341fea2c --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/model/Tag.java @@ -0,0 +1 @@ +// not in use diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/model/User.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/model/User.java new file mode 100644 index 0000000000..d5341fea2c --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/model/User.java @@ -0,0 +1 @@ +// not in use diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/request/PetApi.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/request/PetApi.java new file mode 100644 index 0000000000..a014b1c53f --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/request/PetApi.java @@ -0,0 +1,862 @@ +/** + * ================================================== + * GENERATED CLASS, ALL CHANGES WILL BE LOST + * ================================================== + */ + +package org.citrusframework.openapi.generator.rest.petstore.request; + +import jakarta.annotation.Generated; +import org.citrusframework.testapi.GeneratedApi; +import org.citrusframework.testapi.GeneratedApiRequest; +import jakarta.servlet.http.Cookie; +import org.apache.commons.lang3.StringUtils; +import org.citrusframework.context.TestContext; +import org.citrusframework.exceptions.CitrusRuntimeException; +import org.citrusframework.spi.Resources; +import org.citrusframework.http.actions.HttpActionBuilder; +import org.citrusframework.http.actions.HttpClientRequestActionBuilder; +import org.citrusframework.http.actions.HttpClientRequestActionBuilder.HttpMessageBuilderSupport; +import org.citrusframework.util.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.MediaType; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import org.citrusframework.openapi.generator.rest.petstore.citrus.PetStoreAbstractTestRequest; + +import java.io.IOException; +import java.util.Base64; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + + +@Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen") +public class PetApi implements GeneratedApi +{ + + public static final PetApi INSTANCE = new PetApi(); + + public String getApiTitle() { + return "OpenAPI Petstore"; + } + + public String getApiVersion() { + return "1.0.0"; + } + + public String getApiPrefix() { + return "PetStore"; + } + + public Map getApiInfoExtensions() { + Map infoExtensionMap = new HashMap<>(); + infoExtensionMap.put("x-citrus-api-name", "petstore"); + infoExtensionMap.put("x-citrus-app", "PETS"); + return infoExtensionMap; + } + + /** addPet (POST /pet) + Add a new pet to the store + + **/ + public static class AddPetRequest extends PetStoreAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/pet"; + private final Logger coverageLogger = LoggerFactory.getLogger(AddPetRequest.class); + + + public AddPetRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("PetStore".toLowerCase() + ":addPetRequestType"); + } + + public String getOperationName() { + return "addPet"; + } + + public String getMethod() { + return "POST"; + } + + public String getPath() { + return "/pet"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .post(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "addPet;POST;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + private String replacePathParams(String endpoint) { + + return endpoint; + } + } + /** deletePet (DELETE /pet/{petId}) + Deletes a pet + + **/ + public static class DeletePetRequest extends PetStoreAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/pet/{petId}"; + private final Logger coverageLogger = LoggerFactory.getLogger(DeletePetRequest.class); + + private String petId; + + + public DeletePetRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("PetStore".toLowerCase() + ":deletePetRequestType"); + } + + public String getOperationName() { + return "deletePet"; + } + + public String getMethod() { + return "DELETE"; + } + + public String getPath() { + return "/pet/{petId}"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .delete(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "deletePet;DELETE;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + public void setPetId(String petId) { + this.petId = petId; + } + + private String replacePathParams(String endpoint) { + endpoint = endpoint.replace("{" + "petId" + "}", petId); + return endpoint; + } + } + /** findPetsByStatus (GET /pet/findByStatus) + Finds Pets by status + + **/ + public static class FindPetsByStatusRequest extends PetStoreAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/pet/findByStatus"; + private final Logger coverageLogger = LoggerFactory.getLogger(FindPetsByStatusRequest.class); + + private String status; + + + public FindPetsByStatusRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("PetStore".toLowerCase() + ":findPetsByStatusRequestType"); + } + + public String getOperationName() { + return "findPetsByStatus"; + } + + public String getMethod() { + return "GET"; + } + + public String getPath() { + return "/pet/findByStatus"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .get(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + + if (StringUtils.isNotBlank(this.status)) { + queryParams.put("status", context.replaceDynamicContentInString(this.status)); + httpClientRequestActionBuilder.queryParam("status", this.status); + } + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "findPetsByStatus;GET;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + public void setStatus(String status) { + this.status = status; + } + + private String replacePathParams(String endpoint) { + + return endpoint; + } + } + /** findPetsByTags (GET /pet/findByTags) + Finds Pets by tags + + **/ + public static class FindPetsByTagsRequest extends PetStoreAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/pet/findByTags"; + private final Logger coverageLogger = LoggerFactory.getLogger(FindPetsByTagsRequest.class); + + private String tags; + + + public FindPetsByTagsRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("PetStore".toLowerCase() + ":findPetsByTagsRequestType"); + } + + public String getOperationName() { + return "findPetsByTags"; + } + + public String getMethod() { + return "GET"; + } + + public String getPath() { + return "/pet/findByTags"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .get(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + + if (StringUtils.isNotBlank(this.tags)) { + queryParams.put("tags", context.replaceDynamicContentInString(this.tags)); + httpClientRequestActionBuilder.queryParam("tags", this.tags); + } + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "findPetsByTags;GET;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + public void setTags(String tags) { + this.tags = tags; + } + + private String replacePathParams(String endpoint) { + + return endpoint; + } + } + /** getPetById (GET /pet/{petId}) + Find pet by ID + + **/ + public static class GetPetByIdRequest extends PetStoreAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/pet/{petId}"; + private final Logger coverageLogger = LoggerFactory.getLogger(GetPetByIdRequest.class); + + private String petId; + + + @Value("${" + "petStoreEndpoint.basic.username:#{null}}") + private String basicUsername; + @Value("${" + "petStoreEndpoint.basic.password:#{null}}") + private String basicPassword; + + + public GetPetByIdRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("PetStore".toLowerCase() + ":getPetByIdRequestType"); + } + + public String getOperationName() { + return "getPetById"; + } + + public String getMethod() { + return "GET"; + } + + public String getPath() { + return "/pet/{petId}"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .get(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + + if(basicUsername != null && basicPassword != null){ + messageBuilderSupport.header("Authorization", "Basic " + Base64.getEncoder().encodeToString((context.replaceDynamicContentInString(basicUsername)+":"+context.replaceDynamicContentInString(basicPassword)).getBytes())); + } + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "getPetById;GET;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + public void setPetId(String petId) { + this.petId = petId; + } + + + public void setBasicUsername(String basicUsername) { + this.basicUsername = basicUsername; + } + + public void setBasicPassword(String basicPassword) { + this.basicPassword = basicPassword; + } + + private String replacePathParams(String endpoint) { + endpoint = endpoint.replace("{" + "petId" + "}", petId); + return endpoint; + } + } + /** updatePet (PUT /pet) + Update an existing pet + + **/ + public static class UpdatePetRequest extends PetStoreAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/pet"; + private final Logger coverageLogger = LoggerFactory.getLogger(UpdatePetRequest.class); + + + public UpdatePetRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("PetStore".toLowerCase() + ":updatePetRequestType"); + } + + public String getOperationName() { + return "updatePet"; + } + + public String getMethod() { + return "PUT"; + } + + public String getPath() { + return "/pet"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .put(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "updatePet;PUT;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + private String replacePathParams(String endpoint) { + + return endpoint; + } + } + /** updatePetWithForm (POST /pet/{petId}) + Updates a pet in the store with form data + + **/ + public static class UpdatePetWithFormRequest extends PetStoreAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/pet/{petId}"; + private final Logger coverageLogger = LoggerFactory.getLogger(UpdatePetWithFormRequest.class); + + private String petId; + + + public UpdatePetWithFormRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("PetStore".toLowerCase() + ":updatePetWithFormRequestType"); + } + + public String getOperationName() { + return "updatePetWithForm"; + } + + public String getMethod() { + return "POST"; + } + + public String getPath() { + return "/pet/{petId}"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .post(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "updatePetWithForm;POST;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + public void setPetId(String petId) { + this.petId = petId; + } + + private String replacePathParams(String endpoint) { + endpoint = endpoint.replace("{" + "petId" + "}", petId); + return endpoint; + } + } + /** uploadFile (POST /pet/{petId}/uploadImage) + uploads an image + + **/ + public static class UploadFileRequest extends PetStoreAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/pet/{petId}/uploadImage"; + private final Logger coverageLogger = LoggerFactory.getLogger(UploadFileRequest.class); + + private String petId; + + private String additionalMetadata; + + private String _file; + + + public UploadFileRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("PetStore".toLowerCase() + ":uploadFileRequestType"); + } + + public String getOperationName() { + return "uploadFile"; + } + + public String getMethod() { + return "POST"; + } + + public String getPath() { + return "/pet/{petId}/uploadImage"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .post(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + MultiValueMap multiValues = new LinkedMultiValueMap<>(); + if (StringUtils.isNotBlank(additionalMetadata)) { + // first try to load from resource + ClassPathResource resource = null; + try { + resource = new ClassPathResource(additionalMetadata); + } + catch(Exception ignore) { + // Use plain text instead of resource + } + + if(resource != null && resource.exists()){ + multiValues.add("additionalMetadata", resource); + } else { + multiValues.add("additionalMetadata", additionalMetadata); + } + bodyLog += additionalMetadata.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") +","; + } + if (StringUtils.isNotBlank(_file)) { + multiValues.add("_file", new ClassPathResource(_file)); + bodyLog += _file.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") +","; + } + + bodyLog += "\";\"" + MediaType.MULTIPART_FORM_DATA_VALUE + "\""; + messageBuilderSupport.contentType(MediaType.MULTIPART_FORM_DATA_VALUE) + .body(multiValues); + + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "uploadFile;POST;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + public void setPetId(String petId) { + this.petId = petId; + } + + public void setAdditionalMetadata(String additionalMetadata) { + this.additionalMetadata = additionalMetadata; + } + + public void set_file(String _file) { + this._file = _file; + } + + private String replacePathParams(String endpoint) { + endpoint = endpoint.replace("{" + "petId" + "}", petId); + return endpoint; + } + } +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/request/StoreApi.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/request/StoreApi.java new file mode 100644 index 0000000000..406f97f2f9 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/request/StoreApi.java @@ -0,0 +1,433 @@ +/** + * ================================================== + * GENERATED CLASS, ALL CHANGES WILL BE LOST + * ================================================== + */ + +package org.citrusframework.openapi.generator.rest.petstore.request; + +import jakarta.annotation.Generated; +import org.citrusframework.testapi.GeneratedApi; +import org.citrusframework.testapi.GeneratedApiRequest; +import jakarta.servlet.http.Cookie; +import org.apache.commons.lang3.StringUtils; +import org.citrusframework.context.TestContext; +import org.citrusframework.exceptions.CitrusRuntimeException; +import org.citrusframework.spi.Resources; +import org.citrusframework.http.actions.HttpActionBuilder; +import org.citrusframework.http.actions.HttpClientRequestActionBuilder; +import org.citrusframework.http.actions.HttpClientRequestActionBuilder.HttpMessageBuilderSupport; +import org.citrusframework.util.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.MediaType; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import org.citrusframework.openapi.generator.rest.petstore.citrus.PetStoreAbstractTestRequest; + +import java.io.IOException; +import java.util.Base64; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + + +@Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen") +public class StoreApi implements GeneratedApi +{ + + public static final StoreApi INSTANCE = new StoreApi(); + + public String getApiTitle() { + return "OpenAPI Petstore"; + } + + public String getApiVersion() { + return "1.0.0"; + } + + public String getApiPrefix() { + return "PetStore"; + } + + public Map getApiInfoExtensions() { + Map infoExtensionMap = new HashMap<>(); + infoExtensionMap.put("x-citrus-api-name", "petstore"); + infoExtensionMap.put("x-citrus-app", "PETS"); + return infoExtensionMap; + } + + /** deleteOrder (DELETE /store/order/{order_id}) + Delete purchase order by ID + + **/ + public static class DeleteOrderRequest extends PetStoreAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/store/order/{order_id}"; + private final Logger coverageLogger = LoggerFactory.getLogger(DeleteOrderRequest.class); + + private String orderId; + + + public DeleteOrderRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("PetStore".toLowerCase() + ":deleteOrderRequestType"); + } + + public String getOperationName() { + return "deleteOrder"; + } + + public String getMethod() { + return "DELETE"; + } + + public String getPath() { + return "/store/order/{order_id}"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .delete(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "deleteOrder;DELETE;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + private String replacePathParams(String endpoint) { + endpoint = endpoint.replace("{" + "order_id" + "}", orderId); + return endpoint; + } + } + /** getInventory (GET /store/inventory) + Returns pet inventories by status + + **/ + public static class GetInventoryRequest extends PetStoreAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/store/inventory"; + private final Logger coverageLogger = LoggerFactory.getLogger(GetInventoryRequest.class); + + + public GetInventoryRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("PetStore".toLowerCase() + ":getInventoryRequestType"); + } + + public String getOperationName() { + return "getInventory"; + } + + public String getMethod() { + return "GET"; + } + + public String getPath() { + return "/store/inventory"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .get(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "getInventory;GET;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + private String replacePathParams(String endpoint) { + + return endpoint; + } + } + /** getOrderById (GET /store/order/{order_id}) + Find purchase order by ID + + **/ + public static class GetOrderByIdRequest extends PetStoreAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/store/order/{order_id}"; + private final Logger coverageLogger = LoggerFactory.getLogger(GetOrderByIdRequest.class); + + private String orderId; + + + public GetOrderByIdRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("PetStore".toLowerCase() + ":getOrderByIdRequestType"); + } + + public String getOperationName() { + return "getOrderById"; + } + + public String getMethod() { + return "GET"; + } + + public String getPath() { + return "/store/order/{order_id}"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .get(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "getOrderById;GET;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + private String replacePathParams(String endpoint) { + endpoint = endpoint.replace("{" + "order_id" + "}", orderId); + return endpoint; + } + } + /** placeOrder (POST /store/order) + Place an order for a pet + + **/ + public static class PlaceOrderRequest extends PetStoreAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/store/order"; + private final Logger coverageLogger = LoggerFactory.getLogger(PlaceOrderRequest.class); + + + public PlaceOrderRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("PetStore".toLowerCase() + ":placeOrderRequestType"); + } + + public String getOperationName() { + return "placeOrder"; + } + + public String getMethod() { + return "POST"; + } + + public String getPath() { + return "/store/order"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .post(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "placeOrder;POST;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + private String replacePathParams(String endpoint) { + + return endpoint; + } + } +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/request/UserApi.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/request/UserApi.java new file mode 100644 index 0000000000..01f4558954 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/request/UserApi.java @@ -0,0 +1,819 @@ +/** + * ================================================== + * GENERATED CLASS, ALL CHANGES WILL BE LOST + * ================================================== + */ + +package org.citrusframework.openapi.generator.rest.petstore.request; + +import jakarta.annotation.Generated; +import org.citrusframework.testapi.GeneratedApi; +import org.citrusframework.testapi.GeneratedApiRequest; +import jakarta.servlet.http.Cookie; +import org.apache.commons.lang3.StringUtils; +import org.citrusframework.context.TestContext; +import org.citrusframework.exceptions.CitrusRuntimeException; +import org.citrusframework.spi.Resources; +import org.citrusframework.http.actions.HttpActionBuilder; +import org.citrusframework.http.actions.HttpClientRequestActionBuilder; +import org.citrusframework.http.actions.HttpClientRequestActionBuilder.HttpMessageBuilderSupport; +import org.citrusframework.util.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.MediaType; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +import org.citrusframework.openapi.generator.rest.petstore.citrus.PetStoreAbstractTestRequest; + +import java.io.IOException; +import java.util.Base64; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + + +@Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen") +public class UserApi implements GeneratedApi +{ + + public static final UserApi INSTANCE = new UserApi(); + + public String getApiTitle() { + return "OpenAPI Petstore"; + } + + public String getApiVersion() { + return "1.0.0"; + } + + public String getApiPrefix() { + return "PetStore"; + } + + public Map getApiInfoExtensions() { + Map infoExtensionMap = new HashMap<>(); + infoExtensionMap.put("x-citrus-api-name", "petstore"); + infoExtensionMap.put("x-citrus-app", "PETS"); + return infoExtensionMap; + } + + /** createUser (POST /user) + Create user + + **/ + public static class CreateUserRequest extends PetStoreAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/user"; + private final Logger coverageLogger = LoggerFactory.getLogger(CreateUserRequest.class); + + + public CreateUserRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("PetStore".toLowerCase() + ":createUserRequestType"); + } + + public String getOperationName() { + return "createUser"; + } + + public String getMethod() { + return "POST"; + } + + public String getPath() { + return "/user"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .post(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "createUser;POST;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + private String replacePathParams(String endpoint) { + + return endpoint; + } + } + /** createUsersWithArrayInput (POST /user/createWithArray) + Creates list of users with given input array + + **/ + public static class CreateUsersWithArrayInputRequest extends PetStoreAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/user/createWithArray"; + private final Logger coverageLogger = LoggerFactory.getLogger(CreateUsersWithArrayInputRequest.class); + + + public CreateUsersWithArrayInputRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("PetStore".toLowerCase() + ":createUsersWithArrayInputRequestType"); + } + + public String getOperationName() { + return "createUsersWithArrayInput"; + } + + public String getMethod() { + return "POST"; + } + + public String getPath() { + return "/user/createWithArray"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .post(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "createUsersWithArrayInput;POST;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + private String replacePathParams(String endpoint) { + + return endpoint; + } + } + /** createUsersWithListInput (POST /user/createWithList) + Creates list of users with given input array + + **/ + public static class CreateUsersWithListInputRequest extends PetStoreAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/user/createWithList"; + private final Logger coverageLogger = LoggerFactory.getLogger(CreateUsersWithListInputRequest.class); + + + public CreateUsersWithListInputRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("PetStore".toLowerCase() + ":createUsersWithListInputRequestType"); + } + + public String getOperationName() { + return "createUsersWithListInput"; + } + + public String getMethod() { + return "POST"; + } + + public String getPath() { + return "/user/createWithList"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .post(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "createUsersWithListInput;POST;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + private String replacePathParams(String endpoint) { + + return endpoint; + } + } + /** deleteUser (DELETE /user/{username}) + Delete user + + **/ + public static class DeleteUserRequest extends PetStoreAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/user/{username}"; + private final Logger coverageLogger = LoggerFactory.getLogger(DeleteUserRequest.class); + + private String username; + + + public DeleteUserRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("PetStore".toLowerCase() + ":deleteUserRequestType"); + } + + public String getOperationName() { + return "deleteUser"; + } + + public String getMethod() { + return "DELETE"; + } + + public String getPath() { + return "/user/{username}"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .delete(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "deleteUser;DELETE;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + public void setUsername(String username) { + this.username = username; + } + + private String replacePathParams(String endpoint) { + endpoint = endpoint.replace("{" + "username" + "}", username); + return endpoint; + } + } + /** getUserByName (GET /user/{username}) + Get user by user name + + **/ + public static class GetUserByNameRequest extends PetStoreAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/user/{username}"; + private final Logger coverageLogger = LoggerFactory.getLogger(GetUserByNameRequest.class); + + private String username; + + + public GetUserByNameRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("PetStore".toLowerCase() + ":getUserByNameRequestType"); + } + + public String getOperationName() { + return "getUserByName"; + } + + public String getMethod() { + return "GET"; + } + + public String getPath() { + return "/user/{username}"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .get(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "getUserByName;GET;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + public void setUsername(String username) { + this.username = username; + } + + private String replacePathParams(String endpoint) { + endpoint = endpoint.replace("{" + "username" + "}", username); + return endpoint; + } + } + /** loginUser (GET /user/login) + Logs user into the system + + **/ + public static class LoginUserRequest extends PetStoreAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/user/login"; + private final Logger coverageLogger = LoggerFactory.getLogger(LoginUserRequest.class); + + private String username; + + private String password; + + + public LoginUserRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("PetStore".toLowerCase() + ":loginUserRequestType"); + } + + public String getOperationName() { + return "loginUser"; + } + + public String getMethod() { + return "GET"; + } + + public String getPath() { + return "/user/login"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .get(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + + if (StringUtils.isNotBlank(this.username)) { + queryParams.put("username", context.replaceDynamicContentInString(this.username)); + httpClientRequestActionBuilder.queryParam("username", this.username); + } + + + if (StringUtils.isNotBlank(this.password)) { + queryParams.put("password", context.replaceDynamicContentInString(this.password)); + httpClientRequestActionBuilder.queryParam("password", this.password); + } + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "loginUser;GET;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + public void setUsername(String username) { + this.username = username; + } + + public void setPassword(String password) { + this.password = password; + } + + private String replacePathParams(String endpoint) { + + return endpoint; + } + } + /** logoutUser (GET /user/logout) + Logs out current logged in user session + + **/ + public static class LogoutUserRequest extends PetStoreAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/user/logout"; + private final Logger coverageLogger = LoggerFactory.getLogger(LogoutUserRequest.class); + + + public LogoutUserRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("PetStore".toLowerCase() + ":logoutUserRequestType"); + } + + public String getOperationName() { + return "logoutUser"; + } + + public String getMethod() { + return "GET"; + } + + public String getPath() { + return "/user/logout"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .get(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "logoutUser;GET;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + private String replacePathParams(String endpoint) { + + return endpoint; + } + } + /** updateUser (PUT /user/{username}) + Updated user + + **/ + public static class UpdateUserRequest extends PetStoreAbstractTestRequest implements GeneratedApiRequest { + + private static final String ENDPOINT = "/user/{username}"; + private final Logger coverageLogger = LoggerFactory.getLogger(UpdateUserRequest.class); + + private String username; + + + public UpdateUserRequest() { + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("PetStore".toLowerCase() + ":updateUserRequestType"); + } + + public String getOperationName() { + return "updateUser"; + } + + public String getMethod() { + return "PUT"; + } + + public String getPath() { + return "/user/{username}"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() + .put(replacePathParams(ENDPOINT)); + + HttpMessageBuilderSupport messageBuilderSupport = httpClientRequestActionBuilder.getMessageBuilderSupport(); + messageBuilderSupport.accept(responseAcceptType); + + if (cookies != null) { + cookies.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + } + + if (headers != null) { + headers.forEach((k, v) -> messageBuilderSupport.cookie(new Cookie(k, v))); + headers.forEach(messageBuilderSupport::header); + } + + String bodyLog = ""; + String payload = null; + String payloadType = null; + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + bodyLog = body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""; + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); + httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); + + httpClientRequestActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "updateUser;PUT;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + bodyLog); + } + + public void setUsername(String username) { + this.username = username; + } + + private String replacePathParams(String endpoint) { + endpoint = endpoint.replace("{" + "username" + "}", username); + return endpoint; + } + } +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/spring/PetStoreBeanConfiguration.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/spring/PetStoreBeanConfiguration.java new file mode 100644 index 0000000000..cb89458c0b --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/rest/petstore/spring/PetStoreBeanConfiguration.java @@ -0,0 +1,142 @@ +/** + * ================================================== + * GENERATED CLASS, ALL CHANGES WILL BE LOST + * ================================================== + */ + +package org.citrusframework.openapi.generator.rest.petstore.spring; + +import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE; + +import org.citrusframework.openapi.generator.rest.petstore.request.PetApi; +import org.citrusframework.openapi.generator.rest.petstore.request.StoreApi; +import org.citrusframework.openapi.generator.rest.petstore.request.UserApi; +import javax.annotation.processing.Generated; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; + +@Configuration +@Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen") +public class PetStoreBeanConfiguration { + + @Bean + @Scope(SCOPE_PROTOTYPE) + public PetApi.AddPetRequest addPetRequest() { + return new PetApi.AddPetRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public PetApi.DeletePetRequest deletePetRequest() { + return new PetApi.DeletePetRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public PetApi.FindPetsByStatusRequest findPetsByStatusRequest() { + return new PetApi.FindPetsByStatusRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public PetApi.FindPetsByTagsRequest findPetsByTagsRequest() { + return new PetApi.FindPetsByTagsRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public PetApi.GetPetByIdRequest getPetByIdRequest() { + return new PetApi.GetPetByIdRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public PetApi.UpdatePetRequest updatePetRequest() { + return new PetApi.UpdatePetRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public PetApi.UpdatePetWithFormRequest updatePetWithFormRequest() { + return new PetApi.UpdatePetWithFormRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public PetApi.UploadFileRequest uploadFileRequest() { + return new PetApi.UploadFileRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public StoreApi.DeleteOrderRequest deleteOrderRequest() { + return new StoreApi.DeleteOrderRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public StoreApi.GetInventoryRequest getInventoryRequest() { + return new StoreApi.GetInventoryRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public StoreApi.GetOrderByIdRequest getOrderByIdRequest() { + return new StoreApi.GetOrderByIdRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public StoreApi.PlaceOrderRequest placeOrderRequest() { + return new StoreApi.PlaceOrderRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public UserApi.CreateUserRequest createUserRequest() { + return new UserApi.CreateUserRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public UserApi.CreateUsersWithArrayInputRequest createUsersWithArrayInputRequest() { + return new UserApi.CreateUsersWithArrayInputRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public UserApi.CreateUsersWithListInputRequest createUsersWithListInputRequest() { + return new UserApi.CreateUsersWithListInputRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public UserApi.DeleteUserRequest deleteUserRequest() { + return new UserApi.DeleteUserRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public UserApi.GetUserByNameRequest getUserByNameRequest() { + return new UserApi.GetUserByNameRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public UserApi.LoginUserRequest loginUserRequest() { + return new UserApi.LoginUserRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public UserApi.LogoutUserRequest logoutUserRequest() { + return new UserApi.LogoutUserRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public UserApi.UpdateUserRequest updateUserRequest() { + return new UserApi.UpdateUserRequest(); + } +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/soap/bookservice/citrus/OpenApiFromWsdlAbstractTestRequest.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/soap/bookservice/citrus/OpenApiFromWsdlAbstractTestRequest.java new file mode 100644 index 0000000000..8acda64ca3 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/soap/bookservice/citrus/OpenApiFromWsdlAbstractTestRequest.java @@ -0,0 +1,187 @@ +/** + * ================================================== + * GENERATED CLASS, ALL CHANGES WILL BE LOST + * ================================================== + */ + +package org.citrusframework.openapi.generator.soap.bookservice.citrus; + +import jakarta.annotation.Generated; +import java.util.List; +import java.util.ServiceLoader; +import org.citrusframework.actions.AbstractTestAction; +import org.citrusframework.context.TestContext; +import org.citrusframework.http.actions.HttpClientRequestActionBuilder; +import org.citrusframework.testapi.ApiActionBuilderCustomizerService; +import org.citrusframework.testapi.GeneratedApi; +import org.citrusframework.spi.Resources; +import org.citrusframework.validation.DelegatingPayloadVariableExtractor; +import org.citrusframework.validation.PathExpressionValidationContext; +import org.citrusframework.validation.script.ScriptValidationContext; +import org.citrusframework.ws.actions.ReceiveSoapMessageAction; +import org.citrusframework.ws.actions.ReceiveSoapMessageAction.SoapMessageBuilderSupport; +import org.citrusframework.ws.actions.SendSoapMessageAction; +import org.citrusframework.ws.actions.SoapActionBuilder; +import org.citrusframework.ws.client.WebServiceClient; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.util.CollectionUtils; + +import javax.sql.DataSource; +import java.util.Map; + +@Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen") +public abstract class OpenApiFromWsdlAbstractTestRequest extends AbstractTestAction { + + protected final Marker coverageMarker = MarkerFactory.getMarker("OPENAPIFROMWSDL-API-COVERAGE"); + + @Autowired + @Qualifier("soapSampleEndpoint") + protected WebServiceClient wsClient; + + @Autowired(required = false) + protected DataSource dataSource; + + @Autowired(required = false) + private List actionBuilderCustomizerServices; + + // attributes of differentNodes + protected String bodyContentType; + protected String bodyLiteralContentType; + protected String bodyFile; + protected String bodyLiteral; + + // children of response element + protected String resource; + protected Map responseVariable; // Contains the 'XPATH' as key and the 'VARIABLE NAME' as value + protected Map responseValue; // Contains the 'XPATH' as key and the 'VALUE TO BE VALIDATED' as value + protected String script; + protected String type; // default script type is groovy - supported types see com.consol.citrus.script.ScriptTypes + protected Map soapHeaders; + protected Map mimeHeaders; + + @Override + public void doExecute(TestContext context) { + sendRequest(context); + receiveResponse(context); + } + + /** + * This method receives the HTTP-Response + */ + public void receiveResponse(TestContext context) { + + ReceiveSoapMessageAction.Builder soapReceiveMessageActionBuilder = new SoapActionBuilder().client(wsClient).receive(); + SoapMessageBuilderSupport messageBuilderSupport = soapReceiveMessageActionBuilder.getMessageBuilderSupport(); + + if (resource != null) { + messageBuilderSupport.body(Resources.create(resource)); + } + + if (!CollectionUtils.isEmpty(responseVariable)) { + DelegatingPayloadVariableExtractor.Builder extractorBuilder = new DelegatingPayloadVariableExtractor.Builder(); + responseVariable.forEach(extractorBuilder::expression); + messageBuilderSupport.extract(extractorBuilder); + } + + if (!CollectionUtils.isEmpty(responseValue)) { + PathExpressionValidationContext.Builder validationContextBuilder = new PathExpressionValidationContext.Builder(); + responseValue.forEach(validationContextBuilder::expression); + messageBuilderSupport.validate(validationContextBuilder); + } + + if (script != null) { + ScriptValidationContext.Builder scriptValidationContextBuilder = new ScriptValidationContext.Builder(); + if (type != null) { + scriptValidationContextBuilder.scriptType(type); + } + scriptValidationContextBuilder.script(script); + messageBuilderSupport.validate(scriptValidationContextBuilder); + } + + soapReceiveMessageActionBuilder.withReferenceResolver(context.getReferenceResolver()); + soapReceiveMessageActionBuilder.build().execute(context); + } + + public abstract void sendRequest(TestContext context); + + public void setBodyLiteral(String bodyLiteral) { + this.bodyLiteral = bodyLiteral; + } + public void setBodyContentType(String bodyContentType) { + this.bodyContentType = bodyContentType; + } + + public void setBodyLiteralContentType(String bodyLiteralContentType) { + this.bodyLiteralContentType = bodyLiteralContentType; + } + + public void setBodyFile(String bodyFile) { + this.bodyFile = bodyFile; + } + + public void setResource(String resource) { + this.resource = resource; + } + + public void setResponseVariable(Map responseVariable) { + this.responseVariable = responseVariable; + } + + public void setResponseValue(Map responseValue) { + this.responseValue = responseValue; + } + + public void setScript(String script) { + this.script = script; + } + + public void setType(String type) { + this.type = type; + } + + public void setSoapHeader(Map soapHeaders) { + this.soapHeaders = soapHeaders; + } + + public void setMimeHeader(Map mimeHeaders) { + this.mimeHeaders = mimeHeaders; + } + + protected SendSoapMessageAction.Builder customizeBuilder(GeneratedApi generatedApi, + TestContext context, SendSoapMessageAction.Builder sendSoapMessageActionBuilder) { + + sendSoapMessageActionBuilder = customizeByBeans(generatedApi, context, sendSoapMessageActionBuilder); + + sendSoapMessageActionBuilder = customizeBySpi(generatedApi, context, sendSoapMessageActionBuilder); + + return sendSoapMessageActionBuilder; + } + + private SendSoapMessageAction.Builder customizeBySpi(GeneratedApi generatedApi, TestContext context, + SendSoapMessageAction.Builder sendSoapMessageActionBuilder) { + + ServiceLoader serviceLoader = ServiceLoader.load( + ApiActionBuilderCustomizerService.class, ApiActionBuilderCustomizerService.class.getClassLoader()); + for (ApiActionBuilderCustomizerService service :serviceLoader) { + sendSoapMessageActionBuilder = service.build(generatedApi, this, context, sendSoapMessageActionBuilder); + } + + return sendSoapMessageActionBuilder; + } + + private SendSoapMessageAction.Builder customizeByBeans( + GeneratedApi generatedApi, TestContext context, SendSoapMessageAction.Builder sendSoapMessageActionBuilder) { + + if (actionBuilderCustomizerServices != null) { + for (ApiActionBuilderCustomizerService apiActionBuilderCustomizer : actionBuilderCustomizerServices) { + sendSoapMessageActionBuilder = apiActionBuilderCustomizer.build(generatedApi, this, + context, sendSoapMessageActionBuilder); + } + } + + return sendSoapMessageActionBuilder; + } +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/soap/bookservice/citrus/OpenApiFromWsdlBeanDefinitionParser.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/soap/bookservice/citrus/OpenApiFromWsdlBeanDefinitionParser.java new file mode 100644 index 0000000000..1c72d58016 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/soap/bookservice/citrus/OpenApiFromWsdlBeanDefinitionParser.java @@ -0,0 +1,215 @@ +/** + * ================================================== + * GENERATED CLASS, ALL CHANGES WILL BE LOST + * ================================================== + */ + +package org.citrusframework.openapi.generator.soap.bookservice.citrus; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.annotation.processing.Generated; + +import org.citrusframework.exceptions.CitrusRuntimeException; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.core.Conventions; +import org.springframework.util.Assert; +import org.apache.commons.lang3.StringUtils; +import org.springframework.util.xml.DomUtils; +import org.w3c.dom.Attr; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; + + +@Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen") +public class OpenApiFromWsdlBeanDefinitionParser implements BeanDefinitionParser { + + private static final String COOKIE = "cookie"; + private static final String HEADER = "header"; + private static final String SOAP_HEADER = "soapHeader"; + private static final String MIME_HEADER = "mimeHeader"; + private static final String NAME = "name"; + private static final String REQUEST_BODY = "body"; + private static final String REQUEST_BODY_LITERAL = "bodyLiteral"; + private static final String MULTIPART_BODY = "multipartBody"; + private static final String RESPONSE = "response"; + private static final String RESPONSE_JSONPATH = "json-path"; + private static final String RESPONSE_XPATH = "xpath"; + private static final String EXPRESSION = "expression"; + private static final String VALUE = "value"; + private static final String RESPONSE_RESOURCE = "resource"; + private static final String FILE = "file"; + private static final String RESPONSE_VARIABLE = "responseVariable"; + private static final String RESPONSE_VALUE = "responseValue"; + private static final String SCRIPT = "script"; + private static final String TYPE = "type"; + private static final String SQL = "sql"; + private static final String COLUMN = "column"; + private static final String VARIABLE = "variable"; + // new + private static final String SCHEMA = "schema"; + // new + private static final String SCHEMA_VALIDATION = "schemaValidation"; + + private final Class beanClass; + + public OpenApiFromWsdlBeanDefinitionParser(Class beanClass) { + this.beanClass = beanClass; + } + + public BeanDefinition parse(Element element) { + return parse(element, null); + } + + /** + * Note: The {@link OpenApiFromWsdlBeanDefinitionParser#parse(Element element)} allows access direct + * access without the {@link org.springframework.beans.factory.xml.ParserContext} for convenience. + */ + @Override + public BeanDefinition parse(Element element, ParserContext parserContext) { + BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(beanClass); + retrieveRootNodeAttributes(element, builder); + retrieveOptionalNodeAttributes(element, REQUEST_BODY, builder); + retrieveTextContentAndNodeAttributes(element, REQUEST_BODY_LITERAL, builder); + retrieveOptionalNodeAttributes(element, RESPONSE, builder); + retrieveParamNodeData(element, builder, COOKIE); + retrieveParamNodeData(element, builder, HEADER); + retrieveParamNodeData(element, builder, SOAP_HEADER); + retrieveParamNodeData(element, builder, MIME_HEADER); + retrieveOptionalNodeAttributes(element, SCHEMA, builder); + retrieveOptionalNodeAttributes(element, SCHEMA_VALIDATION, builder); + retrieveOptionalMultipartElements(element, builder); + retrieveResponseNodeData(element, builder); + builder.addPropertyValue("name", element.getTagName()); + return builder.getBeanDefinition(); + } + + private void retrieveOptionalMultipartElements(Element element, BeanDefinitionBuilder builder) { + var multipartBodyElement = DomUtils.getChildElementByTagName(element, MULTIPART_BODY); + if (multipartBodyElement != null) { + var multipartBodyChildElements = DomUtils.getChildElements(multipartBodyElement); + for(int i = 0; i < multipartBodyChildElements.size(); i++){ + var multipartBodyChildElement = multipartBodyChildElements.get(i); + String propertyName = Conventions.attributeNameToPropertyName(multipartBodyChildElement.getLocalName()); + builder.addPropertyValue(propertyName, multipartBodyChildElement.getTextContent()); + } + } + } + + private void retrieveRootNodeAttributes(Element element, BeanDefinitionBuilder builder) { + NamedNodeMap attributes = element.getAttributes(); + for (int x = 0; x < attributes.getLength(); x++) { + Attr attribute = (Attr) attributes.item(x); + String propertyName = Conventions.attributeNameToPropertyName(attribute.getLocalName()); + Assert.state(StringUtils.isNotBlank(propertyName), "Illegal property name returned, it must not be null or empty."); + builder.addPropertyValue(propertyName, attribute.getValue()); + } + } + + private void retrieveOptionalNodeAttributes(Element element, String elementName, BeanDefinitionBuilder builder) { + if (!DomUtils.getChildElementsByTagName(element, elementName).isEmpty()) { + Element el = DomUtils.getChildElementsByTagName(element, elementName).get(0); + NamedNodeMap attributes = el.getAttributes(); + for (int x = 0; x < attributes.getLength(); x++) { + Attr attribute = (Attr) attributes.item(x); + String propertyName = Conventions.attributeNameToPropertyName(attribute.getLocalName()); + Assert.state(StringUtils.isNotBlank(propertyName), "Illegal property name returned, it must not be null or empty."); + String variableName = el.getLocalName() + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1); + builder.addPropertyValue(variableName, attribute.getValue()); + } + } + } + + private void retrieveTextContentAndNodeAttributes(Element element, String elementName, BeanDefinitionBuilder builder) { + if (!DomUtils.getChildElementsByTagName(element, elementName).isEmpty()) { + Element el1 = DomUtils.getChildElementsByTagName(element, elementName).get(0); + NamedNodeMap attributes = el1.getAttributes(); + for (int x = 0; x < attributes.getLength(); x++) { + Attr attribute = (Attr) attributes.item(x); + String propertyName1 = Conventions.attributeNameToPropertyName(attribute.getLocalName()); + Assert.state(StringUtils.isNotBlank(propertyName1), "Illegal property name returned, it must not be null or empty."); + String variableName = el1.getLocalName() + propertyName1.substring(0, 1).toUpperCase() + propertyName1.substring(1); + builder.addPropertyValue(variableName, attribute.getValue()); + } + Element el = DomUtils.getChildElementsByTagName(element, elementName).get(0); + builder.addPropertyValue(elementName, el.getTextContent()); + } + } + + private void retrieveParamNodeData(Element element, BeanDefinitionBuilder builder, String paramType) { + if (!DomUtils.getChildElementsByTagName(element, paramType).isEmpty()) { + Map params = new HashMap<>(); + List elements = DomUtils.getChildElementsByTagName(element, paramType); + elements.forEach(e -> { + String name = e.getAttribute(NAME); + String value = e.getAttribute(VALUE); + + Assert.state(StringUtils.isNotBlank(name), "Illegal attribute value returned. The 'name' attribute must not be null or empty."); + Assert.state(StringUtils.isNotBlank(value), "Illegal attribute value returned. The 'value' attribute must not be null or empty."); + + params.put(name, value); + }); + builder.addPropertyValue(paramType, params); + } + } + + private void retrieveResponseNodeData(Element element, BeanDefinitionBuilder builder) { + + if (!DomUtils.getChildElementsByTagName(element, RESPONSE).isEmpty()) { + Element response = DomUtils.getChildElementsByTagName(element, RESPONSE).get(0); + List elements = DomUtils.getChildElements(response); + + Map responseVariable = new HashMap<>(); + Map responseValue = new HashMap<>(); + + for (int i = 0; i < elements.size(); i++) { + Element e = elements.get(i); + + if (e.getTagName().contains(RESPONSE_JSONPATH) || e.getTagName().contains(RESPONSE_XPATH)) { + String expression = e.getAttribute(EXPRESSION); + String value = e.getAttribute(VALUE); + + Assert.state(StringUtils.isNotBlank(expression), "Illegal attribute value returned. The 'expression' attribute must not be null or empty."); + Assert.state(StringUtils.isNotBlank(value), "Illegal attribute value returned. The 'value' attribute must not be null or empty."); + + // variable to save @variable('ebid')@ else value to validate + if (value.matches("\\@variable\\('.*'\\)\\@")) { + Matcher match = Pattern.compile("\\'(.*?)\\'").matcher(value); + if (match.find()) { + responseVariable.put(expression, value.substring(match.start() + 1, match.end() - 1)); + } + } else { + responseValue.put(expression, value); + } + } else if (e.getTagName().contains(SCRIPT)) { + String script = e.getTextContent(); + Assert.state(StringUtils.isNotBlank(script), "Illegal attribute value returned. The 'script' attribute must not be null or empty."); + builder.addPropertyValue(SCRIPT, script); + + if (!e.getAttribute(TYPE).isEmpty()) { + String type = e.getAttribute(TYPE); + Assert.state(StringUtils.isNotBlank(type), "Illegal attribute value returned. The 'type' attribute must not be null or empty."); + builder.addPropertyValue(TYPE, type); + } + } else if (e.getTagName().contains(RESPONSE_RESOURCE)) { + String filePath = e.getAttribute(FILE); + Assert.state(StringUtils.isNotBlank(filePath), "Illegal attribute value returned. The 'file' attribute must not be null or empty."); + builder.addPropertyValue(RESPONSE_RESOURCE, filePath); + } + + } + + builder.addPropertyValue(RESPONSE_VARIABLE, responseVariable); + builder.addPropertyValue(RESPONSE_VALUE, responseValue); + } + } +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/soap/bookservice/citrus/extension/OpenApiFromWsdlNamespaceHandler.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/soap/bookservice/citrus/extension/OpenApiFromWsdlNamespaceHandler.java new file mode 100644 index 0000000000..04773ddb99 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/soap/bookservice/citrus/extension/OpenApiFromWsdlNamespaceHandler.java @@ -0,0 +1,26 @@ +/** + * ================================================== + * GENERATED CLASS, ALL CHANGES WILL BE LOST + * ================================================== + */ + +package org.citrusframework.openapi.generator.soap.bookservice.citrus.extension; + +import org.citrusframework.openapi.generator.soap.bookservice.request.BookServiceSoapApi; +import org.citrusframework.openapi.generator.soap.bookservice.citrus.OpenApiFromWsdlBeanDefinitionParser; + +import javax.annotation.processing.Generated; + +import org.springframework.beans.factory.xml.NamespaceHandlerSupport; + + +@Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen") +public class OpenApiFromWsdlNamespaceHandler extends NamespaceHandlerSupport { + + @Override + public void init() { + registerBeanDefinitionParser("addBookRequest", new OpenApiFromWsdlBeanDefinitionParser(BookServiceSoapApi.AddBookRequest.class)); + registerBeanDefinitionParser("getAllBooksRequest", new OpenApiFromWsdlBeanDefinitionParser(BookServiceSoapApi.GetAllBooksRequest.class)); + registerBeanDefinitionParser("getBookRequest", new OpenApiFromWsdlBeanDefinitionParser(BookServiceSoapApi.GetBookRequest.class)); + } +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/soap/bookservice/request/BookServiceSoapApi.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/soap/bookservice/request/BookServiceSoapApi.java new file mode 100644 index 0000000000..dd84878034 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/soap/bookservice/request/BookServiceSoapApi.java @@ -0,0 +1,330 @@ +/** + * ================================================== + * GENERATED CLASS, ALL CHANGES WILL BE LOST + * ================================================== + */ + +package org.citrusframework.openapi.generator.soap.bookservice.request; + +import jakarta.annotation.Generated; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; +import org.citrusframework.context.TestContext; +import org.citrusframework.exceptions.CitrusRuntimeException; +import org.citrusframework.testapi.GeneratedApi; +import org.citrusframework.testapi.GeneratedApiRequest; +import org.citrusframework.openapi.generator.soap.bookservice.citrus.OpenApiFromWsdlAbstractTestRequest; +import org.citrusframework.spi.Resources; +import org.citrusframework.util.FileUtils; +import org.citrusframework.ws.actions.SendSoapMessageAction; +import org.citrusframework.ws.actions.SendSoapMessageAction.Builder.SendSoapMessageBuilderSupport; +import org.citrusframework.ws.actions.SoapActionBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.CollectionUtils; + +import org.citrusframework.openapi.generator.soap.bookservice.citrus.OpenApiFromWsdlAbstractTestRequest; + +@Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen") +public class BookServiceSoapApi implements GeneratedApi +{ + public static final BookServiceSoapApi INSTANCE = new BookServiceSoapApi(); + + public String getApiTitle() { + return "Generated api from wsdl"; + } + + public String getApiVersion() { + return "1.0.0"; + } + + public String getApiPrefix() { + return "OpenApiFromWsdl"; + } + + public Map getApiInfoExtensions() { + Map infoExtensionMap = new HashMap<>(); + return infoExtensionMap; + } + + /** + addBook (POST /AddBook) + + + **/ + public static class AddBookRequest extends OpenApiFromWsdlAbstractTestRequest implements GeneratedApiRequest { + + private final Logger coverageLogger = LoggerFactory.getLogger(AddBookRequest.class); + + // Query params + + + public AddBookRequest(){ + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("OpenApiFromWsdl".toLowerCase() + ":addBookRequestType"); + } + + public String getOperationName() { + return "addBook"; + } + + public String getMethod() { + return "POST"; + } + + public String getPath() { + return "/AddBook"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + + SendSoapMessageAction.Builder soapSendMessageActionBuilder = new SoapActionBuilder().client(wsClient).send(); + SendSoapMessageBuilderSupport messageBuilderSupport = soapSendMessageActionBuilder.getMessageBuilderSupport(); + + messageBuilderSupport.soapAction("addBook"); + + String payload = null; + String payloadType = null; + + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + if (!CollectionUtils.isEmpty(soapHeaders)) { + for (Entry entry : soapHeaders.entrySet()) { + messageBuilderSupport = messageBuilderSupport.header(entry.getKey(), + entry.getValue()); + } + } + + if (!CollectionUtils.isEmpty(mimeHeaders)) { + for (Entry entry : mimeHeaders.entrySet()) { + messageBuilderSupport = messageBuilderSupport.header("citrus_http_" + entry.getKey(), + entry.getValue()); + } + } + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + soapSendMessageActionBuilder.withReferenceResolver(context.getReferenceResolver()); + soapSendMessageActionBuilder = customizeBuilder(INSTANCE, context, soapSendMessageActionBuilder); + + soapSendMessageActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "addBook;POST;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""); + } + + + } + /** + getAllBooks (POST /GetAllBooks) + + + **/ + public static class GetAllBooksRequest extends OpenApiFromWsdlAbstractTestRequest implements GeneratedApiRequest { + + private final Logger coverageLogger = LoggerFactory.getLogger(GetAllBooksRequest.class); + + // Query params + + + public GetAllBooksRequest(){ + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("OpenApiFromWsdl".toLowerCase() + ":getAllBooksRequestType"); + } + + public String getOperationName() { + return "getAllBooks"; + } + + public String getMethod() { + return "POST"; + } + + public String getPath() { + return "/GetAllBooks"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + + SendSoapMessageAction.Builder soapSendMessageActionBuilder = new SoapActionBuilder().client(wsClient).send(); + SendSoapMessageBuilderSupport messageBuilderSupport = soapSendMessageActionBuilder.getMessageBuilderSupport(); + + messageBuilderSupport.soapAction("getAllBooks"); + + String payload = null; + String payloadType = null; + + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + if (!CollectionUtils.isEmpty(soapHeaders)) { + for (Entry entry : soapHeaders.entrySet()) { + messageBuilderSupport = messageBuilderSupport.header(entry.getKey(), + entry.getValue()); + } + } + + if (!CollectionUtils.isEmpty(mimeHeaders)) { + for (Entry entry : mimeHeaders.entrySet()) { + messageBuilderSupport = messageBuilderSupport.header("citrus_http_" + entry.getKey(), + entry.getValue()); + } + } + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + soapSendMessageActionBuilder.withReferenceResolver(context.getReferenceResolver()); + soapSendMessageActionBuilder = customizeBuilder(INSTANCE, context, soapSendMessageActionBuilder); + + soapSendMessageActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "getAllBooks;POST;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""); + } + + + } + /** + getBook (POST /GetBook) + + + **/ + public static class GetBookRequest extends OpenApiFromWsdlAbstractTestRequest implements GeneratedApiRequest { + + private final Logger coverageLogger = LoggerFactory.getLogger(GetBookRequest.class); + + // Query params + + + public GetBookRequest(){ + // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml + setName("OpenApiFromWsdl".toLowerCase() + ":getBookRequestType"); + } + + public String getOperationName() { + return "getBook"; + } + + public String getMethod() { + return "POST"; + } + + public String getPath() { + return "/GetBook"; + } + + /** + * This method sends the HTTP-Request + */ + public void sendRequest(TestContext context) { + + SendSoapMessageAction.Builder soapSendMessageActionBuilder = new SoapActionBuilder().client(wsClient).send(); + SendSoapMessageBuilderSupport messageBuilderSupport = soapSendMessageActionBuilder.getMessageBuilderSupport(); + + messageBuilderSupport.soapAction("getBook"); + + String payload = null; + String payloadType = null; + + if (StringUtils.isNotBlank(this.bodyFile)) { + try { + payload = FileUtils.readToString(Resources.create(this.bodyFile), FileUtils.getDefaultCharset()); + } catch (IOException e) { + throw new CitrusRuntimeException("Failed to read payload resource", e); + } + payloadType = this.bodyContentType; + } else if (StringUtils.isNotBlank(this.bodyLiteral)) { + payload = this.bodyLiteral; + payloadType = this.bodyLiteralContentType; + } + + String body = ""; + String bodyType = ""; + if(payload != null && payloadType != null) { + messageBuilderSupport.body(payload).contentType(payloadType); + body = context.replaceDynamicContentInString(payload); + bodyType = context.replaceDynamicContentInString(payloadType); + } + + if (!CollectionUtils.isEmpty(soapHeaders)) { + for (Entry entry : soapHeaders.entrySet()) { + messageBuilderSupport = messageBuilderSupport.header(entry.getKey(), + entry.getValue()); + } + } + + if (!CollectionUtils.isEmpty(mimeHeaders)) { + for (Entry entry : mimeHeaders.entrySet()) { + messageBuilderSupport = messageBuilderSupport.header("citrus_http_" + entry.getKey(), + entry.getValue()); + } + } + + Map queryParams = new HashMap<>(); + + String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + + soapSendMessageActionBuilder.withReferenceResolver(context.getReferenceResolver()); + soapSendMessageActionBuilder = customizeBuilder(INSTANCE, context, soapSendMessageActionBuilder); + + soapSendMessageActionBuilder.build().execute(context); + + coverageLogger.trace(coverageMarker, "getBook;POST;\"" + + query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + + body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""); + } + + + } +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/soap/bookservice/spring/OpenApiFromWsdlBeanConfiguration.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/soap/bookservice/spring/OpenApiFromWsdlBeanConfiguration.java new file mode 100644 index 0000000000..e462cae9f8 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIntegrationTest/expectedgen/soap/bookservice/spring/OpenApiFromWsdlBeanConfiguration.java @@ -0,0 +1,38 @@ +/** + * ================================================== + * GENERATED CLASS, ALL CHANGES WILL BE LOST + * ================================================== + */ + +package org.citrusframework.openapi.generator.soap.bookservice.spring; + +import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE; + +import org.citrusframework.openapi.generator.soap.bookservice.request.BookServiceSoapApi; +import javax.annotation.processing.Generated; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; + +@Configuration +@Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen") +public class OpenApiFromWsdlBeanConfiguration { + + @Bean + @Scope(SCOPE_PROTOTYPE) + public BookServiceSoapApi.AddBookRequest addBookRequest() { + return new BookServiceSoapApi.AddBookRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public BookServiceSoapApi.GetAllBooksRequest getAllBooksRequest() { + return new BookServiceSoapApi.GetAllBooksRequest(); + } + + @Bean + @Scope(SCOPE_PROTOTYPE) + public BookServiceSoapApi.GetBookRequest getBookRequest() { + return new BookServiceSoapApi.GetBookRequest(); + } +} diff --git a/test-api-generator/citrus-test-api-generator-maven-plugin/pom.xml b/test-api-generator/citrus-test-api-generator-maven-plugin/pom.xml index 134d44aee9..ec01838c57 100644 --- a/test-api-generator/citrus-test-api-generator-maven-plugin/pom.xml +++ b/test-api-generator/citrus-test-api-generator-maven-plugin/pom.xml @@ -36,6 +36,7 @@ + org.citrusframework citrus-test-api-generator-core