diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ScalaClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ScalaClientCodegen.java index 2044b80fc802..3efd6dcd1017 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ScalaClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ScalaClientCodegen.java @@ -9,6 +9,7 @@ import io.swagger.codegen.SupportingFile; import java.io.File; import java.util.Arrays; import java.util.HashMap; +import java.util.Map; import org.apache.commons.lang3.StringUtils; @@ -20,6 +21,7 @@ public class ScalaClientCodegen extends AbstractScalaCodegen implements CodegenC protected String groupId = "io.swagger"; protected String artifactId = "swagger-scala-client"; protected String artifactVersion = "1.0.0"; + protected String clientName = "AsyncClient"; public ScalaClientCodegen() { super(); @@ -51,10 +53,13 @@ public class ScalaClientCodegen extends AbstractScalaCodegen implements CodegenC additionalProperties.put("asyncHttpClient", asyncHttpClient); additionalProperties.put("authScheme", authScheme); additionalProperties.put("authPreemptive", authPreemptive); + additionalProperties.put("clientName", clientName); supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml")); supportingFiles.add(new SupportingFile("apiInvoker.mustache", (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), "ApiInvoker.scala")); + supportingFiles.add(new SupportingFile("client.mustache", + (sourceFolder + File.separator + invokerPackage).replace(".", java.io.File.separator), clientName + ".scala")); supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh")); supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore")); // gradle settings @@ -75,8 +80,8 @@ public class ScalaClientCodegen extends AbstractScalaCodegen implements CodegenC importMapping.remove("Set"); importMapping.remove("Map"); - importMapping.put("DateTime", "org.joda.time.DateTime"); - importMapping.put("ListBuffer", "scala.collection.mutable.ListBuffer"); + importMapping.put("Date", "java.util.Date"); + importMapping.put("ListBuffer", "scala.collections.mutable.ListBuffer"); typeMapping = new HashMap(); typeMapping.put("enum", "NSString"); @@ -90,7 +95,6 @@ public class ScalaClientCodegen extends AbstractScalaCodegen implements CodegenC 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"); @@ -98,6 +102,10 @@ public class ScalaClientCodegen extends AbstractScalaCodegen implements CodegenC // mapped to String as a workaround typeMapping.put("binary", "String"); typeMapping.put("ByteArray", "String"); + typeMapping.put("date-time", "Date"); +// typeMapping.put("date", "Date"); +// typeMapping.put("Date", "Date"); + typeMapping.put("DateTime", "Date"); instantiationTypes.put("array", "ListBuffer"); instantiationTypes.put("map", "HashMap"); @@ -108,7 +116,6 @@ public class ScalaClientCodegen extends AbstractScalaCodegen implements CodegenC @Override public void processOpts() { super.processOpts(); - if (additionalProperties.containsKey(CodegenConstants.MODEL_PROPERTY_NAMING)) { setModelPropertyNaming((String) additionalProperties.get(CodegenConstants.MODEL_PROPERTY_NAMING)); } diff --git a/modules/swagger-codegen/src/main/resources/asyncscala/client.mustache b/modules/swagger-codegen/src/main/resources/asyncscala/client.mustache index d48d031860ef..87d830e3e6ae 100644 --- a/modules/swagger-codegen/src/main/resources/asyncscala/client.mustache +++ b/modules/swagger-codegen/src/main/resources/asyncscala/client.mustache @@ -23,3 +23,4 @@ class {{clientName}}(config: SwaggerConfig) extends Closeable { client.close() } } + diff --git a/modules/swagger-codegen/src/main/resources/scala/api.mustache b/modules/swagger-codegen/src/main/resources/scala/api.mustache index c3dd3effe7d9..5c8c5ec07b4c 100644 --- a/modules/swagger-codegen/src/main/resources/scala/api.mustache +++ b/modules/swagger-codegen/src/main/resources/scala/api.mustache @@ -1,10 +1,11 @@ {{>licenseInfo}} package {{package}} +import java.text.SimpleDateFormat + {{#imports}}import {{import}} {{/imports}} -import {{invokerPackage}}.ApiInvoker -import {{invokerPackage}}.ApiException +import {{invokerPackage}}.{ApiInvoker, ApiException} import com.sun.jersey.multipart.FormDataMultiPart import com.sun.jersey.multipart.file.FileDataBodyPart @@ -16,13 +17,42 @@ import java.util.Date import scala.collection.mutable.HashMap +import com.wordnik.swagger.client._ +import scala.concurrent.Future +import collection.mutable + +import java.net.URI + +import com.wordnik.swagger.client.ClientResponseReaders.Json4sFormatsReader._ +import com.wordnik.swagger.client.RequestWriters.Json4sFormatsWriter._ + +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent._ +import scala.concurrent.duration._ +import scala.util.{Failure, Success, Try} + {{#operations}} class {{classname}}(val defBasePath: String = "{{{basePath}}}", defApiInvoker: ApiInvoker = ApiInvoker) { + + implicit val formats = new org.json4s.DefaultFormats { + override def dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS+0000") + } + implicit val stringReader = ClientResponseReaders.StringReader + implicit val unitReader = ClientResponseReaders.UnitReader + implicit val jvalueReader = ClientResponseReaders.JValueReader + implicit val jsonReader = JsonFormatsReader + implicit val stringWriter = RequestWriters.StringWriter + implicit val jsonWriter = JsonFormatsWriter + var basePath = defBasePath var apiInvoker = defApiInvoker - def addHeader(key: String, value: String) = apiInvoker.defaultHeaders += key -> value + def addHeader(key: String, value: String) = apiInvoker.defaultHeaders += key -> value + + val config = SwaggerConfig.forUrl(new URI(defBasePath)) + val client = new RestClient(config) + val helper = new {{classname}}AsyncHelper(client, config) {{#operation}} /** @@ -32,97 +62,82 @@ class {{classname}}(val defBasePath: String = "{{{basePath}}}", {{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} */ def {{operationId}}({{#allParams}}{{paramName}}: {{#required}}{{dataType}}{{#defaultValue}} /* = {{{defaultValue}}}*/{{/defaultValue}}{{/required}}{{^required}}Option[{{dataType}}]{{#defaultValue}} /* = {{{defaultValue}}}*/{{/defaultValue}}{{^defaultValue}} = None{{/defaultValue}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}){{#returnType}}: Option[{{returnType}}]{{/returnType}} = { - // create path and map variables - val path = "{{{path}}}".replaceAll("\\{format\\}", "json"){{#pathParams}}.replaceAll("\\{" + "{{baseName}}" + "\\}",apiInvoker.escape({{paramName}})){{/pathParams}} - - val contentTypes = List({{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}}{{^consumes}}"application/json"{{/consumes}}) - val contentType = contentTypes(0) - - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] - - {{#allParams}} - {{#required}} - {{^isPrimitiveType}} - if ({{paramName}} == null) throw new Exception("Missing required parameter '{{paramName}}' when calling {{classname}}->{{operationId}}") - - {{/isPrimitiveType}} - {{#isString}} - if ({{paramName}} == null) throw new Exception("Missing required parameter '{{paramName}}' when calling {{classname}}->{{operationId}}") - - {{/isString}} - {{/required}} - {{/allParams}} - {{#queryParams}} - {{#required}} - queryParams += "{{baseName}}" -> {{paramName}}.toString - {{/required}} - {{^required}} - {{paramName}}.map(paramVal => queryParams += "{{baseName}}" -> paramVal.toString) - {{/required}} - {{/queryParams}} - - {{#headerParams}} - {{#required}} - headerParams += "{{baseName}}" -> {{paramName}} - {{/required}} - {{^required}} - {{paramName}}.map(paramVal => headerParams += "{{baseName}}" -> paramVal) - {{/required}} - {{/headerParams}} - - var postBody: AnyRef = {{#bodyParam}}{{#required}}{{paramName}}{{/required}}{{^required}}{{paramName}}.map(paramVal => paramVal){{/required}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}} - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - {{#formParams}} - {{#notFile}} - {{#required}} - mp.field("{{baseName}}", {{paramName}}.toString, MediaType.MULTIPART_FORM_DATA_TYPE) - {{/required}} - {{^required}} - {{paramName}}.map(paramVal => mp.field("{{baseName}}", paramVal.toString, MediaType.MULTIPART_FORM_DATA_TYPE)) - {{/required}} - {{/notFile}} - {{#isFile}} - {{#required}} - mp.field("{{baseName}}", file.getName) - mp.bodyPart(new FileDataBodyPart("{{baseName}}", {{paramName}}, MediaType.MULTIPART_FORM_DATA_TYPE)) - {{/required}} - {{^required}} - file.map(fileVal => mp.field("{{baseName}}", fileVal.getName)) - {{paramName}}.map(paramVal => mp.bodyPart(new FileDataBodyPart("{{baseName}}", paramVal, MediaType.MULTIPART_FORM_DATA_TYPE))) - {{/required}} - {{/isFile}} - {{/formParams}} - postBody = mp - } else { - {{#formParams}} - {{#notFile}} - {{#required}} - formParams += "{{baseName}}" -> {{paramName}}.toString - {{/required}} - {{^required}} - {{paramName}}.map(paramVal => formParams += "{{baseName}}" -> paramVal.toString) - {{/required}} - {{/notFile}} - {{/formParams}} - } - - try { - apiInvoker.invokeApi(basePath, path, "{{httpMethod}}", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - {{#returnType}} Some(apiInvoker.deserialize(s, "{{returnContainer}}", classOf[{{returnBaseType}}]).asInstanceOf[{{returnType}}]) - {{/returnType}} - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex + val await = Try(Await.result({{operationId}}Async({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None } } + /** + * {{summary}} asynchronously + * {{notes}} +{{#allParams}} * @param {{paramName}} {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}} +{{/allParams}} * @return Future({{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}) + */ + def {{operationId}}Async({{#allParams}}{{paramName}}: {{#required}}{{dataType}}{{#defaultValue}} /* = {{{defaultValue}}}*/{{/defaultValue}}{{/required}}{{^required}}Option[{{dataType}}]{{#defaultValue}} /* = {{{defaultValue}}}*/{{/defaultValue}}{{^defaultValue}} = None{{/defaultValue}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}){{#returnType}}: Future[{{returnType}}]{{/returnType}} = { + helper.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) + } + + {{/operation}} } + +class {{classname}}AsyncHelper(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) { + +{{#operation}} + def {{operationId}}({{#allParams}}{{^required}}{{paramName}}: Option[{{dataType}}] = {{#defaultValue}}Some({{defaultValue}}){{/defaultValue}}{{^defaultValue}}None{{/defaultValue}}{{#hasMore}},{{/hasMore}} + {{/required}}{{#required}}{{paramName}}: {{dataType}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{#hasMore}}, + {{/hasMore}}{{/required}}{{/allParams}})(implicit reader: ClientResponseReader[{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Unit{{/returnType}}]{{#bodyParams}}, writer: RequestWriter[{{dataType}}]{{/bodyParams}}){{#returnType}}: Future[{{returnType}}]{{/returnType}}{{^returnType}}: Future[Unit]{{/returnType}} = { + // create path and map variables + val path = (addFmt("{{path}}"){{#pathParams}} + replaceAll ("\\{" + "{{baseName}}" + "\\}",{{paramName}}.toString){{/pathParams}}) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + {{#allParams}} + {{#required}} + {{^isPrimitiveType}} + if ({{paramName}} == null) throw new Exception("Missing required parameter '{{paramName}}' when calling {{classname}}->{{operationId}}") + {{/isPrimitiveType}} + {{#isString}} + if ({{paramName}} == null) throw new Exception("Missing required parameter '{{paramName}}' when calling {{classname}}->{{operationId}}") + + {{/isString}} + {{/required}} + {{/allParams}} + {{#queryParams}} + {{^required}} + {{paramName}} match { + case Some(param) => queryParams += "{{baseName}}" -> param.toString + case _ => queryParams + } + {{/required}} + {{#required}} + queryParams += "{{baseName}}" -> {{paramName}}.toString + {{/required}} + {{/queryParams}} + {{#headerParams}} + {{^required}} + {{paramName}} match { + case Some(param) => headerParams += "{{baseName}}" -> param.toString + case _ => headerParams + } + {{/required}} + {{#required}} + headerParams += "{{baseName}}" -> {{paramName}}.toString + {{/required}} + {{/headerParams}} + + val resFuture = client.submit("{{httpMethod}}", path, queryParams.toMap, headerParams.toMap, {{#bodyParam}}writer.write({{paramName}}){{/bodyParam}}{{^bodyParam}}"{{emptyBodyParam}}"{{/bodyParam}}) + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + +{{/operation}} + +} {{/operations}} diff --git a/modules/swagger-codegen/src/main/resources/scala/build.gradle.mustache b/modules/swagger-codegen/src/main/resources/scala/build.gradle.mustache index 88faa3610b2d..e124eb0a5c78 100644 --- a/modules/swagger-codegen/src/main/resources/scala/build.gradle.mustache +++ b/modules/swagger-codegen/src/main/resources/scala/build.gradle.mustache @@ -104,6 +104,12 @@ ext { jackson_version = "2.4.2" junit_version = "4.8.1" scala_test_version = "2.2.4" + swagger_async_httpclient_version = "0.3.5" +} + +repositories { + mavenLocal() + mavenCentral() } dependencies { @@ -117,4 +123,5 @@ dependencies { testCompile "junit:junit:$junit_version" compile "joda-time:joda-time:$jodatime_version" compile "org.joda:joda-convert:$joda_version" + compile "com.wordnik.swagger:swagger-async-httpclient_2.10:$swagger_async_httpclient_version" } diff --git a/modules/swagger-codegen/src/main/resources/scala/build.sbt.mustache b/modules/swagger-codegen/src/main/resources/scala/build.sbt.mustache index 6a198acb832f..24ee01b6fd50 100644 --- a/modules/swagger-codegen/src/main/resources/scala/build.sbt.mustache +++ b/modules/swagger-codegen/src/main/resources/scala/build.sbt.mustache @@ -1,33 +1,34 @@ -lazy val root = (project in file(".")). - settings( - version := "{{artifactVersion}}", - name := "{{artifactId}}", - organization := "{{groupId}}", - scalaVersion := "2.11.8", +version := "{{artifactVersion}}" - libraryDependencies ++= Seq( - "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.4.2", - "com.sun.jersey" % "jersey-core" % "1.19", - "com.sun.jersey" % "jersey-client" % "1.19", - "com.sun.jersey.contribs" % "jersey-multipart" % "1.19", - "org.jfarcand" % "jersey-ahc-client" % "1.0.5", - "io.swagger" % "swagger-core" % "1.5.8", - "joda-time" % "joda-time" % "2.2", - "org.joda" % "joda-convert" % "1.2", - "org.scalatest" %% "scalatest" % "2.2.4" % "test", - "junit" % "junit" % "4.8.1" % "test" - ), +name := "{{artifactId}}" - resolvers ++= Seq( - Resolver.jcenterRepo, - Resolver.mavenLocal - ), +organization := "{{groupId}}" - scalacOptions := Seq( - "-unchecked", - "-deprecation", - "-feature" - ), +scalaVersion := "2.11.8" + +libraryDependencies ++= Seq( + "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.4.2", + "com.sun.jersey" % "jersey-core" % "1.19", + "com.sun.jersey" % "jersey-client" % "1.19", + "com.sun.jersey.contribs" % "jersey-multipart" % "1.19", + "org.jfarcand" % "jersey-ahc-client" % "1.0.5", + "io.swagger" % "swagger-core" % "1.5.8", + "joda-time" % "joda-time" % "2.2", + "org.joda" % "joda-convert" % "1.2", + "org.scalatest" %% "scalatest" % "2.2.4" % "test", + "junit" % "junit" % "4.8.1" % "test", + "com.wordnik.swagger" %% "swagger-async-httpclient" % "0.3.5" +) + +resolvers ++= Seq( + Resolver.mavenLocal +) + +scalacOptions := Seq( + "-unchecked", + "-deprecation", + "-feature" +) + +publishArtifact in (Compile, packageDoc) := false - publishArtifact in (Compile, packageDoc) := false - ) \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/scala/client.mustache b/modules/swagger-codegen/src/main/resources/scala/client.mustache new file mode 100644 index 000000000000..8098b73c6bbb --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/scala/client.mustache @@ -0,0 +1,22 @@ +package {{invokerPackage}} + +{{#imports}}import {{import}} +{{/imports}} +import {{apiPackage}}._ + +import com.wordnik.swagger.client._ + +import java.io.Closeable + +class {{clientName}}(config: SwaggerConfig) extends Closeable { + val locator = config.locator + val name = config.name + + private[this] val client = transportClient + + protected def transportClient: TransportClient = new RestClient(config) + + def close() { + client.close() + } +} diff --git a/modules/swagger-codegen/src/main/resources/scala/pom.mustache b/modules/swagger-codegen/src/main/resources/scala/pom.mustache index 11331dce41d3..d459d29a9750 100644 --- a/modules/swagger-codegen/src/main/resources/scala/pom.mustache +++ b/modules/swagger-codegen/src/main/resources/scala/pom.mustache @@ -209,6 +209,11 @@ joda-convert ${joda-version} + + com.wordnik.swagger + swagger-async-httpclient_2.10 + ${swagger-async-httpclient-version} + 2.10.4 @@ -223,6 +228,7 @@ 4.8.1 3.1.5 2.2.4 + 0.3.5 UTF-8 diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/scala/ScalaModelTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/scala/ScalaModelTest.java index 95e08c6b3621..57b9023b0776 100644 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/scala/ScalaModelTest.java +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/scala/ScalaModelTest.java @@ -66,10 +66,10 @@ public class ScalaModelTest { Assert.assertEquals(property3.baseName, "createdAt"); Assert.assertEquals(property3.getter, "getCreatedAt"); Assert.assertEquals(property3.setter, "setCreatedAt"); - Assert.assertEquals(property3.datatype, "DateTime"); + Assert.assertEquals(property3.datatype, "Date"); Assert.assertEquals(property3.name, "createdAt"); Assert.assertEquals(property3.defaultValue, "null"); - Assert.assertEquals(property3.baseType, "DateTime"); + Assert.assertEquals(property3.baseType, "Date"); Assert.assertFalse(property3.hasMore); Assert.assertFalse(property3.required); Assert.assertTrue(property3.isNotContainer); diff --git a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/SwaggerClient.scala b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/SwaggerClient.scala index f9f2e5d6216e..7c4afb20e093 100644 --- a/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/SwaggerClient.scala +++ b/samples/client/petstore/async-scala/src/main/scala/io/swagger/client/SwaggerClient.scala @@ -25,3 +25,4 @@ class SwaggerClient(config: SwaggerConfig) extends Closeable { client.close() } } + diff --git a/samples/client/petstore/scala/build.gradle b/samples/client/petstore/scala/build.gradle index 979db7783c43..707c4f9e988c 100644 --- a/samples/client/petstore/scala/build.gradle +++ b/samples/client/petstore/scala/build.gradle @@ -104,6 +104,12 @@ ext { jackson_version = "2.4.2" junit_version = "4.8.1" scala_test_version = "2.2.4" + swagger_async_httpclient_version = "0.3.5" +} + +repositories { + mavenLocal() + mavenCentral() } dependencies { @@ -117,4 +123,5 @@ dependencies { testCompile "junit:junit:$junit_version" compile "joda-time:joda-time:$jodatime_version" compile "org.joda:joda-convert:$joda_version" + compile "com.wordnik.swagger:swagger-async-httpclient_2.10:$swagger_async_httpclient_version" } diff --git a/samples/client/petstore/scala/build.sbt b/samples/client/petstore/scala/build.sbt index 063b2b0d4908..bececaf181b9 100644 --- a/samples/client/petstore/scala/build.sbt +++ b/samples/client/petstore/scala/build.sbt @@ -1,33 +1,34 @@ -lazy val root = (project in file(".")). - settings( - version := "1.0.0", - name := "swagger-scala-client", - organization := "io.swagger", - scalaVersion := "2.11.8", +version := "1.0.0" - libraryDependencies ++= Seq( - "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.4.2", - "com.sun.jersey" % "jersey-core" % "1.19", - "com.sun.jersey" % "jersey-client" % "1.19", - "com.sun.jersey.contribs" % "jersey-multipart" % "1.19", - "org.jfarcand" % "jersey-ahc-client" % "1.0.5", - "io.swagger" % "swagger-core" % "1.5.8", - "joda-time" % "joda-time" % "2.2", - "org.joda" % "joda-convert" % "1.2", - "org.scalatest" %% "scalatest" % "2.2.4" % "test", - "junit" % "junit" % "4.8.1" % "test" - ), +name := "swagger-scala-client" - resolvers ++= Seq( - Resolver.jcenterRepo, - Resolver.mavenLocal - ), +organization := "io.swagger" - scalacOptions := Seq( - "-unchecked", - "-deprecation", - "-feature" - ), +scalaVersion := "2.11.8" + +libraryDependencies ++= Seq( + "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.4.2", + "com.sun.jersey" % "jersey-core" % "1.19", + "com.sun.jersey" % "jersey-client" % "1.19", + "com.sun.jersey.contribs" % "jersey-multipart" % "1.19", + "org.jfarcand" % "jersey-ahc-client" % "1.0.5", + "io.swagger" % "swagger-core" % "1.5.8", + "joda-time" % "joda-time" % "2.2", + "org.joda" % "joda-convert" % "1.2", + "org.scalatest" %% "scalatest" % "2.2.4" % "test", + "junit" % "junit" % "4.8.1" % "test", + "com.wordnik.swagger" %% "swagger-async-httpclient" % "0.3.5" +) + +resolvers ++= Seq( + Resolver.mavenLocal +) + +scalacOptions := Seq( + "-unchecked", + "-deprecation", + "-feature" +) + +publishArtifact in (Compile, packageDoc) := false - publishArtifact in (Compile, packageDoc) := false - ) \ No newline at end of file diff --git a/samples/client/petstore/scala/pom.xml b/samples/client/petstore/scala/pom.xml index a54aac0067d1..02c83f264dfb 100644 --- a/samples/client/petstore/scala/pom.xml +++ b/samples/client/petstore/scala/pom.xml @@ -209,6 +209,11 @@ joda-convert ${joda-version} + + com.wordnik.swagger + swagger-async-httpclient_2.10 + ${swagger-async-httpclient-version} + 2.10.4 @@ -223,6 +228,7 @@ 4.8.1 3.1.5 2.2.4 + 0.3.5 UTF-8 diff --git a/samples/client/petstore/scala/src/main/scala/io/swagger/client/AsyncClient.scala b/samples/client/petstore/scala/src/main/scala/io/swagger/client/AsyncClient.scala new file mode 100644 index 000000000000..c518277f577e --- /dev/null +++ b/samples/client/petstore/scala/src/main/scala/io/swagger/client/AsyncClient.scala @@ -0,0 +1,20 @@ +package io.swagger.client + +import io.swagger.client.api._ + +import com.wordnik.swagger.client._ + +import java.io.Closeable + +class AsyncClient(config: SwaggerConfig) extends Closeable { + val locator = config.locator + val name = config.name + + private[this] val client = transportClient + + protected def transportClient: TransportClient = new RestClient(config) + + def close() { + client.close() + } +} diff --git a/samples/client/petstore/scala/src/main/scala/io/swagger/client/api/PetApi.scala b/samples/client/petstore/scala/src/main/scala/io/swagger/client/api/PetApi.scala index 3bcadab73c9d..2941fd914f49 100644 --- a/samples/client/petstore/scala/src/main/scala/io/swagger/client/api/PetApi.scala +++ b/samples/client/petstore/scala/src/main/scala/io/swagger/client/api/PetApi.scala @@ -12,11 +12,12 @@ package io.swagger.client.api +import java.text.SimpleDateFormat + import io.swagger.client.model.ApiResponse import java.io.File import io.swagger.client.model.Pet -import io.swagger.client.ApiInvoker -import io.swagger.client.ApiException +import io.swagger.client.{ApiInvoker, ApiException} import com.sun.jersey.multipart.FormDataMultiPart import com.sun.jersey.multipart.file.FileDataBodyPart @@ -28,12 +29,41 @@ import java.util.Date import scala.collection.mutable.HashMap +import com.wordnik.swagger.client._ +import scala.concurrent.Future +import collection.mutable + +import java.net.URI + +import com.wordnik.swagger.client.ClientResponseReaders.Json4sFormatsReader._ +import com.wordnik.swagger.client.RequestWriters.Json4sFormatsWriter._ + +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent._ +import scala.concurrent.duration._ +import scala.util.{Failure, Success, Try} + class PetApi(val defBasePath: String = "http://petstore.swagger.io/v2", defApiInvoker: ApiInvoker = ApiInvoker) { + + implicit val formats = new org.json4s.DefaultFormats { + override def dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS+0000") + } + implicit val stringReader = ClientResponseReaders.StringReader + implicit val unitReader = ClientResponseReaders.UnitReader + implicit val jvalueReader = ClientResponseReaders.JValueReader + implicit val jsonReader = JsonFormatsReader + implicit val stringWriter = RequestWriters.StringWriter + implicit val jsonWriter = JsonFormatsWriter + var basePath = defBasePath var apiInvoker = defApiInvoker - def addHeader(key: String, value: String) = apiInvoker.defaultHeaders += key -> value + def addHeader(key: String, value: String) = apiInvoker.defaultHeaders += key -> value + + val config = SwaggerConfig.forUrl(new URI(defBasePath)) + val client = new RestClient(config) + val helper = new PetApiAsyncHelper(client, config) /** * Add a new pet to the store @@ -42,39 +72,25 @@ class PetApi(val defBasePath: String = "http://petstore.swagger.io/v2", * @return void */ def addPet(body: Pet) = { - // create path and map variables - val path = "/pet".replaceAll("\\{format\\}", "json") - - val contentTypes = List("application/json", "application/xml") - val contentType = contentTypes(0) - - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] - - if (body == null) throw new Exception("Missing required parameter 'body' when calling PetApi->addPet") - - - - var postBody: AnyRef = body - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - postBody = mp - } else { + val await = Try(Await.result(addPetAsync(body), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None } - try { - apiInvoker.invokeApi(basePath, path, "POST", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex - } } + /** + * Add a new pet to the store asynchronously + * + * @param body Pet object that needs to be added to the store + * @return Future(void) + */ + def addPetAsync(body: Pet) = { + helper.addPet(body) + } + + /** * Deletes a pet * @@ -83,38 +99,26 @@ class PetApi(val defBasePath: String = "http://petstore.swagger.io/v2", * @return void */ def deletePet(petId: Long, apiKey: Option[String] = None) = { - // create path and map variables - val path = "/pet/{petId}".replaceAll("\\{format\\}", "json").replaceAll("\\{" + "petId" + "\\}",apiInvoker.escape(petId)) - - val contentTypes = List("application/json") - val contentType = contentTypes(0) - - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] - - - apiKey.map(paramVal => headerParams += "api_key" -> paramVal) - - var postBody: AnyRef = null - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - postBody = mp - } else { + val await = Try(Await.result(deletePetAsync(petId, apiKey), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None } - try { - apiInvoker.invokeApi(basePath, path, "DELETE", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex - } } + /** + * Deletes a pet asynchronously + * + * @param petId Pet id to delete + * @param apiKey (optional) + * @return Future(void) + */ + def deletePetAsync(petId: Long, apiKey: Option[String] = None) = { + helper.deletePet(petId, apiKey) + } + + /** * Finds Pets by status * Multiple status values can be provided with comma separated strings @@ -122,41 +126,25 @@ class PetApi(val defBasePath: String = "http://petstore.swagger.io/v2", * @return List[Pet] */ def findPetsByStatus(status: List[String]): Option[List[Pet]] = { - // create path and map variables - val path = "/pet/findByStatus".replaceAll("\\{format\\}", "json") - - val contentTypes = List("application/json") - val contentType = contentTypes(0) - - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] - - if (status == null) throw new Exception("Missing required parameter 'status' when calling PetApi->findPetsByStatus") - - queryParams += "status" -> status.toString - - - var postBody: AnyRef = null - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - postBody = mp - } else { + val await = Try(Await.result(findPetsByStatusAsync(status), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None } - try { - apiInvoker.invokeApi(basePath, path, "GET", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - Some(apiInvoker.deserialize(s, "array", classOf[Pet]).asInstanceOf[List[Pet]]) - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex - } } + /** + * Finds Pets by status asynchronously + * Multiple status values can be provided with comma separated strings + * @param status Status values that need to be considered for filter + * @return Future(List[Pet]) + */ + def findPetsByStatusAsync(status: List[String]): Future[List[Pet]] = { + helper.findPetsByStatus(status) + } + + /** * Finds Pets by tags * Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. @@ -164,41 +152,25 @@ class PetApi(val defBasePath: String = "http://petstore.swagger.io/v2", * @return List[Pet] */ def findPetsByTags(tags: List[String]): Option[List[Pet]] = { - // create path and map variables - val path = "/pet/findByTags".replaceAll("\\{format\\}", "json") - - val contentTypes = List("application/json") - val contentType = contentTypes(0) - - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] - - if (tags == null) throw new Exception("Missing required parameter 'tags' when calling PetApi->findPetsByTags") - - queryParams += "tags" -> tags.toString - - - var postBody: AnyRef = null - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - postBody = mp - } else { + val await = Try(Await.result(findPetsByTagsAsync(tags), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None } - try { - apiInvoker.invokeApi(basePath, path, "GET", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - Some(apiInvoker.deserialize(s, "array", classOf[Pet]).asInstanceOf[List[Pet]]) - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex - } } + /** + * Finds Pets by tags asynchronously + * Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. + * @param tags Tags to filter by + * @return Future(List[Pet]) + */ + def findPetsByTagsAsync(tags: List[String]): Future[List[Pet]] = { + helper.findPetsByTags(tags) + } + + /** * Find pet by ID * Returns a single pet @@ -206,38 +178,25 @@ class PetApi(val defBasePath: String = "http://petstore.swagger.io/v2", * @return Pet */ def getPetById(petId: Long): Option[Pet] = { - // create path and map variables - val path = "/pet/{petId}".replaceAll("\\{format\\}", "json").replaceAll("\\{" + "petId" + "\\}",apiInvoker.escape(petId)) - - val contentTypes = List("application/json") - val contentType = contentTypes(0) - - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] - - - - var postBody: AnyRef = null - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - postBody = mp - } else { + val await = Try(Await.result(getPetByIdAsync(petId), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None } - try { - apiInvoker.invokeApi(basePath, path, "GET", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - Some(apiInvoker.deserialize(s, "", classOf[Pet]).asInstanceOf[Pet]) - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex - } } + /** + * Find pet by ID asynchronously + * Returns a single pet + * @param petId ID of pet to return + * @return Future(Pet) + */ + def getPetByIdAsync(petId: Long): Future[Pet] = { + helper.getPetById(petId) + } + + /** * Update an existing pet * @@ -245,39 +204,25 @@ class PetApi(val defBasePath: String = "http://petstore.swagger.io/v2", * @return void */ def updatePet(body: Pet) = { - // create path and map variables - val path = "/pet".replaceAll("\\{format\\}", "json") - - val contentTypes = List("application/json", "application/xml") - val contentType = contentTypes(0) - - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] - - if (body == null) throw new Exception("Missing required parameter 'body' when calling PetApi->updatePet") - - - - var postBody: AnyRef = body - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - postBody = mp - } else { + val await = Try(Await.result(updatePetAsync(body), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None } - try { - apiInvoker.invokeApi(basePath, path, "PUT", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex - } } + /** + * Update an existing pet asynchronously + * + * @param body Pet object that needs to be added to the store + * @return Future(void) + */ + def updatePetAsync(body: Pet) = { + helper.updatePet(body) + } + + /** * Updates a pet in the store with form data * @@ -287,41 +232,27 @@ class PetApi(val defBasePath: String = "http://petstore.swagger.io/v2", * @return void */ def updatePetWithForm(petId: Long, name: Option[String] = None, status: Option[String] = None) = { - // create path and map variables - val path = "/pet/{petId}".replaceAll("\\{format\\}", "json").replaceAll("\\{" + "petId" + "\\}",apiInvoker.escape(petId)) - - val contentTypes = List("application/x-www-form-urlencoded") - val contentType = contentTypes(0) - - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] - - - - var postBody: AnyRef = null - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - name.map(paramVal => mp.field("name", paramVal.toString, MediaType.MULTIPART_FORM_DATA_TYPE)) - status.map(paramVal => mp.field("status", paramVal.toString, MediaType.MULTIPART_FORM_DATA_TYPE)) - postBody = mp - } else { - name.map(paramVal => formParams += "name" -> paramVal.toString) - status.map(paramVal => formParams += "status" -> paramVal.toString) + val await = Try(Await.result(updatePetWithFormAsync(petId, name, status), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None } - try { - apiInvoker.invokeApi(basePath, path, "POST", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex - } } + /** + * Updates a pet in the store with form data asynchronously + * + * @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 Future(void) + */ + def updatePetWithFormAsync(petId: Long, name: Option[String] = None, status: Option[String] = None) = { + helper.updatePetWithForm(petId, name, status) + } + + /** * uploads an image * @@ -331,40 +262,172 @@ class PetApi(val defBasePath: String = "http://petstore.swagger.io/v2", * @return ApiResponse */ def uploadFile(petId: Long, additionalMetadata: Option[String] = None, file: Option[File] = None): Option[ApiResponse] = { - // create path and map variables - val path = "/pet/{petId}/uploadImage".replaceAll("\\{format\\}", "json").replaceAll("\\{" + "petId" + "\\}",apiInvoker.escape(petId)) - - val contentTypes = List("multipart/form-data") - val contentType = contentTypes(0) - - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] - - - - var postBody: AnyRef = null - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - additionalMetadata.map(paramVal => mp.field("additionalMetadata", paramVal.toString, MediaType.MULTIPART_FORM_DATA_TYPE)) - file.map(fileVal => mp.field("file", fileVal.getName)) - file.map(paramVal => mp.bodyPart(new FileDataBodyPart("file", paramVal, MediaType.MULTIPART_FORM_DATA_TYPE))) - postBody = mp - } else { - additionalMetadata.map(paramVal => formParams += "additionalMetadata" -> paramVal.toString) + val await = Try(Await.result(uploadFileAsync(petId, additionalMetadata, file), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None } - try { - apiInvoker.invokeApi(basePath, path, "POST", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - Some(apiInvoker.deserialize(s, "", classOf[ApiResponse]).asInstanceOf[ApiResponse]) - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex + } + + /** + * uploads an image asynchronously + * + * @param petId ID of pet to update + * @param additionalMetadata Additional data to pass to server (optional) + * @param file file to upload (optional) + * @return Future(ApiResponse) + */ + def uploadFileAsync(petId: Long, additionalMetadata: Option[String] = None, file: Option[File] = None): Future[ApiResponse] = { + helper.uploadFile(petId, additionalMetadata, file) + } + + +} + +class PetApiAsyncHelper(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) { + + def addPet(body: Pet)(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[Pet]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/pet")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + if (body == null) throw new Exception("Missing required parameter 'body' when calling PetApi->addPet") + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) } } + def deletePet(petId: Long, + apiKey: Option[String] = None + )(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/pet/{petId}") + replaceAll ("\\{" + "petId" + "\\}",petId.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + apiKey match { + case Some(param) => headerParams += "api_key" -> param.toString + case _ => headerParams + } + + val resFuture = client.submit("DELETE", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + def findPetsByStatus(status: List[String])(implicit reader: ClientResponseReader[List[Pet]]): Future[List[Pet]] = { + // create path and map variables + val path = (addFmt("/pet/findByStatus")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + if (status == null) throw new Exception("Missing required parameter 'status' when calling PetApi->findPetsByStatus") + queryParams += "status" -> status.toString + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + def findPetsByTags(tags: List[String])(implicit reader: ClientResponseReader[List[Pet]]): Future[List[Pet]] = { + // create path and map variables + val path = (addFmt("/pet/findByTags")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + if (tags == null) throw new Exception("Missing required parameter 'tags' when calling PetApi->findPetsByTags") + queryParams += "tags" -> tags.toString + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + def getPetById(petId: Long)(implicit reader: ClientResponseReader[Pet]): Future[Pet] = { + // create path and map variables + val path = (addFmt("/pet/{petId}") + replaceAll ("\\{" + "petId" + "\\}",petId.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + def updatePet(body: Pet)(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[Pet]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/pet")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + if (body == null) throw new Exception("Missing required parameter 'body' when calling PetApi->updatePet") + + val resFuture = client.submit("PUT", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + def updatePetWithForm(petId: Long, + name: Option[String] = None, + status: Option[String] = None + )(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/pet/{petId}") + replaceAll ("\\{" + "petId" + "\\}",petId.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + def uploadFile(petId: Long, + additionalMetadata: Option[String] = None, + file: Option[File] = None + )(implicit reader: ClientResponseReader[ApiResponse]): Future[ApiResponse] = { + // create path and map variables + val path = (addFmt("/pet/{petId}/uploadImage") + replaceAll ("\\{" + "petId" + "\\}",petId.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + } diff --git a/samples/client/petstore/scala/src/main/scala/io/swagger/client/api/StoreApi.scala b/samples/client/petstore/scala/src/main/scala/io/swagger/client/api/StoreApi.scala index 3f72757f9eb9..cb2ebf47255c 100644 --- a/samples/client/petstore/scala/src/main/scala/io/swagger/client/api/StoreApi.scala +++ b/samples/client/petstore/scala/src/main/scala/io/swagger/client/api/StoreApi.scala @@ -12,9 +12,10 @@ package io.swagger.client.api +import java.text.SimpleDateFormat + import io.swagger.client.model.Order -import io.swagger.client.ApiInvoker -import io.swagger.client.ApiException +import io.swagger.client.{ApiInvoker, ApiException} import com.sun.jersey.multipart.FormDataMultiPart import com.sun.jersey.multipart.file.FileDataBodyPart @@ -26,12 +27,41 @@ import java.util.Date import scala.collection.mutable.HashMap +import com.wordnik.swagger.client._ +import scala.concurrent.Future +import collection.mutable + +import java.net.URI + +import com.wordnik.swagger.client.ClientResponseReaders.Json4sFormatsReader._ +import com.wordnik.swagger.client.RequestWriters.Json4sFormatsWriter._ + +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent._ +import scala.concurrent.duration._ +import scala.util.{Failure, Success, Try} + class StoreApi(val defBasePath: String = "http://petstore.swagger.io/v2", defApiInvoker: ApiInvoker = ApiInvoker) { + + implicit val formats = new org.json4s.DefaultFormats { + override def dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS+0000") + } + implicit val stringReader = ClientResponseReaders.StringReader + implicit val unitReader = ClientResponseReaders.UnitReader + implicit val jvalueReader = ClientResponseReaders.JValueReader + implicit val jsonReader = JsonFormatsReader + implicit val stringWriter = RequestWriters.StringWriter + implicit val jsonWriter = JsonFormatsWriter + var basePath = defBasePath var apiInvoker = defApiInvoker - def addHeader(key: String, value: String) = apiInvoker.defaultHeaders += key -> value + def addHeader(key: String, value: String) = apiInvoker.defaultHeaders += key -> value + + val config = SwaggerConfig.forUrl(new URI(defBasePath)) + val client = new RestClient(config) + val helper = new StoreApiAsyncHelper(client, config) /** * Delete purchase order by ID @@ -40,77 +70,49 @@ class StoreApi(val defBasePath: String = "http://petstore.swagger.io/v2", * @return void */ def deleteOrder(orderId: String) = { - // create path and map variables - val path = "/store/order/{orderId}".replaceAll("\\{format\\}", "json").replaceAll("\\{" + "orderId" + "\\}",apiInvoker.escape(orderId)) - - val contentTypes = List("application/json") - val contentType = contentTypes(0) - - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] - - if (orderId == null) throw new Exception("Missing required parameter 'orderId' when calling StoreApi->deleteOrder") - - - - var postBody: AnyRef = null - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - postBody = mp - } else { + val await = Try(Await.result(deleteOrderAsync(orderId), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None } - try { - apiInvoker.invokeApi(basePath, path, "DELETE", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex - } } + /** + * Delete purchase order by ID asynchronously + * 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 Future(void) + */ + def deleteOrderAsync(orderId: String) = { + helper.deleteOrder(orderId) + } + + /** * Returns pet inventories by status * Returns a map of status codes to quantities * @return Map[String, Integer] */ def getInventory(): Option[Map[String, Integer]] = { - // create path and map variables - val path = "/store/inventory".replaceAll("\\{format\\}", "json") - - val contentTypes = List("application/json") - val contentType = contentTypes(0) - - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] - - - - var postBody: AnyRef = null - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - postBody = mp - } else { + val await = Try(Await.result(getInventoryAsync(), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None } - try { - apiInvoker.invokeApi(basePath, path, "GET", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - Some(apiInvoker.deserialize(s, "map", classOf[Integer]).asInstanceOf[Map[String, Integer]]) - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex - } } + /** + * Returns pet inventories by status asynchronously + * Returns a map of status codes to quantities + * @return Future(Map[String, Integer]) + */ + def getInventoryAsync(): Future[Map[String, Integer]] = { + helper.getInventory() + } + + /** * Find purchase order by ID * For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions @@ -118,38 +120,25 @@ class StoreApi(val defBasePath: String = "http://petstore.swagger.io/v2", * @return Order */ def getOrderById(orderId: Long): Option[Order] = { - // create path and map variables - val path = "/store/order/{orderId}".replaceAll("\\{format\\}", "json").replaceAll("\\{" + "orderId" + "\\}",apiInvoker.escape(orderId)) - - val contentTypes = List("application/json") - val contentType = contentTypes(0) - - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] - - - - var postBody: AnyRef = null - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - postBody = mp - } else { + val await = Try(Await.result(getOrderByIdAsync(orderId), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None } - try { - apiInvoker.invokeApi(basePath, path, "GET", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - Some(apiInvoker.deserialize(s, "", classOf[Order]).asInstanceOf[Order]) - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex - } } + /** + * Find purchase order by ID asynchronously + * 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 Future(Order) + */ + def getOrderByIdAsync(orderId: Long): Future[Order] = { + helper.getOrderById(orderId) + } + + /** * Place an order for a pet * @@ -157,38 +146,93 @@ class StoreApi(val defBasePath: String = "http://petstore.swagger.io/v2", * @return Order */ def placeOrder(body: Order): Option[Order] = { - // create path and map variables - val path = "/store/order".replaceAll("\\{format\\}", "json") - - val contentTypes = List("application/json") - val contentType = contentTypes(0) - - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] - - if (body == null) throw new Exception("Missing required parameter 'body' when calling StoreApi->placeOrder") - - - - var postBody: AnyRef = body - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - postBody = mp - } else { + val await = Try(Await.result(placeOrderAsync(body), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None } - try { - apiInvoker.invokeApi(basePath, path, "POST", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - Some(apiInvoker.deserialize(s, "", classOf[Order]).asInstanceOf[Order]) - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex + } + + /** + * Place an order for a pet asynchronously + * + * @param body order placed for purchasing the pet + * @return Future(Order) + */ + def placeOrderAsync(body: Order): Future[Order] = { + helper.placeOrder(body) + } + + +} + +class StoreApiAsyncHelper(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) { + + def deleteOrder(orderId: String)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/store/order/{orderId}") + replaceAll ("\\{" + "orderId" + "\\}",orderId.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + if (orderId == null) throw new Exception("Missing required parameter 'orderId' when calling StoreApi->deleteOrder") + + + val resFuture = client.submit("DELETE", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) } } + def getInventory()(implicit reader: ClientResponseReader[Map[String, Integer]]): Future[Map[String, Integer]] = { + // create path and map variables + val path = (addFmt("/store/inventory")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + def getOrderById(orderId: Long)(implicit reader: ClientResponseReader[Order]): Future[Order] = { + // create path and map variables + val path = (addFmt("/store/order/{orderId}") + replaceAll ("\\{" + "orderId" + "\\}",orderId.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + def placeOrder(body: Order)(implicit reader: ClientResponseReader[Order], writer: RequestWriter[Order]): Future[Order] = { + // create path and map variables + val path = (addFmt("/store/order")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + if (body == null) throw new Exception("Missing required parameter 'body' when calling StoreApi->placeOrder") + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + } diff --git a/samples/client/petstore/scala/src/main/scala/io/swagger/client/api/UserApi.scala b/samples/client/petstore/scala/src/main/scala/io/swagger/client/api/UserApi.scala index df039c1f7cc0..7893cc266772 100644 --- a/samples/client/petstore/scala/src/main/scala/io/swagger/client/api/UserApi.scala +++ b/samples/client/petstore/scala/src/main/scala/io/swagger/client/api/UserApi.scala @@ -12,9 +12,10 @@ package io.swagger.client.api +import java.text.SimpleDateFormat + import io.swagger.client.model.User -import io.swagger.client.ApiInvoker -import io.swagger.client.ApiException +import io.swagger.client.{ApiInvoker, ApiException} import com.sun.jersey.multipart.FormDataMultiPart import com.sun.jersey.multipart.file.FileDataBodyPart @@ -26,12 +27,41 @@ import java.util.Date import scala.collection.mutable.HashMap +import com.wordnik.swagger.client._ +import scala.concurrent.Future +import collection.mutable + +import java.net.URI + +import com.wordnik.swagger.client.ClientResponseReaders.Json4sFormatsReader._ +import com.wordnik.swagger.client.RequestWriters.Json4sFormatsWriter._ + +import scala.concurrent.ExecutionContext.Implicits.global +import scala.concurrent._ +import scala.concurrent.duration._ +import scala.util.{Failure, Success, Try} + class UserApi(val defBasePath: String = "http://petstore.swagger.io/v2", defApiInvoker: ApiInvoker = ApiInvoker) { + + implicit val formats = new org.json4s.DefaultFormats { + override def dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS+0000") + } + implicit val stringReader = ClientResponseReaders.StringReader + implicit val unitReader = ClientResponseReaders.UnitReader + implicit val jvalueReader = ClientResponseReaders.JValueReader + implicit val jsonReader = JsonFormatsReader + implicit val stringWriter = RequestWriters.StringWriter + implicit val jsonWriter = JsonFormatsWriter + var basePath = defBasePath var apiInvoker = defApiInvoker - def addHeader(key: String, value: String) = apiInvoker.defaultHeaders += key -> value + def addHeader(key: String, value: String) = apiInvoker.defaultHeaders += key -> value + + val config = SwaggerConfig.forUrl(new URI(defBasePath)) + val client = new RestClient(config) + val helper = new UserApiAsyncHelper(client, config) /** * Create user @@ -40,39 +70,25 @@ class UserApi(val defBasePath: String = "http://petstore.swagger.io/v2", * @return void */ def createUser(body: User) = { - // create path and map variables - val path = "/user".replaceAll("\\{format\\}", "json") - - val contentTypes = List("application/json") - val contentType = contentTypes(0) - - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] - - if (body == null) throw new Exception("Missing required parameter 'body' when calling UserApi->createUser") - - - - var postBody: AnyRef = body - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - postBody = mp - } else { + val await = Try(Await.result(createUserAsync(body), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None } - try { - apiInvoker.invokeApi(basePath, path, "POST", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex - } } + /** + * Create user asynchronously + * This can only be done by the logged in user. + * @param body Created user object + * @return Future(void) + */ + def createUserAsync(body: User) = { + helper.createUser(body) + } + + /** * Creates list of users with given input array * @@ -80,39 +96,25 @@ class UserApi(val defBasePath: String = "http://petstore.swagger.io/v2", * @return void */ def createUsersWithArrayInput(body: List[User]) = { - // create path and map variables - val path = "/user/createWithArray".replaceAll("\\{format\\}", "json") - - val contentTypes = List("application/json") - val contentType = contentTypes(0) - - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] - - if (body == null) throw new Exception("Missing required parameter 'body' when calling UserApi->createUsersWithArrayInput") - - - - var postBody: AnyRef = body - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - postBody = mp - } else { + val await = Try(Await.result(createUsersWithArrayInputAsync(body), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None } - try { - apiInvoker.invokeApi(basePath, path, "POST", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex - } } + /** + * Creates list of users with given input array asynchronously + * + * @param body List of user object + * @return Future(void) + */ + def createUsersWithArrayInputAsync(body: List[User]) = { + helper.createUsersWithArrayInput(body) + } + + /** * Creates list of users with given input array * @@ -120,39 +122,25 @@ class UserApi(val defBasePath: String = "http://petstore.swagger.io/v2", * @return void */ def createUsersWithListInput(body: List[User]) = { - // create path and map variables - val path = "/user/createWithList".replaceAll("\\{format\\}", "json") - - val contentTypes = List("application/json") - val contentType = contentTypes(0) - - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] - - if (body == null) throw new Exception("Missing required parameter 'body' when calling UserApi->createUsersWithListInput") - - - - var postBody: AnyRef = body - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - postBody = mp - } else { + val await = Try(Await.result(createUsersWithListInputAsync(body), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None } - try { - apiInvoker.invokeApi(basePath, path, "POST", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex - } } + /** + * Creates list of users with given input array asynchronously + * + * @param body List of user object + * @return Future(void) + */ + def createUsersWithListInputAsync(body: List[User]) = { + helper.createUsersWithListInput(body) + } + + /** * Delete user * This can only be done by the logged in user. @@ -160,39 +148,25 @@ class UserApi(val defBasePath: String = "http://petstore.swagger.io/v2", * @return void */ def deleteUser(username: String) = { - // create path and map variables - val path = "/user/{username}".replaceAll("\\{format\\}", "json").replaceAll("\\{" + "username" + "\\}",apiInvoker.escape(username)) - - val contentTypes = List("application/json") - val contentType = contentTypes(0) - - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] - - if (username == null) throw new Exception("Missing required parameter 'username' when calling UserApi->deleteUser") - - - - var postBody: AnyRef = null - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - postBody = mp - } else { + val await = Try(Await.result(deleteUserAsync(username), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None } - try { - apiInvoker.invokeApi(basePath, path, "DELETE", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex - } } + /** + * Delete user asynchronously + * This can only be done by the logged in user. + * @param username The name that needs to be deleted + * @return Future(void) + */ + def deleteUserAsync(username: String) = { + helper.deleteUser(username) + } + + /** * Get user by user name * @@ -200,40 +174,25 @@ class UserApi(val defBasePath: String = "http://petstore.swagger.io/v2", * @return User */ def getUserByName(username: String): Option[User] = { - // create path and map variables - val path = "/user/{username}".replaceAll("\\{format\\}", "json").replaceAll("\\{" + "username" + "\\}",apiInvoker.escape(username)) - - val contentTypes = List("application/json") - val contentType = contentTypes(0) - - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] - - if (username == null) throw new Exception("Missing required parameter 'username' when calling UserApi->getUserByName") - - - - var postBody: AnyRef = null - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - postBody = mp - } else { + val await = Try(Await.result(getUserByNameAsync(username), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None } - try { - apiInvoker.invokeApi(basePath, path, "GET", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - Some(apiInvoker.deserialize(s, "", classOf[User]).asInstanceOf[User]) - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex - } } + /** + * Get user by user name asynchronously + * + * @param username The name that needs to be fetched. Use user1 for testing. + * @return Future(User) + */ + def getUserByNameAsync(username: String): Future[User] = { + helper.getUserByName(username) + } + + /** * Logs user into the system * @@ -242,81 +201,50 @@ class UserApi(val defBasePath: String = "http://petstore.swagger.io/v2", * @return String */ def loginUser(username: String, password: String): Option[String] = { - // create path and map variables - val path = "/user/login".replaceAll("\\{format\\}", "json") - - val contentTypes = List("application/json") - val contentType = contentTypes(0) - - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] - - if (username == null) throw new Exception("Missing required parameter 'username' when calling UserApi->loginUser") - - if (password == null) throw new Exception("Missing required parameter 'password' when calling UserApi->loginUser") - - queryParams += "username" -> username.toString - queryParams += "password" -> password.toString - - - var postBody: AnyRef = null - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - postBody = mp - } else { + val await = Try(Await.result(loginUserAsync(username, password), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None } - try { - apiInvoker.invokeApi(basePath, path, "GET", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - Some(apiInvoker.deserialize(s, "", classOf[String]).asInstanceOf[String]) - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex - } } + /** + * Logs user into the system asynchronously + * + * @param username The user name for login + * @param password The password for login in clear text + * @return Future(String) + */ + def loginUserAsync(username: String, password: String): Future[String] = { + helper.loginUser(username, password) + } + + /** * Logs out current logged in user session * * @return void */ def logoutUser() = { - // create path and map variables - val path = "/user/logout".replaceAll("\\{format\\}", "json") - - val contentTypes = List("application/json") - val contentType = contentTypes(0) - - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] - - - - var postBody: AnyRef = null - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - postBody = mp - } else { + val await = Try(Await.result(logoutUserAsync(), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None } - try { - apiInvoker.invokeApi(basePath, path, "GET", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex - } } + /** + * Logs out current logged in user session asynchronously + * + * @return Future(void) + */ + def logoutUserAsync() = { + helper.logoutUser() + } + + /** * Updated user * This can only be done by the logged in user. @@ -325,39 +253,170 @@ class UserApi(val defBasePath: String = "http://petstore.swagger.io/v2", * @return void */ def updateUser(username: String, body: User) = { + val await = Try(Await.result(updateUserAsync(username, body), Duration.Inf)) + await match { + case Success(i) => Some(await.get) + case Failure(t) => None + } + + } + + /** + * Updated user asynchronously + * This can only be done by the logged in user. + * @param username name that need to be deleted + * @param body Updated user object + * @return Future(void) + */ + def updateUserAsync(username: String, body: User) = { + helper.updateUser(username, body) + } + + +} + +class UserApiAsyncHelper(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) { + + def createUser(body: User)(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[User]): Future[Unit] = { // create path and map variables - val path = "/user/{username}".replaceAll("\\{format\\}", "json").replaceAll("\\{" + "username" + "\\}",apiInvoker.escape(username)) + val path = (addFmt("/user")) - val contentTypes = List("application/json") - val contentType = contentTypes(0) + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] - val queryParams = new HashMap[String, String] - val headerParams = new HashMap[String, String] - val formParams = new HashMap[String, String] + if (body == null) throw new Exception("Missing required parameter 'body' when calling UserApi->createUser") + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + def createUsersWithArrayInput(body: List[User])(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[List[User]]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/user/createWithArray")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + if (body == null) throw new Exception("Missing required parameter 'body' when calling UserApi->createUsersWithArrayInput") + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + def createUsersWithListInput(body: List[User])(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[List[User]]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/user/createWithList")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + if (body == null) throw new Exception("Missing required parameter 'body' when calling UserApi->createUsersWithListInput") + + val resFuture = client.submit("POST", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + def deleteUser(username: String)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/user/{username}") + replaceAll ("\\{" + "username" + "\\}",username.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + if (username == null) throw new Exception("Missing required parameter 'username' when calling UserApi->deleteUser") + + + val resFuture = client.submit("DELETE", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + def getUserByName(username: String)(implicit reader: ClientResponseReader[User]): Future[User] = { + // create path and map variables + val path = (addFmt("/user/{username}") + replaceAll ("\\{" + "username" + "\\}",username.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + if (username == null) throw new Exception("Missing required parameter 'username' when calling UserApi->getUserByName") + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + def loginUser(username: String, + password: String)(implicit reader: ClientResponseReader[String]): Future[String] = { + // create path and map variables + val path = (addFmt("/user/login")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + if (username == null) throw new Exception("Missing required parameter 'username' when calling UserApi->loginUser") + + if (password == null) throw new Exception("Missing required parameter 'password' when calling UserApi->loginUser") + + queryParams += "username" -> username.toString + queryParams += "password" -> password.toString + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + def logoutUser()(implicit reader: ClientResponseReader[Unit]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/user/logout")) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] + + + val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "") + resFuture flatMap { resp => + process(reader.read(resp)) + } + } + + def updateUser(username: String, + body: User)(implicit reader: ClientResponseReader[Unit], writer: RequestWriter[User]): Future[Unit] = { + // create path and map variables + val path = (addFmt("/user/{username}") + replaceAll ("\\{" + "username" + "\\}",username.toString)) + + // query params + val queryParams = new mutable.HashMap[String, String] + val headerParams = new mutable.HashMap[String, String] if (username == null) throw new Exception("Missing required parameter 'username' when calling UserApi->updateUser") if (body == null) throw new Exception("Missing required parameter 'body' when calling UserApi->updateUser") - - - var postBody: AnyRef = body - - if (contentType.startsWith("multipart/form-data")) { - val mp = new FormDataMultiPart - postBody = mp - } else { - } - - try { - apiInvoker.invokeApi(basePath, path, "PUT", queryParams.toMap, formParams.toMap, postBody, headerParams.toMap, contentType) match { - case s: String => - case _ => None - } - } catch { - case ex: ApiException if ex.code == 404 => None - case ex: ApiException => throw ex + val resFuture = client.submit("PUT", path, queryParams.toMap, headerParams.toMap, writer.write(body)) + resFuture flatMap { resp => + process(reader.read(resp)) } } + } diff --git a/samples/client/petstore/scala/src/main/scala/io/swagger/client/model/Order.scala b/samples/client/petstore/scala/src/main/scala/io/swagger/client/model/Order.scala index a88c0ec23d92..84691796eaf5 100644 --- a/samples/client/petstore/scala/src/main/scala/io/swagger/client/model/Order.scala +++ b/samples/client/petstore/scala/src/main/scala/io/swagger/client/model/Order.scala @@ -12,13 +12,13 @@ package io.swagger.client.model -import org.joda.time.DateTime +import java.util.Date case class Order ( id: Option[Long], petId: Option[Long], quantity: Option[Integer], - shipDate: Option[DateTime], + shipDate: Option[Date], /* Order Status */ status: Option[String], complete: Option[Boolean] diff --git a/samples/client/petstore/scala/src/test/scala/StoreApiTest.scala b/samples/client/petstore/scala/src/test/scala/StoreApiTest.scala index 4c1a06f1cb6f..78932dc10a3d 100644 --- a/samples/client/petstore/scala/src/test/scala/StoreApiTest.scala +++ b/samples/client/petstore/scala/src/test/scala/StoreApiTest.scala @@ -1,7 +1,8 @@ import io.swagger.client._ import io.swagger.client.api._ import io.swagger.client.model._ - +import org.joda.time.DateTime + import org.junit.runner.RunWith import org.scalatest.junit.JUnitRunner import org.scalatest._ @@ -9,6 +10,7 @@ import org.scalatest._ import scala.collection.mutable.{ ListBuffer, HashMap } import scala.collection.JavaConverters._ import scala.beans.BeanProperty +import java.util.Date @RunWith(classOf[JUnitRunner]) class StoreApiTest extends FlatSpec with Matchers { @@ -18,7 +20,7 @@ class StoreApiTest extends FlatSpec with Matchers { api.apiInvoker.defaultHeaders += "api_key" -> "special-key" it should "place and fetch an order" in { - val now = new org.joda.time.DateTime + val now = new Date() val order = Order( petId = Some(10), id = Some(1000), @@ -31,18 +33,17 @@ class StoreApiTest extends FlatSpec with Matchers { api.getOrderById(1000) match { case Some(order) => { - order.id should be(Some(1000)) - order.petId should be(Some(10)) - order.quantity should be(Some(101)) - // use `getMillis` to compare across timezones - order.shipDate.get.getMillis.equals(now.getMillis) should be(true) + order.id.get should be(1000) + order.petId.get should be(10) + order.quantity.get should be(101) + order.shipDate.get.getTime().equals(now.getTime()) should be(true) } case None => fail("didn't find order created") } } it should "delete an order" in { - val now = new org.joda.time.DateTime + val now = new Date() val order = Order( id = Some(1001), petId = Some(10), @@ -59,6 +60,7 @@ class StoreApiTest extends FlatSpec with Matchers { } api.deleteOrder("1001") + val x = api.getOrderById(1001) api.getOrderById(1001) match { case Some(order) => fail("order should have been deleted") case None =>