[scala] fix akka-scala-client template compilation warnings (#5106)

* fix akka-scala-client template compilation warnings

add COOKIE location authorization key
regenerate template

* fix scala akka-http client model imports

* fix #4004 custom package name in reference.conf

* fix scaka-akka codegen test
This commit is contained in:
Aleksandr Nekrasov
2020-02-06 21:15:43 +07:00
committed by GitHub
parent 8779fc6485
commit 1bba3a563e
23 changed files with 202 additions and 104 deletions

View File

@@ -150,12 +150,13 @@ public class ScalaAkkaClientCodegen extends AbstractScalaCodegen implements Code
super.processOpts();
if (additionalProperties.containsKey("mainPackage")) {
setMainPackage((String) additionalProperties.get("mainPackage"));
additionalProperties.replace("configKeyPath", this.configKeyPath);
apiPackage = mainPackage + ".api";
modelPackage = mainPackage + ".model";
invokerPackage = mainPackage + ".core";
additionalProperties.put("apiPackage", apiPackage);
additionalProperties.put("modelPackage", apiPackage);
additionalProperties.put("invokerPackage", apiPackage);
additionalProperties.put("modelPackage", modelPackage);
additionalProperties.put("invokerPackage", invokerPackage);
}
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
@@ -366,6 +367,6 @@ public class ScalaAkkaClientCodegen extends AbstractScalaCodegen implements Code
}
public void setMainPackage(String mainPackage) {
this.mainPackage = mainPackage;
this.configKeyPath = this.mainPackage = mainPackage;
}
}

View File

