Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Server-side power API #179 #429

Merged
merged 45 commits into from
Feb 25, 2019
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
6d90c85
Draft implementation
ctoomey Oct 2, 2018
b983c53
Fix missing content-type header in Play response
ctoomey Oct 8, 2018
ff4f0d1
Fixed missing Content-Type header
ctoomey Oct 8, 2018
4a9515c
Ripped out Play changes
ctoomey Oct 13, 2018
2d8872f
Cleanup
ctoomey Oct 13, 2018
42a9431
Remove PowerAPI from generated names
ctoomey Oct 13, 2018
502072b
Remove PowerAPI from generated names
ctoomey Oct 13, 2018
fe75c41
Merge power API handling into handler template
ctoomey Oct 15, 2018
73e9397
Merge power API handling into handler template
ctoomey Oct 15, 2018
fb86f38
Merge remote-tracking branch 'upstream/master' into 179-server-power-…
ctoomey Oct 27, 2018
747744e
Integrate extended code generator options into akkaGrpcCodeGeneratorS…
ctoomey Oct 28, 2018
54c863c
Integrate extended code generator options into akkaGrpcCodeGeneratorS…
ctoomey Oct 28, 2018
f7ac227
Fix enum
ctoomey Oct 28, 2018
8a346af
Make GeneratorOption accessible
ctoomey Oct 28, 2018
d06be06
Latest changes requested on PR
ctoomey Nov 12, 2018
2522ccc
Latest changes requested on PR
ctoomey Nov 12, 2018
3a1a1b4
Latest PR-requested updates
ctoomey Nov 12, 2018
cf28c1f
Fix handler name in comments
ctoomey Nov 25, 2018
bd37a4d
Changed handling of server power APIs generator option
ctoomey Nov 25, 2018
c37e267
Revert "Changed handling of server power APIs generator option"
ctoomey Nov 25, 2018
d8eae54
Revert unrelated package name fix
ctoomey Nov 25, 2018
bff5466
Fix handling of both client/server generators
ctoomey Dec 3, 2018
84b0335
Updated ReflectiveCodeGen
ctoomey Dec 10, 2018
f92a635
Update Java code generators
ctoomey Dec 17, 2018
58ca34d
Java power API
ctoomey Jan 11, 2019
f39c234
Backed out unfinished Java power API Metadata.asMap
ctoomey Jan 11, 2019
7fe4b78
Java power API
ctoomey Jan 14, 2019
edc28d2
Merge branch 'master' into 179-server-power-apis2.update-from-master
ctoomey Jan 16, 2019
7544cae
Java power API
ctoomey Jan 22, 2019
cebba99
Maven for power APIs
ctoomey Jan 22, 2019
190964f
Fix missing headers warning
ctoomey Jan 22, 2019
fc1d9be
Fix missing headers warning
ctoomey Jan 22, 2019
0af4c9b
Gradle
ctoomey Jan 22, 2019
6a7b9a2
Build tool fixes
ctoomey Jan 23, 2019
b6684eb
Merge branch 'master' into 179-server-power-apis2
ctoomey Jan 24, 2019
ac44100
Power API test for scala
ctoomey Jan 25, 2019
18fd974
Power API test for java
ctoomey Jan 25, 2019
6444b55
Power API test for java
ctoomey Jan 25, 2019
707a5ae
Power API test fixes for maven, gradle
ctoomey Jan 25, 2019
e7481d1
Power API documentation
ctoomey Feb 5, 2019
e2d5b68
Merge branch 'master' into 179-server-power-apis2
ctoomey Feb 5, 2019
e87129e
Merge branch 'master' into 179-server-power-apis2
ctoomey Feb 6, 2019
686aa5d
Power API tweaks
ctoomey Feb 6, 2019
cbfd17b
Updated Play router templates
ctoomey Feb 12, 2019
c8dba56
sbt Play generators moved back to akkaGrpcExtraGenerators
ctoomey Feb 12, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ scalaVersion := scala212

