0

Is there a way to convert javadsl Route to Flow? In Scala we have handlerFlow available implicitly, but in Java we have no analogues.

Tried to call handlerFlow, but it uses scaladsl types and incompatible with javadsl version of Route.

I want to use low-level version of API for ability to bind to http and https, and to be able to access connections.

==========================
Update: I used idea from svezfaz's answer and now I get code:

Flow<HttpRequest, HttpResponse, NotUsed> createFlow(ActorSystem system, Materializer mat) {
  scala.Function1<akka.http.scaladsl.server.RequestContext, scala.concurrent.Future<akka.http.scaladsl.server.RouteResult>> r = RouteImplementation.apply(createRoute());
  Flow f = RouteResult$.MODULE$.route2HandlerFlow(
      r,
      RoutingSettings$.MODULE$.apply(system),
      ParserSettings$.MODULE$.apply(system),
      mat,
      RoutingLog$.MODULE$.fromActorSystem(system),
      null,
      RejectionHandler$.MODULE$._mthdefault(),
      null
      ).asJava();
  return f;
}

It looks correct, but it doesn't compile. Probably, I have to include Scala Library into classpath. And then work a little with other Scala-to-Java type conversions.

I think it just easier to rewrite it w/o Routes in Java.

Cyrille Corpet
  • 5,265
  • 1
  • 14
  • 31
EuDgee
  • 13
  • 5

2 Answers2

1

You can take inspiration from akka.http.javadsl.server.HttpServiceBase (see below). Use RouteImplementation to convert javadsl to scaladsl, then call route2HandlerFlow to convert to flow.

  /**
   * Uses the route to handle incoming connections and requests for the ServerBinding.
   */
  def handleConnectionsWithRoute(interface: String, port: Int, route: Route, system: ActorSystem, materializer: Materializer): CompletionStage[ServerBinding] = {
    implicit val s = system
    implicit val m = materializer

    import system.dispatcher
    val r: server.Route = RouteImplementation(route)
    Http(system).bind(interface, port).toMat(Sink.foreach(_.handleWith(akka.http.scaladsl.server.RouteResult.route2HandlerFlow(r))))(Keep.left).run()(materializer).toJava
  }
Stefano Bonetti
  • 8,973
  • 1
  • 25
  • 44
1

In akka-http 10.0.6, you can use

akka.http.scaladsl.server.Route.handlerFlow(route: Route): Flow[HttpRequest, HttpResponse, NotUsed]

There are some implicits needed, but they are easy to get into scope.

Cyrille Corpet
  • 5,265
  • 1
  • 14
  • 31