diff --git a/datamodel/openapi/openapi-api-apache-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/apache/sodastore/api/SodasApi.java b/datamodel/openapi/openapi-api-apache-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/apache/sodastore/api/SodasApi.java index bdcadeb55..30a327769 100644 --- a/datamodel/openapi/openapi-api-apache-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/apache/sodastore/api/SodasApi.java +++ b/datamodel/openapi/openapi-api-apache-sample/src/main/java/com/sap/cloud/sdk/datamodel/openapi/apache/sodastore/api/SodasApi.java @@ -4,6 +4,7 @@ package com.sap.cloud.sdk.datamodel.openapi.apache.sodastore.api; +import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -21,6 +22,7 @@ import com.sap.cloud.sdk.services.openapi.apache.apiclient.BaseApi; import com.sap.cloud.sdk.services.openapi.apache.apiclient.Pair; import com.sap.cloud.sdk.services.openapi.apache.core.OpenApiRequestException; +import com.sap.cloud.sdk.services.openapi.apache.core.OpenApiResponse; /** * SodaStore API in version 1.0.0. @@ -243,6 +245,68 @@ public SodaWithId sodasIdGet( @Nonnull final Long id ) localVarReturnType); } + /** + *
+ * Import soda data from a file + *
+ *
+ * 200 - Imported successfully
+ *
+ * @param _file
+ * The value for the parameter _file
+ * @return An OpenApiResponse containing the status code of the HttpResponse.
+ * @throws OpenApiRequestException
+ * if an error occurs while attempting to invoke the API
+ */
+ @Nonnull
+ public OpenApiResponse sodasImportPost( @Nonnull final File _file )
+ throws OpenApiRequestException
+ {
+
+ // verify the required parameter '_file' is set
+ if( _file == null ) {
+ throw new OpenApiRequestException("Missing the required parameter '_file' when calling sodasImportPost")
+ .statusCode(400);
+ }
+
+ // create path and map variables
+ final String localVarPath = "/sodas/upload";
+
+ final StringJoiner localVarQueryStringJoiner = new StringJoiner("&");
+ final List
* Update a specific soda product by ID
diff --git a/datamodel/openapi/openapi-api-apache-sample/src/main/resources/sodastore.yaml b/datamodel/openapi/openapi-api-apache-sample/src/main/resources/sodastore.yaml
index bf2b80a7f..6c9128a25 100644
--- a/datamodel/openapi/openapi-api-apache-sample/src/main/resources/sodastore.yaml
+++ b/datamodel/openapi/openapi-api-apache-sample/src/main/resources/sodastore.yaml
@@ -281,6 +281,27 @@ paths:
format: binary
'404':
description: Soda product not found
+ /sodas/upload:
+ post:
+ summary: Import soda data from a file
+ operationId: sodasImportPost
+ tags:
+ - Sodas
+ requestBody:
+ required: true
+ content:
+ multipart/form-data:
+ schema:
+ type: object
+ required:
+ - file
+ properties:
+ file:
+ type: string
+ format: binary
+ responses:
+ '200':
+ description: Imported successfully
/orders:
post:
summary: Create a new order
diff --git a/datamodel/openapi/openapi-api-apache-sample/src/test/java/com/sap/cloud/sdk/services/openapi/apache/SerializationTest.java b/datamodel/openapi/openapi-api-apache-sample/src/test/java/com/sap/cloud/sdk/services/openapi/apache/SerializationTest.java
index 5486d3f06..7a97bb1ac 100644
--- a/datamodel/openapi/openapi-api-apache-sample/src/test/java/com/sap/cloud/sdk/services/openapi/apache/SerializationTest.java
+++ b/datamodel/openapi/openapi-api-apache-sample/src/test/java/com/sap/cloud/sdk/services/openapi/apache/SerializationTest.java
@@ -1,7 +1,14 @@
package com.sap.cloud.sdk.services.openapi.apache;
+import static com.github.tomakehurst.wiremock.client.WireMock.aMultipart;
+import static com.github.tomakehurst.wiremock.client.WireMock.containing;
+import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
+import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static org.assertj.core.api.Assertions.assertThat;
+import java.io.File;
+import java.io.IOException;
+
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -98,12 +105,28 @@ void testJacksonSerializeOrder()
assertThat(new ObjectMapper().readValue(expected, Order.class)).isEqualTo(order);
}
+ @Test
+ void testFileUploadHasFilenameInContentDisposition()
+ throws IOException
+ {
+ WireMock.stubFor(WireMock.post(urlEqualTo("/sodas/upload")).willReturn(WireMock.ok()));
+
+ final var tempFile = File.createTempFile("test-soda-import", ".csv");
+ tempFile.deleteOnExit();
+
+ sut.sodasImportPost(tempFile);
+
+ final var filePart =
+ aMultipart("file").withHeader("Content-Disposition", containing(tempFile.getName())).build();
+ WireMock.verify(postRequestedFor(urlEqualTo("/sodas/upload")).withRequestBodyPart(filePart));
+ }
+
private void verify( String requestBody )
{
WireMock
.verify(
WireMock
- .putRequestedFor(WireMock.urlEqualTo("/sodas"))
+ .putRequestedFor(urlEqualTo("/sodas"))
.withHeader("Content-Type", WireMock.equalTo("application/json; charset=UTF-8"))
.withRequestBody(WireMock.equalToJson(requestBody)));
}
diff --git a/datamodel/openapi/openapi-generator/src/main/resources/openapi-generator/mustache-templates/libraries/apache-httpclient/api.mustache b/datamodel/openapi/openapi-generator/src/main/resources/openapi-generator/mustache-templates/libraries/apache-httpclient/api.mustache
index b8d3f2b97..fcd38765f 100644
--- a/datamodel/openapi/openapi-generator/src/main/resources/openapi-generator/mustache-templates/libraries/apache-httpclient/api.mustache
+++ b/datamodel/openapi/openapi-generator/src/main/resources/openapi-generator/mustache-templates/libraries/apache-httpclient/api.mustache
@@ -146,7 +146,7 @@ public class {{classname}} extends BaseApi {
@Deprecated
{{/isDeprecated}}
{{#vendorExtensions.x-return-nullable}}@Nullable{{/vendorExtensions.x-return-nullable}}{{^vendorExtensions.x-return-nullable}}@Nonnull{{/vendorExtensions.x-return-nullable}}
- public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}OpenApiResponse {{/returnType}}{{#vendorExtensions.x-sap-cloud-sdk-operation-name}}{{vendorExtensions.x-sap-cloud-sdk-operation-name}}{{/vendorExtensions.x-sap-cloud-sdk-operation-name}}{{^vendorExtensions.x-sap-cloud-sdk-operation-name}}{{operationId}}{{/vendorExtensions.x-sap-cloud-sdk-operation-name}}({{#allParams}}{{>nullable_var_annotations}} final {{{dataType}}} {{paramName}}{{^-last}}, {{/-last}}{{/allParams}}) throws OpenApiRequestException {
+ public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}OpenApiResponse {{/returnType}}{{#vendorExtensions.x-sap-cloud-sdk-operation-name}}{{vendorExtensions.x-sap-cloud-sdk-operation-name}}{{/vendorExtensions.x-sap-cloud-sdk-operation-name}}{{^vendorExtensions.x-sap-cloud-sdk-operation-name}}{{operationId}}{{/vendorExtensions.x-sap-cloud-sdk-operation-name}}({{#allParams}}{{>nullable_var_annotations}} final {{#isFile}}File{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}} {{^-last}}, {{/-last}}{{/allParams}}) throws OpenApiRequestException {
{{>operationBody}}
}
{{/hasOptionalParams}}
@@ -185,7 +185,7 @@ public class {{classname}} extends BaseApi {
@Deprecated
{{/isDeprecated}}
{{#vendorExtensions.x-return-nullable}}@Nullable{{/vendorExtensions.x-return-nullable}}{{^vendorExtensions.x-return-nullable}}@Nonnull{{/vendorExtensions.x-return-nullable}}
- public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}OpenApiResponse {{/returnType}}{{#vendorExtensions.x-sap-cloud-sdk-operation-name}}{{vendorExtensions.x-sap-cloud-sdk-operation-name}}{{/vendorExtensions.x-sap-cloud-sdk-operation-name}}{{^vendorExtensions.x-sap-cloud-sdk-operation-name}}{{operationId}}{{/vendorExtensions.x-sap-cloud-sdk-operation-name}}({{#requiredParams}}{{>nullable_var_annotations}} final {{{dataType}}} {{paramName}}{{^-last}}, {{/-last}}{{/requiredParams}}) throws OpenApiRequestException {
+ public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}OpenApiResponse {{/returnType}}{{#vendorExtensions.x-sap-cloud-sdk-operation-name}}{{vendorExtensions.x-sap-cloud-sdk-operation-name}}{{/vendorExtensions.x-sap-cloud-sdk-operation-name}}{{^vendorExtensions.x-sap-cloud-sdk-operation-name}}{{operationId}}{{/vendorExtensions.x-sap-cloud-sdk-operation-name}}({{#requiredParams}}{{>nullable_var_annotations}} final {{#isFile}}File{{/isFile}}{{^isFile}}{{{dataType}}}{{/isFile}} {{paramName}}{{^-last}}, {{/-last}}{{/requiredParams}}) throws OpenApiRequestException {
{{#hasOptionalParams}}
return {{#vendorExtensions.x-sap-cloud-sdk-operation-name}}{{vendorExtensions.x-sap-cloud-sdk-operation-name}}{{/vendorExtensions.x-sap-cloud-sdk-operation-name}}{{^vendorExtensions.x-sap-cloud-sdk-operation-name}}{{operationId}}{{/vendorExtensions.x-sap-cloud-sdk-operation-name}}({{#hasRequiredParams}}{{#requiredParams}}{{paramName}}{{^-last}}, {{/-last}}{{/requiredParams}}, {{/hasRequiredParams}}{{#optionalParams}}null{{^-last}}, {{/-last}}{{/optionalParams}});
{{/hasOptionalParams}}
diff --git a/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorApacheIntegrationTest.java b/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorApacheIntegrationTest.java
index cbd349e99..33677cfd8 100644
--- a/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorApacheIntegrationTest.java
+++ b/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorApacheIntegrationTest.java
@@ -57,7 +57,8 @@ void integrationTests( final TestCase testCase, @TempDir final Path path )
.withSapCopyrightHeader(true)
.oneOfAnyOfGenerationEnabled(testCase.anyOfOneOfGenerationEnabled)
.additionalProperty("useAbstractionForFiles", "true")
- .additionalProperty("library", LIBRARY);
+ .additionalProperty("library", LIBRARY)
+ .typeMappings(testCase.typeMappings);
testCase.additionalProperties.forEach(generationConfiguration::additionalProperty);
@@ -103,7 +104,8 @@ void generateDataModelForComparison( final TestCase testCase )
.withSapCopyrightHeader(true)
.oneOfAnyOfGenerationEnabled(testCase.anyOfOneOfGenerationEnabled)
.additionalProperty("useAbstractionForFiles", "true")
- .additionalProperty("library", LIBRARY);
+ .additionalProperty("library", LIBRARY)
+ .typeMappings(testCase.typeMappings);
testCase.additionalProperties.forEach(generationConfiguration::additionalProperty);
GenerationConfiguration build = generationConfiguration.build();
diff --git a/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorIntegrationTest.java b/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorIntegrationTest.java
index 3059cfee4..2bf6cc632 100644
--- a/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorIntegrationTest.java
+++ b/datamodel/openapi/openapi-generator/src/test/java/com/sap/cloud/sdk/datamodel/openapi/generator/DataModelGeneratorIntegrationTest.java
@@ -36,7 +36,8 @@ enum TestCase
true,
true,
6,
- Map.of("aiSdkConstructor", "true", "fixRedundantIsBooleanPrefix", "true", "useFloatArrays", "true")),
+ Map.of("aiSdkConstructor", "true", "fixRedundantIsBooleanPrefix", "true", "useFloatArrays", "true"),
+ Map.of()),
API_CLASS_VENDOR_EXTENSION_YAML(
"api-class-vendor-extension-yaml",
"sodastore.yaml",
@@ -46,6 +47,7 @@ enum TestCase
false,
true,
4,
+ Map.of(),
Map.of()),
API_CLASS_VENDOR_EXTENSION_JSON(
"api-class-vendor-extension-json",
@@ -56,6 +58,7 @@ enum TestCase
false,
true,
6,
+ Map.of(),
Map.of()),
INLINEOBJECT_SCHEMA_NAME(
"inlineobject-schemas-enabled",
@@ -66,7 +69,8 @@ enum TestCase
true,
true,
5,
- Map.of("fixResponseSchemaTitles", "true")),
+ Map.of("fixResponseSchemaTitles", "true"),
+ Map.of()),
PARTIAL_GENERATION(
"partial-generation",
"sodastore.json",
@@ -80,7 +84,8 @@ enum TestCase
.ofEntries(
entry("excludePaths", "/sodas,/foobar/{baz}"),
entry("excludeProperties", "Foo.bar,Soda.embedding,Soda.flavor,UpdateSoda.flavor,SodaWithFoo.foo"),
- entry("removeUnusedComponents", "true"))),
+ entry("removeUnusedComponents", "true")),
+ Map.of()),
INPUT_SPEC_WITH_UPPERCASE_FILE_EXTENSION(
"input-spec-with-uppercase-file-extension",
"sodastore.JSON",
@@ -90,6 +95,7 @@ enum TestCase
false,
true,
6,
+ Map.of(),
Map.of()),
ONE_OF_INTERFACES_DISABLED(
"oneof-interfaces-disabled",
@@ -100,6 +106,7 @@ enum TestCase
false,
true,
9,
+ Map.of(),
Map.of()),
ONE_OF_INTERFACES_ENABLED(
"oneof-interfaces-enabled",
@@ -110,7 +117,8 @@ enum TestCase
true,
true,
11,
- Map.of("useOneOfInterfaces", "true", "useOneOfCreators", "true", "useFloatArrays", "true")),
+ Map.of("useOneOfInterfaces", "true", "useOneOfCreators", "true", "useFloatArrays", "true"),
+ Map.of()),
INPUT_SPEC_WITH_BUILDER(
"input-spec-with-builder",
"sodastore.JSON",
@@ -127,7 +135,8 @@ enum TestCase
"pojoBuildMethodName",
"build",
"pojoConstructorVisibility",
- "private")),
+ "private"),
+ Map.of()),
REMOVE_OPERATION_ID_PREFIX(
"remove-operation-id-prefix",
"sodastore.json",
@@ -144,7 +153,8 @@ enum TestCase
"removeOperationIdPrefixDelimiter",
"\\.",
"removeOperationIdPrefixCount",
- "3")),
+ "3"),
+ Map.of()),
GENERATE_APIS(
"generate-apis",
"sodastore.yaml",
@@ -154,7 +164,19 @@ enum TestCase
true,
false,
7,
- Map.of());
+ Map.of(),
+ Map.of()),
+ FILE_HANDLING(
+ "file-handling",
+ "file-handling.yaml",
+ "com.sap.cloud.sdk.services.filehandling.api",
+ "com.sap.cloud.sdk.services.filehandling.model",
+ ApiMaturity.RELEASED,
+ false,
+ true,
+ 1,
+ Map.of(),
+ Map.of("File", "byte[]"));
final String testCaseName;
final String inputSpecFileName;
@@ -165,10 +187,11 @@ enum TestCase
final boolean generateApis;
final int expectedNumberOfGeneratedFiles;
final Map
+ * API for managing sodas in a soda store
+ */
+public class FilesApi extends BaseApi {
+
+ /**
+ * Instantiates this API class to invoke operations on the Soda Store API.
+ *
+ * @param httpDestination The destination that API should be used with
+ */
+ public FilesApi( @Nonnull final Destination httpDestination )
+ {
+ super(httpDestination);
+ }
+
+ /**
+ * Instantiates this API class to invoke operations on the Soda Store API based on a given {@link ApiClient}.
+ *
+ * @param apiClient
+ * ApiClient to invoke the API on
+ */
+ public FilesApi(@Nonnull final ApiClient apiClient) {
+ super(apiClient);
+ }
+
+ /**
+ * Creates a new API instance with additional default headers.
+ *
+ * @param defaultHeaders Additional headers to include in all requests
+ * @return A new API instance with the combined headers
+ */
+ public FilesApi withDefaultHeaders(@Nonnull final Map Download a file
+ *
+ * 200 - File content as binary
+ * @return byte[]
+ * @throws OpenApiRequestException if an error occurs while attempting to invoke the API
+ */
+ @Nonnull
+ public byte[] exportFile() throws OpenApiRequestException {
+
+ // create path and map variables
+ final String localVarPath = "/files/export";
+
+ final StringJoiner localVarQueryStringJoiner = new StringJoiner("&");
+ final List Upload a file
+ *
+ * 200 - File imported successfully
+ * @param _file
+ * The value for the parameter _file
+ * @return An OpenApiResponse containing the status code of the HttpResponse.
+ * @throws OpenApiRequestException if an error occurs while attempting to invoke the API
+ */
+ @Nonnull
+ public OpenApiResponse importFile(@Nonnull final File _file) throws OpenApiRequestException {
+
+ // verify the required parameter '_file' is set
+ if (_file == null) {
+ throw new OpenApiRequestException("Missing the required parameter '_file' when calling importFile")
+ .statusCode(400);
+ }
+
+ // create path and map variables
+ final String localVarPath = "/files/import";
+
+ final StringJoiner localVarQueryStringJoiner = new StringJoiner("&");
+ final List