diff --git a/catalog/citrus-bom/pom.xml b/catalog/citrus-bom/pom.xml index 0e0aa4a2f4..d542f0bbae 100644 --- a/catalog/citrus-bom/pom.xml +++ b/catalog/citrus-bom/pom.xml @@ -238,6 +238,21 @@ citrus-openapi 4.4.0-SNAPSHOT + + org.citrusframework + citrus-test-api-core + 4.4.0-SNAPSHOT + + + org.citrusframework + citrus-test-api-generator-core + 4.4.0-SNAPSHOT + + + org.citrusframework + citrus-test-api-spring + 4.4.0-SNAPSHOT + org.citrusframework citrus-jms diff --git a/connectors/citrus-openapi/README.md b/connectors/citrus-openapi/README.md new file mode 100644 index 0000000000..7669d15a9e --- /dev/null +++ b/connectors/citrus-openapi/README.md @@ -0,0 +1,6 @@ +// TODO +OpenApiServerRequest +- SchemaValidation is active by default (also in other scenarios) + +Oas Validation now by ValidationFramework +- no control response message is created any more \ No newline at end of file diff --git a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/OpenApiPathRegistry.java b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/OpenApiPathRegistry.java deleted file mode 100644 index 6218baaceb..0000000000 --- a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/OpenApiPathRegistry.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.citrusframework.openapi; - -import org.citrusframework.exceptions.CitrusRuntimeException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; - -import static java.lang.String.format; - -/** - * A registry to store objects by OpenApi paths. The registry uses a digital tree data structure - * that performs path matching with variable placeholders. Variable - * placeholders must be enclosed in curly braces '{}', e.g., '/api/v1/pet/{id}'. This data structure - * is optimized for matching paths efficiently, handling both static and dynamic segments. - *

- * This class is currently not in use but may serve scenarios where a path needs to be mapped to an - * OasOperation without explicit knowledge of the API to which the path belongs. - * It could be utilized, for instance, in implementing an OAS message validator based on - * {@link org.citrusframework.validation.AbstractMessageValidator}. - */ -public class OpenApiPathRegistry { - - private static final Logger logger = LoggerFactory.getLogger(OpenApiPathRegistry.class); - - private final RegistryNode root = new RegistryNode(); - - private final Map allPaths = new ConcurrentHashMap<>(); - - public T search(String path) { - RegistryNode trieNode = internalSearch(path); - return trieNode != null ? trieNode.value : null; - } - - RegistryNode internalSearch(String path) { - String[] segments = path.split("/"); - return searchHelper(root, segments, 0); - } - - public boolean insert(String path, T value) { - return insertInternal(path, value) != null; - } - - RegistryNode insertInternal(String path, T value) { - - if (path == null || value == null) { - return null; - } - - String[] segments = path.split("/"); - RegistryNode node = root; - - if (!allPaths.isEmpty() && (isPathAlreadyContainedWithDifferentValue(path, value) - || isPathMatchedByOtherPath(path, value))) { - return null; - } - - allPaths.put(path, value); - StringBuilder builder = new StringBuilder(); - for (String segment : segments) { - if (builder.isEmpty() || builder.charAt(builder.length() - 1) != '/') { - builder.append("/"); - } - builder.append(segment); - - if (!node.children.containsKey(segment)) { - RegistryNode trieNode = new RegistryNode(); - trieNode.path = builder.toString(); - node.children.put(segment, trieNode); - } - node = node.children.get(segment); - } - - // Sanity check to disallow overwrite of existing values - if (node.value != null && !node.value.equals(value)) { - throw new CitrusRuntimeException(format( - "Illegal attempt to overwrite an existing node value. This is probably a bug. path=%s value=%s", - node.path, node.value)); - } - node.value = value; - - return node; - } - - /** - * Tests if the path is either matching an existing path or any existing path matches the given - * patch. - *

- * For example '/a/b' does not match '/{a}/{b}', but '/{a}/{b}' matches '/a/b'. - */ - private boolean isPathMatchedByOtherPath(String path, T value) { - - // Does the given path match any existing - RegistryNode currentValue = internalSearch(path); - if (currentValue != null && !Objects.equals(path, currentValue.path)) { - logger.error( - "Attempt to insert an equivalent path potentially overwriting an existing value. Value for path is ignored: path={}, value={} currentValue={} ", - path, currentValue, value); - return true; - } - - // Does any existing match the path. - OpenApiPathRegistry tmpTrie = new OpenApiPathRegistry<>(); - tmpTrie.insert(path, value); - - List allMatching = allPaths.keySet().stream() - .filter(existingPath -> { - RegistryNode trieNode = tmpTrie.internalSearch(existingPath); - return trieNode != null && !existingPath.equals(trieNode.path); - }).map(existingPath -> "'" + existingPath + "'").toList(); - if (!allMatching.isEmpty() && logger.isErrorEnabled()) { - logger.error( - "Attempt to insert an equivalent path overwritten by existing paths. Value for path is ignored: path={}, value={} existingPaths=[{}]", - path, currentValue, String.join(",", allMatching)); - - } - - return !allMatching.isEmpty(); - } - - private boolean isPathAlreadyContainedWithDifferentValue(String path, T value) { - T currentValue = allPaths.get(path); - if (currentValue != null) { - if (value.equals(currentValue)) { - return false; - } - logger.error( - "Attempt to overwrite value for path is ignored: path={}, value={} currentValue={} ", - path, currentValue, value); - return true; - } - return false; - } - - private RegistryNode searchHelper(RegistryNode node, String[] segments, int index) { - if (node == null) { - return null; - } - if (index == segments.length) { - return node; - } - - String segment = segments[index]; - - // Exact match - if (node.children.containsKey(segment)) { - RegistryNode foundNode = searchHelper(node.children.get(segment), segments, index + 1); - if (foundNode != null && foundNode.value != null) { - return foundNode; - } - } - - // Variable match - for (String key : node.children.keySet()) { - if (key.startsWith("{") && key.endsWith("}")) { - RegistryNode foundNode = searchHelper(node.children.get(key), segments, index + 1); - if (foundNode != null && foundNode.value != null) { - return foundNode; - } - } - } - - return null; - } - - class RegistryNode { - Map children = new HashMap<>(); - String path; - T value = null; - } -} diff --git a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/OpenApiResourceLoader.java b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/OpenApiResourceLoader.java index df39c8a2f5..7f4e31efa3 100644 --- a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/OpenApiResourceLoader.java +++ b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/OpenApiResourceLoader.java @@ -21,6 +21,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; import io.apicurio.datamodels.Library; import io.apicurio.datamodels.openapi.models.OasDocument; +import java.io.InputStream; +import java.net.URLConnection; import org.apache.hc.client5.http.ssl.NoopHostnameVerifier; import org.apache.hc.client5.http.ssl.TrustAllStrategy; import org.apache.hc.core5.http.HttpHeaders; @@ -109,24 +111,31 @@ public static String rawFromWebResource(URL url) { } private static T fromWebResource(URL url, Resolver resolver) { - HttpURLConnection con = null; + URLConnection con = null; try { - con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod(HttpMethod.GET.name()); - con.setRequestProperty(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE); + con = url.openConnection(); + + if (con instanceof HttpURLConnection httpURLConnection) { + httpURLConnection.setRequestMethod(HttpMethod.GET.name()); + con.setRequestProperty(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE); + + int status = httpURLConnection.getResponseCode(); + if (status > 299) { + throw new IllegalStateException( + "Failed to retrieve Open API specification: " + url, + new IOException(FileUtils.readToString(httpURLConnection.getErrorStream()))); + } + } - int status = con.getResponseCode(); - if (status > 299) { - throw new IllegalStateException("Failed to retrieve Open API specification: " + url, - new IOException(FileUtils.readToString(con.getErrorStream()))); - } else { - return resolve(FileUtils.readToString(con.getInputStream()), resolver); + try (InputStream inputStream = con.getInputStream()) { + return resolve(FileUtils.readToString(inputStream), resolver); } + } catch (IOException e) { throw new IllegalStateException("Failed to retrieve Open API specification: " + url, e); } finally { - if (con != null) { - con.disconnect(); + if (con instanceof HttpURLConnection httpURLConnection) { + httpURLConnection.disconnect(); } } } diff --git a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/OpenApiSpecification.java b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/OpenApiSpecification.java index b344e7d9cd..a31d84019f 100644 --- a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/OpenApiSpecification.java +++ b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/OpenApiSpecification.java @@ -41,8 +41,8 @@ import org.citrusframework.openapi.model.OasModelHelper; import org.citrusframework.openapi.model.OperationPathAdapter; import org.citrusframework.openapi.util.OpenApiUtils; -import org.citrusframework.openapi.validation.SwaggerOpenApiValidationContext; -import org.citrusframework.openapi.validation.SwaggerOpenApiValidationContextLoader; +import org.citrusframework.openapi.validation.OpenApiValidationContext; +import org.citrusframework.openapi.validation.OpenApiValidationContextLoader; import org.citrusframework.spi.Resource; import org.citrusframework.spi.Resources; import org.citrusframework.util.StringUtils; @@ -95,7 +95,7 @@ public class OpenApiSpecification { private OasDocument openApiDoc; - private SwaggerOpenApiValidationContext swaggerOpenApiValidationContext; + private OpenApiValidationContext openApiValidationContext; private boolean generateOptionalFields = isGenerateOptionalFieldsGlobally(); @@ -140,19 +140,19 @@ public static OpenApiSpecification from(String specUrl) { public static OpenApiSpecification from(URL specUrl) { OpenApiSpecification specification = new OpenApiSpecification(); OasDocument openApiDoc; - SwaggerOpenApiValidationContext swaggerOpenApiValidationContext; + OpenApiValidationContext openApiValidationContext; if (specUrl.getProtocol().startsWith(HTTPS)) { openApiDoc = OpenApiResourceLoader.fromSecuredWebResource(specUrl); - swaggerOpenApiValidationContext = SwaggerOpenApiValidationContextLoader.fromSecuredWebResource(specUrl); + openApiValidationContext = OpenApiValidationContextLoader.fromSecuredWebResource(specUrl); } else { openApiDoc = OpenApiResourceLoader.fromWebResource(specUrl); - swaggerOpenApiValidationContext = SwaggerOpenApiValidationContextLoader.fromWebResource(specUrl); + openApiValidationContext = OpenApiValidationContextLoader.fromWebResource(specUrl); } specification.setSpecUrl(specUrl.toString()); specification.initPathLookups(); specification.setOpenApiDoc(openApiDoc); - specification.setSwaggerOpenApiValidationContext(swaggerOpenApiValidationContext); + specification.setOpenApiValidationContext(openApiValidationContext); specification.setRequestUrl( String.format("%s://%s%s%s", specUrl.getProtocol(), specUrl.getHost(), specUrl.getPort() > 0 ? ":" + specUrl.getPort() : "", @@ -166,7 +166,7 @@ public static OpenApiSpecification from(Resource resource) { OasDocument openApiDoc = OpenApiResourceLoader.fromFile(resource); specification.setOpenApiDoc(openApiDoc); - specification.setSwaggerOpenApiValidationContext(SwaggerOpenApiValidationContextLoader.fromFile(resource)); + specification.setOpenApiValidationContext(OpenApiValidationContextLoader.fromFile(resource)); String schemeToUse = Optional.ofNullable(OasModelHelper.getSchemes(openApiDoc)) .orElse(Collections.singletonList(HTTP)) @@ -218,10 +218,10 @@ public synchronized OasDocument getOpenApiDoc(TestContext context) { initApiDoc( () -> OpenApiResourceLoader.fromSecuredWebResource(specWebResource)); - setSwaggerOpenApiValidationContext(SwaggerOpenApiValidationContextLoader.fromSecuredWebResource(specWebResource)); + setOpenApiValidationContext(OpenApiValidationContextLoader.fromSecuredWebResource(specWebResource)); } else { initApiDoc(() -> OpenApiResourceLoader.fromWebResource(specWebResource)); - setSwaggerOpenApiValidationContext(SwaggerOpenApiValidationContextLoader.fromWebResource(specWebResource)); + setOpenApiValidationContext(OpenApiValidationContextLoader.fromWebResource(specWebResource)); } if (requestUrl == null) { @@ -235,7 +235,7 @@ public synchronized OasDocument getOpenApiDoc(TestContext context) { Resource resource = Resources.create(resolvedSpecUrl); initApiDoc( () -> OpenApiResourceLoader.fromFile(resource)); - setSwaggerOpenApiValidationContext(SwaggerOpenApiValidationContextLoader.fromFile(resource)); + setOpenApiValidationContext(OpenApiValidationContextLoader.fromFile(resource)); if (requestUrl == null) { String schemeToUse = Optional.ofNullable(OasModelHelper.getSchemes(openApiDoc)) @@ -255,8 +255,8 @@ public synchronized OasDocument getOpenApiDoc(TestContext context) { return openApiDoc; } - public SwaggerOpenApiValidationContext getSwaggerOpenApiValidationContext() { - return swaggerOpenApiValidationContext; + public OpenApiValidationContext getOpenApiValidationContext() { + return openApiValidationContext; } @@ -274,10 +274,11 @@ void setOpenApiDoc(OasDocument openApiDoc) { initApiDoc(() -> openApiDoc); } - private void setSwaggerOpenApiValidationContext(SwaggerOpenApiValidationContext swaggerOpenApiValidationContext) { - this.swaggerOpenApiValidationContext = swaggerOpenApiValidationContext; - this.swaggerOpenApiValidationContext.setResponseValidationEnabled(apiResponseValidationEnabled); - this.swaggerOpenApiValidationContext.setRequestValidationEnabled(apiRequestValidationEnabled); + private void setOpenApiValidationContext( + OpenApiValidationContext openApiValidationContext) { + this.openApiValidationContext = openApiValidationContext; + this.openApiValidationContext.setResponseValidationEnabled(apiResponseValidationEnabled); + this.openApiValidationContext.setRequestValidationEnabled(apiRequestValidationEnabled); } private void initApiDoc(Supplier openApiDocSupplier) { @@ -323,8 +324,7 @@ private void storeOperationPathAdapter(OasOperation operation, String path) { String basePath = OasModelHelper.getBasePath(openApiDoc); String fullOperationPath = StringUtils.appendSegmentToUrlPath(basePath, path); - String uniqueOperationId = OpenApiUtils.createFullPathOperationIdentifier(fullOperationPath, - operation); + String uniqueOperationId = OpenApiUtils.createFullPathOperationIdentifier(operation, fullOperationPath); operationToUniqueId.put(operation, uniqueOperationId); OperationPathAdapter operationPathAdapter = new OperationPathAdapter(path, rootContextPath, @@ -370,8 +370,8 @@ public boolean isApiRequestValidationEnabled() { public void setApiRequestValidationEnabled(boolean enabled) { this.apiRequestValidationEnabled = enabled; - if (this.swaggerOpenApiValidationContext != null) { - this.swaggerOpenApiValidationContext.setRequestValidationEnabled(enabled); + if (this.openApiValidationContext != null) { + this.openApiValidationContext.setRequestValidationEnabled(enabled); } } @@ -381,8 +381,8 @@ public boolean isApiResponseValidationEnabled() { public void setApiResponseValidationEnabled(boolean enabled) { this.apiResponseValidationEnabled = enabled; - if (this.swaggerOpenApiValidationContext != null) { - this.swaggerOpenApiValidationContext.setResponseValidationEnabled(enabled); + if (this.openApiValidationContext != null) { + this.openApiValidationContext.setResponseValidationEnabled(enabled); } } diff --git a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/actions/OpenApiClientRequestActionBuilder.java b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/actions/OpenApiClientRequestActionBuilder.java index ee009fe5aa..3bd3e484cb 100644 --- a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/actions/OpenApiClientRequestActionBuilder.java +++ b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/actions/OpenApiClientRequestActionBuilder.java @@ -16,13 +16,15 @@ package org.citrusframework.openapi.actions; +import static org.citrusframework.openapi.OpenApiTestDataGenerator.createRandomValueExpression; +import static org.citrusframework.util.StringUtils.isNotEmpty; + import io.apicurio.datamodels.openapi.models.OasOperation; import io.apicurio.datamodels.openapi.models.OasParameter; import io.apicurio.datamodels.openapi.models.OasSchema; import java.util.List; import java.util.Locale; import java.util.Optional; -import java.util.regex.Pattern; import org.citrusframework.CitrusSettings; import org.citrusframework.actions.SendMessageAction; import org.citrusframework.context.TestContext; @@ -37,6 +39,7 @@ import org.citrusframework.openapi.model.OasModelHelper; import org.citrusframework.openapi.model.OperationPathAdapter; import org.citrusframework.openapi.validation.OpenApiMessageProcessor; +import org.citrusframework.openapi.validation.OpenApiValidationContext; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -51,7 +54,7 @@ public class OpenApiClientRequestActionBuilder extends HttpClientRequestActionBu private final String operationId; - private boolean oasValidationEnabled = true; + private boolean schemaValidation = true; /** * Default constructor initializes http request message builder. @@ -64,9 +67,14 @@ public OpenApiClientRequestActionBuilder(OpenApiSpecificationSource openApiSpec, public OpenApiClientRequestActionBuilder(HttpMessage httpMessage, OpenApiSpecificationSource openApiSpec, String operationId) { - super(new OpenApiClientRequestMessageBuilder(httpMessage, openApiSpec, operationId), - httpMessage); + this(openApiSpec, new OpenApiClientRequestMessageBuilder(httpMessage, openApiSpec, operationId), + httpMessage, operationId); + } + public OpenApiClientRequestActionBuilder(OpenApiSpecificationSource openApiSpec, + OpenApiClientRequestMessageBuilder messageBuilder, HttpMessage message, + String operationId) { + super(messageBuilder, message); this.openApiSpecificationSource = openApiSpec; this.operationId = operationId; } @@ -75,8 +83,14 @@ public OpenApiClientRequestActionBuilder(HttpMessage httpMessage, public SendMessageAction doBuild() { OpenApiSpecification openApiSpecification = openApiSpecificationSource.resolve( referenceResolver); - if (oasValidationEnabled && !messageProcessors.contains( - openApiMessageProcessor)) { + + // Honor default enablement of schema validation + OpenApiValidationContext openApiValidationContext = openApiSpecification.getOpenApiValidationContext(); + if (openApiValidationContext != null && schemaValidation) { + schemaValidation = openApiValidationContext.isRequestValidationEnabled(); + } + + if (schemaValidation && !messageProcessors.contains(openApiMessageProcessor)) { openApiMessageProcessor = new OpenApiMessageProcessor(openApiSpecification, operationId, OpenApiMessageType.REQUEST); process(openApiMessageProcessor); @@ -95,26 +109,23 @@ protected HttpMessageBuilderSupport createHttpMessageBuilderSupport() { return httpMessageBuilderSupport; } - public OpenApiClientRequestActionBuilder disableOasValidation(boolean disabled) { - oasValidationEnabled = !disabled; + public OpenApiClientRequestActionBuilder schemaValidation(boolean schemaValidation) { + this.schemaValidation = schemaValidation; return this; } - private static class OpenApiClientRequestMessageBuilder extends HttpMessageBuilder { + public static class OpenApiClientRequestMessageBuilder extends HttpMessageBuilder { private final OpenApiSpecificationSource openApiSpecificationSource; private final String operationId; - private final HttpMessage httpMessage; - public OpenApiClientRequestMessageBuilder(HttpMessage httpMessage, OpenApiSpecificationSource openApiSpec, String operationId) { super(httpMessage); this.openApiSpecificationSource = openApiSpec; this.operationId = operationId; - this.httpMessage = httpMessage; } @Override @@ -133,6 +144,14 @@ public Message build(TestContext context, String messageType) { return super.build(context, messageType); } + @Override + public Object buildMessagePayload(TestContext context, String messageType) { + if (getPayloadBuilder() == null) { + this.setPayloadBuilder(new OpenApiPayloadBuilder(getMessage().getPayload())); + } + return super.buildMessagePayload(context, messageType); + } + private void buildMessageFromOperation(OpenApiSpecification openApiSpecification, OperationPathAdapter operationPathAdapter, TestContext context) { OasOperation operation = operationPathAdapter.operation(); @@ -141,69 +160,88 @@ private void buildMessageFromOperation(OpenApiSpecification openApiSpecification operationPathAdapter.operation().getMethod().toUpperCase(Locale.US)); if (operation.parameters != null) { - setSpecifiedHeaders(openApiSpecification, context, operation); - setSpecifiedQueryParameters(context, operation); + setMissingRequiredHeadersToRandomValues(openApiSpecification, context, operation); + setMissingRequiredQueryParametersToRandomValues(context, operation); } - if (httpMessage.getPayload() == null || (httpMessage.getPayload() instanceof String p - && p.isEmpty())) { - setSpecifiedBody(openApiSpecification, context, operation); - } - - String randomizedPath = path; + setMissingRequiredBodyToRandomValue(openApiSpecification, context, operation); + String randomizedPath = getMessage().getPath() != null ? getMessage().getPath() : path; if (operation.parameters != null) { List pathParams = operation.parameters.stream() .filter(p -> "path".equals(p.in)).toList(); for (OasParameter parameter : pathParams) { String parameterValue; - if (context.getVariables().containsKey(parameter.getName())) { - parameterValue = "\\" + CitrusSettings.VARIABLE_PREFIX + parameter.getName() - + CitrusSettings.VARIABLE_SUFFIX; + String pathParameterValue = getDefinedPathParameter(context, parameter.getName()); + if (isNotEmpty(pathParameterValue)) { + parameterValue = "\\" + pathParameterValue; } else { - parameterValue = OpenApiTestDataGenerator.createRandomValueExpression( + parameterValue = createRandomValueExpression( (OasSchema) parameter.schema); } - randomizedPath = Pattern.compile("\\{" + parameter.getName() + "}") - .matcher(randomizedPath) - .replaceAll(parameterValue); + + randomizedPath = randomizedPath.replaceAll("\\{"+parameter.getName()+"}", parameterValue); } } OasModelHelper.getRequestContentType(operation) .ifPresent( - contentType -> httpMessage.setHeader(HttpHeaders.CONTENT_TYPE, contentType)); + contentType -> getMessage().setHeader(HttpHeaders.CONTENT_TYPE, contentType)); - httpMessage.path(randomizedPath); - httpMessage.method(method); + getMessage().path(randomizedPath); + getMessage().method(method); } - private void setSpecifiedBody(OpenApiSpecification openApiSpecification, - TestContext context, OasOperation operation) { - Optional body = OasModelHelper.getRequestBodySchema( - openApiSpecification.getOpenApiDoc(context), operation); - body.ifPresent(oasSchema -> httpMessage.setPayload( - OpenApiTestDataGenerator.createOutboundPayload(oasSchema, - openApiSpecification))); + protected String getDefinedPathParameter(TestContext context, String name) { + if (context.getVariables().containsKey(name)) { + return CitrusSettings.VARIABLE_PREFIX + name + + CitrusSettings.VARIABLE_SUFFIX; + } + return null; + } + + private void setMissingRequiredBodyToRandomValue(OpenApiSpecification openApiSpecification, TestContext context, OasOperation operation) { + if (getMessage().getPayload() == null || (getMessage().getPayload() instanceof String p + && p.isEmpty())) { + Optional body = OasModelHelper.getRequestBodySchema( + openApiSpecification.getOpenApiDoc(context), operation); + body.ifPresent(oasSchema -> getMessage().setPayload( + OpenApiTestDataGenerator.createOutboundPayload(oasSchema, + openApiSpecification))); + } } - private void setSpecifiedQueryParameters(TestContext context, OasOperation operation) { + /** + * Creates all required query parameters, if they have not already been specified. + */ + private void setMissingRequiredQueryParametersToRandomValues(TestContext context, OasOperation operation) { operation.parameters.stream() .filter(param -> "query".equals(param.in)) .filter( - param -> (param.required != null && param.required) || context.getVariables() + param -> Boolean.TRUE.equals(param.required) || context.getVariables() .containsKey(param.getName())) .forEach(param -> { - if (!httpMessage.getQueryParams().containsKey(param.getName())) { - httpMessage.queryParam(param.getName(), - OpenApiTestDataGenerator.createRandomValueExpression(param.getName(), - (OasSchema) param.schema, - context)); + // If not already configured explicitly, create a random value + if (!getMessage().getQueryParams().containsKey(param.getName())) { + try { + getMessage().queryParam(param.getName(), + createRandomValueExpression(param.getName(), + (OasSchema) param.schema, + context)); + } catch (Exception e) { + // Note that exploded object query parameter representation for example, cannot properly + // be randomized. + logger.warn("Unable to set missing required query parameter to random value: {}", param); + } } }); } - private void setSpecifiedHeaders(OpenApiSpecification openApiSpecification, TestContext context, OasOperation operation) { + /** + * Creates all required headers, if they have not already been specified. + */ + private void setMissingRequiredHeadersToRandomValues(OpenApiSpecification openApiSpecification, + TestContext context, OasOperation operation) { List configuredHeaders = getHeaderBuilders() .stream() .flatMap(b -> b.builderHeaders(context).keySet().stream()) @@ -211,18 +249,18 @@ private void setSpecifiedHeaders(OpenApiSpecification openApiSpecification, Test operation.parameters.stream() .filter(param -> "header".equals(param.in)) .filter( - param -> (param.required != null && param.required) || context.getVariables() + param -> Boolean.TRUE.equals(param.required) || context.getVariables() .containsKey(param.getName())) .forEach(param -> { - if (httpMessage.getHeader(param.getName()) == null + // If not already configured explicitly, create a random value + if (getMessage().getHeader(param.getName()) == null && !configuredHeaders.contains(param.getName())) { - httpMessage.setHeader(param.getName(), - OpenApiTestDataGenerator.createRandomValueExpression(param.getName(), + getMessage().setHeader(param.getName(), + createRandomValueExpression(param.getName(), (OasSchema) param.schema, openApiSpecification, context)); } }); } } - } diff --git a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/actions/OpenApiClientResponseActionBuilder.java b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/actions/OpenApiClientResponseActionBuilder.java index adf514cc0d..2cb4f16f1b 100644 --- a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/actions/OpenApiClientResponseActionBuilder.java +++ b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/actions/OpenApiClientResponseActionBuilder.java @@ -24,6 +24,7 @@ import io.apicurio.datamodels.openapi.models.OasSchema; import jakarta.annotation.Nullable; import java.util.Collection; +import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.regex.Pattern; @@ -37,10 +38,11 @@ import org.citrusframework.message.Message; import org.citrusframework.message.MessageType; import org.citrusframework.openapi.OpenApiSpecification; -import org.citrusframework.openapi.OpenApiTestValidationDataGenerator; import org.citrusframework.openapi.model.OasModelHelper; import org.citrusframework.openapi.model.OperationPathAdapter; import org.citrusframework.openapi.validation.OpenApiMessageProcessor; +import org.citrusframework.openapi.validation.OpenApiMessageValidationContext; +import org.citrusframework.openapi.validation.OpenApiValidationContext; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -56,7 +58,7 @@ public class OpenApiClientResponseActionBuilder extends HttpClientResponseAction private final String operationId; - private boolean oasValidationEnabled = true; + private boolean schemaValidation = true; /** * Default constructor initializes http response message builder. @@ -69,51 +71,72 @@ public OpenApiClientResponseActionBuilder(OpenApiSpecificationSource openApiSpec public OpenApiClientResponseActionBuilder(HttpMessage httpMessage, OpenApiSpecificationSource openApiSpecificationSource, String operationId, String statusCode) { - super(new OpenApiClientResponseMessageBuilder(httpMessage, openApiSpecificationSource, operationId, - statusCode), httpMessage); - this.openApiSpecificationSource = openApiSpecificationSource; + this(openApiSpecificationSource, new OpenApiClientResponseMessageBuilder(httpMessage, openApiSpecificationSource, operationId, + statusCode), httpMessage, operationId); + } + + public OpenApiClientResponseActionBuilder(OpenApiSpecificationSource openApiSpec, OpenApiClientResponseMessageBuilder messageBuilder, HttpMessage message, + String operationId) { + super(messageBuilder, message); + this.openApiSpecificationSource = openApiSpec; this.operationId = operationId; } + /** + * Overridden to change the default message type to JSON, as Json is more common in OpenAPI context. + */ + @Override + protected HttpMessageBuilderSupport createHttpMessageBuilderSupport() { + HttpMessageBuilderSupport support = super.createHttpMessageBuilderSupport(); + support.type(CitrusSettings.getPropertyEnvOrDefault( + CitrusSettings.DEFAULT_MESSAGE_TYPE_PROPERTY, + CitrusSettings.DEFAULT_MESSAGE_TYPE_ENV, + MessageType.JSON.toString())); + return support; + } + @Override public ReceiveMessageAction doBuild() { OpenApiSpecification openApiSpecification = openApiSpecificationSource.resolve(referenceResolver); - validate(openApi(openApiSpecification)); - if (oasValidationEnabled && !messageProcessors.contains(openApiMessageProcessor)) { + + // Honor default enablement of schema validation + OpenApiValidationContext openApiValidationContext = openApiSpecification.getOpenApiValidationContext(); + if (openApiValidationContext != null && schemaValidation) { + schemaValidation = openApiValidationContext.isResponseValidationEnabled(); + } + + if (schemaValidation && !messageProcessors.contains(openApiMessageProcessor)) { openApiMessageProcessor = new OpenApiMessageProcessor( openApiSpecification, operationId, RESPONSE); process(openApiMessageProcessor); } + if (schemaValidation && getValidationContexts().stream().noneMatch(OpenApiMessageValidationContext.class::isInstance)) { + validate(openApi(openApiSpecification) + .schemaValidation(schemaValidation) + .build()); + } + return super.doBuild(); } - public OpenApiClientResponseActionBuilder disableOasValidation(boolean disable) { - oasValidationEnabled = !disable; - ((OpenApiClientResponseMessageBuilder)getMessageBuilderSupport().getMessageBuilder()).setOasValidationEnabled(oasValidationEnabled); + public OpenApiClientResponseActionBuilder schemaValidation(boolean enabled) { + schemaValidation = enabled; return this; } - public static void fillMessageFromResponse(OpenApiSpecification openApiSpecification, - TestContext context, HttpMessage httpMessage, @Nullable OasOperation operation, + public static void fillMessageTypeFromResponse(OpenApiSpecification openApiSpecification, + HttpMessage httpMessage, @Nullable OasOperation operation, @Nullable OasResponse response) { if (operation == null || response == null) { return; } - fillRequiredHeaders( - openApiSpecification, context, httpMessage, response); - Optional responseSchema = OasModelHelper.getSchema(response); responseSchema.ifPresent(oasSchema -> { - httpMessage.setPayload( - OpenApiTestValidationDataGenerator.createInboundPayload(oasSchema, - OasModelHelper.getSchemaDefinitions( - openApiSpecification.getOpenApiDoc(context)), openApiSpecification)); - OasSchema resolvedSchema = OasModelHelper.resolveSchema( openApiSpecification.getOpenApiDoc(null), oasSchema); if (OasModelHelper.isObjectType(resolvedSchema) || OasModelHelper.isObjectArrayType( @@ -130,56 +153,34 @@ public static void fillMessageFromResponse(OpenApiSpecification openApiSpecifica ); } - private static void fillRequiredHeaders( - OpenApiSpecification openApiSpecification, TestContext context, HttpMessage httpMessage, - OasResponse response) { - - Map requiredHeaders = OasModelHelper.getRequiredHeaders(response); - for (Map.Entry header : requiredHeaders.entrySet()) { - httpMessage.setHeader(header.getKey(), - OpenApiTestValidationDataGenerator.createValidationExpression(header.getKey(), - header.getValue(), - OasModelHelper.getSchemaDefinitions( - openApiSpecification.getOpenApiDoc(context)), false, - openApiSpecification, - context)); - } - - Map headers = OasModelHelper.getHeaders(response); - for (Map.Entry header : headers.entrySet()) { - if (!requiredHeaders.containsKey(header.getKey()) && context.getVariables() - .containsKey(header.getKey())) { - httpMessage.setHeader(header.getKey(), - CitrusSettings.VARIABLE_PREFIX + header.getKey() - + CitrusSettings.VARIABLE_SUFFIX); - } - } - } - - private static class OpenApiClientResponseMessageBuilder extends HttpMessageBuilder { + public static class OpenApiClientResponseMessageBuilder extends HttpMessageBuilder { private final OpenApiSpecificationSource openApiSpecificationSource; private final String operationId; - private final String statusCode; + private String statusCode; private final HttpMessage httpMessage; - private boolean oasValidationEnabled = true; - public OpenApiClientResponseMessageBuilder(HttpMessage httpMessage, - OpenApiSpecificationSource oopenApiSpecificationSourceenApiSpec, + OpenApiSpecificationSource openApiSpecificationSource, String operationId, String statusCode) { super(httpMessage); - this.openApiSpecificationSource = oopenApiSpecificationSourceenApiSpec; + this.openApiSpecificationSource = openApiSpecificationSource; this.operationId = operationId; this.statusCode = statusCode; this.httpMessage = httpMessage; } + public OpenApiClientResponseMessageBuilder statusCode(String statusCode) { + this.statusCode =statusCode; + return this; + } + @Override public Message build(TestContext context, String messageType) { OpenApiSpecification openApiSpecification = openApiSpecificationSource.resolve(context.getReferenceResolver()); + openApiSpecification.getOperation(operationId, context).ifPresentOrElse(operationPathAdapter -> buildMessageFromOperation(openApiSpecification, operationPathAdapter, context), () -> { throw new CitrusRuntimeException("Unable to locate operation with id '%s' in OpenAPI specification %s".formatted(operationId, openApiSpecification.getSpecUrl())); @@ -191,12 +192,16 @@ public Message build(TestContext context, String messageType) { private void buildMessageFromOperation(OpenApiSpecification openApiSpecification, OperationPathAdapter operationPathAdapter, TestContext context) { OasOperation operation = operationPathAdapter.operation(); - if (oasValidationEnabled && operation.responses != null) { + // Headers already present in httpMessage should not be overwritten by open api. + // E.g. if a reasonPhrase was explicitly set in the builder, it must not be overwritten. + Map currentHeaders = new HashMap<>(httpMessage.getHeaders()); + + if (operation.responses != null) { Optional responseForRandomGeneration = OasModelHelper.getResponseForRandomGeneration( openApiSpecification.getOpenApiDoc(context), operation, statusCode, null); responseForRandomGeneration.ifPresent( - oasResponse -> fillMessageFromResponse(openApiSpecification, context, httpMessage, + oasResponse -> fillMessageTypeFromResponse(openApiSpecification, httpMessage, operation, oasResponse)); } @@ -205,10 +210,9 @@ private void buildMessageFromOperation(OpenApiSpecification openApiSpecification } else { httpMessage.status(HttpStatus.OK); } - } - public void setOasValidationEnabled(boolean oasValidationEnabled) { - this.oasValidationEnabled = oasValidationEnabled; + httpMessage.getHeaders().putAll(currentHeaders); } + } } diff --git a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/actions/OpenApiPayloadBuilder.java b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/actions/OpenApiPayloadBuilder.java new file mode 100644 index 0000000000..a08759d4ea --- /dev/null +++ b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/actions/OpenApiPayloadBuilder.java @@ -0,0 +1,56 @@ +package org.citrusframework.openapi.actions; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import org.citrusframework.context.TestContext; +import org.citrusframework.message.builder.DefaultPayloadBuilder; +import org.springframework.util.MultiValueMap; + +public class OpenApiPayloadBuilder extends DefaultPayloadBuilder { + + public OpenApiPayloadBuilder(Object payload) { + super(payload); + } + + @Override + public Object buildPayload(TestContext context) { + + if (getPayload() instanceof MultiValueMap multiValueMap) { + replaceDynamicContentInMultiValueMap(context, + (MultiValueMap) multiValueMap); + } + + return super.buildPayload(context); + } + + private static void replaceDynamicContentInMultiValueMap(TestContext context, MultiValueMap multiValueMap) { + Set cache = new HashSet<>(multiValueMap.entrySet()); + multiValueMap.clear(); + for (Object value : cache) { + if (value instanceof Map.Entry entry) { + replaceDynamicContentInEntry(context, multiValueMap, entry); + } + } + } + + private static void replaceDynamicContentInEntry(TestContext context, MultiValueMap multiValueMap, + Entry entry) { + Object key = entry.getKey(); + + List list = (List) entry.getValue(); + if (list != null) { + for (int i=0;i - buildMessageFromOperation(openApiSpecification, operationPathAdapter, context), () -> { - throw new CitrusRuntimeException("Unable to locate operation with id '%s' in OpenAPI specification %s".formatted(operationId, openApiSpecification.getSpecUrl())); - }); + openApiSpecification.getOperation(operationId, context) + .ifPresentOrElse(operationPathAdapter -> + buildMessageFromOperation(openApiSpecification, operationPathAdapter, context), + () -> { + throw new CitrusRuntimeException( + "Unable to locate operation with id '%s' in OpenAPI specification %s".formatted( + operationId, openApiSpecification.getSpecUrl())); + }); return super.build(context, messageType); } - private void buildMessageFromOperation(OpenApiSpecification openApiSpecification, OperationPathAdapter operationPathAdapter, TestContext context) { + private void buildMessageFromOperation(OpenApiSpecification openApiSpecification, + OperationPathAdapter operationPathAdapter, TestContext context) { setSpecifiedMessageType(operationPathAdapter); setSpecifiedHeaders(context, openApiSpecification, operationPathAdapter); @@ -142,12 +171,15 @@ private void setSpecifiedRequestContentType(OperationPathAdapter operationPathAd String.format("@startsWith(%s)@", contentType))); } - private void setSpecifiedPath(TestContext context, OpenApiSpecification openApiSpecification, OperationPathAdapter operationPathAdapter) { - String randomizedPath = OasModelHelper.getBasePath(openApiSpecification.getOpenApiDoc(context)) - + operationPathAdapter.apiPath(); + private void setSpecifiedPath(TestContext context, + OpenApiSpecification openApiSpecification, OperationPathAdapter operationPathAdapter) { + String randomizedPath = + OasModelHelper.getBasePath(openApiSpecification.getOpenApiDoc(context)) + + operationPathAdapter.apiPath(); randomizedPath = randomizedPath.replace("//", "/"); - randomizedPath = appendSegmentToUrlPath(openApiSpecification.getRootContextPath(), randomizedPath); + randomizedPath = appendSegmentToUrlPath(openApiSpecification.getRootContextPath(), + randomizedPath); if (operationPathAdapter.operation().parameters != null) { randomizedPath = determinePath(context, operationPathAdapter.operation(), @@ -157,7 +189,8 @@ private void setSpecifiedPath(TestContext context, OpenApiSpecification openApiS httpMessage.path(randomizedPath); } - private void setSpecifiedBody(TestContext context, OpenApiSpecification openApiSpecification, OperationPathAdapter operationPathAdapter) { + private void setSpecifiedBody(TestContext context, + OpenApiSpecification openApiSpecification, OperationPathAdapter operationPathAdapter) { Optional body = OasModelHelper.getRequestBodySchema( openApiSpecification.getOpenApiDoc(context), operationPathAdapter.operation()); body.ifPresent(oasSchema -> httpMessage.setPayload( @@ -195,7 +228,8 @@ private String determinePath(TestContext context, OasOperation operation, return randomizedPath; } - private void setSpecifiedQueryParameters(TestContext context, OpenApiSpecification openApiSpecification, + private void setSpecifiedQueryParameters(TestContext context, + OpenApiSpecification openApiSpecification, OperationPathAdapter operationPathAdapter) { if (operationPathAdapter.operation().parameters == null) { @@ -210,13 +244,15 @@ private void setSpecifiedQueryParameters(TestContext context, OpenApiSpecificati .forEach(param -> httpMessage.queryParam(param.getName(), OpenApiTestValidationDataGenerator.createValidationExpression(param.getName(), OasModelHelper.getParameterSchema(param).orElse(null), - OasModelHelper.getSchemaDefinitions(openApiSpecification.getOpenApiDoc(context)), false, + OasModelHelper.getSchemaDefinitions( + openApiSpecification.getOpenApiDoc(context)), false, openApiSpecification, context))); } - private void setSpecifiedHeaders(TestContext context, OpenApiSpecification openApiSpecification, + private void setSpecifiedHeaders(TestContext context, + OpenApiSpecification openApiSpecification, OperationPathAdapter operationPathAdapter) { if (operationPathAdapter.operation().parameters == null) { @@ -231,7 +267,8 @@ private void setSpecifiedHeaders(TestContext context, OpenApiSpecification openA .forEach(param -> httpMessage.setHeader(param.getName(), OpenApiTestValidationDataGenerator.createValidationExpression(param.getName(), OasModelHelper.getParameterSchema(param).orElse(null), - OasModelHelper.getSchemaDefinitions(openApiSpecification.getOpenApiDoc(context)), false, + OasModelHelper.getSchemaDefinitions( + openApiSpecification.getOpenApiDoc(context)), false, openApiSpecification, context))); } @@ -251,7 +288,8 @@ private void setSpecifiedMessageType(OperationPathAdapter operationPathAdapter) } private void setSpecifiedMethod(OperationPathAdapter operationPathAdapter) { - httpMessage.method(HttpMethod.valueOf(operationPathAdapter.operation().getMethod().toUpperCase())); + httpMessage.method( + HttpMethod.valueOf(operationPathAdapter.operation().getMethod().toUpperCase())); } } } diff --git a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/actions/OpenApiServerResponseActionBuilder.java b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/actions/OpenApiServerResponseActionBuilder.java index 4518f1e6b3..dee3ccb155 100644 --- a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/actions/OpenApiServerResponseActionBuilder.java +++ b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/actions/OpenApiServerResponseActionBuilder.java @@ -53,6 +53,7 @@ import org.citrusframework.openapi.model.OasModelHelper; import org.citrusframework.openapi.model.OperationPathAdapter; import org.citrusframework.openapi.validation.OpenApiMessageProcessor; +import org.citrusframework.openapi.validation.OpenApiValidationContext; import org.springframework.http.HttpStatus; /** @@ -66,7 +67,7 @@ public class OpenApiServerResponseActionBuilder extends HttpServerResponseAction private final String operationId; - private boolean oasValidationEnabled = true; + private boolean schemaValidation = true; /** * Default constructor initializes http response message builder. @@ -88,17 +89,24 @@ public OpenApiServerResponseActionBuilder(HttpMessage httpMessage, @Override public SendMessageAction doBuild() { OpenApiSpecification openApiSpecification = openApiSpecificationSource.resolve(referenceResolver); - if (oasValidationEnabled && !messageProcessors.contains(openApiMessageProcessor)) { - openApiMessageProcessor = new OpenApiMessageProcessor( - openApiSpecification, operationId, OpenApiMessageType.RESPONSE); + + // Honor default enablement of schema validation + OpenApiValidationContext openApiValidationContext = openApiSpecification.getOpenApiValidationContext(); + if (openApiValidationContext != null && schemaValidation) { + schemaValidation = openApiValidationContext.isResponseValidationEnabled(); + } + + if (schemaValidation && !messageProcessors.contains(openApiMessageProcessor)) { + openApiMessageProcessor = new OpenApiMessageProcessor(openApiSpecification, operationId, + OpenApiMessageType.RESPONSE); process(openApiMessageProcessor); } return super.doBuild(); } - public OpenApiServerResponseActionBuilder disableOasValidation(boolean disable) { - oasValidationEnabled = !disable; + public OpenApiServerResponseActionBuilder schemaValidation(boolean schemaValidation) { + this.schemaValidation = schemaValidation; return this; } diff --git a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/model/OperationPathAdapter.java b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/model/OperationPathAdapter.java index e5aebaea7e..4d63466c58 100644 --- a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/model/OperationPathAdapter.java +++ b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/model/OperationPathAdapter.java @@ -16,10 +16,10 @@ package org.citrusframework.openapi.model; -import io.apicurio.datamodels.openapi.models.OasOperation; -import org.citrusframework.openapi.util.OpenApiUtils; - import static java.lang.String.format; +import static org.citrusframework.openapi.util.OpenApiUtils.getMethodPath; + +import io.apicurio.datamodels.openapi.models.OasOperation; /** * Adapts the different paths associated with an OpenAPI operation to the {@link OasOperation}. @@ -34,6 +34,6 @@ public record OperationPathAdapter(String apiPath, String contextPath, String fu @Override public String toString() { - return format("%s (%s)",OpenApiUtils.getMethodPath(operation.getMethod(), apiPath), operation.operationId); + return format("%s (%s)", getMethodPath(operation.getMethod(), apiPath), operation.operationId); } } diff --git a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/util/OpenApiUtils.java b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/util/OpenApiUtils.java index 3e9ea0951e..1e0916a40f 100644 --- a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/util/OpenApiUtils.java +++ b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/util/OpenApiUtils.java @@ -17,17 +17,15 @@ package org.citrusframework.openapi.util; import static java.lang.String.format; +import static org.citrusframework.util.StringUtils.hasText; import io.apicurio.datamodels.openapi.models.OasOperation; import io.apicurio.datamodels.openapi.models.OasSchema; import jakarta.annotation.Nonnull; import java.util.stream.Collectors; -import org.citrusframework.http.message.HttpMessage; -import org.citrusframework.http.message.HttpMessageHeaders; import org.citrusframework.openapi.OpenApiConstants; import org.citrusframework.openapi.OpenApiRepository; import org.citrusframework.spi.ReferenceResolver; -import org.citrusframework.util.StringUtils; public class OpenApiUtils { @@ -35,28 +33,27 @@ private OpenApiUtils() { // Static access only } - public static String getMethodPath(@Nonnull HttpMessage httpMessage) { - Object methodHeader = httpMessage.getHeader(HttpMessageHeaders.HTTP_REQUEST_METHOD); - Object path = httpMessage.getHeader(HttpMessageHeaders.HTTP_REQUEST_URI); - - return getMethodPath(methodHeader != null ? methodHeader.toString().toLowerCase() : "null", - path != null ? path.toString() : "null"); - } - public static String getMethodPath(@Nonnull String method, @Nonnull String path) { - if (StringUtils.hasText(path) && path.startsWith("/")) { + if (hasText(path) && path.startsWith("/")) { path = path.substring(1); } - return format("/%s/%s", method.toLowerCase(), path); + return format("%s_/%s", method.toUpperCase(), path); } /** * @return a unique scenario id for the {@link OasOperation} */ - public static String createFullPathOperationIdentifier(String path, OasOperation oasOperation) { + public static String createFullPathOperationIdentifier(OasOperation oasOperation, String path) { return format("%s_%s", oasOperation.getMethod().toUpperCase(), path); } + /** + * @return a unique scenario id for the {@link OasOperation} + */ + public static String createFullPathOperationIdentifier(String method, String path) { + return format("%s_%s", method.toUpperCase(), path); + } + public static boolean isAnyNumberScheme(OasSchema schema) { return ( schema != null && diff --git a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiMessageValidationContext.java b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiMessageValidationContext.java index cc79a4a5a4..6a3a18a76c 100644 --- a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiMessageValidationContext.java +++ b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiMessageValidationContext.java @@ -14,7 +14,7 @@ public class OpenApiMessageValidationContext extends DefaultValidationContext implements SchemaValidationContext { - /** + /** * Should message be validated with its schema definition. This is enabled with respect to * global settings, which are true by default. as only messages processed by open api actions * will be processed and validation information will be derived from open api spec. @@ -22,8 +22,7 @@ public class OpenApiMessageValidationContext extends DefaultValidationContext im *

Note that the default registered validation context is used for received messages. This is * why the schema validation is initialized with response validation enabled globally. */ - private boolean schemaValidation = OpenApiSettings.isResponseValidationEnabledGlobally(); - + private final boolean schemaValidation; public OpenApiMessageValidationContext(Builder builder) { super(); diff --git a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiRequestValidationProcessor.java b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiRequestValidationProcessor.java deleted file mode 100644 index e8c49cb2b6..0000000000 --- a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiRequestValidationProcessor.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.citrusframework.openapi.validation; - -import org.citrusframework.context.TestContext; -import org.citrusframework.http.message.HttpMessage; -import org.citrusframework.message.Message; -import org.citrusframework.openapi.OpenApiMessageHeaders; -import org.citrusframework.openapi.OpenApiSpecification; -import org.citrusframework.validation.ValidationProcessor; - -/** - * {@code ValidationProcessor} that facilitates the use of Atlassian's Swagger Request Validator, - * and delegates validation of OpenApi requests to instances of {@link OpenApiRequestValidator}. - */ -public class OpenApiRequestValidationProcessor implements - ValidationProcessor { - - private final OpenApiSpecification openApiSpecification; - - private final String operationId; - - private final OpenApiRequestValidator openApiRequestValidator; - - public OpenApiRequestValidationProcessor(OpenApiSpecification openApiSpecification, - String operationId) { - this.openApiSpecification = openApiSpecification; - this.operationId = operationId; - this.openApiRequestValidator = new OpenApiRequestValidator(openApiSpecification); - } - - @Override - public void validate(Message message, TestContext context) { - - if (!(message instanceof HttpMessage httpMessage)) { - return; - } - - message.setHeader(OpenApiMessageHeaders.OAS_UNIQUE_OPERATION_ID, operationId); - - openApiSpecification.getOperation( - operationId, context).ifPresent(operationPathAdapter -> - openApiRequestValidator.validateRequest(operationPathAdapter, httpMessage)); - } - -} diff --git a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiRequestValidator.java b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiRequestValidator.java index b37e53f660..a3809f1858 100644 --- a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiRequestValidator.java +++ b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiRequestValidator.java @@ -19,6 +19,10 @@ import com.atlassian.oai.validator.model.Request; import com.atlassian.oai.validator.model.SimpleRequest; import com.atlassian.oai.validator.report.ValidationReport; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; import org.citrusframework.exceptions.ValidationException; @@ -27,6 +31,8 @@ import org.citrusframework.http.message.HttpMessageUtils; import org.citrusframework.openapi.OpenApiSpecification; import org.citrusframework.openapi.model.OperationPathAdapter; +import org.citrusframework.util.FileUtils; +import org.springframework.util.MultiValueMap; /** * Specific validator that uses atlassian and is responsible for validating HTTP requests @@ -36,7 +42,6 @@ public class OpenApiRequestValidator extends OpenApiValidator { public OpenApiRequestValidator(OpenApiSpecification openApiSpecification) { super(openApiSpecification); - setEnabled(openApiSpecification.getSwaggerOpenApiValidationContext() != null && openApiSpecification.getSwaggerOpenApiValidationContext().isRequestValidationEnabled()); } @Override @@ -47,7 +52,7 @@ protected String getType() { public void validateRequest(OperationPathAdapter operationPathAdapter, HttpMessage requestMessage) { - if (enabled && openApiInteractionValidator != null) { + if (openApiInteractionValidator != null) { ValidationReport validationReport = openApiInteractionValidator.validateRequest( createRequestFromMessage(operationPathAdapter, requestMessage)); if (validationReport.hasErrors()) { @@ -60,7 +65,7 @@ public void validateRequest(OperationPathAdapter operationPathAdapter, public ValidationReport validateRequestToReport(OperationPathAdapter operationPathAdapter, HttpMessage requestMessage) { - if (enabled && openApiInteractionValidator != null) { + if (openApiInteractionValidator != null) { return openApiInteractionValidator.validateRequest( createRequestFromMessage(operationPathAdapter, requestMessage)); } @@ -83,7 +88,7 @@ Request createRequestFromMessage(OperationPathAdapter operationPathAdapter, ); if (payload != null) { - requestBuilder = requestBuilder.withBody(payload.toString()); + requestBuilder = requestBuilder.withBody(convertPayload(payload)); } SimpleRequest.Builder finalRequestBuilder = requestBuilder; @@ -102,7 +107,40 @@ Request createRequestFromMessage(OperationPathAdapter operationPathAdapter, } }); + httpMessage.getCookies().forEach(cookie -> finalRequestBuilder.withHeader("Cookie", URLDecoder.decode(cookie.getName()+"="+cookie.getValue(), + FileUtils.getDefaultCharset()))); + return requestBuilder.build(); } + private String convertPayload(Object payload) { + + if (payload instanceof MultiValueMap multiValueMap) { + return serializeForm(multiValueMap, StandardCharsets.UTF_8); + } + + return payload != null ? payload.toString() : null; + } + + /** + * We cannot validate a MultiValueMap. The map will later on be converted to a string representation + * by Spring. For validation, we need to mimic this transformation here. + + * @see org.springframework.http.converter.FormHttpMessageConverter + */ + private String serializeForm(MultiValueMap formData, Charset charset) { + StringBuilder builder = new StringBuilder(); + formData.forEach((name, values) -> values.forEach(value -> { + if (!builder.isEmpty()) { + builder.append('&'); + } + builder.append(URLEncoder.encode(name.toString(), charset)); + if (value != null) { + builder.append('='); + builder.append(URLEncoder.encode(String.valueOf(value), charset)); + } + })); + + return builder.toString(); + } } diff --git a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiResponseValidator.java b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiResponseValidator.java index 8a08242617..c7af584c62 100644 --- a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiResponseValidator.java +++ b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiResponseValidator.java @@ -34,7 +34,6 @@ public class OpenApiResponseValidator extends OpenApiValidator { public OpenApiResponseValidator(OpenApiSpecification openApiSpecification) { super(openApiSpecification); - setEnabled(openApiSpecification.getSwaggerOpenApiValidationContext() != null && openApiSpecification.getSwaggerOpenApiValidationContext().isResponseValidationEnabled()); } @Override @@ -44,7 +43,7 @@ protected String getType() { public void validateResponse(OperationPathAdapter operationPathAdapter, HttpMessage httpMessage) { - if (enabled && openApiInteractionValidator != null) { + if (openApiInteractionValidator != null) { HttpStatusCode statusCode = httpMessage.getStatusCode(); Response response = createResponseFromMessage(httpMessage, statusCode != null ? statusCode.value() : null); @@ -61,7 +60,7 @@ public void validateResponse(OperationPathAdapter operationPathAdapter, HttpMess public ValidationReport validateResponseToReport(OperationPathAdapter operationPathAdapter, HttpMessage httpMessage) { - if (enabled && openApiInteractionValidator != null) { + if (openApiInteractionValidator != null) { HttpStatusCode statusCode = httpMessage.getStatusCode(); Response response = createResponseFromMessage(httpMessage, statusCode != null ? statusCode.value() : null); diff --git a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiSchemaValidation.java b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiSchemaValidation.java index 74b5a55046..9bfe3affbd 100644 --- a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiSchemaValidation.java +++ b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiSchemaValidation.java @@ -4,6 +4,7 @@ import jakarta.annotation.Nullable; import java.util.ArrayList; import java.util.List; +import java.util.Set; import org.citrusframework.context.TestContext; import org.citrusframework.exceptions.CitrusRuntimeException; import org.citrusframework.exceptions.ValidationException; @@ -15,20 +16,32 @@ import org.citrusframework.openapi.model.OperationPathAdapter; import org.citrusframework.openapi.util.OpenApiUtils; import org.citrusframework.openapi.validation.OpenApiMessageValidationContext.Builder; -import org.citrusframework.validation.MessageValidator; +import org.citrusframework.validation.AbstractMessageValidator; import org.citrusframework.validation.SchemaValidator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class OpenApiSchemaValidation implements MessageValidator, +public class OpenApiSchemaValidation extends AbstractMessageValidator implements SchemaValidator { - private Logger logger = LoggerFactory.getLogger(OpenApiSchemaValidation.class); + private static final Set FILTERED_ERROR_MESSAGE_KEYS = Set.of( + // Filtered because in general OpenAPI is not required to specify all response codes. + // So this should not be considered as validation error. + "validation.response.status.unknown" + ); + + private static final Logger logger = LoggerFactory.getLogger(OpenApiSchemaValidation.class); + + @Override + protected Class getRequiredValidationContextType() { + return OpenApiMessageValidationContext.class; + } @Override - public void validateMessage(Message receivedMessage, Message controlMessage, - TestContext context, List list) throws ValidationException { - validate(receivedMessage, context, new Builder().schemaValidation(true).build()); + public void validateMessage(Message receivedMessage, Message controlMessage, TestContext context, + OpenApiMessageValidationContext validationContext) { + // No control message validation, only schema validation + validate(receivedMessage, context, validationContext); } @Override @@ -43,17 +56,33 @@ public void validate( ValidationReportData validationReportData = validate(context, httpMessage, findSchemaRepositories(context), validationContext); - if (validationReportData != null && validationReportData.report.hasErrors()) { - if (logger.isErrorEnabled()) { - logger.error("Failed to validate Json schema for message:\n{}", - message.getPayload(String.class)); + + if (validationReportData != null && validationReportData.report != null) { + + ValidationReport filteredReport = filterIrrelevantMessages( + validationReportData); + if (filteredReport.hasErrors()) { + if (logger.isErrorEnabled()) { + logger.error("Failed to validate Json schema for message:\n{}", + message.getPayload(String.class)); + } + throw new ValidationException(constructErrorMessage(validationReportData)); } - throw new ValidationException(constructErrorMessage(validationReportData)); } logger.debug("Json schema validation successful: All values OK"); } + /** + * Filter specific messages from the report which are considered irrelevant. + * See {@link OpenApiSchemaValidation#FILTERED_ERROR_MESSAGE_KEYS} for more details. + */ + private static ValidationReport filterIrrelevantMessages(ValidationReportData validationReportData) { + return ValidationReport.from( + validationReportData.report.getMessages().stream() + .filter(msg -> !FILTERED_ERROR_MESSAGE_KEYS.contains(msg.getKey())).toList()); + } + @Override public boolean supportsMessageType(String messageType, Message message) { return message.getHeader(OpenApiMessageHeaders.OAS_UNIQUE_OPERATION_ID) != null; diff --git a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/SwaggerOpenApiValidationContext.java b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiValidationContext.java similarity index 86% rename from connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/SwaggerOpenApiValidationContext.java rename to connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiValidationContext.java index ad9dbcf23e..832f063b6f 100644 --- a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/SwaggerOpenApiValidationContext.java +++ b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiValidationContext.java @@ -25,7 +25,12 @@ import com.atlassian.oai.validator.schema.SwaggerV20Library; import io.swagger.v3.oas.models.OpenAPI; -public class SwaggerOpenApiValidationContext { +/** + * Represents the context for OpenAPI validation, providing configuration and validators for request and response validation. + * This context maintains settings for both request and response validation, which can be controlled at an instance level. + * By default, these settings are initialized based on a global configuration. + */ +public class OpenApiValidationContext { private final OpenAPI openApi; @@ -37,7 +42,7 @@ public class SwaggerOpenApiValidationContext { private boolean requestValidationEnabled = isRequestValidationEnabledGlobally(); - public SwaggerOpenApiValidationContext(OpenAPI openApi) { + public OpenApiValidationContext(OpenAPI openApi) { this.openApi = openApi; } diff --git a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/SwaggerOpenApiValidationContextLoader.java b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiValidationContextLoader.java similarity index 67% rename from connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/SwaggerOpenApiValidationContextLoader.java rename to connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiValidationContextLoader.java index 51d0ba4412..a541c3948f 100644 --- a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/SwaggerOpenApiValidationContextLoader.java +++ b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiValidationContextLoader.java @@ -27,45 +27,45 @@ import org.citrusframework.spi.Resource; /** - * Utility class for loading Swagger OpenAPI specifications from various resources. + * Utility class for creation of {@link OpenApiValidationContext}. */ -public abstract class SwaggerOpenApiValidationContextLoader { +public abstract class OpenApiValidationContextLoader { - private SwaggerOpenApiValidationContextLoader() { + private OpenApiValidationContextLoader() { // Static access only } /** - * Loads an OpenAPI specification from a secured web resource. + * Creates an OpenApiValidationContext from a secured OpenAPI web resource. * - * @param url the URL of the secured web resource - * @return the loaded OpenAPI specification + * @param url the URL of the secured OpenAPI web resource + * @return the OpenApiValidationContext */ - public static SwaggerOpenApiValidationContext fromSecuredWebResource(@Nonnull URL url) { + public static OpenApiValidationContext fromSecuredWebResource(@Nonnull URL url) { return createValidationContext(new OpenApiLoader().loadApi(SpecSource.inline(OpenApiResourceLoader.rawFromSecuredWebResource(url)), Collections.emptyList(), defaultParseOptions())); } /** - * Loads an OpenAPI specification from a web resource. + * Creates an OpenApiValidationContext from an OpenAPI web resource. * - * @param url the URL of the web resource - * @return the loaded OpenAPI specification + * @param url the URL of the OpenAPI web resource + * @return the OpenApiValidationContext */ - public static SwaggerOpenApiValidationContext fromWebResource(@Nonnull URL url) { + public static OpenApiValidationContext fromWebResource(@Nonnull URL url) { return createValidationContext(new OpenApiLoader().loadApi(SpecSource.inline(OpenApiResourceLoader.rawFromWebResource(url)), Collections.emptyList(), defaultParseOptions())); } /** - * Loads an OpenAPI specification from a file. + * Creates an OpenApiValidationContext from an OpenAPI file. * * @param resource the file resource containing the OpenAPI specification - * @return the loaded OpenAPI specification + * @return the OpenApiValidationContext */ - public static SwaggerOpenApiValidationContext fromFile(@Nonnull Resource resource) { + public static OpenApiValidationContext fromFile(@Nonnull Resource resource) { return createValidationContext(new OpenApiLoader().loadApi(SpecSource.inline(OpenApiResourceLoader.rawFromFile(resource)), Collections.emptyList(), defaultParseOptions())); } - private static SwaggerOpenApiValidationContext createValidationContext(OpenAPI openApi) { - return new SwaggerOpenApiValidationContext(openApi); + private static OpenApiValidationContext createValidationContext(OpenAPI openApi) { + return new OpenApiValidationContext(openApi); } private static ParseOptions defaultParseOptions() { diff --git a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiValidator.java b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiValidator.java index c5393f8051..61766421db 100644 --- a/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiValidator.java +++ b/connectors/citrus-openapi/src/main/java/org/citrusframework/openapi/validation/OpenApiValidator.java @@ -25,26 +25,16 @@ public abstract class OpenApiValidator { protected final OpenApiInteractionValidator openApiInteractionValidator; - protected boolean enabled; - protected OpenApiValidator(OpenApiSpecification openApiSpecification) { - SwaggerOpenApiValidationContext swaggerOpenApiValidationContext = openApiSpecification.getSwaggerOpenApiValidationContext(); - if (swaggerOpenApiValidationContext != null) { - openApiInteractionValidator = openApiSpecification.getSwaggerOpenApiValidationContext() + OpenApiValidationContext openApiValidationContext = openApiSpecification.getOpenApiValidationContext(); + if (openApiValidationContext != null) { + openApiInteractionValidator = openApiSpecification.getOpenApiValidationContext() .getOpenApiInteractionValidator(); } else { openApiInteractionValidator = null; } } - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public boolean isEnabled() { - return enabled; - } - protected abstract String getType(); /** diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiMessageTypeTest.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiMessageTypeTest.java index 39486d14f8..2c15ea89c3 100644 --- a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiMessageTypeTest.java +++ b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiMessageTypeTest.java @@ -13,6 +13,6 @@ public void testToHeaderNameRequest() { @Test public void testToHeaderNameResponse() { - assertEquals(OpenApiMessageHeaders.REQUEST_TYPE, OpenApiMessageHeaders.RESPONSE_TYPE); + assertEquals(OpenApiMessageType.RESPONSE.toHeaderName(), OpenApiMessageHeaders.RESPONSE_TYPE); } } diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiPathRegistryTest.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiPathRegistryTest.java deleted file mode 100644 index d837f1f0ee..0000000000 --- a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiPathRegistryTest.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.citrusframework.openapi; - -import org.testng.Assert; -import org.testng.annotations.Test; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.stream.Collectors; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertNull; -import static org.testng.Assert.assertTrue; - -public class OpenApiPathRegistryTest { - - private static final String[] SEGMENTS = {"api", "v1", "pet", "user", "order", "product", - "category", "service", "data"}; - private static final String VARIABLE_TEMPLATE = "{%s}"; - private static final String[] VARIABLES = {"id", "userId", "orderId", "productId", - "categoryId"}; - - public static List generatePaths(int numberOfPaths) { - List paths = new ArrayList<>(); - Random random = new Random(); - - Set allGenerated = new HashSet<>(); - while (allGenerated.size() < numberOfPaths) { - int numberOfSegments = 1 + random.nextInt(7); // 1 to 7 segments - StringBuilder pathBuilder = new StringBuilder("/api/v1"); - - int nids = 0; - for (int j = 0; j < numberOfSegments; j++) { - if (nids < 2 && nids < numberOfSegments - 1 && random.nextBoolean()) { - nids++; - // Add a segment with a variable - pathBuilder.append("/").append(String.format(VARIABLE_TEMPLATE, - VARIABLES[random.nextInt(VARIABLES.length)])); - } else { - // Add a fixed segment - pathBuilder.append("/").append(SEGMENTS[random.nextInt(SEGMENTS.length)]); - } - } - - String path = pathBuilder.toString(); - if (!allGenerated.contains(path)) { - paths.add(path); - allGenerated.add(path); - } - } - return paths; - } - - @Test - public void insertShouldSucceedOnSameValue() { - OpenApiPathRegistry openApiPathRegistry = new OpenApiPathRegistry<>(); - assertTrue(openApiPathRegistry.insert("/s1/s2", "root")); - assertTrue(openApiPathRegistry.insert("/s1/s2", "root")); - assertEquals(openApiPathRegistry.search("/s1/s2"), "root"); - } - - @Test - public void insertShouldFailOnSamePathWithDifferentValue() { - OpenApiPathRegistry openApiPathRegistry = new OpenApiPathRegistry<>(); - assertTrue(openApiPathRegistry.insert("/s1/s2", "root1")); - assertFalse(openApiPathRegistry.insert("/s1/s2", "root2")); - assertEquals(openApiPathRegistry.search("/s1/s2"), "root1"); - } - - @Test - public void searchShouldSucceedOnPartialPathMatchWithDifferentVariables() { - OpenApiPathRegistry openApiPathRegistry = new OpenApiPathRegistry<>(); - assertTrue(openApiPathRegistry.insert("/s1/s2/{id1}", "root1")); - assertTrue(openApiPathRegistry.insert("/s1/s2/{id2}/s4/{id1}", "root2")); - assertEquals(openApiPathRegistry.search("/s1/s2/1111"), "root1"); - assertEquals(openApiPathRegistry.search("/s1/s2/123/s4/222"), "root2"); - - openApiPathRegistry = new OpenApiPathRegistry<>(); - assertTrue(openApiPathRegistry.insert("/s1/s2/{id2}", "root1")); - assertTrue(openApiPathRegistry.insert("/s1/s2/{id1}/s4/{id2}", "root2")); - assertEquals(openApiPathRegistry.search("/s1/s2/1111"), "root1"); - assertEquals(openApiPathRegistry.search("/s1/s2/123/s4/222"), "root2"); - } - - @Test - public void insertShouldFailOnMatchingPathWithDifferentValue() { - OpenApiPathRegistry openApiPathRegistry = new OpenApiPathRegistry<>(); - assertTrue(openApiPathRegistry.insert("/s1/s2", "root1")); - assertFalse(openApiPathRegistry.insert("/s1/{id1}", "root2")); - assertEquals(openApiPathRegistry.search("/s1/s2"), "root1"); - assertNull(openApiPathRegistry.search("/s1/111")); - - assertTrue(openApiPathRegistry.insert("/s1/s2/s3/{id2}", "root3")); - assertFalse(openApiPathRegistry.insert("/s1/{id1}/s3/{id2}", "root4")); - assertEquals(openApiPathRegistry.search("/s1/s2/s3/123"), "root3"); - assertEquals(openApiPathRegistry.search("/s1/s2/s3/456"), "root3"); - assertNull(openApiPathRegistry.search("/s1/111/s3/111")); - - openApiPathRegistry = new OpenApiPathRegistry<>(); - assertTrue(openApiPathRegistry.insert("/s1/{id1}", "root2")); - assertFalse(openApiPathRegistry.insert("/s1/s2", "root1")); - assertEquals(openApiPathRegistry.search("/s1/111"), "root2"); - assertEquals(openApiPathRegistry.search("/s1/s2"), "root2"); - - assertTrue(openApiPathRegistry.insert("/s1/{id1}/s3/{id2}", "root3")); - assertFalse(openApiPathRegistry.insert("/s1/s2/s3/{id2}", "root4")); - assertEquals(openApiPathRegistry.search("/s1/5678/s3/1234"), "root3"); - assertEquals(openApiPathRegistry.search("/s1/s2/s3/1234"), "root3"); - } - - @Test - public void insertShouldNotOverwriteNested() { - OpenApiPathRegistry openApiPathRegistry = new OpenApiPathRegistry<>(); - assertTrue(openApiPathRegistry.insert("/s1/s2/{id1}", "root1")); - assertTrue(openApiPathRegistry.insert("/s1/s2/{id1}/s3/{id2}", "root2")); - assertEquals(openApiPathRegistry.search("/s1/s2/123"), "root1"); - assertEquals(openApiPathRegistry.search("/s1/s2/1233/s3/121"), "root2"); - - openApiPathRegistry = new OpenApiPathRegistry<>(); - assertTrue(openApiPathRegistry.insert("/s1/s2/{id1}/s3/{id2}", "root2")); - assertTrue(openApiPathRegistry.insert("/s1/s2/{id1}", "root1")); - assertEquals(openApiPathRegistry.search("/s1/s2/123"), "root1"); - assertEquals(openApiPathRegistry.search("/s1/s2/1233/s3/121"), "root2"); - } - - @Test - public void randomAccess() { - OpenApiPathRegistry openApiPathRegistry = new OpenApiPathRegistry<>(); - - int numberOfPaths = 1000; // Specify the number of paths you want to generate - List paths = generatePaths(numberOfPaths); - - Map pathToValueMap = paths.stream() - .collect(Collectors.toMap(path -> path, k -> k.replaceAll("\\{[a-zA-Z]*}", "1111"))); - paths.removeIf(path -> !openApiPathRegistry.insert(path, pathToValueMap.get(path))); - - Random random = new Random(); - int[] indexes = new int[1000]; - for (int i = 0; i < 1000; i++) { - indexes[i] = random.nextInt(paths.size() - 1); - } - - for (int i = 0; i < 1000; i++) { - String path = paths.get(indexes[i]); - String realPath = pathToValueMap.get(path); - String result = openApiPathRegistry.search(realPath); - Assert.assertNotNull(result, - "No result for real path " + realPath + " expected a match by path " + path); - Assert.assertEquals(result, realPath); - } - } -} diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiSpecificationTest.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiSpecificationTest.java index 668ecb9b64..bbe892c193 100644 --- a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiSpecificationTest.java +++ b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiSpecificationTest.java @@ -120,7 +120,7 @@ public void shouldInitializeFromUrl(String urlString) { private void assertPingApi(OpenApiSpecification specification) { assertNotNull(specification); - assertNotNull(specification.getSwaggerOpenApiValidationContext()); + assertNotNull(specification.getOpenApiValidationContext()); Optional pingOperationPathAdapter = specification.getOperation( PING_OPERATION_ID, testContextMock); @@ -244,21 +244,21 @@ URL toSpecUrl(String resolvedSpecUrl) { // Then (not yet initialized) assertFalse(specification.isApiRequestValidationEnabled()); - assertNull(specification.getSwaggerOpenApiValidationContext()); + assertNull(specification.getOpenApiValidationContext()); // When (initialize) specification.getOpenApiDoc(testContextMock); // Then assertFalse(specification.isApiRequestValidationEnabled()); - assertNotNull(specification.getSwaggerOpenApiValidationContext()); + assertNotNull(specification.getOpenApiValidationContext()); // When specification.setApiRequestValidationEnabled(true); // Then assertTrue(specification.isApiRequestValidationEnabled()); - assertTrue(specification.getSwaggerOpenApiValidationContext().isRequestValidationEnabled()); + assertTrue(specification.getOpenApiValidationContext().isRequestValidationEnabled()); } @@ -290,15 +290,15 @@ public void shouldDisableEnableResponseValidationWhenSet() { // Then assertFalse(specification.isApiResponseValidationEnabled()); - assertNotNull(specification.getSwaggerOpenApiValidationContext()); - assertFalse(specification.getSwaggerOpenApiValidationContext().isResponseValidationEnabled()); + assertNotNull(specification.getOpenApiValidationContext()); + assertFalse(specification.getOpenApiValidationContext().isResponseValidationEnabled()); // When specification.setApiResponseValidationEnabled(true); // Then assertTrue(specification.isApiResponseValidationEnabled()); - assertTrue(specification.getSwaggerOpenApiValidationContext().isResponseValidationEnabled()); + assertTrue(specification.getOpenApiValidationContext().isResponseValidationEnabled()); } diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiTestDataGeneratorTest.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiTestDataGeneratorTest.java index 6ac0dd9d60..a0e89a4e6e 100644 --- a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiTestDataGeneratorTest.java +++ b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiTestDataGeneratorTest.java @@ -68,7 +68,7 @@ public static void beforeClass() { openApiSpecification = OpenApiSpecification.from( Resources.fromClasspath("org/citrusframework/openapi/ping/ping-api.yaml")); - schemaValidator = openApiSpecification.getSwaggerOpenApiValidationContext() + schemaValidator = openApiSpecification.getOpenApiValidationContext() .getSchemaValidator(); } @@ -289,7 +289,7 @@ void testPingApiSchemas(String schemaType) throws IOException { OasSchema schema = OasModelHelper.getSchemaDefinitions( openApiSpecification.getOpenApiDoc(null)).get(schemaType); - Schema swaggerValidationSchema = openApiSpecification.getSwaggerOpenApiValidationContext() + Schema swaggerValidationSchema = openApiSpecification.getOpenApiValidationContext() .getSwaggerOpenApi().getComponents().getSchemas().get(schemaType); assertNotNull(schema); diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiTestValidationDataGeneratorTest.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiTestValidationDataGeneratorTest.java index 820a8cbbae..3461d46b60 100644 --- a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiTestValidationDataGeneratorTest.java +++ b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiTestValidationDataGeneratorTest.java @@ -16,15 +16,20 @@ package org.citrusframework.openapi; +import static org.assertj.core.api.Assertions.assertThat; import static org.citrusframework.openapi.OpenApiTestValidationDataGenerator.createValidationExpression; +import static org.citrusframework.openapi.OpenApiTestValidationDataGenerator.createValidationRegex; import static org.mockito.Mockito.mock; import static org.testng.Assert.assertEquals; +import io.apicurio.datamodels.openapi.models.OasSchema; import io.apicurio.datamodels.openapi.v2.models.Oas20Schema; import io.apicurio.datamodels.openapi.v2.models.Oas20Schema.Oas20AllOfSchema; import io.apicurio.datamodels.openapi.v3.models.Oas30Schema; import java.util.HashMap; import java.util.List; +import java.util.regex.Pattern; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; public class OpenApiTestValidationDataGeneratorTest { @@ -68,4 +73,85 @@ public void allOfIsIgnoredForOas2() { assertEquals(createValidationExpression( allOfSchema, new HashMap<>(), true, mock()), "\"@ignore@\""); } + + @DataProvider(name = "createValidationRegexDataProvider") + public static Object[][] createValidationRegexDataProvider() { + + Oas30Schema stringSchema = new Oas30Schema(); + stringSchema.type = OpenApiConstants.TYPE_STRING; + + Oas30Schema uuidSchema = new Oas30Schema(); + uuidSchema.type = OpenApiConstants.TYPE_STRING; + uuidSchema.format = OpenApiConstants.FORMAT_UUID; + + Oas30Schema dateSchema = new Oas30Schema(); + dateSchema.type = OpenApiConstants.TYPE_STRING; + dateSchema.format = OpenApiConstants.FORMAT_DATE; + + Oas30Schema dateTimeSchema = new Oas30Schema(); + dateTimeSchema.type = OpenApiConstants.TYPE_STRING; + dateTimeSchema.format = OpenApiConstants.FORMAT_DATE_TIME; + + Oas30Schema integerSchema = new Oas30Schema(); + integerSchema.type = OpenApiConstants.TYPE_INTEGER; + + Oas30Schema numberSchema = new Oas30Schema(); + numberSchema.type = OpenApiConstants.TYPE_NUMBER; + + Oas30Schema booleanSchema = new Oas30Schema(); + booleanSchema.type = OpenApiConstants.TYPE_BOOLEAN; + + Oas30Schema regexSchema = new Oas30Schema(); + regexSchema.type = OpenApiConstants.TYPE_STRING; + regexSchema.pattern = "[1234]5[6789]"; + + Oas30Schema enumSchema = new Oas30Schema(); + enumSchema.type = OpenApiConstants.TYPE_STRING; + enumSchema.enum_ = List.of("A","B","C"); + + return new Object[][]{ + {stringSchema, "xyz", true}, + {uuidSchema, "123e4567-e89b-12d3-a456-426614174000", true}, + {uuidSchema, "123e4567-e89b-12d3-a456-42661417400", false}, + {dateSchema, "2023-05-15", true}, + {dateSchema, "2023-15-15", false}, + {dateTimeSchema, "2023-05-15T10:15:30Z", true}, + {dateTimeSchema, "2023-05-15T25:15:30Z", false}, + {integerSchema, "2023", true}, + {integerSchema, "2023.05", false}, + {numberSchema, "2023", true}, + {numberSchema, "2023.xx", false}, + {booleanSchema, "true", true}, + {booleanSchema, "false", true}, + {booleanSchema, "yes", false}, + {booleanSchema, "no", false}, + {booleanSchema, "yes", false}, + {booleanSchema, "no", false}, + {regexSchema, "156", true}, + {regexSchema, "651", false}, + {enumSchema, "A", true}, + {enumSchema, "B", true}, + {enumSchema, "C", true}, + {enumSchema, "a", false}, + {enumSchema, "D", false}, + }; + } + + @Test(dataProvider = "createValidationRegexDataProvider") + void createValidationRegex_shouldValidateRealDataCorrectly(OasSchema schema, String toValidate, boolean result) { + String regex = createValidationRegex(schema); + assertThat(Pattern.matches(regex, toValidate)).isEqualTo(result); + } + + @Test + void validationRegexOfNullIsEmpty() { + assertThat(createValidationRegex(null)).isEmpty(); + } + + @Test + void defaultvalidationRegexIsEmpty() { + Oas30Schema oas30Schema = new Oas30Schema(); + oas30Schema.type = "xxxx"; + assertThat(createValidationRegex(oas30Schema)).isEmpty(); + } } diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiUtilsTest.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiUtilsTest.java index 533ccb5211..cc222f3f67 100644 --- a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiUtilsTest.java +++ b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/OpenApiUtilsTest.java @@ -16,31 +16,24 @@ package org.citrusframework.openapi; +import static org.citrusframework.openapi.util.OpenApiUtils.getKnownOpenApiAliases; +import static org.citrusframework.openapi.util.OpenApiUtils.getMethodPath; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + import java.util.List; import java.util.Map; import java.util.Set; -import org.citrusframework.http.message.HttpMessage; -import org.citrusframework.http.message.HttpMessageHeaders; -import org.citrusframework.openapi.util.OpenApiUtils; -import org.citrusframework.openapi.validation.OpenApiMessageProcessor; import org.citrusframework.spi.ReferenceResolver; -import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import static org.citrusframework.openapi.util.OpenApiUtils.getKnownOpenApiAliases; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; - public class OpenApiUtilsTest { - @Mock - private HttpMessage httpMessageMock; - private AutoCloseable mockCloseable; @BeforeMethod @@ -53,54 +46,28 @@ public void afterMethod() throws Exception { mockCloseable.close(); } - @Test - public void shouldReturnFormattedMethodPathWhenHttpMessageHasMethodAndPath() { - // Given - when(httpMessageMock.getHeader(HttpMessageHeaders.HTTP_REQUEST_METHOD)).thenReturn("GET"); - when(httpMessageMock.getHeader(HttpMessageHeaders.HTTP_REQUEST_URI)).thenReturn("/api/path"); - - // When - String methodPath = OpenApiUtils.getMethodPath(httpMessageMock); - - // Then - assertEquals(methodPath, "/get/api/path"); - } - - @Test - public void shouldReturnDefaultMethodPathWhenHttpMessageHasNoMethodAndPath() { - // Given - when(httpMessageMock.getHeader(HttpMessageHeaders.HTTP_REQUEST_METHOD)).thenReturn(null); - when(httpMessageMock.getHeader(HttpMessageHeaders.HTTP_REQUEST_URI)).thenReturn(null); - - // When - String methodPath = OpenApiUtils.getMethodPath(httpMessageMock); - - // Then - assertEquals(methodPath, "/null/null"); - } - @Test public void shouldReturnFormattedMethodPathWhenMethodAndPathAreProvided() { // When - String methodPath = OpenApiUtils.getMethodPath("POST", "/api/path"); + String methodPath = getMethodPath("POST", "/api/path"); // Then - assertEquals(methodPath, "/post/api/path"); + assertEquals(methodPath, "POST_/api/path"); } @Test public void shouldReturnFormattedMethodPathWhenMethodIsEmptyAndPathIsProvided() { // When - String methodPath = OpenApiUtils.getMethodPath("", "/api/path"); + String methodPath = getMethodPath("", "/api/path"); // Then - assertEquals(methodPath, "//api/path"); + assertEquals(methodPath, "_/api/path"); } @Test public void shouldReturnFormattedMethodPathWhenMethodAndPathAreEmpty() { // When - String methodPath = OpenApiUtils.getMethodPath("", ""); + String methodPath = getMethodPath("", ""); // Then - assertEquals(methodPath, "//"); + assertEquals(methodPath, "_/"); } @Test diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/actions/OpenApiClientActionBuilderTest.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/actions/OpenApiClientActionBuilderTest.java index 1095cba8e2..1cf06d73a0 100644 --- a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/actions/OpenApiClientActionBuilderTest.java +++ b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/actions/OpenApiClientActionBuilderTest.java @@ -1,25 +1,23 @@ package org.citrusframework.openapi.actions; +import static org.mockito.Mockito.mock; +import static org.testng.Assert.assertNotNull; + import org.citrusframework.endpoint.Endpoint; -import org.citrusframework.openapi.OpenApiSpecification; -import org.citrusframework.spi.AbstractReferenceResolverAwareTestActionBuilder; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import static org.mockito.Mockito.mock; -import static org.testng.Assert.assertTrue; - public class OpenApiClientActionBuilderTest { private OpenApiClientActionBuilder fixture; @BeforeMethod public void beforeMethod() { - fixture = new OpenApiClientActionBuilder(mock(Endpoint.class), mock(OpenApiSpecification.class)); + fixture = new OpenApiClientActionBuilder(mock(Endpoint.class), mock(OpenApiSpecificationSource.class)); } @Test public void isReferenceResolverAwareTestActionBuilder() { - assertTrue(fixture instanceof AbstractReferenceResolverAwareTestActionBuilder, "Is instanceof AbstractReferenceResolverAwareTestActionBuilder"); + assertNotNull(fixture, "Is instanceof AbstractReferenceResolverAwareTestActionBuilder"); } } diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/actions/OpenApiPayloadBuilderTest.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/actions/OpenApiPayloadBuilderTest.java new file mode 100644 index 0000000000..856a39ce6f --- /dev/null +++ b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/actions/OpenApiPayloadBuilderTest.java @@ -0,0 +1,65 @@ +package org.citrusframework.openapi.actions; + +import org.citrusframework.context.TestContext; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.testng.Assert; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +public class OpenApiPayloadBuilderTest { + + private TestContext context; + + @BeforeClass + public void setUp() { + context = new TestContext(); + } + + @Test + public void testBuildPayloadWithMultiValueMap() { + // Given + MultiValueMap multiValueMap = new LinkedMultiValueMap<>(); + multiValueMap.add("key1", "value1"); + multiValueMap.add("key2", "Hello ${user}, welcome!"); + multiValueMap.add("key2", "Another ${user} message"); + multiValueMap.add("${k3}", "a"); + multiValueMap.add("${k3}", "b"); + multiValueMap.add("${k3}", "${user}"); + + context.setVariable("user", "John"); + context.setVariable("k3", "key3"); + + OpenApiPayloadBuilder payloadBuilder = new OpenApiPayloadBuilder(multiValueMap); + + // When + Object payload = payloadBuilder.buildPayload(context); + + // Then + Assert.assertTrue(payload instanceof MultiValueMap); + MultiValueMap result = (MultiValueMap) payload; + + Assert.assertEquals(result.get("key1").get(0), "value1"); + Assert.assertEquals(result.get("key2").get(0), "Hello John, welcome!"); + Assert.assertEquals(result.get("key2").get(1), "Another John message"); + Assert.assertEquals(result.get("key3").get(0), "a"); + Assert.assertEquals(result.get("key3").get(1), "b"); + Assert.assertEquals(result.get("key3").get(2), "John"); + } + + @Test + public void testBuildPayloadWithPlainObject() { + // Given + String simplePayload = "This is a simple ${message}"; + context.setVariable("message", "test"); + + OpenApiPayloadBuilder payloadBuilder = new OpenApiPayloadBuilder(simplePayload); + + // When + Object payload = payloadBuilder.buildPayload(context); + + // Then + Assert.assertTrue(payload instanceof String); + Assert.assertEquals(payload, "This is a simple test"); + } +} diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/actions/OpenApiServerActionBuilderTest.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/actions/OpenApiServerActionBuilderTest.java index dce3c9962f..86fcf00504 100644 --- a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/actions/OpenApiServerActionBuilderTest.java +++ b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/actions/OpenApiServerActionBuilderTest.java @@ -1,21 +1,20 @@ package org.citrusframework.openapi.actions; +import static org.mockito.Mockito.mock; +import static org.testng.Assert.assertTrue; + import org.citrusframework.endpoint.Endpoint; -import org.citrusframework.openapi.OpenApiSpecification; import org.citrusframework.spi.AbstractReferenceResolverAwareTestActionBuilder; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import static org.mockito.Mockito.mock; -import static org.testng.Assert.assertTrue; - public class OpenApiServerActionBuilderTest { private OpenApiServerActionBuilder fixture; @BeforeMethod public void beforeMethod() { - fixture = new OpenApiServerActionBuilder(mock(Endpoint.class), mock(OpenApiSpecification.class)); + fixture = new OpenApiServerActionBuilder(mock(Endpoint.class), mock(OpenApiSpecificationSource.class)); } @Test diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/groovy/OpenApiClientTest.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/groovy/OpenApiClientTest.java index 33aad7e924..d9d06aabf3 100644 --- a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/groovy/OpenApiClientTest.java +++ b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/groovy/OpenApiClientTest.java @@ -113,7 +113,7 @@ public void cleanupEndpoints() { } @Test - public void shouldLoadOpenApiClientActions() throws IOException { + public void shouldLoadOpenApiClientActions() { GroovyTestLoader testLoader = createTestLoader("classpath:org/citrusframework/openapi/groovy/openapi-client.test.groovy"); context.setVariable("port", port); @@ -187,8 +187,6 @@ public void shouldLoadOpenApiClientActions() throws IOException { httpMessageBuilder = ((HttpMessageBuilder)receiveMessageAction.getMessageBuilder()); Assert.assertNotNull(httpMessageBuilder); - Assert.assertEquals(httpMessageBuilder.buildMessagePayload(context, receiveMessageAction.getMessageType()), - "{\"id\": \"@isNumber()@\",\"category\": {\"id\": \"@isNumber()@\",\"name\": \"@notEmpty()@\"},\"name\": \"@notEmpty()@\",\"photoUrls\": \"@ignore@\",\"tags\": \"@ignore@\",\"status\": \"@matches(available|pending|sold)@\"}"); Assert.assertEquals(httpMessageBuilder.getMessage().getHeaders().size(), 5L); Assert.assertNotNull(httpMessageBuilder.getMessage().getHeaders().get(MessageHeaders.ID)); Assert.assertNotNull(httpMessageBuilder.getMessage().getHeaders().get(MessageHeaders.TIMESTAMP)); diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/groovy/OpenApiServerTest.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/groovy/OpenApiServerTest.java index 61023c6dcd..d3a844c00a 100644 --- a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/groovy/OpenApiServerTest.java +++ b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/groovy/OpenApiServerTest.java @@ -33,6 +33,7 @@ import org.citrusframework.message.DefaultMessageQueue; import org.citrusframework.message.MessageHeaders; import org.citrusframework.message.MessageQueue; +import org.citrusframework.openapi.validation.OpenApiMessageValidationContext; import org.citrusframework.spi.BindToRegistry; import org.citrusframework.validation.context.HeaderValidationContext; import org.citrusframework.validation.json.JsonMessageValidationContext; @@ -127,10 +128,11 @@ public void shouldLoadOpenApiServerActions() { int actionIndex = 0; ReceiveMessageAction receiveMessageAction = (ReceiveMessageAction) result.getTestAction(actionIndex++); - assertEquals(receiveMessageAction.getValidationContexts().size(), 3); + assertEquals(receiveMessageAction.getValidationContexts().size(), 4); assertTrue(receiveMessageAction.getValidationContexts().get(0) instanceof HeaderValidationContext); assertTrue(receiveMessageAction.getValidationContexts().get(1) instanceof XmlMessageValidationContext); assertTrue(receiveMessageAction.getValidationContexts().get(2) instanceof JsonMessageValidationContext); + assertTrue(receiveMessageAction.getValidationContexts().get(3) instanceof OpenApiMessageValidationContext); assertEquals(receiveMessageAction.getReceiveTimeout(), 0L); assertTrue(receiveMessageAction.getMessageBuilder() instanceof HttpMessageBuilder); @@ -165,10 +167,11 @@ public void shouldLoadOpenApiServerActions() { assertEquals(sendMessageAction.getMessageProcessors().size(), 1); receiveMessageAction = (ReceiveMessageAction) result.getTestAction(actionIndex++); - assertEquals(receiveMessageAction.getValidationContexts().size(), 3); + assertEquals(receiveMessageAction.getValidationContexts().size(), 4); assertTrue(receiveMessageAction.getValidationContexts().get(0) instanceof HeaderValidationContext); assertTrue(receiveMessageAction.getValidationContexts().get(1) instanceof XmlMessageValidationContext); assertTrue(receiveMessageAction.getValidationContexts().get(2) instanceof JsonMessageValidationContext); + assertTrue(receiveMessageAction.getValidationContexts().get(3) instanceof OpenApiMessageValidationContext); assertEquals(receiveMessageAction.getReceiveTimeout(), 2000L); httpMessageBuilder = ((HttpMessageBuilder)receiveMessageAction.getMessageBuilder()); diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/integration/OpenApiClientIT.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/integration/OpenApiClientIT.java index c210208820..14bfb26f55 100644 --- a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/integration/OpenApiClientIT.java +++ b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/integration/OpenApiClientIT.java @@ -27,11 +27,16 @@ import org.citrusframework.openapi.OpenApiSpecification; import org.citrusframework.openapi.actions.OpenApiActionBuilder; import org.citrusframework.openapi.actions.OpenApiClientResponseActionBuilder; -import org.citrusframework.spi.BindToRegistry; +import org.citrusframework.openapi.integration.OpenApiClientIT.Config; import org.citrusframework.spi.Resources; import org.citrusframework.testng.spring.TestNGCitrusSpringSupport; import org.citrusframework.util.SocketUtils; +import org.junit.jupiter.api.BeforeEach; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; +import org.springframework.test.context.ContextConfiguration; import org.testng.annotations.DataProvider; import org.testng.annotations.Ignore; import org.testng.annotations.Test; @@ -44,29 +49,18 @@ import static org.testng.Assert.fail; @Test +@ContextConfiguration(classes = {Config.class}) public class OpenApiClientIT extends TestNGCitrusSpringSupport { public static final String VALID_PET_PATH = "classpath:org/citrusframework/openapi/petstore/pet.json"; - public static final String INVALID_PET_PATH = "classpath:org/citrusframework/openapi/petstore/pet_invalid.json"; - - private final int port = SocketUtils.findAvailableTcpPort(8080); - @BindToRegistry - private final HttpServer httpServer = new HttpServerBuilder() - .port(port) - .timeout(5000L) - .autoStart(true) - .defaultStatus(HttpStatus.NO_CONTENT) - .build(); + public static final String INVALID_PET_PATH = "classpath:org/citrusframework/openapi/petstore/pet_invalid.json"; - @BindToRegistry - private final HttpClient httpClient = new HttpClientBuilder() - .requestUrl("http://localhost:%d".formatted(port)) - .build(); + @Autowired + private HttpServer httpServer; - @BindToRegistry - private final OpenApiRepository openApiRepository = new OpenApiRepository() - .locations(List.of("classpath:org/citrusframework/openapi/petstore/petstore-v3.json")); + @Autowired + private HttpClient httpClient; private final OpenApiSpecification petstoreSpec = OpenApiSpecification.from( Resources.create("classpath:org/citrusframework/openapi/petstore/petstore-v3.json")); @@ -74,26 +68,30 @@ public class OpenApiClientIT extends TestNGCitrusSpringSupport { private final OpenApiSpecification pingSpec = OpenApiSpecification.from( Resources.create("classpath:org/citrusframework/openapi/ping/ping-api.yaml")); + @BeforeEach + void beforeEach() { + } + @CitrusTest @Test - public void shouldExecuteGetPetByIdFromDirectSpec() { - shouldExecuteGetPetById(openapi(petstoreSpec), VALID_PET_PATH, true, false); + public void shouldExecuteGetPetById() { + shouldExecuteGetPetById(openapi(petstoreSpec), VALID_PET_PATH, true, true); } @CitrusTest @Test public void shouldFailOnMissingNameInResponse() { - shouldExecuteGetPetById(openapi(petstoreSpec), INVALID_PET_PATH, false, false); + shouldExecuteGetPetById(openapi(petstoreSpec), INVALID_PET_PATH, false, true); } @CitrusTest @Test public void shouldSucceedOnMissingNameInResponseWithValidationDisabled() { - shouldExecuteGetPetById(openapi(petstoreSpec), INVALID_PET_PATH, true, true); + shouldExecuteGetPetById(openapi(petstoreSpec), INVALID_PET_PATH, true, false); } private void shouldExecuteGetPetById(OpenApiActionBuilder openapi, String responseFile, - boolean valid, boolean disableValidation) { + boolean valid, boolean schemaValidation) { variable("petId", "1001"); @@ -118,7 +116,7 @@ private void shouldExecuteGetPetById(OpenApiActionBuilder openapi, String respon OpenApiClientResponseActionBuilder clientResponseActionBuilder = openapi .client(httpClient).receive("getPetById", HttpStatus.OK) - .disableOasValidation(disableValidation); + .schemaValidation(schemaValidation); if (valid) { then(clientResponseActionBuilder); @@ -127,12 +125,6 @@ private void shouldExecuteGetPetById(OpenApiActionBuilder openapi, String respon } } - @CitrusTest - @Test - public void shouldProperlyExecuteGetAndAddPetFromDirectSpec() { - shouldExecuteGetAndAddPet(openapi(petstoreSpec)); - } - @CitrusTest @Test public void shouldProperlyExecuteGetAndAddPetFromRepository() { @@ -170,7 +162,7 @@ public void shouldSucceedOnWrongQueryIdTypeWithOasDisabled() { HttpMessageBuilderSupport addPetBuilder = openapi(petstoreSpec) .client(httpClient) .send("addPet") - .disableOasValidation(true) + .schemaValidation(false) .message().body(Resources.create(VALID_PET_PATH)); try { @@ -226,7 +218,7 @@ public static Object[][] pingApiOperationDataprovider() { @Test(dataProvider = "pingApiOperationDataprovider") @CitrusTest - @Ignore // Solve issue with composite schemes + @Ignore public void shouldPerformRoundtripPingOperation(String pingApiOperation) { variable("id", 2001); @@ -251,4 +243,34 @@ public void shouldPerformRoundtripPingOperation(String pingApiOperation) { then(clientResponseActionBuilder); } + + @Configuration + public static class Config { + + private final int port = SocketUtils.findAvailableTcpPort(8080); + + @Bean + public HttpServer httpServer() { + + return new HttpServerBuilder() + .port(port) + .timeout(5000L) + .autoStart(true) + .defaultStatus(HttpStatus.NO_CONTENT) + .build(); + } + + @Bean + public HttpClient httpClient() { + return new HttpClientBuilder() + .requestUrl("http://localhost:%d".formatted(port)) + .build(); + } + + @Bean + public OpenApiRepository petstoreOpenApiRepository() { + return new OpenApiRepository() + .locations(List.of("classpath:org/citrusframework/openapi/petstore/petstore-v3.json")); + } + } } diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/integration/OpenApiServerIT.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/integration/OpenApiServerIT.java index 808c84cdc2..d87831c3f9 100644 --- a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/integration/OpenApiServerIT.java +++ b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/integration/OpenApiServerIT.java @@ -27,11 +27,15 @@ import org.citrusframework.openapi.actions.OpenApiActionBuilder; import org.citrusframework.openapi.actions.OpenApiServerRequestActionBuilder; import org.citrusframework.openapi.actions.OpenApiServerResponseActionBuilder; -import org.citrusframework.spi.BindToRegistry; +import org.citrusframework.openapi.integration.OpenApiServerIT.Config; import org.citrusframework.spi.Resources; import org.citrusframework.testng.spring.TestNGCitrusSpringSupport; import org.citrusframework.util.SocketUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; +import org.springframework.test.context.ContextConfiguration; import org.testng.annotations.Test; import java.util.List; @@ -42,30 +46,17 @@ import static org.testng.Assert.fail; @Test +@ContextConfiguration(classes = {Config.class}) public class OpenApiServerIT extends TestNGCitrusSpringSupport { public static final String VALID_PET_PATH = "classpath:org/citrusframework/openapi/petstore/pet.json"; public static final String INVALID_PET_PATH = "classpath:org/citrusframework/openapi/petstore/pet_invalid.json"; - private final int port = SocketUtils.findAvailableTcpPort(8080); - - @BindToRegistry - private final HttpServer httpServer = new HttpServerBuilder() - .port(port) - .timeout(5000L) - .autoStart(true) - .defaultStatus(HttpStatus.NO_CONTENT) - .build(); - - @BindToRegistry - private final HttpClient httpClient = new HttpClientBuilder() - .requestUrl("http://localhost:%d/petstore/v3".formatted(port)) - .build(); - - @BindToRegistry - private final OpenApiRepository openApiRepository = new OpenApiRepository() - .locations(List.of("classpath:org/citrusframework/openapi/petstore/petstore-v3.json")); + @Autowired + private HttpServer httpServer; + @Autowired + private HttpClient httpClient; @CitrusTest public void shouldExecuteGetPetById() { @@ -81,7 +72,9 @@ public void shouldExecuteGetPetById() { then(openapi("petstore-v3") .server(httpServer) - .receive("getPetById")); + .receive("getPetById") + .message() + ); then(openapi("petstore-v3") .server(httpServer) @@ -107,6 +100,47 @@ public void shouldExecuteGetPetById() { """)); } + @CitrusTest + public void shouldExecuteGetPetByIdWithRandomizedId() { + + when(http() + .client(httpClient) + .send() + .get("/pet/726354") + .message() + .accept("application/json") + .fork(true)); + + then(openapi("petstore-v3") + .server(httpServer) + .receive("getPetById") + .message() + ); + + then(openapi("petstore-v3") + .server(httpServer) + .send("getPetById", HttpStatus.OK)); + + then(http() + .client(httpClient) + .receive() + .response(HttpStatus.OK) + .message() + .body(""" + { + "id": "@isNumber()@", + "name": "@notEmpty()@", + "category": { + "id": "@isNumber()@", + "name": "@notEmpty()@" + }, + "photoUrls": "@notEmpty()@", + "tags": "@ignore@", + "status": "@matches(sold|pending|available)@" + } + """)); + } + @CitrusTest public void executeGetPetByIdShouldFailOnInvalidResponse() { variable("petId", "1001"); @@ -161,7 +195,7 @@ public void executeGetPetByIdShouldSucceedOnInvalidResponseWithValidationDisable HttpMessageBuilderSupport getPetByIdResponseBuilder = openapi("petstore-v3") .server(httpServer) .send("getPetById", HttpStatus.OK) - .disableOasValidation(true) + .schemaValidation(false) .message().body(""" { "id": "xxxx", @@ -199,12 +233,17 @@ public void executeGetPetByIdShouldSucceedOnInvalidResponseWithValidationDisable @CitrusTest public void shouldExecuteAddPet() { - shouldExecuteAddPet(openapi("petstore-v3"), VALID_PET_PATH, true); + shouldExecuteAddPet(openapi("petstore-v3"), VALID_PET_PATH, true, true); } @CitrusTest public void shouldFailOnMissingNameInRequest() { - shouldExecuteAddPet(openapi("petstore-v3"), INVALID_PET_PATH, false); + shouldExecuteAddPet(openapi("petstore-v3"), INVALID_PET_PATH, false, true); + } + + @CitrusTest + public void shouldPassOnMissingNameInRequestIfValidationIsDisabled() { + shouldExecuteAddPet(openapi("petstore-v3"), INVALID_PET_PATH, false, false); } @CitrusTest @@ -268,7 +307,7 @@ public void shouldSucceedOnWrongQueryIdTypeWithOasDisabled() { OpenApiServerRequestActionBuilder addPetBuilder = openapi("petstore-v3") .server(httpServer) .receive("addPet") - .disableOasValidation(false); + .schemaValidation(false); try { when(addPetBuilder); @@ -277,7 +316,7 @@ public void shouldSucceedOnWrongQueryIdTypeWithOasDisabled() { } } - private void shouldExecuteAddPet(OpenApiActionBuilder openapi, String requestFile, boolean valid) { + private void shouldExecuteAddPet(OpenApiActionBuilder openapi, String requestFile, boolean valid, boolean validationEnabled) { variable("petId", "1001"); when(http() @@ -311,4 +350,33 @@ private void shouldExecuteAddPet(OpenApiActionBuilder openapi, String requestFil } + @Configuration + public static class Config { + + private final int port = SocketUtils.findAvailableTcpPort(8080); + + @Bean + public HttpServer httpServer() { + return new HttpServerBuilder() + .port(port) + .timeout(5000L) + .autoStart(true) + .defaultStatus(HttpStatus.NO_CONTENT) + .build(); + } + + @Bean + public HttpClient httpClient() { + return new HttpClientBuilder() + .requestUrl("http://localhost:%d/petstore/v3".formatted(port)) + .build(); + } + + @Bean + public OpenApiRepository petstoreOpenApiRepository() { + return new OpenApiRepository() + .locations(List.of("classpath:org/citrusframework/openapi/petstore/petstore-v3.json")); + } + } + } diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/random/RandomCompositeGeneratorTest.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/random/RandomCompositeGeneratorTest.java index ab2da578e7..160c6d9f91 100644 --- a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/random/RandomCompositeGeneratorTest.java +++ b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/random/RandomCompositeGeneratorTest.java @@ -1,5 +1,6 @@ package org.citrusframework.openapi.random; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.any; import static org.mockito.Mockito.assertArg; import static org.mockito.Mockito.atLeast; @@ -10,7 +11,6 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.testng.Assert.assertTrue; import io.apicurio.datamodels.openapi.models.OasSchema; import io.apicurio.datamodels.openapi.v3.models.Oas30Schema; @@ -39,7 +39,7 @@ public void testHandlesCompositeSchema() { Oas30Schema schema = new Oas30Schema(); schema.allOf = Collections.singletonList(new Oas30Schema()); - assertTrue(generator.handles(schema)); + assertThat(generator.handles(schema)).isTrue(); } @Test @@ -62,9 +62,9 @@ public void testGenerateAnyOf() { generator.generate(mockContext, schema); - verify(builderSpy).object(any()); - verify(mockContext, atLeast(1)).generate(assertArg(arg -> schema.anyOf.contains(arg))); - verify(mockContext, atMost(3)).generate(assertArg(arg -> schema.anyOf.contains(arg))); + verify(builderSpy, atMost(2)).object(any()); + verify(mockContext, atLeast(1)).generate(assertArg(arg -> assertThat(schema.anyOf).contains(arg))); + verify(mockContext, atMost(3)).generate(assertArg(arg -> assertThat(schema.anyOf).contains(arg))); } @Test diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/validation/OpenApiRequestValidationProcessorTest.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/validation/OpenApiRequestValidationProcessorTest.java deleted file mode 100644 index 04a0d47086..0000000000 --- a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/validation/OpenApiRequestValidationProcessorTest.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.citrusframework.openapi.validation; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.anyString; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; -import static org.testng.Assert.assertNotNull; - -import java.util.Optional; -import org.citrusframework.context.TestContext; -import org.citrusframework.http.message.HttpMessage; -import org.citrusframework.message.Message; -import org.citrusframework.openapi.OpenApiSpecification; -import org.citrusframework.openapi.model.OperationPathAdapter; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.springframework.test.util.ReflectionTestUtils; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -public class OpenApiRequestValidationProcessorTest { - - @Mock - private OpenApiSpecification openApiSpecificationMock; - - @Mock - private OperationPathAdapter operationPathAdapterMock; - - private OpenApiRequestValidationProcessor processor; - - private AutoCloseable mockCloseable; - - @BeforeMethod - public void beforeMethod() { - mockCloseable = MockitoAnnotations.openMocks(this); - processor = new OpenApiRequestValidationProcessor(openApiSpecificationMock, "operationId"); - } - - @AfterMethod - public void afterMethod() throws Exception { - mockCloseable.close(); - } - - @Test - public void shouldNotValidateNonHttpMessage() { - Message messageMock = mock(); - - processor.validate(messageMock, mock()); - - verify(openApiSpecificationMock,times(2)).getSwaggerOpenApiValidationContext(); - verifyNoMoreInteractions(openApiSpecificationMock); - } - - @Test - public void shouldValidateHttpMessage() { - HttpMessage httpMessageMock = mock(); - TestContext contextMock = mock(); - - OpenApiRequestValidator openApiRequestValidatorSpy = replaceValidatorWithSpy(httpMessageMock); - - when(openApiSpecificationMock.getOperation(anyString(), any(TestContext.class))) - .thenReturn(Optional.of(operationPathAdapterMock)); - - processor.validate(httpMessageMock, contextMock); - - verify(openApiRequestValidatorSpy).validateRequest(operationPathAdapterMock, httpMessageMock); - } - - @Test - public void shouldCallValidateRequest() { - HttpMessage httpMessageMock = mock(); - TestContext contextMock = mock(); - - OpenApiRequestValidator openApiRequestValidatorSpy = replaceValidatorWithSpy(httpMessageMock); - - when(openApiSpecificationMock.getOperation(anyString(), any(TestContext.class))) - .thenReturn(Optional.empty()); - - processor.validate(httpMessageMock, contextMock); - - verify(openApiSpecificationMock).getOperation(anyString(), - any(TestContext.class)); - verify(openApiRequestValidatorSpy, times(0)).validateRequest(operationPathAdapterMock, httpMessageMock); - } - - private OpenApiRequestValidator replaceValidatorWithSpy(HttpMessage httpMessage) { - OpenApiRequestValidator openApiRequestValidator = (OpenApiRequestValidator) ReflectionTestUtils.getField( - processor, - "openApiRequestValidator"); - - assertNotNull(openApiRequestValidator); - OpenApiRequestValidator openApiRequestValidatorSpy = spy(openApiRequestValidator); - ReflectionTestUtils.setField(processor, "openApiRequestValidator", openApiRequestValidatorSpy); - - doAnswer((invocation) -> null - // do nothing - ).when(openApiRequestValidatorSpy).validateRequest(operationPathAdapterMock, httpMessage); - - return openApiRequestValidatorSpy; - } -} diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/validation/OpenApiRequestValidatorTest.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/validation/OpenApiRequestValidatorTest.java index 3716b503c7..478480e9ba 100644 --- a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/validation/OpenApiRequestValidatorTest.java +++ b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/validation/OpenApiRequestValidatorTest.java @@ -16,9 +16,9 @@ package org.citrusframework.openapi.validation; +import static org.citrusframework.http.message.HttpMessageHeaders.HTTP_REQUEST_URI; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.testng.Assert.assertEquals; @@ -37,13 +37,13 @@ import java.util.Map; import org.citrusframework.exceptions.ValidationException; import org.citrusframework.http.message.HttpMessage; -import org.citrusframework.http.message.HttpMessageHeaders; import org.citrusframework.openapi.OpenApiSpecification; import org.citrusframework.openapi.model.OperationPathAdapter; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.RequestMethod; -import org.testng.Assert; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -54,7 +54,7 @@ public class OpenApiRequestValidatorTest { private OpenApiSpecification openApiSpecificationMock; @Mock - private SwaggerOpenApiValidationContext swaggerOpenApiValidationContextMock; + private OpenApiValidationContext openApiValidationContextMock; @Mock private OpenApiInteractionValidator openApiInteractionValidatorMock; @@ -76,8 +76,8 @@ public class OpenApiRequestValidatorTest { public void beforeMethod() { mockCloseable = MockitoAnnotations.openMocks(this); - doReturn(swaggerOpenApiValidationContextMock).when(openApiSpecificationMock).getSwaggerOpenApiValidationContext(); - doReturn(openApiInteractionValidatorMock).when(swaggerOpenApiValidationContextMock).getOpenApiInteractionValidator(); + doReturn(openApiValidationContextMock).when(openApiSpecificationMock).getOpenApiValidationContext(); + doReturn(openApiInteractionValidatorMock).when(openApiValidationContextMock).getOpenApiInteractionValidator(); openApiRequestValidator = new OpenApiRequestValidator(openApiSpecificationMock); } @@ -87,22 +87,10 @@ public void afterMethod() throws Exception { mockCloseable.close(); } - @Test - public void shouldNotValidateWhenDisabled() { - // Given - openApiRequestValidator.setEnabled(false); - // When - openApiRequestValidator.validateRequest(operationPathAdapterMock, httpMessageMock); - // Then - Assert.assertFalse(openApiRequestValidator.isEnabled()); - verify(openApiInteractionValidatorMock, never()).validateRequest(any(Request.class)); - } - @Test public void shouldValidateRequestWithNoErrors() { // Given - openApiRequestValidator.setEnabled(true); - when(httpMessageMock.getHeader(HttpMessageHeaders.HTTP_REQUEST_URI)).thenReturn("/api/test"); + when(httpMessageMock.getHeader(HTTP_REQUEST_URI)).thenReturn("/api/test"); when(httpMessageMock.getRequestMethod()).thenReturn(RequestMethod.GET); when(openApiInteractionValidatorMock.validateRequest(any(Request.class))) .thenReturn(validationReportMock); @@ -119,8 +107,7 @@ public void shouldValidateRequestWithNoErrors() { @Test(expectedExceptions = ValidationException.class) public void shouldValidateRequestWithErrors() { // Given - openApiRequestValidator.setEnabled(true); - when(httpMessageMock.getHeader(HttpMessageHeaders.HTTP_REQUEST_URI)).thenReturn("/api/test"); + when(httpMessageMock.getHeader(HTTP_REQUEST_URI)).thenReturn("/api/test"); when(httpMessageMock.getRequestMethod()).thenReturn(RequestMethod.GET); when(openApiInteractionValidatorMock.validateRequest(any(Request.class))) .thenReturn(validationReportMock); @@ -145,7 +132,7 @@ public void shouldCreateRequestFromMessage() throws IOException { headers.put("simple", "s1"); when(httpMessageMock.getHeaders()).thenReturn(headers); - when(httpMessageMock.getHeader(HttpMessageHeaders.HTTP_REQUEST_URI)).thenReturn("/api/test"); + when(httpMessageMock.getHeader(HTTP_REQUEST_URI)).thenReturn("/api/test"); when(httpMessageMock.getRequestMethod()).thenReturn(RequestMethod.GET); when(httpMessageMock.getAccept()).thenReturn("application/json"); when(operationPathAdapterMock.contextPath()).thenReturn("/api"); @@ -167,4 +154,24 @@ public void shouldCreateRequestFromMessage() throws IOException { assertEquals(request.getRequestBody().get().toString(StandardCharsets.UTF_8), "payload"); } + @Test + public void shouldCreateFormRequestFromMessage() throws IOException { + // Given + MultiValueMap formData = new LinkedMultiValueMap<>(); + formData.add("name", "John Doe"); + formData.add("age", 30); + formData.add("city", "New York"); + + when(httpMessageMock.getPayload()).thenReturn(formData); + + when(httpMessageMock.getHeader(HTTP_REQUEST_URI)).thenReturn("/api/test"); + when(httpMessageMock.getRequestMethod()).thenReturn(RequestMethod.GET); + + // When + Request request = openApiRequestValidator.createRequestFromMessage(operationPathAdapterMock, httpMessageMock); + + // Then + assertEquals(request.getRequestBody().get().toString(StandardCharsets.UTF_8), "name=John+Doe&age=30&city=New+York"); + } + } diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/validation/OpenApiResponseValidatorTest.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/validation/OpenApiResponseValidatorTest.java index cfccf76d92..2246b0c00f 100644 --- a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/validation/OpenApiResponseValidatorTest.java +++ b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/validation/OpenApiResponseValidatorTest.java @@ -19,7 +19,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.testng.Assert.assertEquals; @@ -42,7 +41,6 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.springframework.http.HttpStatusCode; -import org.testng.Assert; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -53,7 +51,7 @@ public class OpenApiResponseValidatorTest { private OpenApiSpecification openApiSpecificationMock; @Mock - private SwaggerOpenApiValidationContext swaggerOpenApiValidationContextMock; + private OpenApiValidationContext openApiValidationContextMock; @Mock private OpenApiInteractionValidator openApiInteractionValidatorMock; @@ -79,8 +77,8 @@ public class OpenApiResponseValidatorTest { public void beforeMethod() { mockCloseable = MockitoAnnotations.openMocks(this); - doReturn(swaggerOpenApiValidationContextMock).when(openApiSpecificationMock).getSwaggerOpenApiValidationContext(); - doReturn(openApiInteractionValidatorMock).when(swaggerOpenApiValidationContextMock).getOpenApiInteractionValidator(); + doReturn(openApiValidationContextMock).when(openApiSpecificationMock).getOpenApiValidationContext(); + doReturn(openApiInteractionValidatorMock).when(openApiValidationContextMock).getOpenApiInteractionValidator(); openApiResponseValidator = new OpenApiResponseValidator(openApiSpecificationMock); } @@ -90,21 +88,10 @@ public void afterMethod() throws Exception { mockCloseable.close(); } - @Test - public void shouldNotValidateWhenDisabled() { - // Given - openApiResponseValidator.setEnabled(false); - // When - openApiResponseValidator.validateResponse(operationPathAdapterMock, httpMessageMock); - // Then - Assert.assertFalse(openApiResponseValidator.isEnabled()); - verify(openApiInteractionValidatorMock, never()).validateResponse(anyString(), any(Method.class), any(Response.class)); - } @Test public void shouldValidateWithNoErrors() { // Given - openApiResponseValidator.setEnabled(true); when(openApiInteractionValidatorMock.validateResponse(anyString(), any(Method.class), any(Response.class))) .thenReturn(validationReportMock); when(validationReportMock.hasErrors()).thenReturn(false); @@ -125,7 +112,6 @@ public void shouldValidateWithNoErrors() { @Test(expectedExceptions = ValidationException.class) public void shouldValidateWithErrors() { // Given - openApiResponseValidator.setEnabled(true); when(openApiInteractionValidatorMock.validateResponse(anyString(), any(Method.class), any(Response.class))) .thenReturn(validationReportMock); when(validationReportMock.hasErrors()).thenReturn(true); diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/xml/OpenApiClientTest.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/xml/OpenApiClientTest.java index 2fc0bb33bf..c18d7509dc 100644 --- a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/xml/OpenApiClientTest.java +++ b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/xml/OpenApiClientTest.java @@ -193,8 +193,6 @@ public void shouldLoadOpenApiClientActions() throws IOException { httpMessageBuilder = ((HttpMessageBuilder)receiveMessageAction.getMessageBuilder()); Assert.assertNotNull(httpMessageBuilder); - Assert.assertEquals(httpMessageBuilder.buildMessagePayload(context, receiveMessageAction.getMessageType()), - "{\"id\": \"@isNumber()@\",\"category\": {\"id\": \"@isNumber()@\",\"name\": \"@notEmpty()@\"},\"name\": \"@notEmpty()@\",\"photoUrls\": \"@ignore@\",\"tags\": \"@ignore@\",\"status\": \"@matches(available|pending|sold)@\"}"); Assert.assertEquals(httpMessageBuilder.getMessage().getHeaders().size(), 5L); Assert.assertNotNull(httpMessageBuilder.getMessage().getHeaders().get(MessageHeaders.ID)); Assert.assertNotNull(httpMessageBuilder.getMessage().getHeaders().get(MessageHeaders.TIMESTAMP)); diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/xml/OpenApiServerTest.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/xml/OpenApiServerTest.java index b151699c66..bcfee0463f 100644 --- a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/xml/OpenApiServerTest.java +++ b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/xml/OpenApiServerTest.java @@ -32,6 +32,7 @@ import org.citrusframework.message.DefaultMessageQueue; import org.citrusframework.message.MessageHeaders; import org.citrusframework.message.MessageQueue; +import org.citrusframework.openapi.validation.OpenApiMessageValidationContext; import org.citrusframework.spi.BindToRegistry; import org.citrusframework.validation.context.HeaderValidationContext; import org.citrusframework.validation.json.JsonMessageValidationContext; @@ -124,10 +125,11 @@ public void shouldLoadOpenApiServerActions() { int actionIndex = 0; ReceiveMessageAction receiveMessageAction = (ReceiveMessageAction) result.getTestAction(actionIndex++); - Assert.assertEquals(receiveMessageAction.getValidationContexts().size(), 3); + Assert.assertEquals(receiveMessageAction.getValidationContexts().size(), 4); Assert.assertTrue(receiveMessageAction.getValidationContexts().get(0) instanceof HeaderValidationContext); Assert.assertTrue(receiveMessageAction.getValidationContexts().get(1) instanceof XmlMessageValidationContext); Assert.assertTrue(receiveMessageAction.getValidationContexts().get(2) instanceof JsonMessageValidationContext); + Assert.assertTrue(receiveMessageAction.getValidationContexts().get(3) instanceof OpenApiMessageValidationContext); Assert.assertEquals(receiveMessageAction.getReceiveTimeout(), 0L); Assert.assertTrue(receiveMessageAction.getMessageBuilder() instanceof HttpMessageBuilder); @@ -162,10 +164,11 @@ public void shouldLoadOpenApiServerActions() { Assert.assertEquals(sendMessageAction.getMessageProcessors().size(), 1); receiveMessageAction = (ReceiveMessageAction) result.getTestAction(actionIndex++); - Assert.assertEquals(receiveMessageAction.getValidationContexts().size(), 3); + Assert.assertEquals(receiveMessageAction.getValidationContexts().size(), 4); Assert.assertTrue(receiveMessageAction.getValidationContexts().get(0) instanceof HeaderValidationContext); Assert.assertTrue(receiveMessageAction.getValidationContexts().get(1) instanceof XmlMessageValidationContext); Assert.assertTrue(receiveMessageAction.getValidationContexts().get(2) instanceof JsonMessageValidationContext); + Assert.assertTrue(receiveMessageAction.getValidationContexts().get(3) instanceof OpenApiMessageValidationContext); Assert.assertEquals(receiveMessageAction.getReceiveTimeout(), 2000L); httpMessageBuilder = ((HttpMessageBuilder)receiveMessageAction.getMessageBuilder()); diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/yaml/OpenApiClientTest.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/yaml/OpenApiClientTest.java index e81a89e63b..24757fb060 100644 --- a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/yaml/OpenApiClientTest.java +++ b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/yaml/OpenApiClientTest.java @@ -114,7 +114,7 @@ public void cleanupEndpoints() { } @Test - public void shouldLoadOpenApiClientActions() throws IOException { + public void shouldLoadOpenApiClientActions() { YamlTestLoader testLoader = createTestLoader("classpath:org/citrusframework/openapi/yaml/openapi-client-test.yaml"); context.setVariable("port", port); @@ -188,8 +188,6 @@ public void shouldLoadOpenApiClientActions() throws IOException { httpMessageBuilder = ((HttpMessageBuilder)receiveMessageAction.getMessageBuilder()); Assert.assertNotNull(httpMessageBuilder); - Assert.assertEquals(httpMessageBuilder.buildMessagePayload(context, receiveMessageAction.getMessageType()), - "{\"id\": \"@isNumber()@\",\"category\": {\"id\": \"@isNumber()@\",\"name\": \"@notEmpty()@\"},\"name\": \"@notEmpty()@\",\"photoUrls\": \"@ignore@\",\"tags\": \"@ignore@\",\"status\": \"@matches(available|pending|sold)@\"}"); Assert.assertEquals(httpMessageBuilder.getMessage().getHeaders().size(), 5L); Assert.assertNotNull(httpMessageBuilder.getMessage().getHeaders().get(MessageHeaders.ID)); Assert.assertNotNull(httpMessageBuilder.getMessage().getHeaders().get(MessageHeaders.TIMESTAMP)); diff --git a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/yaml/OpenApiServerTest.java b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/yaml/OpenApiServerTest.java index 723609e773..b0edf652dc 100644 --- a/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/yaml/OpenApiServerTest.java +++ b/connectors/citrus-openapi/src/test/java/org/citrusframework/openapi/yaml/OpenApiServerTest.java @@ -32,6 +32,7 @@ import org.citrusframework.message.DefaultMessageQueue; import org.citrusframework.message.MessageHeaders; import org.citrusframework.message.MessageQueue; +import org.citrusframework.openapi.validation.OpenApiMessageValidationContext; import org.citrusframework.spi.BindToRegistry; import org.citrusframework.validation.context.HeaderValidationContext; import org.citrusframework.validation.json.JsonMessageValidationContext; @@ -124,10 +125,11 @@ public void shouldLoadOpenApiServerActions() { int actionIndex = 0; ReceiveMessageAction receiveMessageAction = (ReceiveMessageAction) result.getTestAction(actionIndex++); - Assert.assertEquals(receiveMessageAction.getValidationContexts().size(), 3); + Assert.assertEquals(receiveMessageAction.getValidationContexts().size(), 4); Assert.assertTrue(receiveMessageAction.getValidationContexts().get(0) instanceof HeaderValidationContext); Assert.assertTrue(receiveMessageAction.getValidationContexts().get(1) instanceof XmlMessageValidationContext); Assert.assertTrue(receiveMessageAction.getValidationContexts().get(2) instanceof JsonMessageValidationContext); + Assert.assertTrue(receiveMessageAction.getValidationContexts().get(3) instanceof OpenApiMessageValidationContext); Assert.assertEquals(receiveMessageAction.getReceiveTimeout(), 0L); Assert.assertTrue(receiveMessageAction.getMessageBuilder() instanceof HttpMessageBuilder); @@ -162,10 +164,11 @@ public void shouldLoadOpenApiServerActions() { Assert.assertEquals(sendMessageAction.getMessageProcessors().size(), 1); receiveMessageAction = (ReceiveMessageAction) result.getTestAction(actionIndex++); - Assert.assertEquals(receiveMessageAction.getValidationContexts().size(), 3); + Assert.assertEquals(receiveMessageAction.getValidationContexts().size(), 4); Assert.assertTrue(receiveMessageAction.getValidationContexts().get(0) instanceof HeaderValidationContext); Assert.assertTrue(receiveMessageAction.getValidationContexts().get(1) instanceof XmlMessageValidationContext); Assert.assertTrue(receiveMessageAction.getValidationContexts().get(2) instanceof JsonMessageValidationContext); + Assert.assertTrue(receiveMessageAction.getValidationContexts().get(3) instanceof OpenApiMessageValidationContext); Assert.assertEquals(receiveMessageAction.getReceiveTimeout(), 2000L); httpMessageBuilder = ((HttpMessageBuilder)receiveMessageAction.getMessageBuilder()); diff --git a/core/citrus-api/src/main/java/org/citrusframework/CitrusSettings.java b/core/citrus-api/src/main/java/org/citrusframework/CitrusSettings.java index 94445abcf3..8de25f9978 100644 --- a/core/citrus-api/src/main/java/org/citrusframework/CitrusSettings.java +++ b/core/citrus-api/src/main/java/org/citrusframework/CitrusSettings.java @@ -427,7 +427,7 @@ public static Set getTestFileNamePattern(String type) { * @param def the default value * @return first value encountered, which is not null. May return null, if default value is null. */ - private static String getPropertyEnvOrDefault(String prop, String env, String def) { + public static String getPropertyEnvOrDefault(String prop, String env, String def) { return getProperty(prop, getenv(env) != null ? getenv(env) : def); } } diff --git a/core/citrus-api/src/main/java/org/citrusframework/util/ReflectionHelper.java b/core/citrus-api/src/main/java/org/citrusframework/util/ReflectionHelper.java index aa9ca41871..aaaed98d12 100644 --- a/core/citrus-api/src/main/java/org/citrusframework/util/ReflectionHelper.java +++ b/core/citrus-api/src/main/java/org/citrusframework/util/ReflectionHelper.java @@ -16,6 +16,9 @@ package org.citrusframework.util; +import static java.lang.String.format; + +import jakarta.annotation.Nonnull; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -224,6 +227,7 @@ public static Object invokeMethod(Method method, Object target, Object... args) } } + @SuppressWarnings("java:S3011") public static void setField(Field f, Object instance, Object value) { try { if (!Modifier.isPublic(f.getModifiers()) && !f.canAccess(instance)) { @@ -235,6 +239,7 @@ public static void setField(Field f, Object instance, Object value) { } } + @SuppressWarnings("java:S3011") public static Object getField(Field f, Object instance) { try { if ((!Modifier.isPublic(f.getModifiers()) || @@ -253,4 +258,31 @@ public static Object getField(Field f, Object instance) { return null; } } + + /** + * Copies the values of all declared fields from a source object to a target object for the specified class. + */ + @SuppressWarnings("java:S3011") + public static void copyFields(@Nonnull Class clazz, @Nonnull Object source, @Nonnull Object target) { + Class currentClass = clazz; + + while (currentClass != null) { + Field[] fields = currentClass.getDeclaredFields(); + + for (Field field : fields) { + try { + field.setAccessible(true); + field.set(target, field.get(source)); + } catch (IllegalAccessException e) { + throw new CitrusRuntimeException(format( + "Unable to reflectively copy fields from source to target. clazz=%s sourceClass=%s targetClass=%s", + clazz, source.getClass(), target.getClass())); + } + } + + currentClass = currentClass.getSuperclass(); + } + + } + } diff --git a/core/citrus-api/src/test/java/org/citrusframework/util/ReflectionHelperTest.java b/core/citrus-api/src/test/java/org/citrusframework/util/ReflectionHelperTest.java new file mode 100644 index 0000000000..b31387a0f1 --- /dev/null +++ b/core/citrus-api/src/test/java/org/citrusframework/util/ReflectionHelperTest.java @@ -0,0 +1,47 @@ +package org.citrusframework.util; + +import org.testng.Assert; +import org.testng.annotations.Test; + +public class ReflectionHelperTest { + + @Test + public void copyFields() { + SubClass source = new SubClass("John Doe", 30, "Super John", 60); + + SubClass target = new SubClass(null, 0, null, 0); + + ReflectionHelper.copyFields(SubClass.class, source, target); + + Assert.assertEquals(target.name, "John Doe"); + Assert.assertEquals(target.age, 30); + + Assert.assertEquals(target.superName, "Super John"); + Assert.assertEquals(target.superAge, 60); + + } + + private static class SuperClass { + + String superName; + int superAge; + + public SuperClass(String superName, int superAge) { + this.superName = superName; + this.superAge = superAge; + } + } + + private static class SubClass extends SuperClass { + + String name; + int age; + + public SubClass(String name, int age, String superName, int superAge) { + super(superName, superAge); + this.name = name; + this.age = age; + } + } + +} diff --git a/core/citrus-base/src/main/java/org/citrusframework/actions/ReceiveMessageAction.java b/core/citrus-base/src/main/java/org/citrusframework/actions/ReceiveMessageAction.java index ea89780675..5f064dc168 100644 --- a/core/citrus-base/src/main/java/org/citrusframework/actions/ReceiveMessageAction.java +++ b/core/citrus-base/src/main/java/org/citrusframework/actions/ReceiveMessageAction.java @@ -428,7 +428,7 @@ public MessageBuilder getMessageBuilder() { /** * Action builder. */ - public static final class Builder extends ReceiveMessageActionBuilder { + public static class Builder extends ReceiveMessageActionBuilder { /** * Fluent API action building entry method used in Java DSL. diff --git a/core/citrus-base/src/main/java/org/citrusframework/actions/SendMessageAction.java b/core/citrus-base/src/main/java/org/citrusframework/actions/SendMessageAction.java index d91ae3d002..6283ea0ee7 100644 --- a/core/citrus-base/src/main/java/org/citrusframework/actions/SendMessageAction.java +++ b/core/citrus-base/src/main/java/org/citrusframework/actions/SendMessageAction.java @@ -378,6 +378,7 @@ public static Builder send(Endpoint messageEndpoint) { public static Builder send(String messageEndpointUri) { Builder builder = new Builder(); builder.endpoint(messageEndpointUri); + return builder; } diff --git a/core/citrus-base/src/main/java/org/citrusframework/util/StringUtils.java b/core/citrus-base/src/main/java/org/citrusframework/util/StringUtils.java index 21cf207378..7b68e39ddb 100644 --- a/core/citrus-base/src/main/java/org/citrusframework/util/StringUtils.java +++ b/core/citrus-base/src/main/java/org/citrusframework/util/StringUtils.java @@ -16,6 +16,8 @@ package org.citrusframework.util; +import java.util.Locale; + /** * Utility helper class for Strings. */ @@ -34,6 +36,15 @@ public static boolean hasText(String str) { return str != null && !str.isBlank(); } + /** + * Helper method checks for null or blank String. + * @param str + * @return + */ + public static boolean hasNoText(String str) { + return !hasText(str); + } + /** * String helper checking for isEmpty String and adds null check on given parameter. */ @@ -41,6 +52,15 @@ public static boolean isEmpty(String str) { return str == null || str.isEmpty(); } + /** + * String helper checking for isEmpty String and adds null check on given parameter. + * @param str + * @return + */ + public static boolean isNotEmpty(String str) { + return !isEmpty(str); + } + public static String appendSegmentToUrlPath(String path, String segment) { if (path == null) { @@ -88,4 +108,21 @@ public static void trimTrailingComma(StringBuilder builder) { length = builder.length(); } } + + /** + * Converts the first letter of the given input string to uppercase while leaving + * the rest of the string unchanged. If the input string is empty or null, + * an empty string is returned. + * + * @param input The string to be converted to title case. It can be null or empty. + * @return the strnig in title case + */ + public static String titleCase(String input) { + if (input != null && !"".equals(input)) { + String firstLetter = input.substring(0, 1).toUpperCase(Locale.ROOT); + return input.length() == 1 ? firstLetter : firstLetter + input.substring(1); + } else { + return ""; + } + } } diff --git a/core/citrus-base/src/main/java/org/citrusframework/validation/DefaultHeaderValidator.java b/core/citrus-base/src/main/java/org/citrusframework/validation/DefaultHeaderValidator.java index 85e223f2fe..d62bce85db 100644 --- a/core/citrus-base/src/main/java/org/citrusframework/validation/DefaultHeaderValidator.java +++ b/core/citrus-base/src/main/java/org/citrusframework/validation/DefaultHeaderValidator.java @@ -16,10 +16,13 @@ package org.citrusframework.validation; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Optional; - import org.citrusframework.context.TestContext; import org.citrusframework.exceptions.ValidationException; import org.citrusframework.util.StringUtils; @@ -74,8 +77,101 @@ public void validateHeader(String headerName, Object receivedValue, Object contr } if (logger.isDebugEnabled()) { - logger.debug("Validating header element: " + headerName + "='" + expectedValue + "': OK"); + logger.debug("Validating header element: %s='%s' : OK".formatted(headerName, expectedValue)); + } + } + + public void validateHeaderArray(String headerName, Object receivedValue, Object controlValue, TestContext context, HeaderValidationContext validationContext) { + Optional validator = getHeaderValidator(headerName, controlValue, context); + if (validator.isPresent()) { + validator.get().validateHeader(headerName, receivedValue, controlValue, context, validationContext); + return; } + + List receivedValues = toList(receivedValue); + List controlValues = toList(controlValue); + + // Convert and replace dynamic content for controlValue + List expectedValues = controlValues.stream() + .map(value -> context.getTypeConverter().convertIfNecessary(value, String.class)) + .map(context::replaceDynamicContentInString) + .toList(); + + // Process received values + if (receivedValue != null) { + List receivedValueStrings = receivedValues.stream() + .map(value -> context.getTypeConverter().convertIfNecessary(value, String.class)) + .toList(); + + List expectedValuesCopy = new ArrayList<>(expectedValues); + + // Iterate over received values and try to match with expected values + for (String receivedValueString : receivedValueStrings) { + + Iterator expectedIterator = expectedValuesCopy.iterator(); + boolean validated = validateExpected(headerName, context, receivedValueString, expectedIterator); + + if (!validated) { + throw new ValidationException(String.format("Values not equal for header element '%s', expected '%s' but was '%s'", + headerName, String.join(", ", expectedValues), receivedValueString)); + } + } + + if (!expectedValuesCopy.isEmpty()) { + throw new ValidationException(String.format("Values not equal for header element '%s', expected '%s' but was '%s'", + headerName, String.join(", ", expectedValues), String.join(", ", receivedValues))); + } + + } else if (!expectedValues.isEmpty()) { + throw new ValidationException(String.format("Values not equal for header element '%s', expected '%s' but was 'null'", + headerName, String.join(", ", expectedValues))); + } + + if (logger.isDebugEnabled()) { + logger.debug("Validating header element: %s='%s' : OK".formatted(headerName, String.join(", ", expectedValues))); + } + } + + private static boolean validateExpected(String headerName, TestContext context, + String receivedValueString, Iterator expectedIterator) { + boolean validated = false; + while (expectedIterator.hasNext()) { + String expectedValue = expectedIterator.next(); + + if (ValidationMatcherUtils.isValidationMatcherExpression(expectedValue)) { + try { + ValidationMatcherUtils.resolveValidationMatcher(headerName, receivedValueString, expectedValue, + context); + validated = true; + expectedIterator.remove(); // Remove matched value + break; + } catch (ValidationException e) { + // Ignore this exception and try other expected values + } + } else { + if (receivedValueString.equals(expectedValue)) { + validated = true; + expectedIterator.remove(); // Remove matched value + break; + } + } + } + return validated; + } + + private static List toList(Object value) { + List receivedValuesList; + if (value == null) { + receivedValuesList = Collections.emptyList(); + } else if (!(value instanceof List)) { + receivedValuesList = new ArrayList<>(); + receivedValuesList.add(value.toString()); + } else { + //noinspection unchecked + receivedValuesList = (List) value; + } + + return receivedValuesList; } @Override @@ -87,11 +183,7 @@ public boolean supports(String headerName, Class type) { * Combines header validators from multiple sources. Includes validators coming from reference resolver * and resource path lookup are added. * - * Then pick validator that explicitly supports the given header name or control value and return as optional. - * @param headerName - * @param controlValue - * @param context - * @return + *

Then pick validator that explicitly supports the given header name or control value and return as optional. */ private static Optional getHeaderValidator(String headerName, Object controlValue, TestContext context) { // add validators from resource path lookup diff --git a/core/citrus-base/src/test/java/org/citrusframework/endpoint/AbstractEndpointBuilderTest.java b/core/citrus-base/src/test/java/org/citrusframework/endpoint/AbstractEndpointBuilderTest.java index 0296245da3..195083fe57 100644 --- a/core/citrus-base/src/test/java/org/citrusframework/endpoint/AbstractEndpointBuilderTest.java +++ b/core/citrus-base/src/test/java/org/citrusframework/endpoint/AbstractEndpointBuilderTest.java @@ -22,18 +22,19 @@ import org.citrusframework.annotations.CitrusEndpointProperty; import org.citrusframework.context.TestContextFactory; import org.mockito.Mockito; -import org.testng.Assert; import org.testng.annotations.Test; +import static org.testng.Assert.assertEquals; + public class AbstractEndpointBuilderTest extends UnitTestSupport { @CitrusEndpoint( - name = "fooEndpoint", - properties = { - @CitrusEndpointProperty(name = "message", value = "Hello from Citrus!"), - @CitrusEndpointProperty(name = "number", value = "1", type = int.class), - @CitrusEndpointProperty(name = "person", value = "testPerson", type = TestEndpointBuilder.Person.class) - } + name = "fooEndpoint", + properties = { + @CitrusEndpointProperty(name = "message", value = "Hello from Citrus!"), + @CitrusEndpointProperty(name = "number", value = "1", type = int.class), + @CitrusEndpointProperty(name = "person", value = "testPerson", type = TestEndpointBuilder.Person.class) + } ) private Endpoint injected; @@ -52,10 +53,10 @@ protected TestContextFactory createTestContextFactory() { public void buildFromEndpointProperties() { CitrusEndpointAnnotations.injectEndpoints(this, context); - Assert.assertEquals(injected, endpointBuilder.mockEndpoint); - Assert.assertEquals(endpointBuilder.message, "Hello from Citrus!"); - Assert.assertEquals(endpointBuilder.number, 1); - Assert.assertEquals(endpointBuilder.person, person); + assertEquals(injected, endpointBuilder.mockEndpoint); + assertEquals(endpointBuilder.message, "Hello from Citrus!"); + assertEquals(endpointBuilder.number, 1); + assertEquals(endpointBuilder.person, person); } public static final class TestEndpointBuilder extends AbstractEndpointBuilder { diff --git a/core/citrus-base/src/test/java/org/citrusframework/endpoint/direct/annotation/DirectEndpointConfigParserTest.java b/core/citrus-base/src/test/java/org/citrusframework/endpoint/direct/annotation/DirectEndpointConfigParserTest.java index eefc5fbb3b..dc309940b9 100644 --- a/core/citrus-base/src/test/java/org/citrusframework/endpoint/direct/annotation/DirectEndpointConfigParserTest.java +++ b/core/citrus-base/src/test/java/org/citrusframework/endpoint/direct/annotation/DirectEndpointConfigParserTest.java @@ -16,8 +16,6 @@ package org.citrusframework.endpoint.direct.annotation; -import java.util.Map; - import org.citrusframework.TestActor; import org.citrusframework.annotations.CitrusEndpoint; import org.citrusframework.annotations.CitrusEndpointAnnotations; @@ -35,6 +33,8 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; +import java.util.Map; + import static org.mockito.Mockito.when; public class DirectEndpointConfigParserTest { diff --git a/core/citrus-base/src/test/java/org/citrusframework/util/StringUtilsTest.java b/core/citrus-base/src/test/java/org/citrusframework/util/StringUtilsTest.java index dbed312239..4d0e99f494 100644 --- a/core/citrus-base/src/test/java/org/citrusframework/util/StringUtilsTest.java +++ b/core/citrus-base/src/test/java/org/citrusframework/util/StringUtilsTest.java @@ -2,7 +2,11 @@ import static org.citrusframework.util.StringUtils.hasText; import static org.citrusframework.util.StringUtils.isEmpty; +import static org.citrusframework.util.StringUtils.quote; +import static org.citrusframework.util.StringUtils.trimTrailingComma; +import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; import org.testng.annotations.DataProvider; @@ -53,4 +57,131 @@ public void isEmpty_returnsFalse_forText(String str) { public void isEmpty_returnsFalse_forBlankText(String str) { assertFalse(isEmpty(str)); } + + @Test + public void appendSegmentToPath() { + assertEquals(StringUtils.appendSegmentToUrlPath("s1", "s2"), "s1/s2"); + assertEquals(StringUtils.appendSegmentToUrlPath("s1/", "s2"), "s1/s2"); + assertEquals(StringUtils.appendSegmentToUrlPath("s1/", "/s2"), "s1/s2"); + assertEquals(StringUtils.appendSegmentToUrlPath("/s1", "/s2"), "/s1/s2"); + assertEquals(StringUtils.appendSegmentToUrlPath("/s1/", "/s2"), "/s1/s2"); + assertEquals(StringUtils.appendSegmentToUrlPath("/s1/", "/s2/"), "/s1/s2/"); + assertEquals(StringUtils.appendSegmentToUrlPath("/s1/", null), "/s1/"); + assertEquals(StringUtils.appendSegmentToUrlPath(null, "/s2/"), "/s2/"); + assertNull(StringUtils.appendSegmentToUrlPath(null, null)); + } + + @Test + public void testQuoteTrue() { + String input = "Hello, World!"; + String expected = "\"Hello, World!\""; + String result = quote(input, true); + + assertEquals(result, expected, "The text should be quoted."); + } + + @Test + public void testQuoteFalse() { + String input = "Hello, World!"; + String expected = "Hello, World!"; + String result = quote(input, false); + + assertEquals(result, expected, "The text should not be quoted."); + } + + @Test + public void testQuoteEmptyStringTrue() { + String input = ""; + String expected = "\"\""; + String result = quote(input, true); + + assertEquals(result, expected, "The empty text should be quoted."); + } + + @Test + public void testQuoteEmptyStringFalse() { + String input = ""; + String expected = ""; + String result = quote(input, false); + + assertEquals(result, expected, "The empty text should not be quoted."); + } + + @Test + public void testQuoteNullStringTrue() { + String input = null; + String expected = "\"null\""; + String result = quote(input, true); + + assertEquals(result, expected, "The null text should be treated as a string 'null'."); + } + + @Test + public void testQuoteNullStringFalse() { + assertNull(quote(null, false)); + } + + @DataProvider(name = "trimTrailingCommaDataProvider") + public Object[][] trimTrailingCommaDataProvider() { + return new Object[][]{ + {new StringBuilder("Example text, "), "Example text"}, + {new StringBuilder("No trailing comma "), "No trailing comma"}, + {new StringBuilder("No trailing comma,\n\t\n "), "No trailing comma"}, + {new StringBuilder("Trailing comma,"), "Trailing comma"}, + {new StringBuilder("Multiple commas and spaces,,, "), "Multiple commas and spaces,,"}, + {new StringBuilder("No trim needed"), "No trim needed"}, + {new StringBuilder(), ""} + }; + } + + @Test(dataProvider = "trimTrailingCommaDataProvider") + public void testTrimTrailingComma(StringBuilder input, String expected) { + trimTrailingComma(input); + assertEquals(input.toString(), expected); + } + + @Test + public void testTrimTrailingCommaOnlySpaces() { + StringBuilder builder = new StringBuilder(" "); + trimTrailingComma(builder); + assertEquals(builder.toString(), ""); + + builder = new StringBuilder(","); + trimTrailingComma(builder); + assertEquals(builder.toString(), ""); + + builder = new StringBuilder(", , "); + trimTrailingComma(builder); + assertEquals(builder.toString(), ", "); + } + + @Test + public void testTrimTrailingCommaWithNull() { + StringBuilder builder = new StringBuilder(); + trimTrailingComma(builder); + assertEquals(builder.toString(), ""); + } + + @DataProvider(name = "titleCaseData") + public Object[][] titleCaseData() { + return new Object[][]{ + {"hello", "Hello"}, + {"h", "H"}, + {"Hello", "Hello"}, + {null, ""}, + {"", ""}, + {"hello world", "Hello world"}, + {" hello", " hello"}, + {"1test", "1test"}, + {"!special", "!special"} + }; + } + + @Test(dataProvider = "titleCaseData") + public void testTitleCase(String input, String expected) { + String actual = StringUtils.titleCase(input); + assertEquals(actual, expected, + "The titleCase method did not return the expected result."); + } + } diff --git a/core/citrus-spring/src/main/java/org/citrusframework/config/xml/ReceiveMessageActionParser.java b/core/citrus-spring/src/main/java/org/citrusframework/config/xml/ReceiveMessageActionParser.java index 5ee0feb42b..b07b732015 100644 --- a/core/citrus-spring/src/main/java/org/citrusframework/config/xml/ReceiveMessageActionParser.java +++ b/core/citrus-spring/src/main/java/org/citrusframework/config/xml/ReceiveMessageActionParser.java @@ -30,6 +30,7 @@ import org.citrusframework.config.util.BeanDefinitionParserUtils; import org.citrusframework.config.util.ValidateMessageParserUtil; import org.citrusframework.config.util.VariableExtractorParserUtil; +import org.citrusframework.util.StringUtils; import org.citrusframework.validation.builder.DefaultMessageBuilder; import org.citrusframework.validation.context.HeaderValidationContext; import org.citrusframework.validation.context.SchemaValidationContext; @@ -62,11 +63,7 @@ public class ReceiveMessageActionParser extends AbstractMessageActionParser { @Override public BeanDefinition parse(Element element, ParserContext parserContext) { - String endpointUri = element.getAttribute("endpoint"); - - if (!hasText(endpointUri)) { - throw new BeanCreationException("Endpoint reference must not be empty"); - } + String endpointUri = parseEndpoint(element); BeanDefinitionBuilder builder = parseComponent(element, parserContext); builder.addPropertyValue("name", element.getLocalName()); @@ -101,6 +98,15 @@ public BeanDefinition parse(Element element, ParserContext parserContext) { return builder.getBeanDefinition(); } + protected String parseEndpoint(Element element) { + String endpointUri = element.getAttribute("endpoint"); + + if (!StringUtils.hasText(endpointUri)) { + throw new BeanCreationException("Endpoint reference must not be empty"); + } + return endpointUri; + } + /** * Parse message validation contexts. * @param messageElement @@ -267,7 +273,7 @@ private XmlMessageValidationContext getXmlMessageValidationContext(Element messa * @param messageElement The message element to get the configuration from * @param context The context to set the schema validation configuration to */ - private void addSchemaInformationToValidationContext(Element messageElement, SchemaValidationContext.Builder context) { + protected void addSchemaInformationToValidationContext(Element messageElement, SchemaValidationContext.Builder context) { String schemaValidation = messageElement.getAttribute("schema-validation"); if (hasText(schemaValidation)) { context.schemaValidation(parseBoolean(schemaValidation)); @@ -479,7 +485,11 @@ private void extractJsonPathValidateExpressions( * @return */ protected BeanDefinitionBuilder parseComponent(Element element, ParserContext parserContext) { - return BeanDefinitionBuilder.genericBeanDefinition(ReceiveMessageActionFactoryBean.class); + return BeanDefinitionBuilder.genericBeanDefinition(getMessageFactoryClass()); + } + + protected Class getMessageFactoryClass() { + return ReceiveMessageActionFactoryBean.class; } /** diff --git a/core/citrus-spring/src/main/java/org/citrusframework/config/xml/SendMessageActionParser.java b/core/citrus-spring/src/main/java/org/citrusframework/config/xml/SendMessageActionParser.java index ec3f5ee57f..6e05883f0f 100644 --- a/core/citrus-spring/src/main/java/org/citrusframework/config/xml/SendMessageActionParser.java +++ b/core/citrus-spring/src/main/java/org/citrusframework/config/xml/SendMessageActionParser.java @@ -23,6 +23,7 @@ import org.citrusframework.CitrusSettings; import org.citrusframework.actions.SendMessageAction; import org.citrusframework.config.util.BeanDefinitionParserUtils; +import org.citrusframework.message.MessageBuilder; import org.citrusframework.util.StringUtils; import org.citrusframework.validation.builder.DefaultMessageBuilder; import org.citrusframework.variable.VariableExtractor; @@ -41,11 +42,7 @@ public class SendMessageActionParser extends AbstractMessageActionParser { @Override public BeanDefinition parse(Element element, ParserContext parserContext) { - String endpointUri = element.getAttribute("endpoint"); - - if (!StringUtils.hasText(endpointUri)) { - throw new BeanCreationException("Endpoint reference must not be empty"); - } + String endpointUri = parseEndpoint(element); BeanDefinitionBuilder builder = parseComponent(element, parserContext); builder.addPropertyValue("name", element.getLocalName()); @@ -108,6 +105,15 @@ public BeanDefinition parse(Element element, ParserContext parserContext) { return builder.getBeanDefinition(); } + protected String parseEndpoint(Element element) { + String endpointUri = element.getAttribute("endpoint"); + + if (!StringUtils.hasText(endpointUri)) { + throw new BeanCreationException("Endpoint reference must not be empty"); + } + return endpointUri; + } + /** * Parse component returning generic bean definition. * @param element @@ -115,14 +121,13 @@ public BeanDefinition parse(Element element, ParserContext parserContext) { * @return */ protected BeanDefinitionBuilder parseComponent(Element element, ParserContext parserContext) { - return BeanDefinitionBuilder.genericBeanDefinition(getBeanDefinitionClass()); + return BeanDefinitionBuilder.genericBeanDefinition(getMessageFactoryClass()); } /** * Gets the bean definition builder class. - * @return */ - protected Class> getBeanDefinitionClass() { + protected Class> getMessageFactoryClass() { return SendMessageActionFactoryBean.class; } @@ -131,7 +136,17 @@ protected BeanDefinitionBuilder parseComponent(Element element, ParserContext pa */ public static class SendMessageActionFactoryBean extends AbstractSendMessageActionFactoryBean { - private final SendMessageAction.Builder builder = new SendMessageAction.Builder(); + private final SendMessageAction.Builder builder; + + + public SendMessageActionFactoryBean() { + builder = new SendMessageAction.Builder(); + } + + public SendMessageActionFactoryBean(MessageBuilder messageBuilder) { + builder = new SendMessageAction.Builder(); + builder.message(messageBuilder); + } @Override public SendMessageAction getObject() throws Exception { diff --git a/endpoints/citrus-http/src/main/java/org/citrusframework/http/client/HttpEndpointConfiguration.java b/endpoints/citrus-http/src/main/java/org/citrusframework/http/client/HttpEndpointConfiguration.java index 172acc9d7d..16694e9378 100644 --- a/endpoints/citrus-http/src/main/java/org/citrusframework/http/client/HttpEndpointConfiguration.java +++ b/endpoints/citrus-http/src/main/java/org/citrusframework/http/client/HttpEndpointConfiguration.java @@ -98,6 +98,10 @@ public class HttpEndpointConfiguration extends AbstractPollableEndpointConfigura /** Should handle http cookies */ private boolean handleCookies = false; + /** Should handle http semicolon uri content e.g. for matrix encoded path variables */ + // TODO: Christoph Deppisch advise whether this is a reasonable approach to support matrix encoded path parameters + private boolean handleSemicolonPathContent = false; + /** Default status code returned by http server */ private int defaultStatusCode = HttpStatus.OK.value(); @@ -396,6 +400,24 @@ public void setHandleCookies(boolean handleCookies) { this.handleCookies = handleCookies; } + /** + * Gets the handleSemicolonPathContent. + * + * @return + */ + public boolean isHandleSemicolonPathContent() { + return handleSemicolonPathContent; + } + + /** + * Sets the handleSemicolonPathContent. + * + * @param handleSemicolonPathContent + */ + public void setHandleSemicolonPathContent(boolean handleSemicolonPathContent) { + this.handleSemicolonPathContent = handleSemicolonPathContent; + } + /** * Gets the errorHandler. * diff --git a/endpoints/citrus-http/src/main/java/org/citrusframework/http/config/xml/HttpReceiveResponseActionParser.java b/endpoints/citrus-http/src/main/java/org/citrusframework/http/config/xml/HttpReceiveResponseActionParser.java index 3d8ce1b216..830d55cde2 100644 --- a/endpoints/citrus-http/src/main/java/org/citrusframework/http/config/xml/HttpReceiveResponseActionParser.java +++ b/endpoints/citrus-http/src/main/java/org/citrusframework/http/config/xml/HttpReceiveResponseActionParser.java @@ -48,6 +48,13 @@ public class HttpReceiveResponseActionParser extends ReceiveMessageActionParser @Override public BeanDefinition parse(Element element, ParserContext parserContext) { + BeanDefinitionBuilder builder = createBeanDefinitionBuilder( + element, parserContext); + return builder.getBeanDefinition(); + } + + protected BeanDefinitionBuilder createBeanDefinitionBuilder(Element element, + ParserContext parserContext) { BeanDefinitionBuilder builder = parseComponent(element, parserContext); builder.addPropertyValue("name", "http:" + element.getLocalName()); @@ -59,9 +66,7 @@ public BeanDefinition parse(Element element, ParserContext parserContext) { builder.addPropertyValue("receiveTimeout", Long.valueOf(receiveTimeout)); } - if (!element.hasAttribute("uri") && !element.hasAttribute("client")) { - throw new BeanCreationException("Neither http request uri nor http client endpoint reference is given - invalid test action definition"); - } + validateEndpointConfiguration(element); if (element.hasAttribute("client")) { builder.addPropertyReference("endpoint", element.getAttribute("client")); @@ -130,7 +135,8 @@ public BeanDefinition parse(Element element, ParserContext parserContext) { doParse(element, builder); - HttpMessageBuilder httpMessageBuilder = new HttpMessageBuilder(httpMessage); + HttpMessageBuilder httpMessageBuilder = createMessageBuilder( + httpMessage); DefaultMessageBuilder messageContentBuilder = constructMessageBuilder(body, builder); httpMessageBuilder.setName(messageContentBuilder.getName()); @@ -141,6 +147,28 @@ public BeanDefinition parse(Element element, ParserContext parserContext) { builder.addPropertyValue("validationContexts", validationContexts); builder.addPropertyValue("variableExtractors", getVariableExtractors(element)); - return builder.getBeanDefinition(); + return builder; + } + + protected HttpMessageBuilder createMessageBuilder(HttpMessage httpMessage) { + HttpMessageBuilder httpMessageBuilder = new HttpMessageBuilder(httpMessage); + return httpMessageBuilder; + } + + /** + * Validates the endpoint configuration for the given XML element. + *

+ * This method is designed to be overridden by subclasses if custom validation logic is required. + * By default, it checks whether the 'uri' or 'client' attributes are present in the element. + * If neither is found, it throws a {@link BeanCreationException} indicating an invalid test action definition. + *

+ * + * @param element the XML element representing the endpoint configuration to validate + * @throws BeanCreationException if neither 'uri' nor 'client' attributes are present + */ + protected void validateEndpointConfiguration(Element element) { + if (!element.hasAttribute("uri") && !element.hasAttribute("client")) { + throw new BeanCreationException("Neither http request uri nor http client endpoint reference is given - invalid test action definition"); + } } } diff --git a/endpoints/citrus-http/src/main/java/org/citrusframework/http/config/xml/HttpSendRequestActionParser.java b/endpoints/citrus-http/src/main/java/org/citrusframework/http/config/xml/HttpSendRequestActionParser.java index 028d3c17f9..7e20f95750 100644 --- a/endpoints/citrus-http/src/main/java/org/citrusframework/http/config/xml/HttpSendRequestActionParser.java +++ b/endpoints/citrus-http/src/main/java/org/citrusframework/http/config/xml/HttpSendRequestActionParser.java @@ -44,6 +44,13 @@ public class HttpSendRequestActionParser extends SendMessageActionParser { @Override public BeanDefinition parse(Element element, ParserContext parserContext) { + BeanDefinitionBuilder builder = createBeanDefinitionBuilder( + element, parserContext); + return builder.getBeanDefinition(); + } + + protected BeanDefinitionBuilder createBeanDefinitionBuilder(Element element, + ParserContext parserContext) { BeanDefinitionBuilder builder = parseComponent(element, parserContext); builder.addPropertyValue("name", "http:" + element.getLocalName()); @@ -53,9 +60,7 @@ public BeanDefinition parse(Element element, ParserContext parserContext) { HttpMessage httpMessage = new HttpMessage(); - if (!element.hasAttribute("uri") && !element.hasAttribute("client")) { - throw new BeanCreationException("Neither http request uri nor http client endpoint reference is given - invalid test action definition"); - } + validateEndpointConfiguration(element); if (element.hasAttribute("client")) { builder.addPropertyReference("endpoint", element.getAttribute("client")); @@ -69,7 +74,7 @@ public BeanDefinition parse(Element element, ParserContext parserContext) { } } - Element requestElement = DomUtils.getChildElements(element).get(0); + Element requestElement = getRequestElement(element); httpMessage.method(HttpMethod.valueOf(requestElement.getLocalName().toUpperCase())); if (requestElement.hasAttribute("path")) { httpMessage.path(requestElement.getAttribute("path")); @@ -81,7 +86,7 @@ public BeanDefinition parse(Element element, ParserContext parserContext) { httpMessage.queryParam(param.getAttribute("name"), param.getAttribute("value")); } - Element headers = DomUtils.getChildElementByTagName(requestElement, "headers"); + Element headers = getHeadersElement(requestElement); if (headers != null) { List headerElements = DomUtils.getChildElementsByTagName(headers, "header"); for (Object headerElement : headerElements) { @@ -141,7 +146,8 @@ public BeanDefinition parse(Element element, ParserContext parserContext) { } } - HttpMessageBuilder httpMessageBuilder = new HttpMessageBuilder(httpMessage); + HttpMessageBuilder httpMessageBuilder = createMessageBuilder( + httpMessage); DefaultMessageBuilder messageContentBuilder = constructMessageBuilder(body, builder); httpMessageBuilder.setName(messageContentBuilder.getName()); @@ -156,7 +162,42 @@ public BeanDefinition parse(Element element, ParserContext parserContext) { if (!variableExtractors.isEmpty()) { builder.addPropertyValue("variableExtractors", variableExtractors); } + return builder; + } - return builder.getBeanDefinition(); + protected Element getRequestElement(Element element) { + if (element.hasChildNodes()) { + return DomUtils.getChildElements(element).get(0); + } + throw new BeanCreationException("No request element specified for http send - invalid test action definition"); + } + + protected Element getHeadersElement(Element requestElement) { + Element headers = DomUtils.getChildElementByTagName(requestElement, "headers"); + return headers; + } + + /** + * This method is designed to be overridden by subclasses if a custom message builder is required. + */ + protected HttpMessageBuilder createMessageBuilder(HttpMessage httpMessage) { + return new HttpMessageBuilder(httpMessage); + } + + /** + * Validates the endpoint configuration for the given XML element. + *

+ * This method is designed to be overridden by subclasses if custom validation logic is required. + * By default, it checks whether the 'uri' or 'client' attributes are present in the element. + * If neither is found, it throws a {@link BeanCreationException} indicating an invalid test action definition. + *

+ * + * @param element the XML element representing the endpoint configuration to validate + * @throws BeanCreationException if neither 'uri' nor 'client' attributes are present + */ + protected void validateEndpointConfiguration(Element element) { + if (!element.hasAttribute("uri") && !element.hasAttribute("client")) { + throw new BeanCreationException("Neither http request uri nor http client endpoint reference is given - invalid test action definition"); + } } } diff --git a/endpoints/citrus-http/src/main/java/org/citrusframework/http/controller/HttpMessageController.java b/endpoints/citrus-http/src/main/java/org/citrusframework/http/controller/HttpMessageController.java index 9e3bb54f1d..aa62ab4f47 100644 --- a/endpoints/citrus-http/src/main/java/org/citrusframework/http/controller/HttpMessageController.java +++ b/endpoints/citrus-http/src/main/java/org/citrusframework/http/controller/HttpMessageController.java @@ -130,6 +130,7 @@ private ResponseEntity handleRequestInternal(HttpMethod method, HttpEntity HttpServletRequest servletRequest = ((ServletRequestAttributes) attributes).getRequest(); UrlPathHelper pathHelper = new UrlPathHelper(); + pathHelper.setRemoveSemicolonContent(!endpointConfiguration.isHandleSemicolonPathContent()); Enumeration allHeaders = servletRequest.getHeaderNames(); for (String headerName : CollectionUtils.toArray(allHeaders, new String[] {})) { diff --git a/endpoints/citrus-http/src/main/java/org/citrusframework/http/message/HttpQueryParamHeaderValidator.java b/endpoints/citrus-http/src/main/java/org/citrusframework/http/message/HttpQueryParamHeaderValidator.java index 2988291f2c..8b1545e5d5 100644 --- a/endpoints/citrus-http/src/main/java/org/citrusframework/http/message/HttpQueryParamHeaderValidator.java +++ b/endpoints/citrus-http/src/main/java/org/citrusframework/http/message/HttpQueryParamHeaderValidator.java @@ -16,11 +16,12 @@ package org.citrusframework.http.message; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; - import org.citrusframework.context.TestContext; import org.citrusframework.exceptions.ValidationException; import org.citrusframework.util.StringUtils; @@ -42,41 +43,57 @@ public void validateHeader(String name, Object received, Object control, TestCon return; } - Map receiveParams = convertToMap(received); - Map controlParams = convertToMap(control); + // TODO Christoph Deppisch: I changed this to support multi lists, e.q. required for array query parameters. + // Not sure about consequences though. Therefore, i call a new method super.validateHeaderArray below. + // Maybe we should fix this in general. + Map receiveParams = convertToMap(received); + Map controlParams = convertToMap(control); - for (Map.Entry param : controlParams.entrySet()) { + for (Map.Entry param : controlParams.entrySet()) { if (!receiveParams.containsKey(param.getKey())) { throw new ValidationException("Validation failed: Query param '" + param.getKey() + "' is missing"); } - super.validateHeader(HttpMessageHeaders.HTTP_QUERY_PARAMS + "(" + param.getKey() + ")", receiveParams.get(param.getKey()), param.getValue(), context, validationContext); + super.validateHeaderArray(HttpMessageHeaders.HTTP_QUERY_PARAMS + "(" + param.getKey() + ")", receiveParams.get(param.getKey()), param.getValue(), context, validationContext); } + } /** - * Convert query string key-value expression to map. - * @param expression - * @return + * Convert query string key-value expression to map. Note, that there could be hamcrest matchers + * encoded in the expression. */ - private Map convertToMap(Object expression) { - if (expression instanceof Map) { - return (Map) expression; + private Map convertToMap(Object expression) { + + if (expression instanceof Map) { + return (Map) expression; } return Stream.of(Optional.ofNullable(expression) .map(Object::toString) .orElse("") .split(",")) - .map(keyValue -> keyValue.split("=")) - .filter(keyValue -> StringUtils.hasText(keyValue[0])) - .map(keyValue -> { - if (keyValue.length < 2) { - return new String[]{keyValue[0], ""}; + .map(keyValue -> keyValue.split("=")) + .filter(keyValue -> StringUtils.hasText(keyValue[0])) + .collect(Collectors.toMap( + keyValue -> keyValue[0], // Key function + keyValue -> + // Value function: if no value is present, use an empty string + (keyValue.length < 2 ? "" : keyValue[1]) + , + (existingValue, newValue) -> { // Merge function to handle duplicate keys + if (existingValue instanceof List) { + ((List) existingValue).add(newValue.toString()); + return existingValue; + } else { + List list = new ArrayList<>(); + list.add((String) existingValue); + list.add(newValue.toString()); + return list; } - return keyValue; - }) - .collect(Collectors.toMap(keyValue -> keyValue[0], keyValue -> keyValue[1])); + } + )); + } @Override diff --git a/endpoints/citrus-http/src/main/java/org/citrusframework/http/server/AbstractHttpServerBuilder.java b/endpoints/citrus-http/src/main/java/org/citrusframework/http/server/AbstractHttpServerBuilder.java index 2333db5517..0592b890e9 100644 --- a/endpoints/citrus-http/src/main/java/org/citrusframework/http/server/AbstractHttpServerBuilder.java +++ b/endpoints/citrus-http/src/main/java/org/citrusframework/http/server/AbstractHttpServerBuilder.java @@ -250,6 +250,17 @@ public B handleCookies(boolean flag) { return self; } + /** + * Sets the handleCookies property. + * + * @param flag + * @return + */ + public B handleHandleSemicolonPathContent(boolean flag) { + endpoint.setHandleSemicolonPathContent(flag); + return self; + } + /** * Sets the default status code property. * diff --git a/endpoints/citrus-http/src/main/java/org/citrusframework/http/server/HttpServer.java b/endpoints/citrus-http/src/main/java/org/citrusframework/http/server/HttpServer.java index dc71774c66..7f8edfdb4c 100644 --- a/endpoints/citrus-http/src/main/java/org/citrusframework/http/server/HttpServer.java +++ b/endpoints/citrus-http/src/main/java/org/citrusframework/http/server/HttpServer.java @@ -149,6 +149,11 @@ public class HttpServer extends AbstractServer { */ private boolean handleCookies = false; + /** + * Should handle matrix encoded path parameters + */ + private boolean handleSemicolonPathContent = false; + /** * Default status code returned by http server */ @@ -645,6 +650,25 @@ public void setHandleCookies(boolean handleCookies) { this.handleCookies = handleCookies; } + /** + * Gets the handleSemicolonPathContent. + * + * @return + */ + public boolean isHandleSemicolonPathContent() { + return handleSemicolonPathContent; + } + + /** + * Sets the handleSemicolonPathContent. + * + * @param handleSemicolonPathContent + */ + public void setHandleSemicolonPathContent(boolean handleSemicolonPathContent) { + this.handleSemicolonPathContent = handleSemicolonPathContent; + } + + /** * Gets the response cache size. * diff --git a/endpoints/citrus-http/src/main/java/org/citrusframework/http/servlet/CitrusDispatcherServlet.java b/endpoints/citrus-http/src/main/java/org/citrusframework/http/servlet/CitrusDispatcherServlet.java index 2631ca1db3..e2dd9c6b8e 100644 --- a/endpoints/citrus-http/src/main/java/org/citrusframework/http/servlet/CitrusDispatcherServlet.java +++ b/endpoints/citrus-http/src/main/java/org/citrusframework/http/servlet/CitrusDispatcherServlet.java @@ -111,6 +111,7 @@ protected void configureMessageController(ApplicationContext context) { endpointConfiguration.setHeaderMapper(DefaultHttpHeaderMapper.inboundMapper()); endpointConfiguration.setHandleAttributeHeaders(httpServer.isHandleAttributeHeaders()); endpointConfiguration.setHandleCookies(httpServer.isHandleCookies()); + endpointConfiguration.setHandleSemicolonPathContent(httpServer.isHandleSemicolonPathContent()); endpointConfiguration.setDefaultStatusCode(httpServer.getDefaultStatusCode()); messageController.setEndpointConfiguration(endpointConfiguration); diff --git a/endpoints/citrus-http/src/main/resources/org/citrusframework/schema/citrus-http-testcase.xsd b/endpoints/citrus-http/src/main/resources/org/citrusframework/schema/citrus-http-testcase.xsd index c42b48b394..68825b37b1 100644 --- a/endpoints/citrus-http/src/main/resources/org/citrusframework/schema/citrus-http-testcase.xsd +++ b/endpoints/citrus-http/src/main/resources/org/citrusframework/schema/citrus-http-testcase.xsd @@ -22,179 +22,116 @@ - + Sends Http request as client to server. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Received Http response as client from server. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + @@ -206,131 +143,198 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + Receives Http request as server. - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sends Http response as server to calling client. + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + - - + + + - + + - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - Sends Http response as server to calling client. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/endpoints/citrus-http/src/test/java/org/citrusframework/http/message/HttpQueryParamHeaderValidatorTest.java b/endpoints/citrus-http/src/test/java/org/citrusframework/http/message/HttpQueryParamHeaderValidatorTest.java index ab37efc1c5..71dd7d6907 100644 --- a/endpoints/citrus-http/src/test/java/org/citrusframework/http/message/HttpQueryParamHeaderValidatorTest.java +++ b/endpoints/citrus-http/src/test/java/org/citrusframework/http/message/HttpQueryParamHeaderValidatorTest.java @@ -32,13 +32,8 @@ */ public class HttpQueryParamHeaderValidatorTest extends AbstractTestNGUnitTest { - private HttpQueryParamHeaderValidator validator = new HttpQueryParamHeaderValidator(); - private HeaderValidationContext validationContext = new HeaderValidationContext(); - - @Override - protected TestContextFactory createTestContextFactory() { - return TestContextFactory.newInstance(); - } + private final HttpQueryParamHeaderValidator validator = new HttpQueryParamHeaderValidator(); + private final HeaderValidationContext validationContext = new HeaderValidationContext(); @Test(dataProvider = "successData") public void testValidateHeader(Object receivedValue, Object controlValue) { @@ -51,6 +46,8 @@ public Object[][] successData() { new Object[] { "foobar", "@contains(foo)@" }, new Object[] { "foo=fooValue,bar=barValue", "foo=fooValue,bar=barValue" }, new Object[] { "foo=,bar=barValue", "foo=,bar=barValue" }, + new Object[] { "foo=1,foo=2,foo=3,bar=barValue", "foo=1,foo=2,foo=3,bar=barValue" }, + new Object[] { "foo=1,foo=2,foo=3,bar=barValue", "foo=3,foo=2,foo=1,bar=barValue" }, new Object[] { null, null }, new Object[] { Collections.singletonMap("key", "value"), Collections.singletonMap("key", "value") }, new Object[] { Collections.singletonMap("key", "value"), Collections.singletonMap("key", is("value")) } diff --git a/endpoints/citrus-jms/src/test/java/org/citrusframework/jms/integration/SyncJmsTopicCommunicationIT.java b/endpoints/citrus-jms/src/test/java/org/citrusframework/jms/integration/SyncJmsTopicCommunicationIT.java index ed19e85aec..f1ae835e1c 100644 --- a/endpoints/citrus-jms/src/test/java/org/citrusframework/jms/integration/SyncJmsTopicCommunicationIT.java +++ b/endpoints/citrus-jms/src/test/java/org/citrusframework/jms/integration/SyncJmsTopicCommunicationIT.java @@ -18,6 +18,7 @@ import org.citrusframework.annotations.CitrusTestSource; import org.citrusframework.testng.spring.TestNGCitrusSpringSupport; +import org.testng.annotations.Ignore; import org.testng.annotations.Test; import static org.citrusframework.common.TestLoader.SPRING; diff --git a/endpoints/citrus-rmi/src/test/java/org/citrusframework/rmi/integration/RmiDynamicEndpointIT.java b/endpoints/citrus-rmi/src/test/java/org/citrusframework/rmi/integration/RmiDynamicEndpointIT.java index 8e55806ada..cac94f67a8 100644 --- a/endpoints/citrus-rmi/src/test/java/org/citrusframework/rmi/integration/RmiDynamicEndpointIT.java +++ b/endpoints/citrus-rmi/src/test/java/org/citrusframework/rmi/integration/RmiDynamicEndpointIT.java @@ -19,12 +19,12 @@ import org.citrusframework.annotations.CitrusTestSource; import org.citrusframework.common.TestLoader; import org.citrusframework.testng.spring.TestNGCitrusSpringSupport; +import org.testng.annotations.Ignore; import org.testng.annotations.Test; /** * @since 2.0 */ -@Test public class RmiDynamicEndpointIT extends TestNGCitrusSpringSupport { @CitrusTestSource(type = TestLoader.SPRING, name = "RmiDynamicEndpointIT") diff --git a/endpoints/citrus-rmi/src/test/java/org/citrusframework/rmi/integration/RmiEndpointIT.java b/endpoints/citrus-rmi/src/test/java/org/citrusframework/rmi/integration/RmiEndpointIT.java index 9175809993..a7ae49082a 100644 --- a/endpoints/citrus-rmi/src/test/java/org/citrusframework/rmi/integration/RmiEndpointIT.java +++ b/endpoints/citrus-rmi/src/test/java/org/citrusframework/rmi/integration/RmiEndpointIT.java @@ -19,6 +19,7 @@ import org.citrusframework.annotations.CitrusTestSource; import org.citrusframework.common.TestLoader; import org.citrusframework.testng.spring.TestNGCitrusSpringSupport; +import org.testng.annotations.Ignore; import org.testng.annotations.Test; /** diff --git a/endpoints/citrus-rmi/src/test/java/org/citrusframework/rmi/integration/RmiEndpointJavaIT.java b/endpoints/citrus-rmi/src/test/java/org/citrusframework/rmi/integration/RmiEndpointJavaIT.java index e4de083396..52b3e88b98 100644 --- a/endpoints/citrus-rmi/src/test/java/org/citrusframework/rmi/integration/RmiEndpointJavaIT.java +++ b/endpoints/citrus-rmi/src/test/java/org/citrusframework/rmi/integration/RmiEndpointJavaIT.java @@ -25,6 +25,7 @@ import org.citrusframework.testng.spring.TestNGCitrusSpringSupport; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import org.testng.annotations.Ignore; import org.testng.annotations.Test; import static org.citrusframework.actions.ReceiveMessageAction.Builder.receive; diff --git a/endpoints/citrus-rmi/src/test/java/org/citrusframework/rmi/server/RmiServerTest.java b/endpoints/citrus-rmi/src/test/java/org/citrusframework/rmi/server/RmiServerTest.java index 324f897192..b673bada04 100644 --- a/endpoints/citrus-rmi/src/test/java/org/citrusframework/rmi/server/RmiServerTest.java +++ b/endpoints/citrus-rmi/src/test/java/org/citrusframework/rmi/server/RmiServerTest.java @@ -16,11 +16,15 @@ package org.citrusframework.rmi.server; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.reset; + import java.io.IOException; import java.rmi.Remote; import java.rmi.registry.Registry; import java.util.List; - import org.citrusframework.endpoint.EndpointAdapter; import org.citrusframework.message.DefaultMessage; import org.citrusframework.message.Message; @@ -37,11 +41,6 @@ import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.reset; - /** * @since 2.5 */ diff --git a/endpoints/citrus-ws/src/main/java/org/citrusframework/ws/actions/ReceiveSoapMessageAction.java b/endpoints/citrus-ws/src/main/java/org/citrusframework/ws/actions/ReceiveSoapMessageAction.java index 4957debb01..679f300879 100644 --- a/endpoints/citrus-ws/src/main/java/org/citrusframework/ws/actions/ReceiveSoapMessageAction.java +++ b/endpoints/citrus-ws/src/main/java/org/citrusframework/ws/actions/ReceiveSoapMessageAction.java @@ -98,7 +98,7 @@ public SoapAttachmentValidator getAttachmentValidator() { /** * Action builder. */ - public static final class Builder extends ReceiveMessageActionBuilder { + public static class Builder extends ReceiveMessageActionBuilder { /** Soap message to receive */ private final SoapMessage soapMessage = new SoapMessage(); diff --git a/endpoints/citrus-ws/src/main/java/org/citrusframework/ws/actions/SendSoapMessageAction.java b/endpoints/citrus-ws/src/main/java/org/citrusframework/ws/actions/SendSoapMessageAction.java index 9f4a591ac2..2216336fb1 100644 --- a/endpoints/citrus-ws/src/main/java/org/citrusframework/ws/actions/SendSoapMessageAction.java +++ b/endpoints/citrus-ws/src/main/java/org/citrusframework/ws/actions/SendSoapMessageAction.java @@ -139,7 +139,7 @@ public boolean isMtomEnabled() { /** * Action builder. */ - public static final class Builder extends SendSoapMessageBuilder { + public static class Builder extends SendSoapMessageBuilder { public Builder() { message(new StaticMessageBuilder(soapMessage)); diff --git a/endpoints/citrus-ws/src/main/java/org/citrusframework/ws/config/xml/ReceiveSoapMessageActionParser.java b/endpoints/citrus-ws/src/main/java/org/citrusframework/ws/config/xml/ReceiveSoapMessageActionParser.java index 446afe7518..f959ca124c 100644 --- a/endpoints/citrus-ws/src/main/java/org/citrusframework/ws/config/xml/ReceiveSoapMessageActionParser.java +++ b/endpoints/citrus-ws/src/main/java/org/citrusframework/ws/config/xml/ReceiveSoapMessageActionParser.java @@ -28,6 +28,7 @@ import org.citrusframework.validation.builder.DefaultMessageBuilder; import org.citrusframework.validation.context.ValidationContext; import org.citrusframework.ws.actions.ReceiveSoapMessageAction; +import org.citrusframework.ws.actions.ReceiveSoapMessageAction.Builder; import org.citrusframework.ws.message.SoapAttachment; import org.citrusframework.ws.message.SoapMessageHeaders; import org.citrusframework.ws.validation.SoapAttachmentValidator; @@ -44,7 +45,7 @@ public class ReceiveSoapMessageActionParser extends ReceiveMessageActionParser { @Override protected BeanDefinitionBuilder parseComponent(Element element, ParserContext parserContext) { - BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ReceiveSoapMessageActionFactoryBean.class); + BeanDefinitionBuilder builder = super.parseComponent(element, parserContext); List attachmentElements = DomUtils.getChildElementsByTagName(element, "attachment"); List attachments = new ArrayList<>(); @@ -62,6 +63,11 @@ protected BeanDefinitionBuilder parseComponent(Element element, ParserContext pa return builder; } + @Override + protected Class getMessageFactoryClass() { + return ReceiveSoapMessageActionFactoryBean.class; + } + @Override protected void parseHeaderElements(Element actionElement, DefaultMessageBuilder messageBuilder, List validationContexts) { super.parseHeaderElements(actionElement, messageBuilder, validationContexts); @@ -89,7 +95,15 @@ protected void parseHeaderElements(Element actionElement, DefaultMessageBuilder */ public static class ReceiveSoapMessageActionFactoryBean extends AbstractReceiveMessageActionFactoryBean { - private final ReceiveSoapMessageAction.Builder builder = new ReceiveSoapMessageAction.Builder(); + private final Builder builder; + + public ReceiveSoapMessageActionFactoryBean() { + this(new Builder()); + } + + public ReceiveSoapMessageActionFactoryBean(Builder builder) { + this.builder = builder; + } /** * Sets the control attachments. diff --git a/endpoints/citrus-ws/src/main/java/org/citrusframework/ws/config/xml/SendSoapFaultActionParser.java b/endpoints/citrus-ws/src/main/java/org/citrusframework/ws/config/xml/SendSoapFaultActionParser.java index 877469e157..11e811362d 100644 --- a/endpoints/citrus-ws/src/main/java/org/citrusframework/ws/config/xml/SendSoapFaultActionParser.java +++ b/endpoints/citrus-ws/src/main/java/org/citrusframework/ws/config/xml/SendSoapFaultActionParser.java @@ -108,7 +108,7 @@ private void parseFaultDetail(BeanDefinitionBuilder builder, Element faultElemen } @Override - protected Class getBeanDefinitionClass() { + protected Class getMessageFactoryClass() { return SendSoapFaultActionFactoryBean.class; } diff --git a/endpoints/citrus-ws/src/main/java/org/citrusframework/ws/config/xml/SendSoapMessageActionParser.java b/endpoints/citrus-ws/src/main/java/org/citrusframework/ws/config/xml/SendSoapMessageActionParser.java index 1bb724f17f..c918b1b546 100644 --- a/endpoints/citrus-ws/src/main/java/org/citrusframework/ws/config/xml/SendSoapMessageActionParser.java +++ b/endpoints/citrus-ws/src/main/java/org/citrusframework/ws/config/xml/SendSoapMessageActionParser.java @@ -27,6 +27,7 @@ import org.citrusframework.validation.builder.DefaultMessageBuilder; import org.citrusframework.validation.context.ValidationContext; import org.citrusframework.ws.actions.SendSoapMessageAction; +import org.citrusframework.ws.actions.SendSoapMessageAction.Builder; import org.citrusframework.ws.message.SoapAttachment; import org.citrusframework.ws.message.SoapMessageHeaders; import org.springframework.beans.factory.support.BeanDefinitionBuilder; @@ -82,7 +83,7 @@ protected void parseHeaderElements(Element actionElement, DefaultMessageBuilder } @Override - protected Class> getBeanDefinitionClass() { + protected Class> getMessageFactoryClass() { return SendSoapMessageActionFactoryBean.class; } @@ -91,7 +92,15 @@ protected void parseHeaderElements(Element actionElement, DefaultMessageBuilder */ public static class SendSoapMessageActionFactoryBean extends AbstractSendMessageActionFactoryBean { - private final SendSoapMessageAction.Builder builder = new SendSoapMessageAction.Builder(); + private final SendSoapMessageAction.Builder builder; + + public SendSoapMessageActionFactoryBean() { + this(new Builder()); + } + + public SendSoapMessageActionFactoryBean(SendSoapMessageAction.Builder builder) { + this.builder = builder; + } /** * Sets the control attachments. diff --git a/pom.xml b/pom.xml index 0d4820b6d3..73ed745e67 100644 --- a/pom.xml +++ b/pom.xml @@ -173,7 +173,7 @@ 3.4.0 3.1.1 3.3.0 - 3.5.0 + 3.10.0 1.6.13 3.9.0 3.13.1 @@ -260,6 +260,7 @@ 1.1.10.7 2.3 6.1.14 + 3.3.1 4.0.11 6.3.4 3.0.1 diff --git a/test-api-generator/citrus-test-api-core/pom.xml b/test-api-generator/citrus-test-api-core/pom.xml new file mode 100644 index 0000000000..d0a8b248de --- /dev/null +++ b/test-api-generator/citrus-test-api-core/pom.xml @@ -0,0 +1,81 @@ + + + 4.0.0 + + + citrus-test-api-generator + org.citrusframework + 4.4.0-SNAPSHOT + ../pom.xml + + + citrus-test-api-core + Citrus :: Test API Core + Citrus Test API Core + jar + + + + org.citrusframework + citrus-api + ${project.version} + + + org.citrusframework + citrus-http + ${project.version} + + + org.citrusframework + citrus-openapi + ${project.version} + + + org.citrusframework + citrus-ws + ${project.version} + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + + + org.openapitools + openapi-generator + ${org.openapitools.version} + + + wsdl4j + wsdl4j + + + + + org.assertj + assertj-core + ${assertj.version} + test + + + org.citrusframework + citrus-junit5 + ${project.version} + test + + + org.citrusframework + citrus-validation-json + ${project.version} + test + + + commons-fileupload + commons-fileupload + 1.5 + test + + + + \ No newline at end of file diff --git a/core/citrus-base/src/main/java/org/citrusframework/testapi/ApiActionBuilderCustomizerService.java b/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/ApiActionBuilderCustomizer.java similarity index 65% rename from core/citrus-base/src/main/java/org/citrusframework/testapi/ApiActionBuilderCustomizerService.java rename to test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/ApiActionBuilderCustomizer.java index 3231b622af..5ba5731245 100644 --- a/core/citrus-base/src/main/java/org/citrusframework/testapi/ApiActionBuilderCustomizerService.java +++ b/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/ApiActionBuilderCustomizer.java @@ -14,16 +14,21 @@ * limitations under the License. */ -package org.citrusframework.testapi; +package org.citrusframework.openapi.testapi; -import org.citrusframework.TestAction; +import org.citrusframework.actions.ReceiveMessageAction.ReceiveMessageActionBuilder; import org.citrusframework.actions.SendMessageAction.SendMessageActionBuilder; -import org.citrusframework.context.TestContext; /** * Implementors of this interface are used to customize the SendMessageActionBuilder with application specific information. E.g. cookies * or transactionIds. */ -public interface ApiActionBuilderCustomizerService { - > T build(GeneratedApi generatedApi, TestAction action, TestContext context, T builder); +public interface ApiActionBuilderCustomizer { + + default > void customizeRequestBuilder(GeneratedApi generatedApi, T builder) { + } + + default > void customizeResponseBuilder(GeneratedApi generatedApi, T builder) { + } + } diff --git a/core/citrus-api/src/main/java/org/citrusframework/testapi/GeneratedApi.java b/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/GeneratedApi.java similarity index 88% rename from core/citrus-api/src/main/java/org/citrusframework/testapi/GeneratedApi.java rename to test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/GeneratedApi.java index a37867188c..07c7bad723 100644 --- a/core/citrus-api/src/main/java/org/citrusframework/testapi/GeneratedApi.java +++ b/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/GeneratedApi.java @@ -14,10 +14,13 @@ * limitations under the License. */ -package org.citrusframework.testapi; +package org.citrusframework.openapi.testapi; +import java.util.List; import java.util.Map; +import org.citrusframework.endpoint.Endpoint; + /** * Interface representing a generated API from an OpenAPI specification. * Provides methods to retrieve metadata about the API such as title, version, @@ -58,4 +61,12 @@ public interface GeneratedApi { * where keys are extension names and values are extension values */ Map getApiInfoExtensions(); + + List getCustomizers(); + + /** + * Returns the endpoint of the generated api. + */ + Endpoint getEndpoint(); + } \ No newline at end of file diff --git a/core/citrus-api/src/main/java/org/citrusframework/testapi/GeneratedApiRequest.java b/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/GeneratedApiRequest.java similarity index 96% rename from core/citrus-api/src/main/java/org/citrusframework/testapi/GeneratedApiRequest.java rename to test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/GeneratedApiRequest.java index 1b86cc29b0..80409c72c9 100644 --- a/core/citrus-api/src/main/java/org/citrusframework/testapi/GeneratedApiRequest.java +++ b/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/GeneratedApiRequest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.citrusframework.testapi; +package org.citrusframework.openapi.testapi; /** * Interface representing a generated API request corresponding to an operation in an OpenAPI specification. diff --git a/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/OpenApiParameterFormatter.java b/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/OpenApiParameterFormatter.java new file mode 100644 index 0000000000..ea7bbe63cd --- /dev/null +++ b/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/OpenApiParameterFormatter.java @@ -0,0 +1,226 @@ +/* + * Copyright the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.citrusframework.openapi.testapi; + +import static java.util.Collections.emptyList; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Array; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; +import org.citrusframework.exceptions.CitrusRuntimeException; + +class OpenApiParameterFormatter { + + private static final ObjectMapper objectMapper = new ObjectMapper(); + + private static final FormatParameters DEFAULT_FORMAT_PARAMETERS = new FormatParameters("", ","); + private static final FormatParameters DEFAULT_LABEL_FORMAT_PARAMETERS = new FormatParameters(".", ","); + private static final FormatParameters DEFAULT_LABEL_EXPLODED_PARAMETERS = new FormatParameters(".", "."); + + private OpenApiParameterFormatter() { + // Static access only. + } + + /** + * Formats a list of values as a single String based on the separator and other settings. + */ + static String formatArray(String parameterName, Object parameterValue , ParameterStyle parameterStyle, + boolean explode, boolean isObject) { + + List values = toList(parameterValue, isObject); + if (parameterStyle == ParameterStyle.DEEPOBJECT) { + return formatDeepObject(parameterName, values); + } + + FormatParameters formatParameters = determineFormatParameters(parameterName, parameterStyle, explode, + isObject); + + + if (isObject && explode) { + return formatParameters.prefix + explode(values, formatParameters.separator); + } else { + return formatParameters.prefix + values.stream() + .collect(Collectors.joining(formatParameters.separator)); + } + + } + + private static String formatDeepObject(String parameterName, List values) { + StringBuilder builder = new StringBuilder(); + for (int i=0;i matrixFormatParameters(parameterName, explode, isObject); + case LABEL -> labelFormatParameters(explode); + case FORM -> formFormatParameters(parameterName, explode, isObject); + case SIMPLE, DEEPOBJECT -> DEFAULT_FORMAT_PARAMETERS; + }; + } + + private static FormatParameters formFormatParameters(String parameterName, boolean explode, boolean isObject) { + if (explode) { + if (isObject) { + return new FormatParameters("", "&"); + } + return new FormatParameters(parameterName+"=", "&"+parameterName+"="); + } else { + return new FormatParameters(parameterName+"=", ","); + } + } + + private static FormatParameters labelFormatParameters(boolean explode) { + return explode ? DEFAULT_LABEL_EXPLODED_PARAMETERS : DEFAULT_LABEL_FORMAT_PARAMETERS; + } + + private static FormatParameters matrixFormatParameters(String parameterName, boolean explode, boolean isObject) { + String prefix; + String separator = ","; + if (explode) { + if (isObject) { + prefix = ";"; + separator = prefix; + } else { + prefix = ";" + parameterName + "="; + separator = prefix; + } + } else { + prefix = ";" + parameterName + "="; + } + + return new FormatParameters(prefix, separator); + } + + private static String explode(List values, String delimiter) { + return IntStream.range(0, values.size() / 2) + .mapToObj(i -> values.get(2 * i) + "=" + values.get(2 * i + 1)) + .collect(Collectors.joining(delimiter)); + } + + private static List toList(Object value, boolean isObject) { + + if (value == null) { + return emptyList(); + } + + if (value.getClass().isArray()) { + List list = new ArrayList<>(); + int length = Array.getLength(value); + for (int i = 0; i < length; i++) { + Object singleValue = Array.get(value, i); + list.add(singleValue.toString()); + } + return list; + } else if (value instanceof List list) { + return list.stream().map(Object::toString).toList(); + } else if (value instanceof Map map) { + return map.entrySet().stream() + .flatMap(entry -> Stream.of(entry.getKey().toString(), entry.getValue().toString())) + .toList(); + } else if (isObject && value instanceof String jsonString) { + return toList(convertJsonToMap(jsonString), true); + } else if (isObject) { + return toList(convertBeanToMap(value), true); + } else { + return List.of(value.toString()); + } + } + + public static Map convertJsonToMap(String jsonString) { + JsonNode rootNode; + try { + rootNode = objectMapper.readTree(jsonString); + } catch (JsonProcessingException e) { + throw new IllegalArgumentException("Unable to convert jsonString to JSON object.", e); + } + + if (!rootNode.isObject()) { + throw new IllegalArgumentException("The provided JSON is not a valid JSON object."); + } + + return convertNodeToMap((ObjectNode) rootNode); + } + + private static Map convertNodeToMap(ObjectNode objectNode) { + Map resultMap = new TreeMap<>(); + + Iterator> fields = objectNode.fields(); + while (fields.hasNext()) { + Map.Entry field = fields.next(); + JsonNode valueNode = field.getValue(); + + if (valueNode.isObject() || valueNode.isArray()) { + throw new IllegalArgumentException( + "Nested objects or arrays are not allowed in the JSON."); + } + resultMap.put(field.getKey(), valueNode.asText()); + } + + return resultMap; + } + + protected static Map convertBeanToMap(Object bean) { + Map map = new TreeMap<>(); + try { + for (PropertyDescriptor propertyDescriptor : Introspector.getBeanInfo( + bean.getClass(), Object.class).getPropertyDescriptors()) { + String propertyName = propertyDescriptor.getName(); + Object propertyValue = propertyDescriptor.getReadMethod().invoke(bean); + if (propertyValue != null) { + map.put(propertyName, propertyValue); + } + } + } catch (IntrospectionException | IllegalAccessException | + InvocationTargetException e) { + throw new CitrusRuntimeException("Error converting bean to map: " + e.getMessage(), e); + } + return map; + } + + private record FormatParameters(String prefix, String separator) { + } + +} diff --git a/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/ParameterStyle.java b/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/ParameterStyle.java new file mode 100644 index 0000000000..c5dc997d73 --- /dev/null +++ b/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/ParameterStyle.java @@ -0,0 +1,25 @@ +/* + * Copyright the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.citrusframework.openapi.testapi; + +public enum ParameterStyle { + SIMPLE, + LABEL, + MATRIX, + FORM, + DEEPOBJECT +} diff --git a/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/RestApiReceiveMessageActionBuilder.java b/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/RestApiReceiveMessageActionBuilder.java new file mode 100644 index 0000000000..a87cdb3525 --- /dev/null +++ b/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/RestApiReceiveMessageActionBuilder.java @@ -0,0 +1,72 @@ +/* + * Copyright the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.citrusframework.openapi.testapi; + +import java.util.List; +import org.citrusframework.http.message.HttpMessage; +import org.citrusframework.openapi.OpenApiSpecification; +import org.citrusframework.openapi.actions.OpenApiSpecificationSource; +import org.citrusframework.openapi.util.OpenApiUtils; + +public class RestApiReceiveMessageActionBuilder extends + org.citrusframework.openapi.actions.OpenApiClientResponseActionBuilder { + + private final GeneratedApi generatedApi; + + private final List customizers; + + + public RestApiReceiveMessageActionBuilder(GeneratedApi generatedApi, OpenApiSpecification openApiSpec, + String method, String path, String operationName, String statusCode) { + + super(new OpenApiSpecificationSource(openApiSpec), + OpenApiUtils.createFullPathOperationIdentifier(method, path), statusCode); + + this.generatedApi = generatedApi; + this.customizers = generatedApi.getCustomizers(); + + name(String.format("receive-%s", operationName)); + + endpoint(generatedApi.getEndpoint()); + } + + public RestApiReceiveMessageActionBuilder(GeneratedApi generatedApi, + OpenApiSpecification openApiSpec, + OpenApiClientResponseMessageBuilder messageBuilder, HttpMessage httpMessage, String method, + String path, String operationName) { + + super(new OpenApiSpecificationSource(openApiSpec), messageBuilder, httpMessage, + OpenApiUtils.createFullPathOperationIdentifier(method, path)); + + + this.generatedApi = generatedApi; + this.customizers = generatedApi.getCustomizers(); + + name(String.format("receive-%s", operationName)); + + endpoint(generatedApi.getEndpoint()); + + } + + public GeneratedApi getGeneratedApi() { + return generatedApi; + } + + public List getCustomizers() { + return customizers; + } +} \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/RestApiSendMessageActionBuilder.java b/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/RestApiSendMessageActionBuilder.java new file mode 100644 index 0000000000..02b9ba53cd --- /dev/null +++ b/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/RestApiSendMessageActionBuilder.java @@ -0,0 +1,332 @@ +/* + * Copyright the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.citrusframework.openapi.testapi; + +import static java.lang.String.format; + +import jakarta.servlet.http.Cookie; +import java.lang.reflect.Array; +import java.net.URLEncoder; +import java.util.Base64; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BiConsumer; +import org.citrusframework.actions.SendMessageAction; +import org.citrusframework.context.TestContext; +import org.citrusframework.exceptions.CitrusRuntimeException; +import org.citrusframework.http.actions.HttpClientRequestActionBuilder; +import org.citrusframework.http.message.HttpMessage; +import org.citrusframework.message.Message; +import org.citrusframework.openapi.OpenApiSpecification; +import org.citrusframework.openapi.actions.OpenApiSpecificationSource; +import org.citrusframework.openapi.util.OpenApiUtils; +import org.citrusframework.spi.Resource; +import org.citrusframework.spi.Resources; +import org.citrusframework.util.FileUtils; +import org.citrusframework.util.StringUtils; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +public class RestApiSendMessageActionBuilder extends + org.citrusframework.openapi.actions.OpenApiClientRequestActionBuilder { + + private final GeneratedApi generatedApi; + + private final List customizers; + + private final MultiValueMap formParameters = new LinkedMultiValueMap<>(); + + public RestApiSendMessageActionBuilder(GeneratedApi generatedApi, + OpenApiSpecification openApiSpec, + String method, String path, String operationName) { + this(generatedApi, openApiSpec, new HttpMessage(), method, path, operationName); + } + + public RestApiSendMessageActionBuilder(GeneratedApi generatedApi, + OpenApiSpecification openApiSpec, + HttpMessage httpMessage, String method, + String path, String operationName) { + + this(generatedApi, openApiSpec, + new TestApiClientRequestMessageBuilder(httpMessage, + new OpenApiSpecificationSource(openApiSpec), + OpenApiUtils.createFullPathOperationIdentifier(method, path)), httpMessage, method, path, + operationName); + } + + public RestApiSendMessageActionBuilder(GeneratedApi generatedApi, + OpenApiSpecification openApiSpec, + TestApiClientRequestMessageBuilder messageBuilder, HttpMessage httpMessage, String method, + String path, String operationName) { + + super(new OpenApiSpecificationSource(openApiSpec), messageBuilder, httpMessage, + OpenApiUtils.createFullPathOperationIdentifier(method, path)); + + this.generatedApi = generatedApi; + this.customizers = generatedApi.getCustomizers(); + + endpoint(generatedApi.getEndpoint()); + + httpMessage.path(path); + name(format("send-%s:%s", generatedApi.getClass().getSimpleName().toLowerCase(), + operationName)); + getMessageBuilderSupport().header("citrus_open_api_operation_name", operationName); + getMessageBuilderSupport().header("citrus_open_api_method", method); + getMessageBuilderSupport().header("citrus_open_api_path", path); + + } + + public GeneratedApi getGeneratedApi() { + return generatedApi; + } + + public List getCustomizers() { + return customizers; + } + + @Override + public final HttpClientRequestActionBuilder name(String name) { + return super.name(name); + } + + protected void pathParameter(String name, Object value, ParameterStyle parameterStyle, + boolean explode, boolean isObject) { + + ((TestApiClientRequestMessageBuilder) getMessageBuilderSupport().getMessageBuilder()).pathParameter( + name, value, parameterStyle, explode, isObject); + + } + + protected void formParameter(String name, Object value) { + setFormParameter(name, value); + } + + protected void setFormParameter(String name, Object value) { + + if (value == null || StringUtils.isEmpty(value.toString())) { + return; + } + + setParameter(formParameters::add, name, value); + } + + protected void queryParameter(final String name, Object value) { + + if (value == null || StringUtils.isEmpty(value.toString())) { + return; + } + + setParameter((paramName, paramValue) -> super.queryParam(paramName, + paramValue != null ? paramValue.toString() : null), name, value); + } + + protected void queryParameter(final String name, Object value, ParameterStyle parameterStyle, + boolean explode, boolean isObject) { + + if (value == null || StringUtils.isEmpty(value.toString())) { + return; + } + + String formatted = OpenApiParameterFormatter.formatArray(name, value, parameterStyle, explode, isObject); + String[] queryParamValues = formatted.split("&"); + for (String queryParamValue : queryParamValues) { + String[] keyValue = queryParamValue.split("="); + queryParameter(keyValue[0], keyValue[1]); + } + } + + protected void headerParameter(String name, Object value) { + + if (value == null || StringUtils.isEmpty(value.toString())) { + return; + } + + setParameter( + (paramName, paramValue) -> getMessageBuilderSupport().header(paramName, paramValue), + name, value); + } + + protected void headerParameter(String name, Object value, ParameterStyle parameterStyle, + boolean explode, boolean isObject) { + + if (value == null || StringUtils.isEmpty(value.toString())) { + return; + } + + headerParameter(name, OpenApiParameterFormatter.formatArray(name, value, parameterStyle, explode, isObject)); + } + + protected void cookieParameter(String name, Object value) { + + if (value == null || StringUtils.isEmpty(value.toString())) { + return; + } + + setParameter((paramName, paramValue) -> getMessageBuilderSupport().cookie( + (new Cookie(paramName, paramValue != null ? paramValue.toString() : null))), name, + value); + } + + protected void cookieParameter(String name, Object value, ParameterStyle parameterStyle, + boolean explode, boolean isObject) { + + if (value == null || StringUtils.isEmpty(value.toString())) { + return; + } + + String formatted = OpenApiParameterFormatter.formatArray(name, value, parameterStyle, explode, isObject); + String[] keyValue = formatted.split("="); + + // URL Encoding is mandatory especially in the case of multiple values, as multiple values + // are separated by a comma and a comma is not a valid character in cookies. + cookieParameter(keyValue[0], keyValue[1]); + } + + private void setParameter(BiConsumer parameterConsumer, + final String parameterName, Object parameterValue) { + if (parameterValue != null) { + if (byte[].class.isAssignableFrom(parameterValue.getClass())) { + // Pass through byte array + parameterConsumer.accept(parameterName, parameterValue); + } else if (parameterValue.getClass().isArray()) { + int length = Array.getLength(parameterValue); + for (int i = 0; i < length; i++) { + Object singleValue = Array.get(parameterValue, i); + parameterConsumer.accept(parameterName, singleValue); + } + } else if (parameterValue instanceof Collection collection) { + collection.forEach( + singleValue -> parameterConsumer.accept(parameterName, singleValue)); + } else { + parameterConsumer.accept(parameterName, parameterValue); + } + } + } + + @Override + public SendMessageAction doBuild() { + + if (!formParameters.isEmpty()) { + getMessageBuilderSupport().body(formParameters); + } + + return super.doBuild(); + } + + public static final class TestApiClientRequestMessageBuilder extends + OpenApiClientRequestMessageBuilder { + + private final Map pathParameters = new HashMap<>(); + + public TestApiClientRequestMessageBuilder(HttpMessage httpMessage, + OpenApiSpecificationSource openApiSpec, + String operationId) { + super(httpMessage, openApiSpec, operationId); + } + + public void pathParameter(String name, Object value, ParameterStyle parameterStyle, + boolean explode, boolean isObject) { + + if (value == null) { + throw new CitrusRuntimeException( + "Mandatory path parameter '%s' must not be null".formatted(name)); + } + pathParameters.put(name, + new ParameterData(name, value, parameterStyle, explode, isObject)); + } + + @Override + protected String getDefinedPathParameter(TestContext context, String name) { + ParameterData parameterData = pathParameters.get(name); + String formatted = name; + if (parameterData != null) { + formatted = OpenApiParameterFormatter.formatArray(name, parameterData.value, parameterData.parameterStyle, + parameterData.explode, parameterData.isObject); + } + + return context.replaceDynamicContentInString(formatted); + } + + @Override + public Message build(TestContext context, String messageType) { + HttpMessage message = (HttpMessage) super.build(context, messageType); + encodeArrayStyleCookies(message); + return message; + } + + private static void encodeArrayStyleCookies(HttpMessage message) { + if (message.getCookies() != null && !message.getCookies().isEmpty()) { + for (Cookie cookie : message.getCookies()) { + if (cookie.getValue().contains(",")) { + cookie.setValue( + URLEncoder.encode(cookie.getValue(), FileUtils.getDefaultCharset())); + } + } + } + } + } + + protected byte[] toBinary(Object object) { + if (object instanceof byte[] bytes) { + return bytes; + } else if (object instanceof Resource resource) { + return FileUtils.copyToByteArray(resource.getInputStream()); + } else if (object instanceof String string) { + + Resource resource = Resources.create(string); + if (resource != null && resource.exists()) { + return toBinary(resource); + } + + try { + return Base64.getDecoder().decode(string); + } catch (IllegalArgumentException e) { + // Ignore decoding failure and treat as regular string + } + return string.getBytes(FileUtils.getDefaultCharset()); + } + + throw new IllegalArgumentException( + "Cannot convert object to byte array. Only byte[], Resource, and String are supported: " + + object.getClass()); + } + + protected String getOrDefault(String value, String defaultValue, boolean base64Encode) { + + if (StringUtils.isEmpty(value) && StringUtils.isEmpty(defaultValue)) { + return null; + } + + if (StringUtils.isEmpty(value)) { + value = defaultValue; + } + + if (base64Encode) { + value = "citrus:encodeBase64('" + value + "')"; + } + + return value; + } + + public record ParameterData(String name, Object value, ParameterStyle parameterStyle, + boolean explode, boolean isObject) { + + } + +} \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/SoapApiReceiveMessageActionBuilder.java b/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/SoapApiReceiveMessageActionBuilder.java new file mode 100644 index 0000000000..cabbd162c7 --- /dev/null +++ b/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/SoapApiReceiveMessageActionBuilder.java @@ -0,0 +1,54 @@ +/* + * Copyright the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.citrusframework.openapi.testapi; + +import java.util.List; +import org.citrusframework.ws.actions.ReceiveSoapMessageAction; + +public class SoapApiReceiveMessageActionBuilder extends ReceiveSoapMessageAction.Builder { + + private final GeneratedApi generatedApi; + + private final List customizers; + + public SoapApiReceiveMessageActionBuilder(GeneratedApi generatedApi, String soapAction) { + + super(); + this.generatedApi = generatedApi; + this.customizers = generatedApi.getCustomizers(); + + endpoint(generatedApi.getEndpoint()); + + name(String.format("send-%s:%s", generatedApi.getClass().getSimpleName().toLowerCase(), + soapAction)); + } + + public GeneratedApi getGeneratedApi() { + return generatedApi; + } + + public List getCustomizers() { + return customizers; + } + + + @Override + public ReceiveSoapMessageAction doBuild() { + return new ReceiveSoapMessageAction(this); + } + +} \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/SoapApiSendMessageActionBuilder.java b/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/SoapApiSendMessageActionBuilder.java new file mode 100644 index 0000000000..cd69a5c7f7 --- /dev/null +++ b/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/SoapApiSendMessageActionBuilder.java @@ -0,0 +1,49 @@ +/* + * Copyright the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.citrusframework.openapi.testapi; + +import java.util.List; +import org.citrusframework.ws.actions.SendSoapMessageAction.Builder; + +public class SoapApiSendMessageActionBuilder extends Builder { + + private final GeneratedApi generatedApi; + + private final List customizers; + + public SoapApiSendMessageActionBuilder(GeneratedApi generatedApi, String soapAction) { + + super(); + this.generatedApi = generatedApi; + this.customizers = generatedApi.getCustomizers(); + + endpoint(generatedApi.getEndpoint()); + + name(String.format("send-%s:%s", generatedApi.getClass().getSimpleName().toLowerCase(), + soapAction)); + } + + public GeneratedApi getGeneratedApi() { + return generatedApi; + } + + public List getCustomizers() { + return customizers; + } + + +} \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/TestApiUtils.java b/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/TestApiUtils.java new file mode 100644 index 0000000000..a726e23cad --- /dev/null +++ b/test-api-generator/citrus-test-api-core/src/main/java/org/citrusframework/openapi/testapi/TestApiUtils.java @@ -0,0 +1,51 @@ +/* + * Copyright the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.citrusframework.openapi.testapi; + +import org.citrusframework.http.actions.HttpClientRequestActionBuilder.HttpMessageBuilderSupport; +import org.citrusframework.util.StringUtils; + +public class TestApiUtils { + + private TestApiUtils() { + //prevent instantiation of utility class + } + + public static void addBasicAuthHeader(String username, String password, HttpMessageBuilderSupport messageBuilderSupport) { + if (!StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)) { + messageBuilderSupport.header("Authorization", + "Basic citrus:encodeBase64(" + username + ":" + password + ")"); + } + } + + public static String mapXmlAttributeNameToJavaPropertyName(String attributeName) { + + if (StringUtils.isEmpty(attributeName)) { + return attributeName; + } + + if ("basicUsername".equals(attributeName)) { + return "withBasicAuthUsername"; + } else if ("basicPassword".equals(attributeName)) { + return "withBasicAuthPassword"; + } + + return attributeName; + + } + +} diff --git a/test-api-generator/citrus-test-api-core/src/test/java/org/citrusframework/openapi/testapi/OpenApiParameterFormatterTest.java b/test-api-generator/citrus-test-api-core/src/test/java/org/citrusframework/openapi/testapi/OpenApiParameterFormatterTest.java new file mode 100644 index 0000000000..ab19fbf7a4 --- /dev/null +++ b/test-api-generator/citrus-test-api-core/src/test/java/org/citrusframework/openapi/testapi/OpenApiParameterFormatterTest.java @@ -0,0 +1,73 @@ +package org.citrusframework.openapi.testapi; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.citrusframework.openapi.testapi.OpenApiParameterFormatter.formatArray; +import static org.citrusframework.openapi.testapi.ParameterStyle.DEEPOBJECT; +import static org.citrusframework.openapi.testapi.ParameterStyle.FORM; +import static org.citrusframework.openapi.testapi.ParameterStyle.LABEL; +import static org.citrusframework.openapi.testapi.ParameterStyle.MATRIX; +import static org.citrusframework.openapi.testapi.ParameterStyle.SIMPLE; + +import java.util.List; +import java.util.stream.Stream; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import org.citrusframework.openapi.testapi.RestApiSendMessageActionBuilder.ParameterData; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class OpenApiParameterFormatterTest { + + private static final User USER = User.user().role("admin").firstName("Alex").build(); + private static final List LIST = List.of(3,4,5); + private static final Integer SINGLE = 5; + + static Stream format() { + return Stream.of( + Arguments.arguments("Simple/non exploded/non object/single", new ParameterData("id", SINGLE, SIMPLE, false, false), "5"), + Arguments.arguments("Simple/non exploded/non object/array", new ParameterData("id", LIST, SIMPLE, false, false), "3,4,5"), + Arguments.arguments("Simple/non exploded/Object/single", new ParameterData("id", USER, SIMPLE, false, true) , "firstName,Alex,role,admin"), + Arguments.arguments("Simple/exploded/non object/single", new ParameterData("id", SINGLE, SIMPLE, true, false), "5"), + Arguments.arguments("Simple/exploded/non object/array", new ParameterData("id", LIST, SIMPLE, true, false), "3,4,5"), + Arguments.arguments("Simple/exploded/Object/single", new ParameterData("id", USER, SIMPLE, true, true) , "firstName=Alex,role=admin"), + Arguments.arguments("Label/non exploded/non object/single", new ParameterData("id", SINGLE, LABEL, false, false), ".5"), + Arguments.arguments("Label/non exploded/non object/array", new ParameterData("id", LIST, LABEL, false, false), ".3,4,5"), + Arguments.arguments("Label/non exploded/Object/single", new ParameterData("id", USER, LABEL, false, true) , ".firstName,Alex,role,admin"), + Arguments.arguments("Label/exploded/non object/single", new ParameterData("id", SINGLE, LABEL, true, false), ".5"), + Arguments.arguments("Label/exploded/non object/array", new ParameterData("id", LIST, LABEL, true, false), ".3.4.5"), + Arguments.arguments("Label/exploded/Object/single", new ParameterData("id", USER, LABEL, true, true) , ".firstName=Alex.role=admin"), + Arguments.arguments("Matrix/non exploded/non object/single", new ParameterData("id", SINGLE, MATRIX, false, false), ";id=5"), + Arguments.arguments("Matrix/non exploded/non object/array", new ParameterData("id", LIST, MATRIX, false, false), ";id=3,4,5"), + Arguments.arguments("Matrix/non exploded/Object/single", new ParameterData("id", USER, MATRIX, false, true) , ";id=firstName,Alex,role,admin"), + Arguments.arguments("Matrix/exploded/non object/single", new ParameterData("id", SINGLE, MATRIX, true, false), ";id=5"), + Arguments.arguments("Matrix/exploded/non object/array", new ParameterData("id", LIST, MATRIX, true, false), ";id=3;id=4;id=5"), + Arguments.arguments("Matrix/exploded/Object/single", new ParameterData("id", USER, MATRIX, true, true) , ";firstName=Alex;role=admin"), + Arguments.arguments("Form/non exploded/non object/single", new ParameterData("id", SINGLE, FORM, false, false) , "id=5"), + Arguments.arguments("Form/non exploded/non object/array", new ParameterData("id", LIST, FORM, false, false) , "id=3,4,5"), + Arguments.arguments("Form/non exploded/object/single", new ParameterData("id", USER, FORM, false, true) , "id=firstName,Alex,role,admin"), + Arguments.arguments("Form/exploded/non object/single", new ParameterData("id", SINGLE, FORM, true, false) , "id=5"), + Arguments.arguments("Form/exploded/non object/array", new ParameterData("id", LIST, FORM, true, false) , "id=3&id=4&id=5"), + Arguments.arguments("Form/exploded/object/single", new ParameterData("id", USER, FORM, true, true) , "firstName=Alex&role=admin"), + Arguments.arguments("DeepObject/exploded/object/single", new ParameterData("id", USER, DEEPOBJECT, true, true) , "id[firstName]=Alex&id[role]=admin") + ); + } + + @ParameterizedTest(name = "{0}") + @MethodSource + void format(String name, ParameterData parameterData, String expected) { + assertThat(formatArray(parameterData.name(), parameterData.value(), parameterData.parameterStyle(), parameterData.explode(), + parameterData.isObject())).isEqualTo(expected); + } + + @Getter + @Setter + @AllArgsConstructor + @Builder(builderMethodName = "user") + private static class User { + String role; + String firstName; + } +} diff --git a/test-api-generator/citrus-test-api-core/src/test/java/org/citrusframework/openapi/testapi/TestApiUtilsTest.java b/test-api-generator/citrus-test-api-core/src/test/java/org/citrusframework/openapi/testapi/TestApiUtilsTest.java new file mode 100644 index 0000000000..660130ba12 --- /dev/null +++ b/test-api-generator/citrus-test-api-core/src/test/java/org/citrusframework/openapi/testapi/TestApiUtilsTest.java @@ -0,0 +1,68 @@ +package org.citrusframework.openapi.testapi; + +import static org.mockito.Mockito.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import org.citrusframework.http.actions.HttpClientRequestActionBuilder.HttpMessageBuilderSupport; +import org.junit.jupiter.api.Test; + +class TestApiUtilsTest { + + @Test + void shouldAddBasicAuthHeaderWhenUsernameAndPasswordAreProvided() { + // Given + String username = "user"; + String password = "pass"; + HttpMessageBuilderSupport messageBuilderSupport = mock(HttpMessageBuilderSupport.class); + + // When + TestApiUtils.addBasicAuthHeader(username, password, messageBuilderSupport); + + // Then + verify(messageBuilderSupport).header("Authorization", "Basic citrus:encodeBase64(user:pass)"); + } + + @Test + void shouldNotAddBasicAuthHeaderWhenUsernameIsEmpty() { + // Given + String username = ""; + String password = "pass"; + HttpMessageBuilderSupport messageBuilderSupport = mock(HttpMessageBuilderSupport.class); + + // When + TestApiUtils.addBasicAuthHeader(username, password, messageBuilderSupport); + + // Then + verify(messageBuilderSupport, never()).header(anyString(), anyString()); + } + + @Test + void shouldNotAddBasicAuthHeaderWhenPasswordIsEmpty() { + // Given + String username = "user"; + String password = ""; + HttpMessageBuilderSupport messageBuilderSupport = mock(HttpMessageBuilderSupport.class); + + // When + TestApiUtils.addBasicAuthHeader(username, password, messageBuilderSupport); + + // Then + verify(messageBuilderSupport, never()).header(anyString(), anyString()); + } + + @Test + void shouldNotAddBasicAuthHeaderWhenBothUsernameAndPasswordAreEmpty() { + // Given + String username = ""; + String password = ""; + HttpMessageBuilderSupport messageBuilderSupport = mock(HttpMessageBuilderSupport.class); + + // When + TestApiUtils.addBasicAuthHeader(username, password, messageBuilderSupport); + + // Then + verify(messageBuilderSupport, never()).header(anyString(), anyString()); + } +} diff --git a/test-api-generator/citrus-test-api-generator-core/README.md b/test-api-generator/citrus-test-api-generator-core/README.md new file mode 100644 index 0000000000..a60957b2c7 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/README.md @@ -0,0 +1,102 @@ +TODO +TODO: document properties for security and others +TODO: document default properties for the endpoint -> prefix with lowercase + +## Generated Java Code for API Testing + +The code generator creates Java classes from an OpenAPI specification to facilitate API testing using the Citrus framework. +The Java classes represent Citrus Send and Receive ActionBuilders for each operation of the OpenAPI. Each builder provides +setter for the actual operation parameters. In general a type-safe method is provided, that reflects the correct operation type. +In addition a setter in string representation is provided to allow for citrus dynamic content setting using string expressions. +For each builder a specific operation is added to ... +A type-safe method providing the correct java type and a non type-safe method using a string type, allowing the usage of citrus expressions for the respective content. + +1. **Type-Safe Parameter Method**: This method accepts the required parameters directly. +2. **String-Based Parameter Method**: This method accepts parameters as strings to allow for dynamic content. + +Method names of non type-safe methods are prepended with a `$`. This is mainly to avoid conflicts for + +### Structure of the Generated API Class + +For each API operation, the generated class includes: + +1. **Builder with Type-Safe Required Parameters**: A method that takes the required parameters directly and returns a builder configured with these parameters. + +2. **Builder with Parameters as Strings**: A method that takes parameters as strings, allowing dynamic replacements via the Citrus framework. The method name is suffixed with `$` to distinguish it from the type-safe version. + +### Example + +Consider an operation to delete a pet with the following parameter: +- `petId` (required, type `Long`) + +The generated Java API class might look like this: + +```java +public class PetsApi { + + /** + * Builder with type safe required parameters. + */ + public DeletePetRequestActionBuilder sendDeletePet(Long petId) { + DeletePetRequestActionBuilder builder = new DeletePetRequestActionBuilder(openApiSpecification, petId); + builder.endpoint(httpClient); + return builder; + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public DeletePetRequestActionBuilder sendDeletePet$(String petIdExpression) { + DeletePetRequestActionBuilder builder = new DeletePetRequestActionBuilder(petIdExpression, openApiSpecification); + builder.endpoint(httpClient); + return builder; + } +} +``` + +## Known issues + +## Validation + +It is known, that the used OpenAPI validator is not able to validate certain situations. +E.g. certain array encoding situations related to object encoding + +## Variable processing + +Processing of variables in case of parameter serialization, in some cases causes problems. For example, it +is not possible to assign a json string to a variable and path it into an object into the current +parameter serialization mechanism. This expects a real json, which cannot be resolved. To solve this issue, +serialization of arrays must happen as late as possible. Maybe it is feasible to create an OpenApiEndpointConfiguration +with a respective message converter. + +## Handling of Array Parameters + +Currently, all array parameters are handled in explode mode, regardless of the `explode` setting specified +in the API definition. This means that each item in an array will be serialized as a separate query +parameter, even if the `explode` setting is set to `false` in the OpenAPI specification. + +### Example + +Suppose the OpenAPI specification defines an array parameter named `status` with the following attributes: + +```yaml +parameters: + - name: status + in: query + description: Status values that need to be considered for filter + required: false + explode: false + schema: + type: string + default: available + enum: + - available + - pending + - sold +``` + +Despite the explode: false setting, the request will be serialized as follows: + +``` +?status=available&status=pending&status=sold +``` \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/pom.xml b/test-api-generator/citrus-test-api-generator-core/pom.xml index 3af2a0689e..bb9340ac74 100644 --- a/test-api-generator/citrus-test-api-generator-core/pom.xml +++ b/test-api-generator/citrus-test-api-generator-core/pom.xml @@ -7,7 +7,7 @@ citrus-test-api-generator org.citrusframework - 4.3.0-SNAPSHOT + 4.4.0-SNAPSHOT ../pom.xml @@ -41,13 +41,35 @@ org.citrusframework citrus-spring ${project.version} - test org.citrusframework citrus-ws ${project.version} + + org.citrusframework + citrus-test-api-core + ${project.version} + + + org.citrusframework + citrus-groovy + ${project.version} + test + + + + org.citrusframework + citrus-validation-groovy + ${project.version} + test + + + org.citrusframework + citrus-test-api-spring + ${project.version} + org.assertj @@ -88,6 +110,12 @@ ${spring.boot.version} test + + commons-fileupload + commons-fileupload + 1.5 + test + @@ -98,7 +126,7 @@ ${maven.helper.plugin.version} - add-generated-specs + add-generated-test-resources generate-test-resources add-test-resource @@ -113,7 +141,7 @@ - add-generated-classes + add-generated-test-classes generate-test-sources add-test-source @@ -215,56 +243,54 @@ generate - ${project.basedir}/src/test/resources/apis/petstore.yaml + ${project.basedir}/src/test/resources/apis/petstore-v3.yaml org.citrusframework.openapi.generator.rest.petstore org.citrusframework.openapi.generator.rest.petstore.request org.citrusframework.openapi.generator.rest.petstore.model - PetStore - petStoreEndpoint + petStore + petstore.endpoint - generate-openapi-files-for-soap + generate-openapi-petstore-extended-files compile generate - ${project.basedir}/src/test/resources/org/citrusframework/openapi/generator/SimpleWsdlToOpenApiTransformerTest/BookService-generated.yaml + ${project.basedir}/src/test/resources/apis/petstore-extended-v3.yaml - SOAP - org.citrusframework.openapi.generator.soap.bookservice - org.citrusframework.openapi.generator.soap.bookservice.request - org.citrusframework.openapi.generator.soap.bookservice.model - SoapSample - OpenApiFromWsdl - soapSampleEndpoint + org.citrusframework.openapi.generator.rest.extpetstore + org.citrusframework.openapi.generator.rest.extpetstore.request + org.citrusframework.openapi.generator.rest.extpetstore.model + ExtPetStore + extpetstore.endpoint - - - generate-openapi-multiparttest-files + generate-openapi-files-for-soap compile generate - ${project.basedir}/src/test/resources/apis/multiparttest-rest-resource.yaml + ${project.basedir}/src/test/resources/apis/BookService-generated.yaml - org.citrusframework.openapi.generator.rest.multiparttest - org.citrusframework.openapi.generator.rest.multiparttest.request - org.citrusframework.openapi.generator.rest.multiparttest.model - MultipartTest - multipartTestEndpoint + SOAP + org.citrusframework.openapi.generator.soap.bookservice + org.citrusframework.openapi.generator.soap.bookservice.request + org.citrusframework.openapi.generator.soap.bookservice.model + BookService + bookstore.endpoint + diff --git a/test-api-generator/citrus-test-api-generator-core/src/main/java/org/citrusframework/openapi/generator/CitrusJavaCodegen.java b/test-api-generator/citrus-test-api-generator-core/src/main/java/org/citrusframework/openapi/generator/CitrusJavaCodegen.java new file mode 100644 index 0000000000..50ae1d21b9 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/main/java/org/citrusframework/openapi/generator/CitrusJavaCodegen.java @@ -0,0 +1,595 @@ +/* + * Copyright the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.citrusframework.openapi.generator; + +import static java.lang.Boolean.TRUE; +import static java.lang.String.format; +import static java.util.Arrays.asList; +import static java.util.stream.Collectors.toMap; +import static org.citrusframework.util.ReflectionHelper.copyFields; +import static org.citrusframework.util.StringUtils.appendSegmentToUrlPath; +import static org.citrusframework.util.StringUtils.titleCase; +import static org.openapitools.codegen.CliOption.newString; +import static org.openapitools.codegen.utils.CamelizeOption.LOWERCASE_FIRST_LETTER; +import static org.openapitools.codegen.utils.StringUtils.camelize; + +import io.swagger.v3.core.util.Yaml; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.parameters.Parameter; +import io.swagger.v3.oas.models.parameters.RequestBody; +import io.swagger.v3.oas.models.servers.Server; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Set; +import lombok.Getter; +import lombok.Setter; +import org.citrusframework.exceptions.CitrusRuntimeException; +import org.citrusframework.openapi.testapi.RestApiReceiveMessageActionBuilder; +import org.citrusframework.openapi.testapi.RestApiSendMessageActionBuilder; +import org.citrusframework.openapi.testapi.SoapApiReceiveMessageActionBuilder; +import org.citrusframework.openapi.testapi.SoapApiSendMessageActionBuilder; +import org.openapitools.codegen.CodegenOperation; +import org.openapitools.codegen.CodegenParameter; +import org.openapitools.codegen.CodegenSecurity; +import org.openapitools.codegen.CodegenType; +import org.openapitools.codegen.SupportingFile; +import org.openapitools.codegen.languages.AbstractJavaCodegen; +import org.openapitools.codegen.model.ModelMap; +import org.openapitools.codegen.model.OperationMap; +import org.openapitools.codegen.model.OperationsMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Getter +@Setter +public class CitrusJavaCodegen extends AbstractJavaCodegen { + + private static final Logger logger = LoggerFactory.getLogger(CitrusJavaCodegen.class); + + public static final String CODEGEN_NAME = "java-citrus"; + + public static final String API_TYPE_REST = "REST"; + public static final String API_TYPE_SOAP = "SOAP"; + + public static final String API_ENDPOINT = "apiEndpoint"; + public static final String API_TYPE = "apiType"; + public static final String GENERATED_SCHEMA_FOLDER = "generatedSchemaFolder"; + public static final String PREFIX = "prefix"; + public static final String RESOURCE_FOLDER = "resourceFolder"; + public static final String SOURCE_FOLDER = "sourceFolder"; + public static final String TARGET_XMLNS_NAMESPACE = "targetXmlnsNamespace"; + public static final String REQUEST_BUILDER_CLASS = "requestBuilderClass"; + public static final String RESPONSE_BUILDER_CLASS = "responseBuilderClass"; + public static final String REQUEST_BUILDER_CLASS_NAME = "requestBuilderClassName"; + public static final String RESPONSE_BUILDER_CLASS_NAME = "responseBuilderClassName"; + + protected String apiPrefix = "Api"; + + protected String httpClient = API_ENDPOINT; + + protected String resourceFolder = + "src" + File.separator + "main" + File.separator + "resources"; + protected String generatedSchemaFolder = "schema" + File.separator + "xsd"; + protected String targetXmlnsNamespace; + + protected String apiVersion = "1.0.0"; + private String invokerFolder; + private String springFolder; + private String schemaFolder; + + public CitrusJavaCodegen() { + super(); + + templateDir = CODEGEN_NAME; + + configureAdditionalProperties(); + configureReservedWords(); + configureCliOptions(); + configureTypeMappings(); + } + + private void configureAdditionalProperties() { + additionalProperties.put("apiVersion", apiVersion); + additionalProperties.put(API_TYPE, API_TYPE_REST); + additionalProperties.put("useJakartaEe", true); + } + + private void configureReservedWords() { + Set reservedWordsTemp = reservedWords(); + reservedWordsTemp.addAll( + asList( + "name", + "description", + "httpClient", + "message", + "endpoint", + "validate", + "validator", + "validators", + "process", + "selector", + "transform", + "build", + "actor", + "process") + ); + setReservedWordsLowerCase(new ArrayList<>(reservedWordsTemp)); + } + + private void configureCliOptions() { + cliOptions.add( + newString(API_ENDPOINT, + "Which http client should be used (default " + httpClient + ").")); + cliOptions.add( + newString(API_TYPE, + "Specifies the type of API to be generated specify SOAP to generate a SOAP API. By default a REST API will be generated" + ) + ); + cliOptions.add( + newString(GENERATED_SCHEMA_FOLDER, + "The schema output directory (default " + generatedSchemaFolder + ").") + ); + cliOptions.add( + newString(PREFIX, + "Add a prefix before the name of the files. First character should be upper case (default " + + apiPrefix + ")." + ) + ); + cliOptions.add(newString(PREFIX, "The api prefix (default " + apiPrefix + ").")); + cliOptions.add( + newString(RESOURCE_FOLDER, + "Where the resource files are emitted (default " + resourceFolder + ").")); + cliOptions.add( + newString(TARGET_XMLNS_NAMESPACE, + "Xmlns namespace of the schema (default " + targetXmlnsNamespace + ").") + ); + } + + private void configureTypeMappings() { + this.typeMapping.put("binary", "Resource"); + this.typeMapping.put("file", "Resource"); + } + + /** + * Returns human-friendly help for the generator. Provide the consumer with help tips, + * parameters here + * + * @return A string value for the help message + */ + @Override + public String getHelp() { + return "Generates citrus api requests."; + } + + /** + * Configures a friendly name for the generator. This will be used by the generator to select + * the library with the -g flag. + * + * @return the friendly name for the generator + */ + @Override + public String getName() { + return CODEGEN_NAME; + } + + /** + * Configures the type of generator. + * + * @return the CodegenType for this generator + * @see org.openapitools.codegen.CodegenType + */ + @Override + public CodegenType getTag() { + return CodegenType.CLIENT; + } + + @Override + public void processOpts() { + super.processOpts(); + setupEndpoint(); + setupApiPrefix(); + setupNamespace(); + setupFolders(); + setupApiType(); + addDefaultSupportingFiles(); + writeApiToResourceFolder(); + } + + private void setupEndpoint() { + if (additionalProperties.containsKey(API_ENDPOINT)) { + this.setHttpClient(additionalProperties.get(API_ENDPOINT).toString()); + } + additionalProperties.put(API_ENDPOINT, httpClient); + } + + private void setupApiPrefix() { + if (additionalProperties.containsKey(PREFIX)) { + this.setApiPrefix(additionalProperties.get(PREFIX).toString()); + additionalProperties.put(PREFIX, apiPrefix); + additionalProperties.put(PREFIX + "LowerCase", apiPrefix.toLowerCase()); + } else { + logger.warn( + "Using empty prefix for code generation. A prefix can be configured using \"{}\" property.", + PREFIX); + apiPrefix = ""; + } + } + + private void setupNamespace() { + 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); + } + + private void setupFolders() { + if (additionalProperties.containsKey(GENERATED_SCHEMA_FOLDER)) { + this.setGeneratedSchemaFolder( + additionalProperties.get(GENERATED_SCHEMA_FOLDER).toString()); + } + additionalProperties.put(GENERATED_SCHEMA_FOLDER, generatedSchemaFolder); + + if (additionalProperties.containsKey(RESOURCE_FOLDER)) { + this.setResourceFolder(additionalProperties.get(RESOURCE_FOLDER).toString()); + } + additionalProperties.put(RESOURCE_FOLDER, resourceFolder); + + invokerFolder = (sourceFolder + File.separator + invokerPackage).replace(".", + File.separator); + springFolder = invokerFolder + File.separator + "spring"; + schemaFolder = resourceFolder + File.separator + generatedSchemaFolder; + } + + private void setupApiType() { + Object apiType = additionalProperties.get(API_TYPE); + if (API_TYPE_REST.equals(apiType)) { + setupRestApiType(springFolder, schemaFolder); + } else if (API_TYPE_SOAP.equals(apiType)) { + setupSoapApiType(springFolder, schemaFolder); + } else { + throw new IllegalArgumentException(format("Unknown API_TYPE: '%s'", apiType)); + } + } + + private void setupSoapApiType(String springFolder, String schemaFolder) { + additionalProperties.put(REQUEST_BUILDER_CLASS, + SoapApiSendMessageActionBuilder.class.getName()); + additionalProperties.put(REQUEST_BUILDER_CLASS_NAME, + SoapApiSendMessageActionBuilder.class.getSimpleName()); + additionalProperties.put(RESPONSE_BUILDER_CLASS, + SoapApiReceiveMessageActionBuilder.class.getName()); + additionalProperties.put(RESPONSE_BUILDER_CLASS_NAME, + SoapApiReceiveMessageActionBuilder.class.getSimpleName()); + additionalProperties.put("isRest", false); + additionalProperties.put("isSoap", true); + addSoapSupportingFiles(springFolder, schemaFolder); + } + + private void setupRestApiType(String springFolder, String schemaFolder) { + additionalProperties.put(REQUEST_BUILDER_CLASS, + RestApiSendMessageActionBuilder.class.getName()); + additionalProperties.put(REQUEST_BUILDER_CLASS_NAME, + RestApiSendMessageActionBuilder.class.getSimpleName()); + additionalProperties.put(RESPONSE_BUILDER_CLASS, + RestApiReceiveMessageActionBuilder.class.getName()); + additionalProperties.put(RESPONSE_BUILDER_CLASS_NAME, + RestApiReceiveMessageActionBuilder.class.getSimpleName()); + additionalProperties.put("isRest", true); + additionalProperties.put("isSoap", false); + + addRestSupportingFiles(springFolder, schemaFolder); + } + + /** + * Store a copy of the source open api as resource. + */ + private void writeApiToResourceFolder() { + + String directoryPath = appendSegmentToUrlPath(getOutputDir(), getResourceFolder()); + directoryPath = appendSegmentToUrlPath(directoryPath, + invokerPackage.replace('.', File.separatorChar)); + + String filename = getApiPrefix() + "_openApi.yaml"; + + File directory = new File(directoryPath); + if (!directory.exists() && !directory.mkdirs()) { + throw new CitrusRuntimeException("Unable to create directory for api resource!"); + } + + File file = new File(directory, filename); + + try (FileWriter writer = new FileWriter(file)) { + String yamlContent = Yaml.pretty(openAPI); + writer.write(yamlContent); + } catch (IOException e) { + throw new CitrusRuntimeException( + "Unable to write OpenAPI to resource folder: " + file.getAbsolutePath()); + } + } + + @Override + public void preprocessOpenAPI(OpenAPI openAPI) { + super.preprocessOpenAPI(openAPI); + + Info info = openAPI.getInfo(); + Map extensions = info.getExtensions(); + if (extensions != null) { + 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); + } + } + + private void addRestSupportingFiles(String springFolder, + String schemaFolder) { + + supportingFiles.add(new SupportingFile("namespace_handler.mustache", springFolder, + titleCase(apiPrefix) + "NamespaceHandler.java")); + supportingFiles.add(new SupportingFile("schema.mustache", schemaFolder, + apiPrefix.toLowerCase() + "-api.xsd")); + } + + private void addSoapSupportingFiles(String springFolder, String schemaFolder) { + // Remove the default api template file + apiTemplateFiles().remove("api.mustache"); + apiTemplateFiles().put("api_soap.mustache", ".java"); + + supportingFiles.add(new SupportingFile("namespace_handler_soap.mustache", springFolder, + titleCase(apiPrefix) + "NamespaceHandler.java")); + supportingFiles.add(new SupportingFile("schema_soap.mustache", schemaFolder, + apiPrefix.toLowerCase() + "-api.xsd")); + } + + private void addDefaultSupportingFiles() { + supportingFiles.add(new SupportingFile("api_locator.mustache", invokerFolder, + titleCase(apiPrefix) + ".java")); + supportingFiles.add(new SupportingFile("bean_configuration.mustache", springFolder, + titleCase(apiPrefix) + "BeanConfiguration.java")); + } + + @Override + public CodegenParameter fromRequestBody(RequestBody body, Set imports, + String bodyParameterName) { + CodegenParameter codegenParameter = super.fromRequestBody(body, imports, bodyParameterName); + return convertToCustomCodegenParameter(codegenParameter); + } + + @Override + public CodegenParameter fromFormProperty(String name, Schema propertySchema, + Set imports) { + CodegenParameter codegenParameter = super.fromFormProperty(name, propertySchema, imports); + return convertToCustomCodegenParameter(codegenParameter); + } + + @Override + public CodegenParameter fromParameter(Parameter parameter, Set imports) { + CodegenParameter codegenParameter = super.fromParameter(parameter, imports); + + if ("File".equals(codegenParameter.dataType)) { + codegenParameter.dataType = "Resource"; + } + + return convertToCustomCodegenParameter(codegenParameter); + } + + /** + * Converts given codegenParameter to a custom {@link CustomCodegenParameter} to provide + * additional derived properties. + */ + private CustomCodegenParameter convertToCustomCodegenParameter( + CodegenParameter codegenParameter) { + CustomCodegenParameter customCodegenParameter = new CustomCodegenParameter(); + copyFields(CodegenParameter.class, codegenParameter, customCodegenParameter); + + customCodegenParameter.isBaseTypeString = codegenParameter.isString || "String".equals( + codegenParameter.baseType); + + return customCodegenParameter; + } + + @Override + public CodegenOperation fromOperation(String path, + String httpMethod, + Operation operation, + List servers) { + CodegenOperation op = super.fromOperation(path, httpMethod, operation, servers); + return convertToCustomCodegenOperation(op); + + } + + /** + * Converts given codegenOperation to a custom {@link CustomCodegenOperation} to provide + * additional derived properties. + */ + private CustomCodegenOperation convertToCustomCodegenOperation( + CodegenOperation codegenOperation) { + + CustomCodegenOperation customOperation = new CustomCodegenOperation(); + + copyFields(CodegenOperation.class, codegenOperation, customOperation); + + customOperation.requiredNonBodyParams.addAll(customOperation.requiredParams + .stream() + .filter(param -> !param.isBodyParam).toList()); + + customOperation.needsConstructorWithAllStringParameter = + !customOperation.requiredParams.isEmpty() && + customOperation.requiredParams + .stream() + .anyMatch( + param -> !param.isBodyParam && !"String".equals(param.dataType)); + + if (customOperation.optionalParams != null) { + customOperation.optionalAndAuthParameterNames.addAll( + customOperation.optionalParams.stream() + .map(codegenParameter -> + toVarName(codegenParameter.nameInCamelCase)) + .toList()); + } + + return customOperation; + } + + @Override + public OperationsMap postProcessOperationsWithModels(OperationsMap objs, + List allModels) { + OperationsMap operationsMap = super.postProcessOperationsWithModels(objs, allModels); + + OperationMap operations = objs.getOperations(); + List operationList = operations.getOperation(); + if (operationList != null) { + operationList.forEach(codegenOperation -> { + if (codegenOperation instanceof CustomCodegenOperation customCodegenOperation + && customCodegenOperation.authMethods != null) { + postProcessSecurityParameters(customCodegenOperation); + } + }); + } + + return operationsMap; + } + + private static void postProcessSecurityParameters( + CustomCodegenOperation customCodegenOperation) { + customCodegenOperation.hasApiKeyAuth = customCodegenOperation.authMethods.stream() + .anyMatch(codegenSecurity -> codegenSecurity.isApiKey); + + customCodegenOperation.authWithParameters = customCodegenOperation.hasApiKeyAuth; + for (CodegenSecurity codegenSecurity : customCodegenOperation.authMethods) { + if (TRUE.equals(codegenSecurity.isBasicBasic)) { + customCodegenOperation.optionalAndAuthParameterNames.add( + "basicAuthUsername"); + customCodegenOperation.optionalAndAuthParameterNames.add( + "basicAuthPassword"); + customCodegenOperation.authWithParameters = true; + } else if (TRUE.equals(codegenSecurity.isApiKey)) { + customCodegenOperation.optionalAndAuthParameterNames.add( + camelize(codegenSecurity.keyParamName, LOWERCASE_FIRST_LETTER)); + customCodegenOperation.authWithParameters = true; + } else if (TRUE.equals(codegenSecurity.isBasicBearer)) { + customCodegenOperation.optionalAndAuthParameterNames.add( + "basicAuthBearer"); + customCodegenOperation.authWithParameters = true; + } + } + } + + static class CustomCodegenOperation extends CodegenOperation { + + private final List requiredNonBodyParams; + + /** + * List of all optional parameters plus all authentication specific parameter names. + */ + private final List optionalAndAuthParameterNames; + + private boolean needsConstructorWithAllStringParameter; + + private boolean authWithParameters; + + private boolean hasApiKeyAuth; + + public CustomCodegenOperation() { + super(); + requiredNonBodyParams = new ArrayList<>(); + optionalAndAuthParameterNames = new ArrayList<>(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + if (!super.equals(o)) { + return false; + } + CustomCodegenOperation that = (CustomCodegenOperation) o; + return needsConstructorWithAllStringParameter + == that.needsConstructorWithAllStringParameter + && hasApiKeyAuth == that.hasApiKeyAuth && Objects.equals(requiredNonBodyParams, + that.requiredNonBodyParams) && Objects.equals(optionalAndAuthParameterNames, + that.optionalAndAuthParameterNames); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), requiredNonBodyParams, + optionalAndAuthParameterNames, + needsConstructorWithAllStringParameter, hasApiKeyAuth); + } + } + + static class CustomCodegenParameter extends CodegenParameter { + + boolean isBaseTypeString; + + public CustomCodegenParameter() { + super(); + } + + @Override + public CustomCodegenParameter copy() { + CodegenParameter copy = super.copy(); + CustomCodegenParameter customCopy = new CustomCodegenParameter(); + + copyFields(CodegenParameter.class, copy, customCopy); + customCopy.isBaseTypeString = isBaseTypeString; + + return customCopy; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + if (!super.equals(o)) { + return false; + } + CustomCodegenParameter that = (CustomCodegenParameter) o; + return isBaseTypeString == that.isBaseTypeString; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), isBaseTypeString); + } + } +} 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 deleted file mode 100644 index c624c885f6..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/main/java/org/citrusframework/openapi/generator/JavaCitrusCodegen.java +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.citrusframework.openapi.generator; - -import static java.lang.String.format; -import static java.util.Arrays.asList; -import static java.util.stream.Collectors.toMap; -import static org.openapitools.codegen.CliOption.newString; - -import io.swagger.v3.oas.models.OpenAPI; -import io.swagger.v3.oas.models.info.Info; -import java.io.File; -import java.util.ArrayList; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import lombok.Getter; -import lombok.Setter; -import org.openapitools.codegen.CodegenType; -import org.openapitools.codegen.SupportingFile; -import org.openapitools.codegen.languages.AbstractJavaCodegen; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@Getter -@Setter -public class JavaCitrusCodegen extends AbstractJavaCodegen { - - private static final Logger logger = LoggerFactory.getLogger(JavaCitrusCodegen.class); - - private static final String ABSTRACT_TEST_REQUEST_JAVA = "AbstractTestRequest.java"; - private static final String API_TYPE_REST = "REST"; - private static final String API_TYPE_SOAP = "SOAP"; - public static final String CODEGEN_NAME = "java-citrus"; - - // possible optional parameters - public static final String API_ENDPOINT = "apiEndpoint"; - public static final String API_TYPE = "apiType"; - public static final String GENERATED_SCHEMA_FOLDER = "generatedSchemaFolder"; - public static final String HTTP_PATH_PREFIX = "httpPathPrefix"; - public static final String OPENAPI_SCHEMA = "openapiSchema"; - public static final String PREFIX = "prefix"; - public static final String RESOURCE_FOLDER = "resourceFolder"; - public static final String SOURCE_FOLDER = "sourceFolder"; - public static final String TARGET_XMLNS_NAMESPACE = "targetXmlnsNamespace"; - - // default values for optional parameters - protected String apiPrefix = "Api"; - - protected String httpClient = API_ENDPOINT; - protected String httpPathPrefix = "api"; - protected String openapiSchema = "oas3"; - protected String resourceFolder = - "src" + File.separator + "main" + File.separator + "resources"; - protected String generatedSchemaFolder = "schema" + File.separator + "xsd"; - protected String targetXmlnsNamespace; - - protected String apiVersion = "1.0.0"; - - public JavaCitrusCodegen() { - super(); - - // the root folder where all files are emitted - outputFolder = "generated-code" + File.separator + "java"; - - // this is the location which templates will be read from in the - resources - directory - templateDir = CODEGEN_NAME; - - // register additional properties which will be available in the templates - additionalProperties.put("apiVersion", apiVersion); - - // set default - additionalProperties.put(API_TYPE, API_TYPE_REST); - additionalProperties.put("useJakartaEe", true); - - // add additional reserved words used in CitrusAbstractTestRequest and its base class to prevent name collisions - Set reservedWordsTemp = reservedWords(); - reservedWordsTemp.addAll( - asList( - "name", - "description", - "actor", - "httpClient", - "dataSource", - "schemaValidation", - "schema", - "headerContentType", - "headerAccept", - "bodyFile", - "responseType", - "responseStatus", - "responseReasonPhrase", - "responseVersion", - "resource", - "responseVariable", - "responseValue", - "cookies", - "script", - "type" - ) - ); - setReservedWordsLowerCase(new ArrayList<>(reservedWordsTemp)); - - // add possibility to set a new value for the properties - cliOptions.add( - newString(API_ENDPOINT, - "Which http client should be used (default " + httpClient + ").")); - cliOptions.add( - newString(API_TYPE, - "Specifies the type of API to be generated specify SOAP to generate a SOAP API. By default a REST API will be generated" - ) - ); - cliOptions.add( - newString(GENERATED_SCHEMA_FOLDER, - "The schema output directory (default " + generatedSchemaFolder + ").") - ); - cliOptions.add( - newString(HTTP_PATH_PREFIX, - "Add a prefix to http path for all APIs (default " + httpPathPrefix + ").")); - cliOptions.add( - newString(OPENAPI_SCHEMA, - "Which OpenAPI schema should be used (default " + openapiSchema + ").")); - cliOptions.add( - newString(PREFIX, - "Add a prefix before the name of the files. First character should be upper case (default " + apiPrefix + ")." - ) - ); - cliOptions.add(newString(PREFIX, "The api prefix (default " + apiPrefix + ").")); - cliOptions.add( - newString(RESOURCE_FOLDER, - "Where the resource files are emitted (default " + resourceFolder + ").")); - cliOptions.add( - newString(TARGET_XMLNS_NAMESPACE, - "Xmlns namespace of the schema (default " + targetXmlnsNamespace + ").") - ); - } - - /** - * Returns human-friendly help for the generator. Provide the consumer with help tips, - * parameters here - * - * @return A string value for the help message - */ - @Override - public String getHelp() { - return "Generates citrus api requests."; - } - - /** - * Configures a friendly name for the generator. This will be used by the generator to select - * the library with the -g flag. - * - * @return the friendly name for the generator - */ - @Override - public String getName() { - return CODEGEN_NAME; - } - - /** - * Configures the type of generator. - * - * @return the CodegenType for this generator - * @see org.openapitools.codegen.CodegenType - */ - @Override - public CodegenType getTag() { - return CodegenType.CLIENT; - } - - @Override - public void processOpts() { - super.processOpts(); - - if (additionalProperties.containsKey(API_ENDPOINT)) { - this.setHttpClient(additionalProperties.get(API_ENDPOINT).toString()); - } - 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); - - if (additionalProperties.containsKey(HTTP_PATH_PREFIX)) { - this.setHttpPathPrefix(additionalProperties.get(HTTP_PATH_PREFIX).toString()); - additionalProperties.put(HTTP_PATH_PREFIX, httpPathPrefix); - } else { - logger.warn( - "Using empty http-path-prefix for code generation. A http-path-prefix can be configured using \"{}\" property.", - HTTP_PATH_PREFIX - ); - httpPathPrefix = ""; - } - - if (additionalProperties.containsKey(OPENAPI_SCHEMA)) { - this.setOpenapiSchema(additionalProperties.get(OPENAPI_SCHEMA).toString()); - } - additionalProperties.put(OPENAPI_SCHEMA, openapiSchema); - - if (additionalProperties.containsKey(PREFIX)) { - this.setApiPrefix(additionalProperties.get(PREFIX).toString()); - additionalProperties.put(PREFIX, apiPrefix); - additionalProperties.put(PREFIX + "LowerCase", apiPrefix.toLowerCase()); - } else { - logger.warn( - "Using empty prefix for code generation. A prefix can be configured using \"{}\" property.", - PREFIX); - apiPrefix = ""; - } - - if (additionalProperties.containsKey(RESOURCE_FOLDER)) { - this.setResourceFolder(additionalProperties.get(RESOURCE_FOLDER).toString()); - } - 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"; - final String schemaFolder = resourceFolder + File.separator + generatedSchemaFolder; - - Object apiType = additionalProperties.get(API_TYPE); - if (API_TYPE_REST.equals(apiType)) { - addRestSupportingFiles(citrusFolder, schemaFolder); - } else if (API_TYPE_SOAP.equals(apiType)) { - addSoapSupportingFiles(citrusFolder, schemaFolder); - } else { - throw new IllegalArgumentException(format("Unknown API_TYPE: '%s'", apiType)); - } - - addDefaultSupportingFiles(citrusFolder, extensionFolder, springFolder); - } - - @Override - public void preprocessOpenAPI(OpenAPI openAPI) { - super.preprocessOpenAPI(openAPI); - - Info info = openAPI.getInfo(); - Map extensions = info.getExtensions(); - if (extensions != null) { - 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); - } - } - - 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)); - } - - private void addSoapSupportingFiles(final String citrusFolder, String schemaFolder) { - // Remove the default api template file - apiTemplateFiles().remove("api.mustache"); - apiTemplateFiles().put("api_soap.mustache", ".java"); - - supportingFiles.add(new SupportingFile("schema_soap.mustache", schemaFolder, apiPrefix.toLowerCase() + "-api.xsd")); - supportingFiles.add(new SupportingFile("api_soap.mustache", citrusFolder, apiPrefix + ABSTRACT_TEST_REQUEST_JAVA)); - supportingFiles.add(new SupportingFile("test_base_soap.mustache", citrusFolder, apiPrefix + ABSTRACT_TEST_REQUEST_JAVA)); - } - - private void addDefaultSupportingFiles(final String citrusFolder, final String extensionFolder, final String springFolder) { - supportingFiles.add(new SupportingFile("bean_configuration.mustache", springFolder, apiPrefix + "BeanConfiguration.java")); - supportingFiles.add(new SupportingFile("bean_definition_parser.mustache", citrusFolder, apiPrefix + "BeanDefinitionParser.java")); - 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/TestApiClientRequestActionBuilder.java b/test-api-generator/citrus-test-api-generator-core/src/main/java/org/citrusframework/openapi/generator/TestApiClientRequestActionBuilder.java deleted file mode 100644 index 7945002312..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/main/java/org/citrusframework/openapi/generator/TestApiClientRequestActionBuilder.java +++ /dev/null @@ -1,69 +0,0 @@ -package org.citrusframework.openapi.generator; - -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; -import org.citrusframework.actions.SendMessageAction; -import org.citrusframework.openapi.OpenApiSpecification; -import org.citrusframework.openapi.actions.OpenApiClientRequestActionBuilder; -import org.springframework.http.MediaType; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; - -public class TestApiClientRequestActionBuilder extends OpenApiClientRequestActionBuilder { - - // TODO: do we really need this? - protected OpenApiSpecification openApiSpec; - - private final String path; - - private final Map pathParameters = new HashMap<>(); - - private final MultiValueMap formData = new LinkedMultiValueMap<>(); - - // TODO: can we just pass in the operation? - public TestApiClientRequestActionBuilder(OpenApiSpecification openApiSpec, String method, String path, String operationName) { - super(openApiSpec, "%s_%s".formatted(method, path)); - name(String.format("%s:%s", "PetStore".toLowerCase(), operationName)); - getMessageBuilderSupport().header("citrus_open_api_operation_name", operationName); - getMessageBuilderSupport().header("citrus_open_api_method", method); - getMessageBuilderSupport().header("citrus_open_api_path", path); - - this.openApiSpec = openApiSpec; - this.path = path; - } - - protected void pathParameter(String name, String value) { - pathParameters.put(name, value); - } - - protected void formData(String name, String value) { - formData.add(name, value); - } - - protected String qualifiedPath(String path) { - - String qualifiedPath = path; - for (Entry entry : pathParameters.entrySet()) { - qualifiedPath = qualifiedPath.replace("{%s}".formatted(entry.getKey()), entry.getValue()); - } - return qualifiedPath; - } - - protected String toQueryParam(String...arrayElements) { - return String.join(",", arrayElements); - } - - @Override - public SendMessageAction doBuild() { - // TODO: register callback to modify builder - path(qualifiedPath(path)); - if (!formData.isEmpty()) { - // TODO: do we have to explicitly set the content type or is this done by citrus - messageBuilderSupport.contentType(MediaType.MULTIPART_FORM_DATA_VALUE); - getMessageBuilderSupport().body(formData); - } - return super.doBuild(); - } - - } \ No newline at end of file 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/WsdlToOpenApiTransformer.java similarity index 60% rename from test-api-generator/citrus-test-api-generator-core/src/main/java/org/citrusframework/openapi/generator/SimpleWsdlToOpenApiTransformer.java rename to test-api-generator/citrus-test-api-generator-core/src/main/java/org/citrusframework/openapi/generator/WsdlToOpenApiTransformer.java index 8243be5aa8..db0be8bfe2 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/WsdlToOpenApiTransformer.java @@ -28,6 +28,7 @@ import io.swagger.v3.oas.models.Paths; import io.swagger.v3.oas.models.info.Contact; import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.responses.ApiResponse; import io.swagger.v3.oas.models.responses.ApiResponses; import java.net.URI; import java.util.Collections; @@ -38,6 +39,7 @@ import javax.wsdl.BindingOperation; import javax.wsdl.Definition; import javax.wsdl.WSDLException; +import javax.wsdl.extensions.soap.SOAPOperation; import javax.wsdl.factory.WSDLFactory; import javax.wsdl.xml.WSDLReader; import javax.xml.namespace.QName; @@ -47,14 +49,56 @@ import org.w3c.dom.Element; /** - * Transforms a wsdl specification into a simple OpenApi specification for usage with the OpenApiGenerator. + * Transforms a WSDL specification into a simple OpenAPI specification for usage with the OpenApiGenerator. *

+ * This transformer primarily focuses on mapping WSDL bindings into OpenAPI operations. + * It converts SOAP operations described in the WSDL into corresponding HTTP POST operations + * in the OpenAPI format. However, it does not convert or map schema information, such as + * types or message definitions, from the WSDL. + *

+ * + *

WSDL to OpenAPI Mapping

+ * The transformer processes the following WSDL elements and maps them to the OpenAPI specification: + *
    + *
  • WSDL Bindings: Mapped to OpenAPI paths and operations. Each binding operation is + * converted into a corresponding POST operation in OpenAPI.
  • + *
  • WSDL Operation Name: The operation name in the WSDL is used as the operation ID + * in OpenAPI and forms part of the path in the OpenAPI specification.
  • + *
  • Binding Name: The binding name (for example, "SoapBinding") is used to tag the operation + * in the OpenAPI specification, allowing operations to be grouped logically by their binding.
  • + *
  • WSDL Documentation: If available, the documentation from the WSDL is extracted and used + * as the description for the OpenAPI operation. This provides human-readable documentation for + * each operation in the OpenAPI spec.
  • + *
+ *

+ * The following elements of the WSDL are not mapped to the OpenAPI specification: + *

    + *
  • WSDL Types and Schema: The schema and type definitions from the WSDL are not included in the + * resulting OpenAPI specification. This transformer focuses solely on operations, not data models.
  • + *
  • WSDL Messages: The message parts (input/output) associated with operations are not included + * in the OpenAPI output. This transformation only extracts the operations without message payload details.
  • + *
+ * + *

Usage Example

+ *
+ * {@code
+ * URI wsdlUri = new URI("http://example.com/my-service.wsdl");
+ * SimpleWsdlToOpenApiTransformer transformer = new SimpleWsdlToOpenApiTransformer(wsdlUri);
+ * String openApiYaml = transformer.transformToOpenApi();
+ * System.out.println(openApiYaml);
+ * }
+ * 
+ * + * @see io.swagger.v3.oas.models.OpenAPI + * @see io.swagger.v3.oas.models.Operation + * @see javax.wsdl.Definition + * @see javax.wsdl.Binding + * @see javax.wsdl.BindingOperation * - * Note that this transformer only transforms bindings from the wsdl into operations in the OpenApi. */ -public class SimpleWsdlToOpenApiTransformer { +public class WsdlToOpenApiTransformer { - private static final Logger logger = LoggerFactory.getLogger(SimpleWsdlToOpenApiTransformer.class); + private static final Logger logger = LoggerFactory.getLogger(WsdlToOpenApiTransformer.class); private static final YAMLMapper yamlMapper = (YAMLMapper) YAMLMapper.builder() .enable(SORT_PROPERTIES_ALPHABETICALLY) @@ -63,12 +107,12 @@ public class SimpleWsdlToOpenApiTransformer { private final URI wsdlUri; - public SimpleWsdlToOpenApiTransformer(URI wsdlUri) { + public WsdlToOpenApiTransformer(URI wsdlUri) { this.wsdlUri = wsdlUri; } /** - * Transforms the wsdl of this transfromer into a OpenApi yaml representation. + * Transforms the wsdl of this transformer into a OpenApi yaml representation. * * @return the OpenApi yaml * @throws WsdlToOpenApiTransformationException if the parsing fails @@ -149,7 +193,6 @@ private void addOperations(OpenAPI openApi, QName qName, Binding binding) { } else { bindingApiName = localPart; } - List bindingOperations = binding.getBindingOperations(); for (Object operation : bindingOperations) { if (operation instanceof BindingOperation bindingOperation) { @@ -157,21 +200,26 @@ private void addOperations(OpenAPI openApi, QName qName, Binding binding) { openApi.getPaths(), bindingOperation.getName(), retrieveOperationDescription(bindingOperation), + retrieveSoapAction(bindingOperation), bindingApiName ); } } } - private void addOperation(Paths paths, String name, String description, String tag) { + private void addOperation(Paths paths, String name, String description, String soapAction, String tag) { Operation postOperation = new Operation(); logger.debug("Adding operation to spec: {}", name); postOperation.setOperationId(name); postOperation.setDescription(description); + postOperation.setSummary(soapAction); postOperation.tags(Collections.singletonList(tag)); ApiResponses responses = new ApiResponses(); + ApiResponse apiResponse = new ApiResponse(); + apiResponse.setDescription("Generic Response"); + responses.addApiResponse("default", apiResponse); postOperation.responses(responses); PathItem pi = new PathItem(); @@ -184,16 +232,42 @@ private void addOperation(Paths paths, String name, String description, String t * Retrieve the description of the bindingOperation via the documentation of the associated operation. */ private String retrieveOperationDescription(BindingOperation bindingOperation) { - String description = ""; + StringBuilder description = new StringBuilder(); javax.wsdl.Operation soapOperation = bindingOperation.getOperation(); + Element documentationElement = bindingOperation.getDocumentationElement(); + if (documentationElement != null) { + String documentationText = documentationElement.getTextContent().trim(); + description.append(format("%s",documentationText)); + } + if (soapOperation != null) { - Element documentationElement = soapOperation.getDocumentationElement(); + documentationElement = soapOperation.getDocumentationElement(); if (documentationElement != null) { - description = documentationElement.getTextContent(); + String documentationText = documentationElement.getTextContent().trim(); + if (!description.isEmpty()) { + description.append(" "); + } + description.append(format("%s",documentationText)); + } + } + + return description.toString(); + } + + /** + * Retrieve the soap action. + */ + private String retrieveSoapAction(BindingOperation bindingOperation) { + String soapAction = ""; + + List extensibilityElements = bindingOperation.getExtensibilityElements(); + for (Object element : extensibilityElements) { + if (element instanceof SOAPOperation soapOperation) { + soapAction = soapOperation.getSoapActionURI(); } } - return description; + return soapAction; } private String convertToYaml(OpenAPI openAPI) throws JsonProcessingException { diff --git a/test-api-generator/citrus-test-api-generator-core/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig b/test-api-generator/citrus-test-api-generator-core/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig index 33a85c5059..b63055e186 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig +++ b/test-api-generator/citrus-test-api-generator-core/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig @@ -1 +1 @@ -org.citrusframework.openapi.generator.JavaCitrusCodegen \ No newline at end of file +org.citrusframework.openapi.generator.CitrusJavaCodegen \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/api-model.mustache b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/api-model.mustache deleted file mode 100644 index ae513df561..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/api-model.mustache +++ /dev/null @@ -1,2 +0,0 @@ -OperationId;Path;Method;Parameters{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}} -{{operationId}};{{path}};{{httpMethod}};{{#allParams}}{{paramName}}:{{{dataType}}}{{^-last}},{{/-last}}{{/allParams}}{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} 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 cb2473c14b..09618550e2 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 @@ -1,84 +1,615 @@ -{{>licenseInfo}} +{{! + Copyright the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +}} package {{package}}; +import static java.lang.String.format; +import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; +import static org.citrusframework.util.StringUtils.isEmpty; +import static org.citrusframework.util.StringUtils.isNotEmpty; + +import jakarta.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.net.URL; +import java.time.LocalDate; +import java.util.Base64; import java.util.HashMap; import java.util.Map; -import org.citrusframework.http.client.HttpClient; +import java.util.List; +import org.citrusframework.actions.ReceiveMessageAction; +import org.citrusframework.actions.SendMessageAction; +import org.citrusframework.endpoint.Endpoint; import org.citrusframework.openapi.OpenApiSpecification; -import org.citrusframework.openapi.generator.TestApiClientRequestActionBuilder; -import org.citrusframework.openapi.generator.rest.petstore.model.Pet; -import org.citrusframework.testapi.GeneratedApi; +import org.citrusframework.openapi.testapi.ApiActionBuilderCustomizer; +import org.citrusframework.openapi.testapi.ParameterStyle; +import {{requestBuilderClass}}; +import {{responseBuilderClass}}; +import org.citrusframework.openapi.testapi.TestApiUtils; +import org.citrusframework.spi.Resource; +import org.citrusframework.openapi.testapi.GeneratedApi; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; -import {{invokerPackage}}.citrus.{{prefix}}AbstractSendAction; +import {{invokerPackage}}.{{#lambda.titlecase}}{{prefix}}{{/lambda.titlecase}}; +{{#isRest}}import {{modelPackage}}.*;{{/isRest}} +@SuppressWarnings("unused") {{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{>xmlAnnotation}} public class {{classname}} implements GeneratedApi { - public static final {{classname}} INSTANCE = new {{classname}}(); + @Value("${" + "{{#lambda.lowercase}}{{prefix}}{{/lambda.lowercase}}.base64-encode-api-key:#{false}}") + private boolean base64EncodeApiKey; + {{#authMethods}} + {{#isBasicBasic}} + + @Value("${" + "{{#lambda.lowercase}}{{prefix}}{{/lambda.lowercase}}.basic.username:#{null}}") + private String basicUsername; + + @Value("${" + "{{#lambda.lowercase}}{{prefix}}{{/lambda.lowercase}}.basic.password:#{null}}") + private String basicPassword; + {{/isBasicBasic}} + {{#isBasicBearer}} + + @Value("${" + "{{#lambda.lowercase}}{{prefix}}{{/lambda.lowercase}}.bearer.token:#{null}}") + private String basicAuthBearer; + {{/isBasicBearer}} + {{#isApiKey}} + + @Value("${" + "{{#lambda.lowercase}}{{prefix}}{{/lambda.lowercase}}.{{#lambda.kebabcase}}{{keyParamName}}{{/lambda.kebabcase}}:#{null}}") + private String default{{#lambda.titlecase}}{{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}}{{/lambda.titlecase}}; + {{/isApiKey}} + {{/authMethods}} + + private final List customizers; + + private final Endpoint endpoint; + + private final OpenApiSpecification openApiSpecification; - private OpenApiSpecification openApiSpecification = null; + public {{classname}}(Endpoint endpoint) { + this(endpoint, emptyList()); + } + + public {{classname}}(Endpoint endpoint, List customizers) { + this.endpoint = endpoint; + this.customizers = customizers; + + URL resource = {{#lambda.titlecase}}{{prefix}}{{/lambda.titlecase}}.class.getResource("{{prefix}}_openApi.yaml"); + if (resource == null) { + throw new IllegalStateException(format("Cannot find resource '%s'. This resource is typically created during API generation and should therefore be present. Check API generation.", "{{prefix}}_openApi.yaml")); + } + openApiSpecification = OpenApiSpecification.from(resource); + } + + public static {{classname}} {{#lambda.camelcase}}{{classname}}{{/lambda.camelcase}}(Endpoint endpoint) { + return new {{classname}}(endpoint); + } + @Override public String getApiTitle() { - return "{{appName}}"; + return "{{appName}}"; } + @Override public String getApiVersion() { - return "{{appVersion}}"; + return "{{appVersion}}"; } + @Override public String getApiPrefix() { - return "{{prefix}}"; + return "{{prefix}}"; } - public Map getApiInfoExtensions() { + @Override + public Map getApiInfoExtensions() { + {{#infoExtensions}} Map infoExtensionMap = new HashMap<>(); - {{#infoExtensions}} - {{#entrySet}} + {{#entrySet}} infoExtensionMap.put("{{key}}", "{{value}}"); - {{/entrySet}} - {{/infoExtensions}} + {{/entrySet}} return infoExtensionMap; + {{/infoExtensions}} + {{^infoExtensions}} + return emptyMap(); + {{/infoExtensions}} + } + + @Override + public Endpoint getEndpoint() { + return endpoint; + } + + @Override + public List getCustomizers() { + return customizers; } {{#operations}} {{#operation}} - public {{operationIdCamelCase}}ActionBuilder {{operationId}}() { - return new {{operationIdCamelCase}}ActionBuilder(); - } + /** + * Builder with type safe required parameters. + */ + public {{operationIdCamelCase}}SendActionBuilder send{{operationIdCamelCase}}({{#requiredNonBodyParams}}{{{dataType}}} {{paramName}}{{^-last}}, {{/-last}}{{/requiredNonBodyParams}}) { + {{#authWithParameters}} + {{operationIdCamelCase}}SendActionBuilder builder = new {{operationIdCamelCase}}SendActionBuilder(this, openApiSpecification{{#requiredNonBodyParams}}, {{paramName}}{{/requiredNonBodyParams}}); + {{#hasApiKeyAuth}} + builder.setBase64EncodeApiKey(base64EncodeApiKey); + {{/hasApiKeyAuth}} + {{#isBasicBasic}} + builder.setBasicAuthUsername(basicUsername); + builder.setBasicAuthPassword(basicPassword); + {{/isBasicBasic}} + {{#isBasicBearer}} + builder.setBasicAuthBearer(basicAuthBearer); + {{/isBasicBearer}} + {{#isApiKey}} + builder.set{{#lambda.titlecase}}{{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}}{{/lambda.titlecase}}(default{{#lambda.titlecase}}{{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}}{{/lambda.titlecase}}); + {{/isApiKey}} + return builder; + {{/authWithParameters}} + {{^authWithParameters}} + return new {{operationIdCamelCase}}SendActionBuilder(this, openApiSpecification{{#requiredNonBodyParams}}, {{paramName}}{{/requiredNonBodyParams}}); + {{/authWithParameters}} + } + {{#needsConstructorWithAllStringParameter}} + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public {{operationIdCamelCase}}SendActionBuilder send{{operationIdCamelCase}}$({{#requiredNonBodyParams}}{{^isArray}}String {{paramName}}Expression{{/isArray}}{{#isArray}}List {{paramName}}Expression{{/isArray}}{{^-last}}, {{/-last}} {{/requiredNonBodyParams}}) { + {{#authWithParameters}} + {{operationIdCamelCase}}SendActionBuilder builder = new {{operationIdCamelCase}}SendActionBuilder(openApiSpecification, this{{#requiredNonBodyParams}}, {{paramName}}Expression{{/requiredNonBodyParams}}); + {{#hasApiKeyAuth}} + builder.setBase64EncodeApiKey(base64EncodeApiKey); + {{/hasApiKeyAuth}} + {{#authMethods}} + {{#isBasicBasic}} + builder.setBasicAuthUsername(basicUsername); + builder.setBasicAuthPassword(basicPassword); + {{/isBasicBasic}} + {{#isBasicBearer}} + builder.setBasicAuthBearer(basicAuthBearer); + {{/isBasicBearer}} + {{#isApiKey}} + builder.set{{#lambda.titlecase}}{{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}}{{/lambda.titlecase}}(default{{#lambda.titlecase}}{{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}}{{/lambda.titlecase}}); + {{/isApiKey}} + {{/authMethods}} + return builder; + {{/authWithParameters}} + {{^authWithParameters}} + return new {{operationIdCamelCase}}SendActionBuilder(openApiSpecification, this{{#requiredNonBodyParams}}, {{paramName}}Expression{{/requiredNonBodyParams}}); + {{/authWithParameters}} + } + {{/needsConstructorWithAllStringParameter}} + + public {{operationIdCamelCase}}ReceiveActionBuilder receive{{operationIdCamelCase}}(@NotNull HttpStatus statusCode) { + return new {{operationIdCamelCase}}ReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public {{operationIdCamelCase}}ReceiveActionBuilder receive{{operationIdCamelCase}}(@NotNull String statusCode) { + return new {{operationIdCamelCase}}ReceiveActionBuilder(this, openApiSpecification, statusCode); + } {{/operation}} {{/operations}} - {{#operations}} {{#operation}} - public class {{operationIdCamelCase}}ActionBuilder extends TestApiClientRequestActionBuilder { + public static class {{operationIdCamelCase}}SendActionBuilder extends + {{requestBuilderClassName}} { - private static final String METHOD = "{{httpMethod}}"; + private static final String METHOD = "{{httpMethod}}"; - private static final String ENDPOINT = "{{path}}"; + private static final String ENDPOINT = "{{basePath}}{{path}}"; - private static final String OPERATION_NAME = "{{operationId}}"; + private static final String OPERATION_NAME = "{{operationId}}"; + {{#hasApiKeyAuth}} - public AddPetActionBuilder() { - super(openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); - } + @Value("${" + "{{#lambda.lowercase}}{{prefix}}{{/lambda.lowercase}}.base64-encode-api-key:#{false}}") + private boolean base64EncodeApiKey; + {{/hasApiKeyAuth}} + {{#authMethods}} + {{#isBasicBasic}} + + @Value("${" + "{{#lambda.lowercase}}{{prefix}}{{/lambda.lowercase}}.basic.username:#{null}}") + private String defaultBasicUsername; + + private String basicUsername; + + @Value("${" + "{{#lambda.lowercase}}{{prefix}}{{/lambda.lowercase}}.basic.password:#{null}}") + private String defaultBasicPassword; + + private String basicPassword; + {{/isBasicBasic}} + {{#isBasicBearer}} + + @Value("${" + "{{#lambda.lowercase}}{{prefix}}{{/lambda.lowercase}}.bearer.token:#{null}}") + private String defaultBasicAuthBearer; + + private String basicAuthBearer; + {{/isBasicBearer}} + {{#isApiKey}} + + @Value("${" + "{{#lambda.lowercase}}{{prefix}}{{/lambda.lowercase}}.{{#lambda.kebabcase}}{{keyParamName}}{{/lambda.kebabcase}}:#{null}}") + private String default{{#lambda.titlecase}}{{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}}{{/lambda.titlecase}}; + + private String {{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}}; + {{/isApiKey}} + {{/authMethods}} + + /** + * Constructor with type safe required parameters. + */ + public {{operationIdCamelCase}}SendActionBuilder({{classname}} {{#lambda.camelcase}}{{classname}}{{/lambda.camelcase}}, OpenApiSpecification openApiSpecification{{#requiredNonBodyParams}}, {{{dataType}}} {{paramName}}{{/requiredNonBodyParams}}) { + super({{#lambda.camelcase}}{{classname}}{{/lambda.camelcase}}, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + {{#requiredNonBodyParams}} + {{#isQueryParam}} + queryParameter("{{baseName}}", {{paramName}}, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isQueryParam}} + {{#isPathParam}} + pathParameter("{{baseName}}", {{paramName}}, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isPathParam}} + {{#isHeaderParam}} + headerParameter("{{baseName}}", {{paramName}}, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isHeaderParam}} + {{#isFormParam}} + formParameter("{{baseName}}", {{#isBinary}}toBinary({{paramName}}){{/isBinary}} {{^isBinary}}{{paramName}}{{/isBinary}}); + {{/isFormParam}} + {{#isCookieParam}} + cookieParameter("{{baseName}}", {{paramName}}, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isCookieParam}} + {{/requiredNonBodyParams}} + } + {{#needsConstructorWithAllStringParameter}} + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + {{! + Note that the change in the order of parameters is intentional to be able to differentiate + constructors with Collections parameters which would otherwise have the same erasure type. + }} + public {{operationIdCamelCase}}SendActionBuilder(OpenApiSpecification openApiSpecification, {{classname}} {{#lambda.camelcase}}{{classname}}{{/lambda.camelcase}}{{#requiredNonBodyParams}}, {{^isArray}}String {{paramName}}Expression{{/isArray}}{{#isArray}}List {{paramName}}Expression{{/isArray}}{{/requiredNonBodyParams}}) { + super({{#lambda.camelcase}}{{classname}}{{/lambda.camelcase}}, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + {{#requiredNonBodyParams}} + {{#isQueryParam}} + queryParameter("{{baseName}}", {{paramName}}Expression, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isQueryParam}} + {{#isPathParam}} + pathParameter("{{baseName}}", {{paramName}}Expression, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isPathParam}} + {{#isHeaderParam}} + headerParameter("{{baseName}}", {{paramName}}Expression, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isHeaderParam}} + {{#isFormParam}} + formParameter("{{baseName}}", {{#isBinary}}toBinary({{paramName}}Expression){{/isBinary}} {{^isBinary}}{{paramName}}Expression{{/isBinary}}); + {{/isFormParam}} + {{#isCookieParam}} + cookieParameter("{{baseName}}", {{paramName}}Expression, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isCookieParam}} + {{/requiredNonBodyParams}} + } + {{/needsConstructorWithAllStringParameter}} + + {{#requiredNonBodyParams}} + {{#-first}} + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + {{/-first}} + {{/requiredNonBodyParams}} + public {{operationIdCamelCase}}SendActionBuilder({{classname}} {{#lambda.camelcase}}{{classname}}{{/lambda.camelcase}}, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder{{#requiredNonBodyParams}}, {{^isArray}}String {{paramName}}Expression{{/isArray}}{{#isArray}}List {{paramName}}{{/isArray}}{{/requiredNonBodyParams}}) { + super({{#lambda.camelcase}}{{classname}}{{/lambda.camelcase}}, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + {{#requiredNonBodyParams}} + {{#isQueryParam}} + queryParameter("{{baseName}}", {{paramName}}{{^isArray}}Expression{{/isArray}}, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isQueryParam}} + {{#isPathParam}} + pathParameter("{{baseName}}", {{paramName}}{{^isArray}}Expression{{/isArray}}, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isPathParam}} + {{#isHeaderParam}} + headerParameter("{{baseName}}", {{paramName}}{{^isArray}}Expression{{/isArray}}, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isHeaderParam}} + {{#isFormParam}} + formParameter("{{baseName}}", {{#isBinary}}toBinary({{paramName}}{{^isArray}}Expression{{/isArray}}){{/isBinary}} {{^isBinary}}{{paramName}}{{^isArray}}Expression{{/isArray}}{{/isBinary}}); + {{/isFormParam}} + {{#isCookieParam}} + cookieParameter("{{baseName}}", {{paramName}}{{^isArray}}Expression{{/isArray}}, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isCookieParam}} + {{/requiredNonBodyParams}} + } + {{#requiredNonBodyParams}} - {{#queryParams}} - public {{operationIdCamelCase}}ActionBuilder with{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}(String {{paramName}}) { - queryParam("{{paramName}}", {{paramName}}); - return this; + {{! + Type safe setting of parameter, using builder pattern. + }} + public {{operationIdCamelCase}}SendActionBuilder {{paramName}}({{#isArray}}{{baseType}}...{{/isArray}}{{^isArray}}{{dataType}} {{/isArray}}{{paramName}}) { + {{#isQueryParam}} + queryParameter("{{baseName}}", {{paramName}}, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isQueryParam}} + {{#isPathParam}} + pathParameter("{{baseName}}", {{paramName}}, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isPathParam}} + {{#isHeaderParam}} + headerParameter("{{baseName}}", {{paramName}}, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isHeaderParam}} + {{#isFormParam}} + formParameter("{{baseName}}", {{#isBinary}}toBinary({{paramName}}){{/isBinary}} {{^isBinary}}{{paramName}}{{/isBinary}}); + {{/isFormParam}} + {{#isCookieParam}} + cookieParameter("{{baseName}}", {{paramName}}, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isCookieParam}} + return this; + } + {{^isBaseTypeString}} + + {{! + Non type safe setting of parameter, using builder pattern. + }} + public {{operationIdCamelCase}}SendActionBuilder {{paramName}}(String{{#isArray}}...{{/isArray}}{{^isArray}} {{/isArray}}{{paramName}}Expression) { + {{#isQueryParam}} + queryParameter("{{baseName}}", {{paramName}}Expression, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isQueryParam}} + {{#isPathParam}} + pathParameter("{{baseName}}", {{paramName}}Expression, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isPathParam}} + {{#isHeaderParam}} + headerParameter("{{baseName}}", {{paramName}}Expression, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isHeaderParam}} + {{#isFormParam}} + formParameter("{{baseName}}", {{#isBinary}}toBinary({{paramName}}Expression){{/isBinary}} {{^isBinary}}{{paramName}}Expression{{/isBinary}}); + {{/isFormParam}} + {{#isCookieParam}} + cookieParameter("{{baseName}}", {{paramName}}Expression, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isCookieParam}} + return this; + } + {{/isBaseTypeString}} + {{/requiredNonBodyParams}} + {{#optionalParams}} + + {{! + Type safe setting of the parameter value. + Depending on the parameter type (query, path, header, form, or cookie), + the appropriate method is invoked to set the parameter. + }} + public {{operationIdCamelCase}}SendActionBuilder {{paramName}}({{#isArray}}{{baseType}}...{{/isArray}}{{^isArray}}{{dataType}} {{/isArray}}{{paramName}}) { + {{#isQueryParam}} + queryParameter("{{baseName}}", {{paramName}}, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isQueryParam}} + {{#isPathParam}} + pathParameter("{{baseName}}", {{paramName}}, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isPathParam}} + {{#isHeaderParam}} + headerParameter("{{baseName}}", {{paramName}}, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isHeaderParam}} + {{#isFormParam}} + formParameter("{{baseName}}", {{#isBinary}}toBinary({{paramName}}){{/isBinary}} {{^isBinary}}{{paramName}}{{/isBinary}}); + {{/isFormParam}} + {{#isCookieParam}} + cookieParameter("{{baseName}}", {{paramName}}, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isCookieParam}} + return this; + } + + {{! + Type safe setting of the parameter value. + These setters are used by SendApiRequestActionParser and ReceiveApiResponseActionParser + to inject attributes into the request or response. + Depending on the parameter type (query, path, header, form, or cookie), + the appropriate method is invoked to set the parameter. + }} + public void set{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}({{#isArray}}{{baseType}}...{{/isArray}}{{^isArray}}{{dataType}} {{/isArray}}{{paramName}}) { + {{#isQueryParam}} + queryParameter("{{baseName}}", {{paramName}}, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isQueryParam}} + {{#isPathParam}} + pathParameter("{{baseName}}", {{paramName}}); + {{/isPathParam}} + {{#isHeaderParam}} + headerParameter("{{baseName}}", {{paramName}}, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isHeaderParam}} + {{#isFormParam}} + formParameter("{{baseName}}", {{#isBinary}}toBinary({{paramName}}){{/isBinary}} {{^isBinary}}{{paramName}}{{/isBinary}}); + {{/isFormParam}} + {{#isCookieParam}} + cookieParameter("{{baseName}}", {{paramName}}, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isCookieParam}} + } + {{^isBaseTypeString}} + + {{! + Configures a request action by setting the value of a parameter + (query, path, header, form, or cookie) as a dynamic string expression, + supporting citrus variables. This method handles different parameter types + based on the context and updates the respective parameter accordingly. + Supports arrays if the parameter is marked as such. + }} + public {{operationIdCamelCase}}SendActionBuilder {{paramName}}(String{{#isArray}}...{{/isArray}}{{^isArray}} {{/isArray}}{{paramName}}Expression) { + {{#isQueryParam}} + queryParameter("{{baseName}}", {{paramName}}Expression, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isQueryParam}} + {{#isPathParam}} + pathParameter("{{baseName}}", {{paramName}}Expression); + {{/isPathParam}} + {{#isHeaderParam}} + headerParameter("{{baseName}}", {{paramName}}Expression, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isHeaderParam}} + {{#isFormParam}} + formParameter("{{baseName}}", {{#isBinary}}toBinary({{paramName}}Expression){{/isBinary}} {{^isBinary}}{{paramName}}Expression{{/isBinary}}); + {{/isFormParam}} + {{#isCookieParam}} + cookieParameter("{{baseName}}", {{paramName}}Expression, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isCookieParam}} + return this; + } + + {{! + Sets the value of the parameter as a string expression. + These setters are used by SendApiRequestActionParser and ReceiveApiResponseActionParser + to inject attributes into the request or response. + Depending on the parameter type (query, path, header, form, or cookie), + the appropriate method is invoked to set the parameter. + If the parameter is marked as an array, multiple values are supported. + }} + public void set{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}(String{{#isArray}}...{{/isArray}}{{^isArray}} {{/isArray}}{{paramName}}Expression) { + {{#isQueryParam}} + queryParameter("{{baseName}}", {{paramName}}Expression, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isQueryParam}} + {{#isPathParam}} + pathParameter("{{baseName}}", {{paramName}}Expression); + {{/isPathParam}} + {{#isHeaderParam}} + headerParameter("{{baseName}}", {{paramName}}Expression, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isHeaderParam}} + {{#isFormParam}} + formParameter("{{baseName}}", {{#isBinary}}toBinary({{paramName}}Expression){{/isBinary}} {{^isBinary}}{{paramName}}Expression{{/isBinary}}); + {{/isFormParam}} + {{#isCookieParam}} + cookieParameter("{{baseName}}", {{paramName}}Expression, ParameterStyle.{{#lambda.uppercase}}{{style}}{{/lambda.uppercase}}, {{isExplode}}, {{schema.isModel}}); + {{/isCookieParam}} + } + {{/isBaseTypeString}} + {{/optionalParams}} + {{#hasApiKeyAuth}} + + public void setBase64EncodeApiKey(boolean encode) { + this.base64EncodeApiKey = encode; + } + {{/hasApiKeyAuth}} + {{#authMethods}} + {{#isBasicBasic}} + + public {{operationIdCamelCase}}SendActionBuilder basicAuthUsername(String basicUsername) { + this.basicUsername = basicUsername; + return this; + } + + public void setBasicAuthUsername(String basicUsername) { + this.basicUsername = basicUsername; + } + + public {{operationIdCamelCase}}SendActionBuilder basicAuthPassword(String password) { + this.basicPassword = password; + return this; + } + + public void setBasicAuthPassword(String password) { + this.basicPassword = password; + } + + protected void addBasicAuthHeader(String basicUsername, String basicPassword, + HttpMessageBuilderSupport messageBuilderSupport) { + TestApiUtils.addBasicAuthHeader( + isNotEmpty(basicUsername) ? basicUsername : defaultBasicUsername, + isNotEmpty(basicPassword) ? basicPassword : defaultBasicPassword, + messageBuilderSupport); + } + {{/isBasicBasic}} + {{#isBasicBearer}} + + public {{operationIdCamelCase}}SendActionBuilder basicAuthBearer(String basicAuthBearer) { + this.basicAuthBearer = basicAuthBearer; + return this; + } + + public void setBasicAuthBearer(String basicAuthBearer) { + this.basicAuthBearer = basicAuthBearer; + } + {{/isBasicBearer}} + {{#isApiKey}} + + public {{operationIdCamelCase}}SendActionBuilder {{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}}(String {{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}}) { + this.{{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}} = {{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}}; + return this; + } + + public void set{{#lambda.titlecase}}{{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}}{{/lambda.titlecase}}(String {{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}}) { + this.{{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}} = {{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}}; + } + {{/isApiKey}} + {{/authMethods}} + + @Override + public SendMessageAction doBuild() { + {{#authMethods}} + {{#isBasicBasic}} + addBasicAuthHeader(basicUsername, basicPassword, getMessageBuilderSupport()); + {{/isBasicBasic}} + {{#isBasicBearer}} + if (!isEmpty(basicAuthBearer) || !isEmpty(defaultBasicAuthBearer)) { + headerParameter("Authorization", "Bearer " +getOrDefault(basicAuthBearer, defaultBasicAuthBearer, true)); + } + {{/isBasicBearer}} + {{/authMethods}} + {{#authMethods}} + {{#isApiKey}} + {{#isKeyInHeader}} + headerParameter("{{keyParamName}}", getOrDefault({{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}}, default{{#lambda.titlecase}}{{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}}{{/lambda.titlecase}}, base64EncodeApiKey)); + {{/isKeyInHeader}} + {{#isKeyInQuery}} + queryParameter("{{keyParamName}}", getOrDefault({{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}}, default{{#lambda.titlecase}}{{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}}{{/lambda.titlecase}}, base64EncodeApiKey)); + {{/isKeyInQuery}} + {{#isKeyInCookie}} + cookieParameter("{{keyParamName}}", getOrDefault({{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}}, default{{#lambda.titlecase}}{{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}}{{/lambda.titlecase}}, base64EncodeApiKey)); + {{/isKeyInCookie}} + {{/isApiKey}} + {{/authMethods}} + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } } - {{/queryParams}} - // public AddPetActionBuilder withPet(Pet pet) { - // // TODO: fix this - // getMessageBuilderSupport().body(pet.toString()); - // return this; - // } + public static class {{operationIdCamelCase}}ReceiveActionBuilder extends + {{responseBuilderClassName}} { + + private static final String METHOD = "{{httpMethod}}"; + + private static final String ENDPOINT = "{{basePath}}{{path}}"; + + private static final String OPERATION_NAME = "{{operationId}}"; + + public {{operationIdCamelCase}}ReceiveActionBuilder({{classname}} {{#lambda.camelcase}}{{classname}}{{/lambda.camelcase}}, OpenApiSpecification openApiSpecification, String statusCode) { + super({{#lambda.camelcase}}{{classname}}{{/lambda.camelcase}}, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public {{operationIdCamelCase}}ReceiveActionBuilder({{classname}} {{#lambda.camelcase}}{{classname}}{{/lambda.camelcase}}, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super({{#lambda.camelcase}}{{classname}}{{/lambda.camelcase}}, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } } + {{^-last}} + + {{/-last}} {{/operation}} {{/operations}} } \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/api_locator.mustache b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/api_locator.mustache new file mode 100644 index 0000000000..8155517939 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/api_locator.mustache @@ -0,0 +1,28 @@ +{{! + + Copyright the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +}} +package {{invokerPackage}}; + +import java.net.URL; + +public class {{#lambda.titlecase}}{{prefix}}{{/lambda.titlecase}} { + + public static URL {{#lambda.camelcase}}{{prefix}}{{/lambda.camelcase}}Api() { + return {{#lambda.titlecase}}{{prefix}}{{/lambda.titlecase}}.class.getResource("{{prefix}}_openApi.yaml"); + } + +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/api_old.mustache b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/api_old.mustache deleted file mode 100644 index a023345fb7..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/api_old.mustache +++ /dev/null @@ -1,259 +0,0 @@ -{{>licenseInfo}} - -package {{package}}; - -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 {{invokerPackage}}.citrus.{{prefix}}AbstractTestRequest; - -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; - -{{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{>xmlAnnotation}} -public class {{classname}} implements GeneratedApi -{ - - public static final {{classname}} INSTANCE = new {{classname}}(); - - public String getApiTitle() { - return "{{appName}}"; - } - - public String getApiVersion() { - return "{{appVersion}}"; - } - - public String getApiPrefix() { - return "{{prefix}}"; - } - - public Map getApiInfoExtensions() { - Map infoExtensionMap = new HashMap<>(); - {{#infoExtensions}} - {{#entrySet}} - infoExtensionMap.put("{{key}}", "{{value}}"); - {{/entrySet}} - {{/infoExtensions}} - return infoExtensionMap; - } - - {{#operations}} - {{#operation}} - /** {{operationId}} ({{httpMethod}} {{httpPathPrefix}}{{{path}}}) - {{summary}} - {{description}} - **/ - public static class {{operationIdCamelCase}}Request extends {{prefix}}AbstractTestRequest implements GeneratedApiRequest { - - private static final String ENDPOINT = "{{httpPathPrefix}}{{{path}}}"; - private final Logger coverageLogger = LoggerFactory.getLogger({{operationIdCamelCase}}Request.class); - - {{#queryParams}} - private String {{paramName}}; - - {{/queryParams}} - {{#pathParams}} - private String {{paramName}}; - - {{/pathParams}} - {{#isMultipart}} - {{#formParams}} - private String {{paramName}}; - - {{/formParams}} - {{/isMultipart}} - {{#authMethods}}{{#isBasic}} - @Value("${" + "{{apiEndpoint}}.basic.username:#{null}}") - private String basicUsername; - @Value("${" + "{{apiEndpoint}}.basic.password:#{null}}") - private String basicPassword; - - {{/isBasic}} - {{/authMethods}} - - public {{operationIdCamelCase}}Request() { - // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml - setName("{{prefix}}".toLowerCase() + ":{{operationId}}RequestType"); - } - - public String getOperationName() { - return "{{operationId}}"; - } - - public String getMethod() { - return "{{httpMethod}}"; - } - - public String getPath() { - return "{{path}}"; - } - - /** - * This method sends the HTTP-Request - */ - public void sendRequest(TestContext context) { - HttpClientRequestActionBuilder httpClientRequestActionBuilder = new HttpActionBuilder().client(httpClient).send() - .{{#lambda.lowercase}}{{httpMethod}}{{/lambda.lowercase}}(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 = ""; - {{#isMultipart}} - MultiValueMap multiValues = new LinkedMultiValueMap<>(); - {{#formParams}} - {{#required}} - if(StringUtils.isBlank({{paramName}})) { - throw new CitrusRuntimeException(String.format("Required attribute '%s' is not specified", "{{paramName}}")); - } - {{/required}} - {{#isBinary}} - if (StringUtils.isNotBlank({{paramName}})) { - multiValues.add("{{paramName}}", new ClassPathResource({{paramName}})); - bodyLog += {{paramName}}.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") +","; - } - {{/isBinary}} - {{^isBinary}} - if (StringUtils.isNotBlank({{paramName}})) { - // first try to load from resource - ClassPathResource resource = null; - try { - resource = new ClassPathResource({{paramName}}); - } - catch(Exception ignore) { - // Use plain text instead of resource - } - - if(resource != null && resource.exists()){ - multiValues.add("{{paramName}}", resource); - } else { - multiValues.add("{{paramName}}", {{paramName}}); - } - bodyLog += {{paramName}}.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") +","; - } - {{/isBinary}} - {{/formParams}} - - bodyLog += "\";\"" + MediaType.MULTIPART_FORM_DATA_VALUE + "\""; - messageBuilderSupport.contentType(MediaType.MULTIPART_FORM_DATA_VALUE) - .body(multiValues); - - {{/isMultipart}} - {{^isMultipart}} - 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 + "\""; - {{/isMultipart}} - - Map queryParams = new HashMap<>(); - {{#allParams}}{{#isQueryParam}} - - if (StringUtils.isNotBlank(this.{{paramName}})) { - queryParams.put("{{baseName}}", context.replaceDynamicContentInString(this.{{paramName}})); - httpClientRequestActionBuilder.queryParam("{{baseName}}", this.{{paramName}}); - } - {{/isQueryParam}}{{/allParams}} - String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); - {{#authMethods}}{{#isBasic}} - - if(basicUsername != null && basicPassword != null){ - messageBuilderSupport.header("Authorization", "Basic " + Base64.getEncoder().encodeToString((context.replaceDynamicContentInString(basicUsername)+":"+context.replaceDynamicContentInString(basicPassword)).getBytes())); - } - {{/isBasic}}{{/authMethods}} - httpClientRequestActionBuilder.withReferenceResolver(context.getReferenceResolver()); - httpClientRequestActionBuilder = customizeBuilder(INSTANCE, context, httpClientRequestActionBuilder); - - httpClientRequestActionBuilder.build().execute(context); - - coverageLogger.trace(coverageMarker, "{{operationId}};{{#lambda.uppercase}}{{httpMethod}}{{/lambda.uppercase}};\"" + - query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + - bodyLog); - } - {{#queryParams}} - - public void set{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}(String {{paramName}}) { - this.{{paramName}} = {{paramName}}; - } - {{/queryParams}} - {{#pathParams}} - - public void set{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}(String {{paramName}}) { - this.{{paramName}} = {{paramName}}; - } - {{/pathParams}} - {{#isMultipart}} - {{#formParams}} - - public void set{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}(String {{paramName}}) { - this.{{paramName}} = {{paramName}}; - } - {{/formParams}} - {{/isMultipart}} - {{#authMethods}}{{#isBasic}} - - public void setBasicUsername(String basicUsername) { - this.basicUsername = basicUsername; - } - - public void setBasicPassword(String basicPassword) { - this.basicPassword = basicPassword; - } - {{/isBasic}}{{/authMethods}} - private String replacePathParams(String endpoint) { - {{#pathParams}}endpoint = endpoint.replace("{" + "{{baseName}}" + "}", {{paramName}});{{/pathParams}} - return endpoint; - } - } - {{/operation}} - {{/operations}} -} diff --git a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/api_soap.mustache b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/api_soap.mustache index ba2f8d48a6..4371a2a3bb 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/api_soap.mustache +++ b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/api_soap.mustache @@ -1,160 +1,152 @@ -{{>licenseInfo}} +{{! + Copyright the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +}} package {{package}}; -import java.io.IOException; +import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; + import java.util.HashMap; +import java.util.List; 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.ReceiveSoapMessageAction; 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 {{invokerPackage}}.citrus.{{prefix}}AbstractTestRequest; +import org.citrusframework.endpoint.Endpoint; +import org.citrusframework.openapi.testapi.ApiActionBuilderCustomizer; +import org.citrusframework.openapi.testapi.GeneratedApi; +import org.citrusframework.openapi.testapi.SoapApiReceiveMessageActionBuilder; +import org.citrusframework.openapi.testapi.SoapApiSendMessageActionBuilder; +@SuppressWarnings("unused") {{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{>xmlAnnotation}} public class {{classname}} implements GeneratedApi { - public static final {{classname}} INSTANCE = new {{classname}}(); + private final Endpoint endpoint; + + private final List customizers; + + public {{classname}}(Endpoint endpoint) { + this(endpoint, emptyList()); + } + + public {{classname}}(Endpoint endpoint, List customizers) { + this.endpoint = endpoint; + this.customizers = customizers; + } + + public static {{classname}} {{#lambda.camelcase}}{{classname}}{{/lambda.camelcase}}(Endpoint endpoint) { + return new {{classname}}(endpoint); + } + + @Override public String getApiTitle() { return "{{appName}}"; } + @Override public String getApiVersion() { return "{{appVersion}}"; } + @Override public String getApiPrefix() { return "{{prefix}}"; } - public Map getApiInfoExtensions() { - Map infoExtensionMap = new HashMap<>(); - {{#infoExtensions}} - {{#entrySet}} + @Override + public Map getApiInfoExtensions() { + {{#infoExtensions}} + Map infoExtensionMap = new HashMap<>(); + {{#entrySet}} infoExtensionMap.put("{{key}}", "{{value}}"); - {{/entrySet}} - {{/infoExtensions}} - return infoExtensionMap; + {{/entrySet}} + return infoExtensionMap; + {{/infoExtensions}} + {{^infoExtensions}} + return emptyMap(); + {{/infoExtensions}} } - {{#operations}} + @Override + public Endpoint getEndpoint() { + return endpoint; + } + + @Override + public List getCustomizers() { + return customizers; + } + +{{#operations}} {{#operation}} - /** - {{operationId}} ({{httpMethod}} {{httpPathPrefix}}{{{path}}}) - {{summary}} - {{description}} - **/ - public static class {{operationIdCamelCase}}Request extends {{prefix}}AbstractTestRequest implements GeneratedApiRequest { - - private final Logger coverageLogger = LoggerFactory.getLogger({{operationIdCamelCase}}Request.class); - - // Query params - {{#allParams}}{{#isQueryParam}}private String {{paramName}}; - {{/isQueryParam}}{{/allParams}} - - public {{operationIdCamelCase}}Request(){ - // The name will be overwritten with the tag name using the actual namespace as prefix, when the class is loaded from xml - setName("{{prefix}}".toLowerCase() + ":{{operationId}}RequestType"); - } + public {{operationIdCamelCase}}SendActionBuilder send{{operationIdCamelCase}}({{#requiredNonBodyParams}}{{{dataType}}} {{paramName}}{{^-last}}, {{/-last}}{{/requiredNonBodyParams}}) { + return new {{operationIdCamelCase}}SendActionBuilder(this); + } - public String getOperationName() { - return "{{operationId}}"; - } + public {{operationIdCamelCase}}ReceiveActionBuilder receive{{operationIdCamelCase}}() { + return new {{operationIdCamelCase}}ReceiveActionBuilder(this); + } - public String getMethod() { - return "{{httpMethod}}"; - } + {{/operation}} +{{/operations}} +{{#operations}} + {{#operation}} + public static class {{operationIdCamelCase}}SendActionBuilder extends {{requestBuilderClassName}} { + + private static final String SOAP_ACTION = "{{summary}}"; - public String getPath() { - return "{{path}}"; + public {{operationIdCamelCase}}SendActionBuilder({{classname}} {{#lambda.camelcase}}{{classname}}{{/lambda.camelcase}}) { + super({{#lambda.camelcase}}{{classname}}{{/lambda.camelcase}}, SOAP_ACTION); } - /** - * 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("{{operationId}}"); - - 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); - } + @Override + public SendSoapMessageAction doBuild() { - if (!CollectionUtils.isEmpty(soapHeaders)) { - for (Entry entry : soapHeaders.entrySet()) { - messageBuilderSupport = messageBuilderSupport.header(entry.getKey(), - entry.getValue()); - } + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); } - if (!CollectionUtils.isEmpty(mimeHeaders)) { - for (Entry entry : mimeHeaders.entrySet()) { - messageBuilderSupport = messageBuilderSupport.header("citrus_http_" + entry.getKey(), - entry.getValue()); - } - } - - Map queryParams = new HashMap<>(); - {{#allParams}}{{#isQueryParam}} - if (StringUtils.isNotBlank(this.{{paramName}})) { - queryParams.put("{{baseName}}", context.replaceDynamicContentInString(this.{{paramName}})); - sendSoapMessageActionBuilder.queryParam("{{baseName}}", this.{{paramName}}); - } - {{/isQueryParam}}{{/allParams}} - String query = queryParams.entrySet().stream().map(e -> "\"" + e.getKey() + "\":\"" + e.getValue() + "\"").collect(Collectors.joining(",", "{", "}")); + return super.doBuild(); + } + } - soapSendMessageActionBuilder.withReferenceResolver(context.getReferenceResolver()); - soapSendMessageActionBuilder = customizeBuilder(INSTANCE, context, soapSendMessageActionBuilder); + public static class {{operationIdCamelCase}}ReceiveActionBuilder extends {{responseBuilderClassName}} { - soapSendMessageActionBuilder.build().execute(context); + private static final String SOAP_ACTION = "{{summary}}"; - coverageLogger.trace(coverageMarker, "{{operationId}};{{#lambda.uppercase}}{{httpMethod}}{{/lambda.uppercase}};\"" + - query.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + - body.replace("\n", "\\n").replace("\r", "\\r").replace("\"", "\"\"") + "\";\"" + bodyType + "\""); + public {{operationIdCamelCase}}ReceiveActionBuilder({{classname}} {{#lambda.camelcase}}{{classname}}{{/lambda.camelcase}}) { + super({{#lambda.camelcase}}{{classname}}{{/lambda.camelcase}}, SOAP_ACTION); } - {{#allParams}}{{#isQueryParam}} - public void set{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}(String {{paramName}}) { - this.{{paramName}} = {{paramName}}; + @Override + public ReceiveSoapMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); } - {{/isQueryParam}}{{/allParams}} + } + {{^-last}} + + {{/-last}} {{/operation}} - {{/operations}} +{{/operations}} } diff --git a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/bean_configuration.mustache b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/bean_configuration.mustache index 7bf35af55f..a9b329dba5 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/bean_configuration.mustache +++ b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/bean_configuration.mustache @@ -1,33 +1,58 @@ -{{>licenseInfo}} +{{! -package {{invokerPackage}}.spring; + Copyright the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at -import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE; + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +}} +package {{invokerPackage}}.spring; + +import java.util.List; +import org.citrusframework.endpoint.Endpoint; +import org.citrusframework.openapi.OpenApiRepository; +import org.citrusframework.openapi.OpenApiSpecification; +import org.citrusframework.openapi.testapi.ApiActionBuilderCustomizer; {{#apiInfo}} {{#apis}} import {{package}}.{{classname}}; {{/apis}} {{/apiInfo}} +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Scope; +import {{invokerPackage}}.{{#lambda.titlecase}}{{prefix}}{{/lambda.titlecase}}; + @Configuration {{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{>xmlAnnotation}} -public class {{prefix}}BeanConfiguration { -{{#apiInfo}} - {{#apis}} - {{#operations}} - {{#operation}} +public class {{#lambda.titlecase}}{{prefix}}{{/lambda.titlecase}}BeanConfiguration { @Bean - @Scope(SCOPE_PROTOTYPE) - public {{classname}}.{{operationIdCamelCase}}Request {{operationId}}Request() { - return new {{classname}}.{{operationIdCamelCase}}Request(); + public OpenApiRepository {{#lambda.camelcase}}{{prefix}}{{/lambda.camelcase}}OpenApiRepository() { + var openApiRepository = new OpenApiRepository(); + openApiRepository.getOpenApiSpecifications().add(OpenApiSpecification.from( + {{#lambda.titlecase}}{{prefix}}{{/lambda.titlecase}}.{{#lambda.camelcase}}{{prefix}}{{/lambda.camelcase}}Api())); + return openApiRepository; + } + +{{#apiInfo}} + {{#apis}} + @Bean(name="{{classname}}") + public {{classname}} {{#lambda.camelcase}}{{classname}}{{/lambda.camelcase}}(@Qualifier("{{apiEndpoint}}") Endpoint endpoint, @Autowired(required = false) List customizers) { + return new {{classname}}(endpoint, customizers); } - {{/operation}} - {{/operations}} + {{/apis}} {{/apiInfo}} } diff --git a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/bean_definition_parser.mustache b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/bean_definition_parser.mustache deleted file mode 100644 index 01e502f284..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/bean_definition_parser.mustache +++ /dev/null @@ -1,205 +0,0 @@ -{{>licenseInfo}} - -package {{invokerPackage}}.citrus; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.lang3.StringUtils; -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.springframework.util.xml.DomUtils; -import org.w3c.dom.Attr; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; - -{{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{>xmlAnnotation}} -public class {{prefix}}BeanDefinitionParser 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 {{prefix}}BeanDefinitionParser(Class beanClass) { - this.beanClass = beanClass; - } - - public BeanDefinition parse(Element element) { - return parse(element, null); - } - - /** - * Note: The {@link {{prefix}}BeanDefinitionParser#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/main/resources/java-citrus/namespace_handler.mustache b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/namespace_handler.mustache index 8ca4a446da..27fe698993 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/namespace_handler.mustache +++ b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/namespace_handler.mustache @@ -1,18 +1,47 @@ -{{>licenseInfo}} +{{! -package {{invokerPackage}}.citrus.extension; + Copyright the original author or authors. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +}} +package {{invokerPackage}}.spring; + +import org.citrusframework.openapi.OpenApiSpecification; +import org.citrusframework.openapi.testapi.RestApiSendMessageActionBuilder; +import org.citrusframework.openapi.testapi.RestApiReceiveMessageActionBuilder; {{#apiInfo}} {{#apis}} import {{package}}.{{classname}}; {{/apis}} {{/apiInfo}} -import {{invokerPackage}}.citrus.{{prefix}}BeanDefinitionParser; - +import org.citrusframework.openapi.testapi.spring.RestApiReceiveMessageActionParser; +import org.citrusframework.openapi.testapi.spring.RestApiSendMessageActionParser; +import {{invokerPackage}}.{{#lambda.titlecase}}{{prefix}}{{/lambda.titlecase}}; +import org.citrusframework.openapi.testapi.GeneratedApi; import org.springframework.beans.factory.xml.NamespaceHandlerSupport; {{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{>xmlAnnotation}} -public class {{prefix}}NamespaceHandler extends NamespaceHandlerSupport { +public class {{#lambda.titlecase}}{{prefix}}{{/lambda.titlecase}}NamespaceHandler extends NamespaceHandlerSupport { + + {{#apiInfo}} + {{#apis}} + {{#-first}} + private final OpenApiSpecification openApiSpecification = OpenApiSpecification.from( + {{#lambda.titlecase}}{{prefix}}{{/lambda.titlecase}}.{{#lambda.camelcase}}{{prefix}}{{/lambda.camelcase}}Api()); + {{/-first}} + {{/apis}} + {{/apiInfo}} @Override public void init() { @@ -20,10 +49,37 @@ public class {{prefix}}NamespaceHandler extends NamespaceHandlerSupport { {{#apis}} {{#operations}} {{#operation}} - registerBeanDefinitionParser("{{operationId}}Request", new {{prefix}}BeanDefinitionParser({{classname}}.{{operationIdCamelCase}}Request.class)); + + registerOperationParsers({{classname}}.class,"{{#lambda.kebabcase}}{{operationId}}{{/lambda.kebabcase}}", "{{operationId}}", "{{path}}", + {{classname}}.{{operationIdCamelCase}}SendActionBuilder.class, + {{classname}}.{{operationIdCamelCase}}ReceiveActionBuilder.class, + new String[]{ {{#requiredNonBodyParams}}"{{paramName}}{{^isString}}{{/isString}}"{{^-last}}, {{/-last}}{{/requiredNonBodyParams}} }, + new String[]{ {{#optionalAndAuthParameterNames}}"{{.}}"{{^-last}}, {{/-last}}{{/optionalAndAuthParameterNames}} }); {{/operation}} {{/operations}} {{/apis}} {{/apiInfo}} } + + private void registerOperationParsers(Class apiClass, String elementName, String operationName, String path, + Class sendBeanClass, + Class receiveBeanClass, + String[] constructorParameters, + String[] nonConstructorParameters) { + + RestApiSendMessageActionParser sendParser = new RestApiSendMessageActionParser(openApiSpecification, operationName, + path, + apiClass, + sendBeanClass, + receiveBeanClass, + "{{apiEndpoint}}"); + sendParser.setConstructorParameters(constructorParameters); + sendParser.setNonConstructorParameters(nonConstructorParameters); + registerBeanDefinitionParser("send-"+elementName, sendParser); + + RestApiReceiveMessageActionParser receiveParser = new RestApiReceiveMessageActionParser(openApiSpecification, + operationName, apiClass, receiveBeanClass, "{{apiEndpoint}}"); + registerBeanDefinitionParser("receive-"+elementName, receiveParser); + } + } diff --git a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/namespace_handler_soap.mustache b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/namespace_handler_soap.mustache new file mode 100644 index 0000000000..4104f0b454 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/namespace_handler_soap.mustache @@ -0,0 +1,78 @@ +{{! + + Copyright the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +}} +package {{invokerPackage}}.spring; + +import org.citrusframework.openapi.OpenApiSpecification; +import org.citrusframework.openapi.testapi.SoapApiSendMessageActionBuilder; +import org.citrusframework.openapi.testapi.SoapApiReceiveMessageActionBuilder; +{{#apiInfo}} +{{#apis}} +import {{package}}.{{classname}}; +{{/apis}} +{{/apiInfo}} +import org.citrusframework.openapi.testapi.spring.SoapApiReceiveMessageActionParser; +import org.citrusframework.openapi.testapi.spring.SoapApiSendMessageActionParser; +import {{invokerPackage}}.{{#lambda.titlecase}}{{prefix}}{{/lambda.titlecase}}; +import org.citrusframework.openapi.testapi.GeneratedApi; +import org.springframework.beans.factory.xml.NamespaceHandlerSupport; + +{{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{>xmlAnnotation}} +public class {{#lambda.titlecase}}{{prefix}}{{/lambda.titlecase}}NamespaceHandler extends NamespaceHandlerSupport { + + {{#apiInfo}} + {{#apis}} + {{#-first}} + private final OpenApiSpecification openApiSpecification = OpenApiSpecification.from( + {{#lambda.titlecase}}{{prefix}}{{/lambda.titlecase}}.{{#lambda.camelcase}}{{prefix}}{{/lambda.camelcase}}Api()); + {{/-first}} + {{/apis}} + {{/apiInfo}} + + @Override + public void init() { + {{#apiInfo}} + {{#apis}} + {{#operations}} + {{#operation}} + + registerOperationParsers({{classname}}.class,"{{#lambda.kebabcase}}{{operationId}}{{/lambda.kebabcase}}", + {{classname}}.{{operationIdCamelCase}}SendActionBuilder.class, + {{classname}}.{{operationIdCamelCase}}ReceiveActionBuilder.class); + {{/operation}} + {{/operations}} + {{/apis}} + {{/apiInfo}} + } + + private void registerOperationParsers(Class apiClass, String elementName, + Class sendBeanClass, + Class receiveBeanClass) { + + SoapApiSendMessageActionParser sendParser = new SoapApiSendMessageActionParser( + apiClass, + sendBeanClass, + receiveBeanClass, + "{{apiEndpoint}}"); + registerBeanDefinitionParser("send-"+elementName, sendParser); + + SoapApiReceiveMessageActionParser receiveParser = new SoapApiReceiveMessageActionParser( + apiClass, receiveBeanClass, "{{apiEndpoint}}"); + registerBeanDefinitionParser("receive-"+elementName, receiveParser); + } + +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/openApi.mustache b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/openApi.mustache deleted file mode 100644 index b59349ae63..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/openApi.mustache +++ /dev/null @@ -1,83 +0,0 @@ -{{>licenseInfo}} - -package {{package}}; - -import java.util.HashMap; -import java.util.Map; -import org.citrusframework.http.client.HttpClient; -import org.citrusframework.openapi.OpenApiSpecification; -import org.citrusframework.openapi.generator.rest.petstore.model.Pet; -import org.citrusframework.testapi.GeneratedApi; - -import {{invokerPackage}}.citrus.{{prefix}}AbstractSendAction; - -{{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{>xmlAnnotation}} -public class {{classname}} implements GeneratedApi -{ - - public static final {{classname}} INSTANCE = new {{classname}}(); - - private OpenApiSpecification openApiSpecification = null; - - public String getApiTitle() { - return "{{appName}}"; - } - - public String getApiVersion() { - return "{{appVersion}}"; - } - - public String getApiPrefix() { - return "{{prefix}}"; - } - - public Map getApiInfoExtensions() { - Map infoExtensionMap = new HashMap<>(); - {{#infoExtensions}} - {{#entrySet}} - infoExtensionMap.put("{{key}}", "{{value}}"); - {{/entrySet}} - {{/infoExtensions}} - return infoExtensionMap; - } - - {{#operations}} - {{#operation}} - public {{operationIdCamelCase}}ActionBuilder {{operationId}}() { - return new {{operationIdCamelCase}}ActionBuilder(); - } - {{/operation}} - {{/operations}} - - {{#operations}} - {{#operation}} - public class {{operationIdCamelCase}}ActionBuilder extends {{prefix}}AbstractSendAction.Builder { - - private static final String METHOD = ""{{httpMethod}}"; - - private static final String ENDPOINT = "{{path}}"; - - private static final String OPERATION_NAME = "{{operationId}}"; - - public AddPetActionBuilder() { - super(openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); - } - - {{#queryParams}} - public {{operationIdCamelCase}}ActionBuilder with{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}(String {{paramName}}) { - queryParam("{{paramName}}", {{paramName}}); - return this; - } - } - {{/queryParams}} - -// public AddPetActionBuilder withPet(Pet pet) { -// // TODO: fix this -// getMessageBuilderSupport().body(pet.toString()); -// return this; -// } - - } - {{/operation}} - {{/operations}} -} \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/schema.mustache b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/schema.mustache index 1beddbdebc..64e0738760 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/schema.mustache +++ b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/schema.mustache @@ -1,78 +1,123 @@ +{{! + + Copyright the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +}} - + - + - + - + + + - - - - - - - - + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + {{^isMultipart}} + + + + {{^required}}Optional {{/required}}Body - {{summary}}{{#description}} +

{{description}}

{{/description}} +
+
+
+ {{/isMultipart}} +
+
+
- - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + @@ -111,28 +156,12 @@ {{#operations}} {{#operation}} - {{#isMultipart}} - - - {{#formParams}} - - - - {{^required}}Optional {{/required}}{{#required}}Required{{/required}} - must either be set as attribute or element: {{#description}} -

{{description}}

{{/description}} -
-
-
- {{/formParams}} -
-
- {{/isMultipart}} - - + + {{notes}} {{operationId}} -

{{httpMethod}} {{httpPathPrefix}}{{{path}}}

+

{{httpMethod}} {{{path}}}

    {{#queryParams}}
  • {{paramName}} {{description}}
  • @@ -143,10 +172,18 @@ {{#bodyParams}}
  • Body: {{description}}
  • {{/bodyParams}} - {{#authMethods}}{{#isBasic}} -
  • basicUsername http basic authentication username
  • -
  • basicPassword http basic authentication password
  • - {{/isBasic}}{{/authMethods}} + {{#authMethods}} + {{#isBasicBasic}} +
  • basicAuthUsername http basic authentication username
  • +
  • basicAuthPassword http basic authentication password
  • + {{/isBasicBasic}} + {{#isBasicBearer}} +
  • basicAuthBearer http basic authentication bearer token
  • + {{/isBasicBearer}} + {{#isApiKey}} +
  • {{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}} {{#lambda.camelcase}}{{keyParamName}}{{/lambda.camelcase}} authentication token
  • + {{/isApiKey}} + {{/authMethods}} {{#isMultipart}} {{#formParams}}
  • {{paramName}} {{description}}
  • @@ -156,65 +193,210 @@ - + - {{#isMultipart}} - - {{/isMultipart}} - {{^isMultipart}} - {{#bodyParams}} - - - - {{^required}}Optional {{/required}}Body - {{summary}}{{#description}} -

    {{description}}

    {{/description}} -
    -
    + {{#queryParams}} + {{#isArray}} + + {{#description}} + + {{description}} + + {{/description}} - {{/bodyParams}} - {{/isMultipart}} - + {{/isArray}} + {{/queryParams}} + {{#headerParams}} + {{#isArray}} + + {{#description}} + + {{description}} + + {{/description}} + + {{/isArray}} + {{/headerParams}} + {{#pathParams}} + {{#isArray}} + + {{#description}} + + {{description}} + + {{/description}} + + {{/isArray}} + {{/pathParams}} + {{#formParams}} + {{#isArray}} + + {{#description}} + + {{description}} + + {{/description}} + + {{/isArray}} + {{/formParams}} + {{#cookieParams}} + {{#isArray}} + + {{#description}} + + {{description}} + + {{/description}} + + {{/isArray}} + {{/cookieParams}} +
    {{#queryParams}} - + {{^isArray}} + + {{#description}} {{description}} + {{/description}} + {{/isArray}} {{/queryParams}} + {{#headerParams}} + {{^isArray}} + + {{#description}} + + {{description}} + + {{/description}} + + {{/isArray}} + {{/headerParams}} {{#pathParams}} - + {{^isArray}} + + {{#description}} {{description}} + {{/description}} + {{/isArray}} {{/pathParams}} - {{#isMultipart}} {{#formParams}} - - + {{^isArray}} + + {{#description}} - The filename of the {{paramName}} to upload + {{description}} + {{/description}} + {{/isArray}} {{/formParams}} - {{/isMultipart}} - {{#authMethods}}{{#isBasic}} - + {{#cookieParams}} + {{^isArray}} + + {{#description}} + + {{description}} + + {{/description}} + + {{/isArray}} + {{/cookieParams}} + {{#authMethods}} + {{#isBasicBasic}} + http basic authentication username - + http basic authentication password - {{/isBasic}}{{/authMethods}} + {{/isBasicBasic}} + {{#isBasicBearer}} + + + http basic authentication bearer token + + + {{/isBasicBearer}} + {{#isApiKey}} + + {{#description}} + + {{description}} + + {{/description}} + + {{/isApiKey}} + {{/authMethods}} +
    +
    + + + + + + {{notes}} + {{operationId}} +

    {{httpMethod}} {{{path}}}

    +
      + {{#queryParams}} +
    • {{paramName}} {{description}}
    • + {{/queryParams}} + {{#pathParams}} +
    • {{baseName}} {{description}}
    • + {{/pathParams}} + {{#bodyParams}} +
    • Body: {{description}}
    • + {{/bodyParams}} + {{#isMultipart}} + {{#formParams}} +
    • {{paramName}} {{description}}
    • + {{/formParams}} + {{/isMultipart}} +
    +
    +
    + + + {{#responses}} + {{#-first}} + + + + An enumeration of all specified API response codes. + + + + + {{/-first}} + + + + {{#message}} + Message: {{message}}
    + {{/message}} + {{#dataType}} + Datatype: {{dataType}}
    + {{/dataType}} +
    +
    +
    + {{#-last}} +
    +
    +
    + {{/-last}} + {{/responses}} +
    @@ -225,7 +407,8 @@ {{#operations}} {{#operation}} - + + {{/operation}} {{/operations}} {{/apis}} diff --git a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/schema_soap.mustache b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/schema_soap.mustache index 096cdc9392..39fac4680c 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/schema_soap.mustache +++ b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/schema_soap.mustache @@ -1,123 +1,72 @@ - - +{{! - + Copyright the original author or authors. - - - - - - - - - - - - - - - - + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at - - - - - - - - - - - - - - - - + http://www.apache.org/licenses/LICENSE-2.0 - - - - - - - - - - - - - - - - - - - - - - + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +}} + + + + {{#apiInfo}} - {{#apis}} - {{#operations}} - {{#operation}} - - - - {{operationId}} -

    {{{path}}}

    -
    • - Body: {{description}}
    • -
    -
    -
    - - - - - - - {{^required}}SOAP {{/required}}Body{{summary}}{{#description}} -

    {{description}}

    {{/description}} -
    -
    -
    - -
    -
    -
    -
    + {{#apis}} + {{#operations}} + {{#operation}} + + + + {{notes}} + + + + + + + + + + - {{/operation}} - {{/operations}} - {{/apis}} - {{#apis}} - {{#operations}} - {{#operation}} - + + + + {{notes}} + + + + + + + {{/operation}} + {{/operations}} + {{/apis}} + {{#apis}} + {{#operations}} + {{#operation}} - {{/operation}} - {{/operations}} - {{/apis}} + + + {{/operation}} + {{/operations}} + {{/apis}} {{/apiInfo}}
    diff --git a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/test_base.mustache b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/test_base.mustache deleted file mode 100644 index be87ee214a..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/test_base.mustache +++ /dev/null @@ -1,239 +0,0 @@ -{{>licenseInfo}} - -package {{invokerPackage}}.citrus; - -import static org.springframework.util.CollectionUtils.isEmpty; - -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.spi.Resources; -import org.citrusframework.message.Message; -import org.citrusframework.testapi.ApiActionBuilderCustomizerService; -import org.citrusframework.testapi.GeneratedApi; -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; - -{{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{>xmlAnnotation}} -public abstract class {{prefix}}AbstractTestRequest extends AbstractTestAction { - - protected final Marker coverageMarker = MarkerFactory.getMarker("{{#lambda.uppercase}}{{prefix}}{{/lambda.uppercase}}-API-COVERAGE"); - - @Autowired - @Qualifier("{{apiEndpoint}}") - 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 {{prefix}}AbstractTestRequest#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/main/resources/java-citrus/test_base_soap.mustache b/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/test_base_soap.mustache deleted file mode 100644 index 04f3c5568c..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/main/resources/java-citrus/test_base_soap.mustache +++ /dev/null @@ -1,182 +0,0 @@ -{{>licenseInfo}} - -package {{invokerPackage}}.citrus; - -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; - -{{>additionalModelTypeAnnotations}}{{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}{{>xmlAnnotation}} -public abstract class {{prefix}}AbstractTestRequest extends AbstractTestAction { - - protected final Marker coverageMarker = MarkerFactory.getMarker("{{#lambda.uppercase}}{{prefix}}{{/lambda.uppercase}}-API-COVERAGE"); - - @Autowired - @Qualifier("{{apiEndpoint}}") - 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/java/org/citrusframework/openapi/generator/CitrusJavaCodegenTest.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/CitrusJavaCodegenTest.java new file mode 100644 index 0000000000..07eb532c9b --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/CitrusJavaCodegenTest.java @@ -0,0 +1,177 @@ +package org.citrusframework.openapi.generator; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.citrusframework.openapi.generator.CitrusJavaCodegen.CODEGEN_NAME; + +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.parameters.Parameter; +import io.swagger.v3.oas.models.servers.Server; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.citrusframework.openapi.generator.CitrusJavaCodegen.CustomCodegenOperation; +import org.citrusframework.openapi.generator.CitrusJavaCodegen.CustomCodegenParameter; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.openapitools.codegen.CodegenConfigLoader; +import org.openapitools.codegen.CodegenOperation; +import org.openapitools.codegen.CodegenParameter; +import org.openapitools.codegen.CodegenProperty; + +/** + * This test validates the code generation process. + */ +class CitrusJavaCodegenTest { + + private CitrusJavaCodegen codegen; + + @BeforeEach + void setUp() { + codegen = new CitrusJavaCodegen(); + } + + @Test + void retrieveGeneratorBySpi() { + CitrusJavaCodegen codegen = (CitrusJavaCodegen) CodegenConfigLoader.forName("java-citrus"); + assertThat(codegen).isNotNull(); + } + + @Test + void arePredefinedValuesNotEmptyTest() { + CitrusJavaCodegen codegen = new CitrusJavaCodegen(); + + assertThat(codegen.getName()).isEqualTo(CODEGEN_NAME); + assertThat(codegen.getHelp()).isNotEmpty(); + assertThat(codegen.getHttpClient()).isNotEmpty(); + assertThat(codegen.getApiPrefix()).isNotEmpty(); + assertThat(codegen.getTargetXmlnsNamespace()).isNull(); + assertThat(codegen.getGeneratedSchemaFolder()).isNotEmpty(); + } + + @Test + void testGetName() { + assertThat(codegen.getName()).isEqualTo("java-citrus"); + } + + @Test + void testGetHelp() { + String helpMessage = codegen.getHelp(); + assertThat(helpMessage).isEqualTo("Generates citrus api requests."); + } + + @Test + void testAdditionalPropertiesConfiguration() { + assertThat(codegen.additionalProperties()) + .containsEntry("apiVersion", "1.0.0") + .containsEntry(CitrusJavaCodegen.API_TYPE, CitrusJavaCodegen.API_TYPE_REST) + .containsEntry("useJakartaEe", true); + } + + @Test + void testReservedWordsConfiguration() { + assertThat(codegen.reservedWords()) + .contains("name", "description", "httpclient") + .doesNotContain("nonReservedWord"); + } + + @Test + void testTypeMappings() { + assertThat(codegen.typeMapping()) + .containsEntry("binary", "Resource") + .containsEntry("file", "Resource"); + } + + @Test + void testProcessOptsWithApiType() { + codegen.additionalProperties().put(CitrusJavaCodegen.API_TYPE, "XXX"); + + assertThatThrownBy(() -> codegen.processOpts()) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("Unknown API_TYPE: 'XXX'"); + } + + @Test + void testProcessOptsValidApiType() { + codegen.additionalProperties().put(CitrusJavaCodegen.API_TYPE, CitrusJavaCodegen.API_TYPE_REST); + codegen.processOpts(); + + assertThat(codegen.additionalProperties()) + .containsEntry(CitrusJavaCodegen.API_TYPE, CitrusJavaCodegen.API_TYPE_REST); + } + + @Test + void testPreprocessOpenAPI() { + OpenAPI openAPI = new OpenAPI(); + Info info = new Info(); + Map extensions = new HashMap<>(); + extensions.put("x-api-owner", "citrus-framework"); + extensions.put("x-api-version", "2.0.0"); + info.setExtensions(extensions); + openAPI.setInfo(info); + + codegen.preprocessOpenAPI(openAPI); + + assertThat(codegen.additionalProperties()) + .containsEntry("x-api-owner", "citrus-framework") + .containsEntry("x-api-version", "2.0.0") + .containsEntry("infoExtensions", extensions); + } + + @Test + void testFromProperty() { + // Mock schema + Schema schema = Mockito.mock(Schema.class); + + // Call fromProperty and verify conversion + CodegenProperty codegenProperty = codegen.fromProperty("name", schema, true); + assertThat(codegenProperty) + .isInstanceOf(CodegenProperty.class) + .hasFieldOrPropertyWithValue("name", "_name") + .hasFieldOrPropertyWithValue("required", true); + } + + @Test + void testFromFormProperty() { + Schema schema = Mockito.mock(Schema.class); + + @SuppressWarnings("unchecked") + Set imports = Mockito.mock(Set.class); + + CodegenParameter codegenParameter = codegen.fromFormProperty("formParam", schema, imports); + assertThat(codegenParameter) + .isInstanceOf(CustomCodegenParameter.class) + .hasFieldOrPropertyWithValue("paramName", "formParam"); + } + + @Test + void testFromParameter() { + Parameter parameter = Mockito.mock(Parameter.class); + + @SuppressWarnings("unchecked") + Set imports = Mockito.mock(Set.class); + + CodegenParameter codegenParameter = codegen.fromParameter(parameter, imports); + assertThat(codegenParameter) + .isInstanceOf(CustomCodegenParameter.class); + } + + @Test + void testFromOperation() { + Operation operation = Mockito.mock(Operation.class); + List servers = Collections.emptyList(); + + CodegenOperation codegenOperation = codegen.fromOperation("/path", "GET", operation, servers); + assertThat(codegenOperation) + .isInstanceOf(CustomCodegenOperation.class) + .hasFieldOrPropertyWithValue("httpMethod", "GET") + .hasFieldOrPropertyWithValue("path", "/path"); + } + +} 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/ExpectedCodeGenIT.java similarity index 80% rename from test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/JavaCitrusCodegenIT.java rename to test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/ExpectedCodeGenIT.java index 1d205f9400..1af4ffa9f6 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/ExpectedCodeGenIT.java @@ -3,12 +3,11 @@ import static java.nio.file.Files.readString; import static java.nio.file.Files.walk; import static org.assertj.core.api.Assertions.assertThat; -import static org.citrusframework.openapi.generator.JavaCitrusCodegenTest.getAbsoluteTargetDirectoryPath; -import static org.citrusframework.openapi.generator.JavaCitrusCodegenTest.getAbsoluteTestResourcePath; import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.File; import java.io.IOException; +import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; import java.util.stream.Stream; @@ -25,31 +24,25 @@ /** * This test case is designed to validate the consistency of the code generation process and detect * any discrepancies between the generated API files and the reference files stored in - * '/JavaCitrusCodegenIT/expectedgen/'. It compares the results of API generation against the + * '/ExpectedCodeGenIT/expectedgen/'. It compares the results of API generation against the * reference files, and a failure indicates potential changes in mustache templates or code * generation logic. *

    * If this test fails, it is essential to review the code generation process and underlying * templates carefully. If the changes are intentional and verified, update the reference files by - * copying the generated API sources to the '/JavaCitrusCodegenIT/expectedgen/' directory. To ensure + * copying the generated API sources to the '/ExpectedCodeGenIT/expectedgen/' directory. To ensure * accurate copying, without unwanted code formatting, use a simple File Explorer instead of relying * on IDE-based operations. */ -class JavaCitrusCodegenIT { +class ExpectedCodeGenIT { public static final String BASE_PACKAGE = "org/citrusframework/openapi/generator"; - private static long countFilesRecursively(Path dir) throws IOException { - try (Stream walk = walk(dir)) { - return walk.filter(Files::isRegularFile).count(); - } - } - @Test void noAdditionalFiles() throws IOException { long expectedFileCount = countFilesRecursively( Path.of(getAbsoluteTestResourcePath( - BASE_PACKAGE + "/JavaCitrusCodegenIT/expectedgen/rest"))); + BASE_PACKAGE + "/ExpectedCodeGenIT/expectedgen/rest"))); long actualFileCount = countFilesRecursively( Path.of(getAbsoluteTargetDirectoryPath( "generated-test-sources/" + BASE_PACKAGE + "/rest"))); @@ -114,7 +107,7 @@ private static Stream geClassResourcesIgnoringInnerClasses(String pat private void assertFileContent(File file, String apiDir) throws IOException { assertThat(file).exists(); - String expectedFilePath = BASE_PACKAGE + "/JavaCitrusCodegenIT/expectedgen/" + file.getAbsolutePath().substring(file.getAbsolutePath().indexOf(apiDir)); + String expectedFilePath = BASE_PACKAGE + "/ExpectedCodeGenIT/expectedgen/" + file.getAbsolutePath().substring(file.getAbsolutePath().indexOf(apiDir)); ClassPathResource classPathResource = new ClassPathResource(expectedFilePath); String actualContent = readString(file.toPath()); @@ -129,4 +122,29 @@ private void assertFileContent(File file, String apiDir) throws IOException { assertThat(actualContent).isEqualTo(expectedContent); } + + private static long countFilesRecursively(Path dir) throws IOException { + try (Stream walk = walk(dir)) { + return walk.filter(Files::isRegularFile).count(); + } + } + + /** + * Get the absolute path to the test resources directory. + */ + static String getAbsoluteTestResourcePath(String pathToFileInTestResources) { + URL resourceUrl = CitrusJavaCodegenTest.class.getClassLoader().getResource(pathToFileInTestResources); + assert resourceUrl != null; + File inputSpecFile = new File(resourceUrl.getFile()); + return inputSpecFile.getAbsolutePath(); + } + + /** + * Get the absolute path to the project's target directory. + */ + static String getAbsoluteTargetDirectoryPath(String pathToFileInTargetDirectory) { + String projectBaseDir = System.getProperty("user.dir"); // Base directory of the project + File outputDirFile = new File(projectBaseDir, "target/" + pathToFileInTargetDirectory); + return outputDirFile.getAbsolutePath(); + } } diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/GeneratedApiIT.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/GeneratedApiIT.java deleted file mode 100644 index 4ad6df823a..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/GeneratedApiIT.java +++ /dev/null @@ -1,628 +0,0 @@ -package org.citrusframework.openapi.generator; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.citrusframework.message.MessagePayloadUtils.normalizeWhitespace; -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.verify; -import static org.mockito.Mockito.when; - -import com.networknt.schema.JsonSchema; -import com.networknt.schema.ValidationMessage; -import jakarta.servlet.http.Cookie; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Stream; -import org.assertj.core.api.InstanceOfAssertFactories; -import org.citrusframework.Citrus; -import org.citrusframework.CitrusInstanceManager; -import org.citrusframework.TestAction; -import org.citrusframework.TestCase; -import org.citrusframework.actions.SendMessageAction.SendMessageActionBuilder; -import org.citrusframework.common.SpringXmlTestLoader; -import org.citrusframework.common.TestLoader; -import org.citrusframework.config.CitrusSpringConfig; -import org.citrusframework.context.TestContext; -import org.citrusframework.endpoint.EndpointConfiguration; -import org.citrusframework.exceptions.CitrusRuntimeException; -import org.citrusframework.exceptions.ValidationException; -import org.citrusframework.http.client.HttpClient; -import org.citrusframework.http.client.HttpEndpointConfiguration; -import org.citrusframework.http.message.HttpMessage; -import org.citrusframework.json.schema.SimpleJsonSchema; -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.rest.multiparttest.request.MultiparttestControllerApi.PostFileRequest; -import org.citrusframework.openapi.generator.rest.petstore.request.PetApi.AddPetRequest; -import org.citrusframework.openapi.generator.rest.petstore.request.PetApi.GetPetByIdRequest; -import org.citrusframework.spi.Resources; -import org.citrusframework.testapi.ApiActionBuilderCustomizerService; -import org.citrusframework.testapi.GeneratedApi; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.parallel.Isolated; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.ArgumentCaptor; -import org.mockito.ArgumentMatcher; -import org.mockito.ArgumentMatchers; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.core.io.Resource; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.TestPropertySource; -import org.springframework.util.MultiValueMap; - -/** - * This test tests the generated API - */ -@Isolated -@DirtiesContext -@ExtendWith({CitrusSpringExtension.class}) -@SpringBootTest(classes = {CitrusSpringConfig.class, GeneratedApiIT.Config.class}) -@TestPropertySource( - properties = { - "applicationServiceClient.basic.username=Max Mustermann", - "applicationServiceClient.basic.password=Top secret" - } -) -class GeneratedApiIT { - - @Autowired - private ApplicationContext applicationContext; - - @Autowired - private HttpClient httpClientMock; - - @Mock - private Producer producerMock; - - @Mock - private SelectiveConsumer consumerMock; - - private TestContext testContext; - - @BeforeEach - void beforeEach() { - testContext = applicationContext.getBean(TestContext.class); - } - - @Test - void testValidationFailure() { - mockProducerAndConsumer(createReceiveMessage("{\"some\": \"payload\"}")); - assertThatThrownBy( - () -> executeTest("getPetByIdRequestTest", testContext)).hasCauseExactlyInstanceOf( - ValidationException.class); - } - - @Nested - class WithValidationMatcher { - - @BeforeEach - void beforeEach() { - mockProducerAndConsumer(createReceiveMessage("")); - } - - @Test - void testSendWithBody() { - ArgumentMatcher messageMatcher = message -> { - HttpMessage httpMessage = (HttpMessage) message; - try { - assertThat(httpMessage.getPayload()) - .isEqualTo( - readToString(Resources.create( - "org/citrusframework/openapi/generator/GeneratedApiTest/payloads/addPetMessage.json"), - StandardCharsets.UTF_8) - ); - } catch (IOException e) { - throw new CitrusRuntimeException("Unable to parse file!", e); - } - return true; - }; - - sendAndValidateMessage("sendWithBodyTest", messageMatcher); - } - - @Test - void testSendWithBodyLiteralWithVariable() { - ArgumentMatcher messageMatcher = message -> { - HttpMessage httpMessage = (HttpMessage) message; - assertThat(((String) httpMessage.getPayload()).trim()).isEqualTo("{\"id\": 15}"); - return true; - }; - sendAndValidateMessage("sendWithBodyLiteralWithVariableTest", messageMatcher); - } - - @Test - void testXCitrusApiHeaders() { - ArgumentMatcher messageMatcher = message -> { - HttpMessage httpMessage = (HttpMessage) message; - assertThat(httpMessage.getHeader("x-citrus-api-name")).isEqualTo("petstore"); - assertThat(httpMessage.getHeader("x-citrus-app")).isEqualTo("PETS"); - assertThat(httpMessage.getHeader("x-citrus-api-version")).isEqualTo("1.0.0"); - return true; - }; - - sendAndValidateMessage("sendWithBodyLiteralTest", messageMatcher); - } - - @Test - void testSendWithExtraHeaders() { - ArgumentMatcher messageMatcher = message -> { - HttpMessage httpMessage = (HttpMessage) message; - assertThat(httpMessage.getHeader("h1")).isEqualTo("v1"); - assertThat(httpMessage.getHeader("h2")).isEqualTo("v2"); - return true; - }; - - sendAndValidateMessage("sendWithExtraHeaderTest", messageMatcher); - } - - @Test - void testSendWithBodyLiteral() { - ArgumentMatcher messageMatcher = message -> { - HttpMessage httpMessage = (HttpMessage) message; - assertThat(((String) httpMessage.getPayload()).trim()).isEqualTo("{\"id\": 13}"); - return true; - }; - - sendAndValidateMessage("sendWithBodyLiteralTest", messageMatcher); - } - - private void sendAndValidateMessage(String testName, - ArgumentMatcher messageMatcher) { - GeneratedApiIT.this.sendAndValidateMessage(testName, messageMatcher, - AddPetRequest.class); - } - - } - - @Nested - class WithMultipartMessage { - - @Test - void testSendMultipartFile() { - mockProducerAndConsumer(createReceiveMessage("")); - - ArgumentMatcher messageMatcher = message -> { - assertThat(message.getPayload()).isInstanceOf(MultiValueMap.class); - MultiValueMap multiValueMap = (MultiValueMap) message.getPayload(); - List multipartFile = multiValueMap.get("multipartFile"); - try { - assertThat(((Resource) multipartFile.get(0)).getURL().toString()) - .endsWith( - "test-classes/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetByIdControlMessage1.json"); - } catch (IOException e) { - throw new CitrusRuntimeException("Unable to parse file!", e); - } - - return true; - }; - - sendAndValidateMessage("postFileTest", messageMatcher, PostFileRequest.class); - } - - @Test - void testSendMultipartWithFileAttribute() { - Message payload = createReceiveMessage("{\"id\": 1}"); - mockProducerAndConsumer(payload); - - executeTest("multipartWithFileAttributesTest", testContext); - ArgumentCaptor messageArgumentCaptor = ArgumentCaptor.forClass(Message.class); - verify(producerMock).send(messageArgumentCaptor.capture(), eq(testContext)); - Object producedMessagePayload = messageArgumentCaptor.getValue().getPayload(); - assertThat(producedMessagePayload).isInstanceOf(MultiValueMap.class); - - Object templateValue = ((MultiValueMap) producedMessagePayload).get("template"); - assertThat(templateValue) - .asInstanceOf(InstanceOfAssertFactories.LIST) - .element(0) - .hasFieldOrPropertyWithValue("path", - "org/citrusframework/openapi/generator/GeneratedApiTest/payloads/MultipartTemplate.xml"); - - Object additionalDataValue = ((MultiValueMap) producedMessagePayload).get( - "additionalData"); - assertThat(additionalDataValue) - .asInstanceOf(InstanceOfAssertFactories.LIST) - .element(0) - .hasFieldOrPropertyWithValue("path", - "org/citrusframework/openapi/generator/GeneratedApiTest/payloads/AdditionalData.json"); - - Object schemaValue = ((MultiValueMap) producedMessagePayload).get("_schema"); - assertThat(schemaValue) - .asInstanceOf(InstanceOfAssertFactories.LIST) - .element(0) - .hasFieldOrPropertyWithValue("path", - "org/citrusframework/openapi/generator/GeneratedApiTest/payloads/Schema.json"); - } - - @Test - void testSendMultipartWithPlainText() { - mockProducerAndConsumer(createReceiveMessage("{\"id\": 1}")); - executeTest("multipartWithPlainTextTest", testContext); - ArgumentCaptor messageArgumentCaptor = ArgumentCaptor.forClass(Message.class); - verify(producerMock).send(messageArgumentCaptor.capture(), eq(testContext)); - String producedMessagePayload = normalizeWhitespace( - messageArgumentCaptor.getValue().getPayload().toString(), - true, - true - ); - - String expectedPayload = - "{template=[ ], additionalData=[ {\"data1\":\"value1\"} ], _schema=[ {\"schema\":\"mySchema\"} ]}"; - assertThat(producedMessagePayload).isEqualTo(expectedPayload); - } - - @Test - void testSendMultipartWithMultipleDatatypes() { - Message receiveMessage = createReceiveMessage("{\"id\": 1}"); - mockProducerAndConsumer(receiveMessage); - - executeTest("multipartWithMultipleDatatypesTest", testContext); - ArgumentCaptor messageArgumentCaptor = ArgumentCaptor.forClass(Message.class); - verify(producerMock).send(messageArgumentCaptor.capture(), eq(testContext)); - String producedMessagePayload = normalizeWhitespace( - messageArgumentCaptor.getValue().getPayload().toString(), - true, - true - ); - - String expectedPayload = "{stringData=[Test], booleanData=[true], integerData=[1]}"; - assertThat(producedMessagePayload).isEqualTo(expectedPayload); - } - } - - @Nested - class WithDefaultReceiveMessage { - - private Message defaultRecieveMessage; - - @BeforeEach - void beforeEach() throws IOException { - defaultRecieveMessage = createReceiveMessage( - readToString(Resources.create( - "org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetByIdControlMessage1.json"), - StandardCharsets.UTF_8) - ); - mockProducerAndConsumer(defaultRecieveMessage); - } - - @Test - void testJsonPathExtraction() { - TestCase testCase = executeTest("jsonPathExtractionTest", testContext); - TestAction testAction = testCase.getActions().get(0); - assertThat(testAction).isInstanceOf(GetPetByIdRequest.class); - - assertThat(testContext.getVariable("name")).isEqualTo("Snoopy"); - assertThat(testContext.getVariable("id")).isEqualTo("12"); - } - - @Test - void testCustomizer() { - TestCase testCase = executeTest("getPetByIdRequestTest", testContext); - - TestAction testAction = testCase.getActions().get(0); - assertThat(testAction).isInstanceOf(GetPetByIdRequest.class); - - ArgumentMatcher messageMatcher = message -> { - HttpMessage httpMessage = (HttpMessage) message; - assertThat(httpMessage.getHeader("x-citrus-api-version")).isEqualTo( - "1.0.0"); - - return true; - }; - verify(producerMock).send(ArgumentMatchers.argThat(messageMatcher), eq(testContext)); - verify(consumerMock).receive(testContext, 5000L); - } - - @Test - void testBasicAuthorization() { - TestCase testCase = executeTest("getPetByIdRequestTest", testContext); - - TestAction testAction = testCase.getActions().get(0); - assertThat(testAction).isInstanceOf(GetPetByIdRequest.class); - - ArgumentMatcher messageMatcher = message -> { - HttpMessage httpMessage = (HttpMessage) message; - assertThat(httpMessage.getHeader("Authorization")).isEqualTo( - "Basic YWRtaW46dG9wLXNlY3JldA=="); - return true; - }; - verify(producerMock).send(ArgumentMatchers.argThat(messageMatcher), eq(testContext)); - verify(consumerMock).receive(testContext, 5000L); - } - - @Test - void testRequestPath() { - TestCase testCase = executeTest("getPetByIdRequestTest", testContext); - TestAction testAction = testCase.getActions().get(0); - assertThat(testAction).isInstanceOf(GetPetByIdRequest.class); - - ArgumentMatcher messageMatcher = message -> { - HttpMessage httpMessage = (HttpMessage) message; - assertThat(httpMessage.getHeader("citrus_request_path")).isEqualTo("/pet/1234"); - return true; - }; - verify(producerMock).send(ArgumentMatchers.argThat(messageMatcher), eq(testContext)); - verify(consumerMock).receive(testContext, 5000L); - } - - @Test - void testCookies() { - TestCase testCase = executeTest("getPetByIdRequestTest", testContext); - TestAction testAction = testCase.getActions().get(0); - assertThat(testAction).isInstanceOf(GetPetByIdRequest.class); - - ArgumentMatcher messageMatcher = message -> { - HttpMessage httpMessage = (HttpMessage) message; - Cookie cookie1 = httpMessage.getCookies().get(0); - Cookie cookie2 = httpMessage.getCookies().get(1); - assertThat(cookie1.getName()).isEqualTo("c1"); - assertThat(cookie1.getValue()).isEqualTo("v1"); - assertThat(cookie2.getName()).isEqualTo("c2"); - assertThat(cookie2.getValue()).isEqualTo("v2"); - return true; - }; - verify(producerMock).send(ArgumentMatchers.argThat(messageMatcher), eq(testContext)); - verify(consumerMock).receive(testContext, 5000L); - } - - @Test - void testJsonPathValidation() { - TestCase testCase = executeTest("jsonPathValidationTest", testContext); - assertTestActionType(testCase, GetPetByIdRequest.class); - } - - @Test - void scriptValidationFailureTest() { - TestCase testCase = executeTest("scriptValidationTest", testContext); - assertTestActionType(testCase, GetPetByIdRequest.class); - } - - @Test - void jsonSchemaValidationFailureTest() { - assertThatThrownBy(() -> executeTest("jsonSchemaValidationFailureTest", testContext)) - .hasCauseExactlyInstanceOf(ValidationException.class); - - SimpleJsonSchema testSchema = (SimpleJsonSchema) applicationContext.getBean( - "failingTestSchema"); - - // Assert that schema validation was called - verify(testSchema).getSchema(); - JsonSchema schema = testSchema.getSchema(); - verify(schema).validate(any()); - } - - @Test - void jsonDeactivatedSchemaValidationTest() { - SimpleJsonSchema testSchema = (SimpleJsonSchema) applicationContext.getBean( - "testSchema"); - Mockito.clearInvocations(testSchema, testSchema.getSchema()); - - TestCase testCase = executeTest("jsonDeactivatedSchemaValidationTest", testContext); - - assertTestActionType(testCase, GetPetByIdRequest.class); - - // Assert that schema validation was called - Mockito.verifyNoInteractions(testSchema); - } - - @Test - void defaultOas3SchemaValidationTest() { - SimpleJsonSchema testSchema = (SimpleJsonSchema) applicationContext.getBean("oas3"); - Mockito.clearInvocations(testSchema, testSchema.getSchema()); - - TestCase testCase = executeTest("defaultOas3SchemaValidationTest", testContext); - - assertTestActionType(testCase, GetPetByIdRequest.class); - - // Assert that schema validation was called - verify(testSchema).getSchema(); - JsonSchema schema = testSchema.getSchema(); - verify(schema).validate(any()); - } - - @Test - void jsonSchemaValidationTest() { - SimpleJsonSchema testSchema = (SimpleJsonSchema) applicationContext.getBean( - "testSchema"); - Mockito.clearInvocations(testSchema, testSchema.getSchema()); - - TestCase testCase = executeTest("jsonSchemaValidationTest", testContext); - - assertTestActionType(testCase, GetPetByIdRequest.class); - - // Assert that schema validation was called - verify(testSchema).getSchema(); - JsonSchema schema = testSchema.getSchema(); - verify(schema).validate(any()); - } - - @Test - void testJsonPathValidationFailure() { - mockProducerAndConsumer(defaultRecieveMessage); - - assertThatThrownBy(() -> executeTest("jsonPathValidationFailureTest", testContext)) - .hasCauseExactlyInstanceOf(ValidationException.class); - } - - private static Stream testValidationFailures() { - return Stream.of( - Arguments.of("failOnStatusTest", - "Values not equal for header element 'citrus_http_status_code', expected '201' but was '200'"), - Arguments.of( - "failOnReasonPhraseTest", - "Values not equal for header element 'citrus_http_reason_phrase', expected 'Almost OK' but was 'OK'" - ), - Arguments.of( - "failOnVersionTest", - "Values not equal for header element 'citrus_http_version', expected 'HTTP/1.0' but was 'HTTP/1.1'" - ) - ); - } - - @ParameterizedTest - @MethodSource - void testValidationFailures(String testName, String expectedErrorMessage) { - assertThatThrownBy(() -> executeTest(testName, testContext)) - .hasCauseExactlyInstanceOf(ValidationException.class) - .message() - .startsWith(expectedErrorMessage); - } - } - -// @Test -// void testCoverageLogger() throws IOException { -// List logMessages = new ArrayList<>(); -// Logger logger = LoggerFactory.getLogger(GetPetByIdRequest.class); -// org.qos.logback.classic.Logger l = (org.qos.logback.classic.Logger) logger; -// l.setLevel(Level.TRACE); -// l.addAppender( -// new AppenderBase<>() { -// @Override -// protected void append(ILoggingEvent eventObject) {} -// -// @Override -// public synchronized void doAppend(ILoggingEvent eventObject) { -// logMessages.add(eventObject.getMessage()); -// super.doAppend(eventObject); -// } -// } -// ); -// -// -// -// mockProducer(httpClient); -// -// Message receiveMessage = createReceiveMessage( -// FileUtils.readToString(Resources.create("org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetByIdControlMessage1.json"), StandardCharsets.UTF_8) -// ); -// -// mockConsumer(httpClient, testContext, receiveMessage); -// -// executeTest("getPetByIdRequestTest", testContext); -// -// assertThat(logMessages.get(0)).isEqualTo("getPetById;GET;\"{}\";\"\";\"\""); -// } - - /** - * Test the send message using the given matcher - */ - private void sendAndValidateMessage(String testName, ArgumentMatcher messageMatcher, - Class apiClass) { - - TestCase testCase = executeTest(testName, testContext); - assertTestActionType(testCase, apiClass); - - verify(producerMock).send(ArgumentMatchers.argThat(messageMatcher), eq(testContext)); - } - - /** - * Assert that an action of type 'apiClass' is contained in the list of test actions - */ - private void assertTestActionType(TestCase testCase, Class apiClass) { - TestAction testAction = testCase - .getActions() - .stream() - .filter(action -> apiClass.isAssignableFrom(action.getClass())) - .findAny() - .orElse(null); - assertThat(testAction).isNotNull(); - } - - private void mockProducerAndConsumer(Message receiveMessage) { - when(httpClientMock.createProducer()).thenReturn(producerMock); - when(httpClientMock.createConsumer()).thenReturn(consumerMock); - when(consumerMock.receive(testContext, 5000L)).thenReturn(receiveMessage); - } - - private TestCase executeTest(String testName, TestContext testContext) { - assertThat(CitrusInstanceManager.get()).isPresent(); - - Citrus citrus = CitrusInstanceManager.get().get(); - TestLoader loader = new SpringXmlTestLoader().citrusContext(citrus.getCitrusContext()) - .citrus(citrus) - .context(testContext); - loader.setTestName(testName); - loader.setPackageName("org.citrusframework.openapi.generator.GeneratedApiTest"); - loader.load(); - return loader.getTestCase(); - } - - private Message createReceiveMessage(String payload) { - Message receiveMessage = new DefaultMessage(); - receiveMessage.setPayload(payload); - receiveMessage.getHeaders().put("citrus_http_reason_phrase", "OK"); - receiveMessage.getHeaders().put("citrus_http_version", "HTTP/1.1"); - receiveMessage.getHeaders().put("citrus_http_status_code", 200); - return receiveMessage; - } - - public static class Config { - - @Bean(name = {"applicationServiceClient", "multipartTestEndpoint", - "soapSampleStoreEndpoint", "petStoreEndpoint"}) - public HttpClient applicationServiceClient() { - HttpClient clientMock = mock(); - EndpointConfiguration endpointConfigurationMock = mock(); - when(clientMock.getEndpointConfiguration()).thenReturn(new HttpEndpointConfiguration()); - when(endpointConfigurationMock.getTimeout()).thenReturn(5000L); - return clientMock; - } - - @Bean - public ApiActionBuilderCustomizerService customizer() { - return new ApiActionBuilderCustomizerService() { - @Override - public > T build( - GeneratedApi generatedApi, TestAction action, TestContext context, T builder) { - builder.getMessageBuilderSupport() - .header("x-citrus-api-version", generatedApi.getApiVersion()); - return builder; - } - }; - } - - @Bean({"oas3", "testSchema"}) - public SimpleJsonSchema testSchema() { - JsonSchema schemaMock = mock(); - SimpleJsonSchema jsonSchemaMock = mock(); - - when(jsonSchemaMock.getSchema()).thenReturn(schemaMock); - - Set okReport = new HashSet<>(); - when(schemaMock.validate(any())).thenReturn(okReport); - return jsonSchemaMock; - } - - @Bean - public SimpleJsonSchema failingTestSchema() { - JsonSchema schemaMock = mock(); - SimpleJsonSchema jsonSchemaMock = mock(); - - when(jsonSchemaMock.getSchema()).thenReturn(schemaMock); - - Set nokReport = new HashSet<>(); - nokReport.add(new ValidationMessage.Builder().customMessage( - "This is a simulated validation error message").build()); - when(schemaMock.validate(any())).thenReturn(nokReport); - return jsonSchemaMock; - } - } -} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/GeneratedRestApiIT.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/GeneratedRestApiIT.java new file mode 100644 index 0000000000..7124bb9536 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/GeneratedRestApiIT.java @@ -0,0 +1,3510 @@ +package org.citrusframework.openapi.generator; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.citrusframework.http.actions.HttpActionBuilder.http; +import static org.citrusframework.openapi.generator.util.MultipartConverter.multipartMessageToMap; +import static org.citrusframework.validation.json.JsonPathMessageValidationContext.Builder.jsonPath; +import static org.springframework.http.HttpStatus.OK; + +import jakarta.servlet.http.Cookie; +import java.io.IOException; +import java.math.BigDecimal; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.time.LocalDate; +import java.util.List; +import java.util.Map; +import org.assertj.core.api.Assertions; +import org.citrusframework.TestActor; +import org.citrusframework.TestCaseRunner; +import org.citrusframework.annotations.CitrusResource; +import org.citrusframework.annotations.CitrusTest; +import org.citrusframework.annotations.CitrusTestSource; +import org.citrusframework.common.TestLoader; +import org.citrusframework.config.CitrusSpringConfig; +import org.citrusframework.context.TestContext; +import org.citrusframework.exceptions.MessageTimeoutException; +import org.citrusframework.exceptions.TestCaseFailedException; +import org.citrusframework.exceptions.ValidationException; +import org.citrusframework.http.actions.HttpClientRequestActionBuilder; +import org.citrusframework.http.actions.HttpClientResponseActionBuilder; +import org.citrusframework.http.actions.HttpServerRequestActionBuilder.HttpMessageBuilderSupport; +import org.citrusframework.http.client.HttpClient; +import org.citrusframework.http.client.HttpClientBuilder; +import org.citrusframework.http.message.HttpMessage; +import org.citrusframework.http.server.HttpServer; +import org.citrusframework.http.server.HttpServerBuilder; +import org.citrusframework.junit.jupiter.spring.CitrusSpringExtension; +import org.citrusframework.message.Message; +import org.citrusframework.openapi.generator.GeneratedRestApiIT.Config; +import org.citrusframework.openapi.generator.rest.extpetstore.model.PetIdentifier; +import org.citrusframework.openapi.generator.rest.extpetstore.request.ExtPetApi; +import org.citrusframework.openapi.generator.rest.extpetstore.spring.ExtPetStoreBeanConfiguration; +import org.citrusframework.openapi.generator.rest.petstore.request.PetApi; +import org.citrusframework.openapi.generator.rest.petstore.request.PetApi.GetPetByIdReceiveActionBuilder; +import org.citrusframework.openapi.generator.rest.petstore.spring.PetStoreBeanConfiguration; +import org.citrusframework.spi.Resources; +import org.citrusframework.util.FileUtils; +import org.citrusframework.util.SocketUtils; +import org.citrusframework.validation.json.JsonPathVariableExtractor; +import org.citrusframework.validation.script.ScriptValidationContext; +import org.citrusframework.variable.GlobalVariables; +import org.citrusframework.variable.MessageHeaderVariableExtractor; +import org.citrusframework.ws.endpoint.builder.WebServiceEndpoints; +import org.citrusframework.ws.server.WebServiceServer; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +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; + +/** + * This integration test class for the generated TestAPI aims to comprehensively test all aspects of + * accessing the API using both Java and XML. In addition to serving as a test suite, it also acts + * as a reference example. + * + *

    Therefore, each test is designed to be self-contained and straightforward, allowing + * anyone reviewing the code to easily grasp the purpose and context of the test without needing to + * rely on shared setup or utility methods. + */ + +@ExtendWith(CitrusSpringExtension.class) +@SpringBootTest(classes = {PetStoreBeanConfiguration.class, ExtPetStoreBeanConfiguration.class, + CitrusSpringConfig.class, Config.class}, properties = { + "extpetstore.basic.username=extUser", + "extpetstore.basic.password=extPassword", + "extpetstore.bearer.token=defaultBearerToken", + "extpetstore.api-key-query=defaultTopSecretQueryApiKey", + "extpetstore.api-key-header=defaultTopSecretHeaderApiKey", + "extpetstore.api-key-cookie=defaultTopSecretCookieApiKey", + "extpetstore.base64-encode-api-key=true" +} +) +class GeneratedRestApiIT { + + public static final List PET_ID_LIST = List.of(1, 2); + public static final List PET_ID_AS_STRING_LIST = List.of("1", "2"); + public static final List PET_ID_WITH_VARIABLE_EXPRESSIONS_LIST = List.of("${one}", + "${two}"); + + public static final PetIdentifier PET_IDENTIFIER = new PetIdentifier()._name("Louis") + .alias("Alexander"); + public static final String PET_IDENTIFIER_AS_STRING = """ + {"alias":"Alexander","name":"Louis"}"""; + + @Autowired + private HttpServer httpServer; + + @Autowired + private HttpServer otherHttpServer; + + @Autowired + private PetApi petApi; + + @Autowired + private ExtPetApi extPetApi; + + @Autowired + private TestActor petStoreActor; + + @Autowired + private HttpClient otherApplicationServiceClient; + + /** + * Demonstrates usage of parameter serialization according to + * ... + */ + @Nested + class ParameterSerialization { + + @Nested + class PathParameter { + + @Nested + class SimpleStyle { + + @Nested + class Array { + + @Test + void java_single_value(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithSimpleStyleArray(List.of(1)) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/simple/1") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleArray("200")); + + } + + @Test + void java_array_value(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithSimpleStyleArray(PET_ID_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/simple/1,2") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleArray("200")); + + } + + @Test + void java_array_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithSimpleStyleArray$(PET_ID_AS_STRING_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/simple/1,2") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleArray("200")); + + } + + @Test + void java_array_value_non_type_safe_with_variables( + @CitrusResource TestCaseRunner runner) { + runner.variable("one", "1"); + runner.variable("two", "2"); + + runner.when( + extPetApi.sendGetPetWithSimpleStyleArray$( + PET_ID_WITH_VARIABLE_EXPRESSIONS_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/simple/1,2") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleArray("200")); + + } + + @Test + void java_object_value(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi.sendGetPetWithSimpleStyleObject( + PET_IDENTIFIER) + .schemaValidation(false) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/simple/object/alias,Alexander,name,Louis") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleObject("200")); + } + + @Test + void java_object_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi.sendGetPetWithSimpleStyleObject$(PET_IDENTIFIER_AS_STRING) + .schemaValidation(false) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/simple/object/alias,Alexander,name,Louis") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleObject("200")); + } + + } + + @Nested + class ExplodedArray { + + @Test + void java_single_value(@CitrusResource TestCaseRunner runner) { + runner.variable("petId", "citrus:randomNumber(10)"); + + runner.when(extPetApi.sendGetPetWithSimpleStyleArrayExploded(List.of(1)) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/simple/exploded/1") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleArrayExploded("200")); + + } + + @Test + void java_array_value(@CitrusResource TestCaseRunner runner) { + runner.variable("petId", "citrus:randomNumber(10)"); + + runner.when(extPetApi.sendGetPetWithSimpleStyleArrayExploded(PET_ID_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/simple/exploded/1,2") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleArrayExploded("200")); + + } + + @Test + void java_array_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + runner.when( + extPetApi.sendGetPetWithSimpleStyleArrayExploded$(PET_ID_AS_STRING_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/simple/exploded/1,2") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleArrayExploded("200")); + + } + + @Test + void java_array_value_non_type_safe_with_variables( + @CitrusResource TestCaseRunner runner) { + runner.variable("one", "1"); + runner.variable("two", "2"); + + runner.when( + extPetApi.sendGetPetWithSimpleStyleArrayExploded$( + PET_ID_WITH_VARIABLE_EXPRESSIONS_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/simple/exploded/1,2") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleArrayExploded("200")); + + } + + @Test + void java_object_value(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi.sendGetPetWithSimpleStyleObjectExploded( + PET_IDENTIFIER) + .schemaValidation(false) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get( + "/api/v3/ext/pet/simple/exploded/object/alias=Alexander,name=Louis") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleObjectExploded("200")); + } + + @Test + void java_object_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi.sendGetPetWithSimpleStyleObjectExploded$( + PET_IDENTIFIER_AS_STRING) + .schemaValidation(false) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get( + "/api/v3/ext/pet/simple/exploded/object/alias=Alexander,name=Louis") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleObjectExploded("200")); + } + + } + } + + @Nested + class LabelStyle { + + @Nested + class Array { + + /** + * Non exploded representation is currently not supported by validator. + * Therefore, we get a validation exception. The other tests use disabled + * request validation to overcome this issue. + */ + @Test + void throws_request_validation_exception( + @CitrusResource TestCaseRunner runner) { + + HttpClientRequestActionBuilder builder = extPetApi.sendGetPetWithLabelStyleArray( + PET_ID_LIST) + .fork(false); + + assertThatThrownBy(() -> runner.when(builder)) + .isInstanceOf(TestCaseFailedException.class) + .hasCauseInstanceOf(ValidationException.class) + .hasMessageContaining( + "ERROR - Instance type (string) does not match any allowed primitive type (allowed: [\"integer\"]): []"); + } + + @Test + void java_single_value(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi.sendGetPetWithLabelStyleArray(List.of(1)) + .schemaValidation(true) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/label/.1") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithLabelStyleArray("200")); + + } + + @Test + void java_array_value(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi.sendGetPetWithLabelStyleArray(PET_ID_LIST) + .schemaValidation(false) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/label/.1,2") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithLabelStyleArray("200")); + + } + + @Test + void java_array_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi.sendGetPetWithLabelStyleArray$(PET_ID_AS_STRING_LIST) + .schemaValidation(false) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/label/.1,2") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithLabelStyleArray("200")); + + } + + @Test + void java_array_value_non_type_safe_with_variables( + @CitrusResource TestCaseRunner runner) { + runner.variable("one", "1"); + runner.variable("two", "2"); + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when( + extPetApi.sendGetPetWithLabelStyleArray$( + PET_ID_WITH_VARIABLE_EXPRESSIONS_LIST) + .schemaValidation(false) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/label/.1,2") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithLabelStyleArray("200")); + + } + + @Test + void java_object_value(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi.sendGetPetWithLabelStyleObject( + PET_IDENTIFIER) + .schemaValidation(false) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/label/object/.alias,Alexander,name,Louis") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithLabelStyleObject("200")); + } + + @Test + void java_object_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi.sendGetPetWithLabelStyleObject$(""" + {"name":"Louis","alias":"Alexander"} + """) + .schemaValidation(false) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/label/object/.alias,Alexander,name,Louis") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithLabelStyleObject("200")); + } + } + + @Nested + class ExplodedArray { + + @Test + void java_single_value(@CitrusResource TestCaseRunner runner) { + runner.variable("petId", "citrus:randomNumber(10)"); + + runner.when(extPetApi.sendGetPetWithLabelStyleArrayExploded(List.of(1)) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/label/exploded/.1") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithLabelStyleArrayExploded("200")); + + } + + @Test + void java_array_value(@CitrusResource TestCaseRunner runner) { + runner.variable("petId", "citrus:randomNumber(10)"); + + runner.when(extPetApi.sendGetPetWithLabelStyleArrayExploded(PET_ID_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/label/exploded/.1.2") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithLabelStyleArrayExploded("200")); + + } + + @Test + void java_array_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + runner.when( + extPetApi.sendGetPetWithLabelStyleArrayExploded$(PET_ID_AS_STRING_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/label/exploded/.1.2") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithLabelStyleArrayExploded("200")); + + } + + @Test + void java_array_value_non_type_safe_with_variables( + @CitrusResource TestCaseRunner runner) { + runner.variable("one", "1"); + runner.variable("two", "2"); + + runner.when( + extPetApi.sendGetPetWithLabelStyleArrayExploded$( + PET_ID_WITH_VARIABLE_EXPRESSIONS_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/label/exploded/.1.2") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithLabelStyleArrayExploded("200")); + + } + + @Test + void java_object_value(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi.sendGetPetWithLabelStyleObjectExploded$(""" + {"name":"Louis","alias":"Alexander"} + """) + .schemaValidation(false) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get( + "/api/v3/ext/pet/label/exploded/object/.alias=Alexander.name=Louis") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithLabelStyleObjectExploded("200")); + } + + @Test + void java_object_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi.sendGetPetWithLabelStyleObjectExploded( + PET_IDENTIFIER) + .schemaValidation(false) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get( + "/api/v3/ext/pet/label/exploded/object/.alias=Alexander.name=Louis") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithLabelStyleObjectExploded("200")); + } + } + + } + + @Nested + class MatrixStyle { + + @Nested + class Array { + + @Test + void java_single_value(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithMatrixStyleArray(List.of(1)) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/matrix/;petId=1") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithMatrixStyleArray("200")); + + } + + @Test + void java_array_value(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithMatrixStyleArray(PET_ID_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/matrix/;petId=1,2") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithMatrixStyleArray("200")); + + } + + @Test + void java_array_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithMatrixStyleArray$(PET_ID_AS_STRING_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/matrix/;petId=1,2") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithMatrixStyleArray("200")); + + } + + @Test + void java_array_value_non_type_safe_with_variables( + @CitrusResource TestCaseRunner runner) { + runner.variable("one", "1"); + runner.variable("two", "2"); + + runner.when( + extPetApi.sendGetPetWithMatrixStyleArray$( + PET_ID_WITH_VARIABLE_EXPRESSIONS_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/matrix/;petId=1,2") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithMatrixStyleArray("200")); + + } + + @Test + void java_object_value(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi.sendGetPetWithMatrixStyleObject( + PET_IDENTIFIER) + .schemaValidation(false) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/matrix/object/;petId=alias,Alexander,name,Louis") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithMatrixStyleObject("200")); + } + + @Test + void java_object_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi.sendGetPetWithMatrixStyleObject$( + PET_IDENTIFIER_AS_STRING) + .schemaValidation(false) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/matrix/object/;petId=alias,Alexander,name,Louis") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithMatrixStyleObject("200")); + } + + } + + @Nested + class ExplodedArray { + + @Test + void java_single_value(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithMatrixStyleArrayExploded(List.of(1)) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/matrix/exploded/;petId=1") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithMatrixStyleArrayExploded("200")); + + } + + @Test + void java_array_value(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithMatrixStyleArrayExploded(PET_ID_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/matrix/exploded/;petId=1;petId=2") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithMatrixStyleArrayExploded("200")); + + } + + @Test + void java_array_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + runner.when( + extPetApi.sendGetPetWithMatrixStyleArrayExploded$(PET_ID_AS_STRING_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/matrix/exploded/;petId=1;petId=2") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithMatrixStyleArrayExploded("200")); + + } + + @Test + void java_array_value_non_type_safe_with_variables( + @CitrusResource TestCaseRunner runner) { + + runner.variable("one", "1"); + runner.variable("two", "2"); + + runner.when( + extPetApi.sendGetPetWithMatrixStyleArrayExploded$( + PET_ID_WITH_VARIABLE_EXPRESSIONS_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/matrix/exploded/;petId=1;petId=2") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithMatrixStyleArrayExploded("200")); + + } + + @Test + void java_object_value(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi.sendGetPetWithMatrixStyleObjectExploded( + PET_IDENTIFIER) + .schemaValidation(false) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get( + "/api/v3/ext/pet/matrix/exploded/object/;alias=Alexander;name=Louis") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithMatrixStyleObject("200")); + } + + @Test + void java_object_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi.sendGetPetWithMatrixStyleObjectExploded$( + PET_IDENTIFIER_AS_STRING) + .schemaValidation(false) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get( + "/api/v3/ext/pet/matrix/exploded/object/;alias=Alexander;name=Louis") + .message()); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithMatrixStyleObject("200")); + } + + } + } + } + + @Nested + class HeaderParameter { + + @Nested + class SimpleStyle { + + @Nested + class Array { + + + @Test + void java_single_value(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithSimpleStyleHeader(List.of(1)) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/header/simple") + .message().header("petId", "1")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleHeader("200")); + + } + + @Test + void java_array_value(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithSimpleStyleHeader(PET_ID_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/header/simple") + .message().header("petId", "1,2")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleHeader("200")); + + } + + @Test + void java_array_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithSimpleStyleHeader$( + PET_ID_AS_STRING_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/header/simple") + .message().header("petId", "1,2")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleHeader("200")); + + } + + @Test + void java_array_value_non_type_safe_with_variables( + @CitrusResource TestCaseRunner runner) { + + runner.variable("one", "1"); + runner.variable("two", "2"); + + runner.when(extPetApi.sendGetPetWithSimpleStyleHeader$( + PET_ID_WITH_VARIABLE_EXPRESSIONS_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/header/simple") + .message().header("petId", "1,2")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleHeader("200")); + + } + + @Test + void java_object_value(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi + .sendGetPetWithSimpleStyleObjectHeader( + PET_IDENTIFIER) + .schemaValidation(false) + .fork(true)); + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/header/simple/object") + .message().header("petId", "alias,Alexander,name,Louis")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleExplodedHeader("200")); + } + + @Test + void java_object_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi + .sendGetPetWithSimpleStyleObjectHeader$( + PET_IDENTIFIER_AS_STRING) + .schemaValidation(false) + .fork(true)); + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/header/simple/object") + .message().header("petId", "alias,Alexander,name,Louis")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleExplodedHeader("200")); + } + + } + + @Nested + class ArrayExploded { + + @Test + void java_single_value(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithSimpleStyleExplodedHeader(List.of(1)) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/header/simple/exploded") + .message().header("petId", "1")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleExplodedHeader("200")); + + } + + @Test + void java_array_value(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithSimpleStyleExplodedHeader(PET_ID_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/header/simple/exploded") + .message().header("petId", "1,2")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleExplodedHeader("200")); + + } + + @Test + void java_array_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithSimpleStyleExplodedHeader$( + PET_ID_AS_STRING_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/header/simple/exploded") + .message().header("petId", "1,2")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleExplodedHeader("200")); + + } + + @Test + void java_array_value_non_type_safe_with_variables( + @CitrusResource TestCaseRunner runner) { + + runner.variable("one", "1"); + runner.variable("two", "2"); + + runner.when(extPetApi.sendGetPetWithSimpleStyleExplodedHeader$( + PET_ID_WITH_VARIABLE_EXPRESSIONS_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/header/simple/exploded") + .message().header("petId", "1,2")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithSimpleStyleExplodedHeader("200")); + + } + + @Test + void java_object_value(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi + .sendGetPetWithSimpleStyleExplodedObjectHeader( + PET_IDENTIFIER) + .schemaValidation(false) + .fork(true)); + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/header/simple/exploded/object") + .message().header("petId", "alias=Alexander,name=Louis")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when( + extPetApi.receiveGetPetWithSimpleStyleExplodedObjectHeader("200")); + } + + @Test + void java_object_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi + .sendGetPetWithSimpleStyleExplodedObjectHeader$( + PET_IDENTIFIER_AS_STRING) + .schemaValidation(false) + .fork(true)); + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/header/simple/exploded/object") + .message().header("petId", "alias=Alexander,name=Louis")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when( + extPetApi.receiveGetPetWithSimpleStyleExplodedObjectHeader("200")); + } + } + + } + + } + + @Nested + class QueryParameter { + + @Nested + class FormStyle { + + @Nested + class Array { + + @Test + void java_single_value(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithFormStyleQuery(List.of(1)) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/query/form") + .message().queryParam("petId", "1")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithFormStyleQuery("200")); + + } + + @Test + void java_arrya_value(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithFormStyleQuery(PET_ID_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/query/form") + .message().queryParam("petId", "1,2")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithFormStyleQuery("200")); + } + + @Test + void java_arrya_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithFormStyleQuery$(PET_ID_AS_STRING_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/query/form") + .message().queryParam("petId", "1,2")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithFormStyleQuery("200")); + } + + @Test + void java_arrya_value_non_type_safe_with_variables( + @CitrusResource TestCaseRunner runner) { + + runner.variable("one", "1"); + runner.variable("two", "2"); + + runner.when(extPetApi.sendGetPetWithFormStyleQuery$( + PET_ID_WITH_VARIABLE_EXPRESSIONS_LIST) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/query/form") + .message().queryParam("petId", "1,2")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithFormStyleQuery("200")); + } + + @Test + void java_object_value(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi + .sendGetPetWithFormStyleObjectQuery( + PET_IDENTIFIER) + .schemaValidation(false) + .fork(true)); + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/query/form/object") + .message().queryParam("petId", "alias,Alexander,name,Louis")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithFormStyleObjectQuery("200")); + } + + @Test + void java_object_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi + .sendGetPetWithFormStyleObjectQuery$( + PET_IDENTIFIER_AS_STRING) + .schemaValidation(false) + .fork(true)); + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/query/form/object") + .message().queryParam("petId", "alias,Alexander,name,Louis")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithFormStyleObjectQuery("200")); + } + } + + @Nested + class ArrayExploded { + + @Test + void java_single_value(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithFormStyleExplodedQuery(List.of(1)) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/query/form/exploded") + .message().queryParam("petId", "1")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithFormStyleQuery("200")); + + } + + @Test + void java_array_value(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithFormStyleExplodedQuery(PET_ID_LIST) + .fork(true)); + + // Note that citrus currently fails to validate a query parameter array. Thus, we + // assert against the query_params header. + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/query/form/exploded") + .message() + .queryParam("petId", "1") + .queryParam("petId", "2")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithFormStyleQuery("200")); + } + + @Test + void java_array_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + runner.when( + extPetApi.sendGetPetWithFormStyleExplodedQuery$(PET_ID_AS_STRING_LIST) + .fork(true)); + + // Note that citrus currently fails to validate a query parameter array. Thus, we + // assert against the query_params header. + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/query/form/exploded") + .message() + .queryParam("petId", "1") + .queryParam("petId", "2")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithFormStyleQuery("200")); + } + + @Test + void java_array_value_non_type_safe_with_variables( + @CitrusResource TestCaseRunner runner) { + + runner.variable("one", "1"); + runner.variable("two", "2"); + + runner.when(extPetApi.sendGetPetWithFormStyleExplodedQuery$( + PET_ID_WITH_VARIABLE_EXPRESSIONS_LIST) + .fork(true)); + + // Note that citrus currently fails to validate a query parameter array. Thus, we + // assert against the query_params header. + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/query/form/exploded") + .message() + .queryParam("petId", "1") + .queryParam("petId", "2")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithFormStyleQuery("200")); + } + + @Test + void java_object_value(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi + .sendGetPetWithFormStyleExplodedObjectQuery( + PET_IDENTIFIER) + .fork(true)); + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/query/form/exploded/object") + .message() + .queryParam("alias", "Alexander") + .queryParam("name", "Louis")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithFormStyleObjectQuery("200")); + } + + @Test + void java_object_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi + .sendGetPetWithFormStyleExplodedObjectQuery$( + PET_IDENTIFIER_AS_STRING) + .fork(true)); + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/query/form/exploded/object") + .message() + .queryParam("alias", "Alexander") + .queryParam("name", "Louis")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithFormStyleObjectQuery("200")); + } + } + } + + @Nested + class DeepObjectStyleExploded { + + @Nested + class ArrayExploded { + + @Test + void java_object_value(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi + .sendGetPetWithDeepObjectTypeQuery( + PET_IDENTIFIER) + .fork(true)); + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/query/deep/object") + .message() + .queryParam("petId[alias]", "Alexander") + .queryParam("petId[name]", "Louis")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithDeepObjectTypeQuery("200")); + } + + @Test + void java_object_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi + .sendGetPetWithDeepObjectTypeQuery$( + PET_IDENTIFIER_AS_STRING) + .fork(true)); + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/query/deep/object") + .message() + .queryParam("petId[alias]", "Alexander") + .queryParam("petId[name]", "Louis")); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithDeepObjectTypeQuery("200")); + } + } + } + } + + @Nested + class CookieParameter { + + @Nested + class FormStyle { + + @Nested + class Array { + + @Test + void java_single_value(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithFormStyleCookie(List.of(1)) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/cookie/form") + .message().cookie(new Cookie("petId", "1"))); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithFormStyleCookie("200")); + + } + + @Test + void java_array_value(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithFormStyleCookie(PET_ID_LIST) + .fork(true)); + + // Cookies may not contain "," which is used to separate array values. + // Therefore, cookies are URL encoded and reach the server accordingly. + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/cookie/form") + .message().cookie(new Cookie("petId", "1%2C2"))); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithFormStyleCookie("200")); + + } + + @Test + void java_array_value_non_type_safe(@CitrusResource TestCaseRunner runner) { + + runner.when(extPetApi.sendGetPetWithFormStyleCookie$(PET_ID_AS_STRING_LIST) + .fork(true)); + + // Cookies may not contain "," which is used to separate array values. + // Therefore, cookies are URL encoded and reach the server accordingly. + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/cookie/form") + .message().cookie(new Cookie("petId", "1%2C2"))); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithFormStyleCookie("200")); + + } + + @Test + void java_array_value_non_type_safe_with_variables( + @CitrusResource TestCaseRunner runner) { + + runner.variable("one", "1"); + runner.variable("two", "2"); + + runner.when(extPetApi.sendGetPetWithFormStyleCookie$( + PET_ID_WITH_VARIABLE_EXPRESSIONS_LIST) + .fork(true)); + + // Cookies may not contain "," which is used to separate array values. + // Therefore, cookies are URL encoded and reach the server accordingly. + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/cookie/form") + .message().cookie(new Cookie("petId", "1%2C2"))); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithFormStyleCookie("200")); + + } + + @Test + void java_object_value(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi.sendGetPetWithFormObjectStyleCookie( + PET_IDENTIFIER) + .schemaValidation(false) + .fork(true)); + + // Cookies may not contain "," which is used to separate array values. + // Therefore, cookies are URL encoded and reach the server accordingly. + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/cookie/form/object") + .message() + .cookie(new Cookie("petId", "alias%2CAlexander%2Cname%2CLouis"))); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithFormStyleCookie("200")); + + } + + @Test + void java_object_value_none_type(@CitrusResource TestCaseRunner runner) { + + // Note that we need to disable oas validation here, as validation is + // currently not supported with the chosen serialization approach. + runner.when(extPetApi.sendGetPetWithFormObjectStyleCookie$( + PET_IDENTIFIER_AS_STRING) + .schemaValidation(false) + .fork(true)); + + // Cookies may not contain "," which is used to separate array values. + // Therefore, cookies are URL encoded and reach the server accordingly. + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/cookie/form/object") + .message() + .cookie(new Cookie("petId", "alias%2CAlexander%2Cname%2CLouis"))); + + runner.then(http().server(httpServer) + .send() + .response(OK).message() + .contentType("application/json") + .body("[]")); + + runner.when(extPetApi.receiveGetPetWithFormStyleCookie("200")); + + } + } + } + } + + /** + * Demonstrates testing of array data in query parameters. + */ + @Nested + class Combined { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withArrayQueryDataTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + runner.variable("petId", "1234"); + runner.variable("nick1", "Wind"); + runner.variable("nick2", "Storm"); + runner.variable("tag2", "tag2Value"); + + runner.when(extPetApi + .sendUpdatePetWithArrayQueryData$("${petId}", "Thunder", "sold", + List.of("tag1", "${tag2}"), + List.of("${nick1}", "${nick2}"), "header1") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .put("/api/v3/ext/pet/1234") + .message() + .validate(ScriptValidationContext.Builder.groovy().script(""" + assert receivedMessage.getHeader("sampleStringHeader") == header1 + org.assertj.core.api.Assertions.assertThat(((org.citrusframework.http.message.HttpMessage)receivedMessage).getQueryParams()).containsExactlyInAnyOrderEntriesOf( + java.util.Map.of( + "tags", java.util.List.of("tag1", "tag2Value"), + "name", java.util.List.of("Thunder"), + "nicknames", java.util.List.of("Wind", "Storm"), + "status", java.util.List.of("sold") + """)) + .validate((message, context) -> { + assertThat(message.getHeader("sampleStringHeader")).isEqualTo("header1"); + assertThat( + ((HttpMessage) message).getQueryParams()).containsExactlyInAnyOrderEntriesOf( + Map.of( + "tags", List.of("tag1", "tag2Value"), + "name", List.of("Thunder"), + "nicknames", List.of("Wind", "Storm"), + "status", List.of("sold") + ) + ); + })); + + runner.then(http().server(httpServer) + .send() + .response(OK)); + + runner.when(extPetApi + .receiveUpdatePetWithArrayQueryData(OK) + .message()); + + } + } + } + + /** + * Demonstrates the usage of form data. + */ + @Nested + class FormData { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withFormDataTest") + void xml() { + } + + @Test + void updatePetWithForm_java(@CitrusResource TestCaseRunner runner) { + runner.variable("petId", "citrus:randomNumber(10)"); + + runner.when(petApi.sendUpdatePetWithForm$("${petId}") + ._name("Tom") + .status("sold") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .post("/api/v3/pet/${petId}") + .message() + .queryParam("name", "Tom") + .queryParam("status", "sold")); + + runner.then(http().server(httpServer) + .send() + .response(OK)); + + runner.when(petApi.receiveUpdatePetWithForm("200")); + + } + } + + /** + * Demonstrates the usage of validation is disablement in API requests and + * responses. + */ + @Nested + class DisabledValidation { + + /** + * Test scenarios where response validation is disabled for the API requests. + */ + @Nested + class ResponseValidationDisabled { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withResponseValidationDisabledTest") + void xml() { + } + + @Test + void java( + @CitrusResource TestCaseRunner runner) { + + runner.variable("petId", "1234"); + + runner.when(petApi + .sendGetPetById$("${petId}") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/pet/${petId}") + .message() + .accept("@contains('application/json')@")); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/invalidGetPetById_response.json")) + .contentType("application/json")); + + runner.when(petApi + .receiveGetPetById(OK) + .schemaValidation(false)); + + } + } + } + + /** + * Contains test cases for scenarios where validation failures are expected. + */ + @Nested + class ValidationFailures { + + /** + * Tests where validation fails due to an incorrect reason phrase in the API response. + */ + @Nested + class FailOnReasonPhrase { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withFailOnReasonPhraseTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + + runner.variable("petId", "1234"); + + runner.when(petApi + .sendGetPetById$("${petId}") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/pet/${petId}") + .message() + .accept("@contains('application/json')@")); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json")) + .contentType("application/json")); + + HttpClientResponseActionBuilder.HttpMessageBuilderSupport builder = petApi + .receiveGetPetById(OK).message().reasonPhrase("Almost OK"); + assertThatThrownBy(() -> runner.when(builder)).isInstanceOf( + TestCaseFailedException.class) + .hasMessageContaining( + "Values not equal for header element 'citrus_http_reason_phrase', expected 'Almost OK' but was 'OK'") + .hasCauseInstanceOf(ValidationException.class); + } + } + + /** + * Tests where validation fails due to an incorrect HTTP status in the API response. + */ + @Nested + class FailOnStatus { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withFailOnStatusTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + + runner.variable("petId", "1234"); + + runner.when(petApi + .sendGetPetById$("${petId}") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/pet/${petId}") + .message() + .accept("@contains('application/json')@")); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json")) + .contentType("application/json")); + + GetPetByIdReceiveActionBuilder getPetByIdResponseActionBuilder = petApi + .receiveGetPetById("201"); + assertThatThrownBy(() -> runner.when(getPetByIdResponseActionBuilder)).isInstanceOf( + TestCaseFailedException.class) + .hasMessageContaining( + "Values not equal for header element 'citrus_http_reason_phrase', expected 'CREATED' but was 'OK'") + .hasCauseInstanceOf(ValidationException.class); + } + } + + /** + * Tests where validation fails due to an incorrect HTTP version in the API response. + */ + @Nested + class FailOnVersion { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withFailOnVersionTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + + runner.variable("petId", "1234"); + + runner.when(petApi + .sendGetPetById$("${petId}") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/pet/${petId}") + .message() + .accept("@contains('application/json')@")); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json")) + .contentType("application/json")); + + HttpClientResponseActionBuilder.HttpMessageBuilderSupport builder = petApi + .receiveGetPetById(OK).message().version("HTTP/1.0"); + assertThatThrownBy(() -> runner.when(builder)).isInstanceOf( + TestCaseFailedException.class) + .hasMessageContaining( + "Values not equal for header element 'citrus_http_version', expected 'HTTP/1.0' but was 'HTTP/1.1'") + .hasCauseInstanceOf(ValidationException.class); + } + } + + /** + * Tests where validation fails due to an invalid response body. + */ + @Nested + class FailOnInvalidResponse { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withFailOnInvalidResponseTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + + runner.variable("petId", "1234"); + + runner.when(petApi + .sendGetPetById$("${petId}") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/pet/${petId}") + .message() + .accept("@contains('application/json')@")); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/invalidGetPetById_response.json")) + .contentType("application/json")); + + GetPetByIdReceiveActionBuilder getPetByIdResponseActionBuilder = petApi.receiveGetPetById( + OK); + assertThatThrownBy(() -> runner.when(getPetByIdResponseActionBuilder)).isInstanceOf( + TestCaseFailedException.class) + .hasMessageContaining("Object has missing required properties ([\"name\"]): []") + .hasCauseInstanceOf(ValidationException.class); + + } + } + + /** + * Tests where validation fails due to an incorrect body resource during validation. + */ + @Nested + class FailOnBodyResourceValidation { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withFailOnBodyResourceValidationTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + + runner.variable("petId", "1234"); + + runner.when(petApi + .sendGetPetById$("${petId}") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/pet/${petId}") + .message() + .accept("@contains('application/json')@")); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json")) + .contentType("application/json")); + + HttpClientResponseActionBuilder.HttpMessageBuilderSupport builder = petApi + .receiveGetPetById(OK).message().body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/thisAintNoPed.json")); + assertThatThrownBy(() -> runner.when(builder)).isInstanceOf( + TestCaseFailedException.class) + .hasMessageContaining( + "Number of entries is not equal in element: '$', expected '[description]' but was '[photoUrls, name, id, category, tags, status]'") + .hasCauseInstanceOf(ValidationException.class); + + } + } + + /** + * Tests where validation fails due to incorrect data in the response body. + */ + @Nested + class FailOnBodyDataValidation { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withFailOnBodyDataValidationTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + + runner.variable("petId", "1234"); + + runner.when(petApi + .sendGetPetById$("${petId}") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/pet/${petId}") + .message() + .accept("@contains('application/json')@")); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json")) + .contentType("application/json")); + + HttpClientResponseActionBuilder.HttpMessageBuilderSupport builder = petApi + .receiveGetPetById(OK).message().body(""" + {"description": "no pet"}"""); + assertThatThrownBy(() -> runner.when(builder)).isInstanceOf( + TestCaseFailedException.class) + .hasMessageContaining( + "Number of entries is not equal in element: '$', expected '[description]' but was '[photoUrls, name, id, category, tags, status]'") + .hasCauseInstanceOf(ValidationException.class); + + } + } + + /** + * Tests where validation fails due to invalid JSON path expressions in the response body. + */ + @Nested + class FailOnJsonPathInvalid { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withFailOnJsonPathInvalidTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + + runner.variable("petId", "1234"); + + runner.when(petApi + .sendGetPetById$("${petId}") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/pet/${petId}") + .message() + .accept("@contains('application/json')@")); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json")) + .contentType("application/json")); + + HttpClientResponseActionBuilder.HttpMessageBuilderSupport builder = petApi + .receiveGetPetById(OK).message() + .validate(jsonPath().expression("$.name", "unknown")); + assertThatThrownBy(() -> runner.when(builder)) + .isInstanceOf(TestCaseFailedException.class) + .hasMessageContaining( + "Values not equal for element '$.name', expected 'unknown' but was") + .hasCauseInstanceOf(ValidationException.class); + + } + } + } + + /** + * Demonstrates the usage of a TestActor to control execution of test actions. + */ + @Nested + class Actor { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withActorTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + runner.variable("petId", "1234"); + + runner.when(petApi + .sendGetPetById$("${petId}") + .actor(petStoreActor) + .fork(true)); + + HttpMessageBuilderSupport builder = http().server(httpServer) + .receive() + .get("/api/v3/pet/${petId}") + .message() + .accept("@contains('application/json')@"); + + assertThatThrownBy(() -> runner.$(builder)) + .isInstanceOf(TestCaseFailedException.class) + .hasCauseInstanceOf(MessageTimeoutException.class) + .hasMessageContaining( + "Action timeout after 5000 milliseconds. Failed to receive message on endpoint: 'httpServer.inbound'"); + } + } + + /** + * Demonstrates the usage of a specific URI for sending HTTP requests in tests. + */ + @Nested + class SpecificUri { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withSpecificUriTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + runner.variable("petId", "1234"); + + runner.when(petApi + .sendGetPetById$("${petId}") + .uri("http://localhost:${petstoreApplicationPort}") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/pet/${petId}") + .message() + .accept("@contains('application/json')@")); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json")) + .contentType("application/json")); + + runner.then(petApi.receiveGetPetById(OK) + .message() + .validate(jsonPath().expression("$.name", "@matches('hasso|cutie|fluffy')@")) + ); + } + } + + /** + * Demonstrates the usage of a specific endpoint for sending HTTP requests in tests. + */ + @Nested + class SpecificEndpoint { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withSpecificEndpointTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + runner.variable("petId", "1234"); + + runner.when(petApi + .sendGetPetById$("${petId}").endpoint(otherApplicationServiceClient) + .fork(true)); + + runner.then(http().server(otherHttpServer) + .receive() + .get("/api/v3/pet/${petId}") + .message() + .accept("@contains('application/json')@")); + + runner.then(http().server(otherHttpServer) + .send() + .response(OK) + .message() + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json")) + .contentType("application/json")); + + runner.then(petApi.receiveGetPetById(OK).endpoint(otherApplicationServiceClient) + .message() + .validate(jsonPath().expression("$.name", "@matches('hasso|cutie|fluffy')@")) + ); + } + } + + /** + * Demonstrates the usage of a nested element within an XML configuration for + * testing. + */ + @Nested + class NestedReceiveInXml { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withNestedReceiveInXmlTest") + void xml() { + } + + } + + /** + * Demonstrates the usage of different authentication mechanisms for testing. + */ + @Nested + class Security { + + @Nested + class BasicAuthentication { + + /** + * Demonstrates basic authentication using global credentials from properties. + */ + @Nested + class BasicAuthenticationFromProperties { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withBasicAuthenticationFromPropertiesTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + runner.variable("petId", "1234"); + + runner.when(extPetApi + .sendGetPetByIdWithBasicAuthentication$("${petId}", "true") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/secure-basic/pet/${petId}") + .message() + .header("Authorization", "Basic ZXh0VXNlcjpleHRQYXNzd29yZA==")); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json")) + .contentType("application/json")); + + runner.when(extPetApi + .receiveGetPetByIdWithBasicAuthentication(OK) + .message()); + + } + + } + + /** + * Demonstrates specific basic authentication with custom credentials. + */ + @Nested + class WithBasicAuthenticationOverridingProperties { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withBasicAuthenticationOverridingPropertiesTest") + void xml() { + } + + @Test + void java( + @CitrusResource TestCaseRunner runner) { + runner.variable("petId", "1234"); + + runner.when(extPetApi + .sendGetPetByIdWithBasicAuthentication$("${petId}", "true") + .basicAuthUsername("admin") + .basicAuthPassword("topSecret") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/secure-basic/pet/${petId}") + .message().header("Authorization", "Basic YWRtaW46dG9wU2VjcmV0")); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json")) + .contentType("application/json")); + + runner.when(extPetApi + .receiveGetPetByIdWithBasicAuthentication(OK) + .message()); + + } + + } + } + + @Nested + class BearerAuthentication { + + /** + * Demonstrates bearer authentication using a global token from properties. + */ + @Nested + class WithBasicBearerAuthenticationFromProperties { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withBasicBearerAuthenticationFromPropertiesTest") + void xml() { + } + + @Test + void java( + @CitrusResource TestCaseRunner runner) { + runner.variable("petId", "1234"); + + runner.when(extPetApi + .sendGetPetByIdWithBearerAuthentication$("${petId}", "true") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/secure-bearer/pet/${petId}") + .message() + .header("Authorization", "Bearer ZGVmYXVsdEJlYXJlclRva2Vu")); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json")) + .contentType("application/json")); + + runner.when(extPetApi + .receiveGetPetByIdWithBearerAuthentication(OK) + .message()); + + } + } + + /** + * Demonstrates bearer authentication using specific token. + */ + @Nested + class WithBasicBearerAuthenticationOverridingProperties { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withBasicBearerAuthenticationOverridingPropertiesTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + runner.variable("petId", "1234"); + + runner.when(extPetApi + .sendGetPetByIdWithBearerAuthentication$("${petId}", "true") + .basicAuthBearer("bearerToken") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/secure-bearer/pet/${petId}") + .message().header("Authorization", "Bearer YmVhcmVyVG9rZW4=")); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json")) + .contentType("application/json")); + + runner.when(extPetApi + .receiveGetPetByIdWithBearerAuthentication(OK) + .message()); + + } + + } + + } + + + @Nested + class ApiKeyAuthentication { + + + /** + * Demonstrates API key authentication using default values from properties. + */ + @Nested + class ApiKeyAuthenticationFromProperties { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withApiKeysFromPropertiesTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + + runner.variable("petId", "1234"); + + runner.when(extPetApi + .sendGetPetByIdWithApiKeyAuthentication$("${petId}", "false") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/secure-api-key/pet/${petId}") + .message() + .header("api_key_header", + "citrus:encodeBase64('defaultTopSecretHeaderApiKey')") + .cookie(new Cookie("api_key_cookie", + "citrus:encodeBase64('defaultTopSecretCookieApiKey')")) + .queryParam("api_key_query", + "citrus:encodeBase64('defaultTopSecretQueryApiKey')") + .accept("@contains('application/json')@")); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/invalidGetPetById_response.json")) + .contentType("application/json")); + + runner.when(extPetApi + .receiveGetPetByIdWithApiKeyAuthentication(OK) + .schemaValidation(false)); + } + + } + + /** + * Demonstrates API key authentication with custom values overriding properties. + */ + @Nested + class ApiKeyAuthenticationOverridingProperties { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withApiKeysOverridingPropertiesTest") + void xml() { + } + + @Test + void java( + @CitrusResource TestCaseRunner runner) { + + runner.variable("petId", "1234"); + runner.variable("apiKeyHeader", "TopSecretHeader"); + runner.variable("apiKeyCookie", "TopSecretCookie"); + runner.variable("apiKeyQuery", "TopSecretQuery"); + + runner.when(extPetApi + .sendGetPetByIdWithApiKeyAuthentication$("${petId}", "false") + .apiKeyHeader("${apiKeyHeader}") + .apiKeyCookie("${apiKeyCookie}") + .apiKeyQuery("${apiKeyQuery}") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/secure-api-key/pet/${petId}") + .message() + .header("api_key_header", "citrus:encodeBase64('TopSecretHeader')") + .cookie( + new Cookie("api_key_cookie", "citrus:encodeBase64('TopSecretCookie')")) + .queryParam("api_key_query", "citrus:encodeBase64('TopSecretQuery')") + .accept("@contains('application/json')@")); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/invalidGetPetById_response.json")) + .contentType("application/json")); + + runner.when(extPetApi + .receiveGetPetByIdWithApiKeyAuthentication(OK) + .schemaValidation(false)); + } + } + } + } + + /** + * Demonstrates testing of multipart requests. + */ + @Nested + class Multipart { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withMultiPartTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) throws IOException { + + byte[] templateData = FileUtils.copyToByteArray( + Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/vaccinationTemplate.bin")); + String additionalData = FileUtils.readToString(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/vaccinationAdditionalData.json")); + + runner.when(extPetApi.sendGenerateVaccinationReport$( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/vaccinationTemplate.bin", + "1") + .additionalData(additionalData) + .optIntVal(100) + .optBoolVal(true) + .optStringVal("a") + .optNumberVal(BigDecimal.valueOf(1L)) + .optDateVal(LocalDate.of(2024, 12, 1)) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .post("/api/v3/ext/pet/vaccination/status-report") + .message() + .validate((message, context) -> + Assertions.assertThat(multipartMessageToMap((HttpMessage) message)) + .containsExactlyInAnyOrderEntriesOf(Map.of( + "additionalData", additionalData, + "reqIntVal", "1", + "template", templateData, + "optIntVal", "100", + "optBoolVal", "true", + "optDateVal", "[2024,12,1]", + "optNumberVal", "1", + "optStringVal", "a")) + ) + ); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message().contentType("application/pdf") + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/vaccinationReport.pdf"))); + + runner.then(extPetApi.receiveGenerateVaccinationReport(OK)); + } + } + + /** + * Demonstrates testing of requests using additional, non-API query parameters, headers, and + * cookies. + */ + @Nested + class NonApiQueryParameters { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withNonApiQueryParamTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + runner.variable("petId", "citrus:randomNumber(10)"); + + runner.when(petApi.sendUpdatePet() + .message().body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json")) + .queryParam("nonApiQueryParam", "nonApiQueryParamValue") + .header("nonApiHeader", "nonApiHeaderValue") + .cookie(new Cookie("nonApiCookie", "nonApiCookieValue")) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .put("/api/v3/pet") + .message() + .queryParam("nonApiQueryParam", "nonApiQueryParamValue") + .header("nonApiHeader", "nonApiHeaderValue") + .cookie(new Cookie("nonApiCookie", "nonApiCookieValue")) + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response_validation.json"))); + + runner.then(http().server(httpServer) + .send() + .response(OK)); + + runner.when(petApi.receiveUpdatePetWithForm("200")); + + } + + } + + /** + * Demonstrates testing of form URL-encoded data in requests. + */ + @Nested + class FormUrlEncoded { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withFormUrlEncodedTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + runner.variable("petId", "1234"); + runner.variable("nick1", "Wind"); + runner.variable("nick2", "Storm"); + runner.variable("tag2", "tag2Value"); + + runner.when(extPetApi + .sendUpdatePetWithFormUrlEncoded$("${petId}", "Thunder", "sold", "5", + List.of("tag1", "${tag2}")) + .nicknames( + "${nick1}", + "${nick2}", + URLEncoder.encode("Wei{:/?#[]@!$&'()*+,;=%\"<>^`{|}~ }rd", + StandardCharsets.UTF_8) + ) + .owners("2") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .put("/api/v3/ext/pet/form/1234") + .message() + .contentType("application/x-www-form-urlencoded") + .validate((Message message, TestContext context) -> + assertThat(message.getPayload(String.class)) + .contains("name=Thunder") + .contains("status=sold") + .contains("nicknames=Wind") + .contains("nicknames=Storm") + .contains("tags=tag2") + .contains("tags=tag2Value") + .contains("age=5") + .contains( + "nicknames=Wei%257B%253A%252F%253F%2523%255B%255D%2540%2521%2524%2526%2527%2528%2529*%252B%252C%253B%253D%2525%2522%253C%253E%255E%2560%257B%257C%257D%257E%2B%257Drd") + )); + + runner.then(http().server(httpServer) + .send() + .response(OK)); + + runner.when(extPetApi + .receiveUpdatePetWithFormUrlEncoded(OK) + .message()); + + } + } + + /** + * Demonstrates testing of requests using the type-safe Java DSL. + */ + @Nested + class TypeSafeJavaDsl { + + @Test + void java(@CitrusResource TestCaseRunner runner) { + runner.variable("petId", "1234"); + runner.variable("nick1", "Wind"); + runner.variable("nick2", "Storm"); + runner.variable("tag2", "tag2Value"); + + runner.when(extPetApi + .sendUpdatePetWithFormUrlEncoded(1234L, "Thunder", "sold", 5, + List.of("tag1", "${tag2}")) + .nicknames( + "${nick1}", + "${nick2}", + URLEncoder.encode("Wei{:/?#[]@!$&'()*+,;=%\"<>^`{|}~ }rd", + StandardCharsets.UTF_8) + ) + .owners("2") + .fork(true)); + runner.then(http().server(httpServer) + .receive() + .put("/api/v3/ext/pet/form/1234") + .message() + .contentType("application/x-www-form-urlencoded") + .validate((Message message, TestContext context) -> + assertThat(message.getPayload(String.class)) + .contains("name=Thunder") + .contains("status=sold") + .contains("nicknames=Wind") + .contains("nicknames=Storm") + .contains("tags=tag2") + .contains("tags=tag2Value") + .contains("age=5") + .contains( + "nicknames=Wei%257B%253A%252F%253F%2523%255B%255D%2540%2521%2524%2526%2527%2528%2529*%252B%252C%253B%253D%2525%2522%253C%253E%255E%2560%257B%257C%257D%257E%2B%257Drd") + )); + + runner.then(http().server(httpServer) + .send() + .response(OK)); + + runner.when(extPetApi + .receiveUpdatePetWithFormUrlEncoded(OK) + .message()); + + } + } + + /** + * Demonstrates testing of plain text bodies in requests. + */ + @Nested + class BodyAsPlainText { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withBodyAsPlainTextTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + runner.variable("petId", "citrus:randomNumber(10)"); + + runner.when(petApi.sendUpdatePet() + .message().body(""" + { + "id": ${petId}, + "name": "citrus:randomEnumValue('hasso','cutie','fluffy')", + "category": { + "id": ${petId}, + "name": "citrus:randomEnumValue('dog', 'cat', 'fish')" + }, + "photoUrls": [ + "http://localhost:8080/photos/${petId}" + ], + "tags": [ + { + "id": ${petId}, + "name": "generated" + } + ], + "status": "citrus:randomEnumValue('available', 'pending', 'sold')" + } + """) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .put("/api/v3/pet") + .message().body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response_validation.json"))); + + runner.then(http().server(httpServer) + .send() + .response(OK)); + + runner.when(petApi.receiveUpdatePetWithForm("200")); + + } + } + + /** + * Demonstrates testing of request bodies read from resources. + */ + @Nested + class BodyFromResource { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withBodyFromResourceTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + runner.variable("petId", "citrus:randomNumber(10)"); + + runner.when(petApi.sendUpdatePet() + .message().body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json")) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .put("/api/v3/pet") + .message().body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response_validation.json"))); + + runner.then(http().server(httpServer) + .send() + .response(OK)); + + runner.when(petApi.receiveUpdatePetWithForm("200")); + + } + } + + /** + * Demonstrates testing of control response bodies from plain text. + */ + @Nested + class ReceiveBodyFromPlainText { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withReceiveBodyFromPlainTextTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + runner.variable("petId", "1234"); + + runner.when(petApi + .sendGetPetById$("${petId}") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/pet/${petId}") + .message() + .accept("@contains('application/json')@")); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .cookie(new Cookie("NonApiCookie", "nonApiCookieValue")) + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json")) + .contentType("application/json")); + + runner.then(petApi.receiveGetPetById(OK) + .message() + .body(""" + { + "id": ${petId}, + "name": "@matches('hasso|cutie|fluffy')@", + "category": { + "id": ${petId}, + "name": "@matches('dog|cat|fish')@" + }, + "photoUrls": [ + "http://localhost:8080/photos/${petId}" + ], + "tags": [ + { + "id": ${petId}, + "name": "generated" + } + ], + "status": "@matches('available|pending|sold')@" + } + """) + ); + } + } + + /** + * Demonstrates testing of control response bodies from resource. + */ + @Nested + class ReceiveBodyFromResource { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withReceiveBodyFromResourceTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + runner.variable("petId", "1234"); + + runner.when(petApi + .sendGetPetById$("${petId}") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/pet/${petId}") + .message() + .accept("@contains('application/json')@")); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .cookie(new Cookie("NonApiCookie", "nonApiCookieValue")) + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json")) + .contentType("application/json")); + + runner.then(petApi.receiveGetPetById(OK) + .message() + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response_validation.json")) + ); + } + } + + /** + * Demonstrates testing of received non-API cookies. + */ + @Nested + class ReceiveNonApiCookie { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withReceiveNonApiCookieTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + runner.variable("petId", "1234"); + + runner.when(petApi + .sendGetPetById$("${petId}") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/pet/${petId}") + .message() + .accept("@contains('application/json')@")); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .cookie(new Cookie("NonApiCookie", "nonApiCookieValue")) + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json")) + .contentType("application/json")); + + runner.then(petApi.receiveGetPetById(OK) + .message() + .cookie(new Cookie("NonApiCookie", "nonApiCookieValue")) + ); + } + } + + /** + * Demonstrates validation of response by JSON path validation. + */ + @Nested + class JsonPathValidation { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withJsonPathValidationTest") + void xml() { + } + + @Test + @CitrusTest + void java(@CitrusResource TestCaseRunner runner) { + + runner.variable("petId", "1234"); + + runner.when(petApi + .sendGetPetById$("${petId}") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/pet/${petId}") + .message() + .accept("@contains('application/json')@")); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json")) + .contentType("application/json")); + + runner.then(petApi.receiveGetPetById(OK) + .message() + .validate(jsonPath().expression("$.name", "@matches('hasso|cutie|fluffy')@")) + ); + } + } + + /** + * Demonstrates extraction of response data using JSON path. + */ + @Nested + class JsonPathExtraction { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withJsonPathExtractionTest") + void xml() { + } + + @Test + void java( + @CitrusResource TestCaseRunner runner, @CitrusResource TestContext context) { + + runner.variable("petId", "1234"); + + runner.when(petApi + .sendGetPetById$("${petId}") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/pet/${petId}") + .message() + .accept("@contains('application/json')@")); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json")) + .contentType("application/json")); + + runner.when(petApi + .receiveGetPetById(OK) + .message() + .extract(MessageHeaderVariableExtractor.Builder.fromHeaders() + .expression("Content-Type", "varContentType")) + .extract(JsonPathVariableExtractor.Builder.fromJsonPath() + .expression("$.name", "varName"))) + ; + + assertThat(context.getVariable("varContentType")).isEqualTo("application/json"); + assertThat(context.getVariable("varName")).matches("hasso|cutie|fluffy"); + } + } + + /** + * Demonstrates testing of API cookies in requests. + */ + @Nested + class ApiCookie { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withApiCookieTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + runner.variable("petId", "1234"); + + runner.when(extPetApi + .sendGetPetWithCookie$("${petId}", "cookieValue") + .optTrxId("trxId") + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .get("/api/v3/ext/pet/${petId}") + .message() + .cookie(new Cookie("session_id", "cookieValue")) + .cookie(new Cookie("opt_trx_id", "trxId")) + ); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .body(Resources.create( + "classpath:org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json")) + .contentType("application/json")); + + runner.when(extPetApi + .receiveGetPetWithCookie(OK) + .message()); + } + } + + /** + * Demonstrates testing of file uploads and validations of the response. + */ + @Nested + class FileUpload { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withFileUploadTest") + void uploadFile_xml() { + } + + @Test + @CitrusTest + void uploadFile_java(@CitrusResource TestCaseRunner runner) { + + String additionalMetadata = "myMeta"; + String file = "filedata"; + + runner.variable("petId", "1234"); + + runner.when(petApi.sendUploadFile$("${petId}") + .additionalMetadata(additionalMetadata) + .message() + .body(file) + .fork(true)); + + runner.then(http().server(httpServer) + .receive() + .post("/api/v3/pet/${petId}/uploadImage") + .message() + .contentType("application/octet-stream") + .queryParam("additionalMetadata", "myMeta") + .validate((message, context) -> { + Object payload = message.getPayload(); + assertThat(payload).isInstanceOf(byte[].class); + assertThat(new String((byte[]) payload, StandardCharsets.UTF_8)).isEqualTo( + "filedata"); + }) + ); + + runner.then(http().server(httpServer) + .send() + .response(OK) + .message() + .body(""" + {"code": 12, "type":"post-image-ok", "message":"image successfully uploaded"} + """) + .contentType("application/json")); + + runner.then(petApi + .receiveUploadFile(OK) + .message() + .validate(jsonPath().expression("$.code", "12")) + .validate(jsonPath().expression("$.message", "image successfully uploaded"))); + } + } + + @TestConfiguration + public static class Config { + + private final int port = SocketUtils.findAvailableTcpPort(8080); + + private final int otherPort = SocketUtils.findAvailableTcpPort(8081); + + private final int wsPort = SocketUtils.findAvailableTcpPort(8090); + + /** + * Main http client for accessing the main http server. + */ + @Bean(name = {"petstore.endpoint", "extpetstore.endpoint"}) + public HttpClient applicationServiceClient() { + return new HttpClientBuilder() + .requestUrl("http://localhost:%d".formatted(port)) + .handleCookies(true) + .build(); + } + + /** + * Http client accessing "other" server, see configuration of other server bean below. + */ + @Bean + public HttpClient otherApplicationServiceClient() { + return new HttpClientBuilder() + .requestUrl("http://localhost:%d".formatted(otherPort)) + .build(); + } + + /** + * A sample actor used to test actor configuration and functionality. + */ + @Bean + public TestActor petStoreActor() { + TestActor petStoreActor = new TestActor(); + petStoreActor.setName("PetStoreActor"); + petStoreActor.setDisabled(true); + return petStoreActor; + } + + /** + * Http server for mocking server side messaging and asserting data being send from test api + * requests. + */ + @Bean + public HttpServer httpServer() { + return new HttpServerBuilder() + .port(port) + .timeout(5000L) + .autoStart(true) + .defaultStatus(HttpStatus.NO_CONTENT) + .handleCookies(true) + .handleHandleSemicolonPathContent(true) + .build(); + } + + @Bean + public WebServiceServer soapServer() { + return WebServiceEndpoints.soap().server() + .port(wsPort) + .timeout(5000) + .autoStart(true) + .build(); + } + + /** + * A second http server. Mainly for tests that assert, that the default endpoint + * configuration can be overridden by an explicit endpoint. + */ + @Bean + public HttpServer otherHttpServer() { + return new HttpServerBuilder() + .port(otherPort) + .timeout(5000L) + .autoStart(true) + .defaultStatus(HttpStatus.NO_CONTENT) + .build(); + } + + /* + * Global variables, that make the ports available within the test context. Mainly + * used to access to port for explicit endpoint configuration tests. + */ + @Bean + public GlobalVariables globalVariables() { + return new GlobalVariables.Builder() + .variable("petstoreApplicationPort", port) + .variable("otherPetstoreApplicationPort", otherPort).build(); + } + +// @Bean +// public ApiActionBuilderCustomizer petApiCustomizer() { +// return new ApiActionBuilderCustomizer() { +// @Override +// public T customizeRequestBuilder( +// GeneratedApi generatedApi, T builder) { +// return ApiActionBuilderCustomizer.super.customizeRequestBuilder(generatedApi, +// builder); +// } +// +// @Override +// public T customizeResponseBuilder( +// GeneratedApi generatedApi, T builder) { +// return ApiActionBuilderCustomizer.super.customizeResponseBuilder(generatedApi, +// builder); +// } +// }; +// } + } +} + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/GeneratedSoapApiIT.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/GeneratedSoapApiIT.java new file mode 100644 index 0000000000..ac8289eb9e --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/GeneratedSoapApiIT.java @@ -0,0 +1,117 @@ +package org.citrusframework.openapi.generator; + +import static org.citrusframework.ws.actions.SoapActionBuilder.soap; + +import org.citrusframework.TestCaseRunner; +import org.citrusframework.annotations.CitrusResource; +import org.citrusframework.annotations.CitrusTestSource; +import org.citrusframework.common.TestLoader; +import org.citrusframework.config.CitrusSpringConfig; +import org.citrusframework.junit.jupiter.spring.CitrusSpringExtension; +import org.citrusframework.openapi.generator.GeneratedSoapApiIT.Config; +import org.citrusframework.openapi.generator.soap.bookservice.request.BookServiceSoapApi; +import org.citrusframework.openapi.generator.soap.bookservice.spring.BookServiceBeanConfiguration; +import org.citrusframework.util.SocketUtils; +import org.citrusframework.ws.client.WebServiceClient; +import org.citrusframework.ws.client.WebServiceClientBuilder; +import org.citrusframework.ws.endpoint.builder.WebServiceEndpoints; +import org.citrusframework.ws.server.WebServiceServer; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; + +/** + * This integration test class for the generated TestAPI aims to comprehensively test all aspects of + * accessing the API using both Java and XML. In addition to serving as a test suite, it also acts + * as a reference example. + * + *

    Therefore, each test is designed to be self-contained and straightforward, allowing + * anyone reviewing the code to easily grasp the purpose and context of the test without needing to + * rely on shared setup or utility methods. + */ + +@ExtendWith(CitrusSpringExtension.class) +@SpringBootTest(classes = {BookServiceBeanConfiguration.class, CitrusSpringConfig.class, Config.class} +) +class GeneratedSoapApiIT { + + + @Autowired + private WebServiceServer soapServer; + + @Autowired + private BookServiceSoapApi bookServiceSoapApi; + + @Nested + class SoapApi { + + @Test + @CitrusTestSource(type = TestLoader.SPRING, packageName = "org.citrusframework.openapi.generator.GeneratedApiTest", name = "withSoapTest") + void xml() { + } + + @Test + void java(@CitrusResource TestCaseRunner runner) { + String request = """ + + + Lord of the Rings + J.R.R. Tolkien + + + """; + runner.when(bookServiceSoapApi.sendAddBook().fork(true).message().body(request)); + + runner.then(soap().server(soapServer) + .receive() + .message() + .body(request)); + + String response = """ + + + Lord of the Rings + J.R.R. Tolkien + + + """; + + runner.then(soap().server(soapServer) + .send() + .message() + .body(response)); + + runner.then(bookServiceSoapApi.receiveAddBook() + .message() + .body(response)); + } + } + + @TestConfiguration + public static class Config { + + private final int wsPort = SocketUtils.findAvailableTcpPort(8090); + + @Bean(name = {"bookstore.endpoint"}) + public WebServiceClient soapClient() { + return new WebServiceClientBuilder() + .defaultUri("http://localhost:%d".formatted(wsPort)) + .build(); + } + + @Bean + public WebServiceServer soapServer() { + return WebServiceEndpoints.soap().server() + .port(wsPort) + .timeout(5000) + .autoStart(true) + .build(); + } + + } +} + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/GeneratedSpringBeanConfigurationIT.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/GeneratedSpringBeanConfigurationIT.java new file mode 100644 index 0000000000..db2664db43 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/GeneratedSpringBeanConfigurationIT.java @@ -0,0 +1,73 @@ +package org.citrusframework.openapi.generator; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.citrusframework.annotations.CitrusResource; +import org.citrusframework.annotations.CitrusTest; +import org.citrusframework.config.CitrusSpringConfig; +import org.citrusframework.context.TestContext; +import org.citrusframework.http.client.HttpClient; +import org.citrusframework.http.client.HttpEndpointConfiguration; +import org.citrusframework.junit.jupiter.spring.CitrusSpringSupport; +import org.citrusframework.openapi.generator.GeneratedSpringBeanConfigurationIT.ClientConfiguration; +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.spring.PetStoreBeanConfiguration; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.test.context.ContextConfiguration; + +@CitrusSpringSupport +@ContextConfiguration(classes = {CitrusSpringConfig.class, ClientConfiguration.class, + PetStoreBeanConfiguration.class}) +class GeneratedSpringBeanConfigurationIT { + + @Test + @CitrusTest + void petStoreOpenApiRepositoryIsAvailable(@CitrusResource TestContext testContext) { + var petStoreOpenApiRepository = testContext.getReferenceResolver() + .resolve("petStoreOpenApiRepository"); + assertThat(petStoreOpenApiRepository) + .isNotNull(); + } + + @Test + @CitrusTest + void petApiRepositoryIsAvailable(@CitrusResource TestContext testContext) { + var petApi = testContext.getReferenceResolver() + .resolve(PetApi.class); + assertThat(petApi) + .isNotNull(); + } + + @Test + @CitrusTest + void storeApiRepositoryIsAvailable(@CitrusResource TestContext testContext) { + var storeApi = testContext.getReferenceResolver() + .resolve(StoreApi.class); + assertThat(storeApi) + .isNotNull(); + } + + @Test + @CitrusTest + void userApiRepositoryIsAvailable(@CitrusResource TestContext testContext) { + var userApi = testContext.getReferenceResolver() + .resolve(UserApi.class); + assertThat(userApi) + .isNotNull(); + } + + @TestConfiguration + public static class ClientConfiguration { + + @Bean(name = {"petstore.endpoint"}) + public HttpClient applicationServiceClient() { + var config = new HttpEndpointConfiguration(); + config.setRequestUrl("http://localhost:9000"); + return new HttpClient(config); + } + } +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/GetPetByIdIT.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/GetPetByIdIT.java deleted file mode 100644 index 77961399e3..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/GetPetByIdIT.java +++ /dev/null @@ -1,404 +0,0 @@ -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.http.actions.HttpActionBuilder.http; -import static org.citrusframework.openapi.generator.sample.OpenApiPetStore.AddressEntityValidationContext.Builder.address; -import static org.citrusframework.openapi.generator.sample.OpenApiPetStore.AggregateEntityValidationContext.Builder.allOf; -import static org.citrusframework.openapi.generator.sample.OpenApiPetStore.AggregateEntityValidationContext.Builder.anyOf; -import static org.citrusframework.openapi.generator.sample.OpenApiPetStore.AggregateEntityValidationContext.Builder.oneOf; -import static org.citrusframework.openapi.generator.sample.OpenApiPetStore.PetEntityValidationContext.Builder.pet; -import static org.citrusframework.openapi.generator.sample.OpenApiPetStore.openApiPetStore; -import static org.citrusframework.util.FileUtils.readToString; -import static org.citrusframework.validation.json.JsonPathMessageValidationContext.Builder.jsonPath; -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.List; -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.http.server.HttpServer; -import org.citrusframework.http.server.HttpServerBuilder; -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.GetPetByIdIT.Config; -import org.citrusframework.openapi.generator.rest.petstore.request.PetApi.GetPetByIdRequest; -import org.citrusframework.openapi.generator.rest.petstore.spring.PetStoreBeanConfiguration; -import org.citrusframework.openapi.generator.sample.OpenApiPetStore.AddressEntityValidationContext; -import org.citrusframework.openapi.generator.sample.OpenApiPetStore.AggregateEntityValidationContext; -import org.citrusframework.openapi.generator.sample.OpenApiPetStore.PetEntityValidationContext.Builder; -import org.citrusframework.openapi.generator.sample.PetApi; -import org.citrusframework.spi.BindToRegistry; -import org.citrusframework.spi.Resources; -import org.citrusframework.util.SocketUtils; -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 GetPetByIdIT { - - private final int port = SocketUtils.findAvailableTcpPort(8080); - - @BindToRegistry - private final HttpServer httpServer = new HttpServerBuilder() - .port(port) - .timeout(5000L) - .autoStart(true) - .defaultStatus(HttpStatus.NO_CONTENT) - .build(); - - @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 testByEntityMatcher(@CitrusResource TestCaseRunner runner) { - - when(PetApi.openApiPetStore(httpClient) - .getPetById() - .withId("1234") - .fork(true)); - - runner.then(http().server(httpServer) - .receive() - .get("/pet/${petId}") - .message() - .accept("@contains('application/json')@")); - - runner.then(http().server(httpServer) - .send() - .response(HttpStatus.OK) - .message() - .body(Resources.create("classpath:org/citrusframework/openapi/petstore/pet.json")) - .contentType("application/json")); - - runner.then(openApiPetStore(httpClient) - .receivePetById(HttpStatus.OK) - .message() - .validate(pet().id("1234") - .name("Garfield") - .category("Cat") - .address(address -> address - .street("Nina Hagen Hang") - .zip("12345") - .city("Hagen ATW")) - .owners(anyOf(List.of( - owner -> owner.name("Peter Lustig"), - owner -> owner.name("Hans Meier") - ))) - .owners(oneOf(List.of( - owner -> owner.name("Seppel Hinterhuber") - ))) - .urls(0, "url1") - .urls(1, "url2") - .urls("@contains('url1', 'url2')")). - validate(jsonPath().expression("$.name", "Garfield"))); - - runner.then(openApiPetStore(httpClient) - .receivePetById200() - .withPet(validator -> validator.id("1234") - .name("Garfield") - .category("Cat") - .urls(0,"url1") - .urls(1,"url2") - .urls("@contains('url1', 'url2')")). - validate(jsonPath().expression("$.name", "Garfield")) - ); - } - - @Test - @CitrusTest - void testFindByStatus(@CitrusResource TestCaseRunner runner) { - - when(openApiPetStore(httpClient) - .findByStatus() - .withStatus("SOLD") - .fork(true)); - - runner.then(http().server(httpServer) - .receive() - .get("/pet/${petId}") - .message() - .accept("@contains('application/json')@")); - - runner.then(http().server(httpServer) - .send() - .response(HttpStatus.OK) - .message() - .body(Resources.create("classpath:org/citrusframework/openapi/petstore/pet.json")) - .contentType("application/json")); - - runner.then(openApiPetStore(httpClient) - .receivePetById(HttpStatus.OK) - .message() - .validate(pet().id("1234") - .name("Garfield") - .category("Cat") - .address(address -> address - .street("Nina Hagen Hang") - .zip("12345") - .city("Hagen ATW")) - .owners(anyOf(List.of( - owner -> owner.name("Peter Lustig"), - owner -> owner.name("Hans Meier") - ))) - .owners(oneOf(List.of( - owner -> owner.name("Seppel Hinterhuber") - ))) - .urls(0, "url1") - .urls(1, "url2") - .urls("@contains('url1', 'url2')")). - validate(jsonPath().expression("$.name", "Garfield"))); - - runner.then(openApiPetStore(httpClient) - .receivePetById200() - .withPet(validator -> validator.id("1234") - .name("Garfield") - .category("Cat") - .urls(0,"url1") - .urls(1,"url2") - .urls("@contains('url1', 'url2')")). - validate(jsonPath().expression("$.name", "Garfield")) - ); - } - - @Test - @CitrusTest - void testByJsonPath(@CitrusResource TestCaseRunner runner) { - - when(openApiPetStore(httpClient) - .getPetById() - .withPetId("1234") - .fork(true)); - - runner.then(http().server(httpServer) - .receive() - .get("/pet/${petId}") - .message() - .accept("@contains('application/json')@")); - - runner.then(http().server(httpServer) - .send() - .response(HttpStatus.OK) - .message() - .body(Resources.create("classpath:org/citrusframework/openapi/petstore/pet.json")) - .contentType("application/json")); - - runner.then(openApiPetStore(httpClient) - .receivePetById(HttpStatus.OK) - .message().validate(jsonPath().expression("$.name", "Garfield")) - ); - } - - - /** - * 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/JavaCitrusCodegenTest.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/JavaCitrusCodegenTest.java deleted file mode 100644 index f3860de3b4..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/JavaCitrusCodegenTest.java +++ /dev/null @@ -1,219 +0,0 @@ -package org.citrusframework.openapi.generator; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.citrusframework.openapi.generator.JavaCitrusCodegen.CODEGEN_NAME; - -import java.io.File; -import java.io.IOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import org.junit.jupiter.api.Test; -import org.openapitools.codegen.ClientOptInput; -import org.openapitools.codegen.CodegenConfigLoader; -import org.openapitools.codegen.DefaultGenerator; -import org.openapitools.codegen.config.CodegenConfigurator; - -/** - * This test validates the code generation process. - *

    - * It may also serve as an entry point for debugging the code generation process. When executed in debug mode, it allows you to - * step through the generation process and inspect the resulting output in the specified output directory. - *

    - * To debug the code generator: - *

      - *
    1. Set a breakpoint in the {@code postProcessOperationsWithModels()} method of {@code JavaCitrusCodegen.java}.
    2. - *
    3. In your IDE, launch this test by right-clicking and selecting Debug As > JUnit Test.
    4. - *
    - */ - -class JavaCitrusCodegenTest { - - /** - * Get the absolute path to the test resources directory. - * - * @param pathToFileInTestResources The file within {@code src/test/resources} to look for - * @return the absolute path to the file - */ - static String getAbsoluteTestResourcePath(String pathToFileInTestResources) { - URL resourceUrl = JavaCitrusCodegenTest.class.getClassLoader().getResource(pathToFileInTestResources); - assert resourceUrl != null; - File inputSpecFile = new File(resourceUrl.getFile()); - return inputSpecFile.getAbsolutePath(); - } - - /** - * Get the absolute path to the project's target directory. - * - * @param pathToFileInTargetDirectory The file within {@code target} to look for - * @return the absolute path to the file - */ - static String getAbsoluteTargetDirectoryPath(String pathToFileInTargetDirectory) { - String projectBaseDir = System.getProperty("user.dir"); // Base directory of the project - File outputDirFile = new File(projectBaseDir, "target/" + pathToFileInTargetDirectory); - return outputDirFile.getAbsolutePath(); - } - - @Test - void retrieveGeneratorBsSpi() { - JavaCitrusCodegen codegen = (JavaCitrusCodegen) CodegenConfigLoader.forName("java-citrus"); - assertThat(codegen).isNotNull(); - } - - @Test - void arePredefinedValuesNotEmptyTest() { - JavaCitrusCodegen codegen = new JavaCitrusCodegen(); - - assertThat(codegen.getName()).isEqualTo(CODEGEN_NAME); - assertThat(codegen.getHelp()).isNotEmpty(); - assertThat(codegen.getHttpClient()).isNotEmpty(); - assertThat(codegen.getOpenapiSchema()).isNotEmpty(); - assertThat(codegen.getApiPrefix()).isNotEmpty(); - assertThat(codegen.getHttpPathPrefix()).isNotEmpty(); - assertThat(codegen.getTargetXmlnsNamespace()).isNull(); - assertThat(codegen.getGeneratedSchemaFolder()).isNotEmpty(); - } - - @Test - void areAdditionalPropertiesProcessedTest() { - final String httpClient = "myTestEndpoint"; - final String openapiSchema = "testSchema"; - final String prefix = "testPrefix"; - final String httpPathPrefix = "test/path"; - final String targetXmlnsNamespace = "http://www.citrusframework.org/schema/test/extension"; - final String generatedSchemaFolder = "generatedResourceFolder"; - - Map properties = new HashMap<>(); - properties.put(JavaCitrusCodegen.API_ENDPOINT, httpClient); - properties.put(JavaCitrusCodegen.GENERATED_SCHEMA_FOLDER, generatedSchemaFolder); - properties.put(JavaCitrusCodegen.HTTP_PATH_PREFIX, httpPathPrefix); - properties.put(JavaCitrusCodegen.OPENAPI_SCHEMA, openapiSchema); - properties.put(JavaCitrusCodegen.PREFIX, prefix); - properties.put(JavaCitrusCodegen.TARGET_XMLNS_NAMESPACE, targetXmlnsNamespace); - - JavaCitrusCodegen codegen = new JavaCitrusCodegen(); - codegen.additionalProperties().putAll(properties); - codegen.processOpts(); - - assertThat(codegen.getApiPrefix()).isEqualTo(prefix); - assertThat(codegen.getGeneratedSchemaFolder()).isEqualTo(generatedSchemaFolder); - assertThat(codegen.getHttpClient()).isEqualTo(httpClient); - assertThat(codegen.getHttpPathPrefix()).isEqualTo(httpPathPrefix); - assertThat(codegen.getOpenapiSchema()).isEqualTo(openapiSchema); - assertThat(codegen.getTargetXmlnsNamespace()).isEqualTo(targetXmlnsNamespace); - } - - @Test - void areReservedWordsEscapedTest() throws IOException { - String absoluteInputSpecPath = getAbsoluteTestResourcePath("apis/petstore_reservedWords.yaml"); - String absoluteOutputDirPath = getAbsoluteTargetDirectoryPath("JavaCitrusCodegenTest/petstore_escapedWords"); - - final CodegenConfigurator configurator = new CodegenConfigurator() - .setGeneratorName(CODEGEN_NAME) - .setInputSpec(absoluteInputSpecPath) - .setOutputDir(absoluteOutputDirPath); - - final ClientOptInput clientOptInput = configurator.toClientOptInput(); - DefaultGenerator generator = new DefaultGenerator(); - List outputFiles = generator.opts(clientOptInput).generate(); - - Optional file = outputFiles.stream() - .filter(x -> "PetApi.java".equals(x.getName())) - .findFirst(); - - assertThat(file).isPresent(); - - 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("\"name\", this._name")) - .count()) - .isEqualTo(1L); - } - - @Test - void arePathParamsFieldsPresent() throws IOException { - String absoluteInputSpecPath = getAbsoluteTestResourcePath("apis/petstore.yaml"); - String absoluteOutputDirPath = getAbsoluteTargetDirectoryPath("JavaCitrusCodegenTest/petstore"); - - final CodegenConfigurator configurator = new CodegenConfigurator() - .setGeneratorName(CODEGEN_NAME) - .setInputSpec(absoluteInputSpecPath) - .setOutputDir(absoluteOutputDirPath); - - final ClientOptInput clientOptInput = configurator.toClientOptInput(); - DefaultGenerator generator = new DefaultGenerator(); - List outputFiles = generator.opts(clientOptInput).generate(); - - Optional file = outputFiles.stream() - .filter(x -> "PetApi.java".equals(x.getName())) - .findFirst(); - - assertThat(file).isPresent(); - - 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("private String petId;")) - .count()) - .isEqualTo(4L); - assertThat( - lines.stream() - .filter(x -> x.contains( - "endpoint = endpoint.replace(\"{\" + \"petId\" + \"}\", petId);")) - .count()) - .isEqualTo(4L); - } - - @Test - void areBasicAuthFieldsPresent() throws IOException { - String absoluteInputSpecPath = getAbsoluteTestResourcePath("apis/petstore.yaml"); - String absoluteOutputDirPath = getAbsoluteTargetDirectoryPath("JavaCitrusCodegenTest/petstore"); - - final CodegenConfigurator configurator = new CodegenConfigurator() - .setGeneratorName(CODEGEN_NAME) - .setInputSpec(absoluteInputSpecPath) - .setOutputDir(absoluteOutputDirPath); - - final ClientOptInput clientOptInput = configurator.toClientOptInput(); - DefaultGenerator generator = new DefaultGenerator(); - List outputFiles = generator.opts(clientOptInput).generate(); - - Optional file = outputFiles.stream() - .filter(x -> "PetApi.java".equals(x.getName())) - .findFirst(); - - assertThat(file).isPresent(); - - 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("private String basicUsername;")) - .count()) - .isEqualTo(1L); - assertThat( - lines.stream() - .filter(x -> - x.contains( - "messageBuilderSupport.header(\"Authorization\", \"Basic \" + Base64.getEncoder().encodeToString((context.replaceDynamicContentInString(basicUsername)+\":\"+context.replaceDynamicContentInString(basicPassword)).getBytes()));" - ) - ) - .count()) - .isEqualTo(1L); - } -} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/OpenApiPetStoreTest.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/OpenApiPetStoreTest.java deleted file mode 100644 index 372219d262..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/OpenApiPetStoreTest.java +++ /dev/null @@ -1,181 +0,0 @@ -package org.citrusframework.openapi.generator; - -import static org.citrusframework.openapi.generator.sample.OpenApiPetStore.PetEntityValidationContext.Builder.pet; -import static org.mockito.Mockito.mock; - -import com.jayway.jsonpath.JsonPath; -import com.jayway.jsonpath.ReadContext; -import java.util.Map; -import net.minidev.json.parser.JSONParser; -import net.minidev.json.parser.ParseException; -import org.citrusframework.context.TestContext; -import org.citrusframework.exceptions.CitrusRuntimeException; -import org.citrusframework.functions.DefaultFunctionRegistry; -import org.citrusframework.json.JsonPathUtils; -import org.citrusframework.message.DefaultMessage; -import org.citrusframework.message.Message; -import org.citrusframework.openapi.generator.sample.OpenApiPetStore.AggregateEntityValidationContext; -import org.citrusframework.openapi.generator.sample.OpenApiPetStore.EntityValidationContext; -import org.citrusframework.openapi.generator.sample.OpenApiPetStore.PetEntityValidationContext; -import org.citrusframework.openapi.generator.sample.OpenApiPetStore.PetEntityValidationContext.Builder; -import org.citrusframework.validation.AbstractMessageValidator; -import org.citrusframework.validation.DefaultMessageValidatorRegistry; -import org.citrusframework.validation.ValidationUtils; -import org.testng.annotations.Test; - -public class OpenApiPetStoreTest { - - @Test - public void test() { - Builder petValidationContextBuilder = pet().id("1234") - .name("Garfield") - .category("Cat") - .address(address -> address - .street("Nina Hagen Hang") - .zip("12345") - .city("Hagen ATW")) -// .owners(anyOf(List.of( -// owner -> owner.name("Peter Lustig"), -// owner -> owner.name("Hans Meier") -// ))) -// .owners(oneOf(List.of( -// owner -> owner.name("Seppel Hinterhuber") -// ))) -// .urls(0, "url1") -// .urls(1, "url2") -// .urls("@contains('url1', 'url2')") - ; - - PetEntityValidationContext petValidationContext = petValidationContextBuilder.build(); - OpenApiEntityValidator validator = new OpenApiEntityValidator(); - - Message receivedMessage = new DefaultMessage(); - receivedMessage.setPayload(""" - { - "id": 1234, - "name": "Garfield", - "category": "Cat", - "address": { - "street": "Nina Hagen Hang", - "zip": "12345", - "city": "Hagen ATW" - }, - "owners": [ - { - "name": "Peter Lustig" - }, - { - "name": "Hans Meier" - } - ] - } - """); - TestContext testContext = new TestContext(); - testContext.setReferenceResolver(mock()); - testContext.setMessageValidatorRegistry(new DefaultMessageValidatorRegistry()); - testContext.setFunctionRegistry(new DefaultFunctionRegistry()); - - validator.validateMessage(receivedMessage, null, testContext, petValidationContext); - - - } - - public class OpenApiEntityValidator extends - AbstractMessageValidator { - - public void validateMessage(Message receivedMessage, Message controlMessage, - TestContext context, EntityValidationContext validationContext) { - System.out.println("asSD"); - - validateJson(receivedMessage.getPayload(String.class), context, validationContext); - - - } - - private void validateJson(String jsonString, TestContext context, - EntityValidationContext validationContext) { - validateJsonPathExpressions(jsonString, context, validationContext); - validateNestedJsonPathExpressions(jsonString, context, validationContext); - } - - @Override - protected Class getRequiredValidationContextType() { - return EntityValidationContext.class; - } - - @Override - public boolean supportsMessageType(String messageType, Message message) { - return true; - } - - - private void validateJsonPathExpressions(String jsonString, TestContext context, - EntityValidationContext validationContext) { - String jsonPathExpression; - try { - JSONParser parser = new JSONParser(JSONParser.MODE_JSON_SIMPLE); - Object receivedJson = parser.parse(jsonString); - ReadContext readerContext = JsonPath.parse(receivedJson); - - for (Map.Entry entry : validationContext.getJsonPathExpressions() - .entrySet()) { - Object expectedValue = entry.getValue(); - - jsonPathExpression = context.replaceDynamicContentInString(entry.getKey()); - Object jsonPathResult = JsonPathUtils.evaluate(readerContext, - jsonPathExpression); - - if (expectedValue instanceof EntityValidationContext entityValidationContext) { - validateJson((String) jsonPathResult, context, entityValidationContext); - } else if (expectedValue instanceof AggregateEntityValidationContext) { - - } else { - - if (expectedValue instanceof String) { - //check if expected value is variable or function (and resolve it, if yes) - expectedValue = context.replaceDynamicContentInString( - String.valueOf(expectedValue)); - } - - //do the validation of actual and expected value for element - ValidationUtils.validateValues(jsonPathResult, expectedValue, - jsonPathExpression, context); - - logger.debug("Validating element: {}='{}': OK", jsonPathExpression, - expectedValue); - } - - } - - logger.debug("JSONPath element validation successful: All values OK"); - } catch (ParseException e) { - throw new CitrusRuntimeException("Failed to parse JSON text", e); - } - } - - private void validateNestedJsonPathExpressions(String jsonString, TestContext context, - EntityValidationContext validationContext) { - String jsonPathExpression; - try { - JSONParser parser = new JSONParser(JSONParser.MODE_JSON_SIMPLE); - Object receivedJson = parser.parse(jsonString); - ReadContext readerContext = JsonPath.parse(receivedJson); - - for (Map.Entry entry : validationContext.getNestedValidationContextsBuilders() - .entrySet()) { - - jsonPathExpression = context.replaceDynamicContentInString(entry.getKey()); - Object jsonPathResult = JsonPathUtils.evaluate(readerContext, - jsonPathExpression); - - validateJson(jsonPathResult.toString(), context, entry.getValue()); - - } - - logger.debug("JSONPath element validation successful: All values OK"); - } catch (ParseException e) { - throw new CitrusRuntimeException("Failed to parse JSON text", e); - } - } - } -} 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 deleted file mode 100644 index 419cea9ade..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/ServiceLoaderTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.citrusframework.openapi.generator; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.List; -import java.util.ServiceLoader; -import java.util.ServiceLoader.Provider; -import org.citrusframework.openapi.generator.util.TestApiActionBuilderCustomizer; -import org.citrusframework.testapi.ApiActionBuilderCustomizerService; -import org.junit.jupiter.api.Test; - -class ServiceLoaderTest { - - @Test - void test() { - ServiceLoader serviceLoader = ServiceLoader.load( - ApiActionBuilderCustomizerService.class, ApiActionBuilderCustomizerService.class.getClassLoader()); - List> list = serviceLoader.stream().toList(); - assertThat(list).hasSize(1); - ApiActionBuilderCustomizerService apiActionBuilderCustomizerService = list.iterator().next() - .get(); - assertThat(apiActionBuilderCustomizerService).isInstanceOf(TestApiActionBuilderCustomizer.class); - } -} 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 deleted file mode 100644 index 15dfb85dc3..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/SpringBeanConfigurationIT.java +++ /dev/null @@ -1,55 +0,0 @@ -package org.citrusframework.openapi.generator; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.citrusframework.annotations.CitrusResource; -import org.citrusframework.annotations.CitrusTest; -import org.citrusframework.config.CitrusSpringConfig; -import org.citrusframework.context.TestContext; -import org.citrusframework.http.client.HttpClient; -import org.citrusframework.http.client.HttpEndpointConfiguration; -import org.citrusframework.junit.jupiter.spring.CitrusSpringSupport; -import org.citrusframework.openapi.generator.SpringBeanConfigurationIT.ClientConfiguration; -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.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.test.context.ContextConfiguration; - -@CitrusSpringSupport -@ContextConfiguration(classes = {CitrusSpringConfig.class, ClientConfiguration.class, PetStoreBeanConfiguration.class}) -class SpringBeanConfigurationIT { - - @Autowired - private ApplicationContext applicationContext; - - @Test - @CitrusTest - void fromReferenceResolverIsPrototypeScoped(@CitrusResource TestContext testContext) { - var addPetRequest = testContext.getReferenceResolver().resolve(AddPetRequest.class); - assertThat(addPetRequest) - .isNotNull() - .isNotEqualTo(testContext.getReferenceResolver().resolve(AddPetRequest.class)); - } - - @Test - void fromSpringApplicationContextIsPrototypeScoped() { - assertThat(applicationContext.getBean(AddPetRequest.class)) - .isNotNull() - .isNotEqualTo(applicationContext.getBean(AddPetRequest.class)); - } - - @TestConfiguration - public static class ClientConfiguration { - - @Bean(name= {"applicationServiceClient", "petStoreEndpoint"}) - public HttpClient applicationServiceClient() { - var config = new HttpEndpointConfiguration(); - config.setRequestUrl("http://localhost:9000"); - return new HttpClient(config); - } - } -} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/SimpleWsdlToOpenApiTransformerTest.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/WsdlToOpenApiTransformerTest.java similarity index 87% rename from test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/SimpleWsdlToOpenApiTransformerTest.java rename to test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/WsdlToOpenApiTransformerTest.java index 1ae66986fd..581a3f065a 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/SimpleWsdlToOpenApiTransformerTest.java +++ b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/WsdlToOpenApiTransformerTest.java @@ -10,14 +10,14 @@ import org.junit.jupiter.api.Test; import org.springframework.core.io.ClassPathResource; -class SimpleWsdlToOpenApiTransformerTest { +class WsdlToOpenApiTransformerTest { @Test void testTransform() throws WsdlToOpenApiTransformationException, IOException { ClassPathResource wsdlResource = new ClassPathResource( "/org/citrusframework/openapi/generator/SimpleWsdlToOpenApiTransformerTest/BookService.wsdl"); - SimpleWsdlToOpenApiTransformer simpleWsdlToOpenApiTransformer = new SimpleWsdlToOpenApiTransformer(wsdlResource.getURI()); + WsdlToOpenApiTransformer simpleWsdlToOpenApiTransformer = new WsdlToOpenApiTransformer(wsdlResource.getURI()); String generatedYaml = simpleWsdlToOpenApiTransformer.transformToOpenApi(); Resource expectedYamlResource = new ClasspathResource( diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/sample/OpenApiPetStore.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/sample/OpenApiPetStore.java deleted file mode 100644 index 5ed27a3765..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/sample/OpenApiPetStore.java +++ /dev/null @@ -1,306 +0,0 @@ -package org.citrusframework.openapi.generator.sample; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Consumer; -import org.citrusframework.builder.WithExpressions; -import org.citrusframework.http.actions.HttpClientRequestActionBuilder; -import org.citrusframework.http.actions.HttpClientResponseActionBuilder; -import org.citrusframework.http.client.HttpClient; -import org.citrusframework.message.DelegatingPathExpressionProcessor; -import org.citrusframework.message.MessageProcessor; -import org.citrusframework.message.MessageProcessorAdapter; -import org.citrusframework.openapi.generator.sample.OpenApiPetStore.EntityValidationContext; -import org.citrusframework.openapi.generator.sample.OpenApiPetStore.PetEntityValidationContext.Builder; -import org.citrusframework.openapi.generator.sample.PetApi.FindPetByStatusActionBuilder; -import org.citrusframework.validation.DelegatingPayloadVariableExtractor; -import org.citrusframework.validation.context.DefaultValidationContext; -import org.citrusframework.validation.context.ValidationContext; -import org.citrusframework.variable.VariableExtractor; -import org.citrusframework.variable.VariableExtractorAdapter; -import org.springframework.http.HttpStatus; - -public class OpenApiPetStore { - - public static OpenApiPetStore openApiPetStore(HttpClient httpClient) { - return new OpenApiPetStore(); - } - - public GetPetIdRequestActionBuilder getPetById() { - return new GetPetIdRequestActionBuilder(); - } - - public FindPetByStatusActionBuilder findByStatus() { - return new PetApi.FindPetByStatusActionBuilder(); - } - - public static class GetPetIdRequestActionBuilder extends HttpClientRequestActionBuilder { - - public GetPetIdRequestActionBuilder withPetId(String petId) { - return this; - } - - } - - public GetPetIdResponseActionBuilder receivePetById(HttpStatus status) { - return new GetPetIdResponseActionBuilder(); - } - - public GetPetIdResponseActionBuilder200 receivePetById200() { - return new GetPetIdResponseActionBuilder200(); - } - - public static class GetPetIdResponseActionBuilder extends HttpClientResponseActionBuilder { - - } - - // Per configured response - public static class GetPetIdResponseActionBuilder200 extends HttpClientResponseActionBuilder { - - public HttpMessageBuilderSupport withPet( - Consumer validator) { - PetEntityValidationContext.Builder builder = new PetEntityValidationContext.Builder(); - validator.accept(builder); - return message().validate(builder); - } - } - - public static class EntityValidationContext extends DefaultValidationContext { - - private Map expressions; - - - private Map nestedValidationContextsBuilders = new HashMap<>(); - - public EntityValidationContext(Builder builder) { - super(); - this.expressions = builder.expressions; - builder.nestedValidationContextBuilders.forEach((key, value) -> - nestedValidationContextsBuilders.put(key, value.build())); - - } - - public Map getJsonPathExpressions() { - return expressions; - } - - public Map getNestedValidationContextsBuilders() { - return nestedValidationContextsBuilders; - } - - public static class Builder> implements - ValidationContext.Builder, - WithExpressions, VariableExtractorAdapter, - MessageProcessorAdapter { - - private final Map expressions = new HashMap<>(); - - protected final Map> nestedValidationContextBuilders= new HashMap<>(); - - @Override - public B expressions(Map expressions) { - this.expressions.putAll(expressions); - return (B) this; - } - - @Override - public B expression(final String expression, - final Object value) { - this.expressions.put(expression, value); - return (B) this; - } - - @Override - public EntityValidationContext build() { - return new EntityValidationContext(this); - } - - @Override - public MessageProcessor asProcessor() { - return new DelegatingPathExpressionProcessor.Builder() - .expressions(expressions) - .build(); - } - - @Override - public VariableExtractor asExtractor() { - return new DelegatingPayloadVariableExtractor.Builder() - .expressions(expressions) - .build(); - } - - } - } - - public static class PetEntityValidationContext extends EntityValidationContext { - - public PetEntityValidationContext(Builder builder) { - super(builder); - } - - public static class Builder extends - EntityValidationContext.Builder { - - public Builder id(String expression) { - return expression("$.id", expression); - } - - public Builder name(String expression) { - return expression("$.name", expression); - } - - public Builder category(String expression) { - return expression("$.category", expression); - } - - public Builder urls(String expression) { - return expression("$.urls", expression); - } - - - public Builder urls(int index, String expression) { - return expression("$.urls[%d]".formatted(index), expression); - } - - public Builder address(Consumer validator) { - AddressEntityValidationContext.Builder addressEntityValidationContextBuilder = new AddressEntityValidationContext.Builder(); - validator.accept(addressEntityValidationContextBuilder); - nestedValidationContextBuilders.put("$.address", addressEntityValidationContextBuilder); - - return this; - } - - - public Builder owners(AggregateEntityValidationContext.Builder aggregateContext) { - nestedValidationContextBuilders.put("$.owners", aggregateContext); - return this; - } - - public static Builder pet() { - return new Builder(); - } - - @Override - public PetEntityValidationContext build() { - return new PetEntityValidationContext(this); - } - - } - } - - public static class AddressEntityValidationContext extends EntityValidationContext { - - public AddressEntityValidationContext(Builder builder) { - super(builder); - } - - public static class Builder extends - EntityValidationContext.Builder { - - - public Builder street(String expression) { - return expression("$.street", expression); - } - - public Builder city(String expression) { - return expression("$.city", expression); - } - - public Builder zip(String expression) { - return expression("$.zip", expression); - } - - public static Builder address() { - return new Builder(); - } - - @Override - public AddressEntityValidationContext build() { - return new AddressEntityValidationContext(this); - } - - } - } - - public static class OwnerEntityValidationContext extends EntityValidationContext { - - public OwnerEntityValidationContext(Builder builder) { - super(builder); - } - - public static class Builder extends - EntityValidationContext.Builder { - - public OwnerEntityValidationContext.Builder address(Consumer validator) { - AddressEntityValidationContext.Builder addressEntityValidationContextBuilder = new AddressEntityValidationContext.Builder(); - validator.accept(addressEntityValidationContextBuilder); - nestedValidationContextBuilders.put("address", addressEntityValidationContextBuilder); - return this; - } - - public OwnerEntityValidationContext.Builder name(String expression) { - expression("$.name", expression); - return this; - } - - @Override - public OwnerEntityValidationContext build() { - return new OwnerEntityValidationContext(this); - } - } - } - - public static class AggregateEntityValidationContext> extends EntityValidationContext { - - private final Type type; - - private List> validator; - - public AggregateEntityValidationContext(Builder builder) { - super(builder); - - this.type = builder.type; - this.validator = builder.validator; - } - - public enum Type { - ONE_OF, ANY_OF, ALL_OF, NONE_OF - } - - public static class Builder> extends EntityValidationContext.Builder, Builder> { - - private final Type type; - - private final List> validator; - - public Builder(Type type, List> validator) { - this.type = type; - this.validator = validator; - } - - public static > AggregateEntityValidationContext.Builder anyOf(List> validator) { - return new Builder<>(Type.ANY_OF, validator); - } - - public static > AggregateEntityValidationContext.Builder allOf(List> validator) { - return new Builder<>(Type.ALL_OF, validator); - } - - public static > AggregateEntityValidationContext.Builder noneOf(List> validator) { - - return new Builder<>(Type.NONE_OF, validator); - } - - public static > AggregateEntityValidationContext.Builder oneOf(List> validator) { - return new Builder<>(Type.ONE_OF, validator); - } - - @Override - public AggregateEntityValidationContext build() { - return null; - } - } - - } -} \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/sample/OpenApiPetStore_.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/sample/OpenApiPetStore_.java deleted file mode 100644 index b810d81281..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/sample/OpenApiPetStore_.java +++ /dev/null @@ -1,304 +0,0 @@ -package org.citrusframework.openapi.generator.sample; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Consumer; -import org.citrusframework.builder.WithExpressions; -import org.citrusframework.http.actions.HttpClientRequestActionBuilder; -import org.citrusframework.http.actions.HttpClientResponseActionBuilder; -import org.citrusframework.http.client.HttpClient; -import org.citrusframework.message.DelegatingPathExpressionProcessor; -import org.citrusframework.message.MessageProcessor; -import org.citrusframework.message.MessageProcessorAdapter; -import org.citrusframework.openapi.generator.sample.PetApi.FindPetByStatusActionBuilder; -import org.citrusframework.validation.DelegatingPayloadVariableExtractor; -import org.citrusframework.validation.context.DefaultValidationContext; -import org.citrusframework.validation.context.ValidationContext; -import org.citrusframework.variable.VariableExtractor; -import org.citrusframework.variable.VariableExtractorAdapter; -import org.springframework.http.HttpStatus; - -public class OpenApiPetStore_ { - - public static OpenApiPetStore_ openApiPetStore(HttpClient httpClient) { - return new OpenApiPetStore_(); - } - - public GetPetIdRequestActionBuilder getPetById() { - return new GetPetIdRequestActionBuilder(); - } - - public FindPetByStatusActionBuilder findByStatus() { - return new FindPetByStatusActionBuilder(); - } - - public static class GetPetIdRequestActionBuilder extends HttpClientRequestActionBuilder { - - public GetPetIdRequestActionBuilder withPetId(String petId) { - return this; - } - - } - - public GetPetIdResponseActionBuilder receivePetById(HttpStatus status) { - return new GetPetIdResponseActionBuilder(); - } - - public GetPetIdResponseActionBuilder200 receivePetById200() { - return new GetPetIdResponseActionBuilder200(); - } - - public static class GetPetIdResponseActionBuilder extends HttpClientResponseActionBuilder { - - } - - // Per configured response - public static class GetPetIdResponseActionBuilder200 extends HttpClientResponseActionBuilder { - - public HttpMessageBuilderSupport withPet( - Consumer validator) { - PetEntityValidationContext.Builder builder = new PetEntityValidationContext.Builder(); - validator.accept(builder); - return message().validate(builder); - } - } - - public static class EntityValidationContext extends DefaultValidationContext { - - private Map expressions; - - - private Map nestedValidationContextsBuilders = new HashMap<>(); - - public EntityValidationContext(Builder builder) { - super(); - this.expressions = builder.expressions; - builder.nestedValidationContextBuilders.forEach((key, value) -> - nestedValidationContextsBuilders.put(key, value.build())); - - } - - public Map getJsonPathExpressions() { - return expressions; - } - - public Map getNestedValidationContextsBuilders() { - return nestedValidationContextsBuilders; - } - - public static class Builder> implements - ValidationContext.Builder, - WithExpressions, VariableExtractorAdapter, - MessageProcessorAdapter { - - private final Map expressions = new HashMap<>(); - - protected final Map> nestedValidationContextBuilders= new HashMap<>(); - - @Override - public B expressions(Map expressions) { - this.expressions.putAll(expressions); - return (B) this; - } - - @Override - public B expression(final String expression, - final Object value) { - this.expressions.put(expression, value); - return (B) this; - } - - @Override - public EntityValidationContext build() { - return new EntityValidationContext(this); - } - - @Override - public MessageProcessor asProcessor() { - return new DelegatingPathExpressionProcessor.Builder() - .expressions(expressions) - .build(); - } - - @Override - public VariableExtractor asExtractor() { - return new DelegatingPayloadVariableExtractor.Builder() - .expressions(expressions) - .build(); - } - - } - } - - public static class PetEntityValidationContext extends EntityValidationContext { - - public PetEntityValidationContext(Builder builder) { - super(builder); - } - - public static class Builder extends - EntityValidationContext.Builder { - - public Builder id(String expression) { - return expression("$.id", expression); - } - - public Builder name(String expression) { - return expression("$.name", expression); - } - - public Builder category(String expression) { - return expression("$.category", expression); - } - - public Builder urls(String expression) { - return expression("$.urls", expression); - } - - - public Builder urls(int index, String expression) { - return expression("$.urls[%d]".formatted(index), expression); - } - - public Builder address(Consumer validator) { - AddressEntityValidationContext.Builder addressEntityValidationContextBuilder = new AddressEntityValidationContext.Builder(); - validator.accept(addressEntityValidationContextBuilder); - nestedValidationContextBuilders.put("$.address", addressEntityValidationContextBuilder); - - return this; - } - - - public Builder owners(AggregateEntityValidationContext.Builder aggregateContext) { - nestedValidationContextBuilders.put("$.owners", aggregateContext); - return this; - } - - public static Builder pet() { - return new Builder(); - } - - @Override - public PetEntityValidationContext build() { - return new PetEntityValidationContext(this); - } - - } - } - - public static class AddressEntityValidationContext extends EntityValidationContext { - - public AddressEntityValidationContext(Builder builder) { - super(builder); - } - - public static class Builder extends - EntityValidationContext.Builder { - - - public Builder street(String expression) { - return expression("$.street", expression); - } - - public Builder city(String expression) { - return expression("$.city", expression); - } - - public Builder zip(String expression) { - return expression("$.zip", expression); - } - - public static Builder address() { - return new Builder(); - } - - @Override - public AddressEntityValidationContext build() { - return new AddressEntityValidationContext(this); - } - - } - } - - public static class OwnerEntityValidationContext extends EntityValidationContext { - - public OwnerEntityValidationContext(Builder builder) { - super(builder); - } - - public static class Builder extends - EntityValidationContext.Builder { - - public Builder address(Consumer validator) { - AddressEntityValidationContext.Builder addressEntityValidationContextBuilder = new AddressEntityValidationContext.Builder(); - validator.accept(addressEntityValidationContextBuilder); - nestedValidationContextBuilders.put("address", addressEntityValidationContextBuilder); - return this; - } - - public Builder name(String expression) { - expression("$.name", expression); - return this; - } - - @Override - public OwnerEntityValidationContext build() { - return new OwnerEntityValidationContext(this); - } - } - } - - public static class AggregateEntityValidationContext> extends EntityValidationContext { - - private final Type type; - - private List> validator; - - public AggregateEntityValidationContext(Builder builder) { - super(builder); - - this.type = builder.type; - this.validator = builder.validator; - } - - public enum Type { - ONE_OF, ANY_OF, ALL_OF, NONE_OF - } - - public static class Builder> extends EntityValidationContext.Builder, Builder> { - - private final Type type; - - private final List> validator; - - public Builder(Type type, List> validator) { - this.type = type; - this.validator = validator; - } - - public static > Builder anyOf(List> validator) { - return new Builder<>(Type.ANY_OF, validator); - } - - public static > Builder allOf(List> validator) { - return new Builder<>(Type.ALL_OF, validator); - } - - public static > Builder noneOf(List> validator) { - - return new Builder<>(Type.NONE_OF, validator); - } - - public static > Builder oneOf(List> validator) { - return new Builder<>(Type.ONE_OF, validator); - } - - @Override - public AggregateEntityValidationContext build() { - return null; - } - } - - } -} \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/sample/PetApi.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/sample/PetApi.java deleted file mode 100644 index 325be20a88..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/sample/PetApi.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.citrusframework.openapi.generator.sample; - -import java.util.HashMap; -import java.util.Map; -import org.citrusframework.http.client.HttpClient; -import org.citrusframework.openapi.OpenApiSpecification; -import org.citrusframework.openapi.generator.TestApiClientRequestActionBuilder; -import org.citrusframework.openapi.generator.rest.petstore.model.Pet; -import org.citrusframework.testapi.GeneratedApi; - -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-20T08:47:39.378047600+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -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"; - } - - private OpenApiSpecification openApiSpecification = null; - - public Map getApiInfoExtensions() { - Map infoExtensionMap = new HashMap<>(); - infoExtensionMap.put("x-citrus-api-name", "petstore"); - infoExtensionMap.put("x-citrus-app", "PETS"); - return infoExtensionMap; - } - - public static PetApi openApiPetStore(HttpClient httpClient) { - - return new PetApi(); - } - - private static OpenApiSpecification petApi() { - // TODO implement me - return null; - } - - public AddPetActionBuilder addPet() { - return new AddPetActionBuilder(); - } - - public DeletePetActionBuilder deletePet() { - return new DeletePetActionBuilder(); - } - - public FindPetByStatusActionBuilder findPetsByStatus() { - return new FindPetByStatusActionBuilder(); - } - - public FindPetsByTagsActionBuilder findPetsByTags() { - return new FindPetsByTagsActionBuilder(); - } - - public GetPetByIdActionBuilder getPetById() { - return new GetPetByIdActionBuilder(); - } - - public class AddPetActionBuilder extends PetStoreAbstractSendAction.Builder { - - private static final String METHOD = "POST"; - - private static final String ENDPOINT = "/pet"; - - private static final String OPERATION_NAME = "addPet"; - - public AddPetActionBuilder() { - super(openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); - } - - public AddPetActionBuilder withStatus(String status) { - queryParam("status", status); - return this; - } - - public AddPetActionBuilder withPet(Pet pet) { - // TODO: fix this - getMessageBuilderSupport().body(pet.toString()); - return this; - } - - } - - public class DeletePetActionBuilder extends TestApiClientRequestActionBuilder { - - private static final String METHOD = "DELETE"; - - private static final String ENDPOINT = "/pet/{petId}"; - - private static final String OPERATION_NAME = "deletePet"; - - public DeletePetActionBuilder() { - super(openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); - } - - public DeletePetActionBuilder withId(String id) { - pathParameter("id", id); - return this; - } - - public DeletePetActionBuilder withPet(Pet pet) { - // TODO: fix this pet.toString will not properly work - getMessageBuilderSupport().body(pet.toString()); - return this; - } - - } - - public static class FindPetByStatusActionBuilder extends PetStoreAbstractSendAction.Builder { - - private static final String METHOD = "GET"; - - private static final String ENDPOINT = "/pet/findByStatus"; - - private static final String OPERATION_NAME = "findPetsByStatus"; - - public FindPetByStatusActionBuilder() { - super(PetApi.petApi(), METHOD, ENDPOINT, OPERATION_NAME); - } - - public FindPetByStatusActionBuilder withStatus(String status) { - queryParam("status", status); - return this; - } - - } - - public static class FindPetsByTagsActionBuilder extends PetStoreAbstractSendAction.Builder { - - private static final String METHOD = "GET"; - - private static final String ENDPOINT = "/pet/findByTags"; - - private static final String OPERATION_NAME = "findPetsByTags"; - - public FindPetsByTagsActionBuilder() { - super(PetApi.petApi(), METHOD, ENDPOINT, OPERATION_NAME); - } - - public FindPetsByTagsActionBuilder withTags(String... tags) { - queryParam("tags", toQueryParam(tags)); - return this; - } - } - - public static class GetPetByIdActionBuilder extends PetStoreAbstractSendAction.Builder { - - private static final String METHOD = "GET"; - - private static final String ENDPOINT = "/pet/{petId}"; - - private static final String OPERATION_NAME = "getPetById"; - - public GetPetByIdActionBuilder() { - super(PetApi.petApi(), METHOD, ENDPOINT, OPERATION_NAME); - } - - public GetPetByIdActionBuilder withId(String id) { - pathParameter("id", id); - return this; - } - - - - // TODO: find solution for authentication -// public GetPetByIdActionBuilder withBasicUsername(String basicUsername) { -// this.basicUsername = basicUsername; -// return this; -// } -// -// public GetPetByIdActionBuilder withBasicPassword(String basicPassword) { -// this.basicPassword = basicPassword; -// return this; -// } - } - - public static class UpdatePetActionBuilder extends PetStoreAbstractSendAction.Builder { - - private static final String METHOD = "PUT"; - - private static final String ENDPOINT = "/pet"; - - private static final String OPERATION_NAME = "updatePet"; - - public UpdatePetActionBuilder() { - super(PetApi.petApi(), METHOD, ENDPOINT, OPERATION_NAME); - } - - public UpdatePetActionBuilder withId(String id) { - pathParameter("id", id); - return this; - } - - public UpdatePetActionBuilder withPet(Pet pet) { - // TODO: fix this pet.toString - getMessageBuilderSupport().body(pet.toString()); - return this; - } - } - - public static class UpdatePetWithFormDataActionBuilder extends - PetStoreAbstractSendAction.Builder { - - private static final String METHOD = "POST"; - - private static final String ENDPOINT = "/pet/{petId}"; - - private static final String OPERATION_NAME = "updatePetWithForm"; - - public UpdatePetWithFormDataActionBuilder() { - super(PetApi.petApi(), METHOD, ENDPOINT, OPERATION_NAME); - } - - public UpdatePetWithFormDataActionBuilder withId(String id) { - pathParameter("id", id); - return this; - } - - // TODO: what is the magic about form data request? - } - - public static class UploadFileActionBuilder extends PetStoreAbstractSendAction.Builder { - - private static final String METHOD = "POST"; - - private static final String ENDPOINT = "/pet/{petId}/uploadImage"; - - private static final String OPERATION_NAME = "uploadImage"; - - public UploadFileActionBuilder() { - super(PetApi.petApi(), METHOD, ENDPOINT, OPERATION_NAME); - } - - public UploadFileActionBuilder withId(String id) { - pathParameter("id", id); - return this; - } - - public UploadFileActionBuilder withAdditionalMetadata(String additionalMetadata) { - - // TODO: what is the magic about form data request? - formData("additionalMetadata", additionalMetadata); - return this; - } - } - - - -} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/sample/PetStoreAbstractReceiveActionBuilder.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/sample/PetStoreAbstractReceiveActionBuilder.java deleted file mode 100644 index e8f1e5c473..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/sample/PetStoreAbstractReceiveActionBuilder.java +++ /dev/null @@ -1,250 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.citrusframework.openapi.generator.sample; - -import static org.springframework.util.CollectionUtils.isEmpty; - -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.spi.Resources; -import org.citrusframework.testapi.ApiActionBuilderCustomizerService; -import org.citrusframework.testapi.GeneratedApi; -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; - -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-20T08:47:39.378047600+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -public abstract class PetStoreAbstractReceiveActionBuilder 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) { - recieveResponse(context); - } - - /** - * This method receives the HTTP-Response. - * - * @deprecated use {@link PetStoreAbstractReceiveActionBuilder#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 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/java/org/citrusframework/openapi/generator/sample/PetStoreAbstractSendActionBuilder.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/sample/PetStoreAbstractSendActionBuilder.java deleted file mode 100644 index a02a8d4639..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/sample/PetStoreAbstractSendActionBuilder.java +++ /dev/null @@ -1,234 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.citrusframework.openapi.generator.sample; - -import static org.springframework.util.CollectionUtils.isEmpty; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.ServiceLoader; -import javax.sql.DataSource; -import org.citrusframework.actions.SendMessageAction; -import org.citrusframework.context.TestContext; -import org.citrusframework.http.actions.HttpClientRequestActionBuilder; -import org.citrusframework.http.client.HttpClient; -import org.citrusframework.openapi.OpenApiSpecification; -import org.citrusframework.openapi.actions.OpenApiClientRequestActionBuilder; -import org.citrusframework.testapi.ApiActionBuilderCustomizerService; -import org.citrusframework.testapi.GeneratedApi; -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.http.MediaType; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; - -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-20T08:47:39.378047600+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -public abstract class PetStoreAbstractSendAction extends SendMessageAction { - - 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); - } - - - 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 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; - } - - public static class Builder extends OpenApiClientRequestActionBuilder { - - // TODO: do we really need this? - protected OpenApiSpecification openApiSpec; - - private final String path; - - private final Map pathParameters = new HashMap<>(); - - private final MultiValueMap formData = new LinkedMultiValueMap<>(); - - // TODO: can we just pass in the operation? - public Builder(OpenApiSpecification openApiSpec, String method, String path, String operationName) { - super(openApiSpec, "%s_%s".formatted(method, path)); - name(String.format("%s:%s", "PetStore".toLowerCase(), operationName)); - getMessageBuilderSupport().header("citrus_open_api_operation_name", operationName); - getMessageBuilderSupport().header("citrus_open_api_method", method); - getMessageBuilderSupport().header("citrus_open_api_path", path); - - this.openApiSpec = openApiSpec; - this.path = path; - } - - protected void pathParameter(String name, String value) { - pathParameters.put(name, value); - } - - protected void formData(String name, String value) { - formData.add(name, value); - } - - protected String qualifiedPath(String path) { - - String qualifiedPath = path; - for (Entry entry : pathParameters.entrySet()) { - qualifiedPath = qualifiedPath.replace("{%s}".formatted(entry.getKey()), entry.getValue()); - } - return qualifiedPath; - } - - protected String toQueryParam(String...arrayElements) { - return String.join(",", arrayElements); - } - - @Override - public SendMessageAction doBuild() { - // TODO: register callback to modify builder - path(qualifiedPath(path)); - if (!formData.isEmpty()) { - // TODO: do we have to explicitly set the content type or is this done by citrus - messageBuilderSupport.contentType(MediaType.MULTIPART_FORM_DATA_VALUE); - getMessageBuilderSupport().body(formData); - } - return super.doBuild(); - } - - } -} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/util/MultipartConverter.java b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/util/MultipartConverter.java new file mode 100644 index 0000000000..6869b9ecea --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/util/MultipartConverter.java @@ -0,0 +1,76 @@ +package org.citrusframework.openapi.generator.util; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.apache.commons.fileupload.MultipartStream; +import org.citrusframework.exceptions.CitrusRuntimeException; +import org.citrusframework.http.message.HttpMessage; + +/** + * Provides utility method to convert a multipart http message to a map for simplified assertion. + */ +public class MultipartConverter { + + private static final Pattern NAME_PATTERN = Pattern.compile("name=\"([^\"]+)\""); + + private static final Pattern CONTENT_PATTERN = Pattern.compile("Content-Type:\\s*([^\\s;]+)"); + + public static Map multipartMessageToMap(HttpMessage message) { + String contentType = message.getContentType(); + String boundary = contentType.substring(contentType.indexOf("=") + 1); + + Map partMap = new HashMap<>(); + ByteArrayInputStream inputStream = null; + try { + inputStream = new ByteArrayInputStream(message.getPayload(String.class).getBytes()); + MultipartStream multipartStream = new MultipartStream(inputStream, boundary.getBytes(), + 4096, null); + + boolean nextPart = multipartStream.skipPreamble(); + while (nextPart) { + String headers = multipartStream.readHeaders(); + String partName = getHeaderGroup(headers, NAME_PATTERN); + String partContentType = getHeaderGroup(headers, CONTENT_PATTERN); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + multipartStream.readBodyData(outputStream); + String rawBodyContent = outputStream.toString(); + + partMap.put(partName, convertContent(rawBodyContent, partContentType)); + nextPart = multipartStream.readBoundary(); + } + + return partMap; + } catch (IOException e) { + throw new CitrusRuntimeException("Unable to parse multipart data"); + } + + } + + private static String getHeaderGroup(String headers, Pattern groupPattern) { + + Matcher m = groupPattern.matcher(headers); + + if (m.find()) { + return m.group(1); + } else { + throw new CitrusRuntimeException( + "unable to determine header group name: " + groupPattern); + } + } + + private static Object convertContent(String rawContent, String contentType) { + if (contentType != null) { + if (contentType.contains("application/octet-stream")) { + return rawContent.getBytes(StandardCharsets.ISO_8859_1); + } + } + return rawContent; + } +} 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 deleted file mode 100644 index 1b0b8824a7..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/java/org/citrusframework/openapi/generator/util/TestApiActionBuilderCustomizer.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.citrusframework.openapi.generator.util; - -import org.citrusframework.TestAction; -import org.citrusframework.actions.SendMessageAction.SendMessageActionBuilder; -import org.citrusframework.context.TestContext; -import org.citrusframework.testapi.ApiActionBuilderCustomizerService; -import org.citrusframework.testapi.GeneratedApi; - -public class TestApiActionBuilderCustomizer implements ApiActionBuilderCustomizerService { - - @Override - public > T build(GeneratedApi generatedApi, TestAction action, - TestContext context, T builder) { - - generatedApi.getApiInfoExtensions().forEach((key, value) -> { - builder.getMessageBuilderSupport().header(key, value); - }); - - return builder; - } -} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/META-INF/services/org.citrusframework.testapi.ApiActionBuilderCustomizerService b/test-api-generator/citrus-test-api-generator-core/src/test/resources/META-INF/services/org.citrusframework.testapi.ApiActionBuilderCustomizerService deleted file mode 100644 index ba96f521f6..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/META-INF/services/org.citrusframework.testapi.ApiActionBuilderCustomizerService +++ /dev/null @@ -1 +0,0 @@ -org.citrusframework.openapi.generator.util.TestApiActionBuilderCustomizer \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/META-INF/spring.handlers b/test-api-generator/citrus-test-api-generator-core/src/test/resources/META-INF/spring.handlers index 1f0c4bdb95..f1955af26b 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/META-INF/spring.handlers +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/META-INF/spring.handlers @@ -1,3 +1,3 @@ -http\://www.citrusframework.org/citrus-test-schema/multiparttest-api=org.citrusframework.openapi.generator.rest.multiparttest.citrus.extension.MultipartTestNamespaceHandler -http\://www.citrusframework.org/citrus-test-schema/openapifromwsdl-api=org.citrusframework.openapi.generator.soap.bookservice.citrus.extension.OpenApiFromWsdlNamespaceHandler -http\://www.citrusframework.org/citrus-test-schema/petstore-api=org.citrusframework.openapi.generator.rest.petstore.citrus.extension.PetStoreNamespaceHandler +http\://www.citrusframework.org/citrus-test-schema/bookservice-api=org.citrusframework.openapi.generator.soap.bookservice.spring.BookServiceNamespaceHandler +http\://www.citrusframework.org/citrus-test-schema/petstore-api=org.citrusframework.openapi.generator.rest.petstore.spring.PetStoreNamespaceHandler +http\://www.citrusframework.org/citrus-test-schema/extpetstore-api=org.citrusframework.openapi.generator.rest.extpetstore.spring.ExtPetStoreNamespaceHandler \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/META-INF/spring.schemas b/test-api-generator/citrus-test-api-generator-core/src/test/resources/META-INF/spring.schemas index 0050010472..5b3c2539b9 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/META-INF/spring.schemas +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/META-INF/spring.schemas @@ -1,3 +1,4 @@ -http\://www.citrusframework.org/citrus-test-schema/multiparttest-api/multiparttest-api.xsd=schema/xsd/multiparttest-api.xsd -http\://www.citrusframework.org/citrus-test-schema/openapifromwsdl-api/openapifromwsdl-api.xsd=schema/xsd/openapifromwsdl-api.xsd http\://www.citrusframework.org/citrus-test-schema/petstore-api/petstore-api.xsd=schema/xsd/petstore-api.xsd +http\://www.citrusframework.org/citrus-test-schema/extpetstore-api/extpetstore-api.xsd=schema/xsd/extpetstore-api.xsd +http\://www.citrusframework.org/citrus-test-schema/bookservice-api/bookservice-api.xsd=schema/xsd/bookservice-api.xsd +http\://www.citrusframework.org/bookstore/datatypes/BookDatatypes.xsd=schema/xsd/BookDatatypes.xsd diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/apis/BookService-generated.yaml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/apis/BookService-generated.yaml new file mode 100644 index 0000000000..f70656312d --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/apis/BookService-generated.yaml @@ -0,0 +1,43 @@ +--- +info: + contact: + name: "org.citrusframework.openapi.generator.SimpleWsdlToOpenApiTransformer" + description: "This api has been generated from the following wsdl 'BookService.wsdl'.\ + \ It's purpose is solely to serve as input for SOAP API generation. Note that\ + \ only operations are extracted from the WSDL. No schema information whatsoever\ + \ is generated!" + title: "Generated api from wsdl" + version: "1.0.0" +openapi: "3.0.1" +paths: + /GetBook: + post: + description: "This operation retrieves details for a specific book identified\ + \ by its ID." + operationId: "GetBook" + responses: + default: + description: "Generic Response" + summary: "http://www.citrusframework.com/BookService/GetBook" + tags: + - "BookServiceSOAP" + /AddBook: + post: + description: "" + operationId: "AddBook" + responses: + default: + description: "Generic Response" + summary: "http://www.citrusframework.com/BookService/AddBook" + tags: + - "BookServiceSOAP" + /GetAllBooks: + post: + description: "" + operationId: "GetAllBooks" + responses: + default: + description: "Generic Response" + summary: "http://www.citrusframework.com/BookService/GetAllBooks" + tags: + - "BookServiceSOAP" \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/apis/multiparttest-rest-resource.yaml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/apis/multiparttest-rest-resource.yaml deleted file mode 100644 index cfac634788..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/apis/multiparttest-rest-resource.yaml +++ /dev/null @@ -1,249 +0,0 @@ -openapi: 3.0.3 -info: - title: multiparttest API - version: 2.0.0 - description: | - The service to test mutlipart - x-citrus-app: MPT - x-citrus-api-name: multiparttest-rest-resource - contact: - name: Citrusframework Authors - email: citrus-dev@googlegroups.com - url: https://citrusframework.org -tags: - - name: multiparttest-controller -paths: - /api/v2/multitest-file/{bucket}/{filename}/random: - post: - tags: - - multiparttest-controller - operationId: postRandom - summary: Uploads random file. - parameters: - - name: bucket - description: The name of an existing s3 bucket. - in: path - required: true - schema: - type: string - - name: filename - description: The name under which to store the random file. - in: path - required: true - schema: - type: string - responses: - 200: - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/PutObjectResult' - 500: - description: Internal Server Error - /api/v2/multitest-file/{bucket}/{filename}: - post: - tags: - - multiparttest-controller - operationId: postFile - summary: Uploads file. - parameters: - - name: bucket - description: The name of an existing s3 bucket. - in: path - required: true - schema: - type: string - - name: filename - description: The name of the file which should be uploaded. It may override any existing file with the same name. - in: path - required: true - schema: - type: string - requestBody: - required: true - content: - multipart/form-data: - schema: - type: object - properties: - multipartFile: - type: string - format: binary - responses: - 200: - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/PutObjectResult' - 500: - description: Internal Server Error - delete: - tags: - - multiparttest-controller - operationId: deleteObject - summary: Delete file. - parameters: - - name: bucket - in: path - required: true - schema: - type: string - description: The name of an existing s3 bucket. - - name: filename - in: path - required: true - schema: - type: string - description: The name of the file which should be deleted. - responses: - 200: - description: OK - content: - application/json: - schema: - type: boolean - 500: - description: Internal Server Error - /api/v2/multitest-reportgeneration: - post: - tags: - - multiparttest-controller - operationId: generateReport - summary: summary - requestBody: - required: true - content: - multipart/form-data: - schema: - type: object - required: ['template'] - properties: - template: - description: | - Content of the template. - type: string - additionalData: - $ref: '#/components/schemas/AdditionalData' - schema: - description: | - An optional JSON schema to validate the created report against. - type: string - responses: - 200: - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/PutObjectResult' - 500: - description: Internal Server Error - /api/v2/multitest-multipledatatypes: - post: - tags: - - multiparttest-controller - operationId: multipleDatatypes - summary: summary - requestBody: - required: true - content: - multipart/form-data: - schema: - type: object - properties: - stringData: - type: string - booleanData: - type: boolean - integerData: - type: integer - - responses: - 200: - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/PutObjectResult' - 500: - description: Internal Server Error - /api/v2/multitest-file/{bucket}/{filename}/exists: - get: - tags: - - multiparttest-controller - operationId: fileExists - summary: Checks if file exist. - parameters: - - name: bucket - description: The name of an existing s3 bucket. - in: path - required: true - schema: - type: string - - name: filename - description: The name of the file on which the status should be checked. - in: path - required: true - schema: - type: string - responses: - 200: - description: OK - content: - application/json: - schema: - type: boolean - 500: - description: Internal Server Error -components: - schemas: - Metadata: - type: object - properties: - userMetadata: - type: object - additionalProperties: - type: string - rawMetadata: - type: object - additionalProperties: - type: string - httpExpiresDate: - type: string - format: date-time - expirationTime: - type: string - format: date-time - expirationTimeRuleId: - type: string - ongoingRestore: - type: boolean - restoreExpirationTime: - type: string - format: date-time - bucketKeyEnabled: - type: boolean - PutObjectResult: - type: object - properties: - versionId: - type: string - eTag: - type: string - expirationTime: - type: string - format: date-time - expirationTimeRuleId: - type: string - contentMd5: - type: string - metadata: - $ref: '#/components/schemas/Metadata' - isRequesterCharged: - type: boolean - AdditionalData: - description: | - Additional data provided to the report. For each dataset requested, provide a json - object with the name of the dataset. - type: string diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/apis/petstore-extended-v3.yaml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/apis/petstore-extended-v3.yaml new file mode 100644 index 0000000000..865466c524 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/apis/petstore-extended-v3.yaml @@ -0,0 +1,1230 @@ +openapi: 3.0.2 +info: + title: Extended Petstore API + description: | + This is an extended version of the Petstore API which includes additional operations, + such as updating a pet using form data and managing vaccination records. + version: 1.0.0 +servers: + - url: /api/v3/ext + +paths: + /pet/simple/{petId}: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in path parameter + operationId: getPetWithSimpleStyleArray + description: "Returns multiple pets by ID using multiple ids in path parameter." + parameters: + - name: petId + in: path + description: IDs of pet to return + required: true + style: simple + explode: false + schema: + type: array + items: + type: integer + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/simple/object/{petId}: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in path parameter + operationId: getPetWithSimpleStyleObject + description: "Returns multiple pets by ID using multiple ids in path parameter." + parameters: + - name: petId + in: path + description: IDs of pet to return + required: true + style: simple + explode: false + schema: + $ref: '#/components/schemas/PetIdentifier' + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/simple/exploded/{petId}: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in path parameter + operationId: getPetWithSimpleStyleArrayExploded + description: "Returns multiple pets by ID using multiple ids in path parameter." + parameters: + - name: petId + in: path + description: IDs of pet to return + required: true + style: simple + explode: false + schema: + type: array + items: + type: integer + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/simple/exploded/object/{petId}: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in path parameter + operationId: getPetWithSimpleStyleObjectExploded + description: "Returns multiple pets by ID using multiple ids in path parameter." + parameters: + - name: petId + in: path + description: IDs of pet to return + required: true + style: simple + explode: true + schema: + $ref: '#/components/schemas/PetIdentifier' + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/label/{petId}: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in path parameter + operationId: getPetWithLabelStyleArray + description: "Returns multiple pets by ID using multiple ids in path parameter." + parameters: + - name: petId + in: path + description: IDs of pet to return + required: true + style: label + explode: false + schema: + type: array + items: + type: integer + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/label/object/{petId}: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in path parameter + operationId: getPetWithLabelStyleObject + description: "Returns multiple pets by ID using multiple ids in path parameter." + parameters: + - name: petId + in: path + description: IDs of pet to return + required: true + style: label + explode: false + schema: + $ref: '#/components/schemas/PetIdentifier' + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/label/exploded/{petId}: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in path parameter + operationId: getPetWithLabelStyleArrayExploded + description: "Returns multiple pets by ID using multiple ids in path parameter." + parameters: + - name: petId + in: path + description: IDs of pet to return + required: true + style: label + explode: true + schema: + type: array + items: + type: integer + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/label/exploded/object/{petId}: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in path parameter + operationId: getPetWithLabelStyleObjectExploded + description: "Returns multiple pets by ID using multiple ids in path parameter." + parameters: + - name: petId + in: path + description: IDs of pet to return + required: true + style: label + explode: true + schema: + $ref: '#/components/schemas/PetIdentifier' + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/matrix/{petId}: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in path parameter + operationId: getPetWithMatrixStyleArray + description: "Returns multiple pets by ID using multiple ids in path parameter." + parameters: + - name: petId + in: path + description: IDs of pet to return + required: true + style: matrix + explode: false + schema: + type: array + items: + type: integer + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/matrix/object/{petId}: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in path parameter + operationId: getPetWithMatrixStyleObject + description: "Returns multiple pets by ID using multiple ids in path parameter." + parameters: + - name: petId + in: path + description: IDs of pet to return + required: true + style: matrix + explode: false + schema: + $ref: '#/components/schemas/PetIdentifier' + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/matrix/exploded/{petId}: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in path parameter + operationId: getPetWithMatrixStyleArrayExploded + description: "Returns multiple pets by ID using multiple ids in path parameter." + parameters: + - name: petId + in: path + description: IDs of pet to return + required: true + style: matrix + explode: true + schema: + type: array + items: + type: integer + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/matrix/exploded/object/{petId}: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in path parameter + operationId: getPetWithMatrixStyleObjectExploded + description: "Returns multiple pets by ID using multiple ids in path parameter." + parameters: + - name: petId + in: path + description: IDs of pet to return + required: true + style: matrix + explode: true + schema: + $ref: '#/components/schemas/PetIdentifier' + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/header/simple: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in header parameter + operationId: getPetWithSimpleStyleHeader + description: "Returns multiple pets by ID using multiple ids in path parameter." + parameters: + - name: petId + in: header + description: IDs of pet to return + required: true + style: simple + explode: false + schema: + type: array + items: + type: integer + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/header/simple/exploded: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in header parameter + operationId: getPetWithSimpleStyleExplodedHeader + description: "Returns multiple pets by ID using multiple ids in path parameter." + parameters: + - name: petId + in: header + description: IDs of pet to return + required: true + style: simple + explode: true + schema: + type: array + items: + type: integer + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/header/simple/object: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in header parameter + operationId: getPetWithSimpleStyleObjectHeader + description: "Returns multiple pets by ID using multiple ids in path parameter." + parameters: + - name: petId + in: header + description: IDs of pet to return + required: true + style: simple + explode: false + schema: + $ref: '#/components/schemas/PetIdentifier' + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/header/simple/exploded/object: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in header parameter + operationId: getPetWithSimpleStyleExplodedObjectHeader + description: "Returns multiple pets by ID using multiple ids in header parameter." + parameters: + - name: petId + in: header + description: IDs of pet to return + required: true + style: simple + explode: true + schema: + $ref: '#/components/schemas/PetIdentifier' + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/query/form: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in header parameter + operationId: getPetWithFormStyleQuery + description: "Returns multiple pets by ID using multiple ids in query parameter." + parameters: + - name: petId + in: query + description: IDs of pet to return + required: true + style: form + explode: false + schema: + type: array + items: + type: integer + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/query/form/object: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in header parameter + operationId: getPetWithFormStyleObjectQuery + description: "Returns multiple pets by ID using multiple ids in query parameter." + parameters: + - name: petId + in: query + description: IDs of pet to return + required: true + style: form + explode: false + schema: + $ref: '#/components/schemas/PetIdentifier' + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/query/form/exploded: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in header parameter + operationId: getPetWithFormStyleExplodedQuery + description: "Returns multiple pets by ID using multiple ids in path parameter." + parameters: + - name: petId + in: query + description: IDs of pet to return + required: true + style: form + explode: true + schema: + type: array + items: + type: integer + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/query/form/exploded/object: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in header parameter + operationId: getPetWithFormStyleExplodedObjectQuery + description: "Returns multiple pets by ID using multiple ids in path parameter." + parameters: + - name: petId + in: query + description: IDs of pet to return + required: true + style: form + explode: true + schema: + $ref: '#/components/schemas/PetIdentifier' + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/query/deep/object: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in header parameter + operationId: getPetWithDeepObjectTypeQuery + description: "Returns multiple pets by ID using multiple ids in path parameter." + parameters: + - name: petId + in: query + description: IDs of pet to return + required: true + style: deepObject + explode: true + schema: + $ref: '#/components/schemas/PetIdentifier' + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/cookie/form: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in cookie parameter + operationId: getPetWithFormStyleCookie + description: "Returns multiple pets by ID using multiple ids in path parameter." + parameters: + - name: petId + in: cookie + description: IDs of pet to return + required: true + style: form + explode: false + schema: + type: array + items: + type: integer + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/cookie/form/object: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in cookie parameter + operationId: getPetWithFormObjectStyleCookie + description: "Returns multiple pets by ID using multiple ids in path parameter." + parameters: + - name: petId + in: cookie + description: IDs of pet to return + required: true + style: form + explode: false + schema: + $ref: '#/components/schemas/PetIdentifier' + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/cookie/form/exploded: + get: + tags: + - extPet + summary: Get a pet by id supporting multiple ids in cookie parameter + operationId: getPetWithFormExplodedStyleCookie + description: "Returns multiple pets by ID using multiple ids in cookie parameter." + parameters: + - name: petId + in: cookie + description: IDs of pet to return + required: true + style: form + explode: true + schema: + type: array + items: + type: integer + responses: + '200': + description: Successful operation + content: + application/json: + schema: + type: array + items: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/{petId}: + get: + tags: + - extPet + summary: Get a pet using a session cookie + operationId: getPetWithCookie + description: "Returns a single pet by ID, using a session ID stored in a cookie." + parameters: + - name: petId + in: path + description: ID of pet to return + required: true + schema: + type: integer + format: int64 + - name: session_id + in: cookie + required: true + schema: + type: string + description: The session ID cookie + - name: opt_trx_id + in: cookie + schema: + type: string + description: The optional transaction ID cookie + responses: + '200': + description: Successful operation + content: + application/xml: + schema: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + application/json: + schema: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + put: + tags: + - extPet + summary: Updates a pet in the store with query data. + description: "Update the name, status, tags and nicknames of an existing pet using query data." + operationId: updatePetWithArrayQueryData + parameters: + - name: petId + in: path + required: true + description: ID of the pet that needs to be updated + schema: + type: integer + format: int64 + - name: name + in: query + required: true + description: Updated name of the pet + schema: + type: string + - name: status + in: query + required: true + description: Updated status of the pet + schema: + type: string + - name: tags + in: query + required: true + description: Updated tags of the pet + schema: + type: array + items: + type: string + - name: nicknames + in: query + required: true + description: Updated nicknames of the pet + schema: + type: array + items: + type: string + - name: sampleStringHeader + in: header + required: true + description: A sample string header + schema: + type: string + - name: sampleIntHeader + in: header + description: A sample int header + schema: + type: integer + responses: + '200': + description: Pet successfully updated + '400': + description: Invalid ID supplied + '404': + description: Pet not found + '405': + description: Validation exception + /pet/form/{petId}: + put: + tags: + - extPet + summary: Updates a pet in the store with form data + description: "Update the name or status of an existing pet using url encoded form data." + operationId: updatePetWithFormUrlEncoded + parameters: + - name: petId + in: path + required: true + description: ID of the pet that needs to be updated + schema: + type: integer + format: int64 + requestBody: + required: true + content: + application/x-www-form-urlencoded: + schema: + type: object + required: [ "name", "status", "tags", "age" ] + properties: + name: + description: Updated name of the pet + type: string + status: + description: Updated status of the pet + type: string + age: + description: The age of the pet in years + type: integer + owners: + description: The number of pre owners + type: integer + tags: + type: array + items: + type: string + nicknames: + type: array + items: + type: string + responses: + '200': + description: Pet successfully updated + '400': + description: Invalid ID supplied + '404': + description: Pet not found + '405': + description: Validation exception + /secure-basic/pet/{petId}: + get: + tags: + - extPet + summary: Get a pet via basic authentication + description: "Returns a single pet by ID, requiring basic authentication." + operationId: getPetByIdWithBasicAuthentication + security: + - basicAuth: [ ] + + parameters: + - name: petId + in: path + description: ID of pet to return + required: true + schema: + type: integer + format: int64 + - name: allDetails + in: query + description: Requests all details. + required: true + schema: + type: boolean + - name: details + in: query + description: A list with detail specifiers. + schema: + type: array + items: + type: string + - name: requesterInformation + in: query + description: A list of specific requester information. + schema: + type: array + items: + type: string + responses: + '200': + description: Successful operation + content: + application/xml: + schema: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + application/json: + schema: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /secure-bearer/pet/{petId}: + get: + tags: + - extPet + summary: Get a pet via basic authentication + description: "Returns a single pet by ID, requiring basic authentication." + operationId: getPetByIdWithBearerAuthentication + security: + - bearerAuth: [ ] + + parameters: + - name: petId + in: path + description: ID of pet to return + required: true + schema: + type: integer + format: int64 + - name: allDetails + in: query + description: Requests all details. + required: true + schema: + type: boolean + - name: details + in: query + description: A list with detail specifiers. + schema: + type: array + items: + type: string + - name: requesterInformation + in: query + description: A list of specific requester information. + schema: + type: array + items: + type: string + responses: + '200': + description: Successful operation + content: + application/xml: + schema: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + application/json: + schema: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /secure-api-key/pet/{petId}: + get: + tags: + - extPet + summary: Get a pet via basic authentication + description: "Returns a single pet by ID, requiring basic authentication." + operationId: getPetByIdWithApiKeyAuthentication + security: + - api_key_header: [ ] + - api_key_query: [ ] + - api_key_cookie: [ ] + + parameters: + - name: petId + in: path + description: ID of pet to return + required: true + schema: + type: integer + format: int64 + - name: allDetails + in: query + description: Requests all details. + required: true + schema: + type: boolean + - name: details + in: query + description: A list with detail specifiers. + required: false + schema: + type: array + items: + type: string + - name: requesterInformation + in: query + description: A list of specific requester information. + schema: + type: array + items: + type: string + responses: + '200': + description: Successful operation + content: + application/xml: + schema: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + application/json: + schema: + $ref: './petstore-v3.yaml#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + /pet/vaccination/{bucket}/{filename}: + post: + tags: + - extPet + operationId: postVaccinationDocument + summary: Upload a pet vaccination document + description: "Uploads a vaccination document for a pet to a specified S3 bucket." + parameters: + - name: bucket + description: The name of an existing S3 bucket. + in: path + required: true + schema: + type: string + - name: filename + description: The name under which to store the vaccination document. + in: path + required: true + schema: + type: string + responses: + '201': + description: Document successfully uploaded + content: + application/json: + schema: + $ref: '#/components/schemas/VaccinationDocumentResult' + '400': + description: Bad Request - Invalid parameters supplied + '500': + description: Internal Server Error + /pet/vaccination/status-report: + post: + tags: + - extPet + operationId: generateVaccinationReport + summary: Generate a vaccination status report + description: "Generates a vaccination status report in PDF format based on the provided template and data." + requestBody: + required: true + content: + multipart/form-data: + schema: + type: object + required: [ 'template', "reqIntVal" ] + properties: + template: + description: | + Vaccination report template file. + type: string + format: binary + reqIntVal: + description: | + A required integer value. + type: integer + optIntVal: + description: | + An optional integer value. + type: integer + optBoolVal: + description: | + An optional boolean value. + type: boolean + optNumberVal: + description: | + An optional number value. + type: number + optStringVal: + description: | + An optional string value. + type: string + optDateVal: + description: | + An optional date value. + type: string + format: date + additionalData: + $ref: '#/components/schemas/HistoricalData' + schema: + description: | + An optional JSON schema file to validate the created report against. + type: string + format: binary + responses: + '200': + description: A vaccination report in PDF + content: + application/pdf: + schema: + type: string + format: binary + '422': + description: Unprocessable Entity - Validation error in the provided data + '500': + description: Internal Server Error + /pet/vaccination/form: + post: + tags: + - extPet + operationId: postVaccinationFormData + summary: Submit vaccination form data + description: "Submits vaccination details for a pet." + requestBody: + required: true + content: + multipart/form-data: + schema: + type: object + properties: + vaccine: + type: string + description: The name of the vaccine administered. + isFirstVaccination: + type: boolean + description: Indicates if this is the first vaccination or a repetition. + doseNumber: + type: integer + description: The dose number of the vaccine (e.g., 1 for first dose, 2 for second dose). + vaccinationDate: + type: string + format: date + description: The date when the vaccination was administered. + responses: + '201': + description: Form data successfully submitted + content: + application/json: + schema: + $ref: '#/components/schemas/VaccinationDocumentResult' + '400': + description: Bad Request - Invalid form data + '500': + description: Internal Server Error + +components: + securitySchemes: + basicAuth: + type: http + scheme: basic + bearerAuth: + type: http + scheme: bearer # Specifies Bearer token authentication + bearerFormat: JWT # Optional, specifies the format of the bearer token (e.g., JWT) + api_key_header: + type: apiKey + description: Header api key description + name: api_key_header + in: header + api_key_cookie: + type: apiKey + description: Cookie api key description + name: api_key_cookie + in: cookie + api_key_query: + type: apiKey + description: Query api key description + name: api_key_query + in: query + + schemas: + HistoricalData: + description: | + Additional historical data for a vaccination report, not contained in internal storage. + type: object + properties: + lastVaccinationDate: + type: string + format: date + description: The date of the last vaccination. + vaccinationCount: + type: integer + description: The number of vaccinations the pet has received. + VaccinationDocumentResult: + type: object + properties: + documentId: + type: string + description: The unique ID of the uploaded vaccination document. + example: "abc123" + PetIdentifier: + type: object + properties: + name: + type: string + alias: + type: string diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/apis/petstore-v3.yaml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/apis/petstore-v3.yaml new file mode 100644 index 0000000000..6e38ce59fc --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/apis/petstore-v3.yaml @@ -0,0 +1,803 @@ +openapi: 3.0.2 +info: + title: Swagger Petstore - OpenAPI 3.0 + description: |- + This is a sample Pet Store Server based on the OpenAPI 3.0 specification. You can find out more about + Swagger at [http://swagger.io](http://swagger.io). In the third iteration of the pet store, we've switched to the design first approach! + You can now help us improve the API whether it's by making changes to the definition itself or to the code. + That way, with time, we can improve the API in general, and expose some of the new features in OAS3. + + Some useful links: + - [The Pet Store repository](https://github.com/swagger-api/swagger-petstore) + - [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml) + termsOfService: http://swagger.io/terms/ + contact: + email: apiteam@swagger.io + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html + version: 1.0.19 +externalDocs: + description: Find out more about Swagger + url: http://swagger.io +servers: + - url: /api/v3 +tags: + - name: pet + description: Everything about your Pets + externalDocs: + description: Find out more + url: http://swagger.io + - name: store + description: Access to Petstore orders + externalDocs: + description: Find out more about our store + url: http://swagger.io + - name: user + description: Operations about user +paths: + /pet: + put: + tags: + - pet + summary: Update an existing pet + description: Update an existing pet by Id + operationId: updatePet + requestBody: + description: Update an existent pet in the store + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/Pet' + required: true + responses: + "200": + description: Successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + "400": + description: Invalid ID supplied + "404": + description: Pet not found + "405": + description: Validation exception + security: + - petstore_auth: + - write:pets + - read:pets + post: + tags: + - pet + summary: Add a new pet to the store + description: Add a new pet to the store + operationId: addPet + requestBody: + description: Create a new pet in the store + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/Pet' + required: true + responses: + "200": + description: Successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + "405": + description: Invalid input + security: + - petstore_auth: + - write:pets + - read:pets + /pet/findByStatus: + get: + tags: + - pet + summary: Finds Pets by status + description: Multiple status values can be provided with comma separated strings + operationId: findPetsByStatus + parameters: + - name: status + in: query + description: Status values that need to be considered for filter + required: false + explode: true + schema: + type: string + default: available + enum: + - available + - pending + - sold + responses: + "200": + description: successful operation + content: + application/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + "400": + description: Invalid status value + security: + - petstore_auth: + - write:pets + - read:pets + /pet/findByTags: + get: + tags: + - pet + summary: Finds Pets by tags + description: "Multiple tags can be provided with comma separated strings. Use\ + \ tag1, tag2, tag3 for testing." + operationId: findPetsByTags + parameters: + - name: tags + in: query + description: Tags to filter by + required: false + explode: true + schema: + type: array + items: + type: string + responses: + "200": + description: successful operation + content: + application/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + "400": + description: Invalid tag value + security: + - petstore_auth: + - write:pets + - read:pets + /pet/{petId}: + get: + tags: + - pet + summary: Find pet by ID + description: Returns a single pet + operationId: getPetById + parameters: + - name: petId + in: path + description: ID of pet to return + required: true + schema: + type: integer + format: int64 + responses: + "200": + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + "400": + description: Invalid ID supplied + "404": + description: Pet not found + security: + - api_key: [] + - petstore_auth: + - write:pets + - read:pets + post: + tags: + - pet + summary: Updates a pet in the store with form data + description: "" + operationId: updatePetWithForm + parameters: + - name: petId + in: path + description: ID of pet that needs to be updated + required: true + schema: + type: integer + format: int64 + - name: name + in: query + description: Name of pet that needs to be updated + schema: + type: string + - name: status + in: query + description: Status of pet that needs to be updated + schema: + type: string + responses: + "405": + description: Invalid input + security: + - petstore_auth: + - write:pets + - read:pets + delete: + tags: + - pet + summary: Deletes a pet + description: "" + operationId: deletePet + parameters: + - name: api_key + in: header + description: "" + required: false + schema: + type: string + - name: petId + in: path + description: Pet id to delete + required: true + schema: + type: integer + format: int64 + responses: + "400": + description: Invalid pet value + security: + - petstore_auth: + - write:pets + - read:pets + /pet/{petId}/uploadImage: + post: + tags: + - pet + summary: uploads an image + description: "" + operationId: uploadFile + parameters: + - name: petId + in: path + description: ID of pet to update + required: true + schema: + type: integer + format: int64 + - name: additionalMetadata + in: query + description: Additional Metadata + required: false + schema: + type: string + requestBody: + content: + application/octet-stream: + schema: + type: string + format: binary + responses: + "200": + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + security: + - petstore_auth: + - write:pets + - read:pets + /store/inventory: + get: + tags: + - store + summary: Returns pet inventories by status + description: Returns a map of status codes to quantities + operationId: getInventory + responses: + "200": + description: successful operation + content: + application/json: + schema: + type: object + additionalProperties: + type: integer + format: int32 + security: + - api_key: [] + /store/order: + post: + tags: + - store + summary: Place an order for a pet + description: Place a new order in the store + operationId: placeOrder + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Order' + application/xml: + schema: + $ref: '#/components/schemas/Order' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/Order' + responses: + "200": + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Order' + "405": + description: Invalid input + /store/order/{orderId}: + get: + tags: + - store + summary: Find purchase order by ID + description: For valid response try integer IDs with value <= 5 or > 10. Other + values will generate exceptions. + operationId: getOrderById + parameters: + - name: orderId + in: path + description: ID of order that needs to be fetched + required: true + schema: + type: integer + format: int64 + responses: + "200": + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Order' + application/json: + schema: + $ref: '#/components/schemas/Order' + "400": + description: Invalid ID supplied + "404": + description: Order not found + delete: + tags: + - store + summary: Delete purchase order by ID + description: For valid response try integer IDs with value < 1000. Anything + above 1000 or nonintegers will generate API errors + operationId: deleteOrder + parameters: + - name: orderId + in: path + description: ID of the order that needs to be deleted + required: true + schema: + type: integer + format: int64 + responses: + "400": + description: Invalid ID supplied + "404": + description: Order not found + /user: + post: + tags: + - user + summary: Create user + description: This can only be done by the logged in user. + operationId: createUser + requestBody: + description: Created user object + content: + application/json: + schema: + $ref: '#/components/schemas/User' + application/xml: + schema: + $ref: '#/components/schemas/User' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/User' + responses: + default: + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/User' + application/xml: + schema: + $ref: '#/components/schemas/User' + /user/createWithList: + post: + tags: + - user + summary: Creates list of users with given input array + description: Creates list of users with given input array + operationId: createUsersWithListInput + requestBody: + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/User' + responses: + "200": + description: Successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/User' + application/json: + schema: + $ref: '#/components/schemas/User' + default: + description: successful operation + /user/login: + get: + tags: + - user + summary: Logs user into the system + description: "" + operationId: loginUser + parameters: + - name: username + in: query + description: The user name for login + required: false + schema: + type: string + - name: password + in: query + description: The password for login in clear text + required: false + schema: + type: string + responses: + "200": + description: successful operation + headers: + X-Rate-Limit: + description: calls per hour allowed by the user + schema: + type: integer + format: int32 + X-Expires-After: + description: date in UTC when token expires + schema: + type: string + format: date-time + content: + application/xml: + schema: + type: string + application/json: + schema: + type: string + "400": + description: Invalid username/password supplied + /user/logout: + get: + tags: + - user + summary: Logs out current logged in user session + description: "" + operationId: logoutUser + parameters: [] + responses: + default: + description: successful operation + /user/{username}: + get: + tags: + - user + summary: Get user by user name + description: "" + operationId: getUserByName + parameters: + - name: username + in: path + description: 'The name that needs to be fetched. Use user1 for testing. ' + required: true + schema: + type: string + responses: + "200": + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/User' + application/json: + schema: + $ref: '#/components/schemas/User' + "400": + description: Invalid username supplied + "404": + description: User not found + put: + tags: + - user + summary: Update user + description: This can only be done by the logged in user. + operationId: updateUser + parameters: + - name: username + in: path + description: name that needs to be updated + required: true + schema: + type: string + requestBody: + description: Update an existent user in the store + content: + application/json: + schema: + $ref: '#/components/schemas/User' + application/xml: + schema: + $ref: '#/components/schemas/User' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/User' + responses: + default: + description: successful operation + delete: + tags: + - user + summary: Delete user + description: This can only be done by the logged in user. + operationId: deleteUser + parameters: + - name: username + in: path + description: The name that needs to be deleted + required: true + schema: + type: string + responses: + "400": + description: Invalid username supplied + "404": + description: User not found +components: + schemas: + Order: + type: object + properties: + id: + type: integer + format: int64 + example: 10 + petId: + type: integer + format: int64 + example: 198772 + quantity: + type: integer + format: int32 + example: 7 + shipDate: + type: string + format: date-time + status: + type: string + description: Order Status + example: approved + enum: + - placed + - approved + - delivered + complete: + type: boolean + xml: + name: order + Customer: + type: object + properties: + id: + type: integer + format: int64 + example: 100000 + username: + type: string + example: fehguy + address: + type: array + xml: + name: addresses + wrapped: true + items: + $ref: '#/components/schemas/Address' + xml: + name: customer + Address: + type: object + properties: + street: + type: string + example: 437 Lytton + city: + type: string + example: Palo Alto + state: + type: string + example: CA + zip: + type: string + example: "94301" + xml: + name: address + Category: + type: object + properties: + id: + type: integer + format: int64 + example: 1 + name: + type: string + example: Dogs + xml: + name: category + User: + type: object + properties: + id: + type: integer + format: int64 + example: 10 + username: + type: string + example: theUser + firstName: + type: string + example: John + lastName: + type: string + example: James + email: + type: string + example: john@email.com + password: + type: string + example: "12345" + phone: + type: string + example: "12345" + userStatus: + type: integer + description: User Status + format: int32 + example: 1 + xml: + name: user + Tag: + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + xml: + name: tag + Pet: + required: + - name + - photoUrls + type: object + properties: + id: + type: integer + format: int64 + example: 10 + name: + type: string + example: doggie + category: + $ref: '#/components/schemas/Category' + photoUrls: + type: array + xml: + wrapped: true + items: + type: string + xml: + name: photoUrl + tags: + type: array + xml: + wrapped: true + items: + $ref: '#/components/schemas/Tag' + status: + type: string + description: pet status in the store + enum: + - available + - pending + - sold + xml: + name: pet + ApiResponse: + type: object + properties: + code: + type: integer + format: int32 + type: + type: string + message: + type: string + xml: + name: '##default' + requestBodies: + Pet: + description: Pet object that needs to be added to the store + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + UserArray: + description: List of user object + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/User' + securitySchemes: + petstore_auth: + type: oauth2 + flows: + implicit: + authorizationUrl: https://petstore3.swagger.io/oauth/authorize + scopes: + write:pets: modify pets in your account + read:pets: read your pets + api_key: + type: apiKey + name: api_key + in: header diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/apis/petstore.yaml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/apis/petstore.yaml deleted file mode 100644 index 79249f26ed..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/apis/petstore.yaml +++ /dev/null @@ -1,700 +0,0 @@ -swagger: '2.0' -info: - description: 'This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.' - version: 1.0.0 - x-citrus-app: PETS - x-citrus-api-name: petstore - title: OpenAPI Petstore - license: - name: Apache-2.0 - url: 'https://www.apache.org/licenses/LICENSE-2.0.html' -host: petstore.swagger.io -basePath: /v2 -tags: - - name: pet - description: Everything about your Pets - - name: store - description: Access to Petstore orders - - name: user - description: Operations about user -schemes: - - http -paths: - /pet: - post: - tags: - - pet - summary: Add a new pet to the store - description: '' - operationId: addPet - consumes: - - application/json - - application/xml - produces: - - application/xml - - application/json - parameters: - - in: body - name: body - description: Pet object that needs to be added to the store - required: true - schema: - $ref: '#/definitions/Pet' - responses: - '405': - description: Invalid input - security: - - petstore_auth: - - 'write:pets' - - 'read:pets' - put: - tags: - - pet - summary: Update an existing pet - description: '' - operationId: updatePet - consumes: - - application/json - - application/xml - produces: - - application/xml - - application/json - parameters: - - in: body - name: body - description: Pet object that needs to be added to the store - required: true - schema: - $ref: '#/definitions/Pet' - responses: - '400': - description: Invalid ID supplied - '404': - description: Pet not found - '405': - description: Validation exception - security: - - petstore_auth: - - 'write:pets' - - 'read:pets' - /pet/findByStatus: - get: - tags: - - pet - summary: Finds Pets by status - description: Multiple status values can be provided with comma separated strings - operationId: findPetsByStatus - produces: - - application/xml - - application/json - parameters: - - name: status - in: query - description: Status values that need to be considered for filter - required: true - type: array - items: - type: string - enum: - - available - - pending - - sold - default: available - collectionFormat: csv - responses: - '200': - description: successful operation - schema: - type: array - items: - $ref: '#/definitions/Pet' - '400': - description: Invalid status value - security: - - petstore_auth: - - 'write:pets' - - 'read:pets' - /pet/findByTags: - get: - tags: - - pet - summary: Finds Pets by tags - description: 'Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.' - operationId: findPetsByTags - produces: - - application/xml - - application/json - parameters: - - name: tags - in: query - description: Tags to filter by - required: true - type: array - items: - type: string - collectionFormat: csv - responses: - '200': - description: successful operation - schema: - type: array - items: - $ref: '#/definitions/Pet' - '400': - description: Invalid tag value - security: - - petstore_auth: - - 'write:pets' - - 'read:pets' - deprecated: true - '/pet/{petId}': - get: - tags: - - pet - summary: Find pet by ID - description: Returns a single pet - operationId: getPetById - produces: - - application/xml - - application/json - parameters: - - name: petId - in: path - description: ID of pet to return - required: true - type: integer - format: int64 - responses: - '200': - description: successful operation - schema: - $ref: '#/definitions/Pet' - '400': - description: Invalid ID supplied - '404': - description: Pet not found - security: - - api_key: [] - - basicAuth: [] - post: - tags: - - pet - summary: Updates a pet in the store with form data - description: '' - operationId: updatePetWithForm - consumes: - - application/x-www-form-urlencoded - produces: - - application/xml - - application/json - parameters: - - name: petId - in: path - description: ID of pet that needs to be updated - required: true - type: integer - format: int64 - - name: name - in: formData - description: Updated name of the pet - required: false - type: string - - name: status - in: formData - description: Updated status of the pet - required: false - type: string - responses: - '405': - description: Invalid input - security: - - petstore_auth: - - 'write:pets' - - 'read:pets' - delete: - tags: - - pet - summary: Deletes a pet - description: '' - operationId: deletePet - produces: - - application/xml - - application/json - parameters: - - name: api_key - in: header - required: false - type: string - - name: petId - in: path - description: Pet id to delete - required: true - type: integer - format: int64 - responses: - '400': - description: Invalid pet value - security: - - petstore_auth: - - 'write:pets' - - 'read:pets' - '/pet/{petId}/uploadImage': - post: - tags: - - pet - summary: uploads an image - description: '' - operationId: uploadFile - consumes: - - multipart/form-data - produces: - - application/json - parameters: - - name: petId - in: path - description: ID of pet to update - required: true - type: integer - format: int64 - - name: additionalMetadata - in: formData - description: Additional data to pass to server - required: false - type: string - - name: file - in: formData - description: file to upload - required: false - type: file - responses: - '200': - description: successful operation - schema: - $ref: '#/definitions/ApiResponse' - security: - - petstore_auth: - - 'write:pets' - - 'read:pets' - /store/inventory: - get: - tags: - - store - summary: Returns pet inventories by status - description: Returns a map of status codes to quantities - operationId: getInventory - produces: - - application/json - parameters: [] - responses: - '200': - description: successful operation - schema: - type: object - additionalProperties: - type: integer - format: int32 - security: - - api_key: [] - /store/order: - post: - tags: - - store - summary: Place an order for a pet - description: '' - operationId: placeOrder - produces: - - application/xml - - application/json - parameters: - - in: body - name: body - description: order placed for purchasing the pet - required: true - schema: - $ref: '#/definitions/Order' - responses: - '200': - description: successful operation - schema: - $ref: '#/definitions/Order' - '400': - description: Invalid Order - '/store/order/{order_id}': - get: - tags: - - store - summary: Find purchase order by ID - description: 'For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions' - operationId: getOrderById - produces: - - application/xml - - application/json - parameters: - - name: order_id - in: path - description: ID of pet that needs to be fetched - required: true - type: integer - maximum: 5 - minimum: 1 - format: int64 - responses: - '200': - description: successful operation - schema: - $ref: '#/definitions/Order' - '400': - description: Invalid ID supplied - '404': - description: Order not found - delete: - tags: - - store - summary: Delete purchase order by ID - description: For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors - operationId: deleteOrder - produces: - - application/xml - - application/json - parameters: - - name: order_id - in: path - description: ID of the order that needs to be deleted - required: true - type: string - responses: - '400': - description: Invalid ID supplied - '404': - description: Order not found - /user: - post: - tags: - - user - summary: Create user - description: This can only be done by the logged in user. - operationId: createUser - produces: - - application/xml - - application/json - parameters: - - in: body - name: body - description: Created user object - required: true - schema: - $ref: '#/definitions/User' - responses: - default: - description: successful operation - /user/createWithArray: - post: - tags: - - user - summary: Creates list of users with given input array - description: '' - operationId: createUsersWithArrayInput - produces: - - application/xml - - application/json - parameters: - - in: body - name: body - description: List of user object - required: true - schema: - type: array - items: - $ref: '#/definitions/User' - responses: - default: - description: successful operation - /user/createWithList: - post: - tags: - - user - summary: Creates list of users with given input array - description: '' - operationId: createUsersWithListInput - produces: - - application/xml - - application/json - parameters: - - in: body - name: body - description: List of user object - required: true - schema: - type: array - items: - $ref: '#/definitions/User' - responses: - default: - description: successful operation - /user/login: - get: - tags: - - user - summary: Logs user into the system - description: '' - operationId: loginUser - produces: - - application/xml - - application/json - parameters: - - name: username - in: query - description: The user name for login - required: true - type: string - - name: password - in: query - description: The password for login in clear text - required: true - type: string - responses: - '200': - description: successful operation - schema: - type: string - headers: - X-Rate-Limit: - type: integer - format: int32 - description: calls per hour allowed by the user - X-Expires-After: - type: string - format: date-time - description: date in UTC when toekn expires - '400': - description: Invalid username/password supplied - /user/logout: - get: - tags: - - user - summary: Logs out current logged in user session - description: '' - operationId: logoutUser - produces: - - application/xml - - application/json - parameters: [] - responses: - default: - description: successful operation - '/user/{username}': - get: - tags: - - user - summary: Get user by user name - description: '' - operationId: getUserByName - produces: - - application/xml - - application/json - parameters: - - name: username - in: path - description: 'The name that needs to be fetched. Use user1 for testing.' - required: true - type: string - responses: - '200': - description: successful operation - schema: - $ref: '#/definitions/User' - '400': - description: Invalid username supplied - '404': - description: User not found - put: - tags: - - user - summary: Updated user - description: This can only be done by the logged in user. - operationId: updateUser - produces: - - application/xml - - application/json - parameters: - - name: username - in: path - description: name that need to be deleted - required: true - type: string - - in: body - name: body - description: Updated user object - required: true - schema: - $ref: '#/definitions/User' - responses: - '400': - description: Invalid user supplied - '404': - description: User not found - delete: - tags: - - user - summary: Delete user - description: This can only be done by the logged in user. - operationId: deleteUser - produces: - - application/xml - - application/json - parameters: - - name: username - in: path - description: The name that needs to be deleted - required: true - type: string - responses: - '400': - description: Invalid username supplied - '404': - description: User not found -securityDefinitions: - petstore_auth: - type: oauth2 - authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog' - flow: implicit - scopes: - 'write:pets': modify pets in your account - 'read:pets': read your pets - api_key: - type: apiKey - name: api_key - in: header - basicAuth: - type: basic -definitions: - Order: - title: Pet Order - description: An order for a pets from the pet store - type: object - properties: - id: - type: integer - format: int64 - petId: - type: integer - format: int64 - quantity: - type: integer - format: int32 - shipDate: - type: string - format: date-time - status: - type: string - description: Order Status - enum: - - placed - - approved - - delivered - complete: - type: boolean - default: false - xml: - name: Order - Category: - title: Pet category - description: A category for a pet - type: object - properties: - id: - type: integer - format: int64 - name: - type: string - xml: - name: Category - User: - title: a User - description: A User who is purchasing from the pet store - type: object - properties: - id: - type: integer - format: int64 - username: - type: string - firstName: - type: string - lastName: - type: string - email: - type: string - password: - type: string - phone: - type: string - userStatus: - type: integer - format: int32 - description: User Status - xml: - name: User - Tag: - title: Pet Tag - description: A tag for a pet - type: object - properties: - id: - type: integer - format: int64 - name: - type: string - xml: - name: Tag - Pet: - title: a Pet - description: A pet for sale in the pet store - type: object - required: - - name - - photoUrls - properties: - id: - type: integer - format: int64 - category: - $ref: '#/definitions/Category' - name: - type: string - example: doggie - photoUrls: - type: array - xml: - name: photoUrl - wrapped: true - items: - type: string - tags: - type: array - xml: - name: tag - wrapped: true - items: - $ref: '#/definitions/Tag' - status: - type: string - description: pet status in the store - enum: - - available - - pending - - sold - xml: - name: Pet - ApiResponse: - title: An uploaded response - description: Describes the result of uploading an image resource - type: object - properties: - code: - type: integer - format: int32 - type: - type: string - message: - type: string diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/apis/petstore_reservedWords.yaml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/apis/petstore_reservedWords.yaml deleted file mode 100644 index 7175b75f0e..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/apis/petstore_reservedWords.yaml +++ /dev/null @@ -1,120 +0,0 @@ -swagger: '2.0' -info: - description: 'This is a modified Petstore server, that uses the reserved word "name" as parameter name. This should be renamed to "_name" in the generated code.' - version: 1.0.0 - title: OpenAPI Petstore - license: - name: Apache-2.0 - url: 'https://www.apache.org/licenses/LICENSE-2.0.html' -host: petstore.swagger.io -basePath: /v2 -tags: - - name: pet - description: Everything about your Pets -schemes: - - http -paths: - /pet/findByName: - get: - tags: - - pet - summary: Finds Pet by name - description: Name can be any text - operationId: findPetByName - produces: - - application/xml - - application/json - parameters: - # name is a reserved word and should be masked with an '_' in the generated api - - name: name - in: query - description: Name of the pet - required: true - type: string - responses: - '200': - description: successful operation - schema: - $ref: '#/definitions/Pet' - '400': - description: Invalid name value - security: - - petstore_auth: - - 'write:pets' - - 'read:pets' -securityDefinitions: - petstore_auth: - type: oauth2 - authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog' - flow: implicit - scopes: - 'write:pets': modify pets in your account - 'read:pets': read your pets - api_key: - type: apiKey - name: api_key - in: header -definitions: - Category: - title: Pet category - description: A category for a pet - type: object - properties: - id: - type: integer - format: int64 - name: - type: string - xml: - name: Category - Tag: - title: Pet Tag - description: A tag for a pet - type: object - properties: - id: - type: integer - format: int64 - name: - type: string - xml: - name: Tag - Pet: - title: a Pet - description: A pet for sale in the pet store - type: object - required: - - name - - photoUrls - properties: - id: - type: integer - format: int64 - category: - $ref: '#/definitions/Category' - name: - type: string - example: doggie - photoUrls: - type: array - xml: - name: photoUrl - wrapped: true - items: - type: string - tags: - type: array - xml: - name: tag - wrapped: true - items: - $ref: '#/definitions/Tag' - status: - type: string - description: pet status in the store - enum: - - available - - pending - - sold - xml: - name: Pet diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/ExtPetStore.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/ExtPetStore.java new file mode 100644 index 0000000000..b3ffdcb025 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/ExtPetStore.java @@ -0,0 +1,11 @@ +package org.citrusframework.openapi.generator.rest.extpetstore; + +import java.net.URL; + +public class ExtPetStore { + + public static URL extPetStoreApi() { + return ExtPetStore.class.getResource("ExtPetStore_openApi.yaml"); + } + +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/model/Category.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/model/Category.java new file mode 100644 index 0000000000..7f57903b45 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/model/Category.java @@ -0,0 +1,119 @@ +/* +* Copyright the original author or authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.citrusframework.openapi.generator.rest.extpetstore.model; + +import java.util.Objects; +import java.util.Arrays; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + * Category + */ +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:46.194751400+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +public class Category { + private Long id; + + private String _name; + + public Category() { + } + + public Category id(Long id) { + + this.id = id; + return this; + } + + /** + * Get id + * @return id + **/ + @jakarta.annotation.Nullable + + public Long getId() { + return id; + } + + + public void setId(Long id) { + this.id = id; + } + + + public Category _name(String _name) { + + this._name = _name; + return this; + } + + /** + * Get _name + * @return _name + **/ + @jakarta.annotation.Nullable + + public String getName() { + return _name; + } + + + public void setName(String _name) { + this._name = _name; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Category category = (Category) o; + return Objects.equals(this.id, category.id) && + Objects.equals(this._name, category._name); + } + + @Override + public int hashCode() { + return Objects.hash(id, _name); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Category {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" _name: ").append(toIndentedString(_name)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/model/HistoricalData.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/model/HistoricalData.java new file mode 100644 index 0000000000..1763cfd8c5 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/model/HistoricalData.java @@ -0,0 +1,120 @@ +/* +* Copyright the original author or authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.citrusframework.openapi.generator.rest.extpetstore.model; + +import java.util.Objects; +import java.util.Arrays; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.time.LocalDate; + +/** + * Additional historical data for a vaccination report, not contained in internal storage. + */ +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:46.194751400+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +public class HistoricalData { + private LocalDate lastVaccinationDate; + + private Integer vaccinationCount; + + public HistoricalData() { + } + + public HistoricalData lastVaccinationDate(LocalDate lastVaccinationDate) { + + this.lastVaccinationDate = lastVaccinationDate; + return this; + } + + /** + * The date of the last vaccination. + * @return lastVaccinationDate + **/ + @jakarta.annotation.Nullable + + public LocalDate getLastVaccinationDate() { + return lastVaccinationDate; + } + + + public void setLastVaccinationDate(LocalDate lastVaccinationDate) { + this.lastVaccinationDate = lastVaccinationDate; + } + + + public HistoricalData vaccinationCount(Integer vaccinationCount) { + + this.vaccinationCount = vaccinationCount; + return this; + } + + /** + * The number of vaccinations the pet has received. + * @return vaccinationCount + **/ + @jakarta.annotation.Nullable + + public Integer getVaccinationCount() { + return vaccinationCount; + } + + + public void setVaccinationCount(Integer vaccinationCount) { + this.vaccinationCount = vaccinationCount; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + HistoricalData historicalData = (HistoricalData) o; + return Objects.equals(this.lastVaccinationDate, historicalData.lastVaccinationDate) && + Objects.equals(this.vaccinationCount, historicalData.vaccinationCount); + } + + @Override + public int hashCode() { + return Objects.hash(lastVaccinationDate, vaccinationCount); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class HistoricalData {\n"); + sb.append(" lastVaccinationDate: ").append(toIndentedString(lastVaccinationDate)).append("\n"); + sb.append(" vaccinationCount: ").append(toIndentedString(vaccinationCount)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/model/Pet.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/model/Pet.java new file mode 100644 index 0000000000..82b87e69b6 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/model/Pet.java @@ -0,0 +1,279 @@ +/* +* Copyright the original author or authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.citrusframework.openapi.generator.rest.extpetstore.model; + +import java.util.Objects; +import java.util.Arrays; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.citrusframework.openapi.generator.rest.extpetstore.model.Category; +import org.citrusframework.openapi.generator.rest.extpetstore.model.Tag; + +/** + * Pet + */ +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:46.194751400+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +public class Pet { + private Long id; + + private String _name; + + private Category category; + + private List photoUrls = new ArrayList<>(); + + private List tags = new ArrayList<>(); + + /** + * pet status in the store + */ + public enum StatusEnum { + AVAILABLE("available"), + + PENDING("pending"), + + SOLD("sold"); + + private String value; + + StatusEnum(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + public static StatusEnum fromValue(String value) { + for (StatusEnum b : StatusEnum.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } + } + + private StatusEnum status; + + public Pet() { + } + + public Pet id(Long id) { + + this.id = id; + return this; + } + + /** + * Get id + * @return id + **/ + @jakarta.annotation.Nullable + + public Long getId() { + return id; + } + + + public void setId(Long id) { + this.id = id; + } + + + public Pet _name(String _name) { + + this._name = _name; + return this; + } + + /** + * Get _name + * @return _name + **/ + @jakarta.annotation.Nonnull + + public String getName() { + return _name; + } + + + public void setName(String _name) { + this._name = _name; + } + + + public Pet category(Category category) { + + this.category = category; + return this; + } + + /** + * Get category + * @return category + **/ + @jakarta.annotation.Nullable + + public Category getCategory() { + return category; + } + + + public void setCategory(Category category) { + this.category = category; + } + + + public Pet photoUrls(List photoUrls) { + + this.photoUrls = photoUrls; + return this; + } + + public Pet addPhotoUrlsItem(String photoUrlsItem) { + if (this.photoUrls == null) { + this.photoUrls = new ArrayList<>(); + } + this.photoUrls.add(photoUrlsItem); + return this; + } + + /** + * Get photoUrls + * @return photoUrls + **/ + @jakarta.annotation.Nonnull + + public List getPhotoUrls() { + return photoUrls; + } + + + public void setPhotoUrls(List photoUrls) { + this.photoUrls = photoUrls; + } + + + public Pet tags(List tags) { + + this.tags = tags; + return this; + } + + public Pet addTagsItem(Tag tagsItem) { + if (this.tags == null) { + this.tags = new ArrayList<>(); + } + this.tags.add(tagsItem); + return this; + } + + /** + * Get tags + * @return tags + **/ + @jakarta.annotation.Nullable + + public List getTags() { + return tags; + } + + + public void setTags(List tags) { + this.tags = tags; + } + + + public Pet status(StatusEnum status) { + + this.status = status; + return this; + } + + /** + * pet status in the store + * @return status + **/ + @jakarta.annotation.Nullable + + public StatusEnum getStatus() { + return status; + } + + + public void setStatus(StatusEnum status) { + this.status = status; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Pet pet = (Pet) o; + return Objects.equals(this.id, pet.id) && + Objects.equals(this._name, pet._name) && + Objects.equals(this.category, pet.category) && + Objects.equals(this.photoUrls, pet.photoUrls) && + Objects.equals(this.tags, pet.tags) && + Objects.equals(this.status, pet.status); + } + + @Override + public int hashCode() { + return Objects.hash(id, _name, category, photoUrls, tags, status); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Pet {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" _name: ").append(toIndentedString(_name)).append("\n"); + sb.append(" category: ").append(toIndentedString(category)).append("\n"); + sb.append(" photoUrls: ").append(toIndentedString(photoUrls)).append("\n"); + sb.append(" tags: ").append(toIndentedString(tags)).append("\n"); + sb.append(" status: ").append(toIndentedString(status)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/model/Tag.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/model/Tag.java new file mode 100644 index 0000000000..59471e20ad --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/model/Tag.java @@ -0,0 +1,119 @@ +/* +* Copyright the original author or authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.citrusframework.openapi.generator.rest.extpetstore.model; + +import java.util.Objects; +import java.util.Arrays; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + * Tag + */ +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:46.194751400+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +public class Tag { + private Long id; + + private String _name; + + public Tag() { + } + + public Tag id(Long id) { + + this.id = id; + return this; + } + + /** + * Get id + * @return id + **/ + @jakarta.annotation.Nullable + + public Long getId() { + return id; + } + + + public void setId(Long id) { + this.id = id; + } + + + public Tag _name(String _name) { + + this._name = _name; + return this; + } + + /** + * Get _name + * @return _name + **/ + @jakarta.annotation.Nullable + + public String getName() { + return _name; + } + + + public void setName(String _name) { + this._name = _name; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Tag tag = (Tag) o; + return Objects.equals(this.id, tag.id) && + Objects.equals(this._name, tag._name); + } + + @Override + public int hashCode() { + return Objects.hash(id, _name); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Tag {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" _name: ").append(toIndentedString(_name)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/model/VaccinationDocumentResult.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/model/VaccinationDocumentResult.java new file mode 100644 index 0000000000..5713e91f12 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/model/VaccinationDocumentResult.java @@ -0,0 +1,93 @@ +/* +* Copyright the original author or authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.citrusframework.openapi.generator.rest.extpetstore.model; + +import java.util.Objects; +import java.util.Arrays; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + * VaccinationDocumentResult + */ +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:46.194751400+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +public class VaccinationDocumentResult { + private String documentId; + + public VaccinationDocumentResult() { + } + + public VaccinationDocumentResult documentId(String documentId) { + + this.documentId = documentId; + return this; + } + + /** + * The unique ID of the uploaded vaccination document. + * @return documentId + **/ + @jakarta.annotation.Nullable + + public String getDocumentId() { + return documentId; + } + + + public void setDocumentId(String documentId) { + this.documentId = documentId; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + VaccinationDocumentResult vaccinationDocumentResult = (VaccinationDocumentResult) o; + return Objects.equals(this.documentId, vaccinationDocumentResult.documentId); + } + + @Override + public int hashCode() { + return Objects.hash(documentId); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class VaccinationDocumentResult {\n"); + sb.append(" documentId: ").append(toIndentedString(documentId)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/request/ExtPetApi.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/request/ExtPetApi.java new file mode 100644 index 0000000000..e8fcfb646e --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/request/ExtPetApi.java @@ -0,0 +1,4081 @@ +package org.citrusframework.openapi.generator.rest.extpetstore.request; + +import static java.lang.String.format; +import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; +import static org.citrusframework.util.StringUtils.isEmpty; +import static org.citrusframework.util.StringUtils.isNotEmpty; + +import jakarta.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.net.URL; +import java.time.LocalDate; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; +import java.util.List; +import org.citrusframework.actions.ReceiveMessageAction; +import org.citrusframework.actions.SendMessageAction; +import org.citrusframework.endpoint.Endpoint; +import org.citrusframework.openapi.OpenApiSpecification; +import org.citrusframework.openapi.testapi.ApiActionBuilderCustomizer; +import org.citrusframework.openapi.testapi.ParameterStyle; +import org.citrusframework.openapi.testapi.RestApiSendMessageActionBuilder; +import org.citrusframework.openapi.testapi.RestApiReceiveMessageActionBuilder; +import org.citrusframework.openapi.testapi.TestApiUtils; +import org.citrusframework.spi.Resource; +import org.citrusframework.openapi.testapi.GeneratedApi; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; + +import org.citrusframework.openapi.generator.rest.extpetstore.ExtPetStore; +import org.citrusframework.openapi.generator.rest.extpetstore.model.*; + +@SuppressWarnings("unused") +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:46.194751400+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +public class ExtPetApi implements GeneratedApi +{ + + @Value("${" + "extpetstore.base64-encode-api-key:#{false}}") + private boolean base64EncodeApiKey; + + @Value("${" + "extpetstore.basic.username:#{null}}") + private String basicUsername; + + @Value("${" + "extpetstore.basic.password:#{null}}") + private String basicPassword; + + @Value("${" + "extpetstore.bearer.token:#{null}}") + private String basicAuthBearer; + + @Value("${" + "extpetstore.api-key-header:#{null}}") + private String defaultApiKeyHeader; + + @Value("${" + "extpetstore.api-key-cookie:#{null}}") + private String defaultApiKeyCookie; + + @Value("${" + "extpetstore.api-key-query:#{null}}") + private String defaultApiKeyQuery; + + private final List customizers; + + private final Endpoint endpoint; + + private final OpenApiSpecification openApiSpecification; + + public ExtPetApi(Endpoint endpoint) { + this(endpoint, emptyList()); + } + + public ExtPetApi(Endpoint endpoint, List customizers) { + this.endpoint = endpoint; + this.customizers = customizers; + + URL resource = ExtPetStore.class.getResource("ExtPetStore_openApi.yaml"); + if (resource == null) { + throw new IllegalStateException(format("Cannot find resource '%s'. This resource is typically created during API generation and should therefore be present. Check API generation.", "ExtPetStore_openApi.yaml")); + } + openApiSpecification = OpenApiSpecification.from(resource); + } + + public static ExtPetApi extPetApi(Endpoint endpoint) { + return new ExtPetApi(endpoint); + } + + @Override + public String getApiTitle() { + return "Extended Petstore API"; + } + + @Override + public String getApiVersion() { + return "1.0.0"; + } + + @Override + public String getApiPrefix() { + return "ExtPetStore"; + } + + @Override + public Map getApiInfoExtensions() { + return emptyMap(); + } + + @Override + public Endpoint getEndpoint() { + return endpoint; + } + + @Override + public List getCustomizers() { + return customizers; + } + + /** + * Builder with type safe required parameters. + */ + public GenerateVaccinationReportSendActionBuilder sendGenerateVaccinationReport(Resource template, Integer reqIntVal) { + return new GenerateVaccinationReportSendActionBuilder(this, openApiSpecification, template, reqIntVal); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GenerateVaccinationReportSendActionBuilder sendGenerateVaccinationReport$(String templateExpression, String reqIntValExpression ) { + return new GenerateVaccinationReportSendActionBuilder(openApiSpecification, this, templateExpression, reqIntValExpression); + } + + public GenerateVaccinationReportReceiveActionBuilder receiveGenerateVaccinationReport(@NotNull HttpStatus statusCode) { + return new GenerateVaccinationReportReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GenerateVaccinationReportReceiveActionBuilder receiveGenerateVaccinationReport(@NotNull String statusCode) { + return new GenerateVaccinationReportReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetByIdWithApiKeyAuthenticationSendActionBuilder sendGetPetByIdWithApiKeyAuthentication(Long petId, Boolean allDetails) { + GetPetByIdWithApiKeyAuthenticationSendActionBuilder builder = new GetPetByIdWithApiKeyAuthenticationSendActionBuilder(this, openApiSpecification, petId, allDetails); + builder.setBase64EncodeApiKey(base64EncodeApiKey); + return builder; + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetByIdWithApiKeyAuthenticationSendActionBuilder sendGetPetByIdWithApiKeyAuthentication$(String petIdExpression, String allDetailsExpression ) { + GetPetByIdWithApiKeyAuthenticationSendActionBuilder builder = new GetPetByIdWithApiKeyAuthenticationSendActionBuilder(openApiSpecification, this, petIdExpression, allDetailsExpression); + builder.setBase64EncodeApiKey(base64EncodeApiKey); + builder.setApiKeyQuery(defaultApiKeyQuery); + builder.setApiKeyHeader(defaultApiKeyHeader); + builder.setApiKeyCookie(defaultApiKeyCookie); + return builder; + } + + public GetPetByIdWithApiKeyAuthenticationReceiveActionBuilder receiveGetPetByIdWithApiKeyAuthentication(@NotNull HttpStatus statusCode) { + return new GetPetByIdWithApiKeyAuthenticationReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetByIdWithApiKeyAuthenticationReceiveActionBuilder receiveGetPetByIdWithApiKeyAuthentication(@NotNull String statusCode) { + return new GetPetByIdWithApiKeyAuthenticationReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetByIdWithBasicAuthenticationSendActionBuilder sendGetPetByIdWithBasicAuthentication(Long petId, Boolean allDetails) { + GetPetByIdWithBasicAuthenticationSendActionBuilder builder = new GetPetByIdWithBasicAuthenticationSendActionBuilder(this, openApiSpecification, petId, allDetails); + return builder; + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetByIdWithBasicAuthenticationSendActionBuilder sendGetPetByIdWithBasicAuthentication$(String petIdExpression, String allDetailsExpression ) { + GetPetByIdWithBasicAuthenticationSendActionBuilder builder = new GetPetByIdWithBasicAuthenticationSendActionBuilder(openApiSpecification, this, petIdExpression, allDetailsExpression); + builder.setBasicAuthUsername(basicUsername); + builder.setBasicAuthPassword(basicPassword); + return builder; + } + + public GetPetByIdWithBasicAuthenticationReceiveActionBuilder receiveGetPetByIdWithBasicAuthentication(@NotNull HttpStatus statusCode) { + return new GetPetByIdWithBasicAuthenticationReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetByIdWithBasicAuthenticationReceiveActionBuilder receiveGetPetByIdWithBasicAuthentication(@NotNull String statusCode) { + return new GetPetByIdWithBasicAuthenticationReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetByIdWithBearerAuthenticationSendActionBuilder sendGetPetByIdWithBearerAuthentication(Long petId, Boolean allDetails) { + GetPetByIdWithBearerAuthenticationSendActionBuilder builder = new GetPetByIdWithBearerAuthenticationSendActionBuilder(this, openApiSpecification, petId, allDetails); + return builder; + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetByIdWithBearerAuthenticationSendActionBuilder sendGetPetByIdWithBearerAuthentication$(String petIdExpression, String allDetailsExpression ) { + GetPetByIdWithBearerAuthenticationSendActionBuilder builder = new GetPetByIdWithBearerAuthenticationSendActionBuilder(openApiSpecification, this, petIdExpression, allDetailsExpression); + builder.setBasicAuthBearer(basicAuthBearer); + return builder; + } + + public GetPetByIdWithBearerAuthenticationReceiveActionBuilder receiveGetPetByIdWithBearerAuthentication(@NotNull HttpStatus statusCode) { + return new GetPetByIdWithBearerAuthenticationReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetByIdWithBearerAuthenticationReceiveActionBuilder receiveGetPetByIdWithBearerAuthentication(@NotNull String statusCode) { + return new GetPetByIdWithBearerAuthenticationReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithCookieSendActionBuilder sendGetPetWithCookie(Long petId, String sessionId) { + return new GetPetWithCookieSendActionBuilder(this, openApiSpecification, petId, sessionId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithCookieSendActionBuilder sendGetPetWithCookie$(String petIdExpression, String sessionIdExpression ) { + return new GetPetWithCookieSendActionBuilder(openApiSpecification, this, petIdExpression, sessionIdExpression); + } + + public GetPetWithCookieReceiveActionBuilder receiveGetPetWithCookie(@NotNull HttpStatus statusCode) { + return new GetPetWithCookieReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithCookieReceiveActionBuilder receiveGetPetWithCookie(@NotNull String statusCode) { + return new GetPetWithCookieReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithDeepObjectTypeQuerySendActionBuilder sendGetPetWithDeepObjectTypeQuery(PetIdentifier petId) { + return new GetPetWithDeepObjectTypeQuerySendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithDeepObjectTypeQuerySendActionBuilder sendGetPetWithDeepObjectTypeQuery$(String petIdExpression ) { + return new GetPetWithDeepObjectTypeQuerySendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithDeepObjectTypeQueryReceiveActionBuilder receiveGetPetWithDeepObjectTypeQuery(@NotNull HttpStatus statusCode) { + return new GetPetWithDeepObjectTypeQueryReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithDeepObjectTypeQueryReceiveActionBuilder receiveGetPetWithDeepObjectTypeQuery(@NotNull String statusCode) { + return new GetPetWithDeepObjectTypeQueryReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithFormExplodedStyleCookieSendActionBuilder sendGetPetWithFormExplodedStyleCookie(List petId) { + return new GetPetWithFormExplodedStyleCookieSendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormExplodedStyleCookieSendActionBuilder sendGetPetWithFormExplodedStyleCookie$(List petIdExpression ) { + return new GetPetWithFormExplodedStyleCookieSendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithFormExplodedStyleCookieReceiveActionBuilder receiveGetPetWithFormExplodedStyleCookie(@NotNull HttpStatus statusCode) { + return new GetPetWithFormExplodedStyleCookieReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithFormExplodedStyleCookieReceiveActionBuilder receiveGetPetWithFormExplodedStyleCookie(@NotNull String statusCode) { + return new GetPetWithFormExplodedStyleCookieReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithFormObjectStyleCookieSendActionBuilder sendGetPetWithFormObjectStyleCookie(PetIdentifier petId) { + return new GetPetWithFormObjectStyleCookieSendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormObjectStyleCookieSendActionBuilder sendGetPetWithFormObjectStyleCookie$(String petIdExpression ) { + return new GetPetWithFormObjectStyleCookieSendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithFormObjectStyleCookieReceiveActionBuilder receiveGetPetWithFormObjectStyleCookie(@NotNull HttpStatus statusCode) { + return new GetPetWithFormObjectStyleCookieReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithFormObjectStyleCookieReceiveActionBuilder receiveGetPetWithFormObjectStyleCookie(@NotNull String statusCode) { + return new GetPetWithFormObjectStyleCookieReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithFormStyleCookieSendActionBuilder sendGetPetWithFormStyleCookie(List petId) { + return new GetPetWithFormStyleCookieSendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormStyleCookieSendActionBuilder sendGetPetWithFormStyleCookie$(List petIdExpression ) { + return new GetPetWithFormStyleCookieSendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithFormStyleCookieReceiveActionBuilder receiveGetPetWithFormStyleCookie(@NotNull HttpStatus statusCode) { + return new GetPetWithFormStyleCookieReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithFormStyleCookieReceiveActionBuilder receiveGetPetWithFormStyleCookie(@NotNull String statusCode) { + return new GetPetWithFormStyleCookieReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithFormStyleExplodedObjectQuerySendActionBuilder sendGetPetWithFormStyleExplodedObjectQuery(PetIdentifier petId) { + return new GetPetWithFormStyleExplodedObjectQuerySendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormStyleExplodedObjectQuerySendActionBuilder sendGetPetWithFormStyleExplodedObjectQuery$(String petIdExpression ) { + return new GetPetWithFormStyleExplodedObjectQuerySendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithFormStyleExplodedObjectQueryReceiveActionBuilder receiveGetPetWithFormStyleExplodedObjectQuery(@NotNull HttpStatus statusCode) { + return new GetPetWithFormStyleExplodedObjectQueryReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithFormStyleExplodedObjectQueryReceiveActionBuilder receiveGetPetWithFormStyleExplodedObjectQuery(@NotNull String statusCode) { + return new GetPetWithFormStyleExplodedObjectQueryReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithFormStyleExplodedQuerySendActionBuilder sendGetPetWithFormStyleExplodedQuery(List petId) { + return new GetPetWithFormStyleExplodedQuerySendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormStyleExplodedQuerySendActionBuilder sendGetPetWithFormStyleExplodedQuery$(List petIdExpression ) { + return new GetPetWithFormStyleExplodedQuerySendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithFormStyleExplodedQueryReceiveActionBuilder receiveGetPetWithFormStyleExplodedQuery(@NotNull HttpStatus statusCode) { + return new GetPetWithFormStyleExplodedQueryReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithFormStyleExplodedQueryReceiveActionBuilder receiveGetPetWithFormStyleExplodedQuery(@NotNull String statusCode) { + return new GetPetWithFormStyleExplodedQueryReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithFormStyleObjectQuerySendActionBuilder sendGetPetWithFormStyleObjectQuery(PetIdentifier petId) { + return new GetPetWithFormStyleObjectQuerySendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormStyleObjectQuerySendActionBuilder sendGetPetWithFormStyleObjectQuery$(String petIdExpression ) { + return new GetPetWithFormStyleObjectQuerySendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithFormStyleObjectQueryReceiveActionBuilder receiveGetPetWithFormStyleObjectQuery(@NotNull HttpStatus statusCode) { + return new GetPetWithFormStyleObjectQueryReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithFormStyleObjectQueryReceiveActionBuilder receiveGetPetWithFormStyleObjectQuery(@NotNull String statusCode) { + return new GetPetWithFormStyleObjectQueryReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithFormStyleQuerySendActionBuilder sendGetPetWithFormStyleQuery(List petId) { + return new GetPetWithFormStyleQuerySendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormStyleQuerySendActionBuilder sendGetPetWithFormStyleQuery$(List petIdExpression ) { + return new GetPetWithFormStyleQuerySendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithFormStyleQueryReceiveActionBuilder receiveGetPetWithFormStyleQuery(@NotNull HttpStatus statusCode) { + return new GetPetWithFormStyleQueryReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithFormStyleQueryReceiveActionBuilder receiveGetPetWithFormStyleQuery(@NotNull String statusCode) { + return new GetPetWithFormStyleQueryReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithLabelStyleArraySendActionBuilder sendGetPetWithLabelStyleArray(List petId) { + return new GetPetWithLabelStyleArraySendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithLabelStyleArraySendActionBuilder sendGetPetWithLabelStyleArray$(List petIdExpression ) { + return new GetPetWithLabelStyleArraySendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithLabelStyleArrayReceiveActionBuilder receiveGetPetWithLabelStyleArray(@NotNull HttpStatus statusCode) { + return new GetPetWithLabelStyleArrayReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithLabelStyleArrayReceiveActionBuilder receiveGetPetWithLabelStyleArray(@NotNull String statusCode) { + return new GetPetWithLabelStyleArrayReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithLabelStyleArrayExplodedSendActionBuilder sendGetPetWithLabelStyleArrayExploded(List petId) { + return new GetPetWithLabelStyleArrayExplodedSendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithLabelStyleArrayExplodedSendActionBuilder sendGetPetWithLabelStyleArrayExploded$(List petIdExpression ) { + return new GetPetWithLabelStyleArrayExplodedSendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithLabelStyleArrayExplodedReceiveActionBuilder receiveGetPetWithLabelStyleArrayExploded(@NotNull HttpStatus statusCode) { + return new GetPetWithLabelStyleArrayExplodedReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithLabelStyleArrayExplodedReceiveActionBuilder receiveGetPetWithLabelStyleArrayExploded(@NotNull String statusCode) { + return new GetPetWithLabelStyleArrayExplodedReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithLabelStyleObjectSendActionBuilder sendGetPetWithLabelStyleObject(PetIdentifier petId) { + return new GetPetWithLabelStyleObjectSendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithLabelStyleObjectSendActionBuilder sendGetPetWithLabelStyleObject$(String petIdExpression ) { + return new GetPetWithLabelStyleObjectSendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithLabelStyleObjectReceiveActionBuilder receiveGetPetWithLabelStyleObject(@NotNull HttpStatus statusCode) { + return new GetPetWithLabelStyleObjectReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithLabelStyleObjectReceiveActionBuilder receiveGetPetWithLabelStyleObject(@NotNull String statusCode) { + return new GetPetWithLabelStyleObjectReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithLabelStyleObjectExplodedSendActionBuilder sendGetPetWithLabelStyleObjectExploded(PetIdentifier petId) { + return new GetPetWithLabelStyleObjectExplodedSendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithLabelStyleObjectExplodedSendActionBuilder sendGetPetWithLabelStyleObjectExploded$(String petIdExpression ) { + return new GetPetWithLabelStyleObjectExplodedSendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithLabelStyleObjectExplodedReceiveActionBuilder receiveGetPetWithLabelStyleObjectExploded(@NotNull HttpStatus statusCode) { + return new GetPetWithLabelStyleObjectExplodedReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithLabelStyleObjectExplodedReceiveActionBuilder receiveGetPetWithLabelStyleObjectExploded(@NotNull String statusCode) { + return new GetPetWithLabelStyleObjectExplodedReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithMatrixStyleArraySendActionBuilder sendGetPetWithMatrixStyleArray(List petId) { + return new GetPetWithMatrixStyleArraySendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithMatrixStyleArraySendActionBuilder sendGetPetWithMatrixStyleArray$(List petIdExpression ) { + return new GetPetWithMatrixStyleArraySendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithMatrixStyleArrayReceiveActionBuilder receiveGetPetWithMatrixStyleArray(@NotNull HttpStatus statusCode) { + return new GetPetWithMatrixStyleArrayReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithMatrixStyleArrayReceiveActionBuilder receiveGetPetWithMatrixStyleArray(@NotNull String statusCode) { + return new GetPetWithMatrixStyleArrayReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithMatrixStyleArrayExplodedSendActionBuilder sendGetPetWithMatrixStyleArrayExploded(List petId) { + return new GetPetWithMatrixStyleArrayExplodedSendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithMatrixStyleArrayExplodedSendActionBuilder sendGetPetWithMatrixStyleArrayExploded$(List petIdExpression ) { + return new GetPetWithMatrixStyleArrayExplodedSendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithMatrixStyleArrayExplodedReceiveActionBuilder receiveGetPetWithMatrixStyleArrayExploded(@NotNull HttpStatus statusCode) { + return new GetPetWithMatrixStyleArrayExplodedReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithMatrixStyleArrayExplodedReceiveActionBuilder receiveGetPetWithMatrixStyleArrayExploded(@NotNull String statusCode) { + return new GetPetWithMatrixStyleArrayExplodedReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithMatrixStyleObjectSendActionBuilder sendGetPetWithMatrixStyleObject(PetIdentifier petId) { + return new GetPetWithMatrixStyleObjectSendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithMatrixStyleObjectSendActionBuilder sendGetPetWithMatrixStyleObject$(String petIdExpression ) { + return new GetPetWithMatrixStyleObjectSendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithMatrixStyleObjectReceiveActionBuilder receiveGetPetWithMatrixStyleObject(@NotNull HttpStatus statusCode) { + return new GetPetWithMatrixStyleObjectReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithMatrixStyleObjectReceiveActionBuilder receiveGetPetWithMatrixStyleObject(@NotNull String statusCode) { + return new GetPetWithMatrixStyleObjectReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithMatrixStyleObjectExplodedSendActionBuilder sendGetPetWithMatrixStyleObjectExploded(PetIdentifier petId) { + return new GetPetWithMatrixStyleObjectExplodedSendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithMatrixStyleObjectExplodedSendActionBuilder sendGetPetWithMatrixStyleObjectExploded$(String petIdExpression ) { + return new GetPetWithMatrixStyleObjectExplodedSendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithMatrixStyleObjectExplodedReceiveActionBuilder receiveGetPetWithMatrixStyleObjectExploded(@NotNull HttpStatus statusCode) { + return new GetPetWithMatrixStyleObjectExplodedReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithMatrixStyleObjectExplodedReceiveActionBuilder receiveGetPetWithMatrixStyleObjectExploded(@NotNull String statusCode) { + return new GetPetWithMatrixStyleObjectExplodedReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithSimpleStyleArraySendActionBuilder sendGetPetWithSimpleStyleArray(List petId) { + return new GetPetWithSimpleStyleArraySendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleArraySendActionBuilder sendGetPetWithSimpleStyleArray$(List petIdExpression ) { + return new GetPetWithSimpleStyleArraySendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithSimpleStyleArrayReceiveActionBuilder receiveGetPetWithSimpleStyleArray(@NotNull HttpStatus statusCode) { + return new GetPetWithSimpleStyleArrayReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithSimpleStyleArrayReceiveActionBuilder receiveGetPetWithSimpleStyleArray(@NotNull String statusCode) { + return new GetPetWithSimpleStyleArrayReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithSimpleStyleArrayExplodedSendActionBuilder sendGetPetWithSimpleStyleArrayExploded(List petId) { + return new GetPetWithSimpleStyleArrayExplodedSendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleArrayExplodedSendActionBuilder sendGetPetWithSimpleStyleArrayExploded$(List petIdExpression ) { + return new GetPetWithSimpleStyleArrayExplodedSendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithSimpleStyleArrayExplodedReceiveActionBuilder receiveGetPetWithSimpleStyleArrayExploded(@NotNull HttpStatus statusCode) { + return new GetPetWithSimpleStyleArrayExplodedReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithSimpleStyleArrayExplodedReceiveActionBuilder receiveGetPetWithSimpleStyleArrayExploded(@NotNull String statusCode) { + return new GetPetWithSimpleStyleArrayExplodedReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithSimpleStyleExplodedHeaderSendActionBuilder sendGetPetWithSimpleStyleExplodedHeader(List petId) { + return new GetPetWithSimpleStyleExplodedHeaderSendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleExplodedHeaderSendActionBuilder sendGetPetWithSimpleStyleExplodedHeader$(List petIdExpression ) { + return new GetPetWithSimpleStyleExplodedHeaderSendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithSimpleStyleExplodedHeaderReceiveActionBuilder receiveGetPetWithSimpleStyleExplodedHeader(@NotNull HttpStatus statusCode) { + return new GetPetWithSimpleStyleExplodedHeaderReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithSimpleStyleExplodedHeaderReceiveActionBuilder receiveGetPetWithSimpleStyleExplodedHeader(@NotNull String statusCode) { + return new GetPetWithSimpleStyleExplodedHeaderReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithSimpleStyleExplodedObjectHeaderSendActionBuilder sendGetPetWithSimpleStyleExplodedObjectHeader(PetIdentifier petId) { + return new GetPetWithSimpleStyleExplodedObjectHeaderSendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleExplodedObjectHeaderSendActionBuilder sendGetPetWithSimpleStyleExplodedObjectHeader$(String petIdExpression ) { + return new GetPetWithSimpleStyleExplodedObjectHeaderSendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithSimpleStyleExplodedObjectHeaderReceiveActionBuilder receiveGetPetWithSimpleStyleExplodedObjectHeader(@NotNull HttpStatus statusCode) { + return new GetPetWithSimpleStyleExplodedObjectHeaderReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithSimpleStyleExplodedObjectHeaderReceiveActionBuilder receiveGetPetWithSimpleStyleExplodedObjectHeader(@NotNull String statusCode) { + return new GetPetWithSimpleStyleExplodedObjectHeaderReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithSimpleStyleHeaderSendActionBuilder sendGetPetWithSimpleStyleHeader(List petId) { + return new GetPetWithSimpleStyleHeaderSendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleHeaderSendActionBuilder sendGetPetWithSimpleStyleHeader$(List petIdExpression ) { + return new GetPetWithSimpleStyleHeaderSendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithSimpleStyleHeaderReceiveActionBuilder receiveGetPetWithSimpleStyleHeader(@NotNull HttpStatus statusCode) { + return new GetPetWithSimpleStyleHeaderReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithSimpleStyleHeaderReceiveActionBuilder receiveGetPetWithSimpleStyleHeader(@NotNull String statusCode) { + return new GetPetWithSimpleStyleHeaderReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithSimpleStyleObjectSendActionBuilder sendGetPetWithSimpleStyleObject(PetIdentifier petId) { + return new GetPetWithSimpleStyleObjectSendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleObjectSendActionBuilder sendGetPetWithSimpleStyleObject$(String petIdExpression ) { + return new GetPetWithSimpleStyleObjectSendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithSimpleStyleObjectReceiveActionBuilder receiveGetPetWithSimpleStyleObject(@NotNull HttpStatus statusCode) { + return new GetPetWithSimpleStyleObjectReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithSimpleStyleObjectReceiveActionBuilder receiveGetPetWithSimpleStyleObject(@NotNull String statusCode) { + return new GetPetWithSimpleStyleObjectReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithSimpleStyleObjectExplodedSendActionBuilder sendGetPetWithSimpleStyleObjectExploded(PetIdentifier petId) { + return new GetPetWithSimpleStyleObjectExplodedSendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleObjectExplodedSendActionBuilder sendGetPetWithSimpleStyleObjectExploded$(String petIdExpression ) { + return new GetPetWithSimpleStyleObjectExplodedSendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithSimpleStyleObjectExplodedReceiveActionBuilder receiveGetPetWithSimpleStyleObjectExploded(@NotNull HttpStatus statusCode) { + return new GetPetWithSimpleStyleObjectExplodedReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithSimpleStyleObjectExplodedReceiveActionBuilder receiveGetPetWithSimpleStyleObjectExploded(@NotNull String statusCode) { + return new GetPetWithSimpleStyleObjectExplodedReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetWithSimpleStyleObjectHeaderSendActionBuilder sendGetPetWithSimpleStyleObjectHeader(PetIdentifier petId) { + return new GetPetWithSimpleStyleObjectHeaderSendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleObjectHeaderSendActionBuilder sendGetPetWithSimpleStyleObjectHeader$(String petIdExpression ) { + return new GetPetWithSimpleStyleObjectHeaderSendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public GetPetWithSimpleStyleObjectHeaderReceiveActionBuilder receiveGetPetWithSimpleStyleObjectHeader(@NotNull HttpStatus statusCode) { + return new GetPetWithSimpleStyleObjectHeaderReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetWithSimpleStyleObjectHeaderReceiveActionBuilder receiveGetPetWithSimpleStyleObjectHeader(@NotNull String statusCode) { + return new GetPetWithSimpleStyleObjectHeaderReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public PostVaccinationDocumentSendActionBuilder sendPostVaccinationDocument(String bucket, String filename) { + return new PostVaccinationDocumentSendActionBuilder(this, openApiSpecification, bucket, filename); + } + + public PostVaccinationDocumentReceiveActionBuilder receivePostVaccinationDocument(@NotNull HttpStatus statusCode) { + return new PostVaccinationDocumentReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public PostVaccinationDocumentReceiveActionBuilder receivePostVaccinationDocument(@NotNull String statusCode) { + return new PostVaccinationDocumentReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public PostVaccinationFormDataSendActionBuilder sendPostVaccinationFormData() { + return new PostVaccinationFormDataSendActionBuilder(this, openApiSpecification); + } + + public PostVaccinationFormDataReceiveActionBuilder receivePostVaccinationFormData(@NotNull HttpStatus statusCode) { + return new PostVaccinationFormDataReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public PostVaccinationFormDataReceiveActionBuilder receivePostVaccinationFormData(@NotNull String statusCode) { + return new PostVaccinationFormDataReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public UpdatePetWithArrayQueryDataSendActionBuilder sendUpdatePetWithArrayQueryData(Long petId, String _name, String status, List tags, List nicknames, String sampleStringHeader) { + return new UpdatePetWithArrayQueryDataSendActionBuilder(this, openApiSpecification, petId, _name, status, tags, nicknames, sampleStringHeader); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public UpdatePetWithArrayQueryDataSendActionBuilder sendUpdatePetWithArrayQueryData$(String petIdExpression, String _nameExpression, String statusExpression, List tagsExpression, List nicknamesExpression, String sampleStringHeaderExpression ) { + return new UpdatePetWithArrayQueryDataSendActionBuilder(openApiSpecification, this, petIdExpression, _nameExpression, statusExpression, tagsExpression, nicknamesExpression, sampleStringHeaderExpression); + } + + public UpdatePetWithArrayQueryDataReceiveActionBuilder receiveUpdatePetWithArrayQueryData(@NotNull HttpStatus statusCode) { + return new UpdatePetWithArrayQueryDataReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public UpdatePetWithArrayQueryDataReceiveActionBuilder receiveUpdatePetWithArrayQueryData(@NotNull String statusCode) { + return new UpdatePetWithArrayQueryDataReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public UpdatePetWithFormUrlEncodedSendActionBuilder sendUpdatePetWithFormUrlEncoded(Long petId, String _name, String status, Integer age, List tags) { + return new UpdatePetWithFormUrlEncodedSendActionBuilder(this, openApiSpecification, petId, _name, status, age, tags); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public UpdatePetWithFormUrlEncodedSendActionBuilder sendUpdatePetWithFormUrlEncoded$(String petIdExpression, String _nameExpression, String statusExpression, String ageExpression, List tagsExpression ) { + return new UpdatePetWithFormUrlEncodedSendActionBuilder(openApiSpecification, this, petIdExpression, _nameExpression, statusExpression, ageExpression, tagsExpression); + } + + public UpdatePetWithFormUrlEncodedReceiveActionBuilder receiveUpdatePetWithFormUrlEncoded(@NotNull HttpStatus statusCode) { + return new UpdatePetWithFormUrlEncodedReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public UpdatePetWithFormUrlEncodedReceiveActionBuilder receiveUpdatePetWithFormUrlEncoded(@NotNull String statusCode) { + return new UpdatePetWithFormUrlEncodedReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + public static class GenerateVaccinationReportSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "POST"; + + private static final String ENDPOINT = "/api/v3/ext/pet/vaccination/status-report"; + + private static final String OPERATION_NAME = "generateVaccinationReport"; + + /** + * Constructor with type safe required parameters. + */ + public GenerateVaccinationReportSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, Resource template, Integer reqIntVal) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + formParameter("template", toBinary(template) ); + formParameter("reqIntVal", reqIntVal); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GenerateVaccinationReportSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, String templateExpression, String reqIntValExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + formParameter("template", toBinary(templateExpression) ); + formParameter("reqIntVal", reqIntValExpression); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GenerateVaccinationReportSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String templateExpression, String reqIntValExpression) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + formParameter("template", toBinary(templateExpression) ); + formParameter("reqIntVal", reqIntValExpression); + } + + public GenerateVaccinationReportSendActionBuilder template(Resource template) { + formParameter("template", toBinary(template) ); + return this; + } + + public GenerateVaccinationReportSendActionBuilder template(String templateExpression) { + formParameter("template", toBinary(templateExpression) ); + return this; + } + + public GenerateVaccinationReportSendActionBuilder reqIntVal(Integer reqIntVal) { + formParameter("reqIntVal", reqIntVal); + return this; + } + + public GenerateVaccinationReportSendActionBuilder reqIntVal(String reqIntValExpression) { + formParameter("reqIntVal", reqIntValExpression); + return this; + } + + public GenerateVaccinationReportSendActionBuilder optIntVal(Integer optIntVal) { + formParameter("optIntVal", optIntVal); + return this; + } + + public void setOptIntVal(Integer optIntVal) { + formParameter("optIntVal", optIntVal); + } + + public GenerateVaccinationReportSendActionBuilder optIntVal(String optIntValExpression) { + formParameter("optIntVal", optIntValExpression); + return this; + } + + public void setOptIntVal(String optIntValExpression) { + formParameter("optIntVal", optIntValExpression); + } + + public GenerateVaccinationReportSendActionBuilder optBoolVal(Boolean optBoolVal) { + formParameter("optBoolVal", optBoolVal); + return this; + } + + public void setOptBoolVal(Boolean optBoolVal) { + formParameter("optBoolVal", optBoolVal); + } + + public GenerateVaccinationReportSendActionBuilder optBoolVal(String optBoolValExpression) { + formParameter("optBoolVal", optBoolValExpression); + return this; + } + + public void setOptBoolVal(String optBoolValExpression) { + formParameter("optBoolVal", optBoolValExpression); + } + + public GenerateVaccinationReportSendActionBuilder optNumberVal(BigDecimal optNumberVal) { + formParameter("optNumberVal", optNumberVal); + return this; + } + + public void setOptNumberVal(BigDecimal optNumberVal) { + formParameter("optNumberVal", optNumberVal); + } + + public GenerateVaccinationReportSendActionBuilder optNumberVal(String optNumberValExpression) { + formParameter("optNumberVal", optNumberValExpression); + return this; + } + + public void setOptNumberVal(String optNumberValExpression) { + formParameter("optNumberVal", optNumberValExpression); + } + + public GenerateVaccinationReportSendActionBuilder optStringVal(String optStringVal) { + formParameter("optStringVal", optStringVal); + return this; + } + + public void setOptStringVal(String optStringVal) { + formParameter("optStringVal", optStringVal); + } + + public GenerateVaccinationReportSendActionBuilder optDateVal(LocalDate optDateVal) { + formParameter("optDateVal", optDateVal); + return this; + } + + public void setOptDateVal(LocalDate optDateVal) { + formParameter("optDateVal", optDateVal); + } + + public GenerateVaccinationReportSendActionBuilder optDateVal(String optDateValExpression) { + formParameter("optDateVal", optDateValExpression); + return this; + } + + public void setOptDateVal(String optDateValExpression) { + formParameter("optDateVal", optDateValExpression); + } + + public GenerateVaccinationReportSendActionBuilder additionalData(HistoricalData additionalData) { + formParameter("additionalData", additionalData); + return this; + } + + public void setAdditionalData(HistoricalData additionalData) { + formParameter("additionalData", additionalData); + } + + public GenerateVaccinationReportSendActionBuilder additionalData(String additionalDataExpression) { + formParameter("additionalData", additionalDataExpression); + return this; + } + + public void setAdditionalData(String additionalDataExpression) { + formParameter("additionalData", additionalDataExpression); + } + + public GenerateVaccinationReportSendActionBuilder schema(Resource schema) { + formParameter("schema", toBinary(schema) ); + return this; + } + + public void setSchema(Resource schema) { + formParameter("schema", toBinary(schema) ); + } + + public GenerateVaccinationReportSendActionBuilder schema(String schemaExpression) { + formParameter("schema", toBinary(schemaExpression) ); + return this; + } + + public void setSchema(String schemaExpression) { + formParameter("schema", toBinary(schemaExpression) ); + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GenerateVaccinationReportReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "POST"; + + private static final String ENDPOINT = "/api/v3/ext/pet/vaccination/status-report"; + + private static final String OPERATION_NAME = "generateVaccinationReport"; + + public GenerateVaccinationReportReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GenerateVaccinationReportReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetByIdWithApiKeyAuthenticationSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/secure-api-key/pet/{petId}"; + + private static final String OPERATION_NAME = "getPetByIdWithApiKeyAuthentication"; + + @Value("${" + "extpetstore.base64-encode-api-key:#{false}}") + private boolean base64EncodeApiKey; + + @Value("${" + "extpetstore.api-key-query:#{null}}") + private String defaultApiKeyQuery; + + private String apiKeyQuery; + + @Value("${" + "extpetstore.api-key-header:#{null}}") + private String defaultApiKeyHeader; + + private String apiKeyHeader; + + @Value("${" + "extpetstore.api-key-cookie:#{null}}") + private String defaultApiKeyCookie; + + private String apiKeyCookie; + + /** + * Constructor with type safe required parameters. + */ + public GetPetByIdWithApiKeyAuthenticationSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, Long petId, Boolean allDetails) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + queryParameter("allDetails", allDetails, ParameterStyle.FORM, true, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetByIdWithApiKeyAuthenticationSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, String petIdExpression, String allDetailsExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + queryParameter("allDetails", allDetailsExpression, ParameterStyle.FORM, true, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetByIdWithApiKeyAuthenticationSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression, String allDetailsExpression) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + queryParameter("allDetails", allDetailsExpression, ParameterStyle.FORM, true, false); + } + + public GetPetByIdWithApiKeyAuthenticationSendActionBuilder petId(Long petId) { + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + return this; + } + + public GetPetByIdWithApiKeyAuthenticationSendActionBuilder petId(String petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + return this; + } + + public GetPetByIdWithApiKeyAuthenticationSendActionBuilder allDetails(Boolean allDetails) { + queryParameter("allDetails", allDetails, ParameterStyle.FORM, true, false); + return this; + } + + public GetPetByIdWithApiKeyAuthenticationSendActionBuilder allDetails(String allDetailsExpression) { + queryParameter("allDetails", allDetailsExpression, ParameterStyle.FORM, true, false); + return this; + } + + public GetPetByIdWithApiKeyAuthenticationSendActionBuilder details(String...details) { + queryParameter("details", details, ParameterStyle.FORM, true, false); + return this; + } + + public void setDetails(String...details) { + queryParameter("details", details, ParameterStyle.FORM, true, false); + } + + public GetPetByIdWithApiKeyAuthenticationSendActionBuilder requesterInformation(String...requesterInformation) { + queryParameter("requesterInformation", requesterInformation, ParameterStyle.FORM, true, false); + return this; + } + + public void setRequesterInformation(String...requesterInformation) { + queryParameter("requesterInformation", requesterInformation, ParameterStyle.FORM, true, false); + } + + public void setBase64EncodeApiKey(boolean encode) { + this.base64EncodeApiKey = encode; + } + + public GetPetByIdWithApiKeyAuthenticationSendActionBuilder apiKeyQuery(String apiKeyQuery) { + this.apiKeyQuery = apiKeyQuery; + return this; + } + + public void setApiKeyQuery(String apiKeyQuery) { + this.apiKeyQuery = apiKeyQuery; + } + + public GetPetByIdWithApiKeyAuthenticationSendActionBuilder apiKeyHeader(String apiKeyHeader) { + this.apiKeyHeader = apiKeyHeader; + return this; + } + + public void setApiKeyHeader(String apiKeyHeader) { + this.apiKeyHeader = apiKeyHeader; + } + + public GetPetByIdWithApiKeyAuthenticationSendActionBuilder apiKeyCookie(String apiKeyCookie) { + this.apiKeyCookie = apiKeyCookie; + return this; + } + + public void setApiKeyCookie(String apiKeyCookie) { + this.apiKeyCookie = apiKeyCookie; + } + + @Override + public SendMessageAction doBuild() { + queryParameter("api_key_query", getOrDefault(apiKeyQuery, defaultApiKeyQuery, base64EncodeApiKey)); + headerParameter("api_key_header", getOrDefault(apiKeyHeader, defaultApiKeyHeader, base64EncodeApiKey)); + cookieParameter("api_key_cookie", getOrDefault(apiKeyCookie, defaultApiKeyCookie, base64EncodeApiKey)); + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetByIdWithApiKeyAuthenticationReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/secure-api-key/pet/{petId}"; + + private static final String OPERATION_NAME = "getPetByIdWithApiKeyAuthentication"; + + public GetPetByIdWithApiKeyAuthenticationReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetByIdWithApiKeyAuthenticationReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetByIdWithBasicAuthenticationSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/secure-basic/pet/{petId}"; + + private static final String OPERATION_NAME = "getPetByIdWithBasicAuthentication"; + + @Value("${" + "extpetstore.basic.username:#{null}}") + private String defaultBasicUsername; + + private String basicUsername; + + @Value("${" + "extpetstore.basic.password:#{null}}") + private String defaultBasicPassword; + + private String basicPassword; + + /** + * Constructor with type safe required parameters. + */ + public GetPetByIdWithBasicAuthenticationSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, Long petId, Boolean allDetails) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + queryParameter("allDetails", allDetails, ParameterStyle.FORM, true, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetByIdWithBasicAuthenticationSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, String petIdExpression, String allDetailsExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + queryParameter("allDetails", allDetailsExpression, ParameterStyle.FORM, true, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetByIdWithBasicAuthenticationSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression, String allDetailsExpression) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + queryParameter("allDetails", allDetailsExpression, ParameterStyle.FORM, true, false); + } + + public GetPetByIdWithBasicAuthenticationSendActionBuilder petId(Long petId) { + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + return this; + } + + public GetPetByIdWithBasicAuthenticationSendActionBuilder petId(String petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + return this; + } + + public GetPetByIdWithBasicAuthenticationSendActionBuilder allDetails(Boolean allDetails) { + queryParameter("allDetails", allDetails, ParameterStyle.FORM, true, false); + return this; + } + + public GetPetByIdWithBasicAuthenticationSendActionBuilder allDetails(String allDetailsExpression) { + queryParameter("allDetails", allDetailsExpression, ParameterStyle.FORM, true, false); + return this; + } + + public GetPetByIdWithBasicAuthenticationSendActionBuilder details(String...details) { + queryParameter("details", details, ParameterStyle.FORM, true, false); + return this; + } + + public void setDetails(String...details) { + queryParameter("details", details, ParameterStyle.FORM, true, false); + } + + public GetPetByIdWithBasicAuthenticationSendActionBuilder requesterInformation(String...requesterInformation) { + queryParameter("requesterInformation", requesterInformation, ParameterStyle.FORM, true, false); + return this; + } + + public void setRequesterInformation(String...requesterInformation) { + queryParameter("requesterInformation", requesterInformation, ParameterStyle.FORM, true, false); + } + + public GetPetByIdWithBasicAuthenticationSendActionBuilder basicAuthUsername(String basicUsername) { + this.basicUsername = basicUsername; + return this; + } + + public void setBasicAuthUsername(String basicUsername) { + this.basicUsername = basicUsername; + } + + public GetPetByIdWithBasicAuthenticationSendActionBuilder basicAuthPassword(String password) { + this.basicPassword = password; + return this; + } + + public void setBasicAuthPassword(String password) { + this.basicPassword = password; + } + + protected void addBasicAuthHeader(String basicUsername, String basicPassword, + HttpMessageBuilderSupport messageBuilderSupport) { + TestApiUtils.addBasicAuthHeader( + isNotEmpty(basicUsername) ? basicUsername : defaultBasicUsername, + isNotEmpty(basicPassword) ? basicPassword : defaultBasicPassword, + messageBuilderSupport); + } + + @Override + public SendMessageAction doBuild() { + addBasicAuthHeader(basicUsername, basicPassword, getMessageBuilderSupport()); + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetByIdWithBasicAuthenticationReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/secure-basic/pet/{petId}"; + + private static final String OPERATION_NAME = "getPetByIdWithBasicAuthentication"; + + public GetPetByIdWithBasicAuthenticationReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetByIdWithBasicAuthenticationReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetByIdWithBearerAuthenticationSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/secure-bearer/pet/{petId}"; + + private static final String OPERATION_NAME = "getPetByIdWithBearerAuthentication"; + + @Value("${" + "extpetstore.bearer.token:#{null}}") + private String defaultBasicAuthBearer; + + private String basicAuthBearer; + + /** + * Constructor with type safe required parameters. + */ + public GetPetByIdWithBearerAuthenticationSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, Long petId, Boolean allDetails) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + queryParameter("allDetails", allDetails, ParameterStyle.FORM, true, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetByIdWithBearerAuthenticationSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, String petIdExpression, String allDetailsExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + queryParameter("allDetails", allDetailsExpression, ParameterStyle.FORM, true, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetByIdWithBearerAuthenticationSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression, String allDetailsExpression) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + queryParameter("allDetails", allDetailsExpression, ParameterStyle.FORM, true, false); + } + + public GetPetByIdWithBearerAuthenticationSendActionBuilder petId(Long petId) { + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + return this; + } + + public GetPetByIdWithBearerAuthenticationSendActionBuilder petId(String petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + return this; + } + + public GetPetByIdWithBearerAuthenticationSendActionBuilder allDetails(Boolean allDetails) { + queryParameter("allDetails", allDetails, ParameterStyle.FORM, true, false); + return this; + } + + public GetPetByIdWithBearerAuthenticationSendActionBuilder allDetails(String allDetailsExpression) { + queryParameter("allDetails", allDetailsExpression, ParameterStyle.FORM, true, false); + return this; + } + + public GetPetByIdWithBearerAuthenticationSendActionBuilder details(String...details) { + queryParameter("details", details, ParameterStyle.FORM, true, false); + return this; + } + + public void setDetails(String...details) { + queryParameter("details", details, ParameterStyle.FORM, true, false); + } + + public GetPetByIdWithBearerAuthenticationSendActionBuilder requesterInformation(String...requesterInformation) { + queryParameter("requesterInformation", requesterInformation, ParameterStyle.FORM, true, false); + return this; + } + + public void setRequesterInformation(String...requesterInformation) { + queryParameter("requesterInformation", requesterInformation, ParameterStyle.FORM, true, false); + } + + public GetPetByIdWithBearerAuthenticationSendActionBuilder basicAuthBearer(String basicAuthBearer) { + this.basicAuthBearer = basicAuthBearer; + return this; + } + + public void setBasicAuthBearer(String basicAuthBearer) { + this.basicAuthBearer = basicAuthBearer; + } + + @Override + public SendMessageAction doBuild() { + if (!isEmpty(basicAuthBearer) || !isEmpty(defaultBasicAuthBearer)) { + headerParameter("Authorization", "Bearer " +getOrDefault(basicAuthBearer, defaultBasicAuthBearer, true)); + } + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetByIdWithBearerAuthenticationReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/secure-bearer/pet/{petId}"; + + private static final String OPERATION_NAME = "getPetByIdWithBearerAuthentication"; + + public GetPetByIdWithBearerAuthenticationReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetByIdWithBearerAuthenticationReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithCookieSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/{petId}"; + + private static final String OPERATION_NAME = "getPetWithCookie"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithCookieSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, Long petId, String sessionId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + cookieParameter("session_id", sessionId, ParameterStyle.FORM, true, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithCookieSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, String petIdExpression, String sessionIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + cookieParameter("session_id", sessionIdExpression, ParameterStyle.FORM, true, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithCookieSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression, String sessionIdExpression) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + cookieParameter("session_id", sessionIdExpression, ParameterStyle.FORM, true, false); + } + + public GetPetWithCookieSendActionBuilder petId(Long petId) { + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + return this; + } + + public GetPetWithCookieSendActionBuilder petId(String petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + return this; + } + + public GetPetWithCookieSendActionBuilder sessionId(String sessionId) { + cookieParameter("session_id", sessionId, ParameterStyle.FORM, true, false); + return this; + } + + public GetPetWithCookieSendActionBuilder optTrxId(String optTrxId) { + cookieParameter("opt_trx_id", optTrxId, ParameterStyle.FORM, true, false); + return this; + } + + public void setOptTrxId(String optTrxId) { + cookieParameter("opt_trx_id", optTrxId, ParameterStyle.FORM, true, false); + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithCookieReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/{petId}"; + + private static final String OPERATION_NAME = "getPetWithCookie"; + + public GetPetWithCookieReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithCookieReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithDeepObjectTypeQuerySendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/query/deep/object"; + + private static final String OPERATION_NAME = "getPetWithDeepObjectTypeQuery"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithDeepObjectTypeQuerySendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, PetIdentifier petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + queryParameter("petId", petId, ParameterStyle.DEEPOBJECT, true, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithDeepObjectTypeQuerySendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, String petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + queryParameter("petId", petIdExpression, ParameterStyle.DEEPOBJECT, true, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithDeepObjectTypeQuerySendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + queryParameter("petId", petIdExpression, ParameterStyle.DEEPOBJECT, true, true); + } + + public GetPetWithDeepObjectTypeQuerySendActionBuilder petId(PetIdentifier petId) { + queryParameter("petId", petId, ParameterStyle.DEEPOBJECT, true, true); + return this; + } + + public GetPetWithDeepObjectTypeQuerySendActionBuilder petId(String petIdExpression) { + queryParameter("petId", petIdExpression, ParameterStyle.DEEPOBJECT, true, true); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithDeepObjectTypeQueryReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/query/deep/object"; + + private static final String OPERATION_NAME = "getPetWithDeepObjectTypeQuery"; + + public GetPetWithDeepObjectTypeQueryReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithDeepObjectTypeQueryReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithFormExplodedStyleCookieSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/cookie/form/exploded"; + + private static final String OPERATION_NAME = "getPetWithFormExplodedStyleCookie"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithFormExplodedStyleCookieSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, List petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + cookieParameter("petId", petId, ParameterStyle.FORM, true, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormExplodedStyleCookieSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, List petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + cookieParameter("petId", petIdExpression, ParameterStyle.FORM, true, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormExplodedStyleCookieSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, List petId) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + cookieParameter("petId", petId, ParameterStyle.FORM, true, false); + } + + public GetPetWithFormExplodedStyleCookieSendActionBuilder petId(Integer...petId) { + cookieParameter("petId", petId, ParameterStyle.FORM, true, false); + return this; + } + + public GetPetWithFormExplodedStyleCookieSendActionBuilder petId(String...petIdExpression) { + cookieParameter("petId", petIdExpression, ParameterStyle.FORM, true, false); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithFormExplodedStyleCookieReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/cookie/form/exploded"; + + private static final String OPERATION_NAME = "getPetWithFormExplodedStyleCookie"; + + public GetPetWithFormExplodedStyleCookieReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithFormExplodedStyleCookieReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithFormObjectStyleCookieSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/cookie/form/object"; + + private static final String OPERATION_NAME = "getPetWithFormObjectStyleCookie"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithFormObjectStyleCookieSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, PetIdentifier petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + cookieParameter("petId", petId, ParameterStyle.FORM, false, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormObjectStyleCookieSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, String petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + cookieParameter("petId", petIdExpression, ParameterStyle.FORM, false, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormObjectStyleCookieSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + cookieParameter("petId", petIdExpression, ParameterStyle.FORM, false, true); + } + + public GetPetWithFormObjectStyleCookieSendActionBuilder petId(PetIdentifier petId) { + cookieParameter("petId", petId, ParameterStyle.FORM, false, true); + return this; + } + + public GetPetWithFormObjectStyleCookieSendActionBuilder petId(String petIdExpression) { + cookieParameter("petId", petIdExpression, ParameterStyle.FORM, false, true); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithFormObjectStyleCookieReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/cookie/form/object"; + + private static final String OPERATION_NAME = "getPetWithFormObjectStyleCookie"; + + public GetPetWithFormObjectStyleCookieReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithFormObjectStyleCookieReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithFormStyleCookieSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/cookie/form"; + + private static final String OPERATION_NAME = "getPetWithFormStyleCookie"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithFormStyleCookieSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, List petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + cookieParameter("petId", petId, ParameterStyle.FORM, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormStyleCookieSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, List petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + cookieParameter("petId", petIdExpression, ParameterStyle.FORM, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormStyleCookieSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, List petId) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + cookieParameter("petId", petId, ParameterStyle.FORM, false, false); + } + + public GetPetWithFormStyleCookieSendActionBuilder petId(Integer...petId) { + cookieParameter("petId", petId, ParameterStyle.FORM, false, false); + return this; + } + + public GetPetWithFormStyleCookieSendActionBuilder petId(String...petIdExpression) { + cookieParameter("petId", petIdExpression, ParameterStyle.FORM, false, false); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithFormStyleCookieReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/cookie/form"; + + private static final String OPERATION_NAME = "getPetWithFormStyleCookie"; + + public GetPetWithFormStyleCookieReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithFormStyleCookieReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithFormStyleExplodedObjectQuerySendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/query/form/exploded/object"; + + private static final String OPERATION_NAME = "getPetWithFormStyleExplodedObjectQuery"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithFormStyleExplodedObjectQuerySendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, PetIdentifier petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + queryParameter("petId", petId, ParameterStyle.FORM, true, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormStyleExplodedObjectQuerySendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, String petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + queryParameter("petId", petIdExpression, ParameterStyle.FORM, true, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormStyleExplodedObjectQuerySendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + queryParameter("petId", petIdExpression, ParameterStyle.FORM, true, true); + } + + public GetPetWithFormStyleExplodedObjectQuerySendActionBuilder petId(PetIdentifier petId) { + queryParameter("petId", petId, ParameterStyle.FORM, true, true); + return this; + } + + public GetPetWithFormStyleExplodedObjectQuerySendActionBuilder petId(String petIdExpression) { + queryParameter("petId", petIdExpression, ParameterStyle.FORM, true, true); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithFormStyleExplodedObjectQueryReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/query/form/exploded/object"; + + private static final String OPERATION_NAME = "getPetWithFormStyleExplodedObjectQuery"; + + public GetPetWithFormStyleExplodedObjectQueryReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithFormStyleExplodedObjectQueryReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithFormStyleExplodedQuerySendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/query/form/exploded"; + + private static final String OPERATION_NAME = "getPetWithFormStyleExplodedQuery"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithFormStyleExplodedQuerySendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, List petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + queryParameter("petId", petId, ParameterStyle.FORM, true, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormStyleExplodedQuerySendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, List petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + queryParameter("petId", petIdExpression, ParameterStyle.FORM, true, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormStyleExplodedQuerySendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, List petId) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + queryParameter("petId", petId, ParameterStyle.FORM, true, false); + } + + public GetPetWithFormStyleExplodedQuerySendActionBuilder petId(Integer...petId) { + queryParameter("petId", petId, ParameterStyle.FORM, true, false); + return this; + } + + public GetPetWithFormStyleExplodedQuerySendActionBuilder petId(String...petIdExpression) { + queryParameter("petId", petIdExpression, ParameterStyle.FORM, true, false); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithFormStyleExplodedQueryReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/query/form/exploded"; + + private static final String OPERATION_NAME = "getPetWithFormStyleExplodedQuery"; + + public GetPetWithFormStyleExplodedQueryReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithFormStyleExplodedQueryReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithFormStyleObjectQuerySendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/query/form/object"; + + private static final String OPERATION_NAME = "getPetWithFormStyleObjectQuery"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithFormStyleObjectQuerySendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, PetIdentifier petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + queryParameter("petId", petId, ParameterStyle.FORM, false, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormStyleObjectQuerySendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, String petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + queryParameter("petId", petIdExpression, ParameterStyle.FORM, false, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormStyleObjectQuerySendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + queryParameter("petId", petIdExpression, ParameterStyle.FORM, false, true); + } + + public GetPetWithFormStyleObjectQuerySendActionBuilder petId(PetIdentifier petId) { + queryParameter("petId", petId, ParameterStyle.FORM, false, true); + return this; + } + + public GetPetWithFormStyleObjectQuerySendActionBuilder petId(String petIdExpression) { + queryParameter("petId", petIdExpression, ParameterStyle.FORM, false, true); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithFormStyleObjectQueryReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/query/form/object"; + + private static final String OPERATION_NAME = "getPetWithFormStyleObjectQuery"; + + public GetPetWithFormStyleObjectQueryReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithFormStyleObjectQueryReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithFormStyleQuerySendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/query/form"; + + private static final String OPERATION_NAME = "getPetWithFormStyleQuery"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithFormStyleQuerySendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, List petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + queryParameter("petId", petId, ParameterStyle.FORM, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormStyleQuerySendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, List petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + queryParameter("petId", petIdExpression, ParameterStyle.FORM, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithFormStyleQuerySendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, List petId) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + queryParameter("petId", petId, ParameterStyle.FORM, false, false); + } + + public GetPetWithFormStyleQuerySendActionBuilder petId(Integer...petId) { + queryParameter("petId", petId, ParameterStyle.FORM, false, false); + return this; + } + + public GetPetWithFormStyleQuerySendActionBuilder petId(String...petIdExpression) { + queryParameter("petId", petIdExpression, ParameterStyle.FORM, false, false); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithFormStyleQueryReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/query/form"; + + private static final String OPERATION_NAME = "getPetWithFormStyleQuery"; + + public GetPetWithFormStyleQueryReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithFormStyleQueryReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithLabelStyleArraySendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/label/{petId}"; + + private static final String OPERATION_NAME = "getPetWithLabelStyleArray"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithLabelStyleArraySendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, List petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.LABEL, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithLabelStyleArraySendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, List petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.LABEL, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithLabelStyleArraySendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, List petId) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.LABEL, false, false); + } + + public GetPetWithLabelStyleArraySendActionBuilder petId(Integer...petId) { + pathParameter("petId", petId, ParameterStyle.LABEL, false, false); + return this; + } + + public GetPetWithLabelStyleArraySendActionBuilder petId(String...petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.LABEL, false, false); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithLabelStyleArrayReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/label/{petId}"; + + private static final String OPERATION_NAME = "getPetWithLabelStyleArray"; + + public GetPetWithLabelStyleArrayReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithLabelStyleArrayReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithLabelStyleArrayExplodedSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/label/exploded/{petId}"; + + private static final String OPERATION_NAME = "getPetWithLabelStyleArrayExploded"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithLabelStyleArrayExplodedSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, List petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.LABEL, true, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithLabelStyleArrayExplodedSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, List petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.LABEL, true, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithLabelStyleArrayExplodedSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, List petId) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.LABEL, true, false); + } + + public GetPetWithLabelStyleArrayExplodedSendActionBuilder petId(Integer...petId) { + pathParameter("petId", petId, ParameterStyle.LABEL, true, false); + return this; + } + + public GetPetWithLabelStyleArrayExplodedSendActionBuilder petId(String...petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.LABEL, true, false); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithLabelStyleArrayExplodedReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/label/exploded/{petId}"; + + private static final String OPERATION_NAME = "getPetWithLabelStyleArrayExploded"; + + public GetPetWithLabelStyleArrayExplodedReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithLabelStyleArrayExplodedReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithLabelStyleObjectSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/label/object/{petId}"; + + private static final String OPERATION_NAME = "getPetWithLabelStyleObject"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithLabelStyleObjectSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, PetIdentifier petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.LABEL, false, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithLabelStyleObjectSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, String petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.LABEL, false, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithLabelStyleObjectSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.LABEL, false, true); + } + + public GetPetWithLabelStyleObjectSendActionBuilder petId(PetIdentifier petId) { + pathParameter("petId", petId, ParameterStyle.LABEL, false, true); + return this; + } + + public GetPetWithLabelStyleObjectSendActionBuilder petId(String petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.LABEL, false, true); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithLabelStyleObjectReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/label/object/{petId}"; + + private static final String OPERATION_NAME = "getPetWithLabelStyleObject"; + + public GetPetWithLabelStyleObjectReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithLabelStyleObjectReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithLabelStyleObjectExplodedSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/label/exploded/object/{petId}"; + + private static final String OPERATION_NAME = "getPetWithLabelStyleObjectExploded"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithLabelStyleObjectExplodedSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, PetIdentifier petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.LABEL, true, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithLabelStyleObjectExplodedSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, String petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.LABEL, true, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithLabelStyleObjectExplodedSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.LABEL, true, true); + } + + public GetPetWithLabelStyleObjectExplodedSendActionBuilder petId(PetIdentifier petId) { + pathParameter("petId", petId, ParameterStyle.LABEL, true, true); + return this; + } + + public GetPetWithLabelStyleObjectExplodedSendActionBuilder petId(String petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.LABEL, true, true); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithLabelStyleObjectExplodedReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/label/exploded/object/{petId}"; + + private static final String OPERATION_NAME = "getPetWithLabelStyleObjectExploded"; + + public GetPetWithLabelStyleObjectExplodedReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithLabelStyleObjectExplodedReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithMatrixStyleArraySendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/matrix/{petId}"; + + private static final String OPERATION_NAME = "getPetWithMatrixStyleArray"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithMatrixStyleArraySendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, List petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.MATRIX, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithMatrixStyleArraySendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, List petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.MATRIX, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithMatrixStyleArraySendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, List petId) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.MATRIX, false, false); + } + + public GetPetWithMatrixStyleArraySendActionBuilder petId(Integer...petId) { + pathParameter("petId", petId, ParameterStyle.MATRIX, false, false); + return this; + } + + public GetPetWithMatrixStyleArraySendActionBuilder petId(String...petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.MATRIX, false, false); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithMatrixStyleArrayReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/matrix/{petId}"; + + private static final String OPERATION_NAME = "getPetWithMatrixStyleArray"; + + public GetPetWithMatrixStyleArrayReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithMatrixStyleArrayReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithMatrixStyleArrayExplodedSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/matrix/exploded/{petId}"; + + private static final String OPERATION_NAME = "getPetWithMatrixStyleArrayExploded"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithMatrixStyleArrayExplodedSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, List petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.MATRIX, true, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithMatrixStyleArrayExplodedSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, List petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.MATRIX, true, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithMatrixStyleArrayExplodedSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, List petId) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.MATRIX, true, false); + } + + public GetPetWithMatrixStyleArrayExplodedSendActionBuilder petId(Integer...petId) { + pathParameter("petId", petId, ParameterStyle.MATRIX, true, false); + return this; + } + + public GetPetWithMatrixStyleArrayExplodedSendActionBuilder petId(String...petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.MATRIX, true, false); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithMatrixStyleArrayExplodedReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/matrix/exploded/{petId}"; + + private static final String OPERATION_NAME = "getPetWithMatrixStyleArrayExploded"; + + public GetPetWithMatrixStyleArrayExplodedReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithMatrixStyleArrayExplodedReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithMatrixStyleObjectSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/matrix/object/{petId}"; + + private static final String OPERATION_NAME = "getPetWithMatrixStyleObject"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithMatrixStyleObjectSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, PetIdentifier petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.MATRIX, false, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithMatrixStyleObjectSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, String petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.MATRIX, false, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithMatrixStyleObjectSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.MATRIX, false, true); + } + + public GetPetWithMatrixStyleObjectSendActionBuilder petId(PetIdentifier petId) { + pathParameter("petId", petId, ParameterStyle.MATRIX, false, true); + return this; + } + + public GetPetWithMatrixStyleObjectSendActionBuilder petId(String petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.MATRIX, false, true); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithMatrixStyleObjectReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/matrix/object/{petId}"; + + private static final String OPERATION_NAME = "getPetWithMatrixStyleObject"; + + public GetPetWithMatrixStyleObjectReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithMatrixStyleObjectReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithMatrixStyleObjectExplodedSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/matrix/exploded/object/{petId}"; + + private static final String OPERATION_NAME = "getPetWithMatrixStyleObjectExploded"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithMatrixStyleObjectExplodedSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, PetIdentifier petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.MATRIX, true, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithMatrixStyleObjectExplodedSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, String petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.MATRIX, true, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithMatrixStyleObjectExplodedSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.MATRIX, true, true); + } + + public GetPetWithMatrixStyleObjectExplodedSendActionBuilder petId(PetIdentifier petId) { + pathParameter("petId", petId, ParameterStyle.MATRIX, true, true); + return this; + } + + public GetPetWithMatrixStyleObjectExplodedSendActionBuilder petId(String petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.MATRIX, true, true); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithMatrixStyleObjectExplodedReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/matrix/exploded/object/{petId}"; + + private static final String OPERATION_NAME = "getPetWithMatrixStyleObjectExploded"; + + public GetPetWithMatrixStyleObjectExplodedReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithMatrixStyleObjectExplodedReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithSimpleStyleArraySendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/simple/{petId}"; + + private static final String OPERATION_NAME = "getPetWithSimpleStyleArray"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithSimpleStyleArraySendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, List petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleArraySendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, List petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleArraySendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, List petId) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + } + + public GetPetWithSimpleStyleArraySendActionBuilder petId(Integer...petId) { + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + return this; + } + + public GetPetWithSimpleStyleArraySendActionBuilder petId(String...petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithSimpleStyleArrayReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/simple/{petId}"; + + private static final String OPERATION_NAME = "getPetWithSimpleStyleArray"; + + public GetPetWithSimpleStyleArrayReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithSimpleStyleArrayReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithSimpleStyleArrayExplodedSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/simple/exploded/{petId}"; + + private static final String OPERATION_NAME = "getPetWithSimpleStyleArrayExploded"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithSimpleStyleArrayExplodedSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, List petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleArrayExplodedSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, List petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleArrayExplodedSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, List petId) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + } + + public GetPetWithSimpleStyleArrayExplodedSendActionBuilder petId(Integer...petId) { + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + return this; + } + + public GetPetWithSimpleStyleArrayExplodedSendActionBuilder petId(String...petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithSimpleStyleArrayExplodedReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/simple/exploded/{petId}"; + + private static final String OPERATION_NAME = "getPetWithSimpleStyleArrayExploded"; + + public GetPetWithSimpleStyleArrayExplodedReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithSimpleStyleArrayExplodedReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithSimpleStyleExplodedHeaderSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/header/simple/exploded"; + + private static final String OPERATION_NAME = "getPetWithSimpleStyleExplodedHeader"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithSimpleStyleExplodedHeaderSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, List petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + headerParameter("petId", petId, ParameterStyle.SIMPLE, true, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleExplodedHeaderSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, List petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + headerParameter("petId", petIdExpression, ParameterStyle.SIMPLE, true, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleExplodedHeaderSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, List petId) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + headerParameter("petId", petId, ParameterStyle.SIMPLE, true, false); + } + + public GetPetWithSimpleStyleExplodedHeaderSendActionBuilder petId(Integer...petId) { + headerParameter("petId", petId, ParameterStyle.SIMPLE, true, false); + return this; + } + + public GetPetWithSimpleStyleExplodedHeaderSendActionBuilder petId(String...petIdExpression) { + headerParameter("petId", petIdExpression, ParameterStyle.SIMPLE, true, false); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithSimpleStyleExplodedHeaderReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/header/simple/exploded"; + + private static final String OPERATION_NAME = "getPetWithSimpleStyleExplodedHeader"; + + public GetPetWithSimpleStyleExplodedHeaderReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithSimpleStyleExplodedHeaderReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithSimpleStyleExplodedObjectHeaderSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/header/simple/exploded/object"; + + private static final String OPERATION_NAME = "getPetWithSimpleStyleExplodedObjectHeader"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithSimpleStyleExplodedObjectHeaderSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, PetIdentifier petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + headerParameter("petId", petId, ParameterStyle.SIMPLE, true, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleExplodedObjectHeaderSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, String petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + headerParameter("petId", petIdExpression, ParameterStyle.SIMPLE, true, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleExplodedObjectHeaderSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + headerParameter("petId", petIdExpression, ParameterStyle.SIMPLE, true, true); + } + + public GetPetWithSimpleStyleExplodedObjectHeaderSendActionBuilder petId(PetIdentifier petId) { + headerParameter("petId", petId, ParameterStyle.SIMPLE, true, true); + return this; + } + + public GetPetWithSimpleStyleExplodedObjectHeaderSendActionBuilder petId(String petIdExpression) { + headerParameter("petId", petIdExpression, ParameterStyle.SIMPLE, true, true); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithSimpleStyleExplodedObjectHeaderReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/header/simple/exploded/object"; + + private static final String OPERATION_NAME = "getPetWithSimpleStyleExplodedObjectHeader"; + + public GetPetWithSimpleStyleExplodedObjectHeaderReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithSimpleStyleExplodedObjectHeaderReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithSimpleStyleHeaderSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/header/simple"; + + private static final String OPERATION_NAME = "getPetWithSimpleStyleHeader"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithSimpleStyleHeaderSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, List petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + headerParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleHeaderSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, List petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + headerParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleHeaderSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, List petId) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + headerParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + } + + public GetPetWithSimpleStyleHeaderSendActionBuilder petId(Integer...petId) { + headerParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + return this; + } + + public GetPetWithSimpleStyleHeaderSendActionBuilder petId(String...petIdExpression) { + headerParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithSimpleStyleHeaderReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/header/simple"; + + private static final String OPERATION_NAME = "getPetWithSimpleStyleHeader"; + + public GetPetWithSimpleStyleHeaderReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithSimpleStyleHeaderReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithSimpleStyleObjectSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/simple/object/{petId}"; + + private static final String OPERATION_NAME = "getPetWithSimpleStyleObject"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithSimpleStyleObjectSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, PetIdentifier petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleObjectSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, String petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleObjectSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, true); + } + + public GetPetWithSimpleStyleObjectSendActionBuilder petId(PetIdentifier petId) { + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, true); + return this; + } + + public GetPetWithSimpleStyleObjectSendActionBuilder petId(String petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, true); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithSimpleStyleObjectReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/simple/object/{petId}"; + + private static final String OPERATION_NAME = "getPetWithSimpleStyleObject"; + + public GetPetWithSimpleStyleObjectReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithSimpleStyleObjectReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithSimpleStyleObjectExplodedSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/simple/exploded/object/{petId}"; + + private static final String OPERATION_NAME = "getPetWithSimpleStyleObjectExploded"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithSimpleStyleObjectExplodedSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, PetIdentifier petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.SIMPLE, true, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleObjectExplodedSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, String petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, true, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleObjectExplodedSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, true, true); + } + + public GetPetWithSimpleStyleObjectExplodedSendActionBuilder petId(PetIdentifier petId) { + pathParameter("petId", petId, ParameterStyle.SIMPLE, true, true); + return this; + } + + public GetPetWithSimpleStyleObjectExplodedSendActionBuilder petId(String petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, true, true); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithSimpleStyleObjectExplodedReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/simple/exploded/object/{petId}"; + + private static final String OPERATION_NAME = "getPetWithSimpleStyleObjectExploded"; + + public GetPetWithSimpleStyleObjectExplodedReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithSimpleStyleObjectExplodedReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetWithSimpleStyleObjectHeaderSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/header/simple/object"; + + private static final String OPERATION_NAME = "getPetWithSimpleStyleObjectHeader"; + + /** + * Constructor with type safe required parameters. + */ + public GetPetWithSimpleStyleObjectHeaderSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, PetIdentifier petId) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + headerParameter("petId", petId, ParameterStyle.SIMPLE, false, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleObjectHeaderSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, String petIdExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + headerParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, true); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetWithSimpleStyleObjectHeaderSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + headerParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, true); + } + + public GetPetWithSimpleStyleObjectHeaderSendActionBuilder petId(PetIdentifier petId) { + headerParameter("petId", petId, ParameterStyle.SIMPLE, false, true); + return this; + } + + public GetPetWithSimpleStyleObjectHeaderSendActionBuilder petId(String petIdExpression) { + headerParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, true); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetWithSimpleStyleObjectHeaderReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/ext/pet/header/simple/object"; + + private static final String OPERATION_NAME = "getPetWithSimpleStyleObjectHeader"; + + public GetPetWithSimpleStyleObjectHeaderReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetWithSimpleStyleObjectHeaderReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class PostVaccinationDocumentSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "POST"; + + private static final String ENDPOINT = "/api/v3/ext/pet/vaccination/{bucket}/{filename}"; + + private static final String OPERATION_NAME = "postVaccinationDocument"; + + /** + * Constructor with type safe required parameters. + */ + public PostVaccinationDocumentSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String bucket, String filename) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("bucket", bucket, ParameterStyle.SIMPLE, false, false); + pathParameter("filename", filename, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public PostVaccinationDocumentSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String bucketExpression, String filenameExpression) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("bucket", bucketExpression, ParameterStyle.SIMPLE, false, false); + pathParameter("filename", filenameExpression, ParameterStyle.SIMPLE, false, false); + } + + public PostVaccinationDocumentSendActionBuilder bucket(String bucket) { + pathParameter("bucket", bucket, ParameterStyle.SIMPLE, false, false); + return this; + } + + public PostVaccinationDocumentSendActionBuilder filename(String filename) { + pathParameter("filename", filename, ParameterStyle.SIMPLE, false, false); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class PostVaccinationDocumentReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "POST"; + + private static final String ENDPOINT = "/api/v3/ext/pet/vaccination/{bucket}/{filename}"; + + private static final String OPERATION_NAME = "postVaccinationDocument"; + + public PostVaccinationDocumentReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public PostVaccinationDocumentReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class PostVaccinationFormDataSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "POST"; + + private static final String ENDPOINT = "/api/v3/ext/pet/vaccination/form"; + + private static final String OPERATION_NAME = "postVaccinationFormData"; + + /** + * Constructor with type safe required parameters. + */ + public PostVaccinationFormDataSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + } + + public PostVaccinationFormDataSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + public PostVaccinationFormDataSendActionBuilder vaccine(String vaccine) { + formParameter("vaccine", vaccine); + return this; + } + + public void setVaccine(String vaccine) { + formParameter("vaccine", vaccine); + } + + public PostVaccinationFormDataSendActionBuilder isFirstVaccination(Boolean isFirstVaccination) { + formParameter("isFirstVaccination", isFirstVaccination); + return this; + } + + public void setIsFirstVaccination(Boolean isFirstVaccination) { + formParameter("isFirstVaccination", isFirstVaccination); + } + + public PostVaccinationFormDataSendActionBuilder isFirstVaccination(String isFirstVaccinationExpression) { + formParameter("isFirstVaccination", isFirstVaccinationExpression); + return this; + } + + public void setIsFirstVaccination(String isFirstVaccinationExpression) { + formParameter("isFirstVaccination", isFirstVaccinationExpression); + } + + public PostVaccinationFormDataSendActionBuilder doseNumber(Integer doseNumber) { + formParameter("doseNumber", doseNumber); + return this; + } + + public void setDoseNumber(Integer doseNumber) { + formParameter("doseNumber", doseNumber); + } + + public PostVaccinationFormDataSendActionBuilder doseNumber(String doseNumberExpression) { + formParameter("doseNumber", doseNumberExpression); + return this; + } + + public void setDoseNumber(String doseNumberExpression) { + formParameter("doseNumber", doseNumberExpression); + } + + public PostVaccinationFormDataSendActionBuilder vaccinationDate(LocalDate vaccinationDate) { + formParameter("vaccinationDate", vaccinationDate); + return this; + } + + public void setVaccinationDate(LocalDate vaccinationDate) { + formParameter("vaccinationDate", vaccinationDate); + } + + public PostVaccinationFormDataSendActionBuilder vaccinationDate(String vaccinationDateExpression) { + formParameter("vaccinationDate", vaccinationDateExpression); + return this; + } + + public void setVaccinationDate(String vaccinationDateExpression) { + formParameter("vaccinationDate", vaccinationDateExpression); + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class PostVaccinationFormDataReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "POST"; + + private static final String ENDPOINT = "/api/v3/ext/pet/vaccination/form"; + + private static final String OPERATION_NAME = "postVaccinationFormData"; + + public PostVaccinationFormDataReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public PostVaccinationFormDataReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class UpdatePetWithArrayQueryDataSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "PUT"; + + private static final String ENDPOINT = "/api/v3/ext/pet/{petId}"; + + private static final String OPERATION_NAME = "updatePetWithArrayQueryData"; + + /** + * Constructor with type safe required parameters. + */ + public UpdatePetWithArrayQueryDataSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, Long petId, String _name, String status, List tags, List nicknames, String sampleStringHeader) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + queryParameter("name", _name, ParameterStyle.FORM, true, false); + queryParameter("status", status, ParameterStyle.FORM, true, false); + queryParameter("tags", tags, ParameterStyle.FORM, true, false); + queryParameter("nicknames", nicknames, ParameterStyle.FORM, true, false); + headerParameter("sampleStringHeader", sampleStringHeader, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public UpdatePetWithArrayQueryDataSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, String petIdExpression, String _nameExpression, String statusExpression, List tagsExpression, List nicknamesExpression, String sampleStringHeaderExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + queryParameter("name", _nameExpression, ParameterStyle.FORM, true, false); + queryParameter("status", statusExpression, ParameterStyle.FORM, true, false); + queryParameter("tags", tagsExpression, ParameterStyle.FORM, true, false); + queryParameter("nicknames", nicknamesExpression, ParameterStyle.FORM, true, false); + headerParameter("sampleStringHeader", sampleStringHeaderExpression, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public UpdatePetWithArrayQueryDataSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression, String _nameExpression, String statusExpression, List tags, List nicknames, String sampleStringHeaderExpression) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + queryParameter("name", _nameExpression, ParameterStyle.FORM, true, false); + queryParameter("status", statusExpression, ParameterStyle.FORM, true, false); + queryParameter("tags", tags, ParameterStyle.FORM, true, false); + queryParameter("nicknames", nicknames, ParameterStyle.FORM, true, false); + headerParameter("sampleStringHeader", sampleStringHeaderExpression, ParameterStyle.SIMPLE, false, false); + } + + public UpdatePetWithArrayQueryDataSendActionBuilder petId(Long petId) { + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + return this; + } + + public UpdatePetWithArrayQueryDataSendActionBuilder petId(String petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + return this; + } + + public UpdatePetWithArrayQueryDataSendActionBuilder _name(String _name) { + queryParameter("name", _name, ParameterStyle.FORM, true, false); + return this; + } + + public UpdatePetWithArrayQueryDataSendActionBuilder status(String status) { + queryParameter("status", status, ParameterStyle.FORM, true, false); + return this; + } + + public UpdatePetWithArrayQueryDataSendActionBuilder tags(String...tags) { + queryParameter("tags", tags, ParameterStyle.FORM, true, false); + return this; + } + + public UpdatePetWithArrayQueryDataSendActionBuilder nicknames(String...nicknames) { + queryParameter("nicknames", nicknames, ParameterStyle.FORM, true, false); + return this; + } + + public UpdatePetWithArrayQueryDataSendActionBuilder sampleStringHeader(String sampleStringHeader) { + headerParameter("sampleStringHeader", sampleStringHeader, ParameterStyle.SIMPLE, false, false); + return this; + } + + public UpdatePetWithArrayQueryDataSendActionBuilder sampleIntHeader(Integer sampleIntHeader) { + headerParameter("sampleIntHeader", sampleIntHeader, ParameterStyle.SIMPLE, false, false); + return this; + } + + public void setSampleIntHeader(Integer sampleIntHeader) { + headerParameter("sampleIntHeader", sampleIntHeader, ParameterStyle.SIMPLE, false, false); + } + + public UpdatePetWithArrayQueryDataSendActionBuilder sampleIntHeader(String sampleIntHeaderExpression) { + headerParameter("sampleIntHeader", sampleIntHeaderExpression, ParameterStyle.SIMPLE, false, false); + return this; + } + + public void setSampleIntHeader(String sampleIntHeaderExpression) { + headerParameter("sampleIntHeader", sampleIntHeaderExpression, ParameterStyle.SIMPLE, false, false); + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class UpdatePetWithArrayQueryDataReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "PUT"; + + private static final String ENDPOINT = "/api/v3/ext/pet/{petId}"; + + private static final String OPERATION_NAME = "updatePetWithArrayQueryData"; + + public UpdatePetWithArrayQueryDataReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public UpdatePetWithArrayQueryDataReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class UpdatePetWithFormUrlEncodedSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "PUT"; + + private static final String ENDPOINT = "/api/v3/ext/pet/form/{petId}"; + + private static final String OPERATION_NAME = "updatePetWithFormUrlEncoded"; + + /** + * Constructor with type safe required parameters. + */ + public UpdatePetWithFormUrlEncodedSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, Long petId, String _name, String status, Integer age, List tags) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + formParameter("name", _name); + formParameter("status", status); + formParameter("age", age); + formParameter("tags", tags); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public UpdatePetWithFormUrlEncodedSendActionBuilder(OpenApiSpecification openApiSpecification, ExtPetApi extPetApi, String petIdExpression, String _nameExpression, String statusExpression, String ageExpression, List tagsExpression) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + formParameter("name", _nameExpression); + formParameter("status", statusExpression); + formParameter("age", ageExpression); + formParameter("tags", tagsExpression); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public UpdatePetWithFormUrlEncodedSendActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression, String _nameExpression, String statusExpression, String ageExpression, List tags) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + formParameter("name", _nameExpression); + formParameter("status", statusExpression); + formParameter("age", ageExpression); + formParameter("tags", tags); + } + + public UpdatePetWithFormUrlEncodedSendActionBuilder petId(Long petId) { + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + return this; + } + + public UpdatePetWithFormUrlEncodedSendActionBuilder petId(String petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + return this; + } + + public UpdatePetWithFormUrlEncodedSendActionBuilder _name(String _name) { + formParameter("name", _name); + return this; + } + + public UpdatePetWithFormUrlEncodedSendActionBuilder status(String status) { + formParameter("status", status); + return this; + } + + public UpdatePetWithFormUrlEncodedSendActionBuilder age(Integer age) { + formParameter("age", age); + return this; + } + + public UpdatePetWithFormUrlEncodedSendActionBuilder age(String ageExpression) { + formParameter("age", ageExpression); + return this; + } + + public UpdatePetWithFormUrlEncodedSendActionBuilder tags(String...tags) { + formParameter("tags", tags); + return this; + } + + public UpdatePetWithFormUrlEncodedSendActionBuilder owners(Integer owners) { + formParameter("owners", owners); + return this; + } + + public void setOwners(Integer owners) { + formParameter("owners", owners); + } + + public UpdatePetWithFormUrlEncodedSendActionBuilder owners(String ownersExpression) { + formParameter("owners", ownersExpression); + return this; + } + + public void setOwners(String ownersExpression) { + formParameter("owners", ownersExpression); + } + + public UpdatePetWithFormUrlEncodedSendActionBuilder nicknames(String...nicknames) { + formParameter("nicknames", nicknames); + return this; + } + + public void setNicknames(String...nicknames) { + formParameter("nicknames", nicknames); + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class UpdatePetWithFormUrlEncodedReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "PUT"; + + private static final String ENDPOINT = "/api/v3/ext/pet/form/{petId}"; + + private static final String OPERATION_NAME = "updatePetWithFormUrlEncoded"; + + public UpdatePetWithFormUrlEncodedReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(extPetApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public UpdatePetWithFormUrlEncodedReceiveActionBuilder(ExtPetApi extPetApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(extPetApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } +} \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/spring/ExtPetStoreBeanConfiguration.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/spring/ExtPetStoreBeanConfiguration.java new file mode 100644 index 0000000000..3929d725f9 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/spring/ExtPetStoreBeanConfiguration.java @@ -0,0 +1,33 @@ +package org.citrusframework.openapi.generator.rest.extpetstore.spring; + +import java.util.List; +import org.citrusframework.endpoint.Endpoint; +import org.citrusframework.openapi.OpenApiRepository; +import org.citrusframework.openapi.OpenApiSpecification; +import org.citrusframework.openapi.testapi.ApiActionBuilderCustomizer; +import org.citrusframework.openapi.generator.rest.extpetstore.request.ExtPetApi; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.citrusframework.openapi.generator.rest.extpetstore.ExtPetStore; + + +@Configuration +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:46.194751400+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +public class ExtPetStoreBeanConfiguration { + + @Bean + public OpenApiRepository extPetStoreOpenApiRepository() { + var openApiRepository = new OpenApiRepository(); + openApiRepository.getOpenApiSpecifications().add(OpenApiSpecification.from( + ExtPetStore.extPetStoreApi())); + return openApiRepository; + } + + @Bean(name="ExtPetApi") + public ExtPetApi extPetApi(@Qualifier("extpetstore.endpoint") Endpoint endpoint, @Autowired(required = false) List customizers) { + return new ExtPetApi(endpoint, customizers); + } + +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/spring/ExtPetStoreNamespaceHandler.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/spring/ExtPetStoreNamespaceHandler.java new file mode 100644 index 0000000000..3676ef192e --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/extpetstore/spring/ExtPetStoreNamespaceHandler.java @@ -0,0 +1,242 @@ +package org.citrusframework.openapi.generator.rest.extpetstore.spring; + +import org.citrusframework.openapi.OpenApiSpecification; +import org.citrusframework.openapi.testapi.RestApiSendMessageActionBuilder; +import org.citrusframework.openapi.testapi.RestApiReceiveMessageActionBuilder; +import org.citrusframework.openapi.generator.rest.extpetstore.request.ExtPetApi; +import org.citrusframework.openapi.testapi.spring.RestApiReceiveMessageActionParser; +import org.citrusframework.openapi.testapi.spring.RestApiSendMessageActionParser; +import org.citrusframework.openapi.generator.rest.extpetstore.ExtPetStore; +import org.citrusframework.openapi.testapi.GeneratedApi; +import org.springframework.beans.factory.xml.NamespaceHandlerSupport; + +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:46.194751400+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +public class ExtPetStoreNamespaceHandler extends NamespaceHandlerSupport { + + private final OpenApiSpecification openApiSpecification = OpenApiSpecification.from( + ExtPetStore.extPetStoreApi()); + + @Override + public void init() { + + registerOperationParsers(ExtPetApi.class,"generate-vaccination-report", "generateVaccinationReport", "/pet/vaccination/status-report", + ExtPetApi.GenerateVaccinationReportSendActionBuilder.class, + ExtPetApi.GenerateVaccinationReportReceiveActionBuilder.class, + new String[]{ "template", "reqIntVal" }, + new String[]{ "optIntVal", "optBoolVal", "optNumberVal", "optStringVal", "optDateVal", "additionalData", "schema" }); + + registerOperationParsers(ExtPetApi.class,"get-pet-by-id-with-api-key-authentication", "getPetByIdWithApiKeyAuthentication", "/secure-api-key/pet/{petId}", + ExtPetApi.GetPetByIdWithApiKeyAuthenticationSendActionBuilder.class, + ExtPetApi.GetPetByIdWithApiKeyAuthenticationReceiveActionBuilder.class, + new String[]{ "petId", "allDetails" }, + new String[]{ "details", "requesterInformation", "apiKeyQuery", "apiKeyHeader", "apiKeyCookie" }); + + registerOperationParsers(ExtPetApi.class,"get-pet-by-id-with-basic-authentication", "getPetByIdWithBasicAuthentication", "/secure-basic/pet/{petId}", + ExtPetApi.GetPetByIdWithBasicAuthenticationSendActionBuilder.class, + ExtPetApi.GetPetByIdWithBasicAuthenticationReceiveActionBuilder.class, + new String[]{ "petId", "allDetails" }, + new String[]{ "details", "requesterInformation", "basicAuthUsername", "basicAuthPassword" }); + + registerOperationParsers(ExtPetApi.class,"get-pet-by-id-with-bearer-authentication", "getPetByIdWithBearerAuthentication", "/secure-bearer/pet/{petId}", + ExtPetApi.GetPetByIdWithBearerAuthenticationSendActionBuilder.class, + ExtPetApi.GetPetByIdWithBearerAuthenticationReceiveActionBuilder.class, + new String[]{ "petId", "allDetails" }, + new String[]{ "details", "requesterInformation", "basicAuthBearer" }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-cookie", "getPetWithCookie", "/pet/{petId}", + ExtPetApi.GetPetWithCookieSendActionBuilder.class, + ExtPetApi.GetPetWithCookieReceiveActionBuilder.class, + new String[]{ "petId", "sessionId" }, + new String[]{ "optTrxId" }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-deep-object-type-query", "getPetWithDeepObjectTypeQuery", "/pet/query/deep/object", + ExtPetApi.GetPetWithDeepObjectTypeQuerySendActionBuilder.class, + ExtPetApi.GetPetWithDeepObjectTypeQueryReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-form-exploded-style-cookie", "getPetWithFormExplodedStyleCookie", "/pet/cookie/form/exploded", + ExtPetApi.GetPetWithFormExplodedStyleCookieSendActionBuilder.class, + ExtPetApi.GetPetWithFormExplodedStyleCookieReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-form-object-style-cookie", "getPetWithFormObjectStyleCookie", "/pet/cookie/form/object", + ExtPetApi.GetPetWithFormObjectStyleCookieSendActionBuilder.class, + ExtPetApi.GetPetWithFormObjectStyleCookieReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-form-style-cookie", "getPetWithFormStyleCookie", "/pet/cookie/form", + ExtPetApi.GetPetWithFormStyleCookieSendActionBuilder.class, + ExtPetApi.GetPetWithFormStyleCookieReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-form-style-exploded-object-query", "getPetWithFormStyleExplodedObjectQuery", "/pet/query/form/exploded/object", + ExtPetApi.GetPetWithFormStyleExplodedObjectQuerySendActionBuilder.class, + ExtPetApi.GetPetWithFormStyleExplodedObjectQueryReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-form-style-exploded-query", "getPetWithFormStyleExplodedQuery", "/pet/query/form/exploded", + ExtPetApi.GetPetWithFormStyleExplodedQuerySendActionBuilder.class, + ExtPetApi.GetPetWithFormStyleExplodedQueryReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-form-style-object-query", "getPetWithFormStyleObjectQuery", "/pet/query/form/object", + ExtPetApi.GetPetWithFormStyleObjectQuerySendActionBuilder.class, + ExtPetApi.GetPetWithFormStyleObjectQueryReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-form-style-query", "getPetWithFormStyleQuery", "/pet/query/form", + ExtPetApi.GetPetWithFormStyleQuerySendActionBuilder.class, + ExtPetApi.GetPetWithFormStyleQueryReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-label-style-array", "getPetWithLabelStyleArray", "/pet/label/{petId}", + ExtPetApi.GetPetWithLabelStyleArraySendActionBuilder.class, + ExtPetApi.GetPetWithLabelStyleArrayReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-label-style-array-exploded", "getPetWithLabelStyleArrayExploded", "/pet/label/exploded/{petId}", + ExtPetApi.GetPetWithLabelStyleArrayExplodedSendActionBuilder.class, + ExtPetApi.GetPetWithLabelStyleArrayExplodedReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-label-style-object", "getPetWithLabelStyleObject", "/pet/label/object/{petId}", + ExtPetApi.GetPetWithLabelStyleObjectSendActionBuilder.class, + ExtPetApi.GetPetWithLabelStyleObjectReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-label-style-object-exploded", "getPetWithLabelStyleObjectExploded", "/pet/label/exploded/object/{petId}", + ExtPetApi.GetPetWithLabelStyleObjectExplodedSendActionBuilder.class, + ExtPetApi.GetPetWithLabelStyleObjectExplodedReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-matrix-style-array", "getPetWithMatrixStyleArray", "/pet/matrix/{petId}", + ExtPetApi.GetPetWithMatrixStyleArraySendActionBuilder.class, + ExtPetApi.GetPetWithMatrixStyleArrayReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-matrix-style-array-exploded", "getPetWithMatrixStyleArrayExploded", "/pet/matrix/exploded/{petId}", + ExtPetApi.GetPetWithMatrixStyleArrayExplodedSendActionBuilder.class, + ExtPetApi.GetPetWithMatrixStyleArrayExplodedReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-matrix-style-object", "getPetWithMatrixStyleObject", "/pet/matrix/object/{petId}", + ExtPetApi.GetPetWithMatrixStyleObjectSendActionBuilder.class, + ExtPetApi.GetPetWithMatrixStyleObjectReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-matrix-style-object-exploded", "getPetWithMatrixStyleObjectExploded", "/pet/matrix/exploded/object/{petId}", + ExtPetApi.GetPetWithMatrixStyleObjectExplodedSendActionBuilder.class, + ExtPetApi.GetPetWithMatrixStyleObjectExplodedReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-simple-style-array", "getPetWithSimpleStyleArray", "/pet/simple/{petId}", + ExtPetApi.GetPetWithSimpleStyleArraySendActionBuilder.class, + ExtPetApi.GetPetWithSimpleStyleArrayReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-simple-style-array-exploded", "getPetWithSimpleStyleArrayExploded", "/pet/simple/exploded/{petId}", + ExtPetApi.GetPetWithSimpleStyleArrayExplodedSendActionBuilder.class, + ExtPetApi.GetPetWithSimpleStyleArrayExplodedReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-simple-style-exploded-header", "getPetWithSimpleStyleExplodedHeader", "/pet/header/simple/exploded", + ExtPetApi.GetPetWithSimpleStyleExplodedHeaderSendActionBuilder.class, + ExtPetApi.GetPetWithSimpleStyleExplodedHeaderReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-simple-style-exploded-object-header", "getPetWithSimpleStyleExplodedObjectHeader", "/pet/header/simple/exploded/object", + ExtPetApi.GetPetWithSimpleStyleExplodedObjectHeaderSendActionBuilder.class, + ExtPetApi.GetPetWithSimpleStyleExplodedObjectHeaderReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-simple-style-header", "getPetWithSimpleStyleHeader", "/pet/header/simple", + ExtPetApi.GetPetWithSimpleStyleHeaderSendActionBuilder.class, + ExtPetApi.GetPetWithSimpleStyleHeaderReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-simple-style-object", "getPetWithSimpleStyleObject", "/pet/simple/object/{petId}", + ExtPetApi.GetPetWithSimpleStyleObjectSendActionBuilder.class, + ExtPetApi.GetPetWithSimpleStyleObjectReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-simple-style-object-exploded", "getPetWithSimpleStyleObjectExploded", "/pet/simple/exploded/object/{petId}", + ExtPetApi.GetPetWithSimpleStyleObjectExplodedSendActionBuilder.class, + ExtPetApi.GetPetWithSimpleStyleObjectExplodedReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"get-pet-with-simple-style-object-header", "getPetWithSimpleStyleObjectHeader", "/pet/header/simple/object", + ExtPetApi.GetPetWithSimpleStyleObjectHeaderSendActionBuilder.class, + ExtPetApi.GetPetWithSimpleStyleObjectHeaderReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"post-vaccination-document", "postVaccinationDocument", "/pet/vaccination/{bucket}/{filename}", + ExtPetApi.PostVaccinationDocumentSendActionBuilder.class, + ExtPetApi.PostVaccinationDocumentReceiveActionBuilder.class, + new String[]{ "bucket", "filename" }, + new String[]{ }); + + registerOperationParsers(ExtPetApi.class,"post-vaccination-form-data", "postVaccinationFormData", "/pet/vaccination/form", + ExtPetApi.PostVaccinationFormDataSendActionBuilder.class, + ExtPetApi.PostVaccinationFormDataReceiveActionBuilder.class, + new String[]{ }, + new String[]{ "vaccine", "isFirstVaccination", "doseNumber", "vaccinationDate" }); + + registerOperationParsers(ExtPetApi.class,"update-pet-with-array-query-data", "updatePetWithArrayQueryData", "/pet/{petId}", + ExtPetApi.UpdatePetWithArrayQueryDataSendActionBuilder.class, + ExtPetApi.UpdatePetWithArrayQueryDataReceiveActionBuilder.class, + new String[]{ "petId", "_name", "status", "tags", "nicknames", "sampleStringHeader" }, + new String[]{ "sampleIntHeader" }); + + registerOperationParsers(ExtPetApi.class,"update-pet-with-form-url-encoded", "updatePetWithFormUrlEncoded", "/pet/form/{petId}", + ExtPetApi.UpdatePetWithFormUrlEncodedSendActionBuilder.class, + ExtPetApi.UpdatePetWithFormUrlEncodedReceiveActionBuilder.class, + new String[]{ "petId", "_name", "status", "age", "tags" }, + new String[]{ "owners", "nicknames" }); + } + + private void registerOperationParsers(Class apiClass, String elementName, String operationName, String path, + Class sendBeanClass, + Class receiveBeanClass, + String[] constructorParameters, + String[] nonConstructorParameters) { + + RestApiSendMessageActionParser sendParser = new RestApiSendMessageActionParser(openApiSpecification, operationName, + path, + apiClass, + sendBeanClass, + receiveBeanClass, + "extpetstore.endpoint"); + sendParser.setConstructorParameters(constructorParameters); + sendParser.setNonConstructorParameters(nonConstructorParameters); + registerBeanDefinitionParser("send-"+elementName, sendParser); + + RestApiReceiveMessageActionParser receiveParser = new RestApiReceiveMessageActionParser(openApiSpecification, + operationName, apiClass, receiveBeanClass, "extpetstore.endpoint"); + registerBeanDefinitionParser("receive-"+elementName, receiveParser); + } + +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/PetStore.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/PetStore.java new file mode 100644 index 0000000000..6c18492c1d --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/PetStore.java @@ -0,0 +1,11 @@ +package org.citrusframework.openapi.generator.rest.petstore; + +import java.net.URL; + +public class PetStore { + + public static URL petStoreApi() { + return PetStore.class.getResource("petStore_openApi.yaml"); + } + +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/Address.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/Address.java new file mode 100644 index 0000000000..dd280d1b47 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/Address.java @@ -0,0 +1,171 @@ +/* +* Copyright the original author or authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.citrusframework.openapi.generator.rest.petstore.model; + +import java.util.Objects; +import java.util.Arrays; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + * Address + */ +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:45.597236600+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +public class Address { + private String street; + + private String city; + + private String state; + + private String zip; + + public Address() { + } + + public Address street(String street) { + + this.street = street; + return this; + } + + /** + * Get street + * @return street + **/ + @jakarta.annotation.Nullable + + public String getStreet() { + return street; + } + + + public void setStreet(String street) { + this.street = street; + } + + + public Address city(String city) { + + this.city = city; + return this; + } + + /** + * Get city + * @return city + **/ + @jakarta.annotation.Nullable + + public String getCity() { + return city; + } + + + public void setCity(String city) { + this.city = city; + } + + + public Address state(String state) { + + this.state = state; + return this; + } + + /** + * Get state + * @return state + **/ + @jakarta.annotation.Nullable + + public String getState() { + return state; + } + + + public void setState(String state) { + this.state = state; + } + + + public Address zip(String zip) { + + this.zip = zip; + return this; + } + + /** + * Get zip + * @return zip + **/ + @jakarta.annotation.Nullable + + public String getZip() { + return zip; + } + + + public void setZip(String zip) { + this.zip = zip; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Address address = (Address) o; + return Objects.equals(this.street, address.street) && + Objects.equals(this.city, address.city) && + Objects.equals(this.state, address.state) && + Objects.equals(this.zip, address.zip); + } + + @Override + public int hashCode() { + return Objects.hash(street, city, state, zip); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Address {\n"); + sb.append(" street: ").append(toIndentedString(street)).append("\n"); + sb.append(" city: ").append(toIndentedString(city)).append("\n"); + sb.append(" state: ").append(toIndentedString(state)).append("\n"); + sb.append(" zip: ").append(toIndentedString(zip)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/model/Category.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/Category.java similarity index 94% rename from test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/model/Category.java rename to test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/Category.java index e53e2d9247..15ad5a078c 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/model/Category.java +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/Category.java @@ -22,9 +22,9 @@ import io.swagger.annotations.ApiModelProperty; /** - * A category for a pet + * Category */ -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:45.610010900+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:45.597236600+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") public class Category { private Long id; diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/Customer.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/Customer.java new file mode 100644 index 0000000000..6e9a6cb7ca --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/Customer.java @@ -0,0 +1,157 @@ +/* +* Copyright the original author or authors. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.citrusframework.openapi.generator.rest.petstore.model; + +import java.util.Objects; +import java.util.Arrays; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.citrusframework.openapi.generator.rest.petstore.model.Address; + +/** + * Customer + */ +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:45.597236600+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +public class Customer { + private Long id; + + private String username; + + private List
    address = new ArrayList<>(); + + public Customer() { + } + + public Customer id(Long id) { + + this.id = id; + return this; + } + + /** + * Get id + * @return id + **/ + @jakarta.annotation.Nullable + + public Long getId() { + return id; + } + + + public void setId(Long id) { + this.id = id; + } + + + public Customer username(String username) { + + this.username = username; + return this; + } + + /** + * Get username + * @return username + **/ + @jakarta.annotation.Nullable + + public String getUsername() { + return username; + } + + + public void setUsername(String username) { + this.username = username; + } + + + public Customer address(List
    address) { + + this.address = address; + return this; + } + + public Customer addAddressItem(Address addressItem) { + if (this.address == null) { + this.address = new ArrayList<>(); + } + this.address.add(addressItem); + return this; + } + + /** + * Get address + * @return address + **/ + @jakarta.annotation.Nullable + + public List
    getAddress() { + return address; + } + + + public void setAddress(List
    address) { + this.address = address; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Customer customer = (Customer) o; + return Objects.equals(this.id, customer.id) && + Objects.equals(this.username, customer.username) && + Objects.equals(this.address, customer.address); + } + + @Override + public int hashCode() { + return Objects.hash(id, username, address); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Customer {\n"); + sb.append(" id: ").append(toIndentedString(id)).append("\n"); + sb.append(" username: ").append(toIndentedString(username)).append("\n"); + sb.append(" address: ").append(toIndentedString(address)).append("\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + if (o == null) { + return "null"; + } + return o.toString().replace("\n", "\n "); + } + +} + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/model/ModelApiResponse.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/ModelApiResponse.java similarity index 71% rename from test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/model/ModelApiResponse.java rename to test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/ModelApiResponse.java index c75502f466..9d60ff92ad 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/model/ModelApiResponse.java +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/ModelApiResponse.java @@ -22,15 +22,15 @@ import io.swagger.annotations.ApiModelProperty; /** - * Describes the result of uploading an image resource + * ModelApiResponse */ -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:45.610010900+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:45.597236600+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") public class ModelApiResponse { private Integer code; - private String _type; + private String type; - private String message; + private String _message; public ModelApiResponse() { } @@ -57,47 +57,47 @@ public void setCode(Integer code) { } - public ModelApiResponse _type(String _type) { + public ModelApiResponse type(String type) { - this._type = _type; + this.type = type; return this; } /** - * Get _type - * @return _type + * Get type + * @return type **/ @jakarta.annotation.Nullable public String getType() { - return _type; + return type; } - public void setType(String _type) { - this._type = _type; + public void setType(String type) { + this.type = type; } - public ModelApiResponse message(String message) { + public ModelApiResponse _message(String _message) { - this.message = message; + this._message = _message; return this; } /** - * Get message - * @return message + * Get _message + * @return _message **/ @jakarta.annotation.Nullable public String getMessage() { - return message; + return _message; } - public void setMessage(String message) { - this.message = message; + public void setMessage(String _message) { + this._message = _message; } @Override @@ -110,13 +110,13 @@ public boolean equals(Object o) { } ModelApiResponse _apiResponse = (ModelApiResponse) o; return Objects.equals(this.code, _apiResponse.code) && - Objects.equals(this._type, _apiResponse._type) && - Objects.equals(this.message, _apiResponse.message); + Objects.equals(this.type, _apiResponse.type) && + Objects.equals(this._message, _apiResponse._message); } @Override public int hashCode() { - return Objects.hash(code, _type, message); + return Objects.hash(code, type, _message); } @Override @@ -124,8 +124,8 @@ public String toString() { StringBuilder sb = new StringBuilder(); sb.append("class ModelApiResponse {\n"); sb.append(" code: ").append(toIndentedString(code)).append("\n"); - sb.append(" _type: ").append(toIndentedString(_type)).append("\n"); - sb.append(" message: ").append(toIndentedString(message)).append("\n"); + sb.append(" type: ").append(toIndentedString(type)).append("\n"); + sb.append(" _message: ").append(toIndentedString(_message)).append("\n"); sb.append("}"); return sb.toString(); } diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/model/Order.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/Order.java similarity index 96% rename from test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/model/Order.java rename to test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/Order.java index e35a75223b..b97c340cc5 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/model/Order.java +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/Order.java @@ -23,9 +23,9 @@ import java.time.OffsetDateTime; /** - * An order for a pets from the pet store + * Order */ -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:45.610010900+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:45.597236600+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") public class Order { private Long id; @@ -72,7 +72,7 @@ public static StatusEnum fromValue(String value) { private StatusEnum status; - private Boolean complete = false; + private Boolean complete; public Order() { } diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/model/Pet.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/Pet.java similarity index 96% rename from test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/model/Pet.java rename to test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/Pet.java index ae8a438c5a..1bd1bebb69 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/model/Pet.java +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/Pet.java @@ -27,16 +27,16 @@ import org.citrusframework.openapi.generator.rest.petstore.model.Tag; /** - * A pet for sale in the pet store + * Pet */ -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:45.610010900+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:45.597236600+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") public class Pet { private Long id; - private Category category; - private String _name; + private Category category; + private List photoUrls = new ArrayList<>(); private List tags = new ArrayList<>(); @@ -103,47 +103,47 @@ public void setId(Long id) { } - public Pet category(Category category) { + public Pet _name(String _name) { - this.category = category; + this._name = _name; return this; } /** - * Get category - * @return category + * Get _name + * @return _name **/ - @jakarta.annotation.Nullable + @jakarta.annotation.Nonnull - public Category getCategory() { - return category; + public String getName() { + return _name; } - public void setCategory(Category category) { - this.category = category; + public void setName(String _name) { + this._name = _name; } - public Pet _name(String _name) { + public Pet category(Category category) { - this._name = _name; + this.category = category; return this; } /** - * Get _name - * @return _name + * Get category + * @return category **/ - @jakarta.annotation.Nonnull + @jakarta.annotation.Nullable - public String getName() { - return _name; + public Category getCategory() { + return category; } - public void setName(String _name) { - this._name = _name; + public void setCategory(Category category) { + this.category = category; } @@ -238,8 +238,8 @@ public boolean equals(Object o) { } Pet pet = (Pet) o; return Objects.equals(this.id, pet.id) && - Objects.equals(this.category, pet.category) && Objects.equals(this._name, pet._name) && + Objects.equals(this.category, pet.category) && Objects.equals(this.photoUrls, pet.photoUrls) && Objects.equals(this.tags, pet.tags) && Objects.equals(this.status, pet.status); @@ -247,7 +247,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(id, category, _name, photoUrls, tags, status); + return Objects.hash(id, _name, category, photoUrls, tags, status); } @Override @@ -255,8 +255,8 @@ public String toString() { StringBuilder sb = new StringBuilder(); sb.append("class Pet {\n"); sb.append(" id: ").append(toIndentedString(id)).append("\n"); - sb.append(" category: ").append(toIndentedString(category)).append("\n"); sb.append(" _name: ").append(toIndentedString(_name)).append("\n"); + sb.append(" category: ").append(toIndentedString(category)).append("\n"); sb.append(" photoUrls: ").append(toIndentedString(photoUrls)).append("\n"); sb.append(" tags: ").append(toIndentedString(tags)).append("\n"); sb.append(" status: ").append(toIndentedString(status)).append("\n"); diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/model/Tag.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/Tag.java similarity index 94% rename from test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/model/Tag.java rename to test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/Tag.java index aefcc664e3..90947c523b 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/model/Tag.java +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/Tag.java @@ -22,9 +22,9 @@ import io.swagger.annotations.ApiModelProperty; /** - * A tag for a pet + * Tag */ -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:45.610010900+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:45.597236600+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") public class Tag { private Long id; diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/model/User.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/User.java similarity index 96% rename from test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/model/User.java rename to test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/User.java index 3581497dda..ae722fc9d2 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/model/User.java +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/model/User.java @@ -22,9 +22,9 @@ import io.swagger.annotations.ApiModelProperty; /** - * A User who is purchasing from the pet store + * User */ -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:45.610010900+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:45.597236600+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") public class User { private Long id; diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/request/PetApi.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/request/PetApi.java new file mode 100644 index 0000000000..7f10ddeb85 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/request/PetApi.java @@ -0,0 +1,914 @@ +package org.citrusframework.openapi.generator.rest.petstore.request; + +import static java.lang.String.format; +import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; +import static org.citrusframework.util.StringUtils.isEmpty; +import static org.citrusframework.util.StringUtils.isNotEmpty; + +import jakarta.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.net.URL; +import java.time.LocalDate; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; +import java.util.List; +import org.citrusframework.actions.ReceiveMessageAction; +import org.citrusframework.actions.SendMessageAction; +import org.citrusframework.endpoint.Endpoint; +import org.citrusframework.openapi.OpenApiSpecification; +import org.citrusframework.openapi.testapi.ApiActionBuilderCustomizer; +import org.citrusframework.openapi.testapi.ParameterStyle; +import org.citrusframework.openapi.testapi.RestApiSendMessageActionBuilder; +import org.citrusframework.openapi.testapi.RestApiReceiveMessageActionBuilder; +import org.citrusframework.openapi.testapi.TestApiUtils; +import org.citrusframework.spi.Resource; +import org.citrusframework.openapi.testapi.GeneratedApi; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; + +import org.citrusframework.openapi.generator.rest.petstore.PetStore; +import org.citrusframework.openapi.generator.rest.petstore.model.*; + +@SuppressWarnings("unused") +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:45.597236600+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +public class PetApi implements GeneratedApi +{ + + @Value("${" + "petstore.base64-encode-api-key:#{false}}") + private boolean base64EncodeApiKey; + + @Value("${" + "petstore.api-key:#{null}}") + private String defaultApiKey; + + private final List customizers; + + private final Endpoint endpoint; + + private final OpenApiSpecification openApiSpecification; + + public PetApi(Endpoint endpoint) { + this(endpoint, emptyList()); + } + + public PetApi(Endpoint endpoint, List customizers) { + this.endpoint = endpoint; + this.customizers = customizers; + + URL resource = PetStore.class.getResource("petStore_openApi.yaml"); + if (resource == null) { + throw new IllegalStateException(format("Cannot find resource '%s'. This resource is typically created during API generation and should therefore be present. Check API generation.", "petStore_openApi.yaml")); + } + openApiSpecification = OpenApiSpecification.from(resource); + } + + public static PetApi petApi(Endpoint endpoint) { + return new PetApi(endpoint); + } + + @Override + public String getApiTitle() { + return "Swagger Petstore - OpenAPI 3.0"; + } + + @Override + public String getApiVersion() { + return "1.0.19"; + } + + @Override + public String getApiPrefix() { + return "petStore"; + } + + @Override + public Map getApiInfoExtensions() { + return emptyMap(); + } + + @Override + public Endpoint getEndpoint() { + return endpoint; + } + + @Override + public List getCustomizers() { + return customizers; + } + + /** + * Builder with type safe required parameters. + */ + public AddPetSendActionBuilder sendAddPet() { + return new AddPetSendActionBuilder(this, openApiSpecification); + } + + public AddPetReceiveActionBuilder receiveAddPet(@NotNull HttpStatus statusCode) { + return new AddPetReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public AddPetReceiveActionBuilder receiveAddPet(@NotNull String statusCode) { + return new AddPetReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public DeletePetSendActionBuilder sendDeletePet(Long petId) { + return new DeletePetSendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public DeletePetSendActionBuilder sendDeletePet$(String petIdExpression ) { + return new DeletePetSendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public DeletePetReceiveActionBuilder receiveDeletePet(@NotNull HttpStatus statusCode) { + return new DeletePetReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public DeletePetReceiveActionBuilder receiveDeletePet(@NotNull String statusCode) { + return new DeletePetReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public FindPetsByStatusSendActionBuilder sendFindPetsByStatus() { + return new FindPetsByStatusSendActionBuilder(this, openApiSpecification); + } + + public FindPetsByStatusReceiveActionBuilder receiveFindPetsByStatus(@NotNull HttpStatus statusCode) { + return new FindPetsByStatusReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public FindPetsByStatusReceiveActionBuilder receiveFindPetsByStatus(@NotNull String statusCode) { + return new FindPetsByStatusReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public FindPetsByTagsSendActionBuilder sendFindPetsByTags() { + return new FindPetsByTagsSendActionBuilder(this, openApiSpecification); + } + + public FindPetsByTagsReceiveActionBuilder receiveFindPetsByTags(@NotNull HttpStatus statusCode) { + return new FindPetsByTagsReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public FindPetsByTagsReceiveActionBuilder receiveFindPetsByTags(@NotNull String statusCode) { + return new FindPetsByTagsReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetPetByIdSendActionBuilder sendGetPetById(Long petId) { + GetPetByIdSendActionBuilder builder = new GetPetByIdSendActionBuilder(this, openApiSpecification, petId); + builder.setBase64EncodeApiKey(base64EncodeApiKey); + return builder; + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetPetByIdSendActionBuilder sendGetPetById$(String petIdExpression ) { + GetPetByIdSendActionBuilder builder = new GetPetByIdSendActionBuilder(openApiSpecification, this, petIdExpression); + builder.setBase64EncodeApiKey(base64EncodeApiKey); + builder.setApiKey(defaultApiKey); + return builder; + } + + public GetPetByIdReceiveActionBuilder receiveGetPetById(@NotNull HttpStatus statusCode) { + return new GetPetByIdReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetPetByIdReceiveActionBuilder receiveGetPetById(@NotNull String statusCode) { + return new GetPetByIdReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public UpdatePetSendActionBuilder sendUpdatePet() { + return new UpdatePetSendActionBuilder(this, openApiSpecification); + } + + public UpdatePetReceiveActionBuilder receiveUpdatePet(@NotNull HttpStatus statusCode) { + return new UpdatePetReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public UpdatePetReceiveActionBuilder receiveUpdatePet(@NotNull String statusCode) { + return new UpdatePetReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public UpdatePetWithFormSendActionBuilder sendUpdatePetWithForm(Long petId) { + return new UpdatePetWithFormSendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public UpdatePetWithFormSendActionBuilder sendUpdatePetWithForm$(String petIdExpression ) { + return new UpdatePetWithFormSendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public UpdatePetWithFormReceiveActionBuilder receiveUpdatePetWithForm(@NotNull HttpStatus statusCode) { + return new UpdatePetWithFormReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public UpdatePetWithFormReceiveActionBuilder receiveUpdatePetWithForm(@NotNull String statusCode) { + return new UpdatePetWithFormReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public UploadFileSendActionBuilder sendUploadFile(Long petId) { + return new UploadFileSendActionBuilder(this, openApiSpecification, petId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public UploadFileSendActionBuilder sendUploadFile$(String petIdExpression ) { + return new UploadFileSendActionBuilder(openApiSpecification, this, petIdExpression); + } + + public UploadFileReceiveActionBuilder receiveUploadFile(@NotNull HttpStatus statusCode) { + return new UploadFileReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public UploadFileReceiveActionBuilder receiveUploadFile(@NotNull String statusCode) { + return new UploadFileReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + public static class AddPetSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "POST"; + + private static final String ENDPOINT = "/api/v3/pet"; + + private static final String OPERATION_NAME = "addPet"; + + /** + * Constructor with type safe required parameters. + */ + public AddPetSendActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification) { + super(petApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + } + + public AddPetSendActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder) { + super(petApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class AddPetReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "POST"; + + private static final String ENDPOINT = "/api/v3/pet"; + + private static final String OPERATION_NAME = "addPet"; + + public AddPetReceiveActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(petApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public AddPetReceiveActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(petApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class DeletePetSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "DELETE"; + + private static final String ENDPOINT = "/api/v3/pet/{petId}"; + + private static final String OPERATION_NAME = "deletePet"; + + /** + * Constructor with type safe required parameters. + */ + public DeletePetSendActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, Long petId) { + super(petApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public DeletePetSendActionBuilder(OpenApiSpecification openApiSpecification, PetApi petApi, String petIdExpression) { + super(petApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public DeletePetSendActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression) { + super(petApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + } + + public DeletePetSendActionBuilder petId(Long petId) { + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + return this; + } + + public DeletePetSendActionBuilder petId(String petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + return this; + } + + public DeletePetSendActionBuilder apiKey(String apiKey) { + headerParameter("api_key", apiKey, ParameterStyle.SIMPLE, false, false); + return this; + } + + public void setApiKey(String apiKey) { + headerParameter("api_key", apiKey, ParameterStyle.SIMPLE, false, false); + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class DeletePetReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "DELETE"; + + private static final String ENDPOINT = "/api/v3/pet/{petId}"; + + private static final String OPERATION_NAME = "deletePet"; + + public DeletePetReceiveActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(petApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public DeletePetReceiveActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(petApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class FindPetsByStatusSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/pet/findByStatus"; + + private static final String OPERATION_NAME = "findPetsByStatus"; + + /** + * Constructor with type safe required parameters. + */ + public FindPetsByStatusSendActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification) { + super(petApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + } + + public FindPetsByStatusSendActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder) { + super(petApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + public FindPetsByStatusSendActionBuilder status(String status) { + queryParameter("status", status, ParameterStyle.FORM, true, false); + return this; + } + + public void setStatus(String status) { + queryParameter("status", status, ParameterStyle.FORM, true, false); + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class FindPetsByStatusReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/pet/findByStatus"; + + private static final String OPERATION_NAME = "findPetsByStatus"; + + public FindPetsByStatusReceiveActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(petApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public FindPetsByStatusReceiveActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(petApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class FindPetsByTagsSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/pet/findByTags"; + + private static final String OPERATION_NAME = "findPetsByTags"; + + /** + * Constructor with type safe required parameters. + */ + public FindPetsByTagsSendActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification) { + super(petApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + } + + public FindPetsByTagsSendActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder) { + super(petApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + public FindPetsByTagsSendActionBuilder tags(String...tags) { + queryParameter("tags", tags, ParameterStyle.FORM, true, false); + return this; + } + + public void setTags(String...tags) { + queryParameter("tags", tags, ParameterStyle.FORM, true, false); + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class FindPetsByTagsReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/pet/findByTags"; + + private static final String OPERATION_NAME = "findPetsByTags"; + + public FindPetsByTagsReceiveActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(petApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public FindPetsByTagsReceiveActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(petApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetPetByIdSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/pet/{petId}"; + + private static final String OPERATION_NAME = "getPetById"; + + @Value("${" + "petstore.base64-encode-api-key:#{false}}") + private boolean base64EncodeApiKey; + + @Value("${" + "petstore.api-key:#{null}}") + private String defaultApiKey; + + private String apiKey; + + /** + * Constructor with type safe required parameters. + */ + public GetPetByIdSendActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, Long petId) { + super(petApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetByIdSendActionBuilder(OpenApiSpecification openApiSpecification, PetApi petApi, String petIdExpression) { + super(petApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetPetByIdSendActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression) { + super(petApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + } + + public GetPetByIdSendActionBuilder petId(Long petId) { + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + return this; + } + + public GetPetByIdSendActionBuilder petId(String petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + return this; + } + + public void setBase64EncodeApiKey(boolean encode) { + this.base64EncodeApiKey = encode; + } + + public GetPetByIdSendActionBuilder apiKey(String apiKey) { + this.apiKey = apiKey; + return this; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + @Override + public SendMessageAction doBuild() { + headerParameter("api_key", getOrDefault(apiKey, defaultApiKey, base64EncodeApiKey)); + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetPetByIdReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/pet/{petId}"; + + private static final String OPERATION_NAME = "getPetById"; + + public GetPetByIdReceiveActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(petApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetPetByIdReceiveActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(petApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class UpdatePetSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "PUT"; + + private static final String ENDPOINT = "/api/v3/pet"; + + private static final String OPERATION_NAME = "updatePet"; + + /** + * Constructor with type safe required parameters. + */ + public UpdatePetSendActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification) { + super(petApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + } + + public UpdatePetSendActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder) { + super(petApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class UpdatePetReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "PUT"; + + private static final String ENDPOINT = "/api/v3/pet"; + + private static final String OPERATION_NAME = "updatePet"; + + public UpdatePetReceiveActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(petApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public UpdatePetReceiveActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(petApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class UpdatePetWithFormSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "POST"; + + private static final String ENDPOINT = "/api/v3/pet/{petId}"; + + private static final String OPERATION_NAME = "updatePetWithForm"; + + /** + * Constructor with type safe required parameters. + */ + public UpdatePetWithFormSendActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, Long petId) { + super(petApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public UpdatePetWithFormSendActionBuilder(OpenApiSpecification openApiSpecification, PetApi petApi, String petIdExpression) { + super(petApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public UpdatePetWithFormSendActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression) { + super(petApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + } + + public UpdatePetWithFormSendActionBuilder petId(Long petId) { + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + return this; + } + + public UpdatePetWithFormSendActionBuilder petId(String petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + return this; + } + + public UpdatePetWithFormSendActionBuilder _name(String _name) { + queryParameter("name", _name, ParameterStyle.FORM, true, false); + return this; + } + + public void set_name(String _name) { + queryParameter("name", _name, ParameterStyle.FORM, true, false); + } + + public UpdatePetWithFormSendActionBuilder status(String status) { + queryParameter("status", status, ParameterStyle.FORM, true, false); + return this; + } + + public void setStatus(String status) { + queryParameter("status", status, ParameterStyle.FORM, true, false); + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class UpdatePetWithFormReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "POST"; + + private static final String ENDPOINT = "/api/v3/pet/{petId}"; + + private static final String OPERATION_NAME = "updatePetWithForm"; + + public UpdatePetWithFormReceiveActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(petApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public UpdatePetWithFormReceiveActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(petApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class UploadFileSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "POST"; + + private static final String ENDPOINT = "/api/v3/pet/{petId}/uploadImage"; + + private static final String OPERATION_NAME = "uploadFile"; + + /** + * Constructor with type safe required parameters. + */ + public UploadFileSendActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, Long petId) { + super(petApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public UploadFileSendActionBuilder(OpenApiSpecification openApiSpecification, PetApi petApi, String petIdExpression) { + super(petApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public UploadFileSendActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String petIdExpression) { + super(petApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + } + + public UploadFileSendActionBuilder petId(Long petId) { + pathParameter("petId", petId, ParameterStyle.SIMPLE, false, false); + return this; + } + + public UploadFileSendActionBuilder petId(String petIdExpression) { + pathParameter("petId", petIdExpression, ParameterStyle.SIMPLE, false, false); + return this; + } + + public UploadFileSendActionBuilder additionalMetadata(String additionalMetadata) { + queryParameter("additionalMetadata", additionalMetadata, ParameterStyle.FORM, true, false); + return this; + } + + public void setAdditionalMetadata(String additionalMetadata) { + queryParameter("additionalMetadata", additionalMetadata, ParameterStyle.FORM, true, false); + } + + public UploadFileSendActionBuilder body(Resource body) { + return this; + } + + public void setBody(Resource body) { + } + + public UploadFileSendActionBuilder body(String bodyExpression) { + return this; + } + + public void setBody(String bodyExpression) { + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class UploadFileReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "POST"; + + private static final String ENDPOINT = "/api/v3/pet/{petId}/uploadImage"; + + private static final String OPERATION_NAME = "uploadFile"; + + public UploadFileReceiveActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(petApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public UploadFileReceiveActionBuilder(PetApi petApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(petApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } +} \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/request/StoreApi.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/request/StoreApi.java new file mode 100644 index 0000000000..449c9b4189 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/request/StoreApi.java @@ -0,0 +1,497 @@ +package org.citrusframework.openapi.generator.rest.petstore.request; + +import static java.lang.String.format; +import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; +import static org.citrusframework.util.StringUtils.isEmpty; +import static org.citrusframework.util.StringUtils.isNotEmpty; + +import jakarta.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.net.URL; +import java.time.LocalDate; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; +import java.util.List; +import org.citrusframework.actions.ReceiveMessageAction; +import org.citrusframework.actions.SendMessageAction; +import org.citrusframework.endpoint.Endpoint; +import org.citrusframework.openapi.OpenApiSpecification; +import org.citrusframework.openapi.testapi.ApiActionBuilderCustomizer; +import org.citrusframework.openapi.testapi.ParameterStyle; +import org.citrusframework.openapi.testapi.RestApiSendMessageActionBuilder; +import org.citrusframework.openapi.testapi.RestApiReceiveMessageActionBuilder; +import org.citrusframework.openapi.testapi.TestApiUtils; +import org.citrusframework.spi.Resource; +import org.citrusframework.openapi.testapi.GeneratedApi; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; + +import org.citrusframework.openapi.generator.rest.petstore.PetStore; +import org.citrusframework.openapi.generator.rest.petstore.model.*; + +@SuppressWarnings("unused") +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:45.597236600+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +public class StoreApi implements GeneratedApi +{ + + @Value("${" + "petstore.base64-encode-api-key:#{false}}") + private boolean base64EncodeApiKey; + + @Value("${" + "petstore.api-key:#{null}}") + private String defaultApiKey; + + private final List customizers; + + private final Endpoint endpoint; + + private final OpenApiSpecification openApiSpecification; + + public StoreApi(Endpoint endpoint) { + this(endpoint, emptyList()); + } + + public StoreApi(Endpoint endpoint, List customizers) { + this.endpoint = endpoint; + this.customizers = customizers; + + URL resource = PetStore.class.getResource("petStore_openApi.yaml"); + if (resource == null) { + throw new IllegalStateException(format("Cannot find resource '%s'. This resource is typically created during API generation and should therefore be present. Check API generation.", "petStore_openApi.yaml")); + } + openApiSpecification = OpenApiSpecification.from(resource); + } + + public static StoreApi storeApi(Endpoint endpoint) { + return new StoreApi(endpoint); + } + + @Override + public String getApiTitle() { + return "Swagger Petstore - OpenAPI 3.0"; + } + + @Override + public String getApiVersion() { + return "1.0.19"; + } + + @Override + public String getApiPrefix() { + return "petStore"; + } + + @Override + public Map getApiInfoExtensions() { + return emptyMap(); + } + + @Override + public Endpoint getEndpoint() { + return endpoint; + } + + @Override + public List getCustomizers() { + return customizers; + } + + /** + * Builder with type safe required parameters. + */ + public DeleteOrderSendActionBuilder sendDeleteOrder(Long orderId) { + return new DeleteOrderSendActionBuilder(this, openApiSpecification, orderId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public DeleteOrderSendActionBuilder sendDeleteOrder$(String orderIdExpression ) { + return new DeleteOrderSendActionBuilder(openApiSpecification, this, orderIdExpression); + } + + public DeleteOrderReceiveActionBuilder receiveDeleteOrder(@NotNull HttpStatus statusCode) { + return new DeleteOrderReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public DeleteOrderReceiveActionBuilder receiveDeleteOrder(@NotNull String statusCode) { + return new DeleteOrderReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetInventorySendActionBuilder sendGetInventory() { + GetInventorySendActionBuilder builder = new GetInventorySendActionBuilder(this, openApiSpecification); + builder.setBase64EncodeApiKey(base64EncodeApiKey); + return builder; + } + + public GetInventoryReceiveActionBuilder receiveGetInventory(@NotNull HttpStatus statusCode) { + return new GetInventoryReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetInventoryReceiveActionBuilder receiveGetInventory(@NotNull String statusCode) { + return new GetInventoryReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetOrderByIdSendActionBuilder sendGetOrderById(Long orderId) { + return new GetOrderByIdSendActionBuilder(this, openApiSpecification, orderId); + } + + /** + * Builder with required parameters as string to allow for dynamic content. + */ + public GetOrderByIdSendActionBuilder sendGetOrderById$(String orderIdExpression ) { + return new GetOrderByIdSendActionBuilder(openApiSpecification, this, orderIdExpression); + } + + public GetOrderByIdReceiveActionBuilder receiveGetOrderById(@NotNull HttpStatus statusCode) { + return new GetOrderByIdReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetOrderByIdReceiveActionBuilder receiveGetOrderById(@NotNull String statusCode) { + return new GetOrderByIdReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public PlaceOrderSendActionBuilder sendPlaceOrder() { + return new PlaceOrderSendActionBuilder(this, openApiSpecification); + } + + public PlaceOrderReceiveActionBuilder receivePlaceOrder(@NotNull HttpStatus statusCode) { + return new PlaceOrderReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public PlaceOrderReceiveActionBuilder receivePlaceOrder(@NotNull String statusCode) { + return new PlaceOrderReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + public static class DeleteOrderSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "DELETE"; + + private static final String ENDPOINT = "/api/v3/store/order/{orderId}"; + + private static final String OPERATION_NAME = "deleteOrder"; + + /** + * Constructor with type safe required parameters. + */ + public DeleteOrderSendActionBuilder(StoreApi storeApi, OpenApiSpecification openApiSpecification, Long orderId) { + super(storeApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("orderId", orderId, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public DeleteOrderSendActionBuilder(OpenApiSpecification openApiSpecification, StoreApi storeApi, String orderIdExpression) { + super(storeApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("orderId", orderIdExpression, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public DeleteOrderSendActionBuilder(StoreApi storeApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String orderIdExpression) { + super(storeApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("orderId", orderIdExpression, ParameterStyle.SIMPLE, false, false); + } + + public DeleteOrderSendActionBuilder orderId(Long orderId) { + pathParameter("orderId", orderId, ParameterStyle.SIMPLE, false, false); + return this; + } + + public DeleteOrderSendActionBuilder orderId(String orderIdExpression) { + pathParameter("orderId", orderIdExpression, ParameterStyle.SIMPLE, false, false); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class DeleteOrderReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "DELETE"; + + private static final String ENDPOINT = "/api/v3/store/order/{orderId}"; + + private static final String OPERATION_NAME = "deleteOrder"; + + public DeleteOrderReceiveActionBuilder(StoreApi storeApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(storeApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public DeleteOrderReceiveActionBuilder(StoreApi storeApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(storeApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetInventorySendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/store/inventory"; + + private static final String OPERATION_NAME = "getInventory"; + + @Value("${" + "petstore.base64-encode-api-key:#{false}}") + private boolean base64EncodeApiKey; + + @Value("${" + "petstore.api-key:#{null}}") + private String defaultApiKey; + + private String apiKey; + + /** + * Constructor with type safe required parameters. + */ + public GetInventorySendActionBuilder(StoreApi storeApi, OpenApiSpecification openApiSpecification) { + super(storeApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + } + + public GetInventorySendActionBuilder(StoreApi storeApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder) { + super(storeApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + public void setBase64EncodeApiKey(boolean encode) { + this.base64EncodeApiKey = encode; + } + + public GetInventorySendActionBuilder apiKey(String apiKey) { + this.apiKey = apiKey; + return this; + } + + public void setApiKey(String apiKey) { + this.apiKey = apiKey; + } + + @Override + public SendMessageAction doBuild() { + headerParameter("api_key", getOrDefault(apiKey, defaultApiKey, base64EncodeApiKey)); + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetInventoryReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/store/inventory"; + + private static final String OPERATION_NAME = "getInventory"; + + public GetInventoryReceiveActionBuilder(StoreApi storeApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(storeApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetInventoryReceiveActionBuilder(StoreApi storeApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(storeApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetOrderByIdSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/store/order/{orderId}"; + + private static final String OPERATION_NAME = "getOrderById"; + + /** + * Constructor with type safe required parameters. + */ + public GetOrderByIdSendActionBuilder(StoreApi storeApi, OpenApiSpecification openApiSpecification, Long orderId) { + super(storeApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("orderId", orderId, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetOrderByIdSendActionBuilder(OpenApiSpecification openApiSpecification, StoreApi storeApi, String orderIdExpression) { + super(storeApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("orderId", orderIdExpression, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetOrderByIdSendActionBuilder(StoreApi storeApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String orderIdExpression) { + super(storeApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("orderId", orderIdExpression, ParameterStyle.SIMPLE, false, false); + } + + public GetOrderByIdSendActionBuilder orderId(Long orderId) { + pathParameter("orderId", orderId, ParameterStyle.SIMPLE, false, false); + return this; + } + + public GetOrderByIdSendActionBuilder orderId(String orderIdExpression) { + pathParameter("orderId", orderIdExpression, ParameterStyle.SIMPLE, false, false); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetOrderByIdReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/store/order/{orderId}"; + + private static final String OPERATION_NAME = "getOrderById"; + + public GetOrderByIdReceiveActionBuilder(StoreApi storeApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(storeApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetOrderByIdReceiveActionBuilder(StoreApi storeApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(storeApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class PlaceOrderSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "POST"; + + private static final String ENDPOINT = "/api/v3/store/order"; + + private static final String OPERATION_NAME = "placeOrder"; + + /** + * Constructor with type safe required parameters. + */ + public PlaceOrderSendActionBuilder(StoreApi storeApi, OpenApiSpecification openApiSpecification) { + super(storeApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + } + + public PlaceOrderSendActionBuilder(StoreApi storeApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder) { + super(storeApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + public PlaceOrderSendActionBuilder order(Order order) { + return this; + } + + public void setOrder(Order order) { + } + + public PlaceOrderSendActionBuilder order(String orderExpression) { + return this; + } + + public void setOrder(String orderExpression) { + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class PlaceOrderReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "POST"; + + private static final String ENDPOINT = "/api/v3/store/order"; + + private static final String OPERATION_NAME = "placeOrder"; + + public PlaceOrderReceiveActionBuilder(StoreApi storeApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(storeApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public PlaceOrderReceiveActionBuilder(StoreApi storeApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(storeApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } +} \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/request/UserApi.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/request/UserApi.java new file mode 100644 index 0000000000..2814877653 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/request/UserApi.java @@ -0,0 +1,714 @@ +package org.citrusframework.openapi.generator.rest.petstore.request; + +import static java.lang.String.format; +import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; +import static org.citrusframework.util.StringUtils.isEmpty; +import static org.citrusframework.util.StringUtils.isNotEmpty; + +import jakarta.validation.constraints.NotNull; +import java.math.BigDecimal; +import java.net.URL; +import java.time.LocalDate; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; +import java.util.List; +import org.citrusframework.actions.ReceiveMessageAction; +import org.citrusframework.actions.SendMessageAction; +import org.citrusframework.endpoint.Endpoint; +import org.citrusframework.openapi.OpenApiSpecification; +import org.citrusframework.openapi.testapi.ApiActionBuilderCustomizer; +import org.citrusframework.openapi.testapi.ParameterStyle; +import org.citrusframework.openapi.testapi.RestApiSendMessageActionBuilder; +import org.citrusframework.openapi.testapi.RestApiReceiveMessageActionBuilder; +import org.citrusframework.openapi.testapi.TestApiUtils; +import org.citrusframework.spi.Resource; +import org.citrusframework.openapi.testapi.GeneratedApi; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; + +import org.citrusframework.openapi.generator.rest.petstore.PetStore; +import org.citrusframework.openapi.generator.rest.petstore.model.*; + +@SuppressWarnings("unused") +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:45.597236600+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +public class UserApi implements GeneratedApi +{ + + @Value("${" + "petstore.base64-encode-api-key:#{false}}") + private boolean base64EncodeApiKey; + + @Value("${" + "petstore.api-key:#{null}}") + private String defaultApiKey; + + private final List customizers; + + private final Endpoint endpoint; + + private final OpenApiSpecification openApiSpecification; + + public UserApi(Endpoint endpoint) { + this(endpoint, emptyList()); + } + + public UserApi(Endpoint endpoint, List customizers) { + this.endpoint = endpoint; + this.customizers = customizers; + + URL resource = PetStore.class.getResource("petStore_openApi.yaml"); + if (resource == null) { + throw new IllegalStateException(format("Cannot find resource '%s'. This resource is typically created during API generation and should therefore be present. Check API generation.", "petStore_openApi.yaml")); + } + openApiSpecification = OpenApiSpecification.from(resource); + } + + public static UserApi userApi(Endpoint endpoint) { + return new UserApi(endpoint); + } + + @Override + public String getApiTitle() { + return "Swagger Petstore - OpenAPI 3.0"; + } + + @Override + public String getApiVersion() { + return "1.0.19"; + } + + @Override + public String getApiPrefix() { + return "petStore"; + } + + @Override + public Map getApiInfoExtensions() { + return emptyMap(); + } + + @Override + public Endpoint getEndpoint() { + return endpoint; + } + + @Override + public List getCustomizers() { + return customizers; + } + + /** + * Builder with type safe required parameters. + */ + public CreateUserSendActionBuilder sendCreateUser() { + return new CreateUserSendActionBuilder(this, openApiSpecification); + } + + public CreateUserReceiveActionBuilder receiveCreateUser(@NotNull HttpStatus statusCode) { + return new CreateUserReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public CreateUserReceiveActionBuilder receiveCreateUser(@NotNull String statusCode) { + return new CreateUserReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public CreateUsersWithListInputSendActionBuilder sendCreateUsersWithListInput() { + return new CreateUsersWithListInputSendActionBuilder(this, openApiSpecification); + } + + public CreateUsersWithListInputReceiveActionBuilder receiveCreateUsersWithListInput(@NotNull HttpStatus statusCode) { + return new CreateUsersWithListInputReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public CreateUsersWithListInputReceiveActionBuilder receiveCreateUsersWithListInput(@NotNull String statusCode) { + return new CreateUsersWithListInputReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public DeleteUserSendActionBuilder sendDeleteUser(String username) { + return new DeleteUserSendActionBuilder(this, openApiSpecification, username); + } + + public DeleteUserReceiveActionBuilder receiveDeleteUser(@NotNull HttpStatus statusCode) { + return new DeleteUserReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public DeleteUserReceiveActionBuilder receiveDeleteUser(@NotNull String statusCode) { + return new DeleteUserReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public GetUserByNameSendActionBuilder sendGetUserByName(String username) { + return new GetUserByNameSendActionBuilder(this, openApiSpecification, username); + } + + public GetUserByNameReceiveActionBuilder receiveGetUserByName(@NotNull HttpStatus statusCode) { + return new GetUserByNameReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public GetUserByNameReceiveActionBuilder receiveGetUserByName(@NotNull String statusCode) { + return new GetUserByNameReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public LoginUserSendActionBuilder sendLoginUser() { + return new LoginUserSendActionBuilder(this, openApiSpecification); + } + + public LoginUserReceiveActionBuilder receiveLoginUser(@NotNull HttpStatus statusCode) { + return new LoginUserReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public LoginUserReceiveActionBuilder receiveLoginUser(@NotNull String statusCode) { + return new LoginUserReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public LogoutUserSendActionBuilder sendLogoutUser() { + return new LogoutUserSendActionBuilder(this, openApiSpecification); + } + + public LogoutUserReceiveActionBuilder receiveLogoutUser(@NotNull HttpStatus statusCode) { + return new LogoutUserReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public LogoutUserReceiveActionBuilder receiveLogoutUser(@NotNull String statusCode) { + return new LogoutUserReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + /** + * Builder with type safe required parameters. + */ + public UpdateUserSendActionBuilder sendUpdateUser(String username) { + return new UpdateUserSendActionBuilder(this, openApiSpecification, username); + } + + public UpdateUserReceiveActionBuilder receiveUpdateUser(@NotNull HttpStatus statusCode) { + return new UpdateUserReceiveActionBuilder(this, openApiSpecification, Integer.toString(statusCode.value())); + } + + public UpdateUserReceiveActionBuilder receiveUpdateUser(@NotNull String statusCode) { + return new UpdateUserReceiveActionBuilder(this, openApiSpecification, statusCode); + } + + public static class CreateUserSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "POST"; + + private static final String ENDPOINT = "/api/v3/user"; + + private static final String OPERATION_NAME = "createUser"; + + /** + * Constructor with type safe required parameters. + */ + public CreateUserSendActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification) { + super(userApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + } + + public CreateUserSendActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder) { + super(userApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + public CreateUserSendActionBuilder user(User user) { + return this; + } + + public void setUser(User user) { + } + + public CreateUserSendActionBuilder user(String userExpression) { + return this; + } + + public void setUser(String userExpression) { + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class CreateUserReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "POST"; + + private static final String ENDPOINT = "/api/v3/user"; + + private static final String OPERATION_NAME = "createUser"; + + public CreateUserReceiveActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(userApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public CreateUserReceiveActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(userApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class CreateUsersWithListInputSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "POST"; + + private static final String ENDPOINT = "/api/v3/user/createWithList"; + + private static final String OPERATION_NAME = "createUsersWithListInput"; + + /** + * Constructor with type safe required parameters. + */ + public CreateUsersWithListInputSendActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification) { + super(userApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + } + + public CreateUsersWithListInputSendActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder) { + super(userApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + public CreateUsersWithListInputSendActionBuilder user(User...user) { + return this; + } + + public void setUser(User...user) { + } + + public CreateUsersWithListInputSendActionBuilder user(String...userExpression) { + return this; + } + + public void setUser(String...userExpression) { + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class CreateUsersWithListInputReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "POST"; + + private static final String ENDPOINT = "/api/v3/user/createWithList"; + + private static final String OPERATION_NAME = "createUsersWithListInput"; + + public CreateUsersWithListInputReceiveActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(userApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public CreateUsersWithListInputReceiveActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(userApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class DeleteUserSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "DELETE"; + + private static final String ENDPOINT = "/api/v3/user/{username}"; + + private static final String OPERATION_NAME = "deleteUser"; + + /** + * Constructor with type safe required parameters. + */ + public DeleteUserSendActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, String username) { + super(userApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("username", username, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public DeleteUserSendActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String usernameExpression) { + super(userApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("username", usernameExpression, ParameterStyle.SIMPLE, false, false); + } + + public DeleteUserSendActionBuilder username(String username) { + pathParameter("username", username, ParameterStyle.SIMPLE, false, false); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class DeleteUserReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "DELETE"; + + private static final String ENDPOINT = "/api/v3/user/{username}"; + + private static final String OPERATION_NAME = "deleteUser"; + + public DeleteUserReceiveActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(userApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public DeleteUserReceiveActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(userApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetUserByNameSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/user/{username}"; + + private static final String OPERATION_NAME = "getUserByName"; + + /** + * Constructor with type safe required parameters. + */ + public GetUserByNameSendActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, String username) { + super(userApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("username", username, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public GetUserByNameSendActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String usernameExpression) { + super(userApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("username", usernameExpression, ParameterStyle.SIMPLE, false, false); + } + + public GetUserByNameSendActionBuilder username(String username) { + pathParameter("username", username, ParameterStyle.SIMPLE, false, false); + return this; + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetUserByNameReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/user/{username}"; + + private static final String OPERATION_NAME = "getUserByName"; + + public GetUserByNameReceiveActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(userApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public GetUserByNameReceiveActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(userApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class LoginUserSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/user/login"; + + private static final String OPERATION_NAME = "loginUser"; + + /** + * Constructor with type safe required parameters. + */ + public LoginUserSendActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification) { + super(userApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + } + + public LoginUserSendActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder) { + super(userApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + public LoginUserSendActionBuilder username(String username) { + queryParameter("username", username, ParameterStyle.FORM, true, false); + return this; + } + + public void setUsername(String username) { + queryParameter("username", username, ParameterStyle.FORM, true, false); + } + + public LoginUserSendActionBuilder password(String password) { + queryParameter("password", password, ParameterStyle.FORM, true, false); + return this; + } + + public void setPassword(String password) { + queryParameter("password", password, ParameterStyle.FORM, true, false); + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class LoginUserReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/user/login"; + + private static final String OPERATION_NAME = "loginUser"; + + public LoginUserReceiveActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(userApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public LoginUserReceiveActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(userApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class LogoutUserSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/user/logout"; + + private static final String OPERATION_NAME = "logoutUser"; + + /** + * Constructor with type safe required parameters. + */ + public LogoutUserSendActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification) { + super(userApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + } + + public LogoutUserSendActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder) { + super(userApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class LogoutUserReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "GET"; + + private static final String ENDPOINT = "/api/v3/user/logout"; + + private static final String OPERATION_NAME = "logoutUser"; + + public LogoutUserReceiveActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(userApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public LogoutUserReceiveActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(userApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class UpdateUserSendActionBuilder extends + RestApiSendMessageActionBuilder { + + private static final String METHOD = "PUT"; + + private static final String ENDPOINT = "/api/v3/user/{username}"; + + private static final String OPERATION_NAME = "updateUser"; + + /** + * Constructor with type safe required parameters. + */ + public UpdateUserSendActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, String username) { + super(userApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("username", username, ParameterStyle.SIMPLE, false, false); + } + + /** + * Constructor with required parameters as string to allow for dynamic content. + */ + public UpdateUserSendActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, TestApiClientRequestMessageBuilder messageBuilder, String usernameExpression) { + super(userApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + pathParameter("username", usernameExpression, ParameterStyle.SIMPLE, false, false); + } + + public UpdateUserSendActionBuilder username(String username) { + pathParameter("username", username, ParameterStyle.SIMPLE, false, false); + return this; + } + + public UpdateUserSendActionBuilder user(User user) { + return this; + } + + public void setUser(User user) { + } + + public UpdateUserSendActionBuilder user(String userExpression) { + return this; + } + + public void setUser(String userExpression) { + } + + @Override + public SendMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class UpdateUserReceiveActionBuilder extends + RestApiReceiveMessageActionBuilder { + + private static final String METHOD = "PUT"; + + private static final String ENDPOINT = "/api/v3/user/{username}"; + + private static final String OPERATION_NAME = "updateUser"; + + public UpdateUserReceiveActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, String statusCode) { + super(userApi, openApiSpecification, METHOD, ENDPOINT, OPERATION_NAME, statusCode); + } + + public UpdateUserReceiveActionBuilder(UserApi userApi, OpenApiSpecification openApiSpecification, OpenApiClientResponseMessageBuilder messageBuilder) { + super(userApi, openApiSpecification, messageBuilder, messageBuilder.getMessage(), METHOD, ENDPOINT, OPERATION_NAME); + } + + @Override + public ReceiveMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } +} \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/spring/PetStoreBeanConfiguration.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/spring/PetStoreBeanConfiguration.java new file mode 100644 index 0000000000..7dcb02ad39 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/spring/PetStoreBeanConfiguration.java @@ -0,0 +1,45 @@ +package org.citrusframework.openapi.generator.rest.petstore.spring; + +import java.util.List; +import org.citrusframework.endpoint.Endpoint; +import org.citrusframework.openapi.OpenApiRepository; +import org.citrusframework.openapi.OpenApiSpecification; +import org.citrusframework.openapi.testapi.ApiActionBuilderCustomizer; +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.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.citrusframework.openapi.generator.rest.petstore.PetStore; + + +@Configuration +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:45.597236600+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +public class PetStoreBeanConfiguration { + + @Bean + public OpenApiRepository petStoreOpenApiRepository() { + var openApiRepository = new OpenApiRepository(); + openApiRepository.getOpenApiSpecifications().add(OpenApiSpecification.from( + PetStore.petStoreApi())); + return openApiRepository; + } + + @Bean(name="PetApi") + public PetApi petApi(@Qualifier("petstore.endpoint") Endpoint endpoint, @Autowired(required = false) List customizers) { + return new PetApi(endpoint, customizers); + } + + @Bean(name="StoreApi") + public StoreApi storeApi(@Qualifier("petstore.endpoint") Endpoint endpoint, @Autowired(required = false) List customizers) { + return new StoreApi(endpoint, customizers); + } + + @Bean(name="UserApi") + public UserApi userApi(@Qualifier("petstore.endpoint") Endpoint endpoint, @Autowired(required = false) List customizers) { + return new UserApi(endpoint, customizers); + } + +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/spring/PetStoreNamespaceHandler.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/spring/PetStoreNamespaceHandler.java new file mode 100644 index 0000000000..db8d84d5bc --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/rest/petstore/spring/PetStoreNamespaceHandler.java @@ -0,0 +1,160 @@ +package org.citrusframework.openapi.generator.rest.petstore.spring; + +import org.citrusframework.openapi.OpenApiSpecification; +import org.citrusframework.openapi.testapi.RestApiSendMessageActionBuilder; +import org.citrusframework.openapi.testapi.RestApiReceiveMessageActionBuilder; +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.testapi.spring.RestApiReceiveMessageActionParser; +import org.citrusframework.openapi.testapi.spring.RestApiSendMessageActionParser; +import org.citrusframework.openapi.generator.rest.petstore.PetStore; +import org.citrusframework.openapi.testapi.GeneratedApi; +import org.springframework.beans.factory.xml.NamespaceHandlerSupport; + +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:45.597236600+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +public class PetStoreNamespaceHandler extends NamespaceHandlerSupport { + + private final OpenApiSpecification openApiSpecification = OpenApiSpecification.from( + PetStore.petStoreApi()); + + @Override + public void init() { + + registerOperationParsers(PetApi.class,"add-pet", "addPet", "/pet", + PetApi.AddPetSendActionBuilder.class, + PetApi.AddPetReceiveActionBuilder.class, + new String[]{ }, + new String[]{ }); + + registerOperationParsers(PetApi.class,"delete-pet", "deletePet", "/pet/{petId}", + PetApi.DeletePetSendActionBuilder.class, + PetApi.DeletePetReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ "apiKey" }); + + registerOperationParsers(PetApi.class,"find-pets-by-status", "findPetsByStatus", "/pet/findByStatus", + PetApi.FindPetsByStatusSendActionBuilder.class, + PetApi.FindPetsByStatusReceiveActionBuilder.class, + new String[]{ }, + new String[]{ "status" }); + + registerOperationParsers(PetApi.class,"find-pets-by-tags", "findPetsByTags", "/pet/findByTags", + PetApi.FindPetsByTagsSendActionBuilder.class, + PetApi.FindPetsByTagsReceiveActionBuilder.class, + new String[]{ }, + new String[]{ "tags" }); + + registerOperationParsers(PetApi.class,"get-pet-by-id", "getPetById", "/pet/{petId}", + PetApi.GetPetByIdSendActionBuilder.class, + PetApi.GetPetByIdReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ "apiKey" }); + + registerOperationParsers(PetApi.class,"update-pet", "updatePet", "/pet", + PetApi.UpdatePetSendActionBuilder.class, + PetApi.UpdatePetReceiveActionBuilder.class, + new String[]{ }, + new String[]{ }); + + registerOperationParsers(PetApi.class,"update-pet-with-form", "updatePetWithForm", "/pet/{petId}", + PetApi.UpdatePetWithFormSendActionBuilder.class, + PetApi.UpdatePetWithFormReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ "_name", "status" }); + + registerOperationParsers(PetApi.class,"upload-file", "uploadFile", "/pet/{petId}/uploadImage", + PetApi.UploadFileSendActionBuilder.class, + PetApi.UploadFileReceiveActionBuilder.class, + new String[]{ "petId" }, + new String[]{ "additionalMetadata", "ERROR_UNKNOWN" }); + + registerOperationParsers(StoreApi.class,"delete-order", "deleteOrder", "/store/order/{orderId}", + StoreApi.DeleteOrderSendActionBuilder.class, + StoreApi.DeleteOrderReceiveActionBuilder.class, + new String[]{ "orderId" }, + new String[]{ }); + + registerOperationParsers(StoreApi.class,"get-inventory", "getInventory", "/store/inventory", + StoreApi.GetInventorySendActionBuilder.class, + StoreApi.GetInventoryReceiveActionBuilder.class, + new String[]{ }, + new String[]{ "apiKey" }); + + registerOperationParsers(StoreApi.class,"get-order-by-id", "getOrderById", "/store/order/{orderId}", + StoreApi.GetOrderByIdSendActionBuilder.class, + StoreApi.GetOrderByIdReceiveActionBuilder.class, + new String[]{ "orderId" }, + new String[]{ }); + + registerOperationParsers(StoreApi.class,"place-order", "placeOrder", "/store/order", + StoreApi.PlaceOrderSendActionBuilder.class, + StoreApi.PlaceOrderReceiveActionBuilder.class, + new String[]{ }, + new String[]{ "ERROR_UNKNOWN" }); + + registerOperationParsers(UserApi.class,"create-user", "createUser", "/user", + UserApi.CreateUserSendActionBuilder.class, + UserApi.CreateUserReceiveActionBuilder.class, + new String[]{ }, + new String[]{ "ERROR_UNKNOWN" }); + + registerOperationParsers(UserApi.class,"create-users-with-list-input", "createUsersWithListInput", "/user/createWithList", + UserApi.CreateUsersWithListInputSendActionBuilder.class, + UserApi.CreateUsersWithListInputReceiveActionBuilder.class, + new String[]{ }, + new String[]{ "user" }); + + registerOperationParsers(UserApi.class,"delete-user", "deleteUser", "/user/{username}", + UserApi.DeleteUserSendActionBuilder.class, + UserApi.DeleteUserReceiveActionBuilder.class, + new String[]{ "username" }, + new String[]{ }); + + registerOperationParsers(UserApi.class,"get-user-by-name", "getUserByName", "/user/{username}", + UserApi.GetUserByNameSendActionBuilder.class, + UserApi.GetUserByNameReceiveActionBuilder.class, + new String[]{ "username" }, + new String[]{ }); + + registerOperationParsers(UserApi.class,"login-user", "loginUser", "/user/login", + UserApi.LoginUserSendActionBuilder.class, + UserApi.LoginUserReceiveActionBuilder.class, + new String[]{ }, + new String[]{ "username", "password" }); + + registerOperationParsers(UserApi.class,"logout-user", "logoutUser", "/user/logout", + UserApi.LogoutUserSendActionBuilder.class, + UserApi.LogoutUserReceiveActionBuilder.class, + new String[]{ }, + new String[]{ }); + + registerOperationParsers(UserApi.class,"update-user", "updateUser", "/user/{username}", + UserApi.UpdateUserSendActionBuilder.class, + UserApi.UpdateUserReceiveActionBuilder.class, + new String[]{ "username" }, + new String[]{ "ERROR_UNKNOWN" }); + } + + private void registerOperationParsers(Class apiClass, String elementName, String operationName, String path, + Class sendBeanClass, + Class receiveBeanClass, + String[] constructorParameters, + String[] nonConstructorParameters) { + + RestApiSendMessageActionParser sendParser = new RestApiSendMessageActionParser(openApiSpecification, operationName, + path, + apiClass, + sendBeanClass, + receiveBeanClass, + "petstore.endpoint"); + sendParser.setConstructorParameters(constructorParameters); + sendParser.setNonConstructorParameters(nonConstructorParameters); + registerBeanDefinitionParser("send-"+elementName, sendParser); + + RestApiReceiveMessageActionParser receiveParser = new RestApiReceiveMessageActionParser(openApiSpecification, + operationName, apiClass, receiveBeanClass, "petstore.endpoint"); + registerBeanDefinitionParser("receive-"+elementName, receiveParser); + } + +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/soap/bookservice/request/BookServiceSoapApi.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/soap/bookservice/request/BookServiceSoapApi.java new file mode 100644 index 0000000000..9fa4b1a025 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/ExpectedCodeGenIT/expectedgen/soap/bookservice/request/BookServiceSoapApi.java @@ -0,0 +1,209 @@ +package org.citrusframework.openapi.generator.soap.bookservice.request; + +import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.citrusframework.ws.actions.ReceiveSoapMessageAction; +import org.citrusframework.ws.actions.SendSoapMessageAction; +import org.citrusframework.endpoint.Endpoint; +import org.citrusframework.openapi.testapi.ApiActionBuilderCustomizer; +import org.citrusframework.openapi.testapi.GeneratedApi; +import org.citrusframework.openapi.testapi.SoapApiReceiveMessageActionBuilder; +import org.citrusframework.openapi.testapi.SoapApiSendMessageActionBuilder; + +@SuppressWarnings("unused") +@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.CitrusJavaCodegen", date = "2024-10-05T19:07:46.419751700+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") +public class BookServiceSoapApi implements GeneratedApi +{ + + private final Endpoint endpoint; + + private final List customizers; + + public BookServiceSoapApi(Endpoint endpoint) { + this(endpoint, emptyList()); + } + + public BookServiceSoapApi(Endpoint endpoint, List customizers) { + this.endpoint = endpoint; + this.customizers = customizers; + } + + public static BookServiceSoapApi bookServiceSoapApi(Endpoint endpoint) { + return new BookServiceSoapApi(endpoint); + } + + @Override + public String getApiTitle() { + return "Generated api from wsdl"; + } + + @Override + public String getApiVersion() { + return "1.0.0"; + } + + @Override + public String getApiPrefix() { + return "BookService"; + } + + @Override + public Map getApiInfoExtensions() { + return emptyMap(); + } + + @Override + public Endpoint getEndpoint() { + return endpoint; + } + + @Override + public List getCustomizers() { + return customizers; + } + + public AddBookSendActionBuilder sendAddBook() { + return new AddBookSendActionBuilder(this); + } + + public AddBookReceiveActionBuilder receiveAddBook() { + return new AddBookReceiveActionBuilder(this); + } + + public GetAllBooksSendActionBuilder sendGetAllBooks() { + return new GetAllBooksSendActionBuilder(this); + } + + public GetAllBooksReceiveActionBuilder receiveGetAllBooks() { + return new GetAllBooksReceiveActionBuilder(this); + } + + public GetBookSendActionBuilder sendGetBook() { + return new GetBookSendActionBuilder(this); + } + + public GetBookReceiveActionBuilder receiveGetBook() { + return new GetBookReceiveActionBuilder(this); + } + + public static class AddBookSendActionBuilder extends SoapApiSendMessageActionBuilder { + + private static final String SOAP_ACTION = "http://www.citrusframework.com/BookService/AddBook"; + + public AddBookSendActionBuilder(BookServiceSoapApi bookServiceSoapApi) { + super(bookServiceSoapApi, SOAP_ACTION); + } + + @Override + public SendSoapMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class AddBookReceiveActionBuilder extends SoapApiReceiveMessageActionBuilder { + + private static final String SOAP_ACTION = "http://www.citrusframework.com/BookService/AddBook"; + + public AddBookReceiveActionBuilder(BookServiceSoapApi bookServiceSoapApi) { + super(bookServiceSoapApi, SOAP_ACTION); + } + + @Override + public ReceiveSoapMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetAllBooksSendActionBuilder extends SoapApiSendMessageActionBuilder { + + private static final String SOAP_ACTION = "http://www.citrusframework.com/BookService/GetAllBooks"; + + public GetAllBooksSendActionBuilder(BookServiceSoapApi bookServiceSoapApi) { + super(bookServiceSoapApi, SOAP_ACTION); + } + + @Override + public SendSoapMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetAllBooksReceiveActionBuilder extends SoapApiReceiveMessageActionBuilder { + + private static final String SOAP_ACTION = "http://www.citrusframework.com/BookService/GetAllBooks"; + + public GetAllBooksReceiveActionBuilder(BookServiceSoapApi bookServiceSoapApi) { + super(bookServiceSoapApi, SOAP_ACTION); + } + + @Override + public ReceiveSoapMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } + + public static class GetBookSendActionBuilder extends SoapApiSendMessageActionBuilder { + + private static final String SOAP_ACTION = "http://www.citrusframework.com/BookService/GetBook"; + + public GetBookSendActionBuilder(BookServiceSoapApi bookServiceSoapApi) { + super(bookServiceSoapApi, SOAP_ACTION); + } + + @Override + public SendSoapMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeRequestBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + } + + public static class GetBookReceiveActionBuilder extends SoapApiReceiveMessageActionBuilder { + + private static final String SOAP_ACTION = "http://www.citrusframework.com/BookService/GetBook"; + + public GetBookReceiveActionBuilder(BookServiceSoapApi bookServiceSoapApi) { + super(bookServiceSoapApi, SOAP_ACTION); + } + + @Override + public ReceiveSoapMessageAction doBuild() { + + if (getCustomizers() != null) { + getCustomizers().forEach(customizer -> customizer.customizeResponseBuilder(getGeneratedApi(), this)); + } + + return super.doBuild(); + } + + } +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/defaultOas3SchemaValidationTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/defaultOas3SchemaValidationTest.xml deleted file mode 100644 index 1784d89782..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/defaultOas3SchemaValidationTest.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/failOnReasonPhraseTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/failOnReasonPhraseTest.xml deleted file mode 100644 index 60f8dc25d0..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/failOnReasonPhraseTest.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/failOnStatusTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/failOnStatusTest.xml deleted file mode 100644 index ca47b78103..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/failOnStatusTest.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/failOnVersionTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/failOnVersionTest.xml deleted file mode 100644 index 5047fc38a0..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/failOnVersionTest.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/getPetByIdRequestTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/getPetByIdRequestTest.xml deleted file mode 100644 index c6f1afc8b5..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/getPetByIdRequestTest.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonDeactivatedSchemaValidationTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonDeactivatedSchemaValidationTest.xml deleted file mode 100644 index 7f4b46ed43..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonDeactivatedSchemaValidationTest.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonPathExtractTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonPathExtractTest.xml deleted file mode 100644 index efb6b3e5a8..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonPathExtractTest.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonPathExtractionTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonPathExtractionTest.xml deleted file mode 100644 index 2ead5c459b..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonPathExtractionTest.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonPathValidationFailureTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonPathValidationFailureTest.xml deleted file mode 100644 index 4d4bff102f..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonPathValidationFailureTest.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonPathValidationTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonPathValidationTest.xml deleted file mode 100644 index 320e32fcd9..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonPathValidationTest.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonSchemaValidationFailureTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonSchemaValidationFailureTest.xml deleted file mode 100644 index 3aeb456f25..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonSchemaValidationFailureTest.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonSchemaValidationTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonSchemaValidationTest.xml deleted file mode 100644 index 50f146bc18..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/jsonSchemaValidationTest.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/multipartWithFileAttributesTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/multipartWithFileAttributesTest.xml deleted file mode 100644 index 4e24ad3e06..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/multipartWithFileAttributesTest.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/multipartWithMultipleDatatypesTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/multipartWithMultipleDatatypesTest.xml deleted file mode 100644 index a727b3bd06..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/multipartWithMultipleDatatypesTest.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Test - true - 1 - - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/multipartWithPlainTextTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/multipartWithPlainTextTest.xml deleted file mode 100644 index a3082ee857..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/multipartWithPlainTextTest.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - ]]> - - - {"data1":"value1"} - - - {"schema":"mySchema"} - - - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/findPetsByStatus_response.json b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/findPetsByStatus_response.json new file mode 100644 index 0000000000..4e3176fe31 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/findPetsByStatus_response.json @@ -0,0 +1,38 @@ +[ + { + "id": 1, + "name": "hasso", + "category": { + "id": 2, + "name": "citrus:randomEnumValue('dog', 'cat', 'fish')" + }, + "photoUrls": [ + "http://localhost:8080/photos/${petId}" + ], + "tags": [ + { + "id": 3, + "name": "generated" + } + ], + "status": "citrus:randomEnumValue('available', 'pending', 'sold')" + }, + { + "id": 4, + "name": "fluffy", + "category": { + "id": 5, + "name": "citrus:randomEnumValue('dog', 'cat', 'fish')" + }, + "photoUrls": [ + "http://localhost:8080/photos/${petId}" + ], + "tags": [ + { + "id": 6, + "name": "generated" + } + ], + "status": "citrus:randomEnumValue('available', 'pending', 'sold')" + } +] \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json new file mode 100644 index 0000000000..53fb68a708 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response.json @@ -0,0 +1,18 @@ +{ + "id": ${petId}, + "name": "citrus:randomEnumValue('hasso','cutie','fluffy')", + "category": { + "id": ${petId}, + "name": "citrus:randomEnumValue('dog', 'cat', 'fish')" + }, + "photoUrls": [ + "http://localhost:8080/photos/${petId}" + ], + "tags": [ + { + "id": ${petId}, + "name": "generated" + } + ], + "status": "citrus:randomEnumValue('available', 'pending', 'sold')" +} \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response_validation.json b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response_validation.json new file mode 100644 index 0000000000..38b4703838 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/getPetById_response_validation.json @@ -0,0 +1,18 @@ +{ + "id": ${petId}, + "name": "@matches('hasso|cutie|fluffy')@", + "category": { + "id": ${petId}, + "name": "@matches('dog|cat|fish')@" + }, + "photoUrls": [ + "http://localhost:8080/photos/${petId}" + ], + "tags": [ + { + "id": ${petId}, + "name": "generated" + } + ], + "status": "@matches('available|pending|sold')@" +} \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/invalidGetPetById_response.json b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/invalidGetPetById_response.json new file mode 100644 index 0000000000..c1657e0b6f --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/invalidGetPetById_response.json @@ -0,0 +1,14 @@ +{ + "category": { + "name": "citrus:randomEnumValue('dog', 'cat', 'fish')" + }, + "photoUrls": [ + "http://localhost:8080/photos/${petId}" + ], + "tags": [ + { + "name": "generated" + } + ], + "status": "citrus:randomEnumValue('available', 'pending', 'sold')" +} \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/pet.json b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/pet.json new file mode 100644 index 0000000000..0d4e504a8f --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/pet.json @@ -0,0 +1,16 @@ +{ + "id": ${petId}, + "name": "citrus:randomEnumValue('hasso','cutie','fluffy')", + "category": { + "id": ${petId}, + "name": "citrus:randomEnumValue('dog', 'cat', 'fish')" + }, + "photoUrls": [ "http://localhost:8080/photos/${petId}" ], + "tags": [ + { + "id": ${petId}, + "name": "generated" + } + ], + "status": "citrus:randomEnumValue('available', 'pending', 'sold')" +} diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/thisAintNoPed.json b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/thisAintNoPed.json new file mode 100644 index 0000000000..9414dcaab0 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/thisAintNoPed.json @@ -0,0 +1 @@ +{"description": "this ain't no ped"} \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/vaccinationAdditionalData.json b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/vaccinationAdditionalData.json new file mode 100644 index 0000000000..c1bc78ed04 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/vaccinationAdditionalData.json @@ -0,0 +1 @@ +{"lastVaccinationDate": "2024-04-02","vaccinationCount": 5} \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/vaccinationReport.pdf b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/vaccinationReport.pdf new file mode 100644 index 0000000000..fe879fe28c Binary files /dev/null and b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/vaccinationReport.pdf differ diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/vaccinationTemplate.bin b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/vaccinationTemplate.bin new file mode 100644 index 0000000000..82090ee2cb --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/payloads/vaccinationTemplate.bin @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/postFileTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/postFileTest.xml deleted file mode 100644 index a04b808966..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/postFileTest.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/scriptValidationTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/scriptValidationTest.xml deleted file mode 100644 index 39efdef351..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/scriptValidationTest.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - assert json.id == 12 - assert json.name == 'Snoopy' - - - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/sendWithBodyLiteralTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/sendWithBodyLiteralTest.xml deleted file mode 100644 index 3daad673c3..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/sendWithBodyLiteralTest.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - {"id": 13} - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/sendWithBodyLiteralWithVariableTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/sendWithBodyLiteralWithVariableTest.xml deleted file mode 100644 index 11aacdf5a0..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/sendWithBodyLiteralWithVariableTest.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - {"id": ${id}} - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/sendWithBodyTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/sendWithBodyTest.xml deleted file mode 100644 index 8cb689bf3f..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/sendWithBodyTest.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/sendWithExtraHeaderTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/sendWithExtraHeaderTest.xml deleted file mode 100644 index b2b002aa24..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/sendWithExtraHeaderTest.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withActorTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withActorTest.xml new file mode 100644 index 0000000000..ed2765f31b --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withActorTest.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withApiCookieTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withApiCookieTest.xml new file mode 100644 index 0000000000..a051f6d1fc --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withApiCookieTest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withApiKeysFromPropertiesTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withApiKeysFromPropertiesTest.xml new file mode 100644 index 0000000000..e9ddb58090 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withApiKeysFromPropertiesTest.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withApiKeysOverridingPropertiesTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withApiKeysOverridingPropertiesTest.xml new file mode 100644 index 0000000000..43b0053054 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withApiKeysOverridingPropertiesTest.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withArrayQueryDataTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withArrayQueryDataTest.xml new file mode 100644 index 0000000000..d2f4a05551 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withArrayQueryDataTest.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + tag1 + ${tag2} + ${nick1} + ${nick2} + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withBasicAuthenticationFromPropertiesTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withBasicAuthenticationFromPropertiesTest.xml new file mode 100644 index 0000000000..770080fb5e --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withBasicAuthenticationFromPropertiesTest.xml @@ -0,0 +1,76 @@ + + + + + + + + + name + previous-owner + MrX + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withBasicAuthenticationOverridingPropertiesTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withBasicAuthenticationOverridingPropertiesTest.xml new file mode 100644 index 0000000000..21a4f9ee0f --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withBasicAuthenticationOverridingPropertiesTest.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withBasicBearerAuthenticationFromPropertiesTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withBasicBearerAuthenticationFromPropertiesTest.xml new file mode 100644 index 0000000000..1645d3348f --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withBasicBearerAuthenticationFromPropertiesTest.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withBasicBearerAuthenticationOverridingPropertiesTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withBasicBearerAuthenticationOverridingPropertiesTest.xml new file mode 100644 index 0000000000..1b84deaa98 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withBasicBearerAuthenticationOverridingPropertiesTest.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withBodyAsPlainTextTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withBodyAsPlainTextTest.xml new file mode 100644 index 0000000000..d5555d4947 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withBodyAsPlainTextTest.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withBodyFromResourceTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withBodyFromResourceTest.xml new file mode 100644 index 0000000000..cf2290bf08 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withBodyFromResourceTest.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnBodyDataValidationTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnBodyDataValidationTest.xml new file mode 100644 index 0000000000..10f6bd7964 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnBodyDataValidationTest.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + {"description": "no pet"} + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnBodyResourceValidationTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnBodyResourceValidationTest.xml new file mode 100644 index 0000000000..93ccf20f5e --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnBodyResourceValidationTest.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnInvalidResponseTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnInvalidResponseTest.xml new file mode 100644 index 0000000000..437a5f5af1 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnInvalidResponseTest.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnJsonPathInvalidTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnJsonPathInvalidTest.xml new file mode 100644 index 0000000000..685ba5e94c --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnJsonPathInvalidTest.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnReasonPhraseTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnReasonPhraseTest.xml new file mode 100644 index 0000000000..2e735d0b00 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnReasonPhraseTest.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnStatusTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnStatusTest.xml new file mode 100644 index 0000000000..9a198cf628 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnStatusTest.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnVersionTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnVersionTest.xml new file mode 100644 index 0000000000..fc6ee9ae54 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFailOnVersionTest.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFileUploadTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFileUploadTest.xml new file mode 100644 index 0000000000..c754a1f07b --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFileUploadTest.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + ${file} + + + + + + + + + [102, 105, 108, 101, 100, 97, 116, 97] + + + + + + + + + + + + {"code": 12, "type":"post-image-ok", "message":"image successfully uploaded"} + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFormDataTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFormDataTest.xml new file mode 100644 index 0000000000..86b439bd74 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFormDataTest.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFormUrlEncodedTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFormUrlEncodedTest.xml new file mode 100644 index 0000000000..c1bef35959 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withFormUrlEncodedTest.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + tag1 + ${tag2} + ${nick1} + ${nick2} + ^`{|}~ }rd]]> + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withJsonPathExtractionTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withJsonPathExtractionTest.xml new file mode 100644 index 0000000000..69b88deed9 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withJsonPathExtractionTest.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + String contentType = context.getVariable("varContentType") + assert contentType == "application/json" : "Expected variable 'varContentType' value 'application/json' but was '${varContentType}'" + + String name = context.getVariable("varName") + List allowedNames = ["cutie", "fluffy", "hasso"] + if (!allowedNames.contains(name)) { + throw new AssertionError("Expected variable 'varName' to be one of " + + allowedNames.join(", ") + " but was '" + name + "'") + } + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withJsonPathValidationTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withJsonPathValidationTest.xml new file mode 100644 index 0000000000..2ae560b2f8 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withJsonPathValidationTest.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withMultipartTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withMultipartTest.xml new file mode 100644 index 0000000000..b68fc8646d --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withMultipartTest.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + import static org.assertj.core.api.Assertions.assertThat + import static java.util.Map.of + import static org.citrusframework.openapi.generator.util.MultipartConverter.multipartMessageToMa + + def multiMap = org.citrusframework.openapi.generator.util.MultipartConverter.multipartMessageToMap((org.citrusframework.http.message.HttpMessage) receivedMessage) + + org.assertj.core.api.Assertions.assertThat(multiMap) + .containsExactlyInAnyOrderEntriesOf(java.util.Map.of( + "additionalData", """${additionalData}""", + "reqIntVal", "1", + "template", new byte[]{36, 123, 116, 101, 109, 112, 108, 97, 116, 101, 68, 97, 116, 97, 125}, + "optIntVal", "100", + "optBoolVal","true", + "optDateVal","2024-12-1", + "optNumberVal","1", + "optStringVal","a")); + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withNestedReceiveInXmlTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withNestedReceiveInXmlTest.xml new file mode 100644 index 0000000000..de467ef686 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withNestedReceiveInXmlTest.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withNonApiQueryParamTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withNonApiQueryParamTest.xml new file mode 100644 index 0000000000..a83d2e6859 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withNonApiQueryParamTest.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withReceiveBodyFromPlainTextTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withReceiveBodyFromPlainTextTest.xml new file mode 100644 index 0000000000..4be7dccdc7 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withReceiveBodyFromPlainTextTest.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withReceiveBodyFromResourceTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withReceiveBodyFromResourceTest.xml new file mode 100644 index 0000000000..2b878dff5f --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withReceiveBodyFromResourceTest.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withReceiveNonApiCookieTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withReceiveNonApiCookieTest.xml new file mode 100644 index 0000000000..eaef099f0a --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withReceiveNonApiCookieTest.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withResponseValidationDisabledTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withResponseValidationDisabledTest.xml new file mode 100644 index 0000000000..8bc1df7b68 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withResponseValidationDisabledTest.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withSoapTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withSoapTest.xml new file mode 100644 index 0000000000..f253752b0b --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withSoapTest.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + J.R. Tolkien + 0815 + Lord of the Rings + + + + + + + + + + J.R. Tolkien + 0815 + Lord of the Rings + + + + + + + + + + + J.R. Tolkien + 0815 + Lord of the Rings + + + + + + + + + + + + J.R. Tolkien + 0815 + Lord of the Rings + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withSpecificEndpointTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withSpecificEndpointTest.xml new file mode 100644 index 0000000000..cc1c66036d --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withSpecificEndpointTest.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withSpecificUriTest.xml b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withSpecificUriTest.xml new file mode 100644 index 0000000000..38e9e03d54 --- /dev/null +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/GeneratedApiTest/withSpecificUriTest.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/citrus/MultipartTestAbstractTestRequest.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/citrus/MultipartTestAbstractTestRequest.java deleted file mode 100644 index d66cc3aa30..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/citrus/MultipartTestAbstractTestRequest.java +++ /dev/null @@ -1,253 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.citrusframework.openapi.generator.rest.multiparttest.citrus; - -import static org.springframework.util.CollectionUtils.isEmpty; - -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.spi.Resources; -import org.citrusframework.message.Message; -import org.citrusframework.testapi.ApiActionBuilderCustomizerService; -import org.citrusframework.testapi.GeneratedApi; -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; - -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:46.388350800+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -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/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/citrus/MultipartTestBeanDefinitionParser.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/citrus/MultipartTestBeanDefinitionParser.java deleted file mode 100644 index 1102147b82..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/citrus/MultipartTestBeanDefinitionParser.java +++ /dev/null @@ -1,219 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.citrusframework.openapi.generator.rest.multiparttest.citrus; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.lang3.StringUtils; -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.springframework.util.xml.DomUtils; -import org.w3c.dom.Attr; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; - -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:46.388350800+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -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/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/citrus/extension/MultipartTestNamespaceHandler.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/citrus/extension/MultipartTestNamespaceHandler.java deleted file mode 100644 index edd3e67e73..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/citrus/extension/MultipartTestNamespaceHandler.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package 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 org.springframework.beans.factory.xml.NamespaceHandlerSupport; - -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:46.388350800+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -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/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/model/Metadata.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/model/Metadata.java deleted file mode 100644 index dbd2bcb664..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/model/Metadata.java +++ /dev/null @@ -1,294 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.citrusframework.openapi.generator.rest.multiparttest.model; - -import java.util.Objects; -import java.util.Arrays; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import java.time.OffsetDateTime; -import java.util.HashMap; -import java.util.Map; - -/** - * Metadata - */ -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:46.388350800+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -public class Metadata { - private Map userMetadata = new HashMap<>(); - - private Map rawMetadata = new HashMap<>(); - - private OffsetDateTime httpExpiresDate; - - private OffsetDateTime expirationTime; - - private String expirationTimeRuleId; - - private Boolean ongoingRestore; - - private OffsetDateTime restoreExpirationTime; - - private Boolean bucketKeyEnabled; - - public Metadata() { - } - - public Metadata userMetadata(Map userMetadata) { - - this.userMetadata = userMetadata; - return this; - } - - public Metadata putUserMetadataItem(String key, String userMetadataItem) { - if (this.userMetadata == null) { - this.userMetadata = new HashMap<>(); - } - this.userMetadata.put(key, userMetadataItem); - return this; - } - - /** - * Get userMetadata - * @return userMetadata - **/ - @jakarta.annotation.Nullable - - public Map getUserMetadata() { - return userMetadata; - } - - - public void setUserMetadata(Map userMetadata) { - this.userMetadata = userMetadata; - } - - - public Metadata rawMetadata(Map rawMetadata) { - - this.rawMetadata = rawMetadata; - return this; - } - - public Metadata putRawMetadataItem(String key, String rawMetadataItem) { - if (this.rawMetadata == null) { - this.rawMetadata = new HashMap<>(); - } - this.rawMetadata.put(key, rawMetadataItem); - return this; - } - - /** - * Get rawMetadata - * @return rawMetadata - **/ - @jakarta.annotation.Nullable - - public Map getRawMetadata() { - return rawMetadata; - } - - - public void setRawMetadata(Map rawMetadata) { - this.rawMetadata = rawMetadata; - } - - - public Metadata httpExpiresDate(OffsetDateTime httpExpiresDate) { - - this.httpExpiresDate = httpExpiresDate; - return this; - } - - /** - * Get httpExpiresDate - * @return httpExpiresDate - **/ - @jakarta.annotation.Nullable - - public OffsetDateTime getHttpExpiresDate() { - return httpExpiresDate; - } - - - public void setHttpExpiresDate(OffsetDateTime httpExpiresDate) { - this.httpExpiresDate = httpExpiresDate; - } - - - public Metadata expirationTime(OffsetDateTime expirationTime) { - - this.expirationTime = expirationTime; - return this; - } - - /** - * Get expirationTime - * @return expirationTime - **/ - @jakarta.annotation.Nullable - - public OffsetDateTime getExpirationTime() { - return expirationTime; - } - - - public void setExpirationTime(OffsetDateTime expirationTime) { - this.expirationTime = expirationTime; - } - - - public Metadata expirationTimeRuleId(String expirationTimeRuleId) { - - this.expirationTimeRuleId = expirationTimeRuleId; - return this; - } - - /** - * Get expirationTimeRuleId - * @return expirationTimeRuleId - **/ - @jakarta.annotation.Nullable - - public String getExpirationTimeRuleId() { - return expirationTimeRuleId; - } - - - public void setExpirationTimeRuleId(String expirationTimeRuleId) { - this.expirationTimeRuleId = expirationTimeRuleId; - } - - - public Metadata ongoingRestore(Boolean ongoingRestore) { - - this.ongoingRestore = ongoingRestore; - return this; - } - - /** - * Get ongoingRestore - * @return ongoingRestore - **/ - @jakarta.annotation.Nullable - - public Boolean getOngoingRestore() { - return ongoingRestore; - } - - - public void setOngoingRestore(Boolean ongoingRestore) { - this.ongoingRestore = ongoingRestore; - } - - - public Metadata restoreExpirationTime(OffsetDateTime restoreExpirationTime) { - - this.restoreExpirationTime = restoreExpirationTime; - return this; - } - - /** - * Get restoreExpirationTime - * @return restoreExpirationTime - **/ - @jakarta.annotation.Nullable - - public OffsetDateTime getRestoreExpirationTime() { - return restoreExpirationTime; - } - - - public void setRestoreExpirationTime(OffsetDateTime restoreExpirationTime) { - this.restoreExpirationTime = restoreExpirationTime; - } - - - public Metadata bucketKeyEnabled(Boolean bucketKeyEnabled) { - - this.bucketKeyEnabled = bucketKeyEnabled; - return this; - } - - /** - * Get bucketKeyEnabled - * @return bucketKeyEnabled - **/ - @jakarta.annotation.Nullable - - public Boolean getBucketKeyEnabled() { - return bucketKeyEnabled; - } - - - public void setBucketKeyEnabled(Boolean bucketKeyEnabled) { - this.bucketKeyEnabled = bucketKeyEnabled; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Metadata metadata = (Metadata) o; - return Objects.equals(this.userMetadata, metadata.userMetadata) && - Objects.equals(this.rawMetadata, metadata.rawMetadata) && - Objects.equals(this.httpExpiresDate, metadata.httpExpiresDate) && - Objects.equals(this.expirationTime, metadata.expirationTime) && - Objects.equals(this.expirationTimeRuleId, metadata.expirationTimeRuleId) && - Objects.equals(this.ongoingRestore, metadata.ongoingRestore) && - Objects.equals(this.restoreExpirationTime, metadata.restoreExpirationTime) && - Objects.equals(this.bucketKeyEnabled, metadata.bucketKeyEnabled); - } - - @Override - public int hashCode() { - return Objects.hash(userMetadata, rawMetadata, httpExpiresDate, expirationTime, expirationTimeRuleId, ongoingRestore, restoreExpirationTime, bucketKeyEnabled); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class Metadata {\n"); - sb.append(" userMetadata: ").append(toIndentedString(userMetadata)).append("\n"); - sb.append(" rawMetadata: ").append(toIndentedString(rawMetadata)).append("\n"); - sb.append(" httpExpiresDate: ").append(toIndentedString(httpExpiresDate)).append("\n"); - sb.append(" expirationTime: ").append(toIndentedString(expirationTime)).append("\n"); - sb.append(" expirationTimeRuleId: ").append(toIndentedString(expirationTimeRuleId)).append("\n"); - sb.append(" ongoingRestore: ").append(toIndentedString(ongoingRestore)).append("\n"); - sb.append(" restoreExpirationTime: ").append(toIndentedString(restoreExpirationTime)).append("\n"); - sb.append(" bucketKeyEnabled: ").append(toIndentedString(bucketKeyEnabled)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - -} - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/model/PutObjectResult.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/model/PutObjectResult.java deleted file mode 100644 index 8e3abaa146..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/model/PutObjectResult.java +++ /dev/null @@ -1,251 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.citrusframework.openapi.generator.rest.multiparttest.model; - -import java.util.Objects; -import java.util.Arrays; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import java.time.OffsetDateTime; -import org.citrusframework.openapi.generator.rest.multiparttest.model.Metadata; - -/** - * PutObjectResult - */ -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:46.388350800+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -public class PutObjectResult { - private String versionId; - - private String eTag; - - private OffsetDateTime expirationTime; - - private String expirationTimeRuleId; - - private String contentMd5; - - private Metadata metadata; - - private Boolean isRequesterCharged; - - public PutObjectResult() { - } - - public PutObjectResult versionId(String versionId) { - - this.versionId = versionId; - return this; - } - - /** - * Get versionId - * @return versionId - **/ - @jakarta.annotation.Nullable - - public String getVersionId() { - return versionId; - } - - - public void setVersionId(String versionId) { - this.versionId = versionId; - } - - - public PutObjectResult eTag(String eTag) { - - this.eTag = eTag; - return this; - } - - /** - * Get eTag - * @return eTag - **/ - @jakarta.annotation.Nullable - - public String geteTag() { - return eTag; - } - - - public void seteTag(String eTag) { - this.eTag = eTag; - } - - - public PutObjectResult expirationTime(OffsetDateTime expirationTime) { - - this.expirationTime = expirationTime; - return this; - } - - /** - * Get expirationTime - * @return expirationTime - **/ - @jakarta.annotation.Nullable - - public OffsetDateTime getExpirationTime() { - return expirationTime; - } - - - public void setExpirationTime(OffsetDateTime expirationTime) { - this.expirationTime = expirationTime; - } - - - public PutObjectResult expirationTimeRuleId(String expirationTimeRuleId) { - - this.expirationTimeRuleId = expirationTimeRuleId; - return this; - } - - /** - * Get expirationTimeRuleId - * @return expirationTimeRuleId - **/ - @jakarta.annotation.Nullable - - public String getExpirationTimeRuleId() { - return expirationTimeRuleId; - } - - - public void setExpirationTimeRuleId(String expirationTimeRuleId) { - this.expirationTimeRuleId = expirationTimeRuleId; - } - - - public PutObjectResult contentMd5(String contentMd5) { - - this.contentMd5 = contentMd5; - return this; - } - - /** - * Get contentMd5 - * @return contentMd5 - **/ - @jakarta.annotation.Nullable - - public String getContentMd5() { - return contentMd5; - } - - - public void setContentMd5(String contentMd5) { - this.contentMd5 = contentMd5; - } - - - public PutObjectResult metadata(Metadata metadata) { - - this.metadata = metadata; - return this; - } - - /** - * Get metadata - * @return metadata - **/ - @jakarta.annotation.Nullable - - public Metadata getMetadata() { - return metadata; - } - - - public void setMetadata(Metadata metadata) { - this.metadata = metadata; - } - - - public PutObjectResult isRequesterCharged(Boolean isRequesterCharged) { - - this.isRequesterCharged = isRequesterCharged; - return this; - } - - /** - * Get isRequesterCharged - * @return isRequesterCharged - **/ - @jakarta.annotation.Nullable - - public Boolean getIsRequesterCharged() { - return isRequesterCharged; - } - - - public void setIsRequesterCharged(Boolean isRequesterCharged) { - this.isRequesterCharged = isRequesterCharged; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - PutObjectResult putObjectResult = (PutObjectResult) o; - return Objects.equals(this.versionId, putObjectResult.versionId) && - Objects.equals(this.eTag, putObjectResult.eTag) && - Objects.equals(this.expirationTime, putObjectResult.expirationTime) && - Objects.equals(this.expirationTimeRuleId, putObjectResult.expirationTimeRuleId) && - Objects.equals(this.contentMd5, putObjectResult.contentMd5) && - Objects.equals(this.metadata, putObjectResult.metadata) && - Objects.equals(this.isRequesterCharged, putObjectResult.isRequesterCharged); - } - - @Override - public int hashCode() { - return Objects.hash(versionId, eTag, expirationTime, expirationTimeRuleId, contentMd5, metadata, isRequesterCharged); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class PutObjectResult {\n"); - sb.append(" versionId: ").append(toIndentedString(versionId)).append("\n"); - sb.append(" eTag: ").append(toIndentedString(eTag)).append("\n"); - sb.append(" expirationTime: ").append(toIndentedString(expirationTime)).append("\n"); - sb.append(" expirationTimeRuleId: ").append(toIndentedString(expirationTimeRuleId)).append("\n"); - sb.append(" contentMd5: ").append(toIndentedString(contentMd5)).append("\n"); - sb.append(" metadata: ").append(toIndentedString(metadata)).append("\n"); - sb.append(" isRequesterCharged: ").append(toIndentedString(isRequesterCharged)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - -} - diff --git a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/request/MultiparttestControllerApi.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/request/MultiparttestControllerApi.java deleted file mode 100644 index 85f1b174b2..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/request/MultiparttestControllerApi.java +++ /dev/null @@ -1,758 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.citrusframework.openapi.generator.rest.multiparttest.request; - -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; - -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:46.388350800+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -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/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/spring/MultipartTestBeanConfiguration.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/spring/MultipartTestBeanConfiguration.java deleted file mode 100644 index d5fd2b4a60..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/multiparttest/spring/MultipartTestBeanConfiguration.java +++ /dev/null @@ -1,65 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package 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 org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Scope; - -@Configuration -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:46.388350800+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -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/JavaCitrusCodegenIT/expectedgen/rest/petstore/citrus/PetStoreAbstractTestRequest.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/citrus/PetStoreAbstractTestRequest.java deleted file mode 100644 index 222b2f239f..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/citrus/PetStoreAbstractTestRequest.java +++ /dev/null @@ -1,253 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.citrusframework.openapi.generator.rest.petstore.citrus; - -import static org.springframework.util.CollectionUtils.isEmpty; - -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.spi.Resources; -import org.citrusframework.message.Message; -import org.citrusframework.testapi.ApiActionBuilderCustomizerService; -import org.citrusframework.testapi.GeneratedApi; -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; - -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:45.610010900+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -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/JavaCitrusCodegenIT/expectedgen/rest/petstore/citrus/PetStoreBeanDefinitionParser.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/citrus/PetStoreBeanDefinitionParser.java deleted file mode 100644 index d1018d8efb..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/citrus/PetStoreBeanDefinitionParser.java +++ /dev/null @@ -1,219 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.citrusframework.openapi.generator.rest.petstore.citrus; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.lang3.StringUtils; -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.springframework.util.xml.DomUtils; -import org.w3c.dom.Attr; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; - -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:45.610010900+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -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/JavaCitrusCodegenIT/expectedgen/rest/petstore/citrus/extension/PetStoreNamespaceHandler.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/citrus/extension/PetStoreNamespaceHandler.java deleted file mode 100644 index ac9e93f527..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/citrus/extension/PetStoreNamespaceHandler.java +++ /dev/null @@ -1,52 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package 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 org.springframework.beans.factory.xml.NamespaceHandlerSupport; - -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:45.610010900+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -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/JavaCitrusCodegenIT/expectedgen/rest/petstore/request/PetApi.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/request/PetApi.java deleted file mode 100644 index 41a154158e..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/request/PetApi.java +++ /dev/null @@ -1,870 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.citrusframework.openapi.generator.rest.petstore.request; - -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; - -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:45.610010900+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -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/JavaCitrusCodegenIT/expectedgen/rest/petstore/request/StoreApi.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/request/StoreApi.java deleted file mode 100644 index db50a61387..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/request/StoreApi.java +++ /dev/null @@ -1,441 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.citrusframework.openapi.generator.rest.petstore.request; - -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; - -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:45.610010900+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -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/JavaCitrusCodegenIT/expectedgen/rest/petstore/request/UserApi.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/request/UserApi.java deleted file mode 100644 index 6b07c599a5..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/request/UserApi.java +++ /dev/null @@ -1,827 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.citrusframework.openapi.generator.rest.petstore.request; - -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; - -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:45.610010900+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -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/JavaCitrusCodegenIT/expectedgen/rest/petstore/spring/PetStoreBeanConfiguration.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/spring/PetStoreBeanConfiguration.java deleted file mode 100644 index 9b31309e7a..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/rest/petstore/spring/PetStoreBeanConfiguration.java +++ /dev/null @@ -1,151 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package 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 org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Scope; - -@Configuration -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:45.610010900+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -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/JavaCitrusCodegenIT/expectedgen/soap/bookservice/citrus/OpenApiFromWsdlAbstractTestRequest.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/soap/bookservice/citrus/OpenApiFromWsdlAbstractTestRequest.java deleted file mode 100644 index 78cc8b5bcf..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/soap/bookservice/citrus/OpenApiFromWsdlAbstractTestRequest.java +++ /dev/null @@ -1,196 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.citrusframework.openapi.generator.soap.bookservice.citrus; - -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; - -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:46.256348400+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -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/JavaCitrusCodegenIT/expectedgen/soap/bookservice/citrus/OpenApiFromWsdlBeanDefinitionParser.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/soap/bookservice/citrus/OpenApiFromWsdlBeanDefinitionParser.java deleted file mode 100644 index e777f4608c..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/soap/bookservice/citrus/OpenApiFromWsdlBeanDefinitionParser.java +++ /dev/null @@ -1,219 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.citrusframework.openapi.generator.soap.bookservice.citrus; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.lang3.StringUtils; -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.springframework.util.xml.DomUtils; -import org.w3c.dom.Attr; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; - -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:46.256348400+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -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/JavaCitrusCodegenIT/expectedgen/soap/bookservice/citrus/extension/OpenApiFromWsdlNamespaceHandler.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/soap/bookservice/citrus/extension/OpenApiFromWsdlNamespaceHandler.java deleted file mode 100644 index 6454ee52fa..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/soap/bookservice/citrus/extension/OpenApiFromWsdlNamespaceHandler.java +++ /dev/null @@ -1,33 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package 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 org.springframework.beans.factory.xml.NamespaceHandlerSupport; - -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:46.256348400+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -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/JavaCitrusCodegenIT/expectedgen/soap/bookservice/request/BookServiceSoapApi.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/soap/bookservice/request/BookServiceSoapApi.java deleted file mode 100644 index ae5505df35..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/soap/bookservice/request/BookServiceSoapApi.java +++ /dev/null @@ -1,339 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.citrusframework.openapi.generator.soap.bookservice.request; - -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; - -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:46.256348400+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -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/JavaCitrusCodegenIT/expectedgen/soap/bookservice/spring/OpenApiFromWsdlBeanConfiguration.java b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/soap/bookservice/spring/OpenApiFromWsdlBeanConfiguration.java deleted file mode 100644 index b1bfeaee9d..0000000000 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/JavaCitrusCodegenIT/expectedgen/soap/bookservice/spring/OpenApiFromWsdlBeanConfiguration.java +++ /dev/null @@ -1,47 +0,0 @@ -/* -* Copyright the original author or authors. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package 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 org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Scope; - -@Configuration -@jakarta.annotation.Generated(value = "org.citrusframework.openapi.generator.JavaCitrusCodegen", date = "2024-07-03T15:24:46.256348400+02:00[Europe/Zurich]", comments = "Generator version: 7.5.0") -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-core/src/test/resources/org/citrusframework/openapi/generator/SimpleWsdlToOpenApiTransformerTest/BookDatatypes.xsd b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/SimpleWsdlToOpenApiTransformerTest/BookDatatypes.xsd index c093acef11..3a735e7dd8 100644 --- a/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/SimpleWsdlToOpenApiTransformerTest/BookDatatypes.xsd +++ b/test-api-generator/citrus-test-api-generator-core/src/test/resources/org/citrusframework/openapi/generator/SimpleWsdlToOpenApiTransformerTest/BookDatatypes.xsd @@ -1,8 +1,8 @@ + This binding defines the SOAP over HTTP transport for BookService operations. + This operation retrieves details for a specific book identified by its ID. + soapAction="http://www.citrusframework.com/BookService/GetBook"> + Detailed Soap Operation documentation. + 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..ce25d9119e 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 @@ -8,7 +8,7 @@ citrus-test-api-generator org.citrusframework - 4.3.0-SNAPSHOT + 4.4.0-SNAPSHOT ../pom.xml diff --git a/test-api-generator/citrus-test-api-generator-maven-plugin/src/main/java/org/citrusframework/maven/plugin/CodeGenMojoWrapper.java b/test-api-generator/citrus-test-api-generator-maven-plugin/src/main/java/org/citrusframework/maven/plugin/CodeGenMojoWrapper.java index 5b1d088727..f672feb374 100644 --- a/test-api-generator/citrus-test-api-generator-maven-plugin/src/main/java/org/citrusframework/maven/plugin/CodeGenMojoWrapper.java +++ b/test-api-generator/citrus-test-api-generator-maven-plugin/src/main/java/org/citrusframework/maven/plugin/CodeGenMojoWrapper.java @@ -17,7 +17,7 @@ package org.citrusframework.maven.plugin; import static java.lang.String.format; -import static org.citrusframework.openapi.generator.JavaCitrusCodegen.CODEGEN_NAME; +import static org.citrusframework.openapi.generator.CitrusJavaCodegen.CODEGEN_NAME; import java.io.File; import java.util.HashMap; @@ -25,7 +25,7 @@ import org.apache.maven.plugin.MojoExecution; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; -import org.citrusframework.openapi.generator.JavaCitrusCodegen; +import org.citrusframework.openapi.generator.CitrusJavaCodegen; import org.openapitools.codegen.plugin.CodeGenMojo; /** @@ -71,17 +71,17 @@ public CodeGenMojoWrapper configOptions(Map configOptionsPropert } public CodeGenMojoWrapper schemaFolder(String schemaFolder) { - configOptionsProperties.put(JavaCitrusCodegen.GENERATED_SCHEMA_FOLDER, schemaFolder); + configOptionsProperties.put(CitrusJavaCodegen.GENERATED_SCHEMA_FOLDER, schemaFolder); return this; } public CodeGenMojoWrapper resourceFolder(String resourceFolder) { - configOptionsProperties.put(JavaCitrusCodegen.RESOURCE_FOLDER, resourceFolder); + configOptionsProperties.put(CitrusJavaCodegen.RESOURCE_FOLDER, resourceFolder); return this; } public CodeGenMojoWrapper sourceFolder(String sourceFolder) { - configOptionsProperties.put(JavaCitrusCodegen.SOURCE_FOLDER, sourceFolder); + configOptionsProperties.put(CitrusJavaCodegen.SOURCE_FOLDER, sourceFolder); return this; } diff --git a/test-api-generator/citrus-test-api-generator-maven-plugin/src/main/java/org/citrusframework/maven/plugin/TestApiGeneratorMojo.java b/test-api-generator/citrus-test-api-generator-maven-plugin/src/main/java/org/citrusframework/maven/plugin/TestApiGeneratorMojo.java index 0c079c7402..491ac48363 100644 --- a/test-api-generator/citrus-test-api-generator-maven-plugin/src/main/java/org/citrusframework/maven/plugin/TestApiGeneratorMojo.java +++ b/test-api-generator/citrus-test-api-generator-maven-plugin/src/main/java/org/citrusframework/maven/plugin/TestApiGeneratorMojo.java @@ -18,10 +18,10 @@ import static java.lang.String.format; import static org.apache.commons.lang3.StringUtils.isBlank; -import static org.citrusframework.openapi.generator.JavaCitrusCodegen.API_ENDPOINT; -import static org.citrusframework.openapi.generator.JavaCitrusCodegen.API_TYPE; -import static org.citrusframework.openapi.generator.JavaCitrusCodegen.PREFIX; -import static org.citrusframework.openapi.generator.JavaCitrusCodegen.TARGET_XMLNS_NAMESPACE; +import static org.citrusframework.openapi.generator.CitrusJavaCodegen.API_ENDPOINT; +import static org.citrusframework.openapi.generator.CitrusJavaCodegen.API_TYPE; +import static org.citrusframework.openapi.generator.CitrusJavaCodegen.PREFIX; +import static org.citrusframework.openapi.generator.CitrusJavaCodegen.TARGET_XMLNS_NAMESPACE; import com.google.common.annotations.VisibleForTesting; import java.io.File; diff --git a/test-api-generator/citrus-test-api-generator-maven-plugin/src/test/java/org/citrusframework/maven/plugin/TestApiGeneratorMojoIntegrationTest.java b/test-api-generator/citrus-test-api-generator-maven-plugin/src/test/java/org/citrusframework/maven/plugin/TestApiGeneratorMojoIntegrationTest.java index 4cccffe386..3408d5f74d 100644 --- a/test-api-generator/citrus-test-api-generator-maven-plugin/src/test/java/org/citrusframework/maven/plugin/TestApiGeneratorMojoIntegrationTest.java +++ b/test-api-generator/citrus-test-api-generator-maven-plugin/src/test/java/org/citrusframework/maven/plugin/TestApiGeneratorMojoIntegrationTest.java @@ -21,7 +21,6 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; -import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; @@ -31,7 +30,6 @@ import org.citrusframework.exceptions.CitrusRuntimeException; import org.citrusframework.exceptions.TestCaseFailedException; import org.citrusframework.maven.plugin.TestApiGeneratorMojo.ApiConfig; -import org.citrusframework.maven.plugin.TestApiGeneratorMojo.ApiType; import org.citrusframework.maven.plugin.stubs.CitrusOpenApiGeneratorMavenProjectStub; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.ParameterizedTest; @@ -49,16 +47,14 @@ class TestApiGeneratorMojoIntegrationTest extends AbstractMojoTestCase { * testing scenario. */ private static final String[] STANDARD_FILE_PATH_TEMPLATES = new String[]{ - "%TARGET_FOLDER%/%GENERATED_SOURCES_FOLDER%/%INVOKER_FOLDER%/citrus/extension/%CAMEL_PREFIX%NamespaceHandler.java", - "%TARGET_FOLDER%/%GENERATED_SOURCES_FOLDER%/%INVOKER_FOLDER%/citrus/%CAMEL_PREFIX%AbstractTestRequest.java", - "%TARGET_FOLDER%/%GENERATED_SOURCES_FOLDER%/%INVOKER_FOLDER%/citrus/%CAMEL_PREFIX%BeanDefinitionParser.java", + "%TARGET_FOLDER%/%GENERATED_SOURCES_FOLDER%/%INVOKER_FOLDER%/%CAMEL_PREFIX%.java", + "%TARGET_FOLDER%/%GENERATED_SOURCES_FOLDER%/%INVOKER_FOLDER%/spring/%CAMEL_PREFIX%NamespaceHandler.java", "%TARGET_FOLDER%/%GENERATED_SOURCES_FOLDER%/%INVOKER_FOLDER%/spring/%CAMEL_PREFIX%BeanConfiguration.java", "%TARGET_FOLDER%/%GENERATED_SOURCES_FOLDER%/%MODEL_FOLDER%/PingReqType.java", "%TARGET_FOLDER%/%GENERATED_SOURCES_FOLDER%/%MODEL_FOLDER%/PingRespType.java", "%TARGET_FOLDER%/%GENERATED_SOURCES_FOLDER%/%REQUEST_FOLDER%/PingApi.java", "%TARGET_FOLDER%/%GENERATED_SOURCES_FOLDER%/%REQUEST_FOLDER%/PungApi.java", - "%TARGET_FOLDER%/%GENERATED_RESOURCES_FOLDER%/%SCHEMA_FOLDER%/%LOWER_PREFIX%-api.xsd", - "%TARGET_FOLDER%/%GENERATED_RESOURCES_FOLDER%/%LOWER_PREFIX%-api-model.csv" + "%TARGET_FOLDER%/%GENERATED_RESOURCES_FOLDER%/%SCHEMA_FOLDER%/%LOWER_PREFIX%-api.xsd" }; /** @@ -170,7 +166,6 @@ private void assertSpecificFileContent(ApiConfig apiConfig) { try { assertEndpointName(apiConfig); assertTargetNamespace(apiConfig); - assertApiType(apiConfig); assertSchemasInSpringSchemas(apiConfig); assertHandlersInSpringHandlers(apiConfig); } catch (IOException e) { @@ -207,18 +202,6 @@ private void assertSchemasInSpringSchemas(ApiConfig apiConfig) throws IOExceptio assertThat(getContentOfFile(apiConfig, "spring.schemas")).doesNotContain(OTHER_CITRUS_META_FILE_CONTENT); } - private void assertApiType(ApiConfig apiConfig) throws IOException { - String text; - switch (apiConfig.getType()) { - case REST -> text = "HttpClient httpClient"; - case SOAP -> text = "WebServiceClient wsClient"; - default -> throw new IllegalArgumentException(String.format("No apiTye set in ApiConfig. Expected one of %s", - stream(ApiType.values()).map(ApiType::toString).collect( - Collectors.joining()))); - } - assertThat(getContentOfFile(apiConfig, "AbstractTestRequest.java")).contains(text); - } - private void assertTargetNamespace(ApiConfig apiConfig) throws IOException { assertThat(getContentOfFile(apiConfig, "-api.xsd")).contains( String.format("targetNamespace=\"%s\"", @@ -226,7 +209,7 @@ private void assertTargetNamespace(ApiConfig apiConfig) throws IOException { } private void assertEndpointName(ApiConfig apiConfig) throws IOException { - assertThat(getContentOfFile(apiConfig, "AbstractTestRequest")).contains( + assertThat(getContentOfFile(apiConfig, "BeanConfiguration")).contains( String.format("@Qualifier(\"%s\")", apiConfig.qualifiedEndpoint())); } diff --git a/test-api-generator/citrus-test-api-spring/pom.xml b/test-api-generator/citrus-test-api-spring/pom.xml new file mode 100644 index 0000000000..ec7d3a6f95 --- /dev/null +++ b/test-api-generator/citrus-test-api-spring/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + + org.citrusframework + citrus + 4.4.0-SNAPSHOT + ../../pom.xml + + + citrus-test-api-spring + Citrus :: Test API Spring + Citrus Test API Spring Integration + jar + + + 17 + 17 + UTF-8 + + + + + org.citrusframework + citrus-spring + ${project.version} + + + org.citrusframework + citrus-test-api-core + ${project.version} + + + + \ No newline at end of file diff --git a/test-api-generator/citrus-test-api-spring/src/main/java/org/citrusframework/openapi/testapi/spring/RestApiReceiveMessageActionParser.java b/test-api-generator/citrus-test-api-spring/src/main/java/org/citrusframework/openapi/testapi/spring/RestApiReceiveMessageActionParser.java new file mode 100644 index 0000000000..6c8bed9e16 --- /dev/null +++ b/test-api-generator/citrus-test-api-spring/src/main/java/org/citrusframework/openapi/testapi/spring/RestApiReceiveMessageActionParser.java @@ -0,0 +1,194 @@ +/* + * Copyright the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.citrusframework.openapi.testapi.spring; + +import java.util.List; +import org.citrusframework.actions.ReceiveMessageAction; +import org.citrusframework.actions.SendMessageAction; +import org.citrusframework.config.xml.AbstractReceiveMessageActionFactoryBean; +import org.citrusframework.http.actions.HttpClientResponseActionBuilder; +import org.citrusframework.http.actions.HttpClientResponseActionBuilder.HttpMessageBuilderSupport; +import org.citrusframework.http.config.xml.HttpReceiveResponseActionParser; +import org.citrusframework.http.message.HttpMessage; +import org.citrusframework.http.message.HttpMessageBuilder; +import org.citrusframework.openapi.OpenApiSpecification; +import org.citrusframework.openapi.actions.OpenApiClientResponseActionBuilder.OpenApiClientResponseMessageBuilder; +import org.citrusframework.openapi.actions.OpenApiSpecificationSource; +import org.citrusframework.openapi.testapi.RestApiReceiveMessageActionBuilder; +import org.citrusframework.openapi.validation.OpenApiMessageValidationContext; +import org.citrusframework.openapi.testapi.GeneratedApi; +import org.citrusframework.validation.context.ValidationContext; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.RuntimeBeanReference; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; +import org.w3c.dom.Element; + +/** + * Parses XML configuration for receiving API responses based on OpenAPI specifications. Extends + * {@link HttpReceiveResponseActionParser} to handle OpenAPI-specific response builders and + * validation. + */ +public class RestApiReceiveMessageActionParser extends HttpReceiveResponseActionParser { + + /** + * The generated api bean class. + */ + private final Class apiBeanClass; + + /** + * The builder class for the receive message action. + */ + private final Class beanClass; + + /** + * The OpenAPI specification related to this parser. + */ + private final OpenApiSpecification openApiSpecification; + + /** + * The OpenAPI operationId associated with this parser. + */ + private final String operationId; + + private final String defaultApiEndpointName; + + public RestApiReceiveMessageActionParser(OpenApiSpecification openApiSpecification, + String operationId, + Class apiBeanClass, + Class beanClass, + String defaultApiEndpointName) { + this.openApiSpecification = openApiSpecification; + this.operationId = operationId; + this.apiBeanClass = apiBeanClass; + this.beanClass = beanClass; + this.defaultApiEndpointName = defaultApiEndpointName; + } + + @Override + protected BeanDefinitionBuilder createBeanDefinitionBuilder(Element element, + ParserContext parserContext) { + + BeanDefinitionBuilder beanDefinitionBuilder = super.createBeanDefinitionBuilder(element, + parserContext); + + // Remove the messageBuilder property and inject it directly into the action builder. + BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition(); + OpenApiClientResponseMessageBuilder messageBuilder = (OpenApiClientResponseMessageBuilder) beanDefinition.getPropertyValues() + .get("messageBuilder"); + messageBuilder.statusCode(element.getAttribute("statusCode")); + + beanDefinition.getPropertyValues().removePropertyValue("messageBuilder"); + + BeanDefinitionBuilder actionBuilder = BeanDefinitionBuilder.genericBeanDefinition( + beanClass); + actionBuilder.addConstructorArgValue(new RuntimeBeanReference(apiBeanClass)); + actionBuilder.addConstructorArgValue(openApiSpecification); + actionBuilder.addConstructorArgValue(messageBuilder); + + beanDefinitionBuilder.addConstructorArgValue(actionBuilder.getBeanDefinition()); + setDefaultEndpoint(beanDefinitionBuilder); + + return beanDefinitionBuilder; + } + + /** + * Sets the default endpoint for the message if not already specified. + */ + private void setDefaultEndpoint(BeanDefinitionBuilder beanDefinitionBuilder) { + if (!beanDefinitionBuilder.getBeanDefinition().getPropertyValues().contains("endpoint")) { + beanDefinitionBuilder.addPropertyReference("endpoint", defaultApiEndpointName); + } + } + + @Override + protected Class> getMessageFactoryClass() { + return TestApiOpenApiClientReceiveActionBuilderFactoryBean.class; + } + + @Override + protected void validateEndpointConfiguration(Element element) { + // skip validation, as we support endpoint injection + } + + @Override + protected HttpMessageBuilder createMessageBuilder(HttpMessage httpMessage) { + return new OpenApiClientResponseMessageBuilder(httpMessage, + new OpenApiSpecificationSource(openApiSpecification), operationId, null); + } + + @Override + protected List parseValidationContexts(Element messageElement, + BeanDefinitionBuilder builder) { + List validationContexts = super.parseValidationContexts(messageElement, + builder); + OpenApiMessageValidationContext openApiMessageValidationContext = getOpenApiMessageValidationContext( + messageElement); + validationContexts.add(openApiMessageValidationContext); + return validationContexts; + } + + /** + * Constructs the OpenAPI message validation context based on the XML element. + */ + private OpenApiMessageValidationContext getOpenApiMessageValidationContext( + Element messageElement) { + OpenApiMessageValidationContext.Builder context = OpenApiMessageValidationContext.Builder.openApi( + openApiSpecification); + + if (messageElement != null) { + addSchemaInformationToValidationContext(messageElement, context); + } + + return context.build(); + } + + /** + * Factory bean for creating {@link ReceiveMessageAction} instances using the provided + * {@link RestApiReceiveMessageActionBuilder}. + */ + public static class TestApiOpenApiClientReceiveActionBuilderFactoryBean extends + AbstractReceiveMessageActionFactoryBean { + + private RestApiReceiveMessageActionBuilder builder; + + public TestApiOpenApiClientReceiveActionBuilderFactoryBean( + RestApiReceiveMessageActionBuilder builder) { + this.builder = builder; + } + + public void setBuilder(RestApiReceiveMessageActionBuilder builder) { + this.builder = builder; + } + + @Override + public ReceiveMessageAction getObject() { + return builder.build(); + } + + @Override + public Class getObjectType() { + return SendMessageAction.class; + } + + @Override + public HttpClientResponseActionBuilder getBuilder() { + return builder; + } + } + +} diff --git a/test-api-generator/citrus-test-api-spring/src/main/java/org/citrusframework/openapi/testapi/spring/RestApiSendMessageActionParser.java b/test-api-generator/citrus-test-api-spring/src/main/java/org/citrusframework/openapi/testapi/spring/RestApiSendMessageActionParser.java new file mode 100644 index 0000000000..b244ef47cf --- /dev/null +++ b/test-api-generator/citrus-test-api-spring/src/main/java/org/citrusframework/openapi/testapi/spring/RestApiSendMessageActionParser.java @@ -0,0 +1,350 @@ +/* + * Copyright the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.citrusframework.openapi.testapi.spring; + +import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; + +import java.util.List; +import java.util.stream.Collectors; +import org.citrusframework.actions.SendMessageAction; +import org.citrusframework.config.xml.AbstractSendMessageActionFactoryBean; +import org.citrusframework.config.xml.AbstractTestContainerFactoryBean; +import org.citrusframework.config.xml.AsyncParser.AsyncFactoryBean; +import org.citrusframework.config.xml.SequenceParser.SequenceFactoryBean; +import org.citrusframework.http.actions.HttpClientRequestActionBuilder; +import org.citrusframework.http.actions.HttpClientRequestActionBuilder.HttpMessageBuilderSupport; +import org.citrusframework.http.config.xml.HttpSendRequestActionParser; +import org.citrusframework.http.message.HttpMessage; +import org.citrusframework.http.message.HttpMessageBuilder; +import org.citrusframework.openapi.OpenApiSpecification; +import org.citrusframework.openapi.actions.OpenApiClientRequestActionBuilder.OpenApiClientRequestMessageBuilder; +import org.citrusframework.openapi.actions.OpenApiSpecificationSource; +import org.citrusframework.openapi.testapi.GeneratedApi; +import org.citrusframework.openapi.testapi.RestApiReceiveMessageActionBuilder; +import org.citrusframework.openapi.testapi.RestApiSendMessageActionBuilder; +import org.citrusframework.openapi.testapi.RestApiSendMessageActionBuilder.TestApiClientRequestMessageBuilder; +import org.citrusframework.openapi.testapi.TestApiUtils; +import org.citrusframework.util.StringUtils; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.RuntimeBeanReference; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.ManagedList; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.xml.DomUtils; +import org.w3c.dom.Attr; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * Parses the XML configuration for sending API requests based on OpenAPI specifications. Extends + * {@link HttpSendRequestActionParser} to handle OpenAPI specific request and response builders. + */ +public class RestApiSendMessageActionParser extends HttpSendRequestActionParser { + + /** + * The generated api bean class. + */ + private final Class apiBeanClass; + + /** + * The builder class for the send message action. + */ + private final Class requestBeanClass; + + /** + * The builder class for the receive message action, required when using nested send/receive xml + * elements. + */ + private final Class receiveBeanClass; + + /** + * The OpenAPI specification that relates to the TestAPI classes. + */ + private final OpenApiSpecification openApiSpecification; + + /** + * The OpenAPI operationId, related to this parser + */ + private final String operationId; + + /** + * The OpenAPI operation path. + */ + private final String path; + + /** + * Constructor parameters for the requestBeanClass. + */ + private List constructorParameters = emptyList(); + + /** + * Optional non constructor parameters for the requestBeanClass. + */ + private List nonConstructorParameters = emptyList(); + + private final String defaultEndpointName; + + public RestApiSendMessageActionParser( + OpenApiSpecification openApiSpecification, + String operationId, + String path, + Class apiBeanClass, + Class sendBeanClass, + Class receiveBeanClass, + String defaultEndpointName) { + this.openApiSpecification = openApiSpecification; + this.operationId = operationId; + this.path = path; + this.apiBeanClass = apiBeanClass; + this.requestBeanClass = sendBeanClass; + this.receiveBeanClass = receiveBeanClass; + this.defaultEndpointName = defaultEndpointName; + } + + @Override + protected BeanDefinitionBuilder createBeanDefinitionBuilder(final Element element, + ParserContext parserContext) { + + BeanDefinitionBuilder beanDefinitionBuilder = super.createBeanDefinitionBuilder(element, + parserContext); + + BeanDefinitionBuilder actionBuilder = createTestApiActionBuilder( + element, beanDefinitionBuilder); + beanDefinitionBuilder.addConstructorArgValue(actionBuilder.getBeanDefinition()); + + setDefaultEndpoint(beanDefinitionBuilder); + + Element receive = DomUtils.getChildElementByTagName(element, "receive"); + if (receive != null) { + boolean fork = Boolean.parseBoolean(element.getAttribute("fork")); + return wrapSendAndReceiveActionInSequence(fork, receive, parserContext, + beanDefinitionBuilder); + } + + return beanDefinitionBuilder; + } + + private BeanDefinitionBuilder createTestApiActionBuilder(Element element, + BeanDefinitionBuilder beanDefinitionBuilder) { + BeanDefinitionBuilder actionBuilder = propagateMessageBuilderToActionBuilder( + beanDefinitionBuilder); + readConstructorParameters(element, actionBuilder); + readNonConstructorParameters(element, actionBuilder); + return actionBuilder; + } + + /** + * Handles the configuration for both sending and receiving actions when a nested + * element is present in the XML specification. It creates appropriate builders for both sending + * and receiving messages and adds them to a container that executes these actions in sequence + * or asynchronously, depending on the {@code fork} parameter. + */ + private BeanDefinitionBuilder wrapSendAndReceiveActionInSequence(boolean fork, Element receive, + ParserContext parserContext, BeanDefinitionBuilder beanDefinitionBuilder) { + + Class> containerClass = + fork ? AsyncFactoryBean.class : SequenceFactoryBean.class; + + BeanDefinitionBuilder sequenceBuilder = BeanDefinitionBuilder.genericBeanDefinition( + containerClass); + + RestApiReceiveMessageActionParser receiveApiResponseActionParser = new RestApiReceiveMessageActionParser( + openApiSpecification, operationId, apiBeanClass, receiveBeanClass, defaultEndpointName); + BeanDefinition receiveResponseBeanDefinition = receiveApiResponseActionParser.parse( + receive, parserContext); + + ManagedList actions = new ManagedList<>(); + actions.add(beanDefinitionBuilder.getBeanDefinition()); + actions.add(receiveResponseBeanDefinition); + + sequenceBuilder.addPropertyValue("actions", actions); + + return sequenceBuilder; + } + + /** + * Propagates the message builder created by the superclass into the specific send message + * action builder. + */ + private BeanDefinitionBuilder propagateMessageBuilderToActionBuilder( + BeanDefinitionBuilder beanDefinitionBuilder) { + + BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition(); + OpenApiClientRequestMessageBuilder messageBuilder = (OpenApiClientRequestMessageBuilder) beanDefinition.getPropertyValues() + .get("messageBuilder"); + beanDefinition.getPropertyValues().removePropertyValue("messageBuilder"); + + BeanDefinitionBuilder actionBuilder = BeanDefinitionBuilder.genericBeanDefinition( + requestBeanClass); + + actionBuilder.addConstructorArgValue(new RuntimeBeanReference(apiBeanClass)); + actionBuilder.addConstructorArgValue(openApiSpecification); + actionBuilder.addConstructorArgValue(messageBuilder); + + return actionBuilder; + } + + /** + * Reads constructor parameters from the XML element and adds them as constructor arguments to + * the provided {@link BeanDefinitionBuilder}. + */ + private void readConstructorParameters(Element element, BeanDefinitionBuilder actionBuilder) { + + for (String parameterName : constructorParameters) { + if (element.hasAttribute(parameterName)) { + actionBuilder.addConstructorArgValue(element.getAttribute(parameterName)); + } else { + List values = collectChildNodeContents(element, parameterName); + actionBuilder.addConstructorArgValue(values); + } + } + } + + /** + * Reads non-constructor parameters from the XML element and adds them as properties to the + * provided {@link BeanDefinitionBuilder}. + */ + private void readNonConstructorParameters(Element element, + BeanDefinitionBuilder actionBuilder) { + + for (String parameterName : nonConstructorParameters) { + + if (isHandledBySuper(parameterName)) { + continue; + } + + // For java parameter types other that string, we need to use the non-typed java property + // with type string. These properties in java dsl are identified by a trailing '$'. In xml + // however, the trailing '$' is omitted. Thus, the respective names are prepared accordingly. + String attributeName = parameterName; + if (parameterName.endsWith("$")) { + attributeName = parameterName.substring(0, parameterName.length() - 1); + } + + Attr attribute = element.getAttributeNode(attributeName); + if (attribute != null) { + actionBuilder.addPropertyValue( + TestApiUtils.mapXmlAttributeNameToJavaPropertyName(parameterName), + attribute.getValue()); + } else { + List values = collectChildNodeContents(element, attributeName); + if (values != null && !values.isEmpty()) { + actionBuilder.addPropertyValue( + TestApiUtils.mapXmlAttributeNameToJavaPropertyName(parameterName), + values); + } + } + } + } + + private static List collectChildNodeContents(Element element, String parameterName) { + return DomUtils.getChildElementsByTagName(element, parameterName) + .stream() + .map(Node::getTextContent) + .filter(StringUtils::isNotEmpty) + .collect(Collectors.toList()); // For further processing, list must not be immutable + } + + /** + * Sets the default endpoint for TestApi actions, if not already specified. + */ + private void setDefaultEndpoint(BeanDefinitionBuilder beanDefinitionBuilder) { + if (!beanDefinitionBuilder.getBeanDefinition().getPropertyValues().contains("endpoint")) { + beanDefinitionBuilder.addPropertyReference("endpoint", defaultEndpointName); + } + } + + /** + * Checks if the property is handled by the superclass implementation. + * + * @param property The property name to check. + * @return True if handled by the superclass, false otherwise. + */ + private boolean isHandledBySuper(String property) { + return "body".equals(property); + } + + @Override + protected Class> getMessageFactoryClass() { + return TestApiOpenApiClientSendActionBuilderFactoryBean.class; + } + + @Override + protected void validateEndpointConfiguration(Element element) { + // skip validation, as we support endpoint injection + } + + @Override + protected Element getRequestElement(Element element) { + return element; + } + + @Override + protected HttpMessageBuilder createMessageBuilder(HttpMessage httpMessage) { + httpMessage.path(path); + return new TestApiClientRequestMessageBuilder(httpMessage, + new OpenApiSpecificationSource(openApiSpecification), operationId); + } + + public void setConstructorParameters(String... constructorParameters) { + this.constructorParameters = + constructorParameters != null ? asList(constructorParameters) + : emptyList(); + } + + public void setNonConstructorParameters(String... nonConstructorParameters) { + this.nonConstructorParameters = + nonConstructorParameters != null ? asList(nonConstructorParameters) + : emptyList(); + } + + /** + * Factory bean for creating {@link SendMessageAction} instances using the provided + * {@link RestApiSendMessageActionBuilder}. + */ + public static class TestApiOpenApiClientSendActionBuilderFactoryBean extends + AbstractSendMessageActionFactoryBean { + + private RestApiSendMessageActionBuilder builder; + + public TestApiOpenApiClientSendActionBuilderFactoryBean( + RestApiSendMessageActionBuilder builder) { + this.builder = builder; + } + + public void setBuilder(RestApiSendMessageActionBuilder builder) { + this.builder = builder; + } + + @Override + public SendMessageAction getObject() { + return builder.build(); + } + + @Override + public Class getObjectType() { + return SendMessageAction.class; + } + + @Override + public HttpClientRequestActionBuilder getBuilder() { + return builder; + } + } + +} diff --git a/test-api-generator/citrus-test-api-spring/src/main/java/org/citrusframework/openapi/testapi/spring/SoapApiReceiveMessageActionParser.java b/test-api-generator/citrus-test-api-spring/src/main/java/org/citrusframework/openapi/testapi/spring/SoapApiReceiveMessageActionParser.java new file mode 100644 index 0000000000..89d6617060 --- /dev/null +++ b/test-api-generator/citrus-test-api-spring/src/main/java/org/citrusframework/openapi/testapi/spring/SoapApiReceiveMessageActionParser.java @@ -0,0 +1,96 @@ +/* + * Copyright the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.citrusframework.openapi.testapi.spring; + +import org.citrusframework.openapi.testapi.GeneratedApi; +import org.citrusframework.openapi.testapi.SoapApiReceiveMessageActionBuilder; +import org.citrusframework.util.StringUtils; +import org.citrusframework.ws.config.xml.ReceiveSoapMessageActionParser; +import org.springframework.beans.factory.config.RuntimeBeanReference; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.ParserContext; +import org.w3c.dom.Element; + +public class SoapApiReceiveMessageActionParser extends ReceiveSoapMessageActionParser { + + /** + * The generated api bean class. + */ + private final Class apiBeanClass; + + /** + * The builder class for the receive message action. + */ + private final Class receiveBeanClass; + + private final String defaultEndpointName; + + public SoapApiReceiveMessageActionParser( + Class apiBeanClass, + Class beanClass, + String defaultEndpointName) { + this.apiBeanClass = apiBeanClass; + this.receiveBeanClass = beanClass; + this.defaultEndpointName = defaultEndpointName; + } + + @Override + protected BeanDefinitionBuilder parseComponent(Element element, ParserContext parserContext) { + BeanDefinitionBuilder beanDefinitionBuilder = super.parseComponent(element, parserContext); + + BeanDefinitionBuilder actionBuilder = createTestApiActionBuilder(); + beanDefinitionBuilder.addConstructorArgValue(actionBuilder.getBeanDefinition()); + + return beanDefinitionBuilder; + } + + protected String parseEndpoint(Element element) { + String endpointUri = element.getAttribute("endpoint"); + + if (!StringUtils.hasText(endpointUri)) { + endpointUri = defaultEndpointName; + } + return endpointUri; + } + + private BeanDefinitionBuilder createTestApiActionBuilder() { + + BeanDefinitionBuilder actionBuilder = BeanDefinitionBuilder.genericBeanDefinition( + receiveBeanClass); + actionBuilder.addConstructorArgValue(new RuntimeBeanReference(apiBeanClass)); + + return actionBuilder; + } + + @Override + protected Class getMessageFactoryClass() { + return TestApiSoapClientReceiveActionBuilderFactoryBean.class; + } + + /** + * Test action factory bean. + */ + public static class TestApiSoapClientReceiveActionBuilderFactoryBean extends + ReceiveSoapMessageActionFactoryBean { + + public TestApiSoapClientReceiveActionBuilderFactoryBean( + SoapApiReceiveMessageActionBuilder builder) { + super(builder); + } + } + +} diff --git a/test-api-generator/citrus-test-api-spring/src/main/java/org/citrusframework/openapi/testapi/spring/SoapApiSendMessageActionParser.java b/test-api-generator/citrus-test-api-spring/src/main/java/org/citrusframework/openapi/testapi/spring/SoapApiSendMessageActionParser.java new file mode 100644 index 0000000000..c498623a00 --- /dev/null +++ b/test-api-generator/citrus-test-api-spring/src/main/java/org/citrusframework/openapi/testapi/spring/SoapApiSendMessageActionParser.java @@ -0,0 +1,147 @@ +/* + * Copyright the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.citrusframework.openapi.testapi.spring; + +import org.citrusframework.config.xml.AbstractTestContainerFactoryBean; +import org.citrusframework.config.xml.AsyncParser.AsyncFactoryBean; +import org.citrusframework.config.xml.SequenceParser.SequenceFactoryBean; +import org.citrusframework.openapi.testapi.GeneratedApi; +import org.citrusframework.openapi.testapi.SoapApiReceiveMessageActionBuilder; +import org.citrusframework.openapi.testapi.SoapApiSendMessageActionBuilder; +import org.citrusframework.util.StringUtils; +import org.citrusframework.ws.config.xml.SendSoapMessageActionParser; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.RuntimeBeanReference; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.ManagedList; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.xml.DomUtils; +import org.w3c.dom.Element; + +public class SoapApiSendMessageActionParser extends SendSoapMessageActionParser { + + /** + * The generated api bean class. + */ + private final Class apiBeanClass; + + /** + * The builder class for the send message action. + */ + private final Class sendBeanClass; + + /** + * The builder class for the receive message action, required when using nested send/receive xml + * elements. + */ + private final Class receiveBeanClass; + + private final String defaultEndpointName; + + public SoapApiSendMessageActionParser( + Class apiBeanClass, + Class sendBeanClass, + Class receiveBeanClass, + String defaultEndpointName) { + this.apiBeanClass = apiBeanClass; + this.sendBeanClass = sendBeanClass; + this.receiveBeanClass = receiveBeanClass; + this.defaultEndpointName = defaultEndpointName; + } + + @Override + public BeanDefinitionBuilder parseComponent(Element element, ParserContext parserContext) { + BeanDefinitionBuilder beanDefinitionBuilder = super.parseComponent(element, parserContext); + + BeanDefinitionBuilder actionBuilder = createTestApiActionBuilder(); + beanDefinitionBuilder.addConstructorArgValue(actionBuilder.getBeanDefinition()); + + Element receive = DomUtils.getChildElementByTagName(element, "receive"); + if (receive != null) { + boolean fork = Boolean.parseBoolean(element.getAttribute("fork")); + return wrapSendAndReceiveActionInSequence(fork, receive, parserContext, + beanDefinitionBuilder); + } + + return beanDefinitionBuilder; + } + + protected String parseEndpoint(Element element) { + String endpointUri = element.getAttribute("endpoint"); + + if (!StringUtils.hasText(endpointUri)) { + endpointUri = defaultEndpointName; + } + return endpointUri; + } + + private BeanDefinitionBuilder createTestApiActionBuilder() { + + BeanDefinitionBuilder actionBuilder = BeanDefinitionBuilder.genericBeanDefinition( + sendBeanClass); + actionBuilder.addConstructorArgValue(new RuntimeBeanReference(apiBeanClass)); + + return actionBuilder; + } + + + @Override + protected Class getMessageFactoryClass() { + return TestApiSoapClientSendActionBuilderFactoryBean.class; + } + + /** + * Handles the configuration for both sending and receiving actions when a nested + * element is present in the XML specification. It creates appropriate builders for both sending + * and receiving messages and adds them to a container that executes these actions in sequence + * or asynchronously, depending on the {@code fork} parameter. + */ + private BeanDefinitionBuilder wrapSendAndReceiveActionInSequence(boolean fork, Element receive, + ParserContext parserContext, BeanDefinitionBuilder beanDefinitionBuilder) { + + Class> containerClass = + fork ? AsyncFactoryBean.class : SequenceFactoryBean.class; + + BeanDefinitionBuilder sequenceBuilder = BeanDefinitionBuilder.genericBeanDefinition( + containerClass); + + SoapApiReceiveMessageActionParser receiveApiResponseActionParser = new SoapApiReceiveMessageActionParser( + apiBeanClass, receiveBeanClass, defaultEndpointName); + BeanDefinition receiveResponseBeanDefinition = receiveApiResponseActionParser.parse( + receive, parserContext); + + ManagedList actions = new ManagedList<>(); + actions.add(beanDefinitionBuilder.getBeanDefinition()); + actions.add(receiveResponseBeanDefinition); + + sequenceBuilder.addPropertyValue("actions", actions); + + return sequenceBuilder; + } + + /** + * Test action factory bean. + */ + public static class TestApiSoapClientSendActionBuilderFactoryBean extends + SendSoapMessageActionFactoryBean { + + public TestApiSoapClientSendActionBuilderFactoryBean( + SoapApiSendMessageActionBuilder builder) { + super(builder); + } + } +} diff --git a/test-api-generator/pom.xml b/test-api-generator/pom.xml index c3776c4931..025be2115a 100644 --- a/test-api-generator/pom.xml +++ b/test-api-generator/pom.xml @@ -6,7 +6,7 @@ org.citrusframework citrus - 4.3.0-SNAPSHOT + 4.4.0-SNAPSHOT ../pom.xml @@ -20,8 +20,10 @@ + citrus-test-api-core citrus-test-api-generator-core citrus-test-api-generator-maven-plugin + citrus-test-api-spring