This project uses Lagom's DevMode to start a Lagom Service and a Play Application (from now on referred to as "the proxy services").
The proxy services are reachable at:
$ curl http://localhost:9000/api/hello/arthur ## the lagom service
$ curl http://localhost:9000/play/hello ## the play app
These two proxy services offer a single HTTP/1.1 endpoint each that proxies the request to "localhost:8080" using an akka-grpc client.
This project runs an embedded akka-grpc server bound to port 8080. This is embedded inside the Lagom service so that when using runAll
, the lagom service will start and the lagom service will also start the akka-grpc server. Summing up: there are 2 processes with a total of three services:
- lagom service process: lagom service endpoint + embedded akka-grpc server on port 8080
- play app process: play app endpoint
Again, running an embedded akka-grpc is a hack until play and lagom can serve grpc.
The .proto
used between the two is a simplified version of the example in the Akka-gRPC docs
This repo depends on a local build of akka-grpc#7d6b719, so clone that and build it locally.
ATTENTION: the injection of a javaAgent is reguired but this remains an unsolved issue. Edit the .jvmopts
file to set the absolute path to the ALPN agent in your local ivy cache.
Run sbt runAll
.
Finally test using curl http://localhost:9000/api/hello/arthur
or curl http://localhost:9000/play/hello
.
The goal of this lab is to find investigate Dev eXperience alternatives so that building a gRPC client that runs within a Lagom service (or a Play app) is as simple as:
(the following is just an alternative, not a final design)
abstract class HelloApplication(context: LagomApplicationContext)
extends LagomApplication(context)
with AhcWSComponents
with GrpcComponents { // Add this (1)
val client: GreetingsService = wire[GreetingsServiceClient] // Add this to use a client to a remote GrpcEchoServer (2)
// regular Lagom stuff creating the Service. (3)
override lazy val lagomServer = serverFor[HelloService](wire[HelloServiceImpl])
}
- Use a
Components
- Wire the gRPC interface to a client
- Inject thhe client into regular code.
src/main/resources/certs
contains some baked certs, PEMs and keys to use during testing with SSL enabled. Note that the clients only useca.pem
while the hhacked embedded server uses thekey.*
src/main/scala
com.example.internal
is code that could eventually be part of Lagomcom.example.hello.impl
is userland codeHelloLoader.scala
contains theGreetinsServiceClient
that would be generated via Lagom's GrpcGenerators usingakka-grpc-sbt-plugin
infra. Maybe Lagom extends theakka-grpc-sbt-plugin
to simplify.HelloLoader.scala
contains a regular LagomHelloLoader
that mixes in the GrpcComponents and wires anEchoClient
The Play code is very similar to the Lagom service code but simpler. We developed the Play App using Maven Layout to ease comparing both codebases.
-
Support Streamed calls.
-
Improve the UX in
build.sbt
:
lazy val `hello-impl` = (project in file("hello-impl"))
.enablePlugins(LagomScala, JavaAgent, AkkaGrpcPlugin)
.settings(
libraryDependencies ++= Seq(
macwire,
scalaTest
),
)
.settings(
PB.protoSources in Compile += target.value / "protobuf",
(akkaGrpcCodeGenerators in Compile) := Seq(
GeneratorAndSettings(ScalaClientCodeGenerator, (akkaGrpcCodeGeneratorSettings in Compile).value)),
javaAgents += "org.mortbay.jetty.alpn" % "jetty-alpn-agent" % "2.0.6" % "runtime",
)
.settings(lagomForkedTestSettings: _*)
.dependsOn(`hello-api`)
-
Manage SSL on dev mode. We'll probably need to allow the setup of CA's on the build so that users can inject their organizationCA when testing with gRPC services implemented by other teams
-
...