New generator - Scala Play Framework (#2421)

* Added new generator for Scala + Play Framework (WIP)

* scala-play-framework: default values reintroduced (mostly); datatype -> dataType

* reintroduced missing EOF newline

* Support single/collection params for header/query params

* Rename apiFutures > supportAsync, implStubs > skipStubs (opt-out instead of opt-in)

* Deleted license and small fixes

* Generate extraction of form parameters from request body

* Added missing call to executeApi for unit methods when supportAsync=false

* Polished some stuff and added routes, application.conf, logback.xml, better default responses

* Disabled generation of Json.format for models with files

* Added README

* Multiple additions and improvements.

- Fix Indentation using mustache lambdas
- Option to set routes file name (default: routes) - allows uninterrupted manual maintenance of main routes file, which may include a subroute to the generated routes file
- Move supporting file classes to a package and update application.conf generation accordingly
- Option to generate custom exceptions (default: true) which are used in the controller to differentiate between API call exceptions and validation exceptions
- Generate error handler with basic exception mapping
- Option to generate API docs under /api route
- Reorder routes file so parameter-less paths are given priority over parameterized paths. Prevents case like /v2/user/:username activating before /v2/user/login (thus shadowing the login route completely) as observed using v3 petstore.yaml
- Option to set base package name (default: org.openapitools) to allow placing supporting files under a different package

* Revert supportAsync default to false

* Added binaries and default api/model packages

* Added scala-play-framework sample

* Add missing contextPath to README and controller comment
This commit is contained in:
Adi Gerber
2019-03-26 10:04:48 +02:00
committed by William Cheng
parent 9e391efd1d
commit 28ae33cb13
59 changed files with 3094 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
# OpenAPI Generator Ignore
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.
# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
#ApiClient.cs
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md

View File

@@ -0,0 +1 @@
4.0.0-SNAPSHOT

View File

@@ -0,0 +1,55 @@
# 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.
This Scala Play Framework project was generated by the OpenAPI generator tool at 2019-03-26T02:45:22.426+02:00[Asia/Jerusalem].
## API
### Pet
|Name|Role|
|----|----|
|`api.PetController`|Play Framework API controller|
|`api.PetApi`|Representing trait|
|`api.PetApiImpl`|Default implementation|
* `POST /pet` - Add a new pet to the store
* `DELETE /pet/:petId` - Deletes a pet
* `GET /pet/findByStatus?status=[value]` - Finds Pets by status
* `GET /pet/findByTags?tags=[value]` - Finds Pets by tags
* `GET /pet/:petId` - Find pet by ID
* `PUT /pet` - Update an existing pet
* `POST /pet/:petId` - Updates a pet in the store with form data
* `POST /pet/:petId/uploadImage` - uploads an image
### Store
|Name|Role|
|----|----|
|`api.StoreController`|Play Framework API controller|
|`api.StoreApi`|Representing trait|
|`api.StoreApiImpl`|Default implementation|
* `DELETE /store/order/:orderId` - Delete purchase order by ID
* `GET /store/inventory` - Returns pet inventories by status
* `GET /store/order/:orderId` - Find purchase order by ID
* `POST /store/order` - Place an order for a pet
### User
|Name|Role|
|----|----|
|`api.UserController`|Play Framework API controller|
|`api.UserApi`|Representing trait|
|`api.UserApiImpl`|Default implementation|
* `POST /user` - Create user
* `POST /user/createWithArray` - Creates list of users with given input array
* `POST /user/createWithList` - Creates list of users with given input array
* `DELETE /user/:username` - Delete user
* `GET /user/:username` - Get user by user name
* `GET /user/login?username=[value]&password=[value]` - Logs user into the system
* `GET /user/logout` - Logs out current logged in user session
* `PUT /user/:username` - Updated user

View File

@@ -0,0 +1,11 @@
package api
import javax.inject.{Inject, Singleton}
import play.api.mvc._
@Singleton
class ApiDocController @Inject()(cc: ControllerComponents) extends AbstractController(cc) {
def api: Action[AnyContent] = Action {
Redirect("/assets/lib/swagger-ui/index.html?/url=/assets/openapi.json")
}
}

View File

@@ -0,0 +1,63 @@
package api
import model.ApiResponse
import model.Pet
import play.api.libs.Files.TemporaryFile
@javax.annotation.Generated(value = Array("org.openapitools.codegen.languages.ScalaPlayFrameworkServerCodegen"), date = "2019-03-26T02:45:22.426+02:00[Asia/Jerusalem]")
trait PetApi {
/**
* Add a new pet to the store
* @param body Pet object that needs to be added to the store
*/
def addPet(body: Pet): Unit
/**
* Deletes a pet
* @param petId Pet id to delete
*/
def deletePet(petId: Long, apiKey: Option[String]): Unit
/**
* Finds Pets by status
* Multiple status values can be provided with comma separated strings
* @param status Status values that need to be considered for filter
*/
def findPetsByStatus(status: List[String]): List[Pet]
/**
* Finds Pets by tags
* Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
* @param tags Tags to filter by
*/
def findPetsByTags(tags: List[String]): List[Pet]
/**
* Find pet by ID
* Returns a single pet
* @param petId ID of pet to return
*/
def getPetById(petId: Long): Pet
/**
* Update an existing pet
* @param body Pet object that needs to be added to the store
*/
def updatePet(body: Pet): Unit
/**
* Updates a pet in the store with form data
* @param petId ID of pet that needs to be updated
* @param name Updated name of the pet
* @param status Updated status of the pet
*/
def updatePetWithForm(petId: Long, name: Option[String], status: Option[String]): Unit
/**
* uploads an image
* @param petId ID of pet to update
* @param additionalMetadata Additional data to pass to server
* @param file file to upload
*/
def uploadFile(petId: Long, additionalMetadata: Option[String], file: Option[TemporaryFile]): ApiResponse
}

View File

@@ -0,0 +1,161 @@
package api
import org.openapitools.OpenApiExceptions
import javax.inject.{Inject, Singleton}
import play.api.libs.json._
import play.api.mvc._
import model.ApiResponse
import model.Pet
import play.api.libs.Files.TemporaryFile
@javax.annotation.Generated(value = Array("org.openapitools.codegen.languages.ScalaPlayFrameworkServerCodegen"), date = "2019-03-26T02:45:22.426+02:00[Asia/Jerusalem]")
@Singleton
class PetApiController @Inject()(cc: ControllerComponents, api: PetApi) extends AbstractController(cc) {
/**
* POST /pet
*/
def addPet(): Action[AnyContent] = Action { request =>
def executeApi(): Unit = {
val body = request.body.asJson.map(_.as[Pet]).getOrElse {
throw new OpenApiExceptions.MissingRequiredParameterException("body", "body")
}
api.addPet(body)
}
executeApi()
Ok
}
/**
* DELETE /pet/:petId
* @param petId Pet id to delete
*/
def deletePet(petId: Long): Action[AnyContent] = Action { request =>
def executeApi(): Unit = {
val apiKey = request.headers.get("api_key")
api.deletePet(petId, apiKey)
}
executeApi()
Ok
}
/**
* GET /pet/findByStatus?status=[value]
*/
def findPetsByStatus(): Action[AnyContent] = Action { request =>
def executeApi(): List[Pet] = {
val status = request.getQueryString("status")
.map(values => splitCollectionParam(values, "csv"))
.getOrElse {
throw new OpenApiExceptions.MissingRequiredParameterException("status", "query string")
}
api.findPetsByStatus(status)
}
val result = executeApi()
val json = Json.toJson(result)
Ok(json)
}
/**
* GET /pet/findByTags?tags=[value]
*/
def findPetsByTags(): Action[AnyContent] = Action { request =>
def executeApi(): List[Pet] = {
val tags = request.getQueryString("tags")
.map(values => splitCollectionParam(values, "csv"))
.getOrElse {
throw new OpenApiExceptions.MissingRequiredParameterException("tags", "query string")
}
api.findPetsByTags(tags)
}
val result = executeApi()
val json = Json.toJson(result)
Ok(json)
}
/**
* GET /pet/:petId
* @param petId ID of pet to return
*/
def getPetById(petId: Long): Action[AnyContent] = Action { request =>
def executeApi(): Pet = {
api.getPetById(petId)
}
val result = executeApi()
val json = Json.toJson(result)
Ok(json)
}
/**
* PUT /pet
*/
def updatePet(): Action[AnyContent] = Action { request =>
def executeApi(): Unit = {
val body = request.body.asJson.map(_.as[Pet]).getOrElse {
throw new OpenApiExceptions.MissingRequiredParameterException("body", "body")
}
api.updatePet(body)
}
executeApi()
Ok
}
/**
* POST /pet/:petId
* @param petId ID of pet that needs to be updated
*/
def updatePetWithForm(petId: Long): Action[AnyContent] = Action { request =>
def executeApi(): Unit = {
val name = (request.body.asMultipartFormData.map(_.asFormUrlEncoded) orElse request.body.asFormUrlEncoded)
.flatMap(_.get("name"))
.flatMap(_.headOption)
val status = (request.body.asMultipartFormData.map(_.asFormUrlEncoded) orElse request.body.asFormUrlEncoded)
.flatMap(_.get("status"))
.flatMap(_.headOption)
api.updatePetWithForm(petId, name, status)
}
executeApi()
Ok
}
/**
* POST /pet/:petId/uploadImage
* @param petId ID of pet to update
*/
def uploadFile(petId: Long): Action[AnyContent] = Action { request =>
def executeApi(): ApiResponse = {
val additionalMetadata = (request.body.asMultipartFormData.map(_.asFormUrlEncoded) orElse request.body.asFormUrlEncoded)
.flatMap(_.get("additionalMetadata"))
.flatMap(_.headOption)
val file = request.body.asMultipartFormData.flatMap(_.file("file").map(_.ref: TemporaryFile))
api.uploadFile(petId, additionalMetadata, file)
}
val result = executeApi()
val json = Json.toJson(result)
Ok(json)
}
private def splitCollectionParam(paramValues: String, collectionFormat: String): List[String] = {
val splitBy =
collectionFormat match {
case "csv" => ",+"
case "tsv" => "\t+"
case "ssv" => " +"
case "pipes" => "|+"
}
paramValues.split(splitBy).toList
}
}

View File

@@ -0,0 +1,83 @@
package api
import model.ApiResponse
import model.Pet
import play.api.libs.Files.TemporaryFile
/**
* Provides a default implementation for [[PetApi]].
*/
@javax.annotation.Generated(value = Array("org.openapitools.codegen.languages.ScalaPlayFrameworkServerCodegen"), date = "2019-03-26T02:45:22.426+02:00[Asia/Jerusalem]")
class PetApiImpl extends PetApi {
/**
* @inheritdoc
*/
override def addPet(body: Pet): Unit = {
// TODO: Implement better logic
}
/**
* @inheritdoc
*/
override def deletePet(petId: Long, apiKey: Option[String]): Unit = {
// TODO: Implement better logic
}
/**
* @inheritdoc
*/
override def findPetsByStatus(status: List[String]): List[Pet] = {
// TODO: Implement better logic
List.empty[Pet]
}
/**
* @inheritdoc
*/
override def findPetsByTags(tags: List[String]): List[Pet] = {
// TODO: Implement better logic
List.empty[Pet]
}
/**
* @inheritdoc
*/
override def getPetById(petId: Long): Pet = {
// TODO: Implement better logic
Pet(None, None, "", List.empty[String], None, None)
}
/**
* @inheritdoc
*/
override def updatePet(body: Pet): Unit = {
// TODO: Implement better logic
}
/**
* @inheritdoc
*/
override def updatePetWithForm(petId: Long, name: Option[String], status: Option[String]): Unit = {
// TODO: Implement better logic
}
/**
* @inheritdoc
*/
override def uploadFile(petId: Long, additionalMetadata: Option[String], file: Option[TemporaryFile]): ApiResponse = {
// TODO: Implement better logic
ApiResponse(None, None, None)
}
}

View File

@@ -0,0 +1,32 @@
package api
import model.Order
@javax.annotation.Generated(value = Array("org.openapitools.codegen.languages.ScalaPlayFrameworkServerCodegen"), date = "2019-03-26T02:45:22.426+02:00[Asia/Jerusalem]")
trait StoreApi {
/**
* Delete purchase order by ID
* For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
* @param orderId ID of the order that needs to be deleted
*/
def deleteOrder(orderId: String): Unit
/**
* Returns pet inventories by status
* Returns a map of status codes to quantities
*/
def getInventory(): Map[String, Int]
/**
* Find purchase order by ID
* For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions
* @param orderId ID of pet that needs to be fetched
*/
def getOrderById(orderId: Long): Order
/**
* Place an order for a pet
* @param body order placed for purchasing the pet
*/
def placeOrder(body: Order): Order
}

View File

@@ -0,0 +1,79 @@
package api
import org.openapitools.OpenApiExceptions
import javax.inject.{Inject, Singleton}
import play.api.libs.json._
import play.api.mvc._
import model.Order
@javax.annotation.Generated(value = Array("org.openapitools.codegen.languages.ScalaPlayFrameworkServerCodegen"), date = "2019-03-26T02:45:22.426+02:00[Asia/Jerusalem]")
@Singleton
class StoreApiController @Inject()(cc: ControllerComponents, api: StoreApi) extends AbstractController(cc) {
/**
* DELETE /store/order/:orderId
* @param orderId ID of the order that needs to be deleted
*/
def deleteOrder(orderId: String): Action[AnyContent] = Action { request =>
def executeApi(): Unit = {
api.deleteOrder(orderId)
}
executeApi()
Ok
}
/**
* GET /store/inventory
*/
def getInventory(): Action[AnyContent] = Action { request =>
def executeApi(): Map[String, Int] = {
api.getInventory()
}
val result = executeApi()
val json = Json.toJson(result)
Ok(json)
}
/**
* GET /store/order/:orderId
* @param orderId ID of pet that needs to be fetched
*/
def getOrderById(orderId: Long): Action[AnyContent] = Action { request =>
def executeApi(): Order = {
api.getOrderById(orderId)
}
val result = executeApi()
val json = Json.toJson(result)
Ok(json)
}
/**
* POST /store/order
*/
def placeOrder(): Action[AnyContent] = Action { request =>
def executeApi(): Order = {
val body = request.body.asJson.map(_.as[Order]).getOrElse {
throw new OpenApiExceptions.MissingRequiredParameterException("body", "body")
}
api.placeOrder(body)
}
val result = executeApi()
val json = Json.toJson(result)
Ok(json)
}
private def splitCollectionParam(paramValues: String, collectionFormat: String): List[String] = {
val splitBy =
collectionFormat match {
case "csv" => ",+"
case "tsv" => "\t+"
case "ssv" => " +"
case "pipes" => "|+"
}
paramValues.split(splitBy).toList
}
}

View File

@@ -0,0 +1,45 @@
package api
import model.Order
/**
* Provides a default implementation for [[StoreApi]].
*/
@javax.annotation.Generated(value = Array("org.openapitools.codegen.languages.ScalaPlayFrameworkServerCodegen"), date = "2019-03-26T02:45:22.426+02:00[Asia/Jerusalem]")
class StoreApiImpl extends StoreApi {
/**
* @inheritdoc
*/
override def deleteOrder(orderId: String): Unit = {
// TODO: Implement better logic
}
/**
* @inheritdoc
*/
override def getInventory(): Map[String, Int] = {
// TODO: Implement better logic
Map.empty[String, Int]
}
/**
* @inheritdoc
*/
override def getOrderById(orderId: Long): Order = {
// TODO: Implement better logic
Order(None, None, None, None, None, None)
}
/**
* @inheritdoc
*/
override def placeOrder(body: Order): Order = {
// TODO: Implement better logic
Order(None, None, None, None, None, None)
}
}

View File

@@ -0,0 +1,58 @@
package api
import model.User
@javax.annotation.Generated(value = Array("org.openapitools.codegen.languages.ScalaPlayFrameworkServerCodegen"), date = "2019-03-26T02:45:22.426+02:00[Asia/Jerusalem]")
trait UserApi {
/**
* Create user
* This can only be done by the logged in user.
* @param body Created user object
*/
def createUser(body: User): Unit
/**
* Creates list of users with given input array
* @param body List of user object
*/
def createUsersWithArrayInput(body: List[User]): Unit
/**
* Creates list of users with given input array
* @param body List of user object
*/
def createUsersWithListInput(body: List[User]): Unit
/**
* Delete user
* This can only be done by the logged in user.
* @param username The name that needs to be deleted
*/
def deleteUser(username: String): Unit
/**
* Get user by user name
* @param username The name that needs to be fetched. Use user1 for testing.
*/
def getUserByName(username: String): User
/**
* Logs user into the system
* @param username The user name for login
* @param password The password for login in clear text
*/
def loginUser(username: String, password: String): String
/**
* Logs out current logged in user session
*/
def logoutUser(): Unit
/**
* Updated user
* This can only be done by the logged in user.
* @param username name that need to be deleted
* @param body Updated user object
*/
def updateUser(username: String, body: User): Unit
}

View File

@@ -0,0 +1,144 @@
package api
import org.openapitools.OpenApiExceptions
import javax.inject.{Inject, Singleton}
import play.api.libs.json._
import play.api.mvc._
import model.User
@javax.annotation.Generated(value = Array("org.openapitools.codegen.languages.ScalaPlayFrameworkServerCodegen"), date = "2019-03-26T02:45:22.426+02:00[Asia/Jerusalem]")
@Singleton
class UserApiController @Inject()(cc: ControllerComponents, api: UserApi) extends AbstractController(cc) {
/**
* POST /user
*/
def createUser(): Action[AnyContent] = Action { request =>
def executeApi(): Unit = {
val body = request.body.asJson.map(_.as[User]).getOrElse {
throw new OpenApiExceptions.MissingRequiredParameterException("body", "body")
}
api.createUser(body)
}
executeApi()
Ok
}
/**
* POST /user/createWithArray
*/
def createUsersWithArrayInput(): Action[AnyContent] = Action { request =>
def executeApi(): Unit = {
val body = request.body.asJson.map(_.as[List[User]]).getOrElse {
throw new OpenApiExceptions.MissingRequiredParameterException("body", "body")
}
api.createUsersWithArrayInput(body)
}
executeApi()
Ok
}
/**
* POST /user/createWithList
*/
def createUsersWithListInput(): Action[AnyContent] = Action { request =>
def executeApi(): Unit = {
val body = request.body.asJson.map(_.as[List[User]]).getOrElse {
throw new OpenApiExceptions.MissingRequiredParameterException("body", "body")
}
api.createUsersWithListInput(body)
}
executeApi()
Ok
}
/**
* DELETE /user/:username
* @param username The name that needs to be deleted
*/
def deleteUser(username: String): Action[AnyContent] = Action { request =>
def executeApi(): Unit = {
api.deleteUser(username)
}
executeApi()
Ok
}
/**
* GET /user/:username
* @param username The name that needs to be fetched. Use user1 for testing.
*/
def getUserByName(username: String): Action[AnyContent] = Action { request =>
def executeApi(): User = {
api.getUserByName(username)
}
val result = executeApi()
val json = Json.toJson(result)
Ok(json)
}
/**
* GET /user/login?username=[value]&password=[value]
*/
def loginUser(): Action[AnyContent] = Action { request =>
def executeApi(): String = {
val username = request.getQueryString("username")
.getOrElse {
throw new OpenApiExceptions.MissingRequiredParameterException("username", "query string")
}
val password = request.getQueryString("password")
.getOrElse {
throw new OpenApiExceptions.MissingRequiredParameterException("password", "query string")
}
api.loginUser(username, password)
}
val result = executeApi()
val json = Json.toJson(result)
Ok(json)
}
/**
* GET /user/logout
*/
def logoutUser(): Action[AnyContent] = Action { request =>
def executeApi(): Unit = {
api.logoutUser()
}
executeApi()
Ok
}
/**
* PUT /user/:username
* @param username name that need to be deleted
*/
def updateUser(username: String): Action[AnyContent] = Action { request =>
def executeApi(): Unit = {
val body = request.body.asJson.map(_.as[User]).getOrElse {
throw new OpenApiExceptions.MissingRequiredParameterException("body", "body")
}
api.updateUser(username, body)
}
executeApi()
Ok
}
private def splitCollectionParam(paramValues: String, collectionFormat: String): List[String] = {
val splitBy =
collectionFormat match {
case "csv" => ",+"
case "tsv" => "\t+"
case "ssv" => " +"
case "pipes" => "|+"
}
paramValues.split(splitBy).toList
}
}

View File

@@ -0,0 +1,81 @@
package api
import model.User
/**
* Provides a default implementation for [[UserApi]].
*/
@javax.annotation.Generated(value = Array("org.openapitools.codegen.languages.ScalaPlayFrameworkServerCodegen"), date = "2019-03-26T02:45:22.426+02:00[Asia/Jerusalem]")
class UserApiImpl extends UserApi {
/**
* @inheritdoc
*/
override def createUser(body: User): Unit = {
// TODO: Implement better logic
}
/**
* @inheritdoc
*/
override def createUsersWithArrayInput(body: List[User]): Unit = {
// TODO: Implement better logic
}
/**
* @inheritdoc
*/
override def createUsersWithListInput(body: List[User]): Unit = {
// TODO: Implement better logic
}
/**
* @inheritdoc
*/
override def deleteUser(username: String): Unit = {
// TODO: Implement better logic
}
/**
* @inheritdoc
*/
override def getUserByName(username: String): User = {
// TODO: Implement better logic
User(None, None, None, None, None, None, None, None)
}
/**
* @inheritdoc
*/
override def loginUser(username: String, password: String): String = {
// TODO: Implement better logic
""
}
/**
* @inheritdoc
*/
override def logoutUser(): Unit = {
// TODO: Implement better logic
}
/**
* @inheritdoc
*/
override def updateUser(username: String, body: User): Unit = {
// TODO: Implement better logic
}
}

View File

@@ -0,0 +1,18 @@
package model
import play.api.libs.json._
/**
* Describes the result of uploading an image resource
*/
@javax.annotation.Generated(value = Array("org.openapitools.codegen.languages.ScalaPlayFrameworkServerCodegen"), date = "2019-03-26T02:45:22.426+02:00[Asia/Jerusalem]")
case class ApiResponse(
code: Option[Int],
`type`: Option[String],
message: Option[String]
)
object ApiResponse {
implicit lazy val apiResponseJsonFormat: Format[ApiResponse] = Json.format[ApiResponse]
}

View File

@@ -0,0 +1,17 @@
package model
import play.api.libs.json._
/**
* A category for a pet
*/
@javax.annotation.Generated(value = Array("org.openapitools.codegen.languages.ScalaPlayFrameworkServerCodegen"), date = "2019-03-26T02:45:22.426+02:00[Asia/Jerusalem]")
case class Category(
id: Option[Long],
name: Option[String]
)
object Category {
implicit lazy val categoryJsonFormat: Format[Category] = Json.format[Category]
}

View File

@@ -0,0 +1,33 @@
package model
import play.api.libs.json._
import java.time.OffsetDateTime
/**
* An order for a pets from the pet store
* @param status Order Status
*/
@javax.annotation.Generated(value = Array("org.openapitools.codegen.languages.ScalaPlayFrameworkServerCodegen"), date = "2019-03-26T02:45:22.426+02:00[Asia/Jerusalem]")
case class Order(
id: Option[Long],
petId: Option[Long],
quantity: Option[Int],
shipDate: Option[OffsetDateTime],
status: Option[Order.Status.Value],
complete: Option[Boolean]
)
object Order {
implicit lazy val orderJsonFormat: Format[Order] = Json.format[Order]
// noinspection TypeAnnotation
object Status extends Enumeration {
val Placed = Value("placed")
val Approved = Value("approved")
val Delivered = Value("delivered")
type Status = Value
implicit lazy val StatusJsonFormat: Format[Value] = Format(Reads.enumNameReads(this), Writes.enumNameWrites[this.type])
}
}

View File

@@ -0,0 +1,32 @@
package model
import play.api.libs.json._
/**
* A pet for sale in the pet store
* @param status pet status in the store
*/
@javax.annotation.Generated(value = Array("org.openapitools.codegen.languages.ScalaPlayFrameworkServerCodegen"), date = "2019-03-26T02:45:22.426+02:00[Asia/Jerusalem]")
case class Pet(
id: Option[Long],
category: Option[Category],
name: String,
photoUrls: List[String],
tags: Option[List[Tag]],
status: Option[Pet.Status.Value]
)
object Pet {
implicit lazy val petJsonFormat: Format[Pet] = Json.format[Pet]
// noinspection TypeAnnotation
object Status extends Enumeration {
val Available = Value("available")
val Pending = Value("pending")
val Sold = Value("sold")
type Status = Value
implicit lazy val StatusJsonFormat: Format[Value] = Format(Reads.enumNameReads(this), Writes.enumNameWrites[this.type])
}
}

View File

@@ -0,0 +1,17 @@
package model
import play.api.libs.json._
/**
* A tag for a pet
*/
@javax.annotation.Generated(value = Array("org.openapitools.codegen.languages.ScalaPlayFrameworkServerCodegen"), date = "2019-03-26T02:45:22.426+02:00[Asia/Jerusalem]")
case class Tag(
id: Option[Long],
name: Option[String]
)
object Tag {
implicit lazy val tagJsonFormat: Format[Tag] = Json.format[Tag]
}

View File

@@ -0,0 +1,24 @@
package model
import play.api.libs.json._
/**
* A User who is purchasing from the pet store
* @param userStatus User Status
*/
@javax.annotation.Generated(value = Array("org.openapitools.codegen.languages.ScalaPlayFrameworkServerCodegen"), date = "2019-03-26T02:45:22.426+02:00[Asia/Jerusalem]")
case class User(
id: Option[Long],
username: Option[String],
firstName: Option[String],
lastName: Option[String],
email: Option[String],
password: Option[String],
phone: Option[String],
userStatus: Option[Int]
)
object User {
implicit lazy val userJsonFormat: Format[User] = Json.format[User]
}

View File

@@ -0,0 +1,20 @@
package org.openapitools
import play.api.http.DefaultHttpErrorHandler
import play.api.libs.json.JsResultException
import play.api.mvc.Results._
import play.api.mvc.{RequestHeader, Result}
import scala.concurrent.Future
class ErrorHandler extends DefaultHttpErrorHandler {
override def onServerError(request: RequestHeader, e: Throwable): Future[Result] = e match {
case _: OpenApiExceptions.MissingRequiredParameterException =>
Future.successful(BadRequest(e.getMessage))
case _: JsResultException =>
Future.successful(BadRequest(e.getMessage))
case _ =>
// Handles dev mode properly, or otherwise returns internal server error in production mode
super.onServerError(request, e)
}
}

View File

@@ -0,0 +1,14 @@
package org.openapitools
import api._
import play.api.inject.{Binding, Module => PlayModule}
import play.api.{Configuration, Environment}
@javax.annotation.Generated(value = Array("org.openapitools.codegen.languages.ScalaPlayFrameworkServerCodegen"), date = "2019-03-26T02:45:22.426+02:00[Asia/Jerusalem]")
class Module extends PlayModule {
override def bindings(environment: Environment, configuration: Configuration): Seq[Binding[_]] = Seq(
bind[PetApi].to[PetApiImpl],
bind[StoreApi].to[StoreApiImpl],
bind[UserApi].to[UserApiImpl]
)
}

View File

@@ -0,0 +1,5 @@
package org.openapitools
object OpenApiExceptions {
class MissingRequiredParameterException(paramName: String, paramType: String) extends Exception(s"Missing required $paramType parameter `$paramName`.")
}

View File

@@ -0,0 +1,14 @@
organization := ""
version := ""
name := ""
scalaVersion := "2.12.6"
enablePlugins(PlayScala)
libraryDependencies ++= Seq(
guice,
ws,
"org.webjars" % "swagger-ui" % "3.1.5",
"org.scalatest" %% "scalatest" % "3.0.4" % Test,
"org.scalatestplus.play" %% "scalatestplus-play" % "3.1.2" % Test
)

View File

@@ -0,0 +1,17 @@
# This is the main configuration file for the application.
# Refer to https://www.playframework.com/documentation/latest/ConfigFile for more information.
play {
filters.headers.contentSecurityPolicy = null
modules.enabled += "org.openapitools.Module"
http {
secret.key = "changeme"
errorHandler = "org.openapitools.ErrorHandler"
}
assets {
path = "/public"
urlPrefix = "/assets"
}
}

View File

@@ -0,0 +1,41 @@
<!-- https://www.playframework.com/documentation/latest/SettingsLogger -->
<configuration>
<conversionRule conversionWord="coloredLevel" converterClass="play.api.libs.logback.ColoredLevel" />
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${application.home:-.}/logs/application.log</file>
<encoder>
<pattern>%date [%level] from %logger in %thread - %message%n%xException</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%coloredLevel %logger{15} - %message%n%xException{10}</pattern>
</encoder>
</appender>
<appender name="ASYNCFILE" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="FILE" />
</appender>
<appender name="ASYNCSTDOUT" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="STDOUT" />
</appender>
<logger name="play" level="INFO" />
<logger name="application" level="DEBUG" />
<!-- Off these ones as they are annoying, and anyway we manage configuration ourselves -->
<logger name="com.avaje.ebean.config.PropertyMapLoader" level="OFF" />
<logger name="com.avaje.ebeaninternal.server.core.XmlConfigLoader" level="OFF" />
<logger name="com.avaje.ebeaninternal.server.lib.BackgroundThread" level="OFF" />
<logger name="com.gargoylesoftware.htmlunit.javascript" level="OFF" />
<root level="WARN">
<appender-ref ref="ASYNCFILE" />
<appender-ref ref="ASYNCSTDOUT" />
</root>
</configuration>

View File

@@ -0,0 +1,40 @@
# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~
# Routes for Pet API
POST /v2/pet api.PetApiController.addPet()
GET /v2/pet/findByStatus api.PetApiController.findPetsByStatus()
GET /v2/pet/findByTags api.PetApiController.findPetsByTags()
PUT /v2/pet api.PetApiController.updatePet()
DELETE /v2/pet/:petId api.PetApiController.deletePet(petId: Long)
GET /v2/pet/:petId api.PetApiController.getPetById(petId: Long)
POST /v2/pet/:petId api.PetApiController.updatePetWithForm(petId: Long)
POST /v2/pet/:petId/uploadImage api.PetApiController.uploadFile(petId: Long)
# Routes for Store API
GET /v2/store/inventory api.StoreApiController.getInventory()
POST /v2/store/order api.StoreApiController.placeOrder()
DELETE /v2/store/order/:orderId api.StoreApiController.deleteOrder(orderId: String)
GET /v2/store/order/:orderId api.StoreApiController.getOrderById(orderId: Long)
# Routes for User API
POST /v2/user api.UserApiController.createUser()
POST /v2/user/createWithArray api.UserApiController.createUsersWithArrayInput()
POST /v2/user/createWithList api.UserApiController.createUsersWithListInput()
GET /v2/user/login api.UserApiController.loginUser()
GET /v2/user/logout api.UserApiController.logoutUser()
DELETE /v2/user/:username api.UserApiController.deleteUser(username: String)
GET /v2/user/:username api.UserApiController.getUserByName(username: String)
PUT /v2/user/:username api.UserApiController.updateUser(username: String)
# Map static resources from the /public folder to the /assets URL path
GET /assets/*file controllers.Assets.at(file)
GET /versionedAssets/*file controllers.Assets.versioned(file)
# Swagger UI
GET /api api.ApiDocController.api

View File

@@ -0,0 +1 @@
sbt.version=1.2.4

View File

@@ -0,0 +1 @@
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.18")

File diff suppressed because it is too large Load Diff