forked from loafle/openapi-generator-original
[Scala][Finch] Adding security definitions to Finch (#6891)
* #6818: support for security definitions and some refactoring * adding support for Either * adding dates with TimeZone (date-time) and Local (date) * cleanup * generating code
This commit is contained in:
parent
5d59dd10ec
commit
1b90a05754
@ -1,6 +1,5 @@
|
||||
package io.swagger.codegen.languages;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import io.swagger.codegen.*;
|
||||
import io.swagger.models.Model;
|
||||
import io.swagger.models.properties.ArrayProperty;
|
||||
@ -81,7 +80,7 @@ public class FinchServerCodegen extends DefaultCodegen implements CodegenConfig
|
||||
typeMapping.put("long", "Long");
|
||||
typeMapping.put("double", "Double");
|
||||
typeMapping.put("number", "BigDecimal");
|
||||
typeMapping.put("date-time", "LocalDateTime");
|
||||
typeMapping.put("date-time", "ZonedDateTime");
|
||||
typeMapping.put("date", "LocalDateTime");
|
||||
typeMapping.put("file", "File");
|
||||
typeMapping.put("array", "Seq");
|
||||
@ -90,7 +89,7 @@ public class FinchServerCodegen extends DefaultCodegen implements CodegenConfig
|
||||
typeMapping.put("object", "Object");
|
||||
typeMapping.put("binary", "Array[Byte]");
|
||||
typeMapping.put("Date", "LocalDateTime");
|
||||
typeMapping.put("DateTime", "LocalDateTime");
|
||||
typeMapping.put("DateTime", "ZonedDateTime");
|
||||
|
||||
additionalProperties.put("modelPackage", modelPackage());
|
||||
additionalProperties.put("apiPackage", apiPackage());
|
||||
@ -154,6 +153,7 @@ public class FinchServerCodegen extends DefaultCodegen implements CodegenConfig
|
||||
importMapping.put("LocalDateTime", "java.time.LocalDateTime");
|
||||
importMapping.put("LocalDate", "java.time.LocalDate");
|
||||
importMapping.put("LocalTime", "java.time.LocalTime");
|
||||
importMapping.put("ZonedDateTime", "java.time.ZonedDateTime");
|
||||
|
||||
cliOptions.clear();
|
||||
cliOptions.add(new CliOption(CodegenConstants.PACKAGE_NAME, "Finch package name (e.g. io.swagger).")
|
||||
@ -206,81 +206,31 @@ public class FinchServerCodegen extends DefaultCodegen implements CodegenConfig
|
||||
return codegenModel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
|
||||
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
|
||||
List<CodegenOperation> operationList = (List<CodegenOperation>) operations.get("operation");
|
||||
for (CodegenOperation op : operationList) {
|
||||
op.httpMethod = op.httpMethod.toLowerCase();
|
||||
|
||||
String path = new String(op.path);
|
||||
// remove first /
|
||||
if (path.startsWith("/")) {
|
||||
path = path.substring(1);
|
||||
}
|
||||
// remove last /
|
||||
if (path.endsWith("/")) {
|
||||
path = path.substring(0, path.length()-1);
|
||||
// Converts GET /foo/bar => get("foo" :: "bar")
|
||||
generateScalaPath(op);
|
||||
|
||||
// Generates e.g. uuid :: header("boo") :: params("baa") under key "x-codegen-pathParams"
|
||||
// Generates e.g. (id: UUID, headerBoo: String, paramBaa: String) under key "x-codegen-typedInputParams"
|
||||
// Generates e.g. (id, headerBoo, paramBaa) under key "x-codegen-inputParams"
|
||||
generateInputParameters(op);
|
||||
|
||||
//Generate Auth parameters using security: definition
|
||||
//Results in header("apiKey") or param("apiKey")
|
||||
authParameters(op);
|
||||
|
||||
//Concatenates all parameters
|
||||
concatParameters(op);
|
||||
}
|
||||
|
||||
String[] items = path.split("/", -1);
|
||||
String scalaPath = "";
|
||||
int pathParamIndex = 0;
|
||||
|
||||
for (int i = 0; i < items.length; ++i) {
|
||||
if (items[i].matches("^\\{(.*)\\}$")) { // wrap in {}
|
||||
// find the datatype of the parameter
|
||||
final CodegenParameter cp = op.pathParams.get(pathParamIndex);
|
||||
|
||||
// TODO: Handle non-primitives…
|
||||
scalaPath = scalaPath + cp.dataType.toLowerCase();
|
||||
|
||||
pathParamIndex++;
|
||||
} else {
|
||||
scalaPath = scalaPath + "\"" + items[i] + "\"";
|
||||
}
|
||||
|
||||
if (i != items.length -1) {
|
||||
scalaPath = scalaPath + " :: ";
|
||||
}
|
||||
}
|
||||
|
||||
for (CodegenParameter p : op.allParams) {
|
||||
// TODO: This hacky, should be converted to mappings if possible to keep it clean.
|
||||
// This could also be done using template imports
|
||||
if(p.isPathParam && p.isPrimitiveType) {
|
||||
p.vendorExtensions.put("x-codegen-normalized-path-type", p.dataType.toLowerCase());
|
||||
p.vendorExtensions.put("x-codegen-normalized-input-type", p.dataType);
|
||||
} else if(p.isHeaderParam) {
|
||||
if(p.required) {
|
||||
p.vendorExtensions.put("x-codegen-normalized-path-type", "header(\"" + p.baseName + "\")");
|
||||
p.vendorExtensions.put("x-codegen-normalized-input-type", p.dataType);
|
||||
} else {
|
||||
p.vendorExtensions.put("x-codegen-normalized-path-type", "headerOption(\"" + p.baseName + "\")");
|
||||
p.vendorExtensions.put("x-codegen-normalized-input-type", "Option["+ p.dataType + "]");
|
||||
}
|
||||
} else if(p.isQueryParam) {
|
||||
if(p.isContainer || p.isListContainer) {
|
||||
p.vendorExtensions.put("x-codegen-normalized-path-type", "params(\"" + p.baseName + "\")");
|
||||
p.vendorExtensions.put("x-codegen-normalized-input-type", p.dataType.replaceAll("^[^\\[]+", "Seq"));
|
||||
} else {
|
||||
p.vendorExtensions.put("x-codegen-normalized-path-type", "param(\"" + p.baseName + "\")");
|
||||
p.vendorExtensions.put("x-codegen-normalized-input-type", p.dataType);
|
||||
}
|
||||
} else if(p.isBodyParam) {
|
||||
p.vendorExtensions.put("x-codegen-normalized-path-type", "jsonBody["+ p.dataType + "]");
|
||||
p.vendorExtensions.put("x-codegen-normalized-input-type", p.dataType);
|
||||
} else if(p.isFile) {
|
||||
p.vendorExtensions.put("x-codegen-normalized-path-type", "fileUpload(\""+ p.baseName + "\")");
|
||||
p.vendorExtensions.put("x-codegen-normalized-input-type", "FileUpload");
|
||||
} else {
|
||||
p.vendorExtensions.put("x-codegen-normalized-path-type", p.dataType);
|
||||
p.vendorExtensions.put("x-codegen-normalized-input-type", p.dataType);
|
||||
}
|
||||
}
|
||||
|
||||
op.vendorExtensions.put("x-codegen-path", scalaPath);
|
||||
}
|
||||
return objs;
|
||||
}
|
||||
|
||||
@ -330,4 +280,172 @@ public class FinchServerCodegen extends DefaultCodegen implements CodegenConfig
|
||||
this.packageName = packageName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param prim
|
||||
* @param isRequired
|
||||
* @param canBeOptional
|
||||
* @return
|
||||
*/
|
||||
private String toPrimitive(String prim, Boolean isRequired, Boolean canBeOptional) {
|
||||
|
||||
String converter = ".map(_.to" + prim + ")";
|
||||
return (canBeOptional ? (isRequired ? converter : ".map(_" + converter +")") : "");
|
||||
}
|
||||
|
||||
//All path parameters are String initially, for primitives these need to be converted
|
||||
private String toPathParameter(CodegenParameter p, String paramType, Boolean canBeOptional ) {
|
||||
|
||||
Boolean isNotAString = !p.dataType.equals("String");
|
||||
|
||||
return paramType + (canBeOptional && !p.required ? "Option" : "") + "(\""+ p.baseName + "\")" + (isNotAString ? toPrimitive(p.dataType,p.required,canBeOptional) : "") ;
|
||||
}
|
||||
|
||||
private String toInputParameter(CodegenParameter p){
|
||||
return (p.required ? "" : "Option[")+p.dataType+(p.required ? "" : "]");
|
||||
}
|
||||
|
||||
private String concat(String original, String addition, String op) {
|
||||
return original + (original.isEmpty() ? "" : (addition.isEmpty() ? "" : op)) + addition;
|
||||
}
|
||||
|
||||
// a, b
|
||||
private String csvConcat(String original, String addition) {
|
||||
return concat(original, addition,", ");
|
||||
}
|
||||
// a :: b
|
||||
private String colConcat(String original, String addition) {
|
||||
return concat(original, addition," :: ");
|
||||
}
|
||||
|
||||
private void authParameters(CodegenOperation op) {
|
||||
|
||||
String authParams = "";
|
||||
String authInputParams = "";
|
||||
String typedAuthInputParams = "";
|
||||
//Append apikey security to path params and create input parameters for functions
|
||||
if(op.authMethods != null){
|
||||
|
||||
for(CodegenSecurity s : op.authMethods) {
|
||||
if(s.isApiKey && s.isKeyInHeader){
|
||||
authParams = colConcat(authParams, "header(\""+ s.keyParamName + "\")");
|
||||
} else if(s.isApiKey && s.isKeyInQuery){
|
||||
authParams = colConcat(authParams, "param(\""+ s.keyParamName + "\")");
|
||||
}
|
||||
if(s.isApiKey) {
|
||||
typedAuthInputParams = csvConcat(typedAuthInputParams, "authParam"+ s.name + ": String");
|
||||
authInputParams = csvConcat(authInputParams,"authParam"+ s.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
op.vendorExtensions.put("x-codegen-authParams", authParams);
|
||||
op.vendorExtensions.put("x-codegen-authInputParams", authInputParams);
|
||||
op.vendorExtensions.put("x-codegen-typedAuthInputParams", typedAuthInputParams);
|
||||
|
||||
}
|
||||
|
||||
private void generateScalaPath(CodegenOperation op) {
|
||||
op.httpMethod = op.httpMethod.toLowerCase();
|
||||
|
||||
String path = new String(op.path);
|
||||
|
||||
// remove first /
|
||||
if (path.startsWith("/")) {
|
||||
path = path.substring(1);
|
||||
}
|
||||
|
||||
// remove last /
|
||||
if (path.endsWith("/")) {
|
||||
path = path.substring(0, path.length()-1);
|
||||
}
|
||||
|
||||
String[] items = path.split("/", -1);
|
||||
String scalaPath = "";
|
||||
Integer pathParamIndex = 0;
|
||||
|
||||
for (int i = 0; i < items.length; ++i) {
|
||||
|
||||
if (items[i].matches("^\\{(.*)\\}$")) { // wrap in {}
|
||||
// find the datatype of the parameter
|
||||
final CodegenParameter cp = op.pathParams.get(pathParamIndex);
|
||||
|
||||
// TODO: Handle non-primitives…
|
||||
scalaPath = colConcat(scalaPath, cp.dataType.toLowerCase());
|
||||
|
||||
pathParamIndex++;
|
||||
} else {
|
||||
scalaPath = colConcat(scalaPath, "\"" + items[i] + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
op.vendorExtensions.put("x-codegen-path", scalaPath);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void concatParameters(CodegenOperation op) {
|
||||
|
||||
String path = colConcat(colConcat(op.vendorExtensions.get("x-codegen-path").toString(),op.vendorExtensions.get("x-codegen-pathParams").toString()), op.vendorExtensions.get("x-codegen-authParams").toString());
|
||||
String parameters = csvConcat(op.vendorExtensions.get("x-codegen-inputParams").toString(), op.vendorExtensions.get("x-codegen-authInputParams").toString());
|
||||
String typedParameters = csvConcat(op.vendorExtensions.get("x-codegen-typedInputParams").toString(), op.vendorExtensions.get("x-codegen-typedAuthInputParams").toString());
|
||||
|
||||
// The input parameters for functions
|
||||
op.vendorExtensions.put("x-codegen-paths",path);
|
||||
op.vendorExtensions.put("x-codegen-params", parameters);
|
||||
op.vendorExtensions.put("x-codegen-typedParams", typedParameters);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void generateInputParameters(CodegenOperation op) {
|
||||
|
||||
String inputParams = "";
|
||||
String typedInputParams = "";
|
||||
String pathParams = "";
|
||||
|
||||
for (CodegenParameter p : op.allParams) {
|
||||
// TODO: This hacky, should be converted to mappings if possible to keep it clean.
|
||||
// This could also be done using template imports
|
||||
|
||||
if(p.isBodyParam) {
|
||||
p.vendorExtensions.put("x-codegen-normalized-path-type", "jsonBody["+ p.dataType + "]");
|
||||
p.vendorExtensions.put("x-codegen-normalized-input-type", p.dataType);
|
||||
} else if(p.isContainer || p.isListContainer) {
|
||||
p.vendorExtensions.put("x-codegen-normalized-path-type", toPathParameter(p,"params", false));
|
||||
p.vendorExtensions.put("x-codegen-normalized-input-type", p.dataType.replaceAll("^[^\\[]+", "Seq"));
|
||||
} else if(p.isQueryParam) {
|
||||
p.vendorExtensions.put("x-codegen-normalized-path-type", toPathParameter(p, "param",true));
|
||||
p.vendorExtensions.put("x-codegen-normalized-input-type", toInputParameter(p));
|
||||
} else if(p.isHeaderParam) {
|
||||
p.vendorExtensions.put("x-codegen-normalized-path-type", toPathParameter(p,"header", true));
|
||||
p.vendorExtensions.put("x-codegen-normalized-input-type", toInputParameter(p));
|
||||
} else if(p.isFile) {
|
||||
p.vendorExtensions.put("x-codegen-normalized-path-type", "fileUpload(\""+ p.paramName + "\")");
|
||||
p.vendorExtensions.put("x-codegen-normalized-input-type", "FileUpload");
|
||||
} else if(p.isPrimitiveType && !p.isPathParam) {
|
||||
p.vendorExtensions.put("x-codegen-normalized-path-type", p.dataType.toLowerCase());
|
||||
p.vendorExtensions.put("x-codegen-normalized-input-type", toInputParameter(p));
|
||||
} else {
|
||||
//Path paremeters are handled in generateScalaPath()
|
||||
p.vendorExtensions.put("x-codegen-normalized-input-type", p.dataType);
|
||||
}
|
||||
if(p.vendorExtensions.get("x-codegen-normalized-path-type") != null){
|
||||
pathParams = colConcat(pathParams , p.vendorExtensions.get("x-codegen-normalized-path-type").toString());
|
||||
}
|
||||
inputParams = csvConcat(inputParams, p.paramName);
|
||||
typedInputParams = csvConcat(typedInputParams , p.paramName + ": " + p.vendorExtensions.get("x-codegen-normalized-input-type"));
|
||||
|
||||
}
|
||||
|
||||
// All body, path, query and header parameters
|
||||
op.vendorExtensions.put("x-codegen-pathParams", pathParams);
|
||||
|
||||
// The input parameters for functions
|
||||
op.vendorExtensions.put("x-codegen-inputParams", inputParams);
|
||||
op.vendorExtensions.put("x-codegen-typedInputParams", typedInputParams);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,9 @@ package {{packageName}}
|
||||
|
||||
// TODO: properly handle custom imports
|
||||
import java.io._
|
||||
import java.util.Date
|
||||
import java.util.UUID
|
||||
import java.time._
|
||||
|
||||
|
||||
import {{modelPackage}}._
|
||||
|
||||
@ -18,7 +20,7 @@ trait DataAccessor {
|
||||
* {{{description}}}
|
||||
* @return A {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Unit{{/returnType}}
|
||||
*/
|
||||
def {{baseName}}_{{operationId}}({{#allParams}}{{paramName}}: {{{dataType}}}{{^-last}}, {{/-last}}{{/allParams}}): {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Unit{{/returnType}} = ???
|
||||
def {{baseName}}_{{operationId}}({{{vendorExtensions.x-codegen-typedParams}}}): Either[CommonError,{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Unit{{/returnType}}] = ???
|
||||
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
|
@ -5,6 +5,11 @@ This server was generated by the [swagger-codegen](https://github.com/swagger-ap
|
||||
[OpenAPI-Spec](https://github.com/swagger-api/swagger-core/wiki) from a remote server, you can easily generate a server stub. This
|
||||
is an example of building a swagger-enabled scalatra server.
|
||||
|
||||
This example uses the [scalatra](http://scalatra.org/) framework. To see how to make this your own, look here:
|
||||
This example uses the [finch](http://github.com/finagle/finch/) framework. To see how to make this your own, look here:
|
||||
|
||||
[README](https://github.com/swagger-api/swagger-codegen/tree/master/samples/server-generator/scalatra)
|
||||
[README](https://github.com/swagger-api/swagger-codegen/tree/master/samples/server-generator/finch)
|
||||
|
||||
|
||||
### After generation
|
||||
|
||||
Run `scalafix RemoveUnusedImports` to cleanup unused imports.
|
@ -17,10 +17,8 @@ import com.twitter.util.{Await, Future}
|
||||
class Server {
|
||||
|
||||
// Loads implementation defined in resources/META-INF/services/{{packageName}}.DataAccessor
|
||||
val db = LoadService[DataAccessor]() match {
|
||||
case accessor :: _ => accessor
|
||||
case _ => new DataAccessor { }
|
||||
}
|
||||
val impls: Seq[DataAccessor] = LoadService[DataAccessor]()
|
||||
val db = if (impls.isEmpty) new DataAccessor { } else impls.head
|
||||
|
||||
val service = endpoint.makeService(db)
|
||||
|
||||
@ -32,7 +30,7 @@ class Server {
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches the PetstoreAPI service when the system is ready.
|
||||
* Launches the API service when the system is ready.
|
||||
*/
|
||||
object Server extends Server with App {
|
||||
Await.ready(server)
|
||||
|
@ -1,7 +1,6 @@
|
||||
package {{apiPackage}}
|
||||
|
||||
import java.io._
|
||||
import java.util.Date
|
||||
import {{packageName}}._
|
||||
import {{modelPackage}}._
|
||||
{{#imports}}import {{import}}
|
||||
@ -17,6 +16,7 @@ import com.twitter.util.Future
|
||||
import com.twitter.io.Buf
|
||||
import io.finch._, items._
|
||||
import java.io.File
|
||||
import java.time._
|
||||
|
||||
object {{classname}} {
|
||||
/**
|
||||
@ -30,21 +30,39 @@ object {{classname}} {
|
||||
{{/operation}}
|
||||
{{/operations}}
|
||||
|
||||
|
||||
private def checkError(e: CommonError) = e match {
|
||||
case InvalidInput(_) => BadRequest(e)
|
||||
case MissingIdentifier(_) => BadRequest(e)
|
||||
case RecordNotFound(_) => NotFound(e)
|
||||
case _ => InternalServerError(e)
|
||||
}
|
||||
|
||||
implicit class StringOps(s: String) {
|
||||
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
lazy val localformatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
|
||||
lazy val datetimeformatter: DateTimeFormatter =
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
|
||||
|
||||
def toLocalDateTime: LocalDateTime = LocalDateTime.parse(s,localformatter)
|
||||
def toZonedDateTime: ZonedDateTime = ZonedDateTime.parse(s, datetimeformatter)
|
||||
|
||||
}
|
||||
|
||||
{{#operations}}
|
||||
{{#operation}}
|
||||
/**
|
||||
* {{{description}}}
|
||||
* @return And endpoint representing a {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Unit{{/returnType}}
|
||||
* @return An endpoint representing a {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Unit{{/returnType}}
|
||||
*/
|
||||
private def {{operationId}}(da: DataAccessor): Endpoint[{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Unit{{/returnType}}] =
|
||||
{{httpMethod}}({{{vendorExtensions.x-codegen-path}}} {{#allParams}}{{^isPathParam}} :: {{& vendorExtensions.x-codegen-normalized-path-type}}{{/isPathParam}}{{/allParams}}) { {{#hasParams}}({{#allParams}}{{paramName}}: {{{vendorExtensions.x-codegen-normalized-input-type}}}{{^-last}}, {{/-last}}{{/allParams}}) => {{/hasParams}}
|
||||
{{#returnType}}
|
||||
Ok(da.{{baseName}}_{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}}))
|
||||
{{/returnType}}
|
||||
{{^returnType}}
|
||||
da.{{baseName}}_{{operationId}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}})
|
||||
NoContent[Unit]
|
||||
{{/returnType}}
|
||||
{{httpMethod}}({{{vendorExtensions.x-codegen-paths}}}) { {{#hasParams}}({{{vendorExtensions.x-codegen-typedParams}}}) => {{/hasParams}}
|
||||
da.{{baseName}}_{{operationId}}({{{vendorExtensions.x-codegen-params}}}) match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ name := "finch-sample"
|
||||
|
||||
version := "0.1.0-SNAPSHOT"
|
||||
|
||||
scalaVersion := "2.11.8"
|
||||
scalaVersion := "2.11.11"
|
||||
|
||||
resolvers += Resolver.sonatypeRepo("snapshots")
|
||||
|
||||
@ -20,6 +20,11 @@ resolvers += "Sonatype OSS Releases" at "http://oss.sonatype.org/content/reposit
|
||||
|
||||
Defaults.itSettings
|
||||
|
||||
lazy val circeVersion = "0.8.0"
|
||||
lazy val finagleVersion = "6.45.0"
|
||||
lazy val finchVersion = "0.15.1"
|
||||
lazy val scalaTestVersion = "3.0.0"
|
||||
|
||||
scalacOptions ++= Seq(
|
||||
"-deprecation",
|
||||
"-encoding", "UTF-8",
|
||||
@ -33,21 +38,21 @@ scalacOptions ++= Seq(
|
||||
"-Ywarn-numeric-widen",
|
||||
"-Xfuture",
|
||||
"-Xlint",
|
||||
// "-Ywarn-unused-import",
|
||||
"-Ywarn-unused-import",
|
||||
"-language:postfixOps"
|
||||
)
|
||||
|
||||
lazy val `it-config-sbt-project` = project.in(file(".")).configs(IntegrationTest)
|
||||
|
||||
libraryDependencies ++= Seq(
|
||||
"com.github.finagle" %% "finch-core" % "0.12.0",
|
||||
"com.github.finagle" %% "finch-circe" % "0.12.0",
|
||||
"io.circe" %% "circe-generic" % "0.7.0",
|
||||
"io.circe" %% "circe-java8" % "0.7.0",
|
||||
"com.twitter" %% "util-core" % "6.40.0",
|
||||
"com.github.finagle" %% "finch-test" % "0.12.0" % "test",
|
||||
"com.github.finagle" %% "finch-core" % finchVersion,
|
||||
"com.github.finagle" %% "finch-circe" % finchVersion,
|
||||
"io.circe" %% "circe-generic" % circeVersion,
|
||||
"io.circe" %% "circe-java8" % circeVersion,
|
||||
"com.twitter" %% "util-core" % finagleVersion,
|
||||
"com.github.finagle" %% "finch-test" % finchVersion % "test",
|
||||
"org.scalacheck" %% "scalacheck" % "1.13.4" % "test",
|
||||
"org.scalatest" %% "scalatest" % "3.0.0" % "test"
|
||||
"org.scalatest" %% "scalatest" % scalaTestVersion % "test"
|
||||
)
|
||||
|
||||
assemblyMergeStrategy in assembly := {
|
||||
|
@ -23,7 +23,7 @@ object endpoint {
|
||||
Json.obj("error" -> Json.fromString("something_not_parsed"))
|
||||
case Error.NotValid(_, _) =>
|
||||
Json.obj("error" -> Json.fromString("something_not_valid"))
|
||||
case error: PetstoreError =>
|
||||
case error: CommonError =>
|
||||
Json.obj("error" -> Json.fromString(error.message))
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ object endpoint {
|
||||
{{/apis}}
|
||||
{{/apiInfo}}
|
||||
).handle({
|
||||
case e: PetstoreError => NotFound(e)
|
||||
case e: CommonError => NotFound(e)
|
||||
}).toService
|
||||
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
package {{packageName}}
|
||||
|
||||
/**
|
||||
* The parent error from which most PetstoreAPI errors extend. Thrown whenever something in the api goes wrong.
|
||||
* The parent error from which most API errors extend. Thrown whenever something in the api goes wrong.
|
||||
*/
|
||||
abstract class PetstoreError(msg: String) extends Exception(msg) {
|
||||
abstract class CommonError(msg: String) extends Exception(msg) {
|
||||
def message: String
|
||||
}
|
||||
|
||||
@ -11,17 +11,17 @@ abstract class PetstoreError(msg: String) extends Exception(msg) {
|
||||
* Thrown when the object given is invalid
|
||||
* @param message An error message
|
||||
*/
|
||||
case class InvalidInput(message: String) extends PetstoreError(message)
|
||||
case class InvalidInput(message: String) extends CommonError(message)
|
||||
|
||||
/**
|
||||
* Thrown when the given object is missing a unique ID.
|
||||
* @param message An error message
|
||||
*/
|
||||
case class MissingIdentifier(message: String) extends PetstoreError(message)
|
||||
case class MissingIdentifier(message: String) extends CommonError(message)
|
||||
|
||||
/**
|
||||
* Thrown when the given record does not exist in the database.
|
||||
* @param message An error message
|
||||
*/
|
||||
case class RecordNotFound(message: String) extends PetstoreError(message)
|
||||
case class RecordNotFound(message: String) extends CommonError(message)
|
||||
|
||||
|
@ -2,6 +2,6 @@ resolvers += Resolver.typesafeRepo("releases")
|
||||
|
||||
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.3")
|
||||
|
||||
// addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.1.4")
|
||||
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.5.3")
|
||||
|
||||
addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.6.0")
|
||||
|
@ -5,6 +5,11 @@ This server was generated by the [swagger-codegen](https://github.com/swagger-ap
|
||||
[OpenAPI-Spec](https://github.com/swagger-api/swagger-core/wiki) from a remote server, you can easily generate a server stub. This
|
||||
is an example of building a swagger-enabled scalatra server.
|
||||
|
||||
This example uses the [scalatra](http://scalatra.org/) framework. To see how to make this your own, look here:
|
||||
This example uses the [finch](http://github.com/finagle/finch/) framework. To see how to make this your own, look here:
|
||||
|
||||
[README](https://github.com/swagger-api/swagger-codegen/tree/master/samples/server-generator/scalatra)
|
||||
[README](https://github.com/swagger-api/swagger-codegen/tree/master/samples/server-generator/finch)
|
||||
|
||||
|
||||
### After generation
|
||||
|
||||
Run `scalafix RemoveUnusedImports` to cleanup unused imports.
|
@ -6,7 +6,7 @@ name := "finch-sample"
|
||||
|
||||
version := "0.1.0-SNAPSHOT"
|
||||
|
||||
scalaVersion := "2.11.8"
|
||||
scalaVersion := "2.11.11"
|
||||
|
||||
resolvers += Resolver.sonatypeRepo("snapshots")
|
||||
|
||||
@ -20,6 +20,11 @@ resolvers += "Sonatype OSS Releases" at "http://oss.sonatype.org/content/reposit
|
||||
|
||||
Defaults.itSettings
|
||||
|
||||
lazy val circeVersion = "0.8.0"
|
||||
lazy val finagleVersion = "6.45.0"
|
||||
lazy val finchVersion = "0.15.1"
|
||||
lazy val scalaTestVersion = "3.0.0"
|
||||
|
||||
scalacOptions ++= Seq(
|
||||
"-deprecation",
|
||||
"-encoding", "UTF-8",
|
||||
@ -33,21 +38,21 @@ scalacOptions ++= Seq(
|
||||
"-Ywarn-numeric-widen",
|
||||
"-Xfuture",
|
||||
"-Xlint",
|
||||
// "-Ywarn-unused-import",
|
||||
"-Ywarn-unused-import",
|
||||
"-language:postfixOps"
|
||||
)
|
||||
|
||||
lazy val `it-config-sbt-project` = project.in(file(".")).configs(IntegrationTest)
|
||||
|
||||
libraryDependencies ++= Seq(
|
||||
"com.github.finagle" %% "finch-core" % "0.12.0",
|
||||
"com.github.finagle" %% "finch-circe" % "0.12.0",
|
||||
"io.circe" %% "circe-generic" % "0.7.0",
|
||||
"io.circe" %% "circe-java8" % "0.7.0",
|
||||
"com.twitter" %% "util-core" % "6.40.0",
|
||||
"com.github.finagle" %% "finch-test" % "0.12.0" % "test",
|
||||
"com.github.finagle" %% "finch-core" % finchVersion,
|
||||
"com.github.finagle" %% "finch-circe" % finchVersion,
|
||||
"io.circe" %% "circe-generic" % circeVersion,
|
||||
"io.circe" %% "circe-java8" % circeVersion,
|
||||
"com.twitter" %% "util-core" % finagleVersion,
|
||||
"com.github.finagle" %% "finch-test" % finchVersion % "test",
|
||||
"org.scalacheck" %% "scalacheck" % "1.13.4" % "test",
|
||||
"org.scalatest" %% "scalatest" % "3.0.0" % "test"
|
||||
"org.scalatest" %% "scalatest" % scalaTestVersion % "test"
|
||||
)
|
||||
|
||||
assemblyMergeStrategy in assembly := {
|
||||
|
@ -2,6 +2,6 @@ resolvers += Resolver.typesafeRepo("releases")
|
||||
|
||||
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.3")
|
||||
|
||||
// addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.1.4")
|
||||
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.5.3")
|
||||
|
||||
addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.6.0")
|
||||
|
@ -2,7 +2,9 @@ package io.swagger
|
||||
|
||||
// TODO: properly handle custom imports
|
||||
import java.io._
|
||||
import java.util.Date
|
||||
import java.util.UUID
|
||||
import java.time._
|
||||
|
||||
|
||||
import io.swagger.models._
|
||||
|
||||
@ -14,120 +16,120 @@ trait DataAccessor {
|
||||
*
|
||||
* @return A Unit
|
||||
*/
|
||||
def Pet_addPet(body: Pet): Unit = ???
|
||||
def Pet_addPet(body: Pet): Either[CommonError,Unit] = ???
|
||||
|
||||
/**
|
||||
*
|
||||
* @return A Unit
|
||||
*/
|
||||
def Pet_deletePet(petId: Long, apiKey: String): Unit = ???
|
||||
def Pet_deletePet(petId: Long, apiKey: Option[String]): Either[CommonError,Unit] = ???
|
||||
|
||||
/**
|
||||
*
|
||||
* @return A Seq[Pet]
|
||||
*/
|
||||
def Pet_findPetsByStatus(status: Seq[String]): Seq[Pet] = ???
|
||||
def Pet_findPetsByStatus(status: Seq[String]): Either[CommonError,Seq[Pet]] = ???
|
||||
|
||||
/**
|
||||
*
|
||||
* @return A Seq[Pet]
|
||||
*/
|
||||
def Pet_findPetsByTags(tags: Seq[String]): Seq[Pet] = ???
|
||||
def Pet_findPetsByTags(tags: Seq[String]): Either[CommonError,Seq[Pet]] = ???
|
||||
|
||||
/**
|
||||
*
|
||||
* @return A Pet
|
||||
*/
|
||||
def Pet_getPetById(petId: Long): Pet = ???
|
||||
def Pet_getPetById(petId: Long, authParamapi_key: String): Either[CommonError,Pet] = ???
|
||||
|
||||
/**
|
||||
*
|
||||
* @return A Unit
|
||||
*/
|
||||
def Pet_updatePet(body: Pet): Unit = ???
|
||||
def Pet_updatePet(body: Pet): Either[CommonError,Unit] = ???
|
||||
|
||||
/**
|
||||
*
|
||||
* @return A Unit
|
||||
*/
|
||||
def Pet_updatePetWithForm(petId: Long, name: String, status: String): Unit = ???
|
||||
def Pet_updatePetWithForm(petId: Long, name: Option[String], status: Option[String]): Either[CommonError,Unit] = ???
|
||||
|
||||
/**
|
||||
*
|
||||
* @return A ApiResponse
|
||||
*/
|
||||
def Pet_uploadFile(petId: Long, additionalMetadata: String, file: File): ApiResponse = ???
|
||||
def Pet_uploadFile(petId: Long, additionalMetadata: Option[String], file: FileUpload): Either[CommonError,ApiResponse] = ???
|
||||
|
||||
/**
|
||||
*
|
||||
* @return A Unit
|
||||
*/
|
||||
def Store_deleteOrder(orderId: String): Unit = ???
|
||||
def Store_deleteOrder(orderId: String): Either[CommonError,Unit] = ???
|
||||
|
||||
/**
|
||||
*
|
||||
* @return A Map[String, Int]
|
||||
*/
|
||||
def Store_getInventory(): Map[String, Int] = ???
|
||||
def Store_getInventory(authParamapi_key: String): Either[CommonError,Map[String, Int]] = ???
|
||||
|
||||
/**
|
||||
*
|
||||
* @return A Order
|
||||
*/
|
||||
def Store_getOrderById(orderId: Long): Order = ???
|
||||
def Store_getOrderById(orderId: Long): Either[CommonError,Order] = ???
|
||||
|
||||
/**
|
||||
*
|
||||
* @return A Order
|
||||
*/
|
||||
def Store_placeOrder(body: Order): Order = ???
|
||||
def Store_placeOrder(body: Order): Either[CommonError,Order] = ???
|
||||
|
||||
/**
|
||||
*
|
||||
* @return A Unit
|
||||
*/
|
||||
def User_createUser(body: User): Unit = ???
|
||||
def User_createUser(body: User): Either[CommonError,Unit] = ???
|
||||
|
||||
/**
|
||||
*
|
||||
* @return A Unit
|
||||
*/
|
||||
def User_createUsersWithArrayInput(body: Seq[User]): Unit = ???
|
||||
def User_createUsersWithArrayInput(body: Seq[User]): Either[CommonError,Unit] = ???
|
||||
|
||||
/**
|
||||
*
|
||||
* @return A Unit
|
||||
*/
|
||||
def User_createUsersWithListInput(body: Seq[User]): Unit = ???
|
||||
def User_createUsersWithListInput(body: Seq[User]): Either[CommonError,Unit] = ???
|
||||
|
||||
/**
|
||||
*
|
||||
* @return A Unit
|
||||
*/
|
||||
def User_deleteUser(username: String): Unit = ???
|
||||
def User_deleteUser(username: String): Either[CommonError,Unit] = ???
|
||||
|
||||
/**
|
||||
*
|
||||
* @return A User
|
||||
*/
|
||||
def User_getUserByName(username: String): User = ???
|
||||
def User_getUserByName(username: String): Either[CommonError,User] = ???
|
||||
|
||||
/**
|
||||
*
|
||||
* @return A String
|
||||
*/
|
||||
def User_loginUser(username: String, password: String): String = ???
|
||||
def User_loginUser(username: String, password: String): Either[CommonError,String] = ???
|
||||
|
||||
/**
|
||||
*
|
||||
* @return A Unit
|
||||
*/
|
||||
def User_logoutUser(): Unit = ???
|
||||
def User_logoutUser(): Either[CommonError,Unit] = ???
|
||||
|
||||
/**
|
||||
*
|
||||
* @return A Unit
|
||||
*/
|
||||
def User_updateUser(username: String, body: User): Unit = ???
|
||||
def User_updateUser(username: String, body: User): Either[CommonError,Unit] = ???
|
||||
|
||||
}
|
@ -15,10 +15,8 @@ import com.twitter.util.{Await, Future}
|
||||
class Server {
|
||||
|
||||
// Loads implementation defined in resources/META-INF/services/io.swagger.DataAccessor
|
||||
val db = LoadService[DataAccessor]() match {
|
||||
case accessor :: _ => accessor
|
||||
case _ => new DataAccessor { }
|
||||
}
|
||||
val impls: Seq[DataAccessor] = LoadService[DataAccessor]()
|
||||
val db = if (impls.isEmpty) new DataAccessor { } else impls.head
|
||||
|
||||
val service = endpoint.makeService(db)
|
||||
|
||||
@ -30,7 +28,7 @@ class Server {
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches the PetstoreAPI service when the system is ready.
|
||||
* Launches the API service when the system is ready.
|
||||
*/
|
||||
object Server extends Server with App {
|
||||
Await.ready(server)
|
||||
|
@ -23,7 +23,7 @@ object endpoint {
|
||||
Json.obj("error" -> Json.fromString("something_not_parsed"))
|
||||
case Error.NotValid(_, _) =>
|
||||
Json.obj("error" -> Json.fromString("something_not_valid"))
|
||||
case error: PetstoreError =>
|
||||
case error: CommonError =>
|
||||
Json.obj("error" -> Json.fromString(error.message))
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ object endpoint {
|
||||
StoreApi.endpoints(da) :+:
|
||||
UserApi.endpoints(da)
|
||||
).handle({
|
||||
case e: PetstoreError => NotFound(e)
|
||||
case e: CommonError => NotFound(e)
|
||||
}).toService
|
||||
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
package io.swagger
|
||||
|
||||
/**
|
||||
* The parent error from which most PetstoreAPI errors extend. Thrown whenever something in the api goes wrong.
|
||||
* The parent error from which most API errors extend. Thrown whenever something in the api goes wrong.
|
||||
*/
|
||||
abstract class PetstoreError(msg: String) extends Exception(msg) {
|
||||
abstract class CommonError(msg: String) extends Exception(msg) {
|
||||
def message: String
|
||||
}
|
||||
|
||||
@ -11,17 +11,17 @@ abstract class PetstoreError(msg: String) extends Exception(msg) {
|
||||
* Thrown when the object given is invalid
|
||||
* @param message An error message
|
||||
*/
|
||||
case class InvalidInput(message: String) extends PetstoreError(message)
|
||||
case class InvalidInput(message: String) extends CommonError(message)
|
||||
|
||||
/**
|
||||
* Thrown when the given object is missing a unique ID.
|
||||
* @param message An error message
|
||||
*/
|
||||
case class MissingIdentifier(message: String) extends PetstoreError(message)
|
||||
case class MissingIdentifier(message: String) extends CommonError(message)
|
||||
|
||||
/**
|
||||
* Thrown when the given record does not exist in the database.
|
||||
* @param message An error message
|
||||
*/
|
||||
case class RecordNotFound(message: String) extends PetstoreError(message)
|
||||
case class RecordNotFound(message: String) extends CommonError(message)
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package io.swagger.apis
|
||||
|
||||
import java.io._
|
||||
import java.util.Date
|
||||
import io.swagger._
|
||||
import io.swagger.models._
|
||||
import io.swagger.models.ApiResponse
|
||||
@ -18,6 +17,7 @@ import com.twitter.util.Future
|
||||
import com.twitter.io.Buf
|
||||
import io.finch._, items._
|
||||
import java.io.File
|
||||
import java.time._
|
||||
|
||||
object PetApi {
|
||||
/**
|
||||
@ -34,94 +34,135 @@ object PetApi {
|
||||
updatePetWithForm(da) :+:
|
||||
uploadFile(da)
|
||||
|
||||
|
||||
private def checkError(e: CommonError) = e match {
|
||||
case InvalidInput(_) => BadRequest(e)
|
||||
case MissingIdentifier(_) => BadRequest(e)
|
||||
case RecordNotFound(_) => NotFound(e)
|
||||
case _ => InternalServerError(e)
|
||||
}
|
||||
|
||||
implicit class StringOps(s: String) {
|
||||
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
lazy val localformatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
|
||||
lazy val datetimeformatter: DateTimeFormatter =
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
|
||||
|
||||
def toLocalDateTime: LocalDateTime = LocalDateTime.parse(s,localformatter)
|
||||
def toZonedDateTime: ZonedDateTime = ZonedDateTime.parse(s, datetimeformatter)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return And endpoint representing a Unit
|
||||
* @return An endpoint representing a Unit
|
||||
*/
|
||||
private def addPet(da: DataAccessor): Endpoint[Unit] =
|
||||
post("pet" :: jsonBody[Pet]) { (body: Pet) =>
|
||||
da.Pet_addPet(body)
|
||||
NoContent[Unit]
|
||||
da.Pet_addPet(body) match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return And endpoint representing a Unit
|
||||
* @return An endpoint representing a Unit
|
||||
*/
|
||||
private def deletePet(da: DataAccessor): Endpoint[Unit] =
|
||||
delete("pet" :: long :: headerOption("api_key")) { (petId: Long, apiKey: Option[String]) =>
|
||||
da.Pet_deletePet(petId, apiKey)
|
||||
NoContent[Unit]
|
||||
da.Pet_deletePet(petId, apiKey) match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return And endpoint representing a Seq[Pet]
|
||||
* @return An endpoint representing a Seq[Pet]
|
||||
*/
|
||||
private def findPetsByStatus(da: DataAccessor): Endpoint[Seq[Pet]] =
|
||||
get("pet" :: "findByStatus" :: params("status")) { (status: Seq[String]) =>
|
||||
Ok(da.Pet_findPetsByStatus(status))
|
||||
da.Pet_findPetsByStatus(status) match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return And endpoint representing a Seq[Pet]
|
||||
* @return An endpoint representing a Seq[Pet]
|
||||
*/
|
||||
private def findPetsByTags(da: DataAccessor): Endpoint[Seq[Pet]] =
|
||||
get("pet" :: "findByTags" :: params("tags")) { (tags: Seq[String]) =>
|
||||
Ok(da.Pet_findPetsByTags(tags))
|
||||
da.Pet_findPetsByTags(tags) match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return And endpoint representing a Pet
|
||||
* @return An endpoint representing a Pet
|
||||
*/
|
||||
private def getPetById(da: DataAccessor): Endpoint[Pet] =
|
||||
get("pet" :: long ) { (petId: Long) =>
|
||||
Ok(da.Pet_getPetById(petId))
|
||||
get("pet" :: long :: header("api_key")) { (petId: Long, authParamapi_key: String) =>
|
||||
da.Pet_getPetById(petId, authParamapi_key) match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return And endpoint representing a Unit
|
||||
* @return An endpoint representing a Unit
|
||||
*/
|
||||
private def updatePet(da: DataAccessor): Endpoint[Unit] =
|
||||
put("pet" :: jsonBody[Pet]) { (body: Pet) =>
|
||||
da.Pet_updatePet(body)
|
||||
NoContent[Unit]
|
||||
da.Pet_updatePet(body) match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return And endpoint representing a Unit
|
||||
* @return An endpoint representing a Unit
|
||||
*/
|
||||
private def updatePetWithForm(da: DataAccessor): Endpoint[Unit] =
|
||||
post("pet" :: long :: String :: String) { (petId: Long, name: String, status: String) =>
|
||||
da.Pet_updatePetWithForm(petId, name, status)
|
||||
NoContent[Unit]
|
||||
post("pet" :: long :: string :: string) { (petId: Long, name: Option[String], status: Option[String]) =>
|
||||
da.Pet_updatePetWithForm(petId, name, status) match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return And endpoint representing a ApiResponse
|
||||
* @return An endpoint representing a ApiResponse
|
||||
*/
|
||||
private def uploadFile(da: DataAccessor): Endpoint[ApiResponse] =
|
||||
post("pet" :: long :: "uploadImage" :: String :: fileUpload("file")) { (petId: Long, additionalMetadata: String, file: FileUpload) =>
|
||||
Ok(da.Pet_uploadFile(petId, additionalMetadata, file))
|
||||
post("pet" :: long :: "uploadImage" :: string :: fileUpload("file")) { (petId: Long, additionalMetadata: Option[String], file: FileUpload) =>
|
||||
da.Pet_uploadFile(petId, additionalMetadata, file) match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package io.swagger.apis
|
||||
|
||||
import java.io._
|
||||
import java.util.Date
|
||||
import io.swagger._
|
||||
import io.swagger.models._
|
||||
import io.swagger.models.Order
|
||||
@ -16,6 +15,7 @@ import com.twitter.util.Future
|
||||
import com.twitter.io.Buf
|
||||
import io.finch._, items._
|
||||
import java.io.File
|
||||
import java.time._
|
||||
|
||||
object StoreApi {
|
||||
/**
|
||||
@ -28,47 +28,79 @@ object StoreApi {
|
||||
getOrderById(da) :+:
|
||||
placeOrder(da)
|
||||
|
||||
|
||||
private def checkError(e: CommonError) = e match {
|
||||
case InvalidInput(_) => BadRequest(e)
|
||||
case MissingIdentifier(_) => BadRequest(e)
|
||||
case RecordNotFound(_) => NotFound(e)
|
||||
case _ => InternalServerError(e)
|
||||
}
|
||||
|
||||
implicit class StringOps(s: String) {
|
||||
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
lazy val localformatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
|
||||
lazy val datetimeformatter: DateTimeFormatter =
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
|
||||
|
||||
def toLocalDateTime: LocalDateTime = LocalDateTime.parse(s,localformatter)
|
||||
def toZonedDateTime: ZonedDateTime = ZonedDateTime.parse(s, datetimeformatter)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return And endpoint representing a Unit
|
||||
* @return An endpoint representing a Unit
|
||||
*/
|
||||
private def deleteOrder(da: DataAccessor): Endpoint[Unit] =
|
||||
delete("store" :: "order" :: string) { (orderId: String) =>
|
||||
da.Store_deleteOrder(orderId)
|
||||
NoContent[Unit]
|
||||
da.Store_deleteOrder(orderId) match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return And endpoint representing a Map[String, Int]
|
||||
* @return An endpoint representing a Map[String, Int]
|
||||
*/
|
||||
private def getInventory(da: DataAccessor): Endpoint[Map[String, Int]] =
|
||||
get("store" :: "inventory" ) {
|
||||
Ok(da.Store_getInventory())
|
||||
get("store" :: "inventory" :: header("api_key")) {
|
||||
da.Store_getInventory(authParamapi_key) match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return And endpoint representing a Order
|
||||
* @return An endpoint representing a Order
|
||||
*/
|
||||
private def getOrderById(da: DataAccessor): Endpoint[Order] =
|
||||
get("store" :: "order" :: long) { (orderId: Long) =>
|
||||
Ok(da.Store_getOrderById(orderId))
|
||||
da.Store_getOrderById(orderId) match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return And endpoint representing a Order
|
||||
* @return An endpoint representing a Order
|
||||
*/
|
||||
private def placeOrder(da: DataAccessor): Endpoint[Order] =
|
||||
post("store" :: "order" :: jsonBody[Order]) { (body: Order) =>
|
||||
Ok(da.Store_placeOrder(body))
|
||||
da.Store_placeOrder(body) match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package io.swagger.apis
|
||||
|
||||
import java.io._
|
||||
import java.util.Date
|
||||
import io.swagger._
|
||||
import io.swagger.models._
|
||||
import scala.collection.immutable.Seq
|
||||
@ -17,6 +16,7 @@ import com.twitter.util.Future
|
||||
import com.twitter.io.Buf
|
||||
import io.finch._, items._
|
||||
import java.io.File
|
||||
import java.time._
|
||||
|
||||
object UserApi {
|
||||
/**
|
||||
@ -33,96 +33,135 @@ object UserApi {
|
||||
logoutUser(da) :+:
|
||||
updateUser(da)
|
||||
|
||||
|
||||
private def checkError(e: CommonError) = e match {
|
||||
case InvalidInput(_) => BadRequest(e)
|
||||
case MissingIdentifier(_) => BadRequest(e)
|
||||
case RecordNotFound(_) => NotFound(e)
|
||||
case _ => InternalServerError(e)
|
||||
}
|
||||
|
||||
implicit class StringOps(s: String) {
|
||||
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
lazy val localformatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
|
||||
lazy val datetimeformatter: DateTimeFormatter =
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
|
||||
|
||||
def toLocalDateTime: LocalDateTime = LocalDateTime.parse(s,localformatter)
|
||||
def toZonedDateTime: ZonedDateTime = ZonedDateTime.parse(s, datetimeformatter)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return And endpoint representing a Unit
|
||||
* @return An endpoint representing a Unit
|
||||
*/
|
||||
private def createUser(da: DataAccessor): Endpoint[Unit] =
|
||||
post("user" :: jsonBody[User]) { (body: User) =>
|
||||
da.User_createUser(body)
|
||||
NoContent[Unit]
|
||||
da.User_createUser(body) match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return And endpoint representing a Unit
|
||||
* @return An endpoint representing a Unit
|
||||
*/
|
||||
private def createUsersWithArrayInput(da: DataAccessor): Endpoint[Unit] =
|
||||
post("user" :: "createWithArray" :: jsonBody[Seq[User]]) { (body: Seq[User]) =>
|
||||
da.User_createUsersWithArrayInput(body)
|
||||
NoContent[Unit]
|
||||
da.User_createUsersWithArrayInput(body) match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return And endpoint representing a Unit
|
||||
* @return An endpoint representing a Unit
|
||||
*/
|
||||
private def createUsersWithListInput(da: DataAccessor): Endpoint[Unit] =
|
||||
post("user" :: "createWithList" :: jsonBody[Seq[User]]) { (body: Seq[User]) =>
|
||||
da.User_createUsersWithListInput(body)
|
||||
NoContent[Unit]
|
||||
da.User_createUsersWithListInput(body) match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return And endpoint representing a Unit
|
||||
* @return An endpoint representing a Unit
|
||||
*/
|
||||
private def deleteUser(da: DataAccessor): Endpoint[Unit] =
|
||||
delete("user" :: string) { (username: String) =>
|
||||
da.User_deleteUser(username)
|
||||
NoContent[Unit]
|
||||
da.User_deleteUser(username) match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return And endpoint representing a User
|
||||
* @return An endpoint representing a User
|
||||
*/
|
||||
private def getUserByName(da: DataAccessor): Endpoint[User] =
|
||||
get("user" :: string) { (username: String) =>
|
||||
Ok(da.User_getUserByName(username))
|
||||
da.User_getUserByName(username) match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return And endpoint representing a String
|
||||
* @return An endpoint representing a String
|
||||
*/
|
||||
private def loginUser(da: DataAccessor): Endpoint[String] =
|
||||
get("user" :: "login" :: param("username") :: param("password")) { (username: String, password: String) =>
|
||||
Ok(da.User_loginUser(username, password))
|
||||
da.User_loginUser(username, password) match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return And endpoint representing a Unit
|
||||
* @return An endpoint representing a Unit
|
||||
*/
|
||||
private def logoutUser(da: DataAccessor): Endpoint[Unit] =
|
||||
get("user" :: "logout") {
|
||||
da.User_logoutUser()
|
||||
NoContent[Unit]
|
||||
da.User_logoutUser() match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return And endpoint representing a Unit
|
||||
* @return An endpoint representing a Unit
|
||||
*/
|
||||
private def updateUser(da: DataAccessor): Endpoint[Unit] =
|
||||
put("user" :: string :: jsonBody[User]) { (username: String, body: User) =>
|
||||
da.User_updateUser(username, body)
|
||||
NoContent[Unit]
|
||||
da.User_updateUser(username, body) match {
|
||||
case Left(error) => checkError(error)
|
||||
case Right(data) => Ok(data)
|
||||
}
|
||||
} handle {
|
||||
case e: Exception => BadRequest(e)
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import io.finch.circe._
|
||||
import io.circe.generic.semiauto._
|
||||
import io.circe.java8.time._
|
||||
import io.swagger._
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZonedDateTime
|
||||
|
||||
/**
|
||||
* An order for a pets from the pet store
|
||||
@ -19,7 +19,7 @@ import java.time.LocalDateTime
|
||||
case class Order(id: Option[Long],
|
||||
petId: Option[Long],
|
||||
quantity: Option[Int],
|
||||
shipDate: Option[LocalDateTime],
|
||||
shipDate: Option[ZonedDateTime],
|
||||
status: Option[String],
|
||||
complete: Option[Boolean]
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user