Skip to content

Commit

Permalink
http (feature): Support Scala 3.3.1 (#3202)
Browse files Browse the repository at this point in the history
- internal: Upgrade airspec to 23.9.0 (#3193)
- Update scala3-staging, ... to 3.3.1
- deprecate registerTraitFactory #3200 
- Fix grpc tests for Scala 3

---------

Co-authored-by: xerial-bot <leo+bot@xerial.org>
  • Loading branch information
xerial and xerial-bot authored Sep 8, 2023
1 parent 3158b64 commit fa553d0
Show file tree
Hide file tree
Showing 17 changed files with 119 additions and 143 deletions.
64 changes: 32 additions & 32 deletions airframe-di/src/main/scala-3/wvlet/airframe/BinderImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ private[airframe] trait BinderImpl[A] extends LogSupport { self: Binder[A] =>
*/
inline def to[B <: A]: DesignWithContext[B] = {
{
registerTraitFactory[B]
// registerTraitFactory[B]
val to = Surface.of[B]
if (self.from == to) {
wvlet.log.Logger("wvlet.airframe.Binder").warn("Binding to the same type is not allowed: " + to.toString)
Expand All @@ -28,7 +28,7 @@ private[airframe] trait BinderImpl[A] extends LogSupport { self: Binder[A] =>

inline def toEagerSingletonOf[B <: A]: DesignWithContext[B] = {
{
registerTraitFactory[B]
// registerTraitFactory[B]
val to = Surface.of[B]
if (self.from == to) {
wvlet.log.Logger("wvlet.airframe.Binder").warn("Binding to the same type is not allowed: " + to.toString)
Expand All @@ -39,7 +39,7 @@ private[airframe] trait BinderImpl[A] extends LogSupport { self: Binder[A] =>
}

inline def toProvider[D1](factory: D1 => A): DesignWithContext[A] = {
registerTraitFactory[D1]
// registerTraitFactory[D1]
self.design.addBinding[A](
ProviderBinding(
DependencyFactory(self.from, Seq(Surface.of[D1]), factory),
Expand All @@ -50,8 +50,8 @@ private[airframe] trait BinderImpl[A] extends LogSupport { self: Binder[A] =>
)
}
inline def toProvider[D1, D2](factory: (D1, D2) => A): DesignWithContext[A] = {
registerTraitFactory[D1]
registerTraitFactory[D2]
// registerTraitFactory[D1]
// registerTraitFactory[D2]
self.design.addBinding[A](
ProviderBinding(
DependencyFactory(self.from, Seq(Surface.of[D1], Surface.of[D2]), factory),
Expand All @@ -62,9 +62,9 @@ private[airframe] trait BinderImpl[A] extends LogSupport { self: Binder[A] =>
)
}
inline def toProvider[D1, D2, D3](factory: (D1, D2, D3) => A): DesignWithContext[A] = {
registerTraitFactory[D1]
registerTraitFactory[D2]
registerTraitFactory[D3]
// registerTraitFactory[D1]
// registerTraitFactory[D2]
// registerTraitFactory[D3]
self.design.addBinding[A](
ProviderBinding(
DependencyFactory(self.from, Seq(Surface.of[D1], Surface.of[D2], Surface.of[D3]), factory),
Expand All @@ -75,10 +75,10 @@ private[airframe] trait BinderImpl[A] extends LogSupport { self: Binder[A] =>
)
}
inline def toProvider[D1, D2, D3, D4](factory: (D1, D2, D3, D4) => A): DesignWithContext[A] = {
registerTraitFactory[D1]
registerTraitFactory[D2]
registerTraitFactory[D3]
registerTraitFactory[D4]
// registerTraitFactory[D1]
// registerTraitFactory[D2]
// registerTraitFactory[D3]
// registerTraitFactory[D4]
self.design.addBinding[A](
ProviderBinding(
DependencyFactory(self.from, Seq(Surface.of[D1], Surface.of[D2], Surface.of[D3], Surface.of[D4]), factory),
Expand All @@ -89,11 +89,11 @@ private[airframe] trait BinderImpl[A] extends LogSupport { self: Binder[A] =>
)
}
inline def toProvider[D1, D2, D3, D4, D5](factory: (D1, D2, D3, D4, D5) => A): DesignWithContext[A] = {
registerTraitFactory[D1]
registerTraitFactory[D2]
registerTraitFactory[D3]
registerTraitFactory[D4]
registerTraitFactory[D5]
// registerTraitFactory[D1]
// registerTraitFactory[D2]
// registerTraitFactory[D3]
// registerTraitFactory[D4]
// registerTraitFactory[D5]
self.design.addBinding[A](
ProviderBinding(
DependencyFactory(
Expand All @@ -109,7 +109,7 @@ private[airframe] trait BinderImpl[A] extends LogSupport { self: Binder[A] =>
}

inline def toEagerSingletonProvider[D1](factory: D1 => A): DesignWithContext[A] = {
registerTraitFactory[D1]
// registerTraitFactory[D1]
self.design.addBinding[A](
ProviderBinding(
DependencyFactory(self.from, Seq(Surface.of[D1]), factory),
Expand All @@ -120,8 +120,8 @@ private[airframe] trait BinderImpl[A] extends LogSupport { self: Binder[A] =>
)
}
inline def toEagerSingletonProvider[D1, D2](factory: (D1, D2) => A): DesignWithContext[A] = {
registerTraitFactory[D1]
registerTraitFactory[D2]
// registerTraitFactory[D1]
// registerTraitFactory[D2]
self.design.addBinding[A](
ProviderBinding(
DependencyFactory(self.from, Seq(Surface.of[D1], Surface.of[D2]), factory),
Expand All @@ -132,9 +132,9 @@ private[airframe] trait BinderImpl[A] extends LogSupport { self: Binder[A] =>
)
}
inline def toEagerSingletonProvider[D1, D2, D3](factory: (D1, D2, D3) => A): DesignWithContext[A] = {
registerTraitFactory[D1]
registerTraitFactory[D2]
registerTraitFactory[D3]
// registerTraitFactory[D1]
// registerTraitFactory[D2]
// registerTraitFactory[D3]
self.design.addBinding[A](
ProviderBinding(
DependencyFactory(self.from, Seq(Surface.of[D1], Surface.of[D2], Surface.of[D3]), factory),
Expand All @@ -145,10 +145,10 @@ private[airframe] trait BinderImpl[A] extends LogSupport { self: Binder[A] =>
)
}
inline def toEagerSingletonProvider[D1, D2, D3, D4](factory: (D1, D2, D3, D4) => A): DesignWithContext[A] = {
registerTraitFactory[D1]
registerTraitFactory[D2]
registerTraitFactory[D3]
registerTraitFactory[D4]
// registerTraitFactory[D1]
// registerTraitFactory[D2]
// registerTraitFactory[D3]
// registerTraitFactory[D4]
self.design.addBinding[A](
ProviderBinding(
DependencyFactory(self.from, Seq(Surface.of[D1], Surface.of[D2], Surface.of[D3], Surface.of[D4]), factory),
Expand All @@ -159,11 +159,11 @@ private[airframe] trait BinderImpl[A] extends LogSupport { self: Binder[A] =>
)
}
inline def toEagerSingletonProvider[D1, D2, D3, D4, D5](factory: (D1, D2, D3, D4, D5) => A): DesignWithContext[A] = {
registerTraitFactory[D1]
registerTraitFactory[D2]
registerTraitFactory[D3]
registerTraitFactory[D4]
registerTraitFactory[D5]
// registerTraitFactory[D1]
// registerTraitFactory[D2]
// registerTraitFactory[D3]
// registerTraitFactory[D4]
// registerTraitFactory[D5]
self.design.addBinding[A](
ProviderBinding(
DependencyFactory(
Expand Down
5 changes: 3 additions & 2 deletions airframe-di/src/main/scala-3/wvlet/airframe/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ package object airframe {
traitFactoryCache.getOrElseUpdate(s, factory)
}

inline def registerTraitFactory[A]: Unit = ${
registerTraitFactoryImpl[A]
@deprecated("Instantiating trait is still experimental in Scala 3.3.1", "23.9.1")
inline def registerTraitFactory[A]: Unit = {
// registerTraitFactoryImpl[A]
}

import scala.quoted._
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ object TraitFactoryTest extends AirSpec {
trait A

test("register trait factory") {
if (isScala3) {
pending("In Scala 3.3.1, creating a new trait instance via macro is still experimental")
}
registerTraitFactory[A]
traitFactoryCache.get(Surface.of[A]) shouldBe defined
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ package wvlet.airframe.http.grpc
import io.grpc.Status
import io.grpc.Status.Code
import io.grpc.StatusRuntimeException
import wvlet.airframe.http.{RPCException, RPCStatus, Router}
import wvlet.airframe.http.{RPCException, RPCStatus, Router, RxRouter}
import wvlet.airframe.http.grpc.GrpcErrorLogTest.DemoApiDebug
import wvlet.airframe.http.grpc.example.DemoApi.DemoApiClient
import wvlet.airframe.http.grpc.internal.GrpcException
Expand All @@ -30,7 +30,7 @@ object GrpcErrorHandlingTest extends AirSpec {
protected override def design = {
gRPC.server
.withName("error-handling-test-api")
.withRouter(Router.add[DemoApiDebug])
.withRouter(RxRouter.of[DemoApiDebug])
.designWithChannel
}

Expand All @@ -45,6 +45,7 @@ object GrpcErrorHandlingTest extends AirSpec {
l.setLogLevel(previousLogLevel)
}
}

test("exception test") { (client: DemoApiClient) =>
warn("Starting a gRPC error handling test")
suppressLog("wvlet.airframe.http.grpc.internal") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,9 @@ package wvlet.airframe.http.grpc
import wvlet.airframe.http.grpc.example.DemoApi
import wvlet.airframe.http.grpc.example.DemoApi.DemoApiClient
import wvlet.airframe.http.grpc.internal.GrpcRequestLogger
import wvlet.airframe.http.Router
import wvlet.airframe.http.HttpAccessLogWriter
import wvlet.airspec.AirSpec
import wvlet.airframe.http.{HttpAccessLogWriter, Router, RxRouter}
import wvlet.airframe.rx.Rx
import wvlet.log.Logger
import wvlet.airspec.AirSpec

import scala.util.{Failure, Try}

Expand All @@ -44,7 +42,7 @@ object GrpcErrorLogTest extends AirSpec {
}
}

private val router = Router.of[DemoApiDebug]
private val router = RxRouter.of[DemoApiDebug]

protected override def design = {
gRPC.server
Expand All @@ -55,6 +53,7 @@ object GrpcErrorLogTest extends AirSpec {
.newLogger(config.name, inMemoryLogWriter)
}
.designWithChannel
.bind[Router].toInstance(Router.of[DemoApiDebug])
}

private def captureAll(body: => Unit): Seq[Map[String, Any]] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
package wvlet.airframe.http.grpc

import wvlet.airframe.http.{RPCEncoding, Router}
import wvlet.airframe.http.grpc.example.DemoApi
import wvlet.airframe.http.grpc.example.{DemoApi, DemoApiImpl}
import wvlet.airframe.http.grpc.example.DemoApi.DemoApiClient
import wvlet.airspec.AirSpec
import wvlet.airframe.rx._
Expand All @@ -23,7 +23,7 @@ import wvlet.airframe.rx._
*/
class GrpcJsonTest extends AirSpec {

private def router = Router.add[DemoApi]
private def router = Router.add[DemoApiImpl]

protected override def design = gRPC.server.withRouter(router).designWithChannel

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class GrpcRequestLoggerTest extends AirSpec {
log("path") shouldBe "/wvlet.airframe.http.grpc.example.DemoApi/hello"
log("content_type") shouldBe "application/grpc"
log("rpc_interface") shouldBe "wvlet.airframe.http.grpc.example.DemoApi"
log("rpc_class") shouldBe "wvlet.airframe.http.grpc.example.DemoApi"
log("rpc_class") shouldBe "wvlet.airframe.http.grpc.example.DemoApiImpl"
log("rpc_method") shouldBe "hello"
log("rpc_args") shouldBe Map("name" -> "gRPC")
log.contains("time") shouldBe true
Expand All @@ -78,7 +78,7 @@ class GrpcRequestLoggerTest extends AirSpec {
log("path") shouldBe "/wvlet.airframe.http.grpc.example.DemoApi/helloClientStreaming"
log("content_type") shouldBe "application/grpc"
log("rpc_interface") shouldBe "wvlet.airframe.http.grpc.example.DemoApi"
log("rpc_class") shouldBe "wvlet.airframe.http.grpc.example.DemoApi"
log("rpc_class") shouldBe "wvlet.airframe.http.grpc.example.DemoApiImpl"
log("rpc_method") shouldBe "helloClientStreaming"
// Do not record rpc_args for client-streaming
log.get("rpc_args") shouldBe empty
Expand All @@ -102,7 +102,7 @@ class GrpcRequestLoggerTest extends AirSpec {
log("path") shouldBe "/wvlet.airframe.http.grpc.example.DemoApi/helloStreaming"
log("content_type") shouldBe "application/grpc"
log("rpc_interface") shouldBe "wvlet.airframe.http.grpc.example.DemoApi"
log("rpc_class") shouldBe "wvlet.airframe.http.grpc.example.DemoApi"
log("rpc_class") shouldBe "wvlet.airframe.http.grpc.example.DemoApiImpl"
log("rpc_method") shouldBe "helloStreaming"
// Do not record rpc_args for client-streaming
log("rpc_args") shouldBe Map("name" -> "gRPC")
Expand All @@ -126,7 +126,7 @@ class GrpcRequestLoggerTest extends AirSpec {
log("path") shouldBe "/wvlet.airframe.http.grpc.example.DemoApi/helloBidiStreaming"
log("content_type") shouldBe "application/grpc"
log("rpc_interface") shouldBe "wvlet.airframe.http.grpc.example.DemoApi"
log("rpc_class") shouldBe "wvlet.airframe.http.grpc.example.DemoApi"
log("rpc_class") shouldBe "wvlet.airframe.http.grpc.example.DemoApiImpl"
log("rpc_method") shouldBe "helloBidiStreaming"
// Do not record rpc_args for client-streaming
log.get("rpc_args") shouldBe empty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
package wvlet.airframe.http.grpc

import wvlet.airframe.http.Router
import wvlet.airframe.http.grpc.example.DemoApi
import wvlet.airframe.http.grpc.example.{DemoApi, DemoApiImpl}
import wvlet.airframe.http.grpc.example.DemoApi.DemoApiClient
import wvlet.airframe.rx.Rx
import wvlet.airspec.AirSpec
Expand All @@ -23,7 +23,7 @@ import wvlet.airspec.AirSpec
*/
object GrpcStreamingTest extends AirSpec {

private lazy val router: Router = Router.add[DemoApi]
private lazy val router: Router = Router.add[DemoApiImpl]
protected override def design = {
gRPC.server.withRouter(router).designWithChannel
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import wvlet.airframe.rx.Rx
import wvlet.log.LogSupport
import wvlet.airframe.http.router.Route

class DemoApiImpl extends DemoApi

@RPC
trait DemoApi extends LogSupport {
def getContext: String = {
Expand Down Expand Up @@ -132,21 +134,15 @@ object DemoApi extends LogSupport {
}
}

val router = Router.add[DemoApiImpl]

def design: Design = gRPC.server
.withRouter(router)
.withName("DemoApi")
.withInterceptor(contextTestInterceptor)
.designWithChannel
.bind[DemoApiClient].toProvider { (channel: Channel) => new DemoApiClient(channel) }

val router = Router.add[DemoApi]

private def getRoute(name: String): Route = {
router.routes.find(_.methodSurface.name == name).getOrElse {
throw new IllegalArgumentException(s"Route is not found :${name}")
}
}

/**
* Manually build a gRPC client here as we can't use sbt-airframe.
* @param channel
Expand All @@ -163,6 +159,13 @@ object DemoApi extends LogSupport {
override def build(channel: Channel, callOptions: CallOptions): DemoApiClient = {
new DemoApiClient(channel, callOptions)
}

private def getRoute(name: String): Route = {
router.routes.find(_.methodSurface.name == name).getOrElse {
throw new IllegalArgumentException(s"Route is not found :${name}")
}
}

private val codec = codecFactory.of[Map[String, Any]]
private val getContextMethodDescriptor =
GrpcServiceBuilder.buildMethodDescriptor(getRoute("getContext"), codecFactory)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import wvlet.airframe.http.router.Route
* Demo gRPC API used for GrpcClientTest
*/
@RPC
trait DemoApiV2 extends LogSupport {
class DemoApiV2 extends LogSupport {
def hello(name: String): String = {
name match {
case "XXX" =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import wvlet.airframe.http.router.Route
/**
*/
@RPC
trait Greeter {
class Greeter {
def hello(name: String): String = s"Hello ${name}!"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ case class User(id: Int, name: String, requestId: String) {
case class UserRequest(id: Int, name: String)
case class DeleteRequestBody(force: Boolean)

trait NettyTestApi extends LogSupport {
class NettyTestApi extends LogSupport {
import wvlet.airframe.http.{Endpoint, HttpMethod}

@Endpoint(method = HttpMethod.GET, path = "/")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@ import wvlet.airframe.surface.Surface

trait RxRouterObjectBase {
inline def of[Controller]: RxRouter = {
wvlet.airframe.registerTraitFactory[Controller]
// wvlet.airframe.registerTraitFactory[Controller]
RxRouter.EndpointNode(Surface.of[Controller], Surface.methodsOf[Controller], None)
}

inline def filter[Filter <: RxHttpFilter]: RxRouter.FilterNode = {
wvlet.airframe.registerTraitFactory[Filter]
// wvlet.airframe.registerTraitFactory[Filter]
RxRouter.FilterNode(None, Surface.of[Filter])
}
}

trait RxRouteFilterBase { self: RxRouter.FilterNode =>
inline def andThen[Filter <: RxHttpFilter]: RxRouter.FilterNode = {
wvlet.airframe.registerTraitFactory[Filter]
// wvlet.airframe.registerTraitFactory[Filter]
val next = RxRouter.FilterNode(None, Surface.of[Filter])
self.andThen(next)
}
Expand Down
Loading

0 comments on commit fa553d0

Please sign in to comment.