forked from loafle/openapi-generator-original
[scala][akka] Update dependencies for scala 2.13 in scala-akka (#8624)
* [scala][akka] Update dependencies for scala 2.13 * Update pom.mustache to support multiple scala's version * Update pom.xml * Scala cross build 2.12 and 2.13 * Update version. Migrate to sbt * Remove space * Add pom.xml back
This commit is contained in:
parent
dbb42f9027
commit
ebc1d7bd95
@ -166,8 +166,8 @@ public class ScalaAkkaClientCodegen extends AbstractScalaCodegen implements Code
|
|||||||
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
|
||||||
|
|
||||||
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||||
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
|
|
||||||
supportingFiles.add(new SupportingFile("build.sbt.mustache", "", "build.sbt"));
|
supportingFiles.add(new SupportingFile("build.sbt.mustache", "", "build.sbt"));
|
||||||
|
supportingFiles.add(new SupportingFile("pom.mustache", "", "pom.xml"));
|
||||||
supportingFiles.add(new SupportingFile("reference.mustache", resourcesFolder, "reference.conf"));
|
supportingFiles.add(new SupportingFile("reference.mustache", resourcesFolder, "reference.conf"));
|
||||||
final String invokerFolder = (sourceFolder + File.separator + invokerPackage).replace(".", File.separator);
|
final String invokerFolder = (sourceFolder + File.separator + invokerPackage).replace(".", File.separator);
|
||||||
supportingFiles.add(new SupportingFile("apiRequest.mustache", invokerFolder, "ApiRequest.scala"));
|
supportingFiles.add(new SupportingFile("apiRequest.mustache", invokerFolder, "ApiRequest.scala"));
|
||||||
@ -175,6 +175,7 @@ public class ScalaAkkaClientCodegen extends AbstractScalaCodegen implements Code
|
|||||||
supportingFiles.add(new SupportingFile("requests.mustache", invokerFolder, "requests.scala"));
|
supportingFiles.add(new SupportingFile("requests.mustache", invokerFolder, "requests.scala"));
|
||||||
supportingFiles.add(new SupportingFile("apiSettings.mustache", invokerFolder, "ApiSettings.scala"));
|
supportingFiles.add(new SupportingFile("apiSettings.mustache", invokerFolder, "ApiSettings.scala"));
|
||||||
final String apiFolder = (sourceFolder + File.separator + apiPackage).replace(".", File.separator);
|
final String apiFolder = (sourceFolder + File.separator + apiPackage).replace(".", File.separator);
|
||||||
|
supportingFiles.add(new SupportingFile("project/build.properties.mustache", "project", "build.properties"));
|
||||||
supportingFiles.add(new SupportingFile("enumsSerializers.mustache", apiFolder, "EnumsSerializers.scala"));
|
supportingFiles.add(new SupportingFile("enumsSerializers.mustache", apiFolder, "EnumsSerializers.scala"));
|
||||||
supportingFiles.add(new SupportingFile("serializers.mustache", invokerFolder, "Serializers.scala"));
|
supportingFiles.add(new SupportingFile("serializers.mustache", invokerFolder, "Serializers.scala"));
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import de.heikoseeberger.akkahttpjson4s.Json4sSupport
|
|||||||
import org.json4s._
|
import org.json4s._
|
||||||
import org.json4s.jackson.JsonMethods._
|
import org.json4s.jackson.JsonMethods._
|
||||||
import org.json4s.jackson.Serialization
|
import org.json4s.jackson.Serialization
|
||||||
|
import scala.collection.compat._
|
||||||
|
|
||||||
import scala.collection.immutable
|
import scala.collection.immutable
|
||||||
import scala.concurrent.{ ExecutionContext, ExecutionContextExecutor, Future }
|
import scala.concurrent.{ ExecutionContext, ExecutionContextExecutor, Future }
|
||||||
@ -86,7 +87,7 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
|
|||||||
|
|
||||||
private val http = Http()
|
private val http = Http()
|
||||||
|
|
||||||
val CompressionFilter: HttpMessage ⇒ Boolean = (msg: HttpMessage) =>
|
val CompressionFilter: HttpMessage => Boolean = (msg: HttpMessage) =>
|
||||||
Seq(
|
Seq(
|
||||||
{ _: HttpMessage => settings.compressionEnabled },
|
{ _: HttpMessage => settings.compressionEnabled },
|
||||||
Encoder.DefaultFilter,
|
Encoder.DefaultFilter,
|
||||||
@ -115,7 +116,7 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
|
|||||||
private def headers(headers: Map[String, Any]): immutable.Seq[HttpHeader] =
|
private def headers(headers: Map[String, Any]): immutable.Seq[HttpHeader] =
|
||||||
headers.asFormattedParams
|
headers.asFormattedParams
|
||||||
.map { case (name, value) => RawHeader(name, value.toString) }
|
.map { case (name, value) => RawHeader(name, value.toString) }
|
||||||
.to[immutable.Seq]
|
.to(immutable.Seq)
|
||||||
|
|
||||||
|
|
||||||
private def bodyPart(name: String, value: Any): BodyPart = {
|
private def bodyPart(name: String, value: Any): BodyPart = {
|
||||||
@ -147,9 +148,9 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
|
|||||||
case MediaTypes.`multipart/form-data` =>
|
case MediaTypes.`multipart/form-data` =>
|
||||||
Multipart.FormData(Source(params.toList.map { case (name, value) => bodyPart(name, value) }))
|
Multipart.FormData(Source(params.toList.map { case (name, value) => bodyPart(name, value) }))
|
||||||
case MediaTypes.`application/x-www-form-urlencoded` =>
|
case MediaTypes.`application/x-www-form-urlencoded` =>
|
||||||
FormData(params.mapValues(_.toString))
|
FormData(params.view.mapValues(_.toString).toMap)
|
||||||
case _: MediaType => // Default : application/x-www-form-urlencoded.
|
case _: MediaType => // Default : application/x-www-form-urlencoded.
|
||||||
FormData(params.mapValues(_.toString))
|
FormData(params.view.mapValues(_.toString).toMap)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -187,7 +188,9 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
|
|||||||
params + (keyName -> key.value)
|
params + (keyName -> key.value)
|
||||||
case (params, _) => params
|
case (params, _) => params
|
||||||
}.asFormattedParams
|
}.asFormattedParams
|
||||||
|
.view
|
||||||
.mapValues(_.toString)
|
.mapValues(_.toString)
|
||||||
|
.toMap
|
||||||
.foldRight[Query](Uri.Query.Empty) {
|
.foldRight[Query](Uri.Query.Empty) {
|
||||||
case ((name, value), acc) => acc.+:(name, value)
|
case ((name, value), acc) => acc.+:(name, value)
|
||||||
}
|
}
|
||||||
@ -196,7 +199,9 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
|
|||||||
def makeUri(r: ApiRequest[_]): Uri = {
|
def makeUri(r: ApiRequest[_]): Uri = {
|
||||||
val opPath = r.operationPath.replaceAll("\\{format\\}", "json")
|
val opPath = r.operationPath.replaceAll("\\{format\\}", "json")
|
||||||
val opPathWithParams = r.pathParams.asFormattedParams
|
val opPathWithParams = r.pathParams.asFormattedParams
|
||||||
|
.view
|
||||||
.mapValues(_.toString)
|
.mapValues(_.toString)
|
||||||
|
.toMap
|
||||||
.foldLeft(opPath) {
|
.foldLeft(opPath) {
|
||||||
case (path, (name, value)) => path.replaceAll(s"\\{$name\\}", value)
|
case (path, (name, value)) => path.replaceAll(s"\\{$name\\}", value)
|
||||||
}
|
}
|
||||||
@ -213,13 +218,13 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
|
|||||||
http
|
http
|
||||||
.singleRequest(request)
|
.singleRequest(request)
|
||||||
.map { response =>
|
.map { response =>
|
||||||
val decoder: Coder with StreamDecoder = response.encoding match {
|
val decoder: Decoder with Decoder = response.encoding match {
|
||||||
case HttpEncodings.gzip ⇒
|
case HttpEncodings.gzip =>
|
||||||
Gzip
|
Coders.Gzip
|
||||||
case HttpEncodings.deflate ⇒
|
case HttpEncodings.deflate =>
|
||||||
Deflate
|
Coders.Deflate
|
||||||
case HttpEncodings.identity ⇒
|
case HttpEncodings.identity =>
|
||||||
NoCoding
|
Coders.NoCoding
|
||||||
case HttpEncoding(encoding) =>
|
case HttpEncoding(encoding) =>
|
||||||
throw new IllegalArgumentException(s"Unsupported encoding: $encoding")
|
throw new IllegalArgumentException(s"Unsupported encoding: $encoding")
|
||||||
}
|
}
|
||||||
@ -247,13 +252,13 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
|
|||||||
request
|
request
|
||||||
.responseForCode(response.status.intValue) match {
|
.responseForCode(response.status.intValue) match {
|
||||||
case Some((Manifest.Unit, state: ResponseState)) =>
|
case Some((Manifest.Unit, state: ResponseState)) =>
|
||||||
Future(responseForState(state, Unit).asInstanceOf[ApiResponse[T]])
|
Future(responseForState(state, ()).asInstanceOf[ApiResponse[T]])
|
||||||
case Some((manifest, state: ResponseState)) if manifest == mf =>
|
case Some((manifest, state: ResponseState)) if manifest == mf =>
|
||||||
implicit val m: Unmarshaller[HttpEntity, T] = unmarshaller[T](mf, serialization, formats)
|
implicit val m: Unmarshaller[HttpEntity, T] = unmarshaller[T](mf, serialization, formats)
|
||||||
Unmarshal(response.entity)
|
Unmarshal(response.entity)
|
||||||
.to[T]
|
.to[T]
|
||||||
.recoverWith {
|
.recoverWith {
|
||||||
case e ⇒ throw ApiError(response.status.intValue, s"Unable to unmarshall content to [$manifest]", Some(response.entity.toString), e)
|
case e => throw ApiError(response.status.intValue, s"Unable to unmarshall content to [$manifest]", Some(response.entity.toString), e)
|
||||||
}
|
}
|
||||||
.map(value => responseForState(state, value))
|
.map(value => responseForState(state, value))
|
||||||
case None | Some(_) =>
|
case None | Some(_) =>
|
||||||
|
@ -3,12 +3,12 @@ package {{invokerPackage}}
|
|||||||
|
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
import akka.actor.{ ExtendedActorSystem, Extension, ExtensionKey }
|
import akka.actor.{ActorSystem, ExtendedActorSystem, Extension, ExtensionId, ExtensionIdProvider}
|
||||||
import akka.http.scaladsl.model.StatusCodes.CustomStatusCode
|
import akka.http.scaladsl.model.StatusCodes.CustomStatusCode
|
||||||
import akka.http.scaladsl.model.headers.RawHeader
|
import akka.http.scaladsl.model.headers.RawHeader
|
||||||
import com.typesafe.config.Config
|
import com.typesafe.config.Config
|
||||||
|
|
||||||
import scala.collection.JavaConverters._
|
import scala.jdk.CollectionConverters._
|
||||||
import scala.concurrent.duration.FiniteDuration
|
import scala.concurrent.duration.FiniteDuration
|
||||||
|
|
||||||
class ApiSettings(config: Config) extends Extension {
|
class ApiSettings(config: Config) extends Extension {
|
||||||
@ -32,4 +32,13 @@ class ApiSettings(config: Config) extends Extension {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object ApiSettings extends ExtensionKey[ApiSettings]
|
object ApiSettings extends ExtensionId[ApiSettings] with ExtensionIdProvider {
|
||||||
|
|
||||||
|
override def lookup = ApiSettings
|
||||||
|
|
||||||
|
override def createExtension(system: ExtendedActorSystem): ApiSettings =
|
||||||
|
new ApiSettings(system)
|
||||||
|
|
||||||
|
// needed to get the type right when used from Java
|
||||||
|
override def get(system: ActorSystem): ApiSettings = super.get(system)
|
||||||
|
}
|
||||||
|
@ -1,22 +1,26 @@
|
|||||||
version := "{{artifactVersion}}"
|
version := "{{artifactVersion}}"
|
||||||
name := "{{artifactId}}"
|
name := "{{artifactId}}"
|
||||||
organization := "{{groupId}}"
|
organization := "{{groupId}}"
|
||||||
scalaVersion := "2.12.8"
|
|
||||||
|
scalaVersion := "2.12.13"
|
||||||
|
crossScalaVersions := Seq(scalaVersion.value, "2.13.4")
|
||||||
|
|
||||||
|
|
||||||
libraryDependencies ++= Seq(
|
libraryDependencies ++= Seq(
|
||||||
"com.typesafe" % "config" % "1.3.3",
|
"com.typesafe" % "config" % "1.4.1",
|
||||||
"com.typesafe.akka" %% "akka-actor" % "2.5.21",
|
"com.typesafe.akka" %% "akka-actor" % "2.6.12",
|
||||||
"com.typesafe.akka" %% "akka-stream" % "2.5.21",
|
"com.typesafe.akka" %% "akka-stream" % "2.6.12",
|
||||||
"com.typesafe.akka" %% "akka-http" % "10.1.7",
|
"com.typesafe.akka" %% "akka-http" % "10.2.3",
|
||||||
{{#joda}}
|
{{#joda}}
|
||||||
"joda-time" % "joda-time" % "2.10.1",
|
"joda-time" % "joda-time" % "2.10.1",
|
||||||
{{/joda}}
|
{{/joda}}
|
||||||
"org.json4s" %% "json4s-jackson" % "3.6.5",
|
"org.json4s" %% "json4s-jackson" % "3.6.7",
|
||||||
"org.json4s" %% "json4s-ext" % "3.6.5",
|
"org.json4s" %% "json4s-ext" % "3.6.7",
|
||||||
"de.heikoseeberger" %% "akka-http-json4s" % "1.25.2",
|
"de.heikoseeberger" %% "akka-http-json4s" % "1.27.0",
|
||||||
|
"org.scala-lang.modules" %% "scala-collection-compat" % "2.4.1",
|
||||||
// test dependencies
|
// test dependencies
|
||||||
"org.scalatest" %% "scalatest" % "3.0.5" % "test",
|
"org.scalatest" %% "scalatest" % "3.2.3" % "test",
|
||||||
"junit" % "junit" % "4.13.1" % "test"
|
"org.scalatestplus" %% "junit-4-13" % "3.2.3.0" % "test"
|
||||||
)
|
)
|
||||||
|
|
||||||
resolvers ++= Seq(Resolver.mavenLocal)
|
resolvers ++= Seq(Resolver.mavenLocal)
|
||||||
|
@ -15,18 +15,19 @@
|
|||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
<scala.version>2.12.8</scala.version>
|
<scala.version>2.12.13</scala.version>
|
||||||
<json4s.jackson.version>3.5.3</json4s.jackson.version>
|
<json4s.jackson.version>3.6.7</json4s.jackson.version>
|
||||||
<json4s.ext.version>3.2.11</json4s.ext.version>
|
<json4s.ext.version>3.6.7</json4s.ext.version>
|
||||||
<akka.version>2.5.21</akka.version>
|
<akka.version>2.6.12</akka.version>
|
||||||
<akka.http.version>10.1.7</akka.http.version>
|
<akka.http.version>10.2.3</akka.http.version>
|
||||||
{{#joda}}
|
{{#joda}}
|
||||||
<joda.time.version>2.10.1</joda.time.version>
|
<joda.time.version>2.10.1</joda.time.version>
|
||||||
{{/joda}}
|
{{/joda}}
|
||||||
<typesafeconfig.version>1.3.3</typesafeconfig.version>
|
<typesafeconfig.version>1.4.1</typesafeconfig.version>
|
||||||
<akka.http.json4s.version>1.25.2</akka.http.json4s.version>
|
<akka.http.json4s.version>1.27.0</akka.http.json4s.version>
|
||||||
<junit.version>4.13.1</junit.version>
|
<scala.compat.version>2.4.1</scala.compat.version>
|
||||||
<scala.test.version>3.0.5</scala.test.version>
|
<scala.test.version>3.2.3</scala.test.version>
|
||||||
|
<scala.test.plus.version>3.2.3.0</scala.test.plus.version>
|
||||||
|
|
||||||
<scala.maven.plugin.version>3.3.1</scala.maven.plugin.version>
|
<scala.maven.plugin.version>3.3.1</scala.maven.plugin.version>
|
||||||
</properties>
|
</properties>
|
||||||
@ -80,6 +81,11 @@
|
|||||||
<artifactId>akka-http-json4s_2.12</artifactId>
|
<artifactId>akka-http-json4s_2.12</artifactId>
|
||||||
<version>${akka.http.json4s.version}</version>
|
<version>${akka.http.json4s.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.scala-lang.modules</groupId>
|
||||||
|
<artifactId>scala-collection-compat_2.12</artifactId>
|
||||||
|
<version>${scala.compat.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!--test dependencies-->
|
<!--test dependencies-->
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -89,9 +95,9 @@
|
|||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>org.scalatestplus</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit-4-13_2.12</artifactId>
|
||||||
<version>${junit.version}</version>
|
<version>${scala.test.plus.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
sbt.version=1.3.10
|
@ -472,7 +472,7 @@ public class ScalaAkkaClientCodegenTest {
|
|||||||
Generator gen = generator.opts(clientOptInput);
|
Generator gen = generator.opts(clientOptInput);
|
||||||
List<File> files = gen.generate();
|
List<File> files = gen.generate();
|
||||||
|
|
||||||
Assert.assertEquals(files.size(), 15);
|
Assert.assertEquals(files.size(), 16);
|
||||||
|
|
||||||
TestUtils.ensureContainsFile(files, output, "src/main/scala/hello/world/model/SomeObj.scala");
|
TestUtils.ensureContainsFile(files, output, "src/main/scala/hello/world/model/SomeObj.scala");
|
||||||
TestUtils.ensureContainsFile(files, output, "src/main/scala/hello/world/core/ApiSettings.scala");
|
TestUtils.ensureContainsFile(files, output, "src/main/scala/hello/world/core/ApiSettings.scala");
|
||||||
@ -509,7 +509,7 @@ public class ScalaAkkaClientCodegenTest {
|
|||||||
Generator gen = generator.opts(clientOptInput);
|
Generator gen = generator.opts(clientOptInput);
|
||||||
|
|
||||||
List<File> files = gen.generate();
|
List<File> files = gen.generate();
|
||||||
Assert.assertEquals(files.size(), 15);
|
Assert.assertEquals(files.size(), 16);
|
||||||
|
|
||||||
TestUtils.ensureContainsFile(files, output, "src/main/scala/hello/world/model/package/SomeObj.scala");
|
TestUtils.ensureContainsFile(files, output, "src/main/scala/hello/world/model/package/SomeObj.scala");
|
||||||
TestUtils.ensureContainsFile(files, output, "src/main/scala/hello/world/package/invoker/ApiSettings.scala");
|
TestUtils.ensureContainsFile(files, output, "src/main/scala/hello/world/package/invoker/ApiSettings.scala");
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
README.md
|
README.md
|
||||||
build.sbt
|
build.sbt
|
||||||
|
project/build.properties
|
||||||
src/main/resources/reference.conf
|
src/main/resources/reference.conf
|
||||||
src/main/scala/org/openapitools/client/api/EnumsSerializers.scala
|
src/main/scala/org/openapitools/client/api/EnumsSerializers.scala
|
||||||
src/main/scala/org/openapitools/client/api/PetApi.scala
|
src/main/scala/org/openapitools/client/api/PetApi.scala
|
||||||
|
@ -1,19 +1,23 @@
|
|||||||
version := "1.0.0"
|
version := "1.0.0"
|
||||||
name := "scala-akka-petstore-client"
|
name := "scala-akka-petstore-client"
|
||||||
organization := "org.openapitools"
|
organization := "org.openapitools"
|
||||||
scalaVersion := "2.12.8"
|
|
||||||
|
scalaVersion := "2.12.13"
|
||||||
|
crossScalaVersions := Seq(scalaVersion.value, "2.13.4")
|
||||||
|
|
||||||
|
|
||||||
libraryDependencies ++= Seq(
|
libraryDependencies ++= Seq(
|
||||||
"com.typesafe" % "config" % "1.3.3",
|
"com.typesafe" % "config" % "1.4.1",
|
||||||
"com.typesafe.akka" %% "akka-actor" % "2.5.21",
|
"com.typesafe.akka" %% "akka-actor" % "2.6.12",
|
||||||
"com.typesafe.akka" %% "akka-stream" % "2.5.21",
|
"com.typesafe.akka" %% "akka-stream" % "2.6.12",
|
||||||
"com.typesafe.akka" %% "akka-http" % "10.1.7",
|
"com.typesafe.akka" %% "akka-http" % "10.2.3",
|
||||||
"org.json4s" %% "json4s-jackson" % "3.6.5",
|
"org.json4s" %% "json4s-jackson" % "3.6.7",
|
||||||
"org.json4s" %% "json4s-ext" % "3.6.5",
|
"org.json4s" %% "json4s-ext" % "3.6.7",
|
||||||
"de.heikoseeberger" %% "akka-http-json4s" % "1.25.2",
|
"de.heikoseeberger" %% "akka-http-json4s" % "1.27.0",
|
||||||
|
"org.scala-lang.modules" %% "scala-collection-compat" % "2.4.1",
|
||||||
// test dependencies
|
// test dependencies
|
||||||
"org.scalatest" %% "scalatest" % "3.0.5" % "test",
|
"org.scalatest" %% "scalatest" % "3.2.3" % "test",
|
||||||
"junit" % "junit" % "4.13.1" % "test"
|
"org.scalatestplus" %% "junit-4-13" % "3.2.3.0" % "test"
|
||||||
)
|
)
|
||||||
|
|
||||||
resolvers ++= Seq(Resolver.mavenLocal)
|
resolvers ++= Seq(Resolver.mavenLocal)
|
||||||
|
@ -15,15 +15,16 @@
|
|||||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
<scala.version>2.12.8</scala.version>
|
<scala.version>2.12.13</scala.version>
|
||||||
<json4s.jackson.version>3.5.3</json4s.jackson.version>
|
<json4s.jackson.version>3.6.7</json4s.jackson.version>
|
||||||
<json4s.ext.version>3.2.11</json4s.ext.version>
|
<json4s.ext.version>3.6.7</json4s.ext.version>
|
||||||
<akka.version>2.5.21</akka.version>
|
<akka.version>2.6.12</akka.version>
|
||||||
<akka.http.version>10.1.7</akka.http.version>
|
<akka.http.version>10.2.3</akka.http.version>
|
||||||
<typesafeconfig.version>1.3.3</typesafeconfig.version>
|
<typesafeconfig.version>1.4.1</typesafeconfig.version>
|
||||||
<akka.http.json4s.version>1.25.2</akka.http.json4s.version>
|
<akka.http.json4s.version>1.27.0</akka.http.json4s.version>
|
||||||
<junit.version>4.13</junit.version>
|
<scala.compat.version>2.4.1</scala.compat.version>
|
||||||
<scala.test.version>3.0.5</scala.test.version>
|
<scala.test.version>3.2.3</scala.test.version>
|
||||||
|
<scala.test.plus.version>3.2.3.0</scala.test.plus.version>
|
||||||
|
|
||||||
<scala.maven.plugin.version>3.3.1</scala.maven.plugin.version>
|
<scala.maven.plugin.version>3.3.1</scala.maven.plugin.version>
|
||||||
</properties>
|
</properties>
|
||||||
@ -70,6 +71,11 @@
|
|||||||
<artifactId>akka-http-json4s_2.12</artifactId>
|
<artifactId>akka-http-json4s_2.12</artifactId>
|
||||||
<version>${akka.http.json4s.version}</version>
|
<version>${akka.http.json4s.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.scala-lang.modules</groupId>
|
||||||
|
<artifactId>scala-collection-compat_2.12</artifactId>
|
||||||
|
<version>${scala.compat.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!--test dependencies-->
|
<!--test dependencies-->
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -79,9 +85,9 @@
|
|||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>org.scalatestplus</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit-4-13_2.12</artifactId>
|
||||||
<version>${junit.version}</version>
|
<version>${scala.test.plus.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
sbt.version=1.3.10
|
@ -28,6 +28,7 @@ import de.heikoseeberger.akkahttpjson4s.Json4sSupport
|
|||||||
import org.json4s._
|
import org.json4s._
|
||||||
import org.json4s.jackson.JsonMethods._
|
import org.json4s.jackson.JsonMethods._
|
||||||
import org.json4s.jackson.Serialization
|
import org.json4s.jackson.Serialization
|
||||||
|
import scala.collection.compat._
|
||||||
|
|
||||||
import scala.collection.immutable
|
import scala.collection.immutable
|
||||||
import scala.concurrent.{ ExecutionContext, ExecutionContextExecutor, Future }
|
import scala.concurrent.{ ExecutionContext, ExecutionContextExecutor, Future }
|
||||||
@ -96,7 +97,7 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
|
|||||||
|
|
||||||
private val http = Http()
|
private val http = Http()
|
||||||
|
|
||||||
val CompressionFilter: HttpMessage ⇒ Boolean = (msg: HttpMessage) =>
|
val CompressionFilter: HttpMessage => Boolean = (msg: HttpMessage) =>
|
||||||
Seq(
|
Seq(
|
||||||
{ _: HttpMessage => settings.compressionEnabled },
|
{ _: HttpMessage => settings.compressionEnabled },
|
||||||
Encoder.DefaultFilter,
|
Encoder.DefaultFilter,
|
||||||
@ -125,7 +126,7 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
|
|||||||
private def headers(headers: Map[String, Any]): immutable.Seq[HttpHeader] =
|
private def headers(headers: Map[String, Any]): immutable.Seq[HttpHeader] =
|
||||||
headers.asFormattedParams
|
headers.asFormattedParams
|
||||||
.map { case (name, value) => RawHeader(name, value.toString) }
|
.map { case (name, value) => RawHeader(name, value.toString) }
|
||||||
.to[immutable.Seq]
|
.to(immutable.Seq)
|
||||||
|
|
||||||
|
|
||||||
private def bodyPart(name: String, value: Any): BodyPart = {
|
private def bodyPart(name: String, value: Any): BodyPart = {
|
||||||
@ -157,9 +158,9 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
|
|||||||
case MediaTypes.`multipart/form-data` =>
|
case MediaTypes.`multipart/form-data` =>
|
||||||
Multipart.FormData(Source(params.toList.map { case (name, value) => bodyPart(name, value) }))
|
Multipart.FormData(Source(params.toList.map { case (name, value) => bodyPart(name, value) }))
|
||||||
case MediaTypes.`application/x-www-form-urlencoded` =>
|
case MediaTypes.`application/x-www-form-urlencoded` =>
|
||||||
FormData(params.mapValues(_.toString))
|
FormData(params.view.mapValues(_.toString).toMap)
|
||||||
case _: MediaType => // Default : application/x-www-form-urlencoded.
|
case _: MediaType => // Default : application/x-www-form-urlencoded.
|
||||||
FormData(params.mapValues(_.toString))
|
FormData(params.view.mapValues(_.toString).toMap)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -197,7 +198,9 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
|
|||||||
params + (keyName -> key.value)
|
params + (keyName -> key.value)
|
||||||
case (params, _) => params
|
case (params, _) => params
|
||||||
}.asFormattedParams
|
}.asFormattedParams
|
||||||
|
.view
|
||||||
.mapValues(_.toString)
|
.mapValues(_.toString)
|
||||||
|
.toMap
|
||||||
.foldRight[Query](Uri.Query.Empty) {
|
.foldRight[Query](Uri.Query.Empty) {
|
||||||
case ((name, value), acc) => acc.+:(name, value)
|
case ((name, value), acc) => acc.+:(name, value)
|
||||||
}
|
}
|
||||||
@ -206,7 +209,9 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
|
|||||||
def makeUri(r: ApiRequest[_]): Uri = {
|
def makeUri(r: ApiRequest[_]): Uri = {
|
||||||
val opPath = r.operationPath.replaceAll("\\{format\\}", "json")
|
val opPath = r.operationPath.replaceAll("\\{format\\}", "json")
|
||||||
val opPathWithParams = r.pathParams.asFormattedParams
|
val opPathWithParams = r.pathParams.asFormattedParams
|
||||||
|
.view
|
||||||
.mapValues(_.toString)
|
.mapValues(_.toString)
|
||||||
|
.toMap
|
||||||
.foldLeft(opPath) {
|
.foldLeft(opPath) {
|
||||||
case (path, (name, value)) => path.replaceAll(s"\\{$name\\}", value)
|
case (path, (name, value)) => path.replaceAll(s"\\{$name\\}", value)
|
||||||
}
|
}
|
||||||
@ -223,13 +228,13 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
|
|||||||
http
|
http
|
||||||
.singleRequest(request)
|
.singleRequest(request)
|
||||||
.map { response =>
|
.map { response =>
|
||||||
val decoder: Coder with StreamDecoder = response.encoding match {
|
val decoder: Decoder with Decoder = response.encoding match {
|
||||||
case HttpEncodings.gzip ⇒
|
case HttpEncodings.gzip =>
|
||||||
Gzip
|
Coders.Gzip
|
||||||
case HttpEncodings.deflate ⇒
|
case HttpEncodings.deflate =>
|
||||||
Deflate
|
Coders.Deflate
|
||||||
case HttpEncodings.identity ⇒
|
case HttpEncodings.identity =>
|
||||||
NoCoding
|
Coders.NoCoding
|
||||||
case HttpEncoding(encoding) =>
|
case HttpEncoding(encoding) =>
|
||||||
throw new IllegalArgumentException(s"Unsupported encoding: $encoding")
|
throw new IllegalArgumentException(s"Unsupported encoding: $encoding")
|
||||||
}
|
}
|
||||||
@ -257,13 +262,13 @@ class ApiInvoker(formats: Formats)(implicit system: ActorSystem) extends CustomC
|
|||||||
request
|
request
|
||||||
.responseForCode(response.status.intValue) match {
|
.responseForCode(response.status.intValue) match {
|
||||||
case Some((Manifest.Unit, state: ResponseState)) =>
|
case Some((Manifest.Unit, state: ResponseState)) =>
|
||||||
Future(responseForState(state, Unit).asInstanceOf[ApiResponse[T]])
|
Future(responseForState(state, ()).asInstanceOf[ApiResponse[T]])
|
||||||
case Some((manifest, state: ResponseState)) if manifest == mf =>
|
case Some((manifest, state: ResponseState)) if manifest == mf =>
|
||||||
implicit val m: Unmarshaller[HttpEntity, T] = unmarshaller[T](mf, serialization, formats)
|
implicit val m: Unmarshaller[HttpEntity, T] = unmarshaller[T](mf, serialization, formats)
|
||||||
Unmarshal(response.entity)
|
Unmarshal(response.entity)
|
||||||
.to[T]
|
.to[T]
|
||||||
.recoverWith {
|
.recoverWith {
|
||||||
case e ⇒ throw ApiError(response.status.intValue, s"Unable to unmarshall content to [$manifest]", Some(response.entity.toString), e)
|
case e => throw ApiError(response.status.intValue, s"Unable to unmarshall content to [$manifest]", Some(response.entity.toString), e)
|
||||||
}
|
}
|
||||||
.map(value => responseForState(state, value))
|
.map(value => responseForState(state, value))
|
||||||
case None | Some(_) =>
|
case None | Some(_) =>
|
||||||
|
@ -13,12 +13,12 @@ package org.openapitools.client.core
|
|||||||
|
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
import akka.actor.{ ExtendedActorSystem, Extension, ExtensionKey }
|
import akka.actor.{ActorSystem, ExtendedActorSystem, Extension, ExtensionId, ExtensionIdProvider}
|
||||||
import akka.http.scaladsl.model.StatusCodes.CustomStatusCode
|
import akka.http.scaladsl.model.StatusCodes.CustomStatusCode
|
||||||
import akka.http.scaladsl.model.headers.RawHeader
|
import akka.http.scaladsl.model.headers.RawHeader
|
||||||
import com.typesafe.config.Config
|
import com.typesafe.config.Config
|
||||||
|
|
||||||
import scala.collection.JavaConverters._
|
import scala.jdk.CollectionConverters._
|
||||||
import scala.concurrent.duration.FiniteDuration
|
import scala.concurrent.duration.FiniteDuration
|
||||||
|
|
||||||
class ApiSettings(config: Config) extends Extension {
|
class ApiSettings(config: Config) extends Extension {
|
||||||
@ -42,4 +42,13 @@ class ApiSettings(config: Config) extends Extension {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object ApiSettings extends ExtensionKey[ApiSettings]
|
object ApiSettings extends ExtensionId[ApiSettings] with ExtensionIdProvider {
|
||||||
|
|
||||||
|
override def lookup = ApiSettings
|
||||||
|
|
||||||
|
override def createExtension(system: ExtendedActorSystem): ApiSettings =
|
||||||
|
new ApiSettings(system)
|
||||||
|
|
||||||
|
// needed to get the type right when used from Java
|
||||||
|
override def get(system: ActorSystem): ApiSettings = super.get(system)
|
||||||
|
}
|
||||||
|
@ -5,18 +5,19 @@ import org.openapitools.client.api._
|
|||||||
import org.openapitools.client.core.{ApiInvoker, ApiKeyValue}
|
import org.openapitools.client.core.{ApiInvoker, ApiKeyValue}
|
||||||
import org.openapitools.client.model._
|
import org.openapitools.client.model._
|
||||||
import org.scalatest.Inspectors._
|
import org.scalatest.Inspectors._
|
||||||
import org.scalatest._
|
import org.scalatest.flatspec.AsyncFlatSpec
|
||||||
import org.scalatest.junit.JUnitRunner
|
import org.scalatest.matchers.should.Matchers
|
||||||
|
import org.scalatestplus.junit.JUnitRunner
|
||||||
|
|
||||||
@RunWith(classOf[JUnitRunner])
|
@RunWith(classOf[JUnitRunner])
|
||||||
class PetApiTest extends AsyncFlatSpec with Matchers {
|
class PetApiTest extends AsyncFlatSpec with Matchers {
|
||||||
|
|
||||||
private implicit val system: ActorSystem = ActorSystem()
|
implicit private val system: ActorSystem = ActorSystem()
|
||||||
|
|
||||||
behavior of "PetApi"
|
behavior of "PetApi"
|
||||||
val api: PetApi = PetApi()
|
val api: PetApi = PetApi()
|
||||||
val invoker: ApiInvoker = ApiInvoker(EnumsSerializers.all)
|
val invoker: ApiInvoker = ApiInvoker(EnumsSerializers.all)
|
||||||
private implicit val apiKey: ApiKeyValue = ApiKeyValue("special-key")
|
implicit private val apiKey: ApiKeyValue = ApiKeyValue("special-key")
|
||||||
|
|
||||||
it should "add and fetch a pet" in {
|
it should "add and fetch a pet" in {
|
||||||
val petId = 1000
|
val petId = 1000
|
||||||
@ -34,7 +35,7 @@ class PetApiTest extends AsyncFlatSpec with Matchers {
|
|||||||
|
|
||||||
for {
|
for {
|
||||||
addResponse <- invoker.execute(addPetRequest)
|
addResponse <- invoker.execute(addPetRequest)
|
||||||
response <- invoker.execute(getPetRequest)
|
response <- invoker.execute(getPetRequest)
|
||||||
} yield {
|
} yield {
|
||||||
addResponse.code should be(200)
|
addResponse.code should be(200)
|
||||||
|
|
||||||
@ -54,7 +55,7 @@ class PetApiTest extends AsyncFlatSpec with Matchers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
it should "update a pet" in {
|
it should "update a pet" in {
|
||||||
val petId = (Math.random()*1000000000).toLong
|
val petId = (Math.random() * 1000000000).toLong
|
||||||
val createdPet = Pet(
|
val createdPet = Pet(
|
||||||
Some(petId),
|
Some(petId),
|
||||||
Some(Category(Some(1), Some("sold"))),
|
Some(Category(Some(1), Some("sold"))),
|
||||||
@ -64,12 +65,12 @@ class PetApiTest extends AsyncFlatSpec with Matchers {
|
|||||||
Some(PetEnums.Status.Available)
|
Some(PetEnums.Status.Available)
|
||||||
)
|
)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
createdPet <- invoker.execute(api.addPet(createdPet))
|
createdPet <- invoker.execute(api.addPet(createdPet))
|
||||||
pet: core.ApiResponse[Pet] <- invoker.execute(api.getPetById(createdPet.content.id.get))
|
pet: core.ApiResponse[Pet] <- invoker.execute(api.getPetById(createdPet.content.id.get))
|
||||||
updatedPet = pet.content.copy(status = Some(PetEnums.Status.Sold), name = "developer")
|
updatedPet = pet.content.copy(status = Some(PetEnums.Status.Sold), name = "developer")
|
||||||
updatedPetResponse: core.ApiResponse[Pet] <- invoker.execute(api.updatePet(updatedPet))
|
updatedPetResponse: core.ApiResponse[Pet] <- invoker.execute(api.updatePet(updatedPet))
|
||||||
updatedRequested: core.ApiResponse[Pet] <- invoker.execute(api.getPetById(createdPet.content.id.get))
|
updatedRequested: core.ApiResponse[Pet] <- invoker.execute(api.getPetById(createdPet.content.id.get))
|
||||||
} yield {
|
} yield {
|
||||||
pet.content.name should be("programmer")
|
pet.content.name should be("programmer")
|
||||||
pet.content.status should be(Some(PetEnums.Status.Available))
|
pet.content.status should be(Some(PetEnums.Status.Available))
|
||||||
@ -120,4 +121,3 @@ class PetApiTest extends AsyncFlatSpec with Matchers {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user