Skip to content

Commit ea00694

Browse files
authored
Merge pull request #272 from innFactory/feat/jsoniterConfig
feat: setting jsoniter config with application.conf
2 parents 5ac774e + c10c137 commit ea00694

11 files changed

+93
-44
lines changed

smithy4play/src/main/scala/de/innfactory/smithy4play/AutoRoutableController.scala

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package de.innfactory.smithy4play
22

3+
import com.github.plokhotnyuk.jsoniter_scala.core.ReaderConfig
34
import de.innfactory.smithy4play.middleware.MiddlewareBase
45
import play.api.mvc.ControllerComponents
56
import play.api.routing.Router.Routes
@@ -17,9 +18,9 @@ trait AutoRoutableController {
1718
service: smithy4s.Service[Alg],
1819
ec: ExecutionContext,
1920
cc: ControllerComponents
20-
): Seq[MiddlewareBase] => Routes = (middlewares: Seq[MiddlewareBase]) =>
21-
new SmithyPlayRouter[Alg, F](impl, service).routes(middlewares)
21+
): (Seq[MiddlewareBase], ReaderConfig) => Routes = (middlewares: Seq[MiddlewareBase], readerConfig: ReaderConfig) =>
22+
new SmithyPlayRouter[Alg, F](impl, service).routes(middlewares, readerConfig)
2223

23-
val router: Seq[MiddlewareBase] => Routes
24+
val router: (Seq[MiddlewareBase], ReaderConfig) => Routes
2425

2526
}

smithy4play/src/main/scala/de/innfactory/smithy4play/AutoRouter.scala

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package de.innfactory.smithy4play
22

