forked from loafle/openapi-generator-original
Add option to enable scalafmt for code formatting (#1032)
* add option to enable scalafmt for code formatting * fix typo
This commit is contained in:
parent
48e66ed627
commit
fc35bb17d0
@ -21,6 +21,7 @@ import com.samskivert.mustache.Escapers;
|
||||
import com.samskivert.mustache.Mustache;
|
||||
import io.swagger.v3.oas.models.media.ArraySchema;
|
||||
import io.swagger.v3.oas.models.media.Schema;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openapitools.codegen.CliOption;
|
||||
import org.openapitools.codegen.CodegenConstants;
|
||||
@ -113,6 +114,10 @@ public abstract class AbstractScalaCodegen extends DefaultCodegen {
|
||||
public void processOpts() {
|
||||
super.processOpts();
|
||||
|
||||
if (StringUtils.isEmpty(System.getenv("SCALAFMT_PATH"))) {
|
||||
LOGGER.info("Environment variable SCALAFMT_PATH not defined so the Scala code may not be properly formatted. To define it, try 'export SCALAFMT_PATH=/usr/local/bin/scalafmt' (Linux/Mac)");
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) {
|
||||
this.setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER));
|
||||
}
|
||||
@ -298,4 +303,31 @@ public abstract class AbstractScalaCodegen extends DefaultCodegen {
|
||||
return input.replace("\"", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessFile(File file, String fileType) {
|
||||
if (file == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String scalafmtPath = System.getenv("SCALAFMT_PATH");
|
||||
if (StringUtils.isEmpty(scalafmtPath)) {
|
||||
return; // skip if SCALAFMT_PATH env variable is not defined
|
||||
}
|
||||
|
||||
// only process files with scala extension
|
||||
if ("scala".equals(FilenameUtils.getExtension(file.toString()))) {
|
||||
String command = scalafmtPath + " " + file.toString();
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(command);
|
||||
p.waitFor();
|
||||
if (p.exitValue() != 0) {
|
||||
LOGGER.error("Error running the command ({}). Exit value: {}", command, p.exitValue());
|
||||
}
|
||||
LOGGER.info("Successfully executed: " + command);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error running the command ({}). Exception: {}", command, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
3.0.0-SNAPSHOT
|
||||
3.3.0-SNAPSHOT
|
@ -17,7 +17,8 @@ import scala.reflect.ClassTag
|
||||
|
||||
object EnumsSerializers {
|
||||
|
||||
def all: Seq[Serializer[_]] = Seq[Serializer[_]]() :+
|
||||
def all: Seq[Serializer[_]] =
|
||||
Seq[Serializer[_]]() :+
|
||||
new EnumNameSerializer(OrderEnums.Status) :+
|
||||
new EnumNameSerializer(PetEnums.Status)
|
||||
|
||||
@ -27,14 +28,15 @@ object EnumsSerializers {
|
||||
|
||||
val EnumerationClass: Class[E#Value] = classOf[E#Value]
|
||||
|
||||
def deserialize(implicit format: Formats):
|
||||
PartialFunction[(TypeInfo, JValue), E#Value] = {
|
||||
def deserialize(implicit format: Formats)
|
||||
: PartialFunction[(TypeInfo, JValue), E#Value] = {
|
||||
case (t @ TypeInfo(EnumerationClass, _), json) if isValid(json) =>
|
||||
json match {
|
||||
case JString(value) =>
|
||||
enum.withName(value)
|
||||
case value =>
|
||||
throw new MappingException(s"Can't convert $value to $EnumerationClass")
|
||||
throw new MappingException(
|
||||
s"Can't convert $value to $EnumerationClass")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,9 +27,13 @@ object PetApi {
|
||||
* @param pet Pet object that needs to be added to the store
|
||||
*/
|
||||
def addPet(pet: Pet): ApiRequest[Unit] =
|
||||
ApiRequest[Unit](ApiMethods.POST, "http://petstore.swagger.io/v2", "/pet", "application/json")
|
||||
ApiRequest[Unit](ApiMethods.POST,
|
||||
"http://petstore.swagger.io/v2",
|
||||
"/pet",
|
||||
"application/json")
|
||||
.withBody(pet)
|
||||
.withErrorResponse[Unit](405)
|
||||
|
||||
/**
|
||||
* Expected answers:
|
||||
* code 400 : (Invalid pet value)
|
||||
@ -38,10 +42,14 @@ object PetApi {
|
||||
* @param apiKey
|
||||
*/
|
||||
def deletePet(petId: Long, apiKey: Option[String] = None): ApiRequest[Unit] =
|
||||
ApiRequest[Unit](ApiMethods.DELETE, "http://petstore.swagger.io/v2", "/pet/{petId}", "application/json")
|
||||
ApiRequest[Unit](ApiMethods.DELETE,
|
||||
"http://petstore.swagger.io/v2",
|
||||
"/pet/{petId}",
|
||||
"application/json")
|
||||
.withPathParam("petId", petId)
|
||||
.withHeaderParam("api_key", apiKey)
|
||||
.withErrorResponse[Unit](400)
|
||||
|
||||
/**
|
||||
* Multiple status values can be provided with comma separated strings
|
||||
*
|
||||
@ -52,10 +60,14 @@ object PetApi {
|
||||
* @param status Status values that need to be considered for filter
|
||||
*/
|
||||
def findPetsByStatus(status: Seq[String]): ApiRequest[Seq[Pet]] =
|
||||
ApiRequest[Seq[Pet]](ApiMethods.GET, "http://petstore.swagger.io/v2", "/pet/findByStatus", "application/json")
|
||||
ApiRequest[Seq[Pet]](ApiMethods.GET,
|
||||
"http://petstore.swagger.io/v2",
|
||||
"/pet/findByStatus",
|
||||
"application/json")
|
||||
.withQueryParam("status", ArrayValues(status, CSV))
|
||||
.withSuccessResponse[Seq[Pet]](200)
|
||||
.withErrorResponse[Unit](400)
|
||||
|
||||
/**
|
||||
* Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
|
||||
*
|
||||
@ -66,10 +78,14 @@ object PetApi {
|
||||
* @param tags Tags to filter by
|
||||
*/
|
||||
def findPetsByTags(tags: Seq[String]): ApiRequest[Seq[Pet]] =
|
||||
ApiRequest[Seq[Pet]](ApiMethods.GET, "http://petstore.swagger.io/v2", "/pet/findByTags", "application/json")
|
||||
ApiRequest[Seq[Pet]](ApiMethods.GET,
|
||||
"http://petstore.swagger.io/v2",
|
||||
"/pet/findByTags",
|
||||
"application/json")
|
||||
.withQueryParam("tags", ArrayValues(tags, CSV))
|
||||
.withSuccessResponse[Seq[Pet]](200)
|
||||
.withErrorResponse[Unit](400)
|
||||
|
||||
/**
|
||||
* Returns a single pet
|
||||
*
|
||||
@ -84,12 +100,16 @@ object PetApi {
|
||||
* @param petId ID of pet to return
|
||||
*/
|
||||
def getPetById(petId: Long)(implicit apiKey: ApiKeyValue): ApiRequest[Unit] =
|
||||
ApiRequest[Unit](ApiMethods.GET, "http://petstore.swagger.io/v2", "/pet/{petId}", "application/json")
|
||||
ApiRequest[Unit](ApiMethods.GET,
|
||||
"http://petstore.swagger.io/v2",
|
||||
"/pet/{petId}",
|
||||
"application/json")
|
||||
.withApiKey(apiKey, "api_key", HEADER)
|
||||
.withPathParam("petId", petId)
|
||||
.withSuccessResponse[Pet](200)
|
||||
.withErrorResponse[Unit](400)
|
||||
.withErrorResponse[Unit](404)
|
||||
|
||||
/**
|
||||
* Expected answers:
|
||||
* code 400 : (Invalid ID supplied)
|
||||
@ -99,11 +119,15 @@ object PetApi {
|
||||
* @param pet Pet object that needs to be added to the store
|
||||
*/
|
||||
def updatePet(pet: Pet): ApiRequest[Unit] =
|
||||
ApiRequest[Unit](ApiMethods.PUT, "http://petstore.swagger.io/v2", "/pet", "application/json")
|
||||
ApiRequest[Unit](ApiMethods.PUT,
|
||||
"http://petstore.swagger.io/v2",
|
||||
"/pet",
|
||||
"application/json")
|
||||
.withBody(pet)
|
||||
.withErrorResponse[Unit](400)
|
||||
.withErrorResponse[Unit](404)
|
||||
.withErrorResponse[Unit](405)
|
||||
|
||||
/**
|
||||
* Expected answers:
|
||||
* code 405 : (Invalid input)
|
||||
@ -112,12 +136,18 @@ object PetApi {
|
||||
* @param name Updated name of the pet
|
||||
* @param status Updated status of the pet
|
||||
*/
|
||||
def updatePetWithForm(petId: Long, name: Option[String] = None, status: Option[String] = None): ApiRequest[Unit] =
|
||||
ApiRequest[Unit](ApiMethods.POST, "http://petstore.swagger.io/v2", "/pet/{petId}", "application/x-www-form-urlencoded")
|
||||
def updatePetWithForm(petId: Long,
|
||||
name: Option[String] = None,
|
||||
status: Option[String] = None): ApiRequest[Unit] =
|
||||
ApiRequest[Unit](ApiMethods.POST,
|
||||
"http://petstore.swagger.io/v2",
|
||||
"/pet/{petId}",
|
||||
"application/x-www-form-urlencoded")
|
||||
.withFormParam("name", name)
|
||||
.withFormParam("status", status)
|
||||
.withPathParam("petId", petId)
|
||||
.withErrorResponse[Unit](405)
|
||||
|
||||
/**
|
||||
* Expected answers:
|
||||
* code 200 : ApiResponse (successful operation)
|
||||
@ -126,13 +156,16 @@ object PetApi {
|
||||
* @param additionalMetadata Additional data to pass to server
|
||||
* @param file file to upload
|
||||
*/
|
||||
def uploadFile(petId: Long, additionalMetadata: Option[String] = None, file: Option[File] = None): ApiRequest[Unit] =
|
||||
ApiRequest[Unit](ApiMethods.POST, "http://petstore.swagger.io/v2", "/pet/{petId}/uploadImage", "multipart/form-data")
|
||||
def uploadFile(petId: Long,
|
||||
additionalMetadata: Option[String] = None,
|
||||
file: Option[File] = None): ApiRequest[Unit] =
|
||||
ApiRequest[Unit](ApiMethods.POST,
|
||||
"http://petstore.swagger.io/v2",
|
||||
"/pet/{petId}/uploadImage",
|
||||
"multipart/form-data")
|
||||
.withFormParam("additionalMetadata", additionalMetadata)
|
||||
.withFormParam("file", file)
|
||||
.withPathParam("petId", petId)
|
||||
.withSuccessResponse[ApiResponse](200)
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -28,10 +28,14 @@ object StoreApi {
|
||||
* @param orderId ID of the order that needs to be deleted
|
||||
*/
|
||||
def deleteOrder(orderId: String): ApiRequest[Unit] =
|
||||
ApiRequest[Unit](ApiMethods.DELETE, "http://petstore.swagger.io/v2", "/store/order/{orderId}", "application/json")
|
||||
ApiRequest[Unit](ApiMethods.DELETE,
|
||||
"http://petstore.swagger.io/v2",
|
||||
"/store/order/{orderId}",
|
||||
"application/json")
|
||||
.withPathParam("orderId", orderId)
|
||||
.withErrorResponse[Unit](400)
|
||||
.withErrorResponse[Unit](404)
|
||||
|
||||
/**
|
||||
* Returns a map of status codes to quantities
|
||||
*
|
||||
@ -41,10 +45,15 @@ object StoreApi {
|
||||
* Available security schemes:
|
||||
* api_key (apiKey)
|
||||
*/
|
||||
def getInventory()(implicit apiKey: ApiKeyValue): ApiRequest[Map[String, Int]] =
|
||||
ApiRequest[Map[String, Int]](ApiMethods.GET, "http://petstore.swagger.io/v2", "/store/inventory", "application/json")
|
||||
def getInventory()(
|
||||
implicit apiKey: ApiKeyValue): ApiRequest[Map[String, Int]] =
|
||||
ApiRequest[Map[String, Int]](ApiMethods.GET,
|
||||
"http://petstore.swagger.io/v2",
|
||||
"/store/inventory",
|
||||
"application/json")
|
||||
.withApiKey(apiKey, "api_key", HEADER)
|
||||
.withSuccessResponse[Map[String, Int]](200)
|
||||
|
||||
/**
|
||||
* For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions
|
||||
*
|
||||
@ -56,11 +65,15 @@ object StoreApi {
|
||||
* @param orderId ID of pet that needs to be fetched
|
||||
*/
|
||||
def getOrderById(orderId: Long): ApiRequest[Unit] =
|
||||
ApiRequest[Unit](ApiMethods.GET, "http://petstore.swagger.io/v2", "/store/order/{orderId}", "application/json")
|
||||
ApiRequest[Unit](ApiMethods.GET,
|
||||
"http://petstore.swagger.io/v2",
|
||||
"/store/order/{orderId}",
|
||||
"application/json")
|
||||
.withPathParam("orderId", orderId)
|
||||
.withSuccessResponse[Order](200)
|
||||
.withErrorResponse[Unit](400)
|
||||
.withErrorResponse[Unit](404)
|
||||
|
||||
/**
|
||||
* Expected answers:
|
||||
* code 200 : Order (successful operation)
|
||||
@ -69,11 +82,12 @@ object StoreApi {
|
||||
* @param order order placed for purchasing the pet
|
||||
*/
|
||||
def placeOrder(order: Order): ApiRequest[Unit] =
|
||||
ApiRequest[Unit](ApiMethods.POST, "http://petstore.swagger.io/v2", "/store/order", "application/json")
|
||||
ApiRequest[Unit](ApiMethods.POST,
|
||||
"http://petstore.swagger.io/v2",
|
||||
"/store/order",
|
||||
"application/json")
|
||||
.withBody(order)
|
||||
.withSuccessResponse[Order](200)
|
||||
.withErrorResponse[Unit](400)
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -27,9 +27,13 @@ object UserApi {
|
||||
* @param user Created user object
|
||||
*/
|
||||
def createUser(user: User): ApiRequest[Unit] =
|
||||
ApiRequest[Unit](ApiMethods.POST, "http://petstore.swagger.io/v2", "/user", "application/json")
|
||||
ApiRequest[Unit](ApiMethods.POST,
|
||||
"http://petstore.swagger.io/v2",
|
||||
"/user",
|
||||
"application/json")
|
||||
.withBody(user)
|
||||
.withDefaultSuccessResponse[Unit]
|
||||
|
||||
/**
|
||||
* Expected answers:
|
||||
* code 0 : (successful operation)
|
||||
@ -37,9 +41,13 @@ object UserApi {
|
||||
* @param user List of user object
|
||||
*/
|
||||
def createUsersWithArrayInput(user: Seq[User]): ApiRequest[Unit] =
|
||||
ApiRequest[Unit](ApiMethods.POST, "http://petstore.swagger.io/v2", "/user/createWithArray", "application/json")
|
||||
ApiRequest[Unit](ApiMethods.POST,
|
||||
"http://petstore.swagger.io/v2",
|
||||
"/user/createWithArray",
|
||||
"application/json")
|
||||
.withBody(user)
|
||||
.withDefaultSuccessResponse[Unit]
|
||||
|
||||
/**
|
||||
* Expected answers:
|
||||
* code 0 : (successful operation)
|
||||
@ -47,9 +55,13 @@ object UserApi {
|
||||
* @param user List of user object
|
||||
*/
|
||||
def createUsersWithListInput(user: Seq[User]): ApiRequest[Unit] =
|
||||
ApiRequest[Unit](ApiMethods.POST, "http://petstore.swagger.io/v2", "/user/createWithList", "application/json")
|
||||
ApiRequest[Unit](ApiMethods.POST,
|
||||
"http://petstore.swagger.io/v2",
|
||||
"/user/createWithList",
|
||||
"application/json")
|
||||
.withBody(user)
|
||||
.withDefaultSuccessResponse[Unit]
|
||||
|
||||
/**
|
||||
* This can only be done by the logged in user.
|
||||
*
|
||||
@ -60,10 +72,14 @@ object UserApi {
|
||||
* @param username The name that needs to be deleted
|
||||
*/
|
||||
def deleteUser(username: String): ApiRequest[Unit] =
|
||||
ApiRequest[Unit](ApiMethods.DELETE, "http://petstore.swagger.io/v2", "/user/{username}", "application/json")
|
||||
ApiRequest[Unit](ApiMethods.DELETE,
|
||||
"http://petstore.swagger.io/v2",
|
||||
"/user/{username}",
|
||||
"application/json")
|
||||
.withPathParam("username", username)
|
||||
.withErrorResponse[Unit](400)
|
||||
.withErrorResponse[Unit](404)
|
||||
|
||||
/**
|
||||
* Expected answers:
|
||||
* code 200 : User (successful operation)
|
||||
@ -73,11 +89,15 @@ object UserApi {
|
||||
* @param username The name that needs to be fetched. Use user1 for testing.
|
||||
*/
|
||||
def getUserByName(username: String): ApiRequest[Unit] =
|
||||
ApiRequest[Unit](ApiMethods.GET, "http://petstore.swagger.io/v2", "/user/{username}", "application/json")
|
||||
ApiRequest[Unit](ApiMethods.GET,
|
||||
"http://petstore.swagger.io/v2",
|
||||
"/user/{username}",
|
||||
"application/json")
|
||||
.withPathParam("username", username)
|
||||
.withSuccessResponse[User](200)
|
||||
.withErrorResponse[Unit](400)
|
||||
.withErrorResponse[Unit](404)
|
||||
|
||||
/**
|
||||
* Expected answers:
|
||||
* code 200 : String (successful operation)
|
||||
@ -90,7 +110,10 @@ object UserApi {
|
||||
* @param password The password for login in clear text
|
||||
*/
|
||||
def loginUser(username: String, password: String): ApiRequest[Unit] =
|
||||
ApiRequest[Unit](ApiMethods.GET, "http://petstore.swagger.io/v2", "/user/login", "application/json")
|
||||
ApiRequest[Unit](ApiMethods.GET,
|
||||
"http://petstore.swagger.io/v2",
|
||||
"/user/login",
|
||||
"application/json")
|
||||
.withQueryParam("username", username)
|
||||
.withQueryParam("password", password)
|
||||
.withSuccessResponse[String](200)
|
||||
@ -98,15 +121,21 @@ object UserApi {
|
||||
|
||||
object LoginUserHeaders {
|
||||
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")
|
||||
}
|
||||
|
||||
/**
|
||||
* Expected answers:
|
||||
* code 0 : (successful operation)
|
||||
*/
|
||||
def logoutUser(): ApiRequest[Unit] =
|
||||
ApiRequest[Unit](ApiMethods.GET, "http://petstore.swagger.io/v2", "/user/logout", "application/json")
|
||||
ApiRequest[Unit](ApiMethods.GET,
|
||||
"http://petstore.swagger.io/v2",
|
||||
"/user/logout",
|
||||
"application/json")
|
||||
.withDefaultSuccessResponse[Unit]
|
||||
|
||||
/**
|
||||
* This can only be done by the logged in user.
|
||||
*
|
||||
@ -118,12 +147,13 @@ object UserApi {
|
||||
* @param user Updated user object
|
||||
*/
|
||||
def updateUser(username: String, user: User): ApiRequest[Unit] =
|
||||
ApiRequest[Unit](ApiMethods.PUT, "http://petstore.swagger.io/v2", "/user/{username}", "application/json")
|
||||
ApiRequest[Unit](ApiMethods.PUT,
|
||||
"http://petstore.swagger.io/v2",
|
||||
"/user/{username}",
|
||||
"application/json")
|
||||
.withBody(user)
|
||||
.withPathParam("username", username)
|
||||
.withErrorResponse[Unit](400)
|
||||
.withErrorResponse[Unit](404)
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -46,17 +46,29 @@ object ApiInvoker {
|
||||
|
||||
def apply()(implicit system: ActorSystem): ApiInvoker =
|
||||
apply(DefaultFormats + DateTimeSerializer)
|
||||
def apply(serializers: Traversable[Serializer[_]])(implicit system: ActorSystem): ApiInvoker =
|
||||
def apply(serializers: Traversable[Serializer[_]])(
|
||||
implicit system: ActorSystem): ApiInvoker =
|
||||
apply(DefaultFormats + DateTimeSerializer ++ serializers)
|
||||
def apply(formats: Formats)(implicit system: ActorSystem): ApiInvoker = new ApiInvoker(formats)
|
||||
def apply(formats: Formats)(implicit system: ActorSystem): ApiInvoker =
|
||||
new ApiInvoker(formats)
|
||||
|
||||
case class CustomStatusCode(value: Int, reason: String = "Application-defined status code", isSuccess: Boolean = true)
|
||||
case class CustomStatusCode(
|
||||
value: Int,
|
||||
reason: String = "Application-defined status code",
|
||||
isSuccess: Boolean = true)
|
||||
|
||||
def addCustomStatusCode(code: CustomStatusCode): Unit = addCustomStatusCode(code.value, code.reason, code.isSuccess)
|
||||
def addCustomStatusCode(code: CustomStatusCode): Unit =
|
||||
addCustomStatusCode(code.value, code.reason, code.isSuccess)
|
||||
|
||||
def addCustomStatusCode(code: Int, reason: String = "Application defined code", isSuccess: Boolean = true): Unit = {
|
||||
def addCustomStatusCode(code: Int,
|
||||
reason: String = "Application defined code",
|
||||
isSuccess: Boolean = true): Unit = {
|
||||
StatusCodes.getForKey(code) foreach { _ =>
|
||||
StatusCodes.registerCustom(code, reason, reason, isSuccess, allowsEntity = true)
|
||||
StatusCodes.registerCustom(code,
|
||||
reason,
|
||||
reason,
|
||||
isSuccess,
|
||||
allowsEntity = true)
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,13 +81,20 @@ object ApiInvoker {
|
||||
*/
|
||||
implicit class ApiRequestImprovements[T](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)
|
||||
|
||||
def response(implicit ec: ExecutionContext, system: ActorSystem, invoker: ApiInvoker): Future[ApiResponse[T]] =
|
||||
def response(implicit ec: ExecutionContext,
|
||||
system: ActorSystem,
|
||||
invoker: ApiInvoker): Future[ApiResponse[T]] =
|
||||
invoker.execute(request)
|
||||
|
||||
def result[U <: T](implicit c: ClassTag[U], ec: ExecutionContext, system: ActorSystem, invoker: ApiInvoker): Future[U] =
|
||||
def result[U <: T](implicit c: ClassTag[U],
|
||||
ec: ExecutionContext,
|
||||
system: ActorSystem,
|
||||
invoker: ApiInvoker): Future[U] =
|
||||
invoker.execute(request).map(_.content).mapTo[U]
|
||||
|
||||
}
|
||||
@ -85,10 +104,13 @@ object ApiInvoker {
|
||||
* @param method the ApiMethod to be converted
|
||||
*/
|
||||
implicit class ApiMethodExtensions(val method: ApiMethod) {
|
||||
def toSprayMethod: HttpMethod = HttpMethods.getForKey(method.value).getOrElse(HttpMethods.GET)
|
||||
def toSprayMethod: HttpMethod =
|
||||
HttpMethods.getForKey(method.value).getOrElse(HttpMethods.GET)
|
||||
}
|
||||
|
||||
case object DateTimeSerializer extends CustomSerializer[DateTime](format => ( {
|
||||
case object DateTimeSerializer
|
||||
extends CustomSerializer[DateTime](format =>
|
||||
({
|
||||
case JString(s) =>
|
||||
ISODateTimeFormat.dateOptionalTimeParser().parseDateTime(s)
|
||||
}, {
|
||||
@ -97,7 +119,9 @@ object ApiInvoker {
|
||||
}))
|
||||
}
|
||||
|
||||
class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends UntrustedSslContext with CustomContentTypes {
|
||||
class ApiInvoker(formats: Formats)(implicit system: ActorSystem)
|
||||
extends UntrustedSslContext
|
||||
with CustomContentTypes {
|
||||
|
||||
import org.openapitools.client.core.ApiInvoker._
|
||||
import org.openapitools.client.core.ParametersMap._
|
||||
@ -109,23 +133,27 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends Untrust
|
||||
|
||||
import spray.http.MessagePredicate._
|
||||
|
||||
val CompressionFilter: MessagePredicate= MessagePredicate({ _ => settings.compressionEnabled}) &&
|
||||
val CompressionFilter: MessagePredicate = MessagePredicate({ _ =>
|
||||
settings.compressionEnabled
|
||||
}) &&
|
||||
Encoder.DefaultFilter && minEntitySize(settings.compressionSizeThreshold)
|
||||
|
||||
settings.customCodes.foreach(addCustomStatusCode)
|
||||
|
||||
private def addAuthentication(credentialsSeq: Seq[Credentials]): pipelining.RequestTransformer =
|
||||
private def addAuthentication(
|
||||
credentialsSeq: Seq[Credentials]): pipelining.RequestTransformer =
|
||||
request =>
|
||||
credentialsSeq.foldLeft(request) {
|
||||
case (req, BasicCredentials(login, password)) =>
|
||||
req ~> addCredentials(BasicHttpCredentials(login, password))
|
||||
case (req, ApiKeyCredentials(keyValue, keyName, ApiKeyLocations.HEADER)) =>
|
||||
case (req,
|
||||
ApiKeyCredentials(keyValue, keyName, ApiKeyLocations.HEADER)) =>
|
||||
req ~> addHeader(RawHeader(keyName, keyValue.value))
|
||||
case (req, _) => req
|
||||
}
|
||||
|
||||
private def addHeaders(headers: Map[String, Any]): pipelining.RequestTransformer = { request =>
|
||||
|
||||
private def addHeaders(
|
||||
headers: Map[String, Any]): pipelining.RequestTransformer = { request =>
|
||||
val rawHeaders = for {
|
||||
(name, value) <- headers.asFormattedParams
|
||||
header = RawHeader(name, String.valueOf(value))
|
||||
@ -155,7 +183,9 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends Untrust
|
||||
Some(
|
||||
normalizedContentType(request.contentType).mediaType match {
|
||||
case MediaTypes.`multipart/form-data` =>
|
||||
MultipartFormData(params.map { case (name, value) => (name, bodyPart(name, value))})
|
||||
MultipartFormData(params.map {
|
||||
case (name, value) => (name, bodyPart(name, value))
|
||||
})
|
||||
case MediaTypes.`application/x-www-form-urlencoded` =>
|
||||
FormData(params.mapValues(String.valueOf))
|
||||
case m: MediaType => // Default : application/x-www-form-urlencoded.
|
||||
@ -180,9 +210,13 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends Untrust
|
||||
case Some(c: MultipartFormData) =>
|
||||
builder.apply(uri, c)
|
||||
case Some(c: String) =>
|
||||
builder.apply(uri, HttpEntity(normalizedContentType(request.contentType), c))
|
||||
builder.apply(
|
||||
uri,
|
||||
HttpEntity(normalizedContentType(request.contentType), c))
|
||||
case _ =>
|
||||
builder.apply(uri, HttpEntity(normalizedContentType(request.contentType), " "))
|
||||
builder.apply(
|
||||
uri,
|
||||
HttpEntity(normalizedContentType(request.contentType), " "))
|
||||
}
|
||||
case _ => builder.apply(uri)
|
||||
}
|
||||
@ -194,11 +228,13 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends Untrust
|
||||
}
|
||||
|
||||
def makeQuery(r: ApiRequest[_]): Query = {
|
||||
r.credentials.foldLeft(r.queryParams) {
|
||||
r.credentials
|
||||
.foldLeft(r.queryParams) {
|
||||
case (params, ApiKeyCredentials(key, keyName, ApiKeyLocations.QUERY)) =>
|
||||
params + (keyName -> key.value)
|
||||
case (params, _) => params
|
||||
}.asFormattedParams
|
||||
}
|
||||
.asFormattedParams
|
||||
.mapValues(String.valueOf)
|
||||
.foldRight[Query](Uri.Query.Empty) {
|
||||
case ((name, value), acc) => acc.+:(name, value)
|
||||
@ -227,7 +263,9 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends Untrust
|
||||
uri.authority.host.toString,
|
||||
uri.effectivePort,
|
||||
sslEncryption = "https".equals(uri.scheme),
|
||||
defaultHeaders = settings.defaultHeaders ++ List(`Accept-Encoding`(gzip, deflate)))
|
||||
defaultHeaders = settings.defaultHeaders ++ List(
|
||||
`Accept-Encoding`(gzip, deflate))
|
||||
)
|
||||
|
||||
val request = createRequest(uri, r)
|
||||
|
||||
@ -237,46 +275,62 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends Untrust
|
||||
} yield {
|
||||
response ~> decode(Deflate) ~> decode(Gzip) ~> unmarshallApiResponse(r)
|
||||
}
|
||||
}
|
||||
catch {
|
||||
} catch {
|
||||
case NonFatal(x) => Future.failed(x)
|
||||
}
|
||||
}
|
||||
|
||||
def unmarshallApiResponse[T](request: ApiRequest[T])(response: HttpResponse): ApiResponse[T] = {
|
||||
def unmarshallApiResponse[T](request: ApiRequest[T])(
|
||||
response: HttpResponse): ApiResponse[T] = {
|
||||
request.responseForCode(response.status.intValue) match {
|
||||
case Some( (manifest: Manifest[T], state: ResponseState) ) =>
|
||||
case Some((manifest: Manifest[T], state: ResponseState)) =>
|
||||
entityUnmarshaller(manifest)(response.entity) match {
|
||||
case Right(value) ⇒
|
||||
state match {
|
||||
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)
|
||||
case ResponseState.Error =>
|
||||
throw ApiError(response.status.intValue, "Error response received",
|
||||
throw ApiError(response.status.intValue,
|
||||
"Error response received",
|
||||
Some(value),
|
||||
headers = response.headers.map(header => (header.name, header.value)).toMap)
|
||||
headers = response.headers
|
||||
.map(header => (header.name, header.value))
|
||||
.toMap)
|
||||
}
|
||||
|
||||
case Left(MalformedContent(error, Some(cause))) ⇒
|
||||
throw ApiError(response.status.intValue, s"Unable to unmarshall content to [$manifest]", Some(response.entity.toString), cause)
|
||||
throw ApiError(response.status.intValue,
|
||||
s"Unable to unmarshall content to [$manifest]",
|
||||
Some(response.entity.toString),
|
||||
cause)
|
||||
|
||||
case Left(MalformedContent(error, None)) ⇒
|
||||
throw ApiError(response.status.intValue, s"Unable to unmarshall content to [$manifest]", Some(response.entity.toString))
|
||||
throw ApiError(response.status.intValue,
|
||||
s"Unable to unmarshall content to [$manifest]",
|
||||
Some(response.entity.toString))
|
||||
|
||||
case Left(ContentExpected) ⇒
|
||||
throw ApiError(response.status.intValue, s"Unable to unmarshall empty response to [$manifest]", Some(response.entity.toString))
|
||||
throw ApiError(
|
||||
response.status.intValue,
|
||||
s"Unable to unmarshall empty response to [$manifest]",
|
||||
Some(response.entity.toString))
|
||||
}
|
||||
|
||||
case _ => throw ApiError(response.status.intValue, "Unexpected response code", Some(response.entity.toString))
|
||||
case _ =>
|
||||
throw ApiError(response.status.intValue,
|
||||
"Unexpected response code",
|
||||
Some(response.entity.toString))
|
||||
}
|
||||
}
|
||||
|
||||
def entityUnmarshaller[T](implicit mf: Manifest[T]): Unmarshaller[T] =
|
||||
Unmarshaller[T](MediaTypes.`application/json`) {
|
||||
case x: HttpEntity.NonEmpty ⇒
|
||||
parse(x.asString(defaultCharset = HttpCharsets.`UTF-8`))
|
||||
.noNulls
|
||||
.camelizeKeys
|
||||
parse(x.asString(defaultCharset = HttpCharsets.`UTF-8`)).noNulls.camelizeKeys
|
||||
.extract[T]
|
||||
}
|
||||
|
||||
@ -285,10 +339,12 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends Untrust
|
||||
sealed trait CustomContentTypes {
|
||||
|
||||
def normalizedContentType(original: String): ContentType =
|
||||
MediaTypes.forExtension(original) map (ContentType(_)) getOrElse parseContentType(original)
|
||||
MediaTypes.forExtension(original) map (ContentType(_)) getOrElse parseContentType(
|
||||
original)
|
||||
|
||||
def parseContentType(contentType: String): ContentType = {
|
||||
val contentTypeAsRawHeader = HttpHeaders.RawHeader("Content-Type", contentType)
|
||||
val contentTypeAsRawHeader =
|
||||
HttpHeaders.RawHeader("Content-Type", contentType)
|
||||
val parsedContentTypeHeader = HttpParser.parseHeader(contentTypeAsRawHeader)
|
||||
(parsedContentTypeHeader: @unchecked) match {
|
||||
case Right(ct: HttpHeaders.`Content-Type`) =>
|
||||
@ -310,9 +366,11 @@ sealed trait UntrustedSslContext {
|
||||
|
||||
case true =>
|
||||
class IgnoreX509TrustManager extends X509TrustManager {
|
||||
def checkClientTrusted(chain: Array[X509Certificate], authType: String): Unit = {}
|
||||
def checkClientTrusted(chain: Array[X509Certificate],
|
||||
authType: String): Unit = {}
|
||||
|
||||
def checkServerTrusted(chain: Array[X509Certificate], authType: String): Unit = {}
|
||||
def checkServerTrusted(chain: Array[X509Certificate],
|
||||
authType: String): Unit = {}
|
||||
|
||||
def getAcceptedIssuers = null
|
||||
}
|
||||
@ -324,8 +382,7 @@ sealed trait UntrustedSslContext {
|
||||
}
|
||||
|
||||
implicit val clientSSLEngineProvider =
|
||||
ClientSSLEngineProvider {
|
||||
_ =>
|
||||
ClientSSLEngineProvider { _ =>
|
||||
val engine = trustfulSslContext.createSSLEngine()
|
||||
engine.setUseClientMode(true)
|
||||
engine
|
||||
|
@ -27,9 +27,9 @@ case class ApiRequest[U](
|
||||
basePath: String,
|
||||
operationPath: String,
|
||||
contentType: String,
|
||||
|
||||
// optional fields
|
||||
responses: Map[Int, (Manifest[_], ResponseState)] = Map.empty,
|
||||
responses: Map[Int, (Manifest[_], ResponseState)] =
|
||||
Map.empty,
|
||||
bodyParam: Option[Any] = None,
|
||||
formParams: Map[String, Any] = Map.empty,
|
||||
pathParams: Map[String, Any] = Map.empty,
|
||||
@ -37,29 +37,43 @@ case class ApiRequest[U](
|
||||
headerParams: Map[String, Any] = Map.empty,
|
||||
credentials: Seq[Credentials] = List.empty) {
|
||||
|
||||
def withCredentials(cred: Credentials): ApiRequest[U] = copy[U](credentials = credentials :+ cred)
|
||||
def withCredentials(cred: Credentials): ApiRequest[U] =
|
||||
copy[U](credentials = credentials :+ cred)
|
||||
|
||||
def withApiKey(key: ApiKeyValue, keyName: String, location: ApiKeyLocation): ApiRequest[U] = withCredentials(ApiKeyCredentials(key, keyName, location))
|
||||
def withApiKey(key: ApiKeyValue,
|
||||
keyName: String,
|
||||
location: ApiKeyLocation): ApiRequest[U] =
|
||||
withCredentials(ApiKeyCredentials(key, keyName, location))
|
||||
|
||||
def withSuccessResponse[T](code: Int)(implicit m: Manifest[T]): ApiRequest[U] = copy[U](responses = responses + (code -> (m, ResponseState.Success)))
|
||||
def withSuccessResponse[T](code: Int)(
|
||||
implicit m: Manifest[T]): ApiRequest[U] =
|
||||
copy[U](responses = responses + (code -> (m, ResponseState.Success)))
|
||||
|
||||
def withErrorResponse[T](code: Int)(implicit m: Manifest[T]): ApiRequest[U] = copy[U](responses = responses + (code -> (m, ResponseState.Error)))
|
||||
def withErrorResponse[T](code: Int)(implicit m: Manifest[T]): ApiRequest[U] =
|
||||
copy[U](responses = responses + (code -> (m, ResponseState.Error)))
|
||||
|
||||
def withDefaultSuccessResponse[T](implicit m: Manifest[T]): ApiRequest[U] = withSuccessResponse[T](0)
|
||||
def withDefaultSuccessResponse[T](implicit m: Manifest[T]): ApiRequest[U] =
|
||||
withSuccessResponse[T](0)
|
||||
|
||||
def withDefaultErrorResponse[T](implicit m: Manifest[T]): ApiRequest[U] = withErrorResponse[T](0)
|
||||
def withDefaultErrorResponse[T](implicit m: Manifest[T]): ApiRequest[U] =
|
||||
withErrorResponse[T](0)
|
||||
|
||||
def responseForCode(statusCode: Int): Option[(Manifest[_], ResponseState)] = responses.get(statusCode) orElse responses.get(0)
|
||||
def responseForCode(statusCode: Int): Option[(Manifest[_], ResponseState)] =
|
||||
responses.get(statusCode) orElse responses.get(0)
|
||||
|
||||
def withoutBody(): ApiRequest[U] = copy[U](bodyParam = None)
|
||||
|
||||
def withBody(body: Any): ApiRequest[U] = copy[U](bodyParam = Some(body))
|
||||
|
||||
def withFormParam(name: String, value: Any): ApiRequest[U] = copy[U](formParams = formParams + (name -> value))
|
||||
def withFormParam(name: String, value: Any): ApiRequest[U] =
|
||||
copy[U](formParams = formParams + (name -> value))
|
||||
|
||||
def withPathParam(name: String, value: Any): ApiRequest[U] = copy[U](pathParams = pathParams + (name -> value))
|
||||
def withPathParam(name: String, value: Any): ApiRequest[U] =
|
||||
copy[U](pathParams = pathParams + (name -> value))
|
||||
|
||||
def withQueryParam(name: String, value: Any): ApiRequest[U] = copy[U](queryParams = queryParams + (name -> value))
|
||||
def withQueryParam(name: String, value: Any): ApiRequest[U] =
|
||||
copy[U](queryParams = queryParams + (name -> value))
|
||||
|
||||
def withHeaderParam(name: String, value: Any): ApiRequest[U] = copy[U](headerParams = headerParams + (name -> value))
|
||||
def withHeaderParam(name: String, value: Any): ApiRequest[U] =
|
||||
copy[U](headerParams = headerParams + (name -> value))
|
||||
}
|
||||
|
@ -27,13 +27,20 @@ class ApiSettings(config: Config) extends Extension {
|
||||
private def cfg = config.getConfig("org.openapitools.client.apiRequest")
|
||||
|
||||
val alwaysTrustCertificates: Boolean = cfg.getBoolean("trust-certificates")
|
||||
val defaultHeaders: List[RawHeader] = cfg.getConfig("default-headers").entrySet.toList.map(c => RawHeader(c.getKey, c.getValue.render))
|
||||
val connectionTimeout = FiniteDuration(cfg.getDuration("connection-timeout", TimeUnit.MILLISECONDS), TimeUnit.MILLISECONDS)
|
||||
val defaultHeaders: List[RawHeader] = cfg
|
||||
.getConfig("default-headers")
|
||||
.entrySet
|
||||
.toList
|
||||
.map(c => RawHeader(c.getKey, c.getValue.render))
|
||||
val connectionTimeout = FiniteDuration(
|
||||
cfg.getDuration("connection-timeout", TimeUnit.MILLISECONDS),
|
||||
TimeUnit.MILLISECONDS)
|
||||
val compressionEnabled: Boolean = cfg.getBoolean("compression.enabled")
|
||||
val compressionSizeThreshold: Int = cfg.getBytes("compression.size-threshold").toInt
|
||||
val customCodes: List[CustomStatusCode] = cfg.getConfigList("custom-codes").toList.map { c =>
|
||||
CustomStatusCode(
|
||||
c.getInt("code"),
|
||||
val compressionSizeThreshold: Int =
|
||||
cfg.getBytes("compression.size-threshold").toInt
|
||||
val customCodes: List[CustomStatusCode] =
|
||||
cfg.getConfigList("custom-codes").toList.map { c =>
|
||||
CustomStatusCode(c.getInt("code"),
|
||||
c.getString("reason"),
|
||||
c.getBoolean("success"))
|
||||
}
|
||||
|
@ -26,28 +26,42 @@ sealed trait ApiReturnWithHeaders {
|
||||
// workaround: return date time header in string instead of datetime object
|
||||
def getDateTimeHeader(name: String): Option[String] = header(name)
|
||||
|
||||
def getIntHeader(name: String): Option[Int] = castedHeader(name, java.lang.Integer.parseInt)
|
||||
def getIntHeader(name: String): Option[Int] =
|
||||
castedHeader(name, java.lang.Integer.parseInt)
|
||||
|
||||
def getLongHeader(name: String): Option[Long] = castedHeader(name, java.lang.Long.parseLong)
|
||||
def getLongHeader(name: String): Option[Long] =
|
||||
castedHeader(name, java.lang.Long.parseLong)
|
||||
|
||||
def getFloatHeader(name: String): Option[Float] = castedHeader(name, java.lang.Float.parseFloat)
|
||||
def getFloatHeader(name: String): Option[Float] =
|
||||
castedHeader(name, java.lang.Float.parseFloat)
|
||||
|
||||
def getDoubleHeader(name: String): Option[Double] = castedHeader(name, java.lang.Double.parseDouble)
|
||||
def getDoubleHeader(name: String): Option[Double] =
|
||||
castedHeader(name, java.lang.Double.parseDouble)
|
||||
|
||||
def getBooleanHeader(name: String): Option[Boolean] = castedHeader(name, java.lang.Boolean.parseBoolean)
|
||||
def getBooleanHeader(name: String): Option[Boolean] =
|
||||
castedHeader(name, java.lang.Boolean.parseBoolean)
|
||||
|
||||
private def castedHeader[U](name: String, conversion: String => U): Option[U] = {
|
||||
private def castedHeader[U](name: String,
|
||||
conversion: String => U): Option[U] = {
|
||||
Try {
|
||||
header(name).map(conversion)
|
||||
}.get
|
||||
}
|
||||
}
|
||||
|
||||
sealed case class ApiResponse[T](code: Int, content: T, headers: Map[String, String] = Map.empty)
|
||||
sealed case class ApiResponse[T](code: Int,
|
||||
content: T,
|
||||
headers: Map[String, String] = Map.empty)
|
||||
extends ApiReturnWithHeaders
|
||||
|
||||
sealed case class ApiError[T](code: Int, message: String, responseContent: Option[T], cause: Throwable = null, headers: Map[String, String] = Map.empty)
|
||||
extends Throwable(s"($code) $message.${responseContent.map(s => s" Content : $s").getOrElse("")}", cause)
|
||||
sealed case class ApiError[T](code: Int,
|
||||
message: String,
|
||||
responseContent: Option[T],
|
||||
cause: Throwable = null,
|
||||
headers: Map[String, String] = Map.empty)
|
||||
extends Throwable(
|
||||
s"($code) $message.${responseContent.map(s => s" Content : $s").getOrElse("")}",
|
||||
cause)
|
||||
with ApiReturnWithHeaders
|
||||
|
||||
sealed case class ApiMethod(value: String)
|
||||
@ -76,9 +90,13 @@ sealed trait Credentials {
|
||||
def asQueryParam: Option[(String, String)] = None
|
||||
}
|
||||
|
||||
sealed case class BasicCredentials(user: String, password: String) extends Credentials
|
||||
sealed case class BasicCredentials(user: String, password: String)
|
||||
extends Credentials
|
||||
|
||||
sealed case class ApiKeyCredentials(key: ApiKeyValue, keyName: String, location: ApiKeyLocation) extends Credentials {
|
||||
sealed case class ApiKeyCredentials(key: ApiKeyValue,
|
||||
keyName: String,
|
||||
location: ApiKeyLocation)
|
||||
extends Credentials {
|
||||
override def asQueryParam: Option[(String, String)] = location match {
|
||||
case ApiKeyLocations.QUERY => Some((keyName, key.value))
|
||||
case _ => None
|
||||
@ -97,7 +115,6 @@ object ApiKeyLocations {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Case class used to unapply numeric values only in pattern matching
|
||||
*
|
||||
@ -109,7 +126,8 @@ sealed case class NumericValue(value: String) {
|
||||
|
||||
object NumericValue {
|
||||
def unapply(n: Any): Option[NumericValue] = n match {
|
||||
case (_: Int | _: Long | _: Float | _: Double | _: Boolean | _: Byte) => Some(NumericValue(String.valueOf(n)))
|
||||
case (_: Int | _: Long | _: Float | _: Double | _: Boolean | _: Byte) =>
|
||||
Some(NumericValue(String.valueOf(n)))
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
@ -117,16 +135,17 @@ object NumericValue {
|
||||
/**
|
||||
* Used for params being arrays
|
||||
*/
|
||||
sealed case class ArrayValues(values: Seq[Any], format: CollectionFormat = CollectionFormats.CSV)
|
||||
sealed case class ArrayValues(values: Seq[Any],
|
||||
format: CollectionFormat = CollectionFormats.CSV)
|
||||
|
||||
object ArrayValues {
|
||||
def apply(values: Option[Seq[Any]], format: CollectionFormat): ArrayValues =
|
||||
ArrayValues(values.getOrElse(Seq.empty), format)
|
||||
|
||||
def apply(values: Option[Seq[Any]]): ArrayValues = ArrayValues(values, CollectionFormats.CSV)
|
||||
def apply(values: Option[Seq[Any]]): ArrayValues =
|
||||
ArrayValues(values, CollectionFormats.CSV)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Defines how arrays should be rendered in query strings.
|
||||
*/
|
||||
@ -166,19 +185,25 @@ object ParametersMap {
|
||||
*/
|
||||
implicit class ParametersMapImprovements(val m: Map[String, Any]) {
|
||||
|
||||
def asFormattedParamsList: List[(String, Any)] = m.toList.flatMap(formattedParams)
|
||||
def asFormattedParamsList: List[(String, Any)] =
|
||||
m.toList.flatMap(formattedParams)
|
||||
|
||||
def asFormattedParams: Map[String, Any] = m.flatMap(formattedParams)
|
||||
|
||||
private def urlEncode(v: Any) = URLEncoder.encode(String.valueOf(v), "utf-8").replaceAll("\\+", "%20")
|
||||
private def urlEncode(v: Any) =
|
||||
URLEncoder.encode(String.valueOf(v), "utf-8").replaceAll("\\+", "%20")
|
||||
|
||||
private def formattedParams(tuple: (String, Any)): Seq[(String, Any)] = formattedParams(tuple._1, tuple._2)
|
||||
private def formattedParams(tuple: (String, Any)): Seq[(String, Any)] =
|
||||
formattedParams(tuple._1, tuple._2)
|
||||
|
||||
private def formattedParams(name: String, value: Any): Seq[(String, Any)] = value match {
|
||||
private def formattedParams(name: String, value: Any): Seq[(String, Any)] =
|
||||
value match {
|
||||
case arr: ArrayValues =>
|
||||
arr.format match {
|
||||
case CollectionFormats.MULTI => arr.values.flatMap(formattedParams(name, _))
|
||||
case format: MergedArrayFormat => Seq((name, arr.values.mkString(format.separator)))
|
||||
case CollectionFormats.MULTI =>
|
||||
arr.values.flatMap(formattedParams(name, _))
|
||||
case format: MergedArrayFormat =>
|
||||
Seq((name, arr.values.mkString(format.separator)))
|
||||
}
|
||||
case None => Seq.empty
|
||||
case Some(opt) => formattedParams(name, opt)
|
||||
|
@ -15,10 +15,8 @@ import org.openapitools.client.core.ApiModel
|
||||
import org.joda.time.DateTime
|
||||
import java.util.UUID
|
||||
|
||||
case class ApiResponse (
|
||||
case class ApiResponse(
|
||||
code: Option[Int],
|
||||
`type`: Option[String],
|
||||
message: Option[String]
|
||||
) extends ApiModel
|
||||
|
||||
|
||||
|
@ -15,9 +15,7 @@ import org.openapitools.client.core.ApiModel
|
||||
import org.joda.time.DateTime
|
||||
import java.util.UUID
|
||||
|
||||
case class Category (
|
||||
case class Category(
|
||||
id: Option[Long],
|
||||
name: Option[String]
|
||||
) extends ApiModel
|
||||
|
||||
|
||||
|
@ -15,7 +15,7 @@ import org.openapitools.client.core.ApiModel
|
||||
import org.joda.time.DateTime
|
||||
import java.util.UUID
|
||||
|
||||
case class Order (
|
||||
case class Order(
|
||||
id: Option[Long],
|
||||
petId: Option[Long],
|
||||
quantity: Option[Int],
|
||||
@ -35,4 +35,3 @@ object OrderEnums {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ import org.openapitools.client.core.ApiModel
|
||||
import org.joda.time.DateTime
|
||||
import java.util.UUID
|
||||
|
||||
case class Pet (
|
||||
case class Pet(
|
||||
id: Option[Long],
|
||||
category: Option[Category],
|
||||
name: String,
|
||||
@ -35,4 +35,3 @@ object PetEnums {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -15,9 +15,7 @@ import org.openapitools.client.core.ApiModel
|
||||
import org.joda.time.DateTime
|
||||
import java.util.UUID
|
||||
|
||||
case class Tag (
|
||||
case class Tag(
|
||||
id: Option[Long],
|
||||
name: Option[String]
|
||||
) extends ApiModel
|
||||
|
||||
|
||||
|
@ -15,7 +15,7 @@ import org.openapitools.client.core.ApiModel
|
||||
import org.joda.time.DateTime
|
||||
import java.util.UUID
|
||||
|
||||
case class User (
|
||||
case class User(
|
||||
id: Option[Long],
|
||||
username: Option[String],
|
||||
firstName: Option[String],
|
||||
@ -26,5 +26,3 @@ case class User (
|
||||
/* User Status */
|
||||
userStatus: Option[Int]
|
||||
) extends ApiModel
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user