val commonSettings = Seq(
organization := "com.lightbend.akka.grpc",

scalacOptions ++= List(
"-unchecked",
"-deprecation",
Expand Down Expand Up @@ -200,7 +199,7 @@ lazy val pluginTesterScala = Project(
.settings(commonSettings)
.enablePlugins(akka.grpc.NoPublish)
.settings(
ReflectiveCodeGen.codeGeneratorSettings ++= Seq("flat_package")
ReflectiveCodeGen.codeGeneratorSettings ++= Seq("flat_package", "server_power_apis")
)
.pluginTestingSettings

Expand All @@ -213,6 +212,7 @@ lazy val pluginTesterJava = Project(
.enablePlugins(akka.grpc.NoPublish)
.settings(
ReflectiveCodeGen.generatedLanguages := Seq("Java"),
ReflectiveCodeGen.codeGeneratorSettings ++= Seq("server_power_apis")
)
.pluginTestingSettings

Expand Down
91 changes: 41 additions & 50 deletions codegen/src/main/scala/akka/grpc/gen/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,14 @@ package akka.grpc.gen
import java.io.ByteArrayOutputStream

import com.google.protobuf.compiler.PluginProtos.CodeGeneratorRequest
import akka.grpc.gen.javadsl.JavaBothCodeGenerator
import akka.grpc.gen.javadsl.JavaClientCodeGenerator
import akka.grpc.gen.javadsl.JavaServerCodeGenerator
import akka.grpc.gen.javadsl.{ JavaClientCodeGenerator, JavaInterfaceCodeGenerator, JavaPowerApiInterfaceCodeGenerator, JavaServerCodeGenerator }
import akka.grpc.gen.javadsl.play.{ PlayJavaClientCodeGenerator, PlayJavaServerCodeGenerator }
import akka.grpc.gen.scaladsl.ScalaBothCodeGenerator
import akka.grpc.gen.scaladsl.ScalaClientCodeGenerator
import akka.grpc.gen.scaladsl.ScalaServerCodeGenerator
import akka.grpc.gen.scaladsl.{ ScalaClientCodeGenerator, ScalaPowerApiTraitCodeGenerator, ScalaServerCodeGenerator, ScalaTraitCodeGenerator }
import akka.grpc.gen.scaladsl.play.{ PlayScalaClientCodeGenerator, PlayScalaServerCodeGenerator }

// This is the protoc plugin that the gradle plugin uses
object Main extends App {
// throw new RuntimeException(s"beginning of Main")
raboof marked this conversation as resolved.
Show resolved Hide resolved

val inBytes: Array[Byte] = {
val baos = new ByteArrayOutputStream(math.max(64, System.in.available()))
Expand All @@ -42,71 +39,65 @@ object Main extends App {

private val generatePlay: Boolean = reqLowerCase.contains("generate_play=true")

private val serverPowerApis: Boolean = reqLowerCase.contains("server_power_apis=true")

val LogFileRegex = """(?:.*,)logfile=([^,]+)(?:,.*)?""".r
private val logger = req.getParameter match {
case LogFileRegex(path) => new FileLogger(path)
case _ => SilencedLogger
}

val out = {
val codeGenerator =
val codeGenerators =
if (!generatePlay) {
if (languageScala) {
// Scala
if (generateClient && generateServer) ScalaBothCodeGenerator
else if (generateClient) ScalaClientCodeGenerator
else if (generateServer) ScalaServerCodeGenerator
else throw new IllegalArgumentException("At least one of generateClient or generateServer must be enabled")
val base =
if (generateClient && generateServer) Seq(ScalaTraitCodeGenerator, ScalaClientCodeGenerator, ScalaServerCodeGenerator(serverPowerApis))
else if (generateClient) Seq(ScalaTraitCodeGenerator, ScalaClientCodeGenerator)
else if (generateServer) Seq(ScalaTraitCodeGenerator, ScalaServerCodeGenerator(serverPowerApis))
else throw new IllegalArgumentException("At least one of generateClient or generateServer must be enabled")
if (serverPowerApis) Seq(ScalaPowerApiTraitCodeGenerator) ++ base
else base
} else {
// Java
if (generateClient && generateServer) JavaBothCodeGenerator
else if (generateClient) JavaClientCodeGenerator
else if (generateServer) JavaServerCodeGenerator
else throw new IllegalArgumentException("At least one of generateClient or generateServer must be enabled")
val base =
if (generateClient && generateServer) Seq(JavaInterfaceCodeGenerator, JavaClientCodeGenerator, JavaServerCodeGenerator(serverPowerApis))
else if (generateClient) Seq(JavaInterfaceCodeGenerator, JavaClientCodeGenerator)
else if (generateServer) Seq(JavaInterfaceCodeGenerator, JavaServerCodeGenerator(serverPowerApis))
else throw new IllegalArgumentException("At least one of generateClient or generateServer must be enabled")
if (serverPowerApis) Seq(JavaPowerApiInterfaceCodeGenerator) ++ base
else base
}
} else {
if (languageScala) {
// Scala
if (generateClient && generateServer) CombinedPlayScalaBothCodeGenerator
else if (generateClient) CombinedPlayScalaClientCodeGenerator
else if (generateServer) CombinedPlayScalaServerCodeGenerator
else throw new IllegalArgumentException("At least one of generateClient or generateServer must be enabled")
val base =
if (generateClient && generateServer) Seq(ScalaTraitCodeGenerator, PlayScalaClientCodeGenerator, PlayScalaServerCodeGenerator(serverPowerApis))
else if (generateClient) Seq(ScalaTraitCodeGenerator, PlayScalaClientCodeGenerator)
else if (generateServer) Seq(ScalaTraitCodeGenerator, PlayScalaServerCodeGenerator(serverPowerApis))
else throw new IllegalArgumentException("At least one of generateClient or generateServer must be enabled")
if (serverPowerApis) Seq(ScalaPowerApiTraitCodeGenerator) ++ base
else base
} else {
// Java
if (generateClient && generateServer) CombinedPlayJavaBothCodeGenerator
else if (generateClient) CombinedPlayJavaClientCodeGenerator
else if (generateServer) CombinedPlayJavaServerCodeGenerator
else throw new IllegalArgumentException("At least one of generateClient or generateServer must be enabled")
val base =
if (generateClient && generateServer) Seq(JavaInterfaceCodeGenerator, JavaClientCodeGenerator, PlayJavaClientCodeGenerator, PlayJavaServerCodeGenerator(serverPowerApis))
else if (generateClient) Seq(JavaInterfaceCodeGenerator, JavaClientCodeGenerator, PlayJavaClientCodeGenerator)
else if (generateServer) Seq(JavaInterfaceCodeGenerator, PlayJavaServerCodeGenerator(serverPowerApis))
else throw new IllegalArgumentException("At least one of generateClient or generateServer must be enabled")
if (serverPowerApis) Seq(JavaPowerApiInterfaceCodeGenerator) ++ base
else base
}
}

codeGenerator.run(req, logger)
}

System.out.write(out.toByteArray)
System.out.flush()
// throw new RuntimeException(s"just before executing code generators")
johanandren marked this conversation as resolved.
Show resolved Hide resolved

/**
* Generators to generate both the 'plain' akka-grpc code and the play-specific code that depends on it.
* In other build tools (Maven and sbt) these are passed to protoc separately, but since Gradle does the
* akka-grpc code generation in a single protoc invocation we need to combine those here:
*/
object CombinedPlayJavaClientCodeGenerator extends PlayJavaClientCodeGenerator with JavaClientCodeGenerator {
override def name = "combined-play-java-client"
}
object CombinedPlayJavaServerCodeGenerator extends PlayJavaServerCodeGenerator with JavaServerCodeGenerator {
override def name = "combined-play-java-server"
}
object CombinedPlayJavaBothCodeGenerator extends PlayJavaClientCodeGenerator with JavaClientCodeGenerator with PlayJavaServerCodeGenerator with JavaServerCodeGenerator {
override def name = "combined-play-java-both"
}
object CombinedPlayScalaClientCodeGenerator extends PlayScalaClientCodeGenerator with ScalaClientCodeGenerator {
override def name = "combined-play-scala-client"
}
object CombinedPlayScalaServerCodeGenerator extends PlayScalaServerCodeGenerator with ScalaServerCodeGenerator {
override def name = "combined-play-scala-server"
}
object CombinedPlayScalaBothCodeGenerator extends PlayScalaClientCodeGenerator with ScalaClientCodeGenerator with PlayScalaServerCodeGenerator with ScalaServerCodeGenerator {
override def name = "combined-play-scala-both"
codeGenerators.foreach { g =>
// println("executing generator " + g.name)
johanandren marked this conversation as resolved.
Show resolved Hide resolved
val gout = g.run(req, logger)
System.out.write(gout.toByteArray)
System.out.flush()
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ trait JavaClientCodeGenerator extends JavaCodeGenerator {

override def perServiceContent: Set[(Logger, Service) ⇒ CodeGeneratorResponse.File] =
super.perServiceContent +
JavaCodeGenerator.generateServiceFile +
generateInterface +
generateRaw

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,3 @@ abstract class JavaCodeGenerator extends CodeGenerator {
override val suggestedDependencies = (scalaBinaryVersion: CodeGenerator.ScalaBinaryVersion) => Seq(
Artifact(BuildInfo.organization, BuildInfo.runtimeArtifactName + "_" + scalaBinaryVersion.prefix, BuildInfo.version))
}

object JavaCodeGenerator {
val generateServiceFile: (Logger, Service) ⇒ CodeGeneratorResponse.File = (logger, service) ⇒ {
val b = CodeGeneratorResponse.File.newBuilder()
b.setContent(ApiInterface(service).body)
b.setName(s"${service.packageDir}/${service.name}.java")
logger.info(s"Generating Akka gRPC service interface for [${service.packageName}.${service.name}]")
b.build
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (C) 2018-2019 Lightbend Inc. <https://www.lightbend.com>
*/

package akka.grpc.gen.javadsl

import akka.grpc.gen.Logger
import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse
import templates.JavaCommon.txt.ApiInterface

object JavaInterfaceCodeGenerator extends JavaCodeGenerator {
override def name = "akka-grpc-javadsl-interface"

override def perServiceContent: Set[(Logger, Service) ⇒ CodeGeneratorResponse.File] = super.perServiceContent + generateServiceFile

val generateServiceFile: (Logger, Service) ⇒ CodeGeneratorResponse.File = (logger, service) ⇒ {
val b = CodeGeneratorResponse.File.newBuilder()
b.setContent(ApiInterface(service).body)
b.setName(s"${service.packageDir}/${service.name}.java")
logger.info(s"Generating Akka gRPC service interface for [${service.packageName}.${service.name}]")
b.build
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (C) 2018-2019 Lightbend Inc. <https://www.lightbend.com>
*/

package akka.grpc.gen.javadsl

import akka.grpc.gen.Logger
import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse
import templates.JavaServer.txt.PowerApiInterface

object JavaPowerApiInterfaceCodeGenerator extends JavaCodeGenerator {
override def name = "akka-grpc-javadsl-power-api-interface"

override def perServiceContent: Set[(Logger, Service) ⇒ CodeGeneratorResponse.File] = super.perServiceContent + generatePowerService

val generatePowerService: (Logger, Service) => CodeGeneratorResponse.File = (logger, service) => {
val b = CodeGeneratorResponse.File.newBuilder()
b.setContent(PowerApiInterface(service).body)
b.setName(s"${service.packageDir}/${service.name}PowerApi.java")
logger.info(s"Generating Akka gRPC service power interface for [${service.packageName}.${service.name}]")
b.build
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,23 @@ import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse
import protocbridge.Artifact
import templates.JavaServer.txt.Handler

trait JavaServerCodeGenerator extends JavaCodeGenerator {
case class JavaServerCodeGenerator(powerApis: Boolean = false) extends JavaCodeGenerator {
override def name = "akka-grpc-javadsl-server"

override def perServiceContent: Set[(Logger, Service) ⇒ CodeGeneratorResponse.File] = super.perServiceContent +
JavaCodeGenerator.generateServiceFile + generateHandlerFactory
override def perServiceContent: Set[(Logger, Service) ⇒ CodeGeneratorResponse.File] = super.perServiceContent + generateHandlerFactory() ++ (
if (powerApis) Set(generateHandlerFactory(powerApis))
else Set.empty
)

def generateHandlerFactory(logger: Logger, service: Service): CodeGeneratorResponse.File = {
val b = CodeGeneratorResponse.File.newBuilder()
b.setContent(Handler(service).body)
override val suggestedDependencies = (scalaBinaryVersion: CodeGenerator.ScalaBinaryVersion) => Seq(
Artifact(BuildInfo.organization, BuildInfo.runtimeArtifactName + "_" + scalaBinaryVersion.prefix, BuildInfo.version))

val serverPath = s"${service.packageDir}/${service.name}HandlerFactory.java"
def generateHandlerFactory(powerApis: Boolean = false): (Logger, Service) ⇒ CodeGeneratorResponse.File = (logger, service) => {
val b = CodeGeneratorResponse.File.newBuilder()
b.setContent(Handler(service, powerApis).body)
val serverPath = s"${service.packageDir}/${service.name}${if (powerApis) "PowerApi" else ""}HandlerFactory.java"
b.setName(serverPath)
logger.info(s"Generating Akka gRPC service${if (powerApis) " power API" else ""} handler for ${service.packageName}.${service.name}")
b.build
}

override val suggestedDependencies = (scalaBinaryVersion: CodeGenerator.ScalaBinaryVersion) => Seq(
Artifact(BuildInfo.organization, BuildInfo.runtimeArtifactName + "_" + scalaBinaryVersion.prefix, BuildInfo.version))
}

object JavaServerCodeGenerator extends JavaServerCodeGenerator
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ trait PlayJavaClientCodeGenerator extends JavaCodeGenerator {
val b = CodeGeneratorResponse.File.newBuilder()
b.setContent(ClientProvider(service).body)
b.setName(s"${service.packageName.replace('.', '/')}/${service.name}ClientProvider.java")
logger.info(s"Generating Akka gRPC play client provider for ${service.packageName}.${service.name}")
b.build
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ import akka.grpc.gen.javadsl.{ JavaCodeGenerator, Service }
import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse
import templates.PlayJavaServer.txt.Router

object PlayJavaServerCodeGenerator extends PlayJavaServerCodeGenerator

trait PlayJavaServerCodeGenerator extends JavaCodeGenerator {
case class PlayJavaServerCodeGenerator(powerApis: Boolean = false) extends JavaCodeGenerator {
override def name: String = "akka-grpc-play-server-java"

override def perServiceContent: Set[(Logger, Service) ⇒ CodeGeneratorResponse.File] =
super.perServiceContent + generateRouter
override def perServiceContent = super.perServiceContent + generateRouter() ++ (
if (powerApis) Set(generateRouter(powerApis))
else Set.empty
)

private val generateRouter: (Logger, Service) => CodeGeneratorResponse.File = (logger, service) => {
private def generateRouter(powerApis: Boolean = false): (Logger, Service) => CodeGeneratorResponse.File = (logger, service) => {
val b = CodeGeneratorResponse.File.newBuilder()
b.setContent(Router(service).body)
b.setName(s"${service.packageDir}/Abstract${service.name}Router.java")
b.setContent(Router(service, powerApis).body)
b.setName(s"${service.packageDir}/Abstract${service.name}${if (powerApis) "PowerApi" else ""}Router.java")
logger.info(s"Generating Akka gRPC service${if (powerApis) " power API" else ""} play router for ${service.packageName}.${service.name}")
b.build
}

}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ import templates.ScalaClient.txt._
trait ScalaClientCodeGenerator extends ScalaCodeGenerator {
override def name = "akka-grpc-scaladsl-client"

override def perServiceContent = super.perServiceContent + ScalaCodeGenerator.generateServiceFile + generateStub
override def perServiceContent = super.perServiceContent + generateStub

def generateStub(logger: Logger, service: Service): CodeGeneratorResponse.File = {
val b = CodeGeneratorResponse.File.newBuilder()
b.setContent(Client(service).body)
b.setName(s"${service.packageDir}/${service.name}Client.scala")
logger.info(s"Generating Akka gRPC client ${service.packageName}.${service.name}")
logger.info(s"Generating Akka gRPC client for ${service.packageName}.${service.name}")
b.build
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,4 @@ abstract class ScalaCodeGenerator extends CodeGenerator {
}
}
}
object ScalaCodeGenerator {
val generateServiceFile: (Logger, Service) => CodeGeneratorResponse.File = (logger, service) => {
val b = CodeGeneratorResponse.File.newBuilder()
b.setContent(ApiTrait(service).body)
b.setName(s"${service.packageDir}/${service.name}.scala")
logger.info(s"Generating Akka gRPC service interface ${service.packageName}.${service.name}")
b.build
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (C) 2009-2019 Lightbend Inc. <https://www.lightbend.com>
*/

package akka.grpc.gen.scaladsl

import akka.grpc.gen.Logger
import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse
import templates.ScalaServer.txt.PowerApiTrait

object ScalaPowerApiTraitCodeGenerator extends ScalaCodeGenerator {
override def name = "akka-grpc-scaladsl-power-api-trait"

override def perServiceContent = super.perServiceContent + generatePowerApiTrait

val generatePowerApiTrait: (Logger, Service) => CodeGeneratorResponse.File = (logger, service) => {
val b = CodeGeneratorResponse.File.newBuilder()
b.setContent(PowerApiTrait(service).body)
b.setName(s"${service.packageDir}/${service.name}PowerApi.scala")
logger.info(s"Generating Akka gRPC service power API interface for ${service.packageName}.${service.name}")
b.build
}
}
Loading