diff --git a/bin/lagomScalaApi-petstore.sh b/bin/lagomScalaApi-petstore.sh new file mode 100644 index 0000000000..0094856885 --- /dev/null +++ b/bin/lagomScalaApi-petstore.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +SCRIPT="$0" + +while [ -h "$SCRIPT" ] ; do + ls=`ls -ld "$SCRIPT"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + SCRIPT="$link" + else + SCRIPT=`dirname "$SCRIPT"`/"$link" + fi +done + +if [ ! -d "${APP_DIR}" ]; then + APP_DIR=`dirname "$SCRIPT"`/.. + APP_DIR=`cd "${APP_DIR}"; pwd` +fi + +executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar" + +if [ ! -f "$executable" ] +then + mvn clean package +fi + +# if you've executed sbt assembly previously it will use that instead. +export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" +ags="$@ generate -t modules/swagger-codegen/src/main/resources/lagomScalaApi -i modules/swagger-codegen/src/test/resources/2_0/petstore.yaml -l scala-lagomApi -o samples/server/petstore/lagomScalaApi" + +java $JAVA_OPTS -jar $executable $ags diff --git a/bin/windows/lagomScalaApi-petstore.bat b/bin/windows/lagomScalaApi-petstore.bat new file mode 100644 index 0000000000..7bf73c9746 --- /dev/null +++ b/bin/windows/lagomScalaApi-petstore.bat @@ -0,0 +1,10 @@ +set executable=.\modules\swagger-codegen-cli\target\swagger-codegen-cli.jar + +If Not Exist %executable% ( + mvn clean package +) + +REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M +set ags=generate -i modules\swagger-codegen\src\test\resources\2_0\petstore.yaml -l scala-lagomApi -o samples\server\petstore\scala-lagomApi + +java %JAVA_OPTS% -jar %executable% %ags% diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ScalaLagomServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ScalaLagomServerCodegen.java new file mode 100644 index 0000000000..c0feb92415 --- /dev/null +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ScalaLagomServerCodegen.java @@ -0,0 +1,280 @@ +package io.swagger.codegen.languages; + +import io.swagger.codegen.*; +import org.apache.commons.lang3.StringUtils; + +import java.util.*; + +public class ScalaLagomServerCodegen extends AbstractScalaCodegen implements CodegenConfig { + + private String authScheme = ""; + private boolean authPreemptive=false; + protected String groupId = "io.swagger"; + protected String artifactId = "scala-lagomApi"; + protected String artifactVersion = "1.0.0"; + + public ScalaLagomServerCodegen() { + super(); + outputFolder = "generated-code/scala-lagomApi"; + modelTemplateFiles.put("model.mustache", ".scala"); + apiTemplateFiles.put("api.mustache", ".scala"); + embeddedTemplateDir = templateDir = "lagomScalaApi"; + apiPackage = "io.swagger.client.api"; + modelPackage = "io.swagger.client.model"; + + setReservedWordsLowerCase( + Arrays.asList( + // local variable names used in API methods (endpoints) + "path", "contentTypes", "contentType", "queryParams", "headerParams", + "formParams", "postBody", "mp", "basePath", "apiInvoker", + + // scala reserved words + "abstract", "case", "catch", "class", "def", "do", "else", "extends", + "false", "final", "finally", "for", "forSome", "if", "implicit", + "import", "lazy", "match", "new", "null", "object", "override", "package", + "private", "protected", "return", "sealed", "super", "this", "throw", + "trait", "try", "true", "type", "val", "var", "while", "with", "yield") + ); + + additionalProperties.put(CodegenConstants.GROUP_ID, groupId); + additionalProperties.put(CodegenConstants.ARTIFACT_ID, artifactId); + additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion); + additionalProperties.put("authScheme", authScheme); + additionalProperties.put("authPreemptive", authPreemptive); + + supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); + supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore")); + supportingFiles.add(new SupportingFile("build.sbt.mustache", "", "build.sbt")); + supportingFiles.add(new SupportingFile("build.properties.mustache", "", "project/build.properties")); + supportingFiles.add(new SupportingFile("plugins.sbt.mustache", "", "project/plugins.sbt")); + + importMapping.remove("List"); + importMapping.remove("Set"); + importMapping.remove("Map"); + + importMapping.put("DateTime", "org.joda.time.DateTime"); + importMapping.put("ListBuffer", "scala.collection.mutable.ListBuffer"); + + typeMapping = new HashMap(); + typeMapping.put("Integer", "Int"); + typeMapping.put("enum", "NSString"); + typeMapping.put("array", "Seq"); + typeMapping.put("set", "Set"); + typeMapping.put("boolean", "Boolean"); + typeMapping.put("string", "String"); + typeMapping.put("int", "Int"); + typeMapping.put("long", "Long"); + typeMapping.put("float", "Float"); + typeMapping.put("byte", "Byte"); + typeMapping.put("short", "Short"); + typeMapping.put("char", "Char"); + typeMapping.put("long", "Long"); + typeMapping.put("double", "Double"); + typeMapping.put("object", "Any"); + typeMapping.put("file", "File"); + + //TODO binary should be mapped to byte array + // mapped to String as a workaround + typeMapping.put("binary", "String"); + typeMapping.put("ByteArray", "String"); + + instantiationTypes.put("array", "ListBuffer"); + instantiationTypes.put("map", "HashMap"); + + cliOptions.add(new CliOption(CodegenConstants.MODEL_PROPERTY_NAMING, + CodegenConstants.MODEL_PROPERTY_NAMING_DESC).defaultValue("camelCase")); + } + + @Override + public void processOpts() { + super.processOpts(); + + if (additionalProperties.containsKey(CodegenConstants.MODEL_PROPERTY_NAMING)) { + setModelPropertyNaming( + (String) additionalProperties.get(CodegenConstants.MODEL_PROPERTY_NAMING)); + } + } + + public void setModelPropertyNaming(String naming) { + if ("original".equals(naming) || "camelCase".equals(naming) || + "PascalCase".equals(naming) || "snake_case".equals(naming)) { + this.modelPropertyNaming = naming; + } else { + throw new IllegalArgumentException("Invalid model property naming '" + + naming + "'. Must be 'original', 'camelCase', " + + "'PascalCase' or 'snake_case'"); + } + } + + public String getModelPropertyNaming() { + return this.modelPropertyNaming; + } + + @Override + public String toVarName(String name) { + // sanitize name + name = sanitizeName( + name); // FIXME: a parameter should not be assigned. Also declare the methods parameters as 'final'. + + if ("_".equals(name)) { + name = "_u"; + } + + // if it's all uppper case, do nothing + if (name.matches("^[A-Z_]*$")) { + return name; + } + + name = getNameUsingModelPropertyNaming(name); + + // for reserved word or word starting with number, append _ + if (isReservedWord(name) || name.matches("^\\d.*")) { + name = escapeReservedWord(name); + } + + return name; + } + + @Override + public String toParamName(String name) { + // should be the same as variable name + return toVarName(name); + } + + private String getNameUsingModelPropertyNaming(String name) { + switch (CodegenConstants.MODEL_PROPERTY_NAMING_TYPE.valueOf(getModelPropertyNaming())) { + case original: + return name; + case camelCase: + return camelize(name, true); + case PascalCase: + return camelize(name); + case snake_case: + return underscore(name); + default: + throw new IllegalArgumentException("Invalid model property naming '" + + name + "'. Must be 'original', 'camelCase', " + + "'PascalCase' or 'snake_case'"); + } + + } + + @Override + public CodegenType getTag() { + return CodegenType.SERVER; + } + + @Override + public String getName() { + return "scala-lagomApi"; + } + + @Override + public String getHelp() { + return "Generates a Lagom API in scala"; + } + + @Override + public String toOperationId(String operationId) { + // throw exception if method name is empty + if (StringUtils.isEmpty(operationId)) { + throw new RuntimeException("Empty method name (operationId) not allowed"); + } + + // method name cannot use reserved keyword, e.g. return + if (isReservedWord(operationId)) { + throw new RuntimeException(operationId + " (reserved word) cannot be used as method name"); + } + + return camelize(operationId, true); + } + + @Override + public String toModelName(final String name) { + final String sanitizedName = sanitizeName(modelNamePrefix + name + modelNameSuffix); + + // camelize the model name + // phone_number => PhoneNumber + final String camelizedName = camelize(sanitizedName); + + // model name cannot use reserved keyword, e.g. return + if (isReservedWord(camelizedName)) { + final String modelName = "Model" + camelizedName; + LOGGER.warn( + camelizedName + " (reserved word) cannot be used as model name. Renamed to " + modelName); + return modelName; + } + + // model name starts with number + if (name.matches("^\\d.*")) { + final String modelName = + "Model" + camelizedName; // e.g. 200Response => Model200Response (after camelize) + LOGGER.warn( + name + " (model name starts with number) cannot be used as model name. Renamed to " + + modelName); + return modelName; + } + + return camelizedName; + } + + @Override + public String escapeQuotationMark(String input) { + // remove " to avoid code injection + return input.replace("\"", ""); + } + + @Override + public Map postProcessModelsEnum(Map objs) { + objs = super.postProcessModelsEnum(objs); + List models = (List) objs.get("models"); + for (Object _mo : models) { + Map mo = (Map) _mo; + CodegenModel cm = (CodegenModel) mo.get("model"); + + for (CodegenProperty var : cm.vars) { + if (var.isEnum) { + List enumValues = (List) var.allowableValues.get("values"); + + for (final ListIterator i = enumValues.listIterator(); i.hasNext(); ) { + final String element = String.valueOf(i.next()); + i.set(element.replaceAll("^\"|\"$", "")); + } + } + } + } + + //Needed import for Gson based libraries + if (additionalProperties.containsKey("gson")) { + List> imports = (List>) objs.get("imports"); + + for (Object _mo : models) { + Map mo = (Map) _mo; + CodegenModel cm = (CodegenModel) mo.get("model"); + // for enum model + if (Boolean.TRUE.equals(cm.isEnum) && cm.allowableValues != null) { + cm.imports.add(importMapping.get("SerializedName")); + Map item = new HashMap(); + item.put("import", importMapping.get("SerializedName")); + imports.add(item); + } + } + } + + return objs; + } + + @Override + public Map postProcessOperations(Map objs) { + Map operations = (Map) objs.get("operations"); + ArrayList oplist = (ArrayList) operations.get("operation"); + + for (CodegenOperation codegenOperation : oplist) { + String path = codegenOperation.path; + codegenOperation.path = path.replaceAll("\\{", ":").replaceAll("}", ""); + } + return objs; + } + + +} diff --git a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig index 804ad41368..5c5d4220ba 100644 --- a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig +++ b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig @@ -59,6 +59,7 @@ io.swagger.codegen.languages.RubyClientCodegen io.swagger.codegen.languages.RustClientCodegen io.swagger.codegen.languages.RustServerCodegen io.swagger.codegen.languages.ScalaClientCodegen +io.swagger.codegen.languages.ScalaLagomServerCodegen io.swagger.codegen.languages.ScalatraServerCodegen io.swagger.codegen.languages.ScalazClientCodegen io.swagger.codegen.languages.SilexServerCodegen @@ -81,4 +82,4 @@ io.swagger.codegen.languages.TypeScriptFetchClientCodegen io.swagger.codegen.languages.TypeScriptJqueryClientCodegen io.swagger.codegen.languages.TypeScriptNodeClientCodegen io.swagger.codegen.languages.UndertowCodegen -io.swagger.codegen.languages.ZendExpressivePathHandlerServerCodegen +io.swagger.codegen.languages.ZendExpressivePathHandlerServerCodegen \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/lagomScalaApi/README.mustache b/modules/swagger-codegen/src/main/resources/lagomScalaApi/README.mustache new file mode 100644 index 0000000000..938d7331cb --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/lagomScalaApi/README.mustache @@ -0,0 +1,13 @@ +# Swagger generated scala-lagomApi + +## Overview +This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the +[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 lagon-api. + +This example uses the [lagomframework](https://www.lagomframework.com) lagomframework. + +# Features which are not supported +- Form Parameters +- Seq in query parameters +- File Handling diff --git a/modules/swagger-codegen/src/main/resources/lagomScalaApi/api.mustache b/modules/swagger-codegen/src/main/resources/lagomScalaApi/api.mustache new file mode 100644 index 0000000000..cf79ddabd3 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/lagomScalaApi/api.mustache @@ -0,0 +1,62 @@ +{{>licenseInfo}} +package {{package}} + +import akka.{Done, NotUsed} +import com.lightbend.lagom.scaladsl.api.transport.Method +import com.lightbend.lagom.scaladsl.api.{Service, ServiceCall} +import play.api.libs.json._ +import com.lightbend.lagom.scaladsl.api.deser.PathParamSerializer + +{{#imports}}import {{import}} +{{/imports}} + +trait {{classname}} extends Service { + + + final override def descriptor = { + import Service._ + named("{{classname}}").withCalls( +{{#operations}} + {{#operation}} + restCall(Method.{{httpMethod}}, "{{path}}{{#queryParams.0}}?{{/queryParams.0}}{{#queryParams}}{{paramName}}{{#hasMore}}&{{/hasMore}}{{/queryParams}}", {{operationId}} _){{#hasMore}}, {{/hasMore}} + {{/operation}} +{{/operations}} + ).withAutoAcl(true) + } + +{{#operations}} + {{#operation}} + {{#hasQueryParams}} + {{#queryParams}}{{#isContainer}} + // {{{paramName}}}:{{dataType}} -- not yet supported Seq PathParamSerializers for multi value query parameters https://github.com/lagom/lagom/issues/643 + {{/isContainer}}{{/queryParams}}{{/hasQueryParams}}{{#hasFormParams}}{{#allParams}} + {{#isFormParam}} + // {{{paramName}}}:{{dataType}} -- not yet supported x-www-form-urlencoded{{/isFormParam}}{{/allParams}}{{/hasFormParams}}{{#hasHeaderParams}}{{#allParams}} + {{#isHeaderParam}} + // {{{paramName}}}:{{dataType}} -- not yet supported heder params{{/isHeaderParam}}{{/allParams}}{{/hasHeaderParams}} + /** + * {{summary}} + * {{notes}} + * {{#allParams}} {{^isBodyParam}} + * @param {{paramName}} {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/isBodyParam}}{{/allParams}} + * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}{{#bodyParams}} Body Parameter {{description}} {{/bodyParams}} + */ + def {{operationId}}({{#queryParams}}{{^isContainer}}{{^isEnum}}{{paramName}}:{{#required}}{{dataType}}{{#defaultValue}} /* = {{{defaultValue}}}*/{{/defaultValue}}{{/required}} {{^required}} Option[{{dataType}}]{{#defaultValue}} /* = {{{defaultValue}}}*/{{/defaultValue}}{{^defaultValue}} = None{{/defaultValue}}{{/required}}{{#hasMore}},{{/hasMore}}{{/isEnum}}{{/isContainer}}{{#isEnum}}{{{paramName}}}: Option[{{classname}}{{enumName}}.{{classname}}{{enumName}}]{{/isEnum}}{{/queryParams}}{{#pathParams}}{{^isEnum}}{{paramName}}: {{#required}}{{dataType}}{{#defaultValue}} /* = {{{defaultValue}}}*/{{/defaultValue}}{{/required}}{{^required}}Option[{{dataType}}]{{#defaultValue}} /* = {{{defaultValue}}}*/{{/defaultValue}}{{^defaultValue}} = None{{/defaultValue}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/isEnum}}{{#isEnum}}{{{paramName}}}: Option[{{classname}}{{enumName}}.{{classname}}{{enumName}}]{{/isEnum}}{{/pathParams}}): ServiceCall[{{#bodyParams}}{{dataType}}{{/bodyParams}}{{^hasBodyParam}}NotUsed{{/hasBodyParam}} ,{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Done{{/returnType}}] + {{/operation}}{{/operations}} + +{{#operations}} + {{#operation}} + {{#allParams}} + {{#isEnum}} + object {{classname}}{{enumName}} extends Enumeration { + val {{#allowableValues}} {{#values}}{{.}}{{^-last}}, {{/-last}}{{/values}} = Value {{/allowableValues}} + type {{classname}}{{enumName}} = Value + implicit val format: Format[Value] = Format(Reads.enumNameReads(this), Writes.enumNameWrites[{{classname}}{{enumName}}.type]) + implicit val pathParamSerializer: PathParamSerializer[{{classname}}{{enumName}}] = PathParamSerializer.required("{{classname}}{{enumName}}")(withName)(_.toString) + } + {{/isEnum}} + {{/allParams}} + {{/operation}} + } +{{/operations}} + diff --git a/modules/swagger-codegen/src/main/resources/lagomScalaApi/build.properties.mustache b/modules/swagger-codegen/src/main/resources/lagomScalaApi/build.properties.mustache new file mode 100644 index 0000000000..c091b86ca4 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/lagomScalaApi/build.properties.mustache @@ -0,0 +1 @@ +sbt.version=0.13.16 diff --git a/modules/swagger-codegen/src/main/resources/lagomScalaApi/build.sbt.mustache b/modules/swagger-codegen/src/main/resources/lagomScalaApi/build.sbt.mustache new file mode 100644 index 0000000000..f6cede96bb --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/lagomScalaApi/build.sbt.mustache @@ -0,0 +1,16 @@ +version := "{{artifactVersion}}" + +name := "{{artifactId}}" + +organization := "{{groupId}}" + +scalaVersion := "2.11.8" + +val playJsonDerivedCodecs = "org.julienrf" %% "play-json-derived-codecs" % "3.3" + +libraryDependencies ++= Seq( +lagomScaladslApi, +playJsonDerivedCodecs +) + + diff --git a/modules/swagger-codegen/src/main/resources/lagomScalaApi/gitignore.mustache b/modules/swagger-codegen/src/main/resources/lagomScalaApi/gitignore.mustache new file mode 100644 index 0000000000..eacfd7da6b --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/lagomScalaApi/gitignore.mustache @@ -0,0 +1,30 @@ +*.class +*.log + +# sbt specific +.cache +.history +.lib/ +dist/* +target/ +lib_managed/ +src_managed/ +project/boot/ +project/plugins/project/ + +# Scala-IDE specific +.scala_dependencies +.worksheet +target +ideatarget +.target +bin +.cache-main +.cache-tests +.classpath +.project +.tmpBin +.factorypath +.settings +logs +.idea diff --git a/modules/swagger-codegen/src/main/resources/lagomScalaApi/licenseInfo.mustache b/modules/swagger-codegen/src/main/resources/lagomScalaApi/licenseInfo.mustache new file mode 100644 index 0000000000..bbd8742e52 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/lagomScalaApi/licenseInfo.mustache @@ -0,0 +1,11 @@ +/** + * {{{appName}}} + * {{{appDescription}}} + * + * {{#version}}OpenAPI spec version: {{{version}}}{{/version}} + * {{#infoEmail}}Contact: {{{infoEmail}}}{{/infoEmail}} + * + * NOTE: This class is auto generated by the swagger code generator program. + * https://github.com/swagger-api/swagger-codegen.git + * Do not edit the class manually. + */ diff --git a/modules/swagger-codegen/src/main/resources/lagomScalaApi/model.mustache b/modules/swagger-codegen/src/main/resources/lagomScalaApi/model.mustache new file mode 100644 index 0000000000..2027c731c3 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/lagomScalaApi/model.mustache @@ -0,0 +1,38 @@ +{{>licenseInfo}} +package {{package}} +import play.api.libs.json._ +{{#imports}} +import {{import}} +{{/imports}} + +{{#models}} +{{#model}} +case class {{classname}} ( +{{#vars}} + {{#isEnum}} + {{{name}}}: Option[{{classname}}{{datatypeWithEnum}}.{{classname}}{{datatypeWithEnum}}]{{#hasMore}},{{/hasMore}} + {{/isEnum}} + {{^isEnum}} + {{#description}} + /* {{{description}}} */ + {{/description}} + {{{name}}}: {{^required}}Option[{{/required}}{{datatype}}{{^required}}]{{/required}}{{#hasMore}},{{/hasMore}} + {{/isEnum}} +{{/vars}} +) + +object {{classname}} { +implicit val format: Format[{{classname}}] = Json.format +} + +{{#vars}} + {{#isEnum}} +object {{classname}}{{datatypeWithEnum}} extends Enumeration { + val {{#allowableValues}} {{#values}}{{.}}{{^-last}}, {{/-last}}{{/values}} = Value{{/allowableValues}} + type {{classname}}{{datatypeWithEnum}} = Value + implicit val format: Format[Value] = Format(Reads.enumNameReads(this), Writes.enumNameWrites[{{classname}}{{datatypeWithEnum}}.type]) +} + {{/isEnum}} +{{/vars}} +{{/model}} +{{/models}} diff --git a/modules/swagger-codegen/src/main/resources/lagomScalaApi/plugins.sbt.mustache b/modules/swagger-codegen/src/main/resources/lagomScalaApi/plugins.sbt.mustache new file mode 100644 index 0000000000..2e1dfa4e05 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/lagomScalaApi/plugins.sbt.mustache @@ -0,0 +1,5 @@ +addSbtPlugin("com.lightbend.lagom" % "lagom-sbt-plugin" % "1.3.8") +// Needed for importing the project into Eclipse +addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "5.1.0") +// The ConductR plugin +addSbtPlugin("com.lightbend.conductr" % "sbt-conductr" % "2.3.5") diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/lagomScalaApi/LagomScalaApiModelTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/lagomScalaApi/LagomScalaApiModelTest.java new file mode 100644 index 0000000000..5885f37859 --- /dev/null +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/lagomScalaApi/LagomScalaApiModelTest.java @@ -0,0 +1,254 @@ +package io.swagger.codegen.lagomScalaApi; + +import com.google.common.collect.Sets; +import io.swagger.codegen.CodegenModel; +import io.swagger.codegen.CodegenProperty; +import io.swagger.codegen.DefaultCodegen; +import io.swagger.codegen.languages.ScalaLagomServerCodegen; +import io.swagger.codegen.languages.ScalaClientCodegen; +import io.swagger.models.ArrayModel; +import io.swagger.models.Model; +import io.swagger.models.ModelImpl; +import io.swagger.models.properties.ArrayProperty; +import io.swagger.models.properties.DateTimeProperty; +import io.swagger.models.properties.LongProperty; +import io.swagger.models.properties.MapProperty; +import io.swagger.models.properties.RefProperty; +import io.swagger.models.properties.StringProperty; +import org.testng.Assert; +import org.testng.annotations.Test; + +@SuppressWarnings("static-method") +public class LagomScalaApiModelTest { + + @Test(description = "convert a simple scala model") + public void simpleModelTest() { + final Model model = new ModelImpl() + .description("a sample model") + .property("id", new LongProperty()) + .property("name", new StringProperty()) + .property("createdAt", new DateTimeProperty()) + .required("id") + .required("name"); + final DefaultCodegen codegen = new ScalaLagomServerCodegen(); + final CodegenModel cm = codegen.fromModel("sample", model); + + Assert.assertEquals(cm.name, "sample"); + Assert.assertEquals(cm.classname, "Sample"); + Assert.assertEquals(cm.description, "a sample model"); + Assert.assertEquals(cm.vars.size(), 3); + + final CodegenProperty property1 = cm.vars.get(0); + Assert.assertEquals(property1.baseName, "id"); + Assert.assertEquals(property1.getter, "getId"); + Assert.assertEquals(property1.setter, "setId"); + Assert.assertEquals(property1.datatype, "Long"); + Assert.assertEquals(property1.name, "id"); + Assert.assertEquals(property1.defaultValue, "null"); + Assert.assertEquals(property1.baseType, "Long"); + Assert.assertTrue(property1.hasMore); + Assert.assertTrue(property1.required); + Assert.assertTrue(property1.isNotContainer); + + final CodegenProperty property2 = cm.vars.get(1); + Assert.assertEquals(property2.baseName, "name"); + Assert.assertEquals(property2.getter, "getName"); + Assert.assertEquals(property2.setter, "setName"); + Assert.assertEquals(property2.datatype, "String"); + Assert.assertEquals(property2.name, "name"); + Assert.assertEquals(property2.defaultValue, "null"); + Assert.assertEquals(property2.baseType, "String"); + Assert.assertTrue(property2.hasMore); + Assert.assertTrue(property2.required); + Assert.assertTrue(property2.isNotContainer); + + final CodegenProperty property3 = cm.vars.get(2); + Assert.assertEquals(property3.baseName, "createdAt"); + Assert.assertEquals(property3.getter, "getCreatedAt"); + Assert.assertEquals(property3.setter, "setCreatedAt"); + Assert.assertEquals(property3.datatype, "DateTime"); + Assert.assertEquals(property3.name, "createdAt"); + Assert.assertEquals(property3.defaultValue, "null"); + Assert.assertEquals(property3.baseType, "DateTime"); + Assert.assertFalse(property3.hasMore); + Assert.assertFalse(property3.required); + Assert.assertTrue(property3.isNotContainer); + } + + @Test(description = "convert a model with list property") + public void listPropertyTest() { + final Model model = new ModelImpl() + .description("a sample model") + .property("id", new LongProperty()) + .property("urls", new ArrayProperty() + .items(new StringProperty())) + .required("id"); + final DefaultCodegen codegen = new ScalaClientCodegen(); + final CodegenModel cm = codegen.fromModel("sample", model); + + Assert.assertEquals(cm.name, "sample"); + Assert.assertEquals(cm.classname, "Sample"); + Assert.assertEquals(cm.description, "a sample model"); + Assert.assertEquals(cm.vars.size(), 2); + + final CodegenProperty property1 = cm.vars.get(1); + Assert.assertEquals(property1.baseName, "urls"); + Assert.assertEquals(property1.getter, "getUrls"); + Assert.assertEquals(property1.setter, "setUrls"); + Assert.assertEquals(property1.datatype, "List[String]"); + Assert.assertEquals(property1.name, "urls"); + Assert.assertEquals(property1.defaultValue, "new ListBuffer[String]() "); + Assert.assertEquals(property1.baseType, "List"); + Assert.assertEquals(property1.containerType, "array"); + Assert.assertFalse(property1.required); + Assert.assertTrue(property1.isContainer); + } + + @Test(description = "convert a model with a map property") + public void mapPropertyTest() { + final Model model = new ModelImpl() + .description("a sample model") + .property("translations", new MapProperty() + .additionalProperties(new StringProperty())) + .required("id"); + final DefaultCodegen codegen = new ScalaClientCodegen(); + final CodegenModel cm = codegen.fromModel("sample", model); + + Assert.assertEquals(cm.name, "sample"); + Assert.assertEquals(cm.classname, "Sample"); + Assert.assertEquals(cm.description, "a sample model"); + Assert.assertEquals(cm.vars.size(), 1); + + final CodegenProperty property1 = cm.vars.get(0); + Assert.assertEquals(property1.baseName, "translations"); + Assert.assertEquals(property1.getter, "getTranslations"); + Assert.assertEquals(property1.setter, "setTranslations"); + Assert.assertEquals(property1.datatype, "Map[String, String]"); + Assert.assertEquals(property1.name, "translations"); + Assert.assertEquals(property1.defaultValue, "new HashMap[String, String]() "); + Assert.assertEquals(property1.baseType, "Map"); + Assert.assertEquals(property1.containerType, "map"); + Assert.assertFalse(property1.required); + Assert.assertTrue(property1.isContainer); + } + + @Test(description = "convert a model with complex properties") + public void complexPropertyTest() { + final Model model = new ModelImpl() + .description("a sample model") + .property("children", new RefProperty("#/definitions/Children")); + final DefaultCodegen codegen = new ScalaClientCodegen(); + final CodegenModel cm = codegen.fromModel("sample", model); + + Assert.assertEquals(cm.name, "sample"); + Assert.assertEquals(cm.classname, "Sample"); + Assert.assertEquals(cm.description, "a sample model"); + Assert.assertEquals(cm.vars.size(), 1); + + final CodegenProperty property1 = cm.vars.get(0); + Assert.assertEquals(property1.baseName, "children"); + Assert.assertEquals(property1.getter, "getChildren"); + Assert.assertEquals(property1.setter, "setChildren"); + Assert.assertEquals(property1.datatype, "Children"); + Assert.assertEquals(property1.name, "children"); + Assert.assertEquals(property1.defaultValue, "null"); + Assert.assertEquals(property1.baseType, "Children"); + Assert.assertFalse(property1.required); + Assert.assertTrue(property1.isNotContainer); + } + + @Test(description = "convert a model with complex list property") + public void complexListPropertyTest() { + final Model model = new ModelImpl() + .description("a sample model") + .property("children", new ArrayProperty() + .items(new RefProperty("#/definitions/Children"))); + final DefaultCodegen codegen = new ScalaClientCodegen(); + final CodegenModel cm = codegen.fromModel("sample", model); + + Assert.assertEquals(cm.name, "sample"); + Assert.assertEquals(cm.classname, "Sample"); + Assert.assertEquals(cm.description, "a sample model"); + Assert.assertEquals(cm.vars.size(), 1); + + final CodegenProperty property1 = cm.vars.get(0); + Assert.assertEquals(property1.baseName, "children"); + Assert.assertEquals(property1.complexType, "Children"); + Assert.assertEquals(property1.getter, "getChildren"); + Assert.assertEquals(property1.setter, "setChildren"); + Assert.assertEquals(property1.datatype, "List[Children]"); + Assert.assertEquals(property1.name, "children"); + Assert.assertEquals(property1.defaultValue, "new ListBuffer[Children]() "); + Assert.assertEquals(property1.baseType, "List"); + Assert.assertEquals(property1.containerType, "array"); + Assert.assertFalse(property1.required); + Assert.assertTrue(property1.isContainer); + } + + @Test(description = "convert a model with complex map property") + public void complexMapPropertyTest() { + final Model model = new ModelImpl() + .description("a sample model") + .property("children", new MapProperty() + .additionalProperties(new RefProperty("#/definitions/Children"))); + final DefaultCodegen codegen = new ScalaClientCodegen(); + final CodegenModel cm = codegen.fromModel("sample", model); + + Assert.assertEquals(cm.name, "sample"); + Assert.assertEquals(cm.classname, "Sample"); + Assert.assertEquals(cm.description, "a sample model"); + Assert.assertEquals(cm.vars.size(), 1); + Assert.assertEquals(Sets.intersection(cm.imports, Sets.newHashSet("Children")).size(), 1); + + final CodegenProperty property1 = cm.vars.get(0); + Assert.assertEquals(property1.baseName, "children"); + Assert.assertEquals(property1.complexType, "Children"); + Assert.assertEquals(property1.getter, "getChildren"); + Assert.assertEquals(property1.setter, "setChildren"); + Assert.assertEquals(property1.datatype, "Map[String, Children]"); + Assert.assertEquals(property1.name, "children"); + Assert.assertEquals(property1.defaultValue, "new HashMap[String, Children]() "); + Assert.assertEquals(property1.baseType, "Map"); + Assert.assertEquals(property1.containerType, "map"); + Assert.assertFalse(property1.required); + Assert.assertTrue(property1.isContainer); + Assert.assertFalse(property1.isNotContainer); + } + + @Test(description = "convert an array model") + public void arrayModelTest() { + final Model model = new ArrayModel() + .description("an array model") + .items(new RefProperty("#/definitions/Children")); + final DefaultCodegen codegen = new ScalaClientCodegen(); + final CodegenModel cm = codegen.fromModel("sample", model); + + Assert.assertEquals(cm.name, "sample"); + Assert.assertEquals(cm.classname, "Sample"); + Assert.assertEquals(cm.description, "an array model"); + Assert.assertEquals(cm.vars.size(), 0); + Assert.assertEquals(cm.parent, "ListBuffer[Children]"); + Assert.assertEquals(cm.imports.size(), 2); + Assert.assertEquals( + Sets.intersection(cm.imports, Sets.newHashSet("ListBuffer", "Children")).size(), 2); + } + + @Test(description = "convert an map model") + public void mapModelTest() { + final Model model = new ModelImpl() + .description("a map model") + .additionalProperties(new RefProperty("#/definitions/Children")); + final DefaultCodegen codegen = new ScalaClientCodegen(); + final CodegenModel cm = codegen.fromModel("sample", model); + + Assert.assertEquals(cm.name, "sample"); + Assert.assertEquals(cm.classname, "Sample"); + Assert.assertEquals(cm.description, "a map model"); + Assert.assertEquals(cm.vars.size(), 0); + Assert.assertEquals(cm.parent, "HashMap[String, Children]"); + Assert.assertEquals(cm.imports.size(), 2); + Assert + .assertEquals(Sets.intersection(cm.imports, Sets.newHashSet("HashMap", "Children")).size(), + 2); + } +} diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/lagomScalaApi/LagomScalaApiOptionsTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/lagomScalaApi/LagomScalaApiOptionsTest.java new file mode 100644 index 0000000000..a4e7ac1dd1 --- /dev/null +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/lagomScalaApi/LagomScalaApiOptionsTest.java @@ -0,0 +1,41 @@ +package io.swagger.codegen.lagomScalaApi; + +import io.swagger.codegen.AbstractOptionsTest; +import io.swagger.codegen.CodegenConfig; +import io.swagger.codegen.languages.ScalaLagomServerCodegen; +import io.swagger.codegen.options.ScalaClientOptionsProvider; +import mockit.Expectations; +import mockit.Tested; + +public class LagomScalaApiOptionsTest extends AbstractOptionsTest { + + @Tested + private ScalaLagomServerCodegen clientCodegen; + + public LagomScalaApiOptionsTest() { + super(new ScalaClientOptionsProvider()); + } + + @Override + protected CodegenConfig getCodegenConfig() { + return clientCodegen; + } + + @SuppressWarnings("unused") + @Override + protected void setExpectations() { + new Expectations(clientCodegen) {{ + clientCodegen.setModelPackage(ScalaClientOptionsProvider.MODEL_PACKAGE_VALUE); + times = 1; + clientCodegen.setApiPackage(ScalaClientOptionsProvider.API_PACKAGE_VALUE); + times = 1; + clientCodegen.setSortParamsByRequiredFlag( + Boolean.valueOf(ScalaClientOptionsProvider.SORT_PARAMS_VALUE)); + times = 1; + clientCodegen.setModelPropertyNaming(ScalaClientOptionsProvider.MODEL_PROPERTY_NAMING); + times = 1; + clientCodegen.setSourceFolder(ScalaClientOptionsProvider.SOURCE_FOLDER_VALUE); + times = 1; + }}; + } +} diff --git a/samples/server/petstore/lagomScalaApi/.gitignore b/samples/server/petstore/lagomScalaApi/.gitignore new file mode 100644 index 0000000000..eacfd7da6b --- /dev/null +++ b/samples/server/petstore/lagomScalaApi/.gitignore @@ -0,0 +1,30 @@ +*.class +*.log + +# sbt specific +.cache +.history +.lib/ +dist/* +target/ +lib_managed/ +src_managed/ +project/boot/ +project/plugins/project/ + +# Scala-IDE specific +.scala_dependencies +.worksheet +target +ideatarget +.target +bin +.cache-main +.cache-tests +.classpath +.project +.tmpBin +.factorypath +.settings +logs +.idea diff --git a/samples/server/petstore/lagomScalaApi/.swagger-codegen-ignore b/samples/server/petstore/lagomScalaApi/.swagger-codegen-ignore new file mode 100644 index 0000000000..c5fa491b4c --- /dev/null +++ b/samples/server/petstore/lagomScalaApi/.swagger-codegen-ignore @@ -0,0 +1,23 @@ +# Swagger Codegen Ignore +# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen + +# 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 Swagger Codgen 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 diff --git a/samples/server/petstore/lagomScalaApi/.swagger-codegen/VERSION b/samples/server/petstore/lagomScalaApi/.swagger-codegen/VERSION new file mode 100644 index 0000000000..f9f7450d13 --- /dev/null +++ b/samples/server/petstore/lagomScalaApi/.swagger-codegen/VERSION @@ -0,0 +1 @@ +2.3.0-SNAPSHOT \ No newline at end of file diff --git a/samples/server/petstore/lagomScalaApi/README.md b/samples/server/petstore/lagomScalaApi/README.md new file mode 100644 index 0000000000..938d7331cb --- /dev/null +++ b/samples/server/petstore/lagomScalaApi/README.md @@ -0,0 +1,13 @@ +# Swagger generated scala-lagomApi + +## Overview +This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the +[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 lagon-api. + +This example uses the [lagomframework](https://www.lagomframework.com) lagomframework. + +# Features which are not supported +- Form Parameters +- Seq in query parameters +- File Handling diff --git a/samples/server/petstore/lagomScalaApi/build.sbt b/samples/server/petstore/lagomScalaApi/build.sbt new file mode 100644 index 0000000000..728fb23096 --- /dev/null +++ b/samples/server/petstore/lagomScalaApi/build.sbt @@ -0,0 +1,16 @@ +version := "1.0.0" + +name := "scala-lagomApi" + +organization := "io.swagger" + +scalaVersion := "2.11.8" + +val playJsonDerivedCodecs = "org.julienrf" %% "play-json-derived-codecs" % "3.3" + +libraryDependencies ++= Seq( +lagomScaladslApi, +playJsonDerivedCodecs +) + + diff --git a/samples/server/petstore/lagomScalaApi/project/build.properties b/samples/server/petstore/lagomScalaApi/project/build.properties new file mode 100644 index 0000000000..c091b86ca4 --- /dev/null +++ b/samples/server/petstore/lagomScalaApi/project/build.properties @@ -0,0 +1 @@ +sbt.version=0.13.16 diff --git a/samples/server/petstore/lagomScalaApi/project/plugins.sbt b/samples/server/petstore/lagomScalaApi/project/plugins.sbt new file mode 100644 index 0000000000..2e1dfa4e05 --- /dev/null +++ b/samples/server/petstore/lagomScalaApi/project/plugins.sbt @@ -0,0 +1,5 @@ +addSbtPlugin("com.lightbend.lagom" % "lagom-sbt-plugin" % "1.3.8") +// Needed for importing the project into Eclipse +addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "5.1.0") +// The ConductR plugin +addSbtPlugin("com.lightbend.conductr" % "sbt-conductr" % "2.3.5") diff --git a/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/api/PetApi.scala b/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/api/PetApi.scala new file mode 100644 index 0000000000..6ee03b22ac --- /dev/null +++ b/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/api/PetApi.scala @@ -0,0 +1,138 @@ +/** + * Swagger Petstore + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI spec version: 1.0.0 + * Contact: apiteam@swagger.io + * + * NOTE: This class is auto generated by the swagger code generator program. + * https://github.com/swagger-api/swagger-codegen.git + * Do not edit the class manually. + */ + +package io.swagger.client.api + +import akka.{Done, NotUsed} +import com.lightbend.lagom.scaladsl.api.transport.Method +import com.lightbend.lagom.scaladsl.api.{Service, ServiceCall} +import play.api.libs.json._ +import com.lightbend.lagom.scaladsl.api.deser.PathParamSerializer + +import io.swagger.client.model.ApiResponse +import java.io.File +import io.swagger.client.model.Pet + +trait PetApi extends Service { + + + final override def descriptor = { + import Service._ + named("PetApi").withCalls( + restCall(Method.POST, "/pet", addPet _), + restCall(Method.DELETE, "/pet/:petId", deletePet _), + restCall(Method.GET, "/pet/findByStatus?status", findPetsByStatus _), + restCall(Method.GET, "/pet/findByTags?tags", findPetsByTags _), + restCall(Method.GET, "/pet/:petId", getPetById _), + restCall(Method.PUT, "/pet", updatePet _), + restCall(Method.POST, "/pet/:petId", updatePetWithForm _), + restCall(Method.POST, "/pet/:petId/uploadImage", uploadFile _) + ).withAutoAcl(true) + } + + + /** + * Add a new pet to the store + * + * + * @return void Body Parameter Pet object that needs to be added to the store + */ + def addPet(): ServiceCall[Pet ,Done] + + + // apiKey:String -- not yet supported heder params + /** + * Deletes a pet + * + * + * @param petId Pet id to delete + * @param apiKey (optional) + * @return void + */ + def deletePet(petId: Long): ServiceCall[NotUsed ,Done] + + // status:Seq[String] -- not yet supported Seq PathParamSerializers for multi value query parameters https://github.com/lagom/lagom/issues/643 + + /** + * 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 + * @return Seq[Pet] + */ + def findPetsByStatus(status: Option[PetApiStatusEnum.PetApiStatusEnum]): ServiceCall[NotUsed ,Seq[Pet]] + + // tags:Seq[String] -- not yet supported Seq PathParamSerializers for multi value query parameters https://github.com/lagom/lagom/issues/643 + + /** + * 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 + * @return Seq[Pet] + */ + def findPetsByTags(): ServiceCall[NotUsed ,Seq[Pet]] + + /** + * Find pet by ID + * Returns a single pet + * + * @param petId ID of pet to return + * @return Pet + */ + def getPetById(petId: Long): ServiceCall[NotUsed ,Pet] + + /** + * Update an existing pet + * + * + * @return void Body Parameter Pet object that needs to be added to the store + */ + def updatePet(): ServiceCall[Pet ,Done] + + + // name:String -- not yet supported x-www-form-urlencoded + // status:String -- not yet supported x-www-form-urlencoded + /** + * 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 (optional) + * @param status Updated status of the pet (optional) + * @return void + */ + def updatePetWithForm(petId: Long): ServiceCall[NotUsed ,Done] + + + // additionalMetadata:String -- not yet supported x-www-form-urlencoded + // file:File -- not yet supported x-www-form-urlencoded + /** + * uploads an image + * + * + * @param petId ID of pet to update + * @param additionalMetadata Additional data to pass to server (optional) + * @param file file to upload (optional) + * @return ApiResponse + */ + def uploadFile(petId: Long): ServiceCall[NotUsed ,ApiResponse] + + + object PetApiStatusEnum extends Enumeration { + val available, pending, sold = Value + type PetApiStatusEnum = Value + implicit val format: Format[Value] = Format(Reads.enumNameReads(this), Writes.enumNameWrites[PetApiStatusEnum.type]) + implicit val pathParamSerializer: PathParamSerializer[PetApiStatusEnum] = PathParamSerializer.required("PetApiStatusEnum")(withName)(_.toString) + } + } + diff --git a/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/api/StoreApi.scala b/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/api/StoreApi.scala new file mode 100644 index 0000000000..ff42a995e9 --- /dev/null +++ b/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/api/StoreApi.scala @@ -0,0 +1,73 @@ +/** + * Swagger Petstore + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI spec version: 1.0.0 + * Contact: apiteam@swagger.io + * + * NOTE: This class is auto generated by the swagger code generator program. + * https://github.com/swagger-api/swagger-codegen.git + * Do not edit the class manually. + */ + +package io.swagger.client.api + +import akka.{Done, NotUsed} +import com.lightbend.lagom.scaladsl.api.transport.Method +import com.lightbend.lagom.scaladsl.api.{Service, ServiceCall} +import play.api.libs.json._ +import com.lightbend.lagom.scaladsl.api.deser.PathParamSerializer + +import io.swagger.client.model.Order + +trait StoreApi extends Service { + + + final override def descriptor = { + import Service._ + named("StoreApi").withCalls( + restCall(Method.DELETE, "/store/order/:orderId", deleteOrder _), + restCall(Method.GET, "/store/inventory", getInventory _), + restCall(Method.GET, "/store/order/:orderId", getOrderById _), + restCall(Method.POST, "/store/order", placeOrder _) + ).withAutoAcl(true) + } + + + /** + * 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 + * @return void + */ + def deleteOrder(orderId: String): ServiceCall[NotUsed ,Done] + + /** + * Returns pet inventories by status + * Returns a map of status codes to quantities + * + * @return Map[String, Int] + */ + def getInventory(): ServiceCall[NotUsed ,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 + * @return Order + */ + def getOrderById(orderId: Long): ServiceCall[NotUsed ,Order] + + /** + * Place an order for a pet + * + * + * @return Order Body Parameter order placed for purchasing the pet + */ + def placeOrder(): ServiceCall[Order ,Order] + + + } + diff --git a/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/api/UserApi.scala b/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/api/UserApi.scala new file mode 100644 index 0000000000..b62b48d875 --- /dev/null +++ b/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/api/UserApi.scala @@ -0,0 +1,112 @@ +/** + * Swagger Petstore + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI spec version: 1.0.0 + * Contact: apiteam@swagger.io + * + * NOTE: This class is auto generated by the swagger code generator program. + * https://github.com/swagger-api/swagger-codegen.git + * Do not edit the class manually. + */ + +package io.swagger.client.api + +import akka.{Done, NotUsed} +import com.lightbend.lagom.scaladsl.api.transport.Method +import com.lightbend.lagom.scaladsl.api.{Service, ServiceCall} +import play.api.libs.json._ +import com.lightbend.lagom.scaladsl.api.deser.PathParamSerializer + +import io.swagger.client.model.User + +trait UserApi extends Service { + + + final override def descriptor = { + import Service._ + named("UserApi").withCalls( + restCall(Method.POST, "/user", createUser _), + restCall(Method.POST, "/user/createWithArray", createUsersWithArrayInput _), + restCall(Method.POST, "/user/createWithList", createUsersWithListInput _), + restCall(Method.DELETE, "/user/:username", deleteUser _), + restCall(Method.GET, "/user/:username", getUserByName _), + restCall(Method.GET, "/user/login?username&password", loginUser _), + restCall(Method.GET, "/user/logout", logoutUser _), + restCall(Method.PUT, "/user/:username", updateUser _) + ).withAutoAcl(true) + } + + + /** + * Create user + * This can only be done by the logged in user. + * + * @return void Body Parameter Created user object + */ + def createUser(): ServiceCall[User ,Done] + + /** + * Creates list of users with given input array + * + * + * @return void Body Parameter List of user object + */ + def createUsersWithArrayInput(): ServiceCall[Seq[User] ,Done] + + /** + * Creates list of users with given input array + * + * + * @return void Body Parameter List of user object + */ + def createUsersWithListInput(): ServiceCall[Seq[User] ,Done] + + /** + * Delete user + * This can only be done by the logged in user. + * + * @param username The name that needs to be deleted + * @return void + */ + def deleteUser(username: String): ServiceCall[NotUsed ,Done] + + /** + * Get user by user name + * + * + * @param username The name that needs to be fetched. Use user1 for testing. + * @return User + */ + def getUserByName(username: String): ServiceCall[NotUsed ,User] + + /** + * Logs user into the system + * + * + * @param username The user name for login + * @param password The password for login in clear text + * @return String + */ + def loginUser(username:String ,password:String ): ServiceCall[NotUsed ,String] + + /** + * Logs out current logged in user session + * + * + * @return void + */ + def logoutUser(): ServiceCall[NotUsed ,Done] + + /** + * Updated user + * This can only be done by the logged in user. + * + * @param username name that need to be deleted + * @return void Body Parameter Updated user object + */ + def updateUser(username: String): ServiceCall[User ,Done] + + + } + diff --git a/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/model/ApiResponse.scala b/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/model/ApiResponse.scala new file mode 100644 index 0000000000..884853e5c2 --- /dev/null +++ b/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/model/ApiResponse.scala @@ -0,0 +1,25 @@ +/** + * Swagger Petstore + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI spec version: 1.0.0 + * Contact: apiteam@swagger.io + * + * NOTE: This class is auto generated by the swagger code generator program. + * https://github.com/swagger-api/swagger-codegen.git + * Do not edit the class manually. + */ + +package io.swagger.client.model +import play.api.libs.json._ + +case class ApiResponse ( + code: Option[Int], + _type: Option[String], + message: Option[String] +) + +object ApiResponse { +implicit val format: Format[ApiResponse] = Json.format +} + diff --git a/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/model/Category.scala b/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/model/Category.scala new file mode 100644 index 0000000000..c50c6e71c6 --- /dev/null +++ b/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/model/Category.scala @@ -0,0 +1,24 @@ +/** + * Swagger Petstore + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI spec version: 1.0.0 + * Contact: apiteam@swagger.io + * + * NOTE: This class is auto generated by the swagger code generator program. + * https://github.com/swagger-api/swagger-codegen.git + * Do not edit the class manually. + */ + +package io.swagger.client.model +import play.api.libs.json._ + +case class Category ( + id: Option[Long], + name: Option[String] +) + +object Category { +implicit val format: Format[Category] = Json.format +} + diff --git a/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/model/Order.scala b/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/model/Order.scala new file mode 100644 index 0000000000..c79ffb780e --- /dev/null +++ b/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/model/Order.scala @@ -0,0 +1,34 @@ +/** + * Swagger Petstore + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI spec version: 1.0.0 + * Contact: apiteam@swagger.io + * + * NOTE: This class is auto generated by the swagger code generator program. + * https://github.com/swagger-api/swagger-codegen.git + * Do not edit the class manually. + */ + +package io.swagger.client.model +import play.api.libs.json._ +import org.joda.time.DateTime + +case class Order ( + id: Option[Long], + petId: Option[Long], + quantity: Option[Int], + shipDate: Option[DateTime], + status: Option[OrderStatusEnum.OrderStatusEnum], + complete: Option[Boolean] +) + +object Order { +implicit val format: Format[Order] = Json.format +} + +object OrderStatusEnum extends Enumeration { + val placed, approved, delivered = Value + type OrderStatusEnum = Value + implicit val format: Format[Value] = Format(Reads.enumNameReads(this), Writes.enumNameWrites[OrderStatusEnum.type]) +} diff --git a/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/model/Pet.scala b/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/model/Pet.scala new file mode 100644 index 0000000000..acc6c25afc --- /dev/null +++ b/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/model/Pet.scala @@ -0,0 +1,33 @@ +/** + * Swagger Petstore + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI spec version: 1.0.0 + * Contact: apiteam@swagger.io + * + * NOTE: This class is auto generated by the swagger code generator program. + * https://github.com/swagger-api/swagger-codegen.git + * Do not edit the class manually. + */ + +package io.swagger.client.model +import play.api.libs.json._ + +case class Pet ( + id: Option[Long], + category: Option[Category], + name: String, + photoUrls: Seq[String], + tags: Option[Seq[Tag]], + status: Option[PetStatusEnum.PetStatusEnum] +) + +object Pet { +implicit val format: Format[Pet] = Json.format +} + +object PetStatusEnum extends Enumeration { + val available, pending, sold = Value + type PetStatusEnum = Value + implicit val format: Format[Value] = Format(Reads.enumNameReads(this), Writes.enumNameWrites[PetStatusEnum.type]) +} diff --git a/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/model/Tag.scala b/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/model/Tag.scala new file mode 100644 index 0000000000..65aa9c628b --- /dev/null +++ b/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/model/Tag.scala @@ -0,0 +1,24 @@ +/** + * Swagger Petstore + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI spec version: 1.0.0 + * Contact: apiteam@swagger.io + * + * NOTE: This class is auto generated by the swagger code generator program. + * https://github.com/swagger-api/swagger-codegen.git + * Do not edit the class manually. + */ + +package io.swagger.client.model +import play.api.libs.json._ + +case class Tag ( + id: Option[Long], + name: Option[String] +) + +object Tag { +implicit val format: Format[Tag] = Json.format +} + diff --git a/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/model/User.scala b/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/model/User.scala new file mode 100644 index 0000000000..b21cd2e7e7 --- /dev/null +++ b/samples/server/petstore/lagomScalaApi/src/main/scala/io/swagger/client/model/User.scala @@ -0,0 +1,31 @@ +/** + * Swagger Petstore + * This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. + * + * OpenAPI spec version: 1.0.0 + * Contact: apiteam@swagger.io + * + * NOTE: This class is auto generated by the swagger code generator program. + * https://github.com/swagger-api/swagger-codegen.git + * Do not edit the class manually. + */ + +package io.swagger.client.model +import play.api.libs.json._ + +case class User ( + id: Option[Long], + username: Option[String], + firstName: Option[String], + lastName: Option[String], + email: Option[String], + password: Option[String], + phone: Option[String], + /* User Status */ + userStatus: Option[Int] +) + +object User { +implicit val format: Format[User] = Json.format +} +