3+
import com.github.plokhotnyuk.jsoniter_scala.core.ReaderConfig
34
import com.typesafe.config.Config
45
import de.innfactory.smithy4play.middleware.{ MiddlewareBase, MiddlewareRegistryBase, ValidateAuthMiddleware }
56
import io.github.classgraph.{ ClassGraph, ScanResult }
@@ -22,7 +23,8 @@ class AutoRouter @Inject(
2223
config: Config
2324
) extends BaseRouter {
2425

25-
private val pkg = config.getString("smithy4play.autoRoutePackage")
26+
private val pkg = config.getString("smithy4play.autoRoutePackage")
27+
private val readerConfig = ReaderConfig.fromApplicationConfig(config)
2628

2729
override val controllers: Seq[Routes] = {
2830
val classGraphScanner: ScanResult = new ClassGraph().enableAllInfo().acceptPackages(pkg).scan()
@@ -39,7 +41,7 @@ class AutoRouter @Inject(
3941

4042
private def createFromClass(clazz: Class[_], middlewares: Seq[MiddlewareBase]): Routes =
4143
app.injector.instanceOf(clazz) match {
42-
case c: AutoRoutableController => c.router(middlewares)
44+
case c: AutoRoutableController => c.router(middlewares, readerConfig)
4345
}
4446

4547
}

smithy4play/src/main/scala/de/innfactory/smithy4play/AutoRoutingMacro.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ object AutoRoutingMacro {
1414
with ..$parentss
1515
with de.innfactory.smithy4play.AutoRoutableController
1616
{ $self =>
17-
override val router: Seq[de.innfactory.smithy4play.middleware.MiddlewareBase] => play.api.routing.Router.Routes = this
17+
override val router:
18+
(Seq[de.innfactory.smithy4play.middleware.MiddlewareBase], com.github.plokhotnyuk.jsoniter_scala.core.ReaderConfig)
19+
=> play.api.routing.Router.Routes = this
1820
..$body }
1921
"""
2022
case _ =>

smithy4play/src/main/scala/de/innfactory/smithy4play/CodecDecider.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package de.innfactory.smithy4play
22

3+
import com.github.plokhotnyuk.jsoniter_scala.core.ReaderConfig
34
import play.api.http.MimeTypes
45
import smithy4s.capability.instances.either._
56
import smithy4s.codecs.Writer.CachedCompiler
@@ -11,12 +12,13 @@ import smithy4s.schema.CachedSchemaCompiler
1112
import smithy4s.xml.Xml
1213
import smithy4s.{ codecs, Blob }
1314

14-
object CodecDecider {
15+
case class CodecDecider(readerConfig: ReaderConfig) {
1516

1617
private val jsonCodecs = Json.payloadCodecs
1718
.withJsoniterCodecCompiler(
1819
Json.jsoniter
1920
)
21+
.withJsoniterReaderConfig(readerConfig)
2022

2123
private val jsonEncoder: BlobEncoder.Compiler = jsonCodecs.encoders
2224
private val jsonDecoder: BlobDecoder.Compiler = jsonCodecs.decoders

smithy4play/src/main/scala/de/innfactory/smithy4play/SmithyPlayEndpoint.scala

+6-13
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,24 @@
11
package de.innfactory.smithy4play
22

3-
import alloy.SimpleRestJson
4-
import aws.protocols.RestXml
53
import cats.data.{ EitherT, Kleisli }
64
import de.innfactory.smithy4play
75
import de.innfactory.smithy4play.middleware.MiddlewareBase
8-
import play.api.http.MimeTypes
96
import play.api.mvc._
107
import smithy4s.codecs.PayloadError
118
import smithy4s.http._
129
import smithy4s.kinds.FunctorInterpreter
1310
import smithy4s.schema.Schema
1411
import smithy4s.{ Blob, Endpoint, Service }
1512

13+
import javax.inject.Inject
1614
import scala.concurrent.{ ExecutionContext, Future }
1715

18-
class SmithyPlayEndpoint[Alg[_[_, _, _, _, _]], F[_] <: ContextRoute[_], Op[
19-
_,
20-
_,
21-
_,
22-
_,
23-
_
24-
], I, E, O, SI, SO](
16+
class SmithyPlayEndpoint[Alg[_[_, _, _, _, _]], F[_] <: ContextRoute[_], Op[_, _, _, _, _], I, E, O, SI, SO](
2517
service: Service[Alg],
2618
impl: FunctorInterpreter[Op, F],
2719
middleware: Seq[MiddlewareBase],
28-
endpoint: Endpoint[Op, I, E, O, SI, SO]
20+
endpoint: Endpoint[Op, I, E, O, SI, SO],
21+
codecDecider: CodecDecider
2922
)(implicit cc: ControllerComponents, ec: ExecutionContext)
3023
extends AbstractController(cc) {
3124

@@ -71,7 +64,7 @@ class SmithyPlayEndpoint[Alg[_[_, _, _, _, _]], F[_] <: ContextRoute[_], Op[
7164
private def mapToEndpointResult(
7265
statusCode: Int
7366
)(output: O)(implicit defaultContentType: ContentType): HttpResponse[Blob] =
74-
CodecDecider
67+
codecDecider
7568
.httpMessageEncoder(Seq(defaultContentType.value))
7669
.fromSchema(outputSchema)
7770
.write(
@@ -106,7 +99,7 @@ class SmithyPlayEndpoint[Alg[_[_, _, _, _, _]], F[_] <: ContextRoute[_], Op[
10699
)(implicit defaultContentType: ContentType): EitherT[Future, ContextRouteError, I] =
107100
EitherT {
108101
Future {
109-
val codec = CodecDecider.requestDecoder(Seq(defaultContentType.value))
102+
val codec = codecDecider.requestDecoder(Seq(defaultContentType.value))
110103
codec
111104
.fromSchema(inputSchema)
112105
.decode({

smithy4play/src/main/scala/de/innfactory/smithy4play/SmithyPlayRouter.scala

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package de.innfactory.smithy4play
22

33
import cats.implicits.toTraverseOps
4+
import com.github.plokhotnyuk.jsoniter_scala.core.ReaderConfig
5+
import com.typesafe.config.Config
46
import de.innfactory.smithy4play.middleware.MiddlewareBase
57
import play.api.mvc.{ AbstractController, ControllerComponents, Handler, RequestHeader }
68
import play.api.routing.Router.Routes
@@ -21,12 +23,13 @@ class SmithyPlayRouter[Alg[_[_, _, _, _, _]], F[
2123
)(implicit cc: ControllerComponents, ec: ExecutionContext)
2224
extends AbstractController(cc) {
2325

24-
def routes(middlewares: Seq[MiddlewareBase]): Routes = {
26+
def routes(middlewares: Seq[MiddlewareBase], readerConfig: ReaderConfig): Routes = {
2527

2628
val interpreter: PolyFunction5[service.Operation, Kind1[F]#toKind5] = service.toPolyFunction[Kind1[F]#toKind5](impl)
2729
val endpoints: Seq[service.Endpoint[_, _, _, _, _]] = service.endpoints
2830
val httpEndpoints: Seq[Either[HttpEndpoint.HttpEndpointError, HttpEndpoint[_]]] =
2931
endpoints.map(ep => HttpEndpoint.cast(ep.schema))
32+
val codecDecider = CodecDecider(readerConfig)
3033

3134
new PartialFunction[RequestHeader, Handler] {
3235
override def isDefinedAt(x: RequestHeader): Boolean = {
@@ -48,7 +51,8 @@ class SmithyPlayRouter[Alg[_[_, _, _, _, _]], F[
4851
service,
4952
interpreter,
5053
middlewares,
51-
endpointAndHttpEndpoint._1
54+
endpointAndHttpEndpoint._1,
55+
codecDecider
5256
).handler(v1)
5357
} match {
5458
case Right(value) => value

smithy4play/src/main/scala/de/innfactory/smithy4play/client/GenericAPIClient.scala

+17-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package de.innfactory.smithy4play.client
22

33
import cats.data.Kleisli
4-
import de.innfactory.smithy4play.{ ClientResponse, RunnableClientRequest }
4+
import com.github.plokhotnyuk.jsoniter_scala.core.ReaderConfig
5+
import de.innfactory.smithy4play.{ ClientResponse, CodecDecider, RunnableClientRequest }
56
import smithy4s.Service
67
import smithy4s.kinds.{ Kind1, PolyFunction5 }
78

@@ -10,10 +11,12 @@ import scala.concurrent.ExecutionContext
1011
private class GenericAPIClient[Alg[_[_, _, _, _, _]]](
1112
service: Service[Alg],
1213
client: RequestClient,
14+
readerConfig: ReaderConfig,
1315
additionalSuccessCodes: List[Int] = List.empty
1416
)(implicit ec: ExecutionContext) {
1517

16-
private val smithyPlayClient = new SmithyPlayClient("/", service, client, additionalSuccessCodes)
18+
private val smithyPlayClient =
19+
new SmithyPlayClient("/", service, client, CodecDecider(readerConfig), additionalSuccessCodes)
1720

1821
/* Takes a service and creates a Transformation[Op, ClientRequest] */
1922
private def transformer(): Alg[Kind1[RunnableClientRequest]#toKind5] =
@@ -53,31 +56,35 @@ object GenericAPIClient {
5356
def withClientAndHeaders(
5457
client: RequestClient,
5558
additionalHeaders: Option[Map[String, Seq[String]]],
56-
additionalSuccessCodes: List[Int] = List.empty
59+
additionalSuccessCodes: List[Int] = List.empty,
60+
readerConfig: ReaderConfig = ReaderConfig
5761
)(implicit ec: ExecutionContext): Alg[Kind1[ClientResponse]#toKind5] =
58-
apply(service, additionalHeaders, additionalSuccessCodes, client)
62+
apply(service, additionalHeaders, additionalSuccessCodes, client, readerConfig)
5963

6064
def withClient(
6165
client: RequestClient,
62-
additionalSuccessCodes: List[Int] = List.empty
66+
additionalSuccessCodes: List[Int] = List.empty,
67+
readerConfig: ReaderConfig = ReaderConfig
6368
)(implicit ec: ExecutionContext): Alg[Kind1[RunnableClientRequest]#toKind5] =
64-
apply(service, client, additionalSuccessCodes)
69+
apply(service, client, additionalSuccessCodes, readerConfig)
6570

6671
}
6772

6873
def apply[Alg[_[_, _, _, _, _]]](
6974
serviceI: Service[Alg],
7075
client: RequestClient,
71-
additionalSuccessCodes: List[Int]
76+
additionalSuccessCodes: List[Int],
77+
readerConfig: ReaderConfig
7278
)(implicit ec: ExecutionContext): Alg[Kind1[RunnableClientRequest]#toKind5] =
73-
new GenericAPIClient(serviceI, client, additionalSuccessCodes).transformer()
79+
new GenericAPIClient(serviceI, client, readerConfig, additionalSuccessCodes).transformer()
7480

7581
def apply[Alg[_[_, _, _, _, _]]](
7682
serviceI: Service[Alg],
7783
additionalHeaders: Option[Map[String, Seq[String]]],
7884
additionalSuccessCodes: List[Int],
79-
client: RequestClient
85+
client: RequestClient,
86+
readerConfig: ReaderConfig
8087
)(implicit ec: ExecutionContext): Alg[Kind1[ClientResponse]#toKind5] =
81-
new GenericAPIClient(serviceI, client, additionalSuccessCodes).transformer(additionalHeaders)
88+
new GenericAPIClient(serviceI, client, readerConfig, additionalSuccessCodes).transformer(additionalHeaders)
8289

8390
}

smithy4play/src/main/scala/de/innfactory/smithy4play/client/SmithyPlayClient.scala

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package de.innfactory.smithy4play.client
22

33
import cats.implicits.toBifunctorOps
4-
import de.innfactory.smithy4play.ClientResponse
4+
import com.github.plokhotnyuk.jsoniter_scala.core.ReaderConfig
5+
import de.innfactory.smithy4play.{ ClientResponse, CodecDecider }
56
import smithy4s.Blob
67
import smithy4s.http.{ CaseInsensitive, HttpEndpoint }
78

@@ -11,6 +12,7 @@ class SmithyPlayClient[Alg[_[_, _, _, _, _]], F[_]](
1112
baseUri: String,
1213
val service: smithy4s.Service[Alg],
1314
client: RequestClient,
15+
codecDecider: CodecDecider,
1416
additionalSuccessCodes: List[Int] = List.empty
1517
)(implicit executionContext: ExecutionContext) {
1618

@@ -31,7 +33,8 @@ class SmithyPlayClient[Alg[_[_, _, _, _, _]], F[_]](
3133
httpEndpoint = httpEndpoint,
3234
input = service.input(op),
3335
serviceHints = service.hints,
34-
client = client
36+
client = client,
37+
codecDecider = codecDecider
3538
).send()
3639
)
3740
.toOption

smithy4play/src/main/scala/de/innfactory/smithy4play/client/SmithyPlayClientEndpoint.scala

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ private[smithy4play] class SmithyPlayClientEndpoint[Op[_, _, _, _, _], I, E, O,
1717
additionalSuccessCodes: List[Int],
1818
httpEndpoint: HttpEndpoint[I],
1919
input: I,
20-
client: RequestClient
20+
client: RequestClient,
21+
codecDecider: CodecDecider
2122
)(implicit executionContext: ExecutionContext) {
2223

2324
private implicit val inputSchema: Schema[I] = endpoint.input
@@ -53,7 +54,7 @@ private[smithy4play] class SmithyPlayClientEndpoint[Op[_, _, _, _, _], I, E, O,
5354
}
5455

5556
private def writeInputToBlob(input: I, contentType: Seq[String]): EndpointRequest = {
56-
val codecs = CodecDecider.requestEncoder(contentType)
57+
val codecs = codecDecider.requestEncoder(contentType)
5758
codecs.fromSchema(inputSchema).write(PlayHttpRequest(Blob.empty, Metadata.empty), input)
5859
}
5960

@@ -72,7 +73,7 @@ private[smithy4play] class SmithyPlayClientEndpoint[Op[_, _, _, _, _], I, E, O,
7273
Future {
7374
val headers = response.headers.map(x => (x._1, x._2))
7475
val contentType = headers.getOrElse(contentTypeKey, Seq(serviceContentType))
75-
val codec = CodecDecider.httpResponseDecoder(contentType)
76+
val codec = codecDecider.httpResponseDecoder(contentType)
7677

7778
codec
7879
.fromSchema(outputSchema)

smithy4play/src/main/scala/de/innfactory/smithy4play/package.scala

+39-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package de.innfactory
33
import alloy.SimpleRestJson
44
import aws.protocols.RestXml
55
import cats.data.{ EitherT, Kleisli }
6+
import com.github.plokhotnyuk.jsoniter_scala.core.ReaderConfig
7+
import com.typesafe.config.Config
68
import de.innfactory.smithy4play.client.SmithyPlayClientEndpointErrorResponse
79
import org.slf4j
810
import play.api.Logger
@@ -15,6 +17,7 @@ import smithy4s.http.{ CaseInsensitive, HttpEndpoint, HttpResponse, Metadata }
1517
import scala.annotation.{ compileTimeOnly, StaticAnnotation }
1618
import scala.concurrent.Future
1719
import scala.language.experimental.macros
20+
import scala.util.Try
1821
import scala.util.matching.Regex
1922
import scala.xml.Elem
2023

@@ -65,6 +68,42 @@ package object smithy4play {
6568
}
6669
}
6770

71+
implicit class EnhancedReaderConfig(readerConfig: ReaderConfig) {
72+
73+
def fromApplicationConfig(config: Config): ReaderConfig = {
74+
val maxCharBufSize =
75+
Try(config.getInt("smithy4play.jsoniter.maxCharBufSize")).toOption
76+
val preferredBufSize =
77+
Try(config.getInt("smithy4play.jsoniter.preferredBufSize")).toOption
78+
val preferredCharBufSize =
79+
Try(config.getInt("smithy4play.jsoniter.preferredCharBufSize")).toOption
80+
val hexDumpSize =
81+
Try(config.getInt("smithy4play.jsoniter.hexDumpSize")).toOption
82+
val maxBufSize =
83+
Try(config.getInt("smithy4play.jsoniter.MaxBufSize")).toOption
84+
val throwReaderExceptionWithStackTrace =
85+
Try(config.getBoolean("smithy4play.jsoniter.throwReaderExceptionWithStackTrace")).toOption
86+
val appendHexDumpToParseException =
87+
Try(config.getBoolean("smithy4play.jsoniter.appendHexDumpToParseException")).toOption
88+
val checkForEndOfInput =
89+
Try(config.getBoolean("smithy4play.jsoniter.checkForEndOfInput")).toOption
90+
91+
readerConfig
92+
.withMaxCharBufSize(maxCharBufSize.getOrElse(readerConfig.maxCharBufSize))
93+
.withPreferredBufSize(preferredBufSize.getOrElse(readerConfig.preferredBufSize))
94+
.withCheckForEndOfInput(checkForEndOfInput.getOrElse(readerConfig.checkForEndOfInput))
95+
.withPreferredCharBufSize(preferredCharBufSize.getOrElse(readerConfig.preferredCharBufSize))
96+
.withHexDumpSize(hexDumpSize.getOrElse(readerConfig.hexDumpSize))
97+
.withMaxBufSize(maxBufSize.getOrElse(readerConfig.maxBufSize))
98+
.withAppendHexDumpToParseException(
99+
appendHexDumpToParseException.getOrElse(readerConfig.appendHexDumpToParseException)
100+
)
101+
.withThrowReaderExceptionWithStackTrace(
102+
throwReaderExceptionWithStackTrace.getOrElse(readerConfig.throwReaderExceptionWithStackTrace)
103+
)
104+
}
105+
}
106+
68107
implicit class EnhancedThrowable(throwable: Throwable) {
69108
private val regex1: Regex = """(?s), offset: (?:0x)?[0-9a-fA-F]+, buf:.*""".r
70109
private val regex2: Regex = """(.*), offset: .*, buf:.* (\(path:.*\))""".r
@@ -77,7 +116,6 @@ package object smithy4play {
77116
case msg => regex1.replaceAllIn(msg, "")
78117
}
79118
)
80-
81119
}
82120

83121
private[smithy4play] case class Smithy4PlayError(

smithy4playTest/test/XmlControllerTest.scala

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
1-
import de.innfactory.smithy4play.CodecDecider
21
import de.innfactory.smithy4play.client.GenericAPIClient.EnhancedGenericAPIClient
32
import de.innfactory.smithy4play.client.SmithyPlayTestUtils._
43
import models.NodeImplicits.NodeEnhancer
54
import models.TestBase
65
import play.api.Application
76
import play.api.inject.guice.GuiceApplicationBuilder
8-
import play.api.libs.json.{ JsValue, Json, OFormat }
7+
import play.api.libs.json.{Json, OFormat}
98
import play.api.test.FakeRequest
109
import play.api.test.Helpers._
11-
import smithy4s.Blob
1210
import smithy4s.http.CaseInsensitive
13-
import testDefinitions.test.{ XmlTestInputBody, XmlControllerDefGen, XmlTestOutput }
11+
import testDefinitions.test.{XmlControllerDefGen, XmlTestInputBody, XmlTestOutput}
1412

15-
import scala.xml._
1613
import scala.concurrent.ExecutionContext.Implicits.global
17-
import scala.xml.{ Elem, Node, PrettyPrinter }
1814

1915
class XmlControllerTest extends TestBase {
2016

0 commit comments

Comments
 (0)