forked from loafle/openapi-generator-original
[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:
parent
8779fc6485
commit
1bba3a563e
@ -150,12 +150,13 @@ public class ScalaAkkaClientCodegen extends AbstractScalaCodegen implements Code
|
|||||||
super.processOpts();
|
super.processOpts();
|
||||||
if (additionalProperties.containsKey("mainPackage")) {
|
if (additionalProperties.containsKey("mainPackage")) {
|
||||||
setMainPackage((String) additionalProperties.get("mainPackage"));
|
setMainPackage((String) additionalProperties.get("mainPackage"));
|
||||||
|
additionalProperties.replace("configKeyPath", this.configKeyPath);
|
||||||
apiPackage = mainPackage + ".api";
|
apiPackage = mainPackage + ".api";
|
||||||
modelPackage = mainPackage + ".model";
|
modelPackage = mainPackage + ".model";
|
||||||
invokerPackage = mainPackage + ".core";
|
invokerPackage = mainPackage + ".core";
|
||||||
additionalProperties.put("apiPackage", apiPackage);
|
additionalProperties.put("apiPackage", apiPackage);
|
||||||
additionalProperties.put("modelPackage", apiPackage);
|
additionalProperties.put("modelPackage", modelPackage);
|
||||||
additionalProperties.put("invokerPackage", apiPackage);
|
additionalProperties.put("invokerPackage", invokerPackage);
|
||||||
}
|
}
|
||||||
|
|
||||||
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||||
@ -366,6 +367,6 @@ public class ScalaAkkaClientCodegen extends AbstractScalaCodegen implements Code
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setMainPackage(String mainPackage) {
|
public void setMainPackage(String mainPackage) {
|
||||||
this.mainPackage = mainPackage;
|
this.configKeyPath = this.mainPackage = mainPackage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ class {{classname}}(baseUrl: String) {
|
|||||||
{{/javadocRenderer}}
|
{{/javadocRenderer}}
|
||||||
def {{operationId}}({{>methodParameters}}): ApiRequest[{{>operationReturnType}}] =
|
def {{operationId}}({{>methodParameters}}): ApiRequest[{{>operationReturnType}}] =
|
||||||
ApiRequest[{{>operationReturnType}}](ApiMethods.{{httpMethod.toUpperCase}}, baseUrl, "{{{path}}}", {{#consumes.0}}"{{{mediaType}}}"{{/consumes.0}}{{^consumes}}"application/json"{{/consumes}})
|
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)
|
{{/isApiKey}}{{#isBasic}}.withCredentials(basicAuth)
|
||||||
{{/isBasic}}{{/authMethods}}{{#bodyParam}}.withBody({{paramName}})
|
{{/isBasic}}{{/authMethods}}{{#bodyParam}}.withBody({{paramName}})
|
||||||
{{/bodyParam}}{{#formParams}}.withFormParam({{>paramCreation}})
|
{{/bodyParam}}{{#formParams}}.withFormParam({{>paramCreation}})
|
||||||
|
@ -45,7 +45,7 @@ object ApiInvoker {
|
|||||||
*
|
*
|
||||||
* @param request the apiRequest to be executed
|
* @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]] =
|
def response(invoker: ApiInvoker)(implicit ec: ExecutionContext, system: ActorSystem): Future[ApiResponse[T]] =
|
||||||
response(ec, system, invoker)
|
response(ec, system, invoker)
|
||||||
@ -67,7 +67,7 @@ object ApiInvoker {
|
|||||||
def toAkkaHttpMethod: HttpMethod = HttpMethods.getForKey(method.value).getOrElse(HttpMethods.GET)
|
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) =>
|
case JString(s) =>
|
||||||
ISODateTimeFormat.dateOptionalTimeParser().parseDateTime(s)
|
ISODateTimeFormat.dateOptionalTimeParser().parseDateTime(s)
|
||||||
}, {
|
}, {
|
||||||
@ -215,7 +215,7 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
|
|||||||
Uri(r.basePath + opPathWithParams).withQuery(query)
|
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
|
implicit val timeout: Timeout = settings.connectionTimeout
|
||||||
|
|
||||||
val request = createRequest(makeUri(r), r)
|
val request = createRequest(makeUri(r), r)
|
||||||
@ -239,8 +239,8 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
|
|||||||
.flatMap(unmarshallApiResponse(r))
|
.flatMap(unmarshallApiResponse(r))
|
||||||
}
|
}
|
||||||
|
|
||||||
def unmarshallApiResponse[T](request: ApiRequest[T])(response: HttpResponse): Future[ApiResponse[T]] = {
|
def unmarshallApiResponse[T: Manifest](request: ApiRequest[T])(response: HttpResponse): Future[ApiResponse[T]] = {
|
||||||
def responseForState[V](state: ResponseState, value: V) = {
|
def responseForState[V](state: ResponseState, value: V): ApiResponse[V] = {
|
||||||
state match {
|
state match {
|
||||||
case ResponseState.Success =>
|
case ResponseState.Success =>
|
||||||
ApiResponse(response.status.intValue, value, response.headers.map(header => (header.name, header.value)).toMap)
|
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
|
request
|
||||||
.responseForCode(response.status.intValue)
|
.responseForCode(response.status.intValue) match {
|
||||||
.map {
|
case Some((Manifest.Unit, state: ResponseState)) =>
|
||||||
case (Manifest.Unit, state: ResponseState) =>
|
Future(responseForState(state, Unit).asInstanceOf[ApiResponse[T]])
|
||||||
// FIXME Casting is ugly, how to do better?
|
case Some((manifest, state: ResponseState)) if manifest == mf =>
|
||||||
Future(responseForState(state, Unit)).asInstanceOf[Future[ApiResponse[T]]]
|
implicit val m: Unmarshaller[HttpEntity, T] = unmarshaller[T](mf, serialization, formats)
|
||||||
case (manifest: Manifest[T], state: ResponseState) =>
|
Unmarshal(response.entity)
|
||||||
implicit val m: Unmarshaller[HttpEntity, T] = unmarshaller[T](manifest, serialization, formats)
|
.to[T]
|
||||||
|
.recoverWith {
|
||||||
Unmarshal(response.entity)
|
case e ⇒ throw ApiError(response.status.intValue, s"Unable to unmarshall content to [$manifest]", Some(response.entity.toString), e)
|
||||||
.to[T]
|
}
|
||||||
.recoverWith {
|
.map(value => responseForState(state, value))
|
||||||
case e ⇒ throw ApiError(response.status.intValue, s"Unable to unmarshall content to [$manifest]", Some(response.entity.toString), e)
|
case None | Some(_) =>
|
||||||
}
|
Future.failed(ApiError(response.status.intValue, "Unexpected response code", Some(response.entity.toString)))
|
||||||
.map(value => responseForState(state, value))
|
}
|
||||||
}
|
|
||||||
.getOrElse(Future.failed(ApiError(response.status.intValue, "Unexpected response code", Some(response.entity.toString))))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed trait CustomContentTypes {
|
sealed trait CustomContentTypes {
|
||||||
|
|
||||||
protected def normalizedContentType(original: String): ContentType =
|
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 = {
|
protected def parseContentType(contentType: String): ContentType = {
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
{{>licenseInfo}}
|
{{>licenseInfo}}
|
||||||
package {{package}}
|
package {{package}}
|
||||||
|
|
||||||
|
{{#imports}}
|
||||||
|
import {{import}}
|
||||||
|
{{/imports}}
|
||||||
import {{mainPackage}}.core.ApiModel
|
import {{mainPackage}}.core.ApiModel
|
||||||
import org.joda.time.DateTime
|
|
||||||
import java.util.UUID
|
|
||||||
|
|
||||||
{{#models}}
|
{{#models}}
|
||||||
{{#model}}
|
{{#model}}
|
||||||
|
@ -85,6 +85,8 @@ object ApiKeyLocations {
|
|||||||
|
|
||||||
case object HEADER extends ApiKeyLocation
|
case object HEADER extends ApiKeyLocation
|
||||||
|
|
||||||
|
case object COOKIE extends ApiKeyLocation
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,6 +26,15 @@ paths:
|
|||||||
description: ''
|
description: ''
|
||||||
operationId: addPet
|
operationId: addPet
|
||||||
responses:
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
'405':
|
'405':
|
||||||
description: Invalid input
|
description: Invalid input
|
||||||
security:
|
security:
|
||||||
@ -41,6 +50,15 @@ paths:
|
|||||||
description: ''
|
description: ''
|
||||||
operationId: updatePet
|
operationId: updatePet
|
||||||
responses:
|
responses:
|
||||||
|
'200':
|
||||||
|
description: successful operation
|
||||||
|
content:
|
||||||
|
application/xml:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Pet'
|
||||||
'400':
|
'400':
|
||||||
description: Invalid ID supplied
|
description: Invalid ID supplied
|
||||||
'404':
|
'404':
|
||||||
|
@ -11,9 +11,8 @@
|
|||||||
*/
|
*/
|
||||||
package hello.world.model
|
package hello.world.model
|
||||||
|
|
||||||
import hello.world.core.ApiModel
|
|
||||||
import org.joda.time.DateTime
|
import org.joda.time.DateTime
|
||||||
import java.util.UUID
|
import hello.world.core.ApiModel
|
||||||
|
|
||||||
case class SomeObj (
|
case class SomeObj (
|
||||||
`type`: Option[SomeObjEnums.`Type`] = None,
|
`type`: Option[SomeObjEnums.`Type`] = None,
|
||||||
|
@ -91,6 +91,8 @@ Class | Method | HTTP request | Description
|
|||||||
|
|
||||||
- [ApiResponse](ApiResponse.md)
|
- [ApiResponse](ApiResponse.md)
|
||||||
- [Category](Category.md)
|
- [Category](Category.md)
|
||||||
|
- [InlineObject](InlineObject.md)
|
||||||
|
- [InlineObject1](InlineObject1.md)
|
||||||
- [Order](Order.md)
|
- [Order](Order.md)
|
||||||
- [Pet](Pet.md)
|
- [Pet](Pet.md)
|
||||||
- [Tag](Tag.md)
|
- [Tag](Tag.md)
|
||||||
@ -106,6 +108,12 @@ Authentication schemes defined for the API:
|
|||||||
- **API key parameter name**: api_key
|
- **API key parameter name**: api_key
|
||||||
- **Location**: HTTP header
|
- **Location**: HTTP header
|
||||||
|
|
||||||
|
### auth_cookie
|
||||||
|
|
||||||
|
- **Type**: API key
|
||||||
|
- **API key parameter name**: AUTH_KEY
|
||||||
|
- **Location**:
|
||||||
|
|
||||||
|
|
||||||
## Author
|
## Author
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
sbt.version=1.2.8
|
sbt.version=1.3.6
|
||||||
|
@ -27,13 +27,15 @@ class PetApi(baseUrl: String) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Expected answers:
|
* Expected answers:
|
||||||
|
* code 200 : Pet (successful operation)
|
||||||
* code 405 : (Invalid input)
|
* code 405 : (Invalid input)
|
||||||
*
|
*
|
||||||
* @param body Pet object that needs to be added to the store
|
* @param pet Pet object that needs to be added to the store
|
||||||
*/
|
*/
|
||||||
def addPet(body: Pet): ApiRequest[Unit] =
|
def addPet(pet: Pet): ApiRequest[Pet] =
|
||||||
ApiRequest[Unit](ApiMethods.POST, baseUrl, "/pet", "application/json")
|
ApiRequest[Pet](ApiMethods.POST, baseUrl, "/pet", "application/json")
|
||||||
.withBody(body)
|
.withBody(pet)
|
||||||
|
.withSuccessResponse[Pet](200)
|
||||||
.withErrorResponse[Unit](405)
|
.withErrorResponse[Unit](405)
|
||||||
|
|
||||||
|
|
||||||
@ -107,15 +109,17 @@ class PetApi(baseUrl: String) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Expected answers:
|
* Expected answers:
|
||||||
|
* code 200 : Pet (successful operation)
|
||||||
* code 400 : (Invalid ID supplied)
|
* code 400 : (Invalid ID supplied)
|
||||||
* code 404 : (Pet not found)
|
* code 404 : (Pet not found)
|
||||||
* code 405 : (Validation exception)
|
* code 405 : (Validation exception)
|
||||||
*
|
*
|
||||||
* @param body Pet object that needs to be added to the store
|
* @param pet Pet object that needs to be added to the store
|
||||||
*/
|
*/
|
||||||
def updatePet(body: Pet): ApiRequest[Unit] =
|
def updatePet(pet: Pet): ApiRequest[Pet] =
|
||||||
ApiRequest[Unit](ApiMethods.PUT, baseUrl, "/pet", "application/json")
|
ApiRequest[Pet](ApiMethods.PUT, baseUrl, "/pet", "application/json")
|
||||||
.withBody(body)
|
.withBody(pet)
|
||||||
|
.withSuccessResponse[Pet](200)
|
||||||
.withErrorResponse[Unit](400)
|
.withErrorResponse[Unit](400)
|
||||||
.withErrorResponse[Unit](404)
|
.withErrorResponse[Unit](404)
|
||||||
.withErrorResponse[Unit](405)
|
.withErrorResponse[Unit](405)
|
||||||
|
@ -77,11 +77,11 @@ class StoreApi(baseUrl: String) {
|
|||||||
* code 200 : Order (successful operation)
|
* code 200 : Order (successful operation)
|
||||||
* code 400 : (Invalid Order)
|
* code 400 : (Invalid Order)
|
||||||
*
|
*
|
||||||
* @param body order placed for purchasing the pet
|
* @param order order placed for purchasing the pet
|
||||||
*/
|
*/
|
||||||
def placeOrder(body: Order): ApiRequest[Order] =
|
def placeOrder(order: Order): ApiRequest[Order] =
|
||||||
ApiRequest[Order](ApiMethods.POST, baseUrl, "/store/order", "application/json")
|
ApiRequest[Order](ApiMethods.POST, baseUrl, "/store/order", "application/json")
|
||||||
.withBody(body)
|
.withBody(order)
|
||||||
.withSuccessResponse[Order](200)
|
.withSuccessResponse[Order](200)
|
||||||
.withErrorResponse[Unit](400)
|
.withErrorResponse[Unit](400)
|
||||||
|
|
||||||
|
@ -29,11 +29,15 @@ class UserApi(baseUrl: String) {
|
|||||||
* Expected answers:
|
* Expected answers:
|
||||||
* code 0 : (successful operation)
|
* code 0 : (successful operation)
|
||||||
*
|
*
|
||||||
* @param body Created user object
|
* Available security schemes:
|
||||||
|
* auth_cookie (apiKey)
|
||||||
|
*
|
||||||
|
* @param user Created user object
|
||||||
*/
|
*/
|
||||||
def createUser(body: User): ApiRequest[Unit] =
|
def createUser(user: User)(implicit apiKey: ApiKeyValue): ApiRequest[Unit] =
|
||||||
ApiRequest[Unit](ApiMethods.POST, baseUrl, "/user", "application/json")
|
ApiRequest[Unit](ApiMethods.POST, baseUrl, "/user", "application/json")
|
||||||
.withBody(body)
|
.withApiKey(apiKey, "AUTH_KEY", COOKIE)
|
||||||
|
.withBody(user)
|
||||||
.withDefaultSuccessResponse[Unit]
|
.withDefaultSuccessResponse[Unit]
|
||||||
|
|
||||||
|
|
||||||
@ -41,11 +45,15 @@ class UserApi(baseUrl: String) {
|
|||||||
* Expected answers:
|
* Expected answers:
|
||||||
* code 0 : (successful operation)
|
* code 0 : (successful operation)
|
||||||
*
|
*
|
||||||
* @param body List of user object
|
* Available security schemes:
|
||||||
|
* auth_cookie (apiKey)
|
||||||
|
*
|
||||||
|
* @param user List of user object
|
||||||
*/
|
*/
|
||||||
def createUsersWithArrayInput(body: Seq[User]): ApiRequest[Unit] =
|
def createUsersWithArrayInput(user: Seq[User])(implicit apiKey: ApiKeyValue): ApiRequest[Unit] =
|
||||||
ApiRequest[Unit](ApiMethods.POST, baseUrl, "/user/createWithArray", "application/json")
|
ApiRequest[Unit](ApiMethods.POST, baseUrl, "/user/createWithArray", "application/json")
|
||||||
.withBody(body)
|
.withApiKey(apiKey, "AUTH_KEY", COOKIE)
|
||||||
|
.withBody(user)
|
||||||
.withDefaultSuccessResponse[Unit]
|
.withDefaultSuccessResponse[Unit]
|
||||||
|
|
||||||
|
|
||||||
@ -53,11 +61,15 @@ class UserApi(baseUrl: String) {
|
|||||||
* Expected answers:
|
* Expected answers:
|
||||||
* code 0 : (successful operation)
|
* code 0 : (successful operation)
|
||||||
*
|
*
|
||||||
* @param body List of user object
|
* Available security schemes:
|
||||||
|
* auth_cookie (apiKey)
|
||||||
|
*
|
||||||
|
* @param user List of user object
|
||||||
*/
|
*/
|
||||||
def createUsersWithListInput(body: Seq[User]): ApiRequest[Unit] =
|
def createUsersWithListInput(user: Seq[User])(implicit apiKey: ApiKeyValue): ApiRequest[Unit] =
|
||||||
ApiRequest[Unit](ApiMethods.POST, baseUrl, "/user/createWithList", "application/json")
|
ApiRequest[Unit](ApiMethods.POST, baseUrl, "/user/createWithList", "application/json")
|
||||||
.withBody(body)
|
.withApiKey(apiKey, "AUTH_KEY", COOKIE)
|
||||||
|
.withBody(user)
|
||||||
.withDefaultSuccessResponse[Unit]
|
.withDefaultSuccessResponse[Unit]
|
||||||
|
|
||||||
|
|
||||||
@ -68,10 +80,14 @@ class UserApi(baseUrl: String) {
|
|||||||
* code 400 : (Invalid username supplied)
|
* code 400 : (Invalid username supplied)
|
||||||
* code 404 : (User not found)
|
* code 404 : (User not found)
|
||||||
*
|
*
|
||||||
|
* Available security schemes:
|
||||||
|
* auth_cookie (apiKey)
|
||||||
|
*
|
||||||
* @param username The name that needs to be deleted
|
* @param username The name that needs to be deleted
|
||||||
*/
|
*/
|
||||||
def deleteUser(username: String): ApiRequest[Unit] =
|
def deleteUser(username: String)(implicit apiKey: ApiKeyValue): ApiRequest[Unit] =
|
||||||
ApiRequest[Unit](ApiMethods.DELETE, baseUrl, "/user/{username}", "application/json")
|
ApiRequest[Unit](ApiMethods.DELETE, baseUrl, "/user/{username}", "application/json")
|
||||||
|
.withApiKey(apiKey, "AUTH_KEY", COOKIE)
|
||||||
.withPathParam("username", username)
|
.withPathParam("username", username)
|
||||||
.withErrorResponse[Unit](400)
|
.withErrorResponse[Unit](400)
|
||||||
.withErrorResponse[Unit](404)
|
.withErrorResponse[Unit](404)
|
||||||
@ -97,6 +113,7 @@ class UserApi(baseUrl: String) {
|
|||||||
* Expected answers:
|
* Expected answers:
|
||||||
* code 200 : String (successful operation)
|
* code 200 : String (successful operation)
|
||||||
* Headers :
|
* Headers :
|
||||||
|
* Set-Cookie - Cookie authentication key for use with the `auth_cookie` apiKey authentication.
|
||||||
* X-Rate-Limit - calls per hour allowed by the user
|
* X-Rate-Limit - calls per hour allowed by the user
|
||||||
* X-Expires-After - date in UTC when toekn expires
|
* X-Expires-After - date in UTC when toekn expires
|
||||||
* code 400 : (Invalid username/password supplied)
|
* code 400 : (Invalid username/password supplied)
|
||||||
@ -112,6 +129,7 @@ class UserApi(baseUrl: String) {
|
|||||||
.withErrorResponse[Unit](400)
|
.withErrorResponse[Unit](400)
|
||||||
|
|
||||||
object LoginUserHeaders {
|
object LoginUserHeaders {
|
||||||
|
def setCookie(r: ApiReturnWithHeaders) = r.getStringHeader("Set-Cookie")
|
||||||
def xRateLimit(r: ApiReturnWithHeaders) = r.getIntHeader("X-Rate-Limit")
|
def xRateLimit(r: ApiReturnWithHeaders) = r.getIntHeader("X-Rate-Limit")
|
||||||
def xExpiresAfter(r: ApiReturnWithHeaders) = r.getDateTimeHeader("X-Expires-After")
|
def xExpiresAfter(r: ApiReturnWithHeaders) = r.getDateTimeHeader("X-Expires-After")
|
||||||
}
|
}
|
||||||
@ -119,9 +137,13 @@ class UserApi(baseUrl: String) {
|
|||||||
/**
|
/**
|
||||||
* Expected answers:
|
* Expected answers:
|
||||||
* code 0 : (successful operation)
|
* code 0 : (successful operation)
|
||||||
|
*
|
||||||
|
* Available security schemes:
|
||||||
|
* auth_cookie (apiKey)
|
||||||
*/
|
*/
|
||||||
def logoutUser(): ApiRequest[Unit] =
|
def logoutUser()(implicit apiKey: ApiKeyValue): ApiRequest[Unit] =
|
||||||
ApiRequest[Unit](ApiMethods.GET, baseUrl, "/user/logout", "application/json")
|
ApiRequest[Unit](ApiMethods.GET, baseUrl, "/user/logout", "application/json")
|
||||||
|
.withApiKey(apiKey, "AUTH_KEY", COOKIE)
|
||||||
.withDefaultSuccessResponse[Unit]
|
.withDefaultSuccessResponse[Unit]
|
||||||
|
|
||||||
|
|
||||||
@ -132,12 +154,16 @@ class UserApi(baseUrl: String) {
|
|||||||
* code 400 : (Invalid user supplied)
|
* code 400 : (Invalid user supplied)
|
||||||
* code 404 : (User not found)
|
* code 404 : (User not found)
|
||||||
*
|
*
|
||||||
|
* Available security schemes:
|
||||||
|
* auth_cookie (apiKey)
|
||||||
|
*
|
||||||
* @param username name that need to be deleted
|
* @param username name that need to be deleted
|
||||||
* @param body Updated user object
|
* @param user Updated user object
|
||||||
*/
|
*/
|
||||||
def updateUser(username: String, body: User): ApiRequest[Unit] =
|
def updateUser(username: String, user: User)(implicit apiKey: ApiKeyValue): ApiRequest[Unit] =
|
||||||
ApiRequest[Unit](ApiMethods.PUT, baseUrl, "/user/{username}", "application/json")
|
ApiRequest[Unit](ApiMethods.PUT, baseUrl, "/user/{username}", "application/json")
|
||||||
.withBody(body)
|
.withApiKey(apiKey, "AUTH_KEY", COOKIE)
|
||||||
|
.withBody(user)
|
||||||
.withPathParam("username", username)
|
.withPathParam("username", username)
|
||||||
.withErrorResponse[Unit](400)
|
.withErrorResponse[Unit](400)
|
||||||
.withErrorResponse[Unit](404)
|
.withErrorResponse[Unit](404)
|
||||||
|
@ -55,7 +55,7 @@ object ApiInvoker {
|
|||||||
*
|
*
|
||||||
* @param request the apiRequest to be executed
|
* @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]] =
|
def response(invoker: ApiInvoker)(implicit ec: ExecutionContext, system: ActorSystem): Future[ApiResponse[T]] =
|
||||||
response(ec, system, invoker)
|
response(ec, system, invoker)
|
||||||
@ -77,7 +77,7 @@ object ApiInvoker {
|
|||||||
def toAkkaHttpMethod: HttpMethod = HttpMethods.getForKey(method.value).getOrElse(HttpMethods.GET)
|
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) =>
|
case JString(s) =>
|
||||||
ISODateTimeFormat.dateOptionalTimeParser().parseDateTime(s)
|
ISODateTimeFormat.dateOptionalTimeParser().parseDateTime(s)
|
||||||
}, {
|
}, {
|
||||||
@ -225,7 +225,7 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
|
|||||||
Uri(r.basePath + opPathWithParams).withQuery(query)
|
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
|
implicit val timeout: Timeout = settings.connectionTimeout
|
||||||
|
|
||||||
val request = createRequest(makeUri(r), r)
|
val request = createRequest(makeUri(r), r)
|
||||||
@ -249,8 +249,8 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
|
|||||||
.flatMap(unmarshallApiResponse(r))
|
.flatMap(unmarshallApiResponse(r))
|
||||||
}
|
}
|
||||||
|
|
||||||
def unmarshallApiResponse[T](request: ApiRequest[T])(response: HttpResponse): Future[ApiResponse[T]] = {
|
def unmarshallApiResponse[T: Manifest](request: ApiRequest[T])(response: HttpResponse): Future[ApiResponse[T]] = {
|
||||||
def responseForState[V](state: ResponseState, value: V) = {
|
def responseForState[V](state: ResponseState, value: V): ApiResponse[V] = {
|
||||||
state match {
|
state match {
|
||||||
case ResponseState.Success =>
|
case ResponseState.Success =>
|
||||||
ApiResponse(response.status.intValue, value, response.headers.map(header => (header.name, header.value)).toMap)
|
ApiResponse(response.status.intValue, value, response.headers.map(header => (header.name, header.value)).toMap)
|
||||||
@ -263,31 +263,29 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val mf = implicitly(manifest[T])
|
||||||
request
|
request
|
||||||
.responseForCode(response.status.intValue)
|
.responseForCode(response.status.intValue) match {
|
||||||
.map {
|
case Some((Manifest.Unit, state: ResponseState)) =>
|
||||||
case (Manifest.Unit, state: ResponseState) =>
|
Future(responseForState(state, Unit).asInstanceOf[ApiResponse[T]])
|
||||||
// FIXME Casting is ugly, how to do better?
|
case Some((manifest, state: ResponseState)) if manifest == mf =>
|
||||||
Future(responseForState(state, Unit)).asInstanceOf[Future[ApiResponse[T]]]
|
implicit val m: Unmarshaller[HttpEntity, T] = unmarshaller[T](mf, serialization, formats)
|
||||||
case (manifest: Manifest[T], state: ResponseState) =>
|
Unmarshal(response.entity)
|
||||||
implicit val m: Unmarshaller[HttpEntity, T] = unmarshaller[T](manifest, serialization, formats)
|
.to[T]
|
||||||
|
.recoverWith {
|
||||||
Unmarshal(response.entity)
|
case e ⇒ throw ApiError(response.status.intValue, s"Unable to unmarshall content to [$manifest]", Some(response.entity.toString), e)
|
||||||
.to[T]
|
}
|
||||||
.recoverWith {
|
.map(value => responseForState(state, value))
|
||||||
case e ⇒ throw ApiError(response.status.intValue, s"Unable to unmarshall content to [$manifest]", Some(response.entity.toString), e)
|
case None | Some(_) =>
|
||||||
}
|
Future.failed(ApiError(response.status.intValue, "Unexpected response code", Some(response.entity.toString)))
|
||||||
.map(value => responseForState(state, value))
|
}
|
||||||
}
|
|
||||||
.getOrElse(Future.failed(ApiError(response.status.intValue, "Unexpected response code", Some(response.entity.toString))))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed trait CustomContentTypes {
|
sealed trait CustomContentTypes {
|
||||||
|
|
||||||
protected def normalizedContentType(original: String): ContentType =
|
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 = {
|
protected def parseContentType(contentType: String): ContentType = {
|
||||||
|
|
||||||
|
@ -95,6 +95,8 @@ object ApiKeyLocations {
|
|||||||
|
|
||||||
case object HEADER extends ApiKeyLocation
|
case object HEADER extends ApiKeyLocation
|
||||||
|
|
||||||
|
case object COOKIE extends ApiKeyLocation
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,8 +12,6 @@
|
|||||||
package org.openapitools.client.model
|
package org.openapitools.client.model
|
||||||
|
|
||||||
import org.openapitools.client.core.ApiModel
|
import org.openapitools.client.core.ApiModel
|
||||||
import org.joda.time.DateTime
|
|
||||||
import java.util.UUID
|
|
||||||
|
|
||||||
case class ApiResponse (
|
case class ApiResponse (
|
||||||
code: Option[Int] = None,
|
code: Option[Int] = None,
|
||||||
|
@ -12,8 +12,6 @@
|
|||||||
package org.openapitools.client.model
|
package org.openapitools.client.model
|
||||||
|
|
||||||
import org.openapitools.client.core.ApiModel
|
import org.openapitools.client.core.ApiModel
|
||||||
import org.joda.time.DateTime
|
|
||||||
import java.util.UUID
|
|
||||||
|
|
||||||
case class Category (
|
case class Category (
|
||||||
id: Option[Long] = None,
|
id: Option[Long] = None,
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* OpenAPI Petstore
|
||||||
|
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: 1.0.0
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
package org.openapitools.client.model
|
||||||
|
|
||||||
|
import org.openapitools.client.core.ApiModel
|
||||||
|
|
||||||
|
case class InlineObject (
|
||||||
|
/* Updated name of the pet */
|
||||||
|
name: Option[String] = None,
|
||||||
|
/* Updated status of the pet */
|
||||||
|
status: Option[String] = None
|
||||||
|
) extends ApiModel
|
||||||
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* OpenAPI Petstore
|
||||||
|
* This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: 1.0.0
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
package org.openapitools.client.model
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
import org.openapitools.client.core.ApiModel
|
||||||
|
|
||||||
|
case class InlineObject1 (
|
||||||
|
/* Additional data to pass to server */
|
||||||
|
additionalMetadata: Option[String] = None,
|
||||||
|
/* file to upload */
|
||||||
|
file: Option[File] = None
|
||||||
|
) extends ApiModel
|
||||||
|
|
||||||
|
|
@ -11,9 +11,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.openapitools.client.model
|
package org.openapitools.client.model
|
||||||
|
|
||||||
import org.openapitools.client.core.ApiModel
|
|
||||||
import org.joda.time.DateTime
|
import org.joda.time.DateTime
|
||||||
import java.util.UUID
|
import org.openapitools.client.core.ApiModel
|
||||||
|
|
||||||
case class Order (
|
case class Order (
|
||||||
id: Option[Long] = None,
|
id: Option[Long] = None,
|
||||||
|
@ -12,8 +12,6 @@
|
|||||||
package org.openapitools.client.model
|
package org.openapitools.client.model
|
||||||
|
|
||||||
import org.openapitools.client.core.ApiModel
|
import org.openapitools.client.core.ApiModel
|
||||||
import org.joda.time.DateTime
|
|
||||||
import java.util.UUID
|
|
||||||
|
|
||||||
case class Pet (
|
case class Pet (
|
||||||
id: Option[Long] = None,
|
id: Option[Long] = None,
|
||||||
|
@ -12,8 +12,6 @@
|
|||||||
package org.openapitools.client.model
|
package org.openapitools.client.model
|
||||||
|
|
||||||
import org.openapitools.client.core.ApiModel
|
import org.openapitools.client.core.ApiModel
|
||||||
import org.joda.time.DateTime
|
|
||||||
import java.util.UUID
|
|
||||||
|
|
||||||
case class Tag (
|
case class Tag (
|
||||||
id: Option[Long] = None,
|
id: Option[Long] = None,
|
||||||
|
@ -12,8 +12,6 @@
|
|||||||
package org.openapitools.client.model
|
package org.openapitools.client.model
|
||||||
|
|
||||||
import org.openapitools.client.core.ApiModel
|
import org.openapitools.client.core.ApiModel
|
||||||
import org.joda.time.DateTime
|
|
||||||
import java.util.UUID
|
|
||||||
|
|
||||||
case class User (
|
case class User (
|
||||||
id: Option[Long] = None,
|
id: Option[Long] = None,
|
||||||
|
@ -2,7 +2,7 @@ import akka.actor.ActorSystem
|
|||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.openapitools.client._
|
import org.openapitools.client._
|
||||||
import org.openapitools.client.api._
|
import org.openapitools.client.api._
|
||||||
import org.openapitools.client.core.{ ApiInvoker, ApiKeyValue }
|
import org.openapitools.client.core.{ApiInvoker, ApiKeyValue}
|
||||||
import org.openapitools.client.model._
|
import org.openapitools.client.model._
|
||||||
import org.scalatest.Inspectors._
|
import org.scalatest.Inspectors._
|
||||||
import org.scalatest._
|
import org.scalatest._
|
||||||
@ -14,8 +14,8 @@ class PetApiTest extends AsyncFlatSpec with Matchers {
|
|||||||
private implicit val system: ActorSystem = ActorSystem()
|
private implicit val system: ActorSystem = ActorSystem()
|
||||||
|
|
||||||
behavior of "PetApi"
|
behavior of "PetApi"
|
||||||
val api = PetApi()
|
val api: PetApi = PetApi()
|
||||||
val invoker = ApiInvoker()
|
val invoker: ApiInvoker = ApiInvoker(EnumsSerializers.all)
|
||||||
private implicit val apiKey: ApiKeyValue = ApiKeyValue("special-key")
|
private implicit val apiKey: ApiKeyValue = ApiKeyValue("special-key")
|
||||||
|
|
||||||
it should "add and fetch a pet" in {
|
it should "add and fetch a pet" in {
|
||||||
@ -54,7 +54,7 @@ class PetApiTest extends AsyncFlatSpec with Matchers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
it should "update a pet" in {
|
it should "update a pet" in {
|
||||||
val petId = Math.random().toInt
|
val petId = (Math.random()*1000000000).toLong
|
||||||
val createdPet = Pet(
|
val createdPet = Pet(
|
||||||
Some(petId),
|
Some(petId),
|
||||||
Some(Category(Some(1), Some("sold"))),
|
Some(Category(Some(1), Some("sold"))),
|
||||||
@ -64,19 +64,24 @@ class PetApiTest extends AsyncFlatSpec with Matchers {
|
|||||||
Some(PetEnums.Status.Available)
|
Some(PetEnums.Status.Available)
|
||||||
)
|
)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
_ <- invoker.execute(api.addPet(createdPet))
|
createdPet <- invoker.execute(api.addPet(createdPet))
|
||||||
pet: core.ApiResponse[Pet] <- invoker.execute(api.getPetById(petId))
|
pet: core.ApiResponse[Pet] <- invoker.execute(api.getPetById(createdPet.content.id.get))
|
||||||
updatedPet = pet.content.copy(status = Some(PetEnums.Status.Sold))
|
updatedPet = pet.content.copy(status = Some(PetEnums.Status.Sold), name = "developer")
|
||||||
_ <- invoker.execute(api.updatePet(updatedPet))
|
updatedPetResponse: core.ApiResponse[Pet] <- invoker.execute(api.updatePet(updatedPet))
|
||||||
updatedRequested <- invoker.execute(api.getPetById(petId))
|
updatedRequested: core.ApiResponse[Pet] <- invoker.execute(api.getPetById(createdPet.content.id.get))
|
||||||
} yield {
|
} yield {
|
||||||
pet.content.name should be("programmer")
|
pet.content.name should be("programmer")
|
||||||
pet.content.status should be(Some(PetEnums.Status.Available))
|
pet.content.status should be(Some(PetEnums.Status.Available))
|
||||||
|
|
||||||
updatedRequested.content.name should be("programmer")
|
updatedPetResponse.content.name should be("developer")
|
||||||
|
updatedPetResponse.content.status should be(Some(PetEnums.Status.Sold))
|
||||||
|
|
||||||
|
updatedRequested.content.name should be("developer")
|
||||||
updatedRequested.content.status should be(Some(PetEnums.Status.Sold))
|
updatedRequested.content.status should be(Some(PetEnums.Status.Sold))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
it should "find pets by status" in {
|
it should "find pets by status" in {
|
||||||
@ -90,7 +95,7 @@ class PetApiTest extends AsyncFlatSpec with Matchers {
|
|||||||
pets should not be empty
|
pets should not be empty
|
||||||
|
|
||||||
forAll(pets) { pet =>
|
forAll(pets) { pet =>
|
||||||
pet.status should contain("available")
|
pet.status should contain(PetEnums.Status.Available)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user