[Scala] Add support for PATCH via X-HTTP-Method-Override (#6539)

* Added support for http PATCH to the scala client using X-HTTP-Method-Override header

* Update Petstore sample
This commit is contained in:
Greg Marzouka 2017-09-26 00:22:01 -04:00 committed by wing328
parent d325c6ee77
commit 0a9e3782c5
9 changed files with 148 additions and 62 deletions

View File

@ -142,6 +142,11 @@ class ApiInvoker(val mapper: ObjectMapper = ScalaJsonUtil.getJsonMapper,
case "DELETE" => {
builder.delete(classOf[ClientResponse])
}
case "PATCH" => {
if(formData != null) builder.header("X-HTTP-Method-Override", "PATCH").post(classOf[ClientResponse], formData)
else if(body == null) builder.header("X-HTTP-Method-Override", "PATCH").post(classOf[ClientResponse], null)
else builder.header("X-HTTP-Method-Override", "PATCH").`type`(contentType).post(classOf[ClientResponse], serialize(body))
}
case _ => null
}
response.getStatusInfo().getStatusCode() match {

View File

@ -0,0 +1 @@
2.3.0-SNAPSHOT

View File

@ -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"
}

View File

@ -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
)

View File

@ -209,6 +209,11 @@
<artifactId>joda-convert</artifactId>
<version>${joda-version}</version>
</dependency>
<dependency>
<groupId>com.wordnik.swagger</groupId>
<artifactId>swagger-async-httpclient_2.10</artifactId>
<version>${swagger-async-httpclient-version}</version>
</dependency>
</dependencies>
<properties>
<scala-version>2.10.4</scala-version>
@ -223,6 +228,7 @@
<junit-version>4.8.1</junit-version>
<scala-maven-plugin-version>3.1.5</scala-maven-plugin-version>
<scala-test-version>2.2.4</scala-test-version>
<swagger-async-httpclient-version>0.3.5</swagger-async-httpclient-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

View File

@ -153,6 +153,11 @@ class ApiInvoker(val mapper: ObjectMapper = ScalaJsonUtil.getJsonMapper,
case "DELETE" => {
builder.delete(classOf[ClientResponse])
}
case "PATCH" => {
if(formData != null) builder.header("X-HTTP-Method-Override", "PATCH").post(classOf[ClientResponse], formData)
else if(body == null) builder.header("X-HTTP-Method-Override", "PATCH").post(classOf[ClientResponse], null)
else builder.header("X-HTTP-Method-Override", "PATCH").`type`(contentType).post(classOf[ClientResponse], serialize(body))
}
case _ => null
}
response.getStatusInfo().getStatusCode() match {

View File

@ -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()
}
}

View File

@ -12,8 +12,9 @@
package io.swagger.client.api
import io.swagger.client.ApiInvoker
import io.swagger.client.ApiException
import java.text.SimpleDateFormat
import io.swagger.client.{ApiInvoker, ApiException}
import com.sun.jersey.multipart.FormDataMultiPart
import com.sun.jersey.multipart.file.FileDataBodyPart
@ -25,12 +26,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 FakeApi(val defBasePath: String = "https://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r",
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 FakeApiAsyncHelper(client, config)
/**
* To test code injection *_/ &#39; \&quot; &#x3D;end -- \\r\\n \\n \\r
@ -39,37 +69,43 @@ class FakeApi(val defBasePath: String = "https://petstore.swagger.io *_/ ' \" =e
* @return void
*/
def testCodeInject * &#39; &quot; &#x3D;end rn n r(testCodeInjectEndRnNR: Option[String] = None) = {
// create path and map variables
val path = "/fake".replaceAll("\\{format\\}", "json")
val contentTypes = List("application/json", "*_/ ' =end -- ")
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
testCodeInjectEndRnNR.map(paramVal => mp.field("test code inject */ &#39; &quot; &#x3D;end -- \r\n \n \r", paramVal.toString, MediaType.MULTIPART_FORM_DATA_TYPE))
postBody = mp
} else {
testCodeInjectEndRnNR.map(paramVal => formParams += "test code inject */ &#39; &quot; &#x3D;end -- \r\n \n \r" -> paramVal.toString)
}
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 await = Try(Await.result(testCodeInject * &#39; &quot; &#x3D;end rn n rAsync(testCodeInjectEndRnNR), Duration.Inf))
await match {
case Success(i) => Some(await.get)
case Failure(t) => None
}
}
/**
* To test code injection *_/ &#39; \&quot; &#x3D;end -- \\r\\n \\n \\r asynchronously
*
* @param testCodeInjectEndRnNR To test code injection *_/ &#39; \&quot; &#x3D;end -- \\r\\n \\n \\r (optional)
* @return Future(void)
*/
def testCodeInject * &#39; &quot; &#x3D;end rn n rAsync(testCodeInjectEndRnNR: Option[String] = None) = {
helper.testCodeInject * &#39; &quot; &#x3D;end rn n r(testCodeInjectEndRnNR)
}
}
class FakeApiAsyncHelper(client: TransportClient, config: SwaggerConfig) extends ApiClient(client, config) {
def testCodeInject * &#39; &quot; &#x3D;end rn n r(testCodeInjectEndRnNR: Option[String] = None
)(implicit reader: ClientResponseReader[Unit]): Future[Unit] = {
// create path and map variables
val path = (addFmt("/fake"))
// query params
val queryParams = new mutable.HashMap[String, String]
val headerParams = new mutable.HashMap[String, String]
val resFuture = client.submit("PUT", path, queryParams.toMap, headerParams.toMap, "")
resFuture flatMap { resp =>
process(reader.read(resp))
}
}
}

View File

@ -153,6 +153,11 @@ class ApiInvoker(val mapper: ObjectMapper = ScalaJsonUtil.getJsonMapper,
case "DELETE" => {
builder.delete(classOf[ClientResponse])
}
case "PATCH" => {
if(formData != null) builder.header("X-HTTP-Method-Override", "PATCH").post(classOf[ClientResponse], formData)
else if(body == null) builder.header("X-HTTP-Method-Override", "PATCH").post(classOf[ClientResponse], null)
else builder.header("X-HTTP-Method-Override", "PATCH").`type`(contentType).post(classOf[ClientResponse], serialize(body))
}
case _ => null
}
response.getStatusInfo().getStatusCode() match {