@@ -22,7 +22,7 @@ class {{classname}}(baseUrl: String) {
{{/javadocRenderer}}
def {{operationId}}({{>methodParameters}}): ApiRequest[{{>operationReturnType}}] =
ApiRequest[{{>operationReturnType}}](ApiMethods.{{httpMethod.toUpperCase}}, baseUrl, "{{{path}}}", {{#consumes.0}}"{{{mediaType}}}"{{/consumes.0}}{{^consumes}}"application/json"{{/consumes}})
{{#authMethods}}{{#isApiKey}}.withApiKey(apiKey, "{{keyParamName}}", {{#isKeyInQuery}}QUERY{{/isKeyInQuery}}{{#isKeyInHeader}}HEADER{{/isKeyInHeader}})
{{#authMethods}}{{#isApiKey}}.withApiKey(apiKey, "{{keyParamName}}", {{#isKeyInQuery}}QUERY{{/isKeyInQuery}}{{#isKeyInHeader}}HEADER{{/isKeyInHeader}}{{#isKeyInCookie}}COOKIE{{/isKeyInCookie}})
{{/isApiKey}}{{#isBasic}}.withCredentials(basicAuth)
{{/isBasic}}{{/authMethods}}{{#bodyParam}}.withBody({{paramName}})
{{/bodyParam}}{{#formParams}}.withFormParam({{>paramCreation}})

View File

@@ -45,7 +45,7 @@ object ApiInvoker {
*
* @param request the apiRequest to be executed
*/
implicit class ApiRequestImprovements[T](request: ApiRequest[T]) {
implicit class ApiRequestImprovements[T: Manifest](request: ApiRequest[T]) {
def response(invoker: ApiInvoker)(implicit ec: ExecutionContext, system: ActorSystem): Future[ApiResponse[T]] =
response(ec, system, invoker)
@@ -67,7 +67,7 @@ object ApiInvoker {
def toAkkaHttpMethod: HttpMethod = HttpMethods.getForKey(method.value).getOrElse(HttpMethods.GET)
}
case object DateTimeSerializer extends CustomSerializer[DateTime](format => ( {
case object DateTimeSerializer extends CustomSerializer[DateTime](_ => ( {
case JString(s) =>
ISODateTimeFormat.dateOptionalTimeParser().parseDateTime(s)
}, {
@@ -215,7 +215,7 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
Uri(r.basePath + opPathWithParams).withQuery(query)
}
def execute[T](r: ApiRequest[T]): Future[ApiResponse[T]] = {
def execute[T: Manifest](r: ApiRequest[T]): Future[ApiResponse[T]] = {
implicit val timeout: Timeout = settings.connectionTimeout
val request = createRequest(makeUri(r), r)
@@ -239,8 +239,8 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
.flatMap(unmarshallApiResponse(r))
}
def unmarshallApiResponse[T](request: ApiRequest[T])(response: HttpResponse): Future[ApiResponse[T]] = {
def responseForState[V](state: ResponseState, value: V) = {
def unmarshallApiResponse[T: Manifest](request: ApiRequest[T])(response: HttpResponse): Future[ApiResponse[T]] = {
def responseForState[V](state: ResponseState, value: V): ApiResponse[V] = {
state match {
case ResponseState.Success =>
ApiResponse(response.status.intValue, value, response.headers.map(header => (header.name, header.value)).toMap)
@@ -253,31 +253,29 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
)
}
}
val mf = implicitly(manifest[T])
request
.responseForCode(response.status.intValue)
.map {
case (Manifest.Unit, state: ResponseState) =>
// FIXME Casting is ugly, how to do better?
Future(responseForState(state, Unit)).asInstanceOf[Future[ApiResponse[T]]]
case (manifest: Manifest[T], state: ResponseState) =>
implicit val m: Unmarshaller[HttpEntity, T] = unmarshaller[T](manifest, serialization, formats)
Unmarshal(response.entity)
.to[T]
.recoverWith {
case e ⇒ throw ApiError(response.status.intValue, s"Unable to unmarshall content to [$manifest]", Some(response.entity.toString), e)
}
.map(value => responseForState(state, value))
}
.getOrElse(Future.failed(ApiError(response.status.intValue, "Unexpected response code", Some(response.entity.toString))))
.responseForCode(response.status.intValue) match {
case Some((Manifest.Unit, state: ResponseState)) =>
Future(responseForState(state, Unit).asInstanceOf[ApiResponse[T]])
case Some((manifest, state: ResponseState)) if manifest == mf =>
implicit val m: Unmarshaller[HttpEntity, T] = unmarshaller[T](mf, serialization, formats)
Unmarshal(response.entity)
.to[T]
.recoverWith {
case e ⇒ throw ApiError(response.status.intValue, s"Unable to unmarshall content to [$manifest]", Some(response.entity.toString), e)
}
.map(value => responseForState(state, value))
case None | Some(_) =>
Future.failed(ApiError(response.status.intValue, "Unexpected response code", Some(response.entity.toString)))
}
}
}
sealed trait CustomContentTypes {
protected def normalizedContentType(original: String): ContentType =
ContentType(MediaTypes.forExtension(original), () => HttpCharsets.`UTF-8`)
ContentType(parseContentType(original).mediaType, () => HttpCharsets.`UTF-8`)
protected def parseContentType(contentType: String): ContentType = {

View File

@@ -1,9 +1,10 @@
{{>licenseInfo}}
package {{package}}
{{#imports}}
import {{import}}
{{/imports}}
import {{mainPackage}}.core.ApiModel
import org.joda.time.DateTime
import java.util.UUID
{{#models}}
{{#model}}

View File

@@ -85,6 +85,8 @@ object ApiKeyLocations {
case object HEADER extends ApiKeyLocation
case object COOKIE extends ApiKeyLocation
}

View File

@@ -26,6 +26,15 @@ paths:
description: ''
operationId: addPet
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:
@@ -41,6 +50,15 @@ paths:
description: ''
operationId: updatePet
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':

View File

@@ -11,9 +11,8 @@
*/
package hello.world.model
import hello.world.core.ApiModel
import org.joda.time.DateTime
import java.util.UUID
import hello.world.core.ApiModel
case class SomeObj (
`type`: Option[SomeObjEnums.`Type`] = None,