Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,9 @@ public ScalaClientCodegen() {
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");
typeMapping.put("binary", "Array[Byte]");
typeMapping.put("ByteArray", "Array[Byte]");
typeMapping.put("date-time", "Date");
// typeMapping.put("date", "Date");
// typeMapping.put("Date", "Date");
typeMapping.put("DateTime", "Date");

instantiationTypes.put("array", "ListBuffer");
Expand Down
22 changes: 16 additions & 6 deletions modules/swagger-codegen/src/main/resources/scala/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import javax.ws.rs.core.MediaType

import java.io.File
import java.util.Date
import java.util.TimeZone

import scala.collection.mutable.HashMap

Expand All @@ -38,9 +39,18 @@ class {{classname}}(
val defBasePath: String = "{{{basePath}}}",
defApiInvoker: ApiInvoker = ApiInvoker
) {

private lazy val dateTimeFormatter = {
val formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
formatter.setTimeZone(TimeZone.getTimeZone("UTC"))
formatter
}
private val dateFormatter = {
val formatter = new SimpleDateFormat("yyyy-MM-dd")
formatter.setTimeZone(TimeZone.getTimeZone("UTC"))
formatter
}
implicit val formats = new org.json4s.DefaultFormats {
override def dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS+0000")
override def dateFormatter = dateTimeFormatter
}
implicit val stringReader: ClientResponseReader[String] = ClientResponseReaders.StringReader
implicit val unitReader: ClientResponseReader[Unit] = ClientResponseReaders.UnitReader
Expand Down Expand Up @@ -68,7 +78,7 @@ class {{classname}}(
{{#allParams}} * @param {{paramName}} {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
*/
def {{operationId}}({{#allParams}}{{paramName}}: {{#required}}{{dataType}}{{#defaultValue}} /* = {{{defaultValue}}}*/{{/defaultValue}}{{/required}}{{^required}}Option[{{dataType}}]{{#defaultValue}} = None /* = {{{defaultValue}}}*/{{/defaultValue}}{{^defaultValue}} = None{{/defaultValue}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}){{#returnType}}: Option[{{returnType}}]{{/returnType}} = {
def {{operationId}}({{#allParams}}{{paramName}}: {{#required}}{{dataType}}{{#defaultValue}} = {{#isString}}"{{{defaultValue}}}"{{/isString}}{{^isString}}{{#isByteArray}}"{{/isByteArray}}{{#isDate}}dateFormatter.parse("{{/isDate}}{{#isDateTime}}dateTimeFormatter.parse("{{/isDateTime}}{{{defaultValue}}}{{#isDate}}"){{/isDate}}{{#isDateTime}}"){{/isDateTime}}{{#isByteArray}}".getBytes{{/isByteArray}}{{/isString}}{{/defaultValue}}{{/required}}{{^required}}Option[{{dataType}}]{{#defaultValue}} = Option({{#isString}}"{{{defaultValue}}}"{{/isString}}{{^isString}}{{#isByteArray}}"{{/isByteArray}}{{#isDate}}dateFormatter.parse("{{/isDate}}{{#isDateTime}}dateTimeFormatter.parse("{{/isDateTime}}{{{defaultValue}}}{{#isDate}}"){{/isDate}}{{#isDateTime}}"){{/isDateTime}}{{#isByteArray}}".getBytes{{/isByteArray}}{{/isString}}){{/defaultValue}}{{^defaultValue}} = None{{/defaultValue}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}){{#returnType}}: Option[{{returnType}}]{{/returnType}} = {
val await = Try(Await.result({{operationId}}Async({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}), Duration.Inf))
await match {
case Success(i) => Some(await.get)
Expand All @@ -83,7 +93,7 @@ class {{classname}}(
{{#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}} = None /* = {{{defaultValue}}}*/{{/defaultValue}}{{^defaultValue}} = None{{/defaultValue}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}){{#returnType}}: Future[{{returnType}}]{{/returnType}} = {
def {{operationId}}Async({{#allParams}}{{paramName}}: {{#required}}{{dataType}}{{#defaultValue}} = {{#isString}}"{{{defaultValue}}}"{{/isString}}{{^isString}}{{#isByteArray}}"{{/isByteArray}}{{#isDate}}dateFormatter.parse("{{/isDate}}{{#isDateTime}}dateTimeFormatter.parse("{{/isDateTime}}{{{defaultValue}}}{{#isDate}}"){{/isDate}}{{#isDateTime}}"){{/isDateTime}}{{#isByteArray}}".getBytes{{/isByteArray}}{{/isString}}{{/defaultValue}}{{/required}}{{^required}}Option[{{dataType}}]{{#defaultValue}} = Option({{#isString}}"{{{defaultValue}}}"{{/isString}}{{^isString}}{{#isByteArray}}"{{/isByteArray}}{{#isDate}}dateFormatter.parse("{{/isDate}}{{#isDateTime}}dateTimeFormatter.parse("{{/isDateTime}}{{{defaultValue}}}{{#isDate}}"){{/isDate}}{{#isDateTime}}"){{/isDateTime}}{{#isByteArray}}".getBytes{{/isByteArray}}{{/isString}}){{/defaultValue}}{{^defaultValue}} = None{{/defaultValue}}{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}){{#returnType}}: Future[{{returnType}}]{{/returnType}} = {
helper.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
}

Expand All @@ -93,8 +103,8 @@ class {{classname}}(
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}},
def {{operationId}}({{#allParams}}{{^required}}{{paramName}}: Option[{{dataType}}] = {{#defaultValue}}Option({{#isString}}"{{{defaultValue}}}"{{/isString}}{{^isString}}{{#isByteArray}}"{{/isByteArray}}{{#isDate}}dateFormatter.parse("{{/isDate}}{{#isDateTime}}dateTimeFormatter.parse("{{/isDateTime}}{{{defaultValue}}}{{#isDate}}"){{/isDate}}{{#isDateTime}}"){{/isDateTime}}{{#isByteArray}}".getBytes{{/isByteArray}}{{/isString}}){{/defaultValue}}{{^defaultValue}}None{{/defaultValue}}{{#hasMore}},{{/hasMore}}
{{/required}}{{#required}}{{paramName}}: {{dataType}}{{#defaultValue}} = {{#isString}}"{{{defaultValue}}}"{{/isString}}{{^isString}}{{#isByteArray}}"{{/isByteArray}}{{#isDate}}dateFormatter.parse("{{/isDate}}{{#isDateTime}}dateTimeFormatter.parse("{{/isDateTime}}{{{defaultValue}}}{{#isDate}}"){{/isDate}}{{#isDateTime}}"){{/isDateTime}}{{#isByteArray}}".getBytes{{/isByteArray}}{{/isString}}{{/defaultValue}}{{#hasMore}},
{{/hasMore}}{{/required}}{{/allParams}})(implicit reader: ClientResponseReader[{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Unit{{/returnType}}]{{#bodyParams}}, writer: RequestWriter[{{^required}}Option[{{dataType}}]{{/required}}{{#required}}{{dataType}}{{/required}}]{{/bodyParams}}){{#returnType}}: Future[{{returnType}}]{{/returnType}}{{^returnType}}: Future[Unit]{{/returnType}} = {
// create path and map variables
val path = (addFmt("{{path}}"){{#pathParams}}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package io.swagger.codegen.scala;

import com.google.common.collect.ImmutableMap;
import io.swagger.codegen.AbstractIntegrationTest;
import io.swagger.codegen.CodegenConfig;
import io.swagger.codegen.CodegenConstants;
import io.swagger.codegen.languages.ScalaClientCodegen;
import io.swagger.codegen.testutils.IntegrationTestPathsConfig;
import org.testng.annotations.Test;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class ScalaClientRequiredAttributesIntegrationTest extends AbstractIntegrationTest {

public ScalaClientRequiredAttributesIntegrationTest() {
generateSwaggerMetadata = false;

ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<String, String>();
systemPropertyOverrides = builder
.put(CodegenConstants.APIS, Boolean.TRUE.toString())
.put(CodegenConstants.MODELS, Boolean.TRUE.toString())
.put(CodegenConstants.API_DOCS, Boolean.FALSE.toString())
.put(CodegenConstants.MODEL_DOCS, Boolean.FALSE.toString())
.put(CodegenConstants.API_TESTS, Boolean.FALSE.toString())
.put(CodegenConstants.MODEL_TESTS, Boolean.FALSE.toString())
.put(CodegenConstants.SUPPORTING_FILES, Boolean.FALSE.toString())
.build();
}

@Override
protected IntegrationTestPathsConfig getIntegrationTestPathsConfig() {
return new IntegrationTestPathsConfig("scala/client/required-attributes");
}

@Override
protected CodegenConfig getCodegenConfig() {
return new ScalaClientCodegen();
}

@Override
protected Map<String, String> configProperties() {
Map<String, String> properties = new HashMap<>();
properties.put(CodegenConstants.EXCLUDE_TESTS, Boolean.TRUE.toString());
return properties;
}

// TODO: Remove this when super.generatesCorrectDirectoryStructure() is re-enabled.
@Test(description = "Verify Scala client's understanding of 'required' attributes. (disabled awaiting CI fix for integration tests classpath)", enabled = false)
public void test() throws IOException {
this.generatesCorrectDirectoryStructure();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;
import java.util.List;

import difflib.Delta;
Expand Down Expand Up @@ -56,8 +57,18 @@ public FileVisitResult preVisitDirectory(Path expectedDir, BasicFileAttributes a
fail(String.format("Directory '%s' is missing.", actualDir));
}

assertEquals(expectedDir.toFile().list(),
actualDir.toFile().list(),
String[] expected = expectedDir.toFile().list();
String[] actual = actualDir.toFile().list();

if (expected != null) {
Arrays.sort(expected);
}
if (actual != null) {
Arrays.sort(actual);
}

assertEquals(expected,
actual,
String.format("Directory content of '%s' and '%s' differ.", expectedDir, actualDir));

return FileVisitResult.CONTINUE;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
/**
* Scala Client API Integration Test
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
*
* OpenAPI spec version: 1
*
*
* 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 java.text.SimpleDateFormat

import io.swagger.client.model.ArrayByte
import java.util.Date
import io.swagger.client.model.Hobby
import io.swagger.client.{ApiInvoker, ApiException}

import com.sun.jersey.multipart.FormDataMultiPart
import com.sun.jersey.multipart.file.FileDataBodyPart

import javax.ws.rs.core.MediaType

import java.io.File
import java.util.Date
import java.util.TimeZone

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}

import org.json4s._

class HobbiesApi(
val defBasePath: String = "https://localhost:8080",
defApiInvoker: ApiInvoker = ApiInvoker
) {
private lazy val dateTimeFormatter = {
val formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
formatter.setTimeZone(TimeZone.getTimeZone("UTC"))
formatter
}
private val dateFormatter = {
val formatter = new SimpleDateFormat("yyyy-MM-dd")
formatter.setTimeZone(TimeZone.getTimeZone("UTC"))
formatter
}
implicit val formats = new org.json4s.DefaultFormats {
override def dateFormatter = dateTimeFormatter
}
implicit val stringReader: ClientResponseReader[String] = ClientResponseReaders.StringReader
implicit val unitReader: ClientResponseReader[Unit] = ClientResponseReaders.UnitReader
implicit val jvalueReader: ClientResponseReader[JValue] = ClientResponseReaders.JValueReader
implicit val jsonReader: ClientResponseReader[Nothing] = JsonFormatsReader
implicit val stringWriter: RequestWriter[String] = RequestWriters.StringWriter
implicit val jsonWriter: RequestWriter[Nothing] = JsonFormatsWriter

var basePath: String = defBasePath
var apiInvoker: ApiInvoker = defApiInvoker

def addHeader(key: String, value: String): mutable.HashMap[String, String] = {
apiInvoker.defaultHeaders += key -> value
}

val config: SwaggerConfig = SwaggerConfig.forUrl(new URI(defBasePath))
val client = new RestClient(config)
val helper = new HobbiesApiAsyncHelper(client, config)

/**
* Get hobbies
* Query hobbies with some additional optional meaningless parameters
*
* @param s a string (optional, default to some string)
* @param i an integer (optional, default to 1)
* @param l a long (optional, default to 2)
* @param bool a bool (optional, default to true)
* @param f a float (optional, default to 0.1)
* @param d a double (optional, default to 10.005)
* @param datetime a date time (optional, default to 2018-01-01T08:30:00Z-04:00)
* @param date a date (optional, default to 2018-01-01)
* @param b a base64 encoded string (optional, default to c3dhZ2dlciBjb2RlZ2Vu)
* @param bin an octet string (optional, default to DEADBEEF)
* @return Hobby
*/
def getHobbies(s: Option[String] = Option("some string"), i: Option[Integer] = Option(1), l: Option[Long] = Option(2), bool: Option[Boolean] = Option(true), f: Option[Float] = Option(0.1), d: Option[Double] = Option(10.005), datetime: Option[Date] = Option(dateTimeFormatter.parse("2018-01-01T08:30:00Z-04:00")), date: Option[Date] = Option(dateFormatter.parse("2018-01-01")), b: Option[ArrayByte] = Option("c3dhZ2dlciBjb2RlZ2Vu".getBytes), bin: Option[ArrayByte] = Option("DEADBEEF".getBytes)): Option[Hobby] = {
val await = Try(Await.result(getHobbiesAsync(s, i, l, bool, f, d, datetime, date, b, bin), Duration.Inf))
await match {
case Success(i) => Some(await.get)
case Failure(t) => None
}
}

/**
* Get hobbies asynchronously
* Query hobbies with some additional optional meaningless parameters
*
* @param s a string (optional, default to some string)
* @param i an integer (optional, default to 1)
* @param l a long (optional, default to 2)
* @param bool a bool (optional, default to true)
* @param f a float (optional, default to 0.1)
* @param d a double (optional, default to 10.005)
* @param datetime a date time (optional, default to 2018-01-01T08:30:00Z-04:00)
* @param date a date (optional, default to 2018-01-01)
* @param b a base64 encoded string (optional, default to c3dhZ2dlciBjb2RlZ2Vu)
* @param bin an octet string (optional, default to DEADBEEF)
* @return Future(Hobby)
*/
def getHobbiesAsync(s: Option[String] = Option("some string"), i: Option[Integer] = Option(1), l: Option[Long] = Option(2), bool: Option[Boolean] = Option(true), f: Option[Float] = Option(0.1), d: Option[Double] = Option(10.005), datetime: Option[Date] = Option(dateTimeFormatter.parse("2018-01-01T08:30:00Z-04:00")), date: Option[Date] = Option(dateFormatter.parse("2018-01-01")), b: Option[ArrayByte] = Option("c3dhZ2dlciBjb2RlZ2Vu".getBytes), bin: Option[ArrayByte] = Option("DEADBEEF".getBytes)): Future[Hobby] = {
helper.getHobbies(s, i, l, bool, f, d, datetime, date, b, bin)
}

}

class HobbiesApiAsyncHelper(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) {

def getHobbies(s: Option[String] = Option("some string"),
i: Option[Integer] = Option(1),
l: Option[Long] = Option(2),
bool: Option[Boolean] = Option(true),
f: Option[Float] = Option(0.1),
d: Option[Double] = Option(10.005),
datetime: Option[Date] = Option(dateTimeFormatter.parse("2018-01-01T08:30:00Z-04:00")),
date: Option[Date] = Option(dateFormatter.parse("2018-01-01")),
b: Option[ArrayByte] = Option("c3dhZ2dlciBjb2RlZ2Vu".getBytes),
bin: Option[ArrayByte] = Option("DEADBEEF".getBytes)
)(implicit reader: ClientResponseReader[Hobby]): Future[Hobby] = {
// create path and map variables
val path = (addFmt("/hobbies"))

// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]

s match {
case Some(param) => queryParams += "s" -> param.toString
case _ => queryParams
}
i match {
case Some(param) => queryParams += "i" -> param.toString
case _ => queryParams
}
l match {
case Some(param) => queryParams += "l" -> param.toString
case _ => queryParams
}
bool match {
case Some(param) => queryParams += "bool" -> param.toString
case _ => queryParams
}
f match {
case Some(param) => queryParams += "f" -> param.toString
case _ => queryParams
}
d match {
case Some(param) => queryParams += "d" -> param.toString
case _ => queryParams
}
datetime match {
case Some(param) => queryParams += "datetime" -> param.toString
case _ => queryParams
}
date match {
case Some(param) => queryParams += "date" -> param.toString
case _ => queryParams
}
b match {
case Some(param) => queryParams += "b" -> param.toString
case _ => queryParams
}
bin match {
case Some(param) => queryParams += "bin" -> param.toString
case _ => queryParams
}

val resFuture = client.submit("GET", path, queryParams.toMap, headerParams.toMap, "")
resFuture flatMap { resp =>
process(reader.read(resp))
}
}


}
Loading