forked from loafle/openapi-generator-original
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:
committed by
William Cheng
parent
9e391efd1d
commit
28ae33cb13
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
4.0.0-SNAPSHOT
|
||||
55
samples/server/petstore/scala-play-framework/README.md
Normal file
55
samples/server/petstore/scala-play-framework/README.md
Normal 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
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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]
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
}
|
||||
|
||||
@@ -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])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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]
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.openapitools
|
||||
|
||||
object OpenApiExceptions {
|
||||
class MissingRequiredParameterException(paramName: String, paramType: String) extends Exception(s"Missing required $paramType parameter `$paramName`.")
|
||||
}
|
||||
14
samples/server/petstore/scala-play-framework/build.sbt
Normal file
14
samples/server/petstore/scala-play-framework/build.sbt
Normal 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
|
||||
)
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
40
samples/server/petstore/scala-play-framework/conf/routes
Normal file
40
samples/server/petstore/scala-play-framework/conf/routes
Normal 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
|
||||
@@ -0,0 +1 @@
|
||||
sbt.version=1.2.4
|
||||
@@ -0,0 +1 @@
|
||||
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.6.18")
|
||||
1012
samples/server/petstore/scala-play-framework/public/openapi.json
Normal file
1012
samples/server/petstore/scala-play-framework/public/openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user