/runtime/src/main/scala/akka/grpc/javadsl/ServiceHandler.scala

https://github.com/akka/akka-grpc · Scala · 64 lines · 33 code · 11 blank · 20 comment · 5 complexity · bc826d915b71d919f7ee88e8e9d6f04e MD5 · raw file

  1. /*
  2. * Copyright (C) 2018-2020 Lightbend Inc. <https://www.lightbend.com>
  3. */
  4. package akka.grpc.javadsl
  5. import java.util.concurrent.{ CompletableFuture, CompletionStage }
  6. import akka.annotation.ApiMayChange
  7. import akka.annotation.InternalApi
  8. import akka.grpc.scaladsl.{ ServiceHandler => sServiceHandler }
  9. import akka.http.javadsl.model.{ HttpRequest, HttpResponse, StatusCodes }
  10. // using japi because bindAndHandleAsync expects that
  11. import akka.japi.{ Function => JFunction }
  12. import scala.annotation.varargs
  13. @ApiMayChange
  14. object ServiceHandler {
  15. /**
  16. * INTERNAL API
  17. */
  18. @InternalApi
  19. private[javadsl] val notFound: CompletionStage[HttpResponse] =
  20. CompletableFuture.completedFuture(HttpResponse.create().withStatus(StatusCodes.NOT_FOUND))
  21. /**
  22. * INTERNAL API
  23. */
  24. @InternalApi
  25. private[javadsl] val unsupportedMediaType: CompletionStage[HttpResponse] =
  26. CompletableFuture.completedFuture(HttpResponse.create().withStatus(StatusCodes.UNSUPPORTED_MEDIA_TYPE))
  27. /**
  28. * This is an alias for handler.
  29. */
  30. @varargs
  31. def concatOrNotFound(handlers: JFunction[HttpRequest, CompletionStage[HttpResponse]]*)
  32. : JFunction[HttpRequest, CompletionStage[HttpResponse]] =
  33. handler(handlers: _*)
  34. /**
  35. * Creates a `HttpRequest` to `HttpResponse` handler for gRPC services that can be used in
  36. * for example `Http().bindAndHandleAsync` for the generated partial function handlers:
  37. * - The generated handler supports the `application/grpc` media type.
  38. * - If the request is for an invalid media type, then a _415: Unsupported Media Type_ response is produced.
  39. * - Otherwise if the request is not handled by one of the provided handlers, a _404: Not Found_ response is produced.
  40. */
  41. @varargs
  42. def handler(handlers: JFunction[HttpRequest, CompletionStage[HttpResponse]]*)
  43. : JFunction[HttpRequest, CompletionStage[HttpResponse]] = {
  44. val servicesHandler = concat(handlers: _*)
  45. (req: HttpRequest) => if (sServiceHandler.isGrpcRequest(req)) servicesHandler(req) else unsupportedMediaType
  46. }
  47. private[javadsl] def concat(handlers: JFunction[HttpRequest, CompletionStage[HttpResponse]]*)
  48. : JFunction[HttpRequest, CompletionStage[HttpResponse]] =
  49. (req: HttpRequest) =>
  50. handlers.foldLeft(notFound) { (comp, next) =>
  51. comp.thenCompose(res => if (res.status == StatusCodes.NOT_FOUND) next.apply(req) else comp)
  52. }
  53. }