From 2a196ce3620aebf9e5ce0c9a17ee8e0c5365afb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Bartolo=20Burl=C3=B2?= Date: Mon, 15 Aug 2022 12:42:06 +0200 Subject: [PATCH] Fixed scala-sttp generator (#11949) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fixed scala-sttp generator * pr checklist * fixed issue with imports in scala-sttp * fixed samples * changed isUnit to isDefault * fixed errors * Update modules/openapi-generator/src/main/resources/scala-sttp/api.mustache Co-authored-by: João Ferreira * updated samples Co-authored-by: João Ferreira --- docs/generators/scala-sttp.md | 2 ++ .../codegen/CodegenOperation.java | 2 +- .../openapitools/codegen/DefaultCodegen.java | 3 +++ .../languages/ScalaSttpClientCodegen.java | 8 +++---- .../main/resources/scala-sttp/api.mustache | 4 ++-- .../org/openapitools/client/api/PetApi.scala | 16 ++++++------- .../openapitools/client/api/StoreApi.scala | 8 +++---- .../org/openapitools/client/api/UserApi.scala | 24 +++++++++---------- 8 files changed, 36 insertions(+), 31 deletions(-) diff --git a/docs/generators/scala-sttp.md b/docs/generators/scala-sttp.md index 089a70ac9895..c56f756df9e9 100644 --- a/docs/generators/scala-sttp.md +++ b/docs/generators/scala-sttp.md @@ -53,6 +53,8 @@ These options may be applied as additional-properties (cli) or configOptions (pl |LocalDate|org.joda.time.*| |LocalDateTime|org.joda.time.*| |LocalTime|org.joda.time.*| +|Seq|scala.collection.immutable.Seq| +|Set|scala.collection.immutable.Set| |Timestamp|java.sql.Timestamp| |URI|java.net.URI| |UUID|java.util.UUID| diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenOperation.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenOperation.java index 16daa41f580f..7051777e5ca0 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenOperation.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenOperation.java @@ -27,7 +27,7 @@ public class CodegenOperation { public boolean hasAuthMethods, hasConsumes, hasProduces, hasParams, hasOptionalParams, hasRequiredParams, returnTypeIsPrimitive, returnSimpleType, subresourceOperation, isMap, isArray, isMultipart, - isResponseBinary = false, isResponseFile = false, isResponseOptional = false, hasReference = false, + isResponseBinary = false, isResponseFile = false, isResponseOptional = false, hasReference = false, defaultReturnType = false, isRestfulIndex, isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy, isRestful, isDeprecated, isCallbackRequest, uniqueItems, hasDefaultResponse = false, hasErrorResponseObject; // if 4xx, 5xx responses have at least one error object defined diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 666b0b9955f3..604bce325ebe 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -4187,6 +4187,9 @@ public CodegenOperation fromOperation(String path, if (Boolean.TRUE.equals(r.isFile) && Boolean.TRUE.equals(r.is2xx) && Boolean.FALSE.equals(op.isResponseFile)) { op.isResponseFile = Boolean.TRUE; } + if (Boolean.TRUE.equals(r.isDefault)) { + op.defaultReturnType = Boolean.TRUE; + } // check if any 4xx or 5xx response has an error response object defined if ((Boolean.TRUE.equals(r.is4xx) || Boolean.TRUE.equals(r.is5xx)) && diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaSttpClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaSttpClientCodegen.java index e9d9039220c5..da71ba41601b 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaSttpClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/ScalaSttpClientCodegen.java @@ -127,10 +127,10 @@ public ScalaSttpClientCodegen() { additionalProperties.put("fnCamelize", new CamelizeLambda(false)); additionalProperties.put("fnEnumEntry", new EnumEntryLambda()); - importMapping.remove("Seq"); - importMapping.remove("List"); - importMapping.remove("Set"); - importMapping.remove("Map"); +// importMapping.remove("Seq"); +// importMapping.remove("List"); +// importMapping.remove("Set"); +// importMapping.remove("Map"); // TODO: there is no specific sttp mapping. All Scala Type mappings should be in AbstractScala typeMapping = new HashMap<>(); diff --git a/modules/openapi-generator/src/main/resources/scala-sttp/api.mustache b/modules/openapi-generator/src/main/resources/scala-sttp/api.mustache index f7d5ba6f8257..29ef3ce991bb 100644 --- a/modules/openapi-generator/src/main/resources/scala-sttp/api.mustache +++ b/modules/openapi-generator/src/main/resources/scala-sttp/api.mustache @@ -20,7 +20,7 @@ class {{classname}}(baseUrl: String) { {{#javadocRenderer}} {{>javadoc}} {{/javadocRenderer}} - def {{operationId}}({{>methodParameters}}): Request[{{#separateErrorChannel}}Either[ResponseException[String, Exception], {{>operationReturnType}}]{{/separateErrorChannel}}{{^separateErrorChannel}}{{>operationReturnType}}{{/separateErrorChannel}}, Nothing] = + def {{operationId}}({{>methodParameters}}): Request[{{#defaultReturnType}}Either[Either[String, String], Unit]{{/defaultReturnType}}{{^defaultReturnType}}{{#separateErrorChannel}}Either[ResponseException[String, Exception], {{>operationReturnType}}]{{/separateErrorChannel}}{{^separateErrorChannel}}{{>operationReturnType}}{{/separateErrorChannel}}{{/defaultReturnType}}, Any] = basicRequest .method(Method.{{httpMethod.toUpperCase}}, uri"$baseUrl{{{path}}}{{#queryParams.0}}?{{#queryParams}}{{baseName}}=${ {{{paramName}}} }{{^-last}}&{{/-last}}{{/queryParams}}{{/queryParams.0}}{{#isApiKey}}{{#isKeyInQuery}}{{^queryParams.0}}?{{/queryParams.0}}{{#queryParams.0}}&{{/queryParams.0}}{{keyParamName}}=${apiKey.value}&{{/isKeyInQuery}}{{/isApiKey}}") .contentType({{#consumes.0}}"{{{mediaType}}}"{{/consumes.0}}{{^consumes}}"application/json"{{/consumes}}){{#headerParams}} @@ -36,7 +36,7 @@ class {{classname}}(baseUrl: String) { {{>paramMultipartCreation}}{{^-last}}, {{/-last}}{{/formParams}} ).flatten){{/isMultipart}}{{/formParams.0}}{{#bodyParam}} .body({{paramName}}){{/bodyParam}} - .response({{#separateErrorChannel}}asJson{{/separateErrorChannel}}{{^separateErrorChannel}}asJsonAlwaysUnsafe{{/separateErrorChannel}}[{{>operationReturnType}}]) + .response({{#defaultReturnType}}asEither(asString, ignore){{/defaultReturnType}}{{^defaultReturnType}}{{#separateErrorChannel}}asJson{{/separateErrorChannel}}{{^separateErrorChannel}}asJsonAlwaysUnsafe{{/separateErrorChannel}}[{{>operationReturnType}}]{{/defaultReturnType}}) {{/operation}} } diff --git a/samples/client/petstore/scala-sttp/src/main/scala/org/openapitools/client/api/PetApi.scala b/samples/client/petstore/scala-sttp/src/main/scala/org/openapitools/client/api/PetApi.scala index 3f6ad7782ee4..e4897aa24163 100644 --- a/samples/client/petstore/scala-sttp/src/main/scala/org/openapitools/client/api/PetApi.scala +++ b/samples/client/petstore/scala-sttp/src/main/scala/org/openapitools/client/api/PetApi.scala @@ -35,7 +35,7 @@ class PetApi(baseUrl: String) { * @param pet Pet object that needs to be added to the store */ def addPet(pet: Pet -): Request[Either[ResponseException[String, Exception], Pet], Nothing] = +): Request[Either[ResponseException[String, Exception], Pet], Any] = basicRequest .method(Method.POST, uri"$baseUrl/pet") .contentType("application/json") @@ -52,7 +52,7 @@ class PetApi(baseUrl: String) { * @param apiKey */ def deletePet(petId: Long, apiKey: Option[String] = None -): Request[Either[ResponseException[String, Exception], Unit], Nothing] = +): Request[Either[ResponseException[String, Exception], Unit], Any] = basicRequest .method(Method.DELETE, uri"$baseUrl/pet/${petId}") .contentType("application/json") @@ -69,7 +69,7 @@ class PetApi(baseUrl: String) { * @param status Status values that need to be considered for filter */ def findPetsByStatus(status: Seq[String] -): Request[Either[ResponseException[String, Exception], Seq[Pet]], Nothing] = +): Request[Either[ResponseException[String, Exception], Seq[Pet]], Any] = basicRequest .method(Method.GET, uri"$baseUrl/pet/findByStatus?status=${ status }") .contentType("application/json") @@ -85,7 +85,7 @@ class PetApi(baseUrl: String) { * @param tags Tags to filter by */ def findPetsByTags(tags: Seq[String] -): Request[Either[ResponseException[String, Exception], Seq[Pet]], Nothing] = +): Request[Either[ResponseException[String, Exception], Seq[Pet]], Any] = basicRequest .method(Method.GET, uri"$baseUrl/pet/findByTags?tags=${ tags }") .contentType("application/json") @@ -105,7 +105,7 @@ class PetApi(baseUrl: String) { * @param petId ID of pet to return */ def getPetById(apiKey: String)(petId: Long -): Request[Either[ResponseException[String, Exception], Pet], Nothing] = +): Request[Either[ResponseException[String, Exception], Pet], Any] = basicRequest .method(Method.GET, uri"$baseUrl/pet/${petId}") .contentType("application/json") @@ -124,7 +124,7 @@ class PetApi(baseUrl: String) { * @param pet Pet object that needs to be added to the store */ def updatePet(pet: Pet -): Request[Either[ResponseException[String, Exception], Pet], Nothing] = +): Request[Either[ResponseException[String, Exception], Pet], Any] = basicRequest .method(Method.PUT, uri"$baseUrl/pet") .contentType("application/json") @@ -142,7 +142,7 @@ class PetApi(baseUrl: String) { * @param status Updated status of the pet */ def updatePetWithForm(petId: Long, name: Option[String] = None, status: Option[String] = None -): Request[Either[ResponseException[String, Exception], Unit], Nothing] = +): Request[Either[ResponseException[String, Exception], Unit], Any] = basicRequest .method(Method.POST, uri"$baseUrl/pet/${petId}") .contentType("application/x-www-form-urlencoded") @@ -163,7 +163,7 @@ class PetApi(baseUrl: String) { * @param file file to upload */ def uploadFile(petId: Long, additionalMetadata: Option[String] = None, file: Option[File] = None -): Request[Either[ResponseException[String, Exception], ApiResponse], Nothing] = +): Request[Either[ResponseException[String, Exception], ApiResponse], Any] = basicRequest .method(Method.POST, uri"$baseUrl/pet/${petId}/uploadImage") .contentType("multipart/form-data") diff --git a/samples/client/petstore/scala-sttp/src/main/scala/org/openapitools/client/api/StoreApi.scala b/samples/client/petstore/scala-sttp/src/main/scala/org/openapitools/client/api/StoreApi.scala index d98fb71e185e..e4db9be33b9b 100644 --- a/samples/client/petstore/scala-sttp/src/main/scala/org/openapitools/client/api/StoreApi.scala +++ b/samples/client/petstore/scala-sttp/src/main/scala/org/openapitools/client/api/StoreApi.scala @@ -33,7 +33,7 @@ class StoreApi(baseUrl: String) { * @param orderId ID of the order that needs to be deleted */ def deleteOrder(orderId: String -): Request[Either[ResponseException[String, Exception], Unit], Nothing] = +): Request[Either[ResponseException[String, Exception], Unit], Any] = basicRequest .method(Method.DELETE, uri"$baseUrl/store/order/${orderId}") .contentType("application/json") @@ -49,7 +49,7 @@ class StoreApi(baseUrl: String) { * api_key (apiKey) */ def getInventory(apiKey: String)( -): Request[Either[ResponseException[String, Exception], Map[String, Int]], Nothing] = +): Request[Either[ResponseException[String, Exception], Map[String, Int]], Any] = basicRequest .method(Method.GET, uri"$baseUrl/store/inventory") .contentType("application/json") @@ -67,7 +67,7 @@ class StoreApi(baseUrl: String) { * @param orderId ID of pet that needs to be fetched */ def getOrderById(orderId: Long -): Request[Either[ResponseException[String, Exception], Order], Nothing] = +): Request[Either[ResponseException[String, Exception], Order], Any] = basicRequest .method(Method.GET, uri"$baseUrl/store/order/${orderId}") .contentType("application/json") @@ -83,7 +83,7 @@ class StoreApi(baseUrl: String) { * @param order order placed for purchasing the pet */ def placeOrder(order: Order -): Request[Either[ResponseException[String, Exception], Order], Nothing] = +): Request[Either[ResponseException[String, Exception], Order], Any] = basicRequest .method(Method.POST, uri"$baseUrl/store/order") .contentType("application/json") diff --git a/samples/client/petstore/scala-sttp/src/main/scala/org/openapitools/client/api/UserApi.scala b/samples/client/petstore/scala-sttp/src/main/scala/org/openapitools/client/api/UserApi.scala index ee236f92f51b..6f035512fc27 100644 --- a/samples/client/petstore/scala-sttp/src/main/scala/org/openapitools/client/api/UserApi.scala +++ b/samples/client/petstore/scala-sttp/src/main/scala/org/openapitools/client/api/UserApi.scala @@ -36,13 +36,13 @@ class UserApi(baseUrl: String) { * @param user Created user object */ def createUser(apiKey: String)(user: User -): Request[Either[ResponseException[String, Exception], Unit], Nothing] = +): Request[Either[Either[String, String], Unit], Any] = basicRequest .method(Method.POST, uri"$baseUrl/user") .contentType("application/json") .header("api_key", apiKey) .body(user) - .response(asJson[Unit]) + .response(asEither(asString, ignore)) /** * @@ -56,13 +56,13 @@ class UserApi(baseUrl: String) { * @param user List of user object */ def createUsersWithArrayInput(apiKey: String)(user: Seq[User] -): Request[Either[ResponseException[String, Exception], Unit], Nothing] = +): Request[Either[Either[String, String], Unit], Any] = basicRequest .method(Method.POST, uri"$baseUrl/user/createWithArray") .contentType("application/json") .header("api_key", apiKey) .body(user) - .response(asJson[Unit]) + .response(asEither(asString, ignore)) /** * @@ -76,13 +76,13 @@ class UserApi(baseUrl: String) { * @param user List of user object */ def createUsersWithListInput(apiKey: String)(user: Seq[User] -): Request[Either[ResponseException[String, Exception], Unit], Nothing] = +): Request[Either[Either[String, String], Unit], Any] = basicRequest .method(Method.POST, uri"$baseUrl/user/createWithList") .contentType("application/json") .header("api_key", apiKey) .body(user) - .response(asJson[Unit]) + .response(asEither(asString, ignore)) /** * This can only be done by the logged in user. @@ -97,7 +97,7 @@ class UserApi(baseUrl: String) { * @param username The name that needs to be deleted */ def deleteUser(apiKey: String)(username: String -): Request[Either[ResponseException[String, Exception], Unit], Nothing] = +): Request[Either[ResponseException[String, Exception], Unit], Any] = basicRequest .method(Method.DELETE, uri"$baseUrl/user/${username}") .contentType("application/json") @@ -115,7 +115,7 @@ class UserApi(baseUrl: String) { * @param username The name that needs to be fetched. Use user1 for testing. */ def getUserByName(username: String -): Request[Either[ResponseException[String, Exception], User], Nothing] = +): Request[Either[ResponseException[String, Exception], User], Any] = basicRequest .method(Method.GET, uri"$baseUrl/user/${username}") .contentType("application/json") @@ -136,7 +136,7 @@ class UserApi(baseUrl: String) { * @param password The password for login in clear text */ def loginUser(username: String, password: String -): Request[Either[ResponseException[String, Exception], String], Nothing] = +): Request[Either[ResponseException[String, Exception], String], Any] = basicRequest .method(Method.GET, uri"$baseUrl/user/login?username=${ username }&password=${ password }") .contentType("application/json") @@ -152,12 +152,12 @@ class UserApi(baseUrl: String) { * api_key (apiKey) */ def logoutUser(apiKey: String)( -): Request[Either[ResponseException[String, Exception], Unit], Nothing] = +): Request[Either[Either[String, String], Unit], Any] = basicRequest .method(Method.GET, uri"$baseUrl/user/logout") .contentType("application/json") .header("api_key", apiKey) - .response(asJson[Unit]) + .response(asEither(asString, ignore)) /** * This can only be done by the logged in user. @@ -173,7 +173,7 @@ class UserApi(baseUrl: String) { * @param user Updated user object */ def updateUser(apiKey: String)(username: String, user: User -): Request[Either[ResponseException[String, Exception], Unit], Nothing] = +): Request[Either[ResponseException[String, Exception], Unit], Any] = basicRequest .method(Method.PUT, uri"$baseUrl/user/${username}") .contentType("application/json")