Skip to content

Commit

Permalink
airframe-rpc: Add an RPC project example (#1250)
Browse files Browse the repository at this point in the history
  • Loading branch information
xerial committed Aug 20, 2020
1 parent ed3b56b commit 942f11e
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 3 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ website/yarn.lock
website/node_modules
website/i18n/*

log/*
airframe-benchmark/log/*
**/log/*json*
.vscode/launch.json
project/metals.sbt
2 changes: 1 addition & 1 deletion docs/airframe-rpc.md
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ sbt-airframe generates ServiceGrpc.scala file to the target API package. You can
import example.api.ServiceGrpc

// Create a client channel
val channel = ManagedChannel.forTaget("localhost:8080").usePlaintext().build()
val channel = ManagedChannelBuilder.forTaget("localhost:8080").usePlaintext().build()

// Create a gRPC blocking client (SyncClient)
val client = ServiceGrpc.newSyncClient(channel)
Expand Down
4 changes: 4 additions & 0 deletions examples/rpc-examples/hello-rpc/.scalafmt.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = 2.6.4
maxColumn = 120
style = defaultWithAlign
optIn.breaksInsideChains = true
19 changes: 19 additions & 0 deletions examples/rpc-examples/hello-rpc/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
val AIRFRAME_VERSION = "20.8.0"
scalaVersion in ThisBuild := "2.12.12"

// RPC API definition. This project should contain only RPC interfaces
lazy val greeter =
project
.in(file("."))
.enablePlugins(AirframeHttpPlugin, PackPlugin)
.settings(
// Generates HTTP clients
airframeHttpClients := Seq("greeter.api:sync", "greeter.api:grpc"),
airframeHttpGeneratorOption := "-l debug",
libraryDependencies ++= Seq(
"org.wvlet.airframe" %% "airframe-http" % AIRFRAME_VERSION,
"org.wvlet.airframe" %% "airframe-http-finagle" % AIRFRAME_VERSION,
"org.wvlet.airframe" %% "airframe-http-grpc" % AIRFRAME_VERSION,
"org.wvlet.airframe" %% "airframe-launcher" % AIRFRAME_VERSION
)
)
1 change: 1 addition & 0 deletions examples/rpc-examples/hello-rpc/project/build.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sbt.version=1.3.13
3 changes: 3 additions & 0 deletions examples/rpc-examples/hello-rpc/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "0.12")
addSbtPlugin("org.wvlet.airframe" % "sbt-airframe" % "20.8.0")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.2")
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package greeter

import greeter.api.{GreeterApi, ServiceGrpc, ServiceSyncClient}
import io.grpc.{ManagedChannel, ManagedChannelBuilder}
import wvlet.airframe.control.Control.withResource
import wvlet.airframe.http.Router
import wvlet.airframe.http.finagle.Finagle
import wvlet.airframe.http.grpc.gRPC
import wvlet.airframe.launcher.{Launcher, command, option}
import wvlet.log.{LogSupport, Logger}

/**
*/
object GreeterMain {
def main(args: Array[String]): Unit = {
Launcher.of[GreeterMain].execute(args)
}
}

class GreeterMain(
@option(prefix = "-h,--help", description = "show help messages", isHelp = true)
help: Boolean,
@option(prefix = "-p,--port", description = "server/client port (default:8080)")
port: Int = 8080
) extends LogSupport {
Logger.init

private def router = Router.of[GreeterApi]

@command(isDefault = true)
def default: Unit = {
info(s"Type --help to see the list of commands")
}

@command(description = "Start a Finagle server")
def finagleServer: Unit = {
Finagle.server
.withRouter(router)
.withPort(port)
.start { server =>
server.waitServerTermination
}
}

@command(description = "Make Finagle RPC requests")
def finagleClient(@option(prefix = "-n", description = "request count") n: Int = 3): Unit = {
withResource(
new ServiceSyncClient(
Finagle.client
.newSyncClient(s"localhost:${port}")
)
) { client =>
for (i <- 0 until n) {
val response = client.GreeterApi.hello(s"RPC${i}")
info(s"Received: ${response}")
}
}
}

@command(description = "Start a gRPC server")
def grpcServer: Unit = {
gRPC.server
.withRouter(router)
.withPort(port)
.start { server =>
server.awaitTermination
}
}

@command(description = "Make gRPC requests")
def grpcClient(@option(prefix = "-n", description = "request count") n: Int = 3): Unit = {
val channel: ManagedChannel =
ManagedChannelBuilder
.forTarget(s"localhost:${port}")
.usePlaintext()
.build()

val client = ServiceGrpc.newSyncClient(channel)
for (i <- 0 until n) {
val response = client.GreeterApi.hello(s"RPC${i}")
info(s"Received: ${response}")
}
channel.shutdownNow()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package greeter.api

import wvlet.airframe.http.RPC
import wvlet.log.LogSupport

@RPC
class GreeterApi extends LogSupport {
def hello(name: String) = {
info(s"Received a request from: ${name}")
s"Hello ${name}!"
}
}

0 comments on commit 942f11e

Please sign in to comment.