-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Language GRPC service for Auto API
- Loading branch information
1 parent
5e8ae3f
commit 2c8bb73
Showing
3 changed files
with
119 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package besom.internal | ||
|
||
import com.google.protobuf.* | ||
import io.grpc.netty.NettyServerBuilder | ||
import io.grpc.stub.StreamObserver | ||
import io.grpc.{InsecureServerCredentials, MethodDescriptor, Server, Status} | ||
import pulumirpc.language.* | ||
import pulumirpc.language.LanguageRuntimeGrpc.LanguageRuntime | ||
import pulumirpc.plugin.* | ||
|
||
import java.util.concurrent.TimeUnit | ||
import scala.concurrent.{ExecutionContext, Future} | ||
|
||
trait LanguageRuntimeService extends LanguageRuntime: | ||
def run(request: RunRequest): Future[RunResponse] = | ||
request.getInfo | ||
Future.successful(RunResponse()) | ||
|
||
// Unimplemented on purpose | ||
def getRequiredPlugins(request: GetRequiredPluginsRequest): Future[GetRequiredPluginsResponse] = | ||
unimplementedUnaryCall(LanguageRuntimeGrpc.METHOD_GET_REQUIRED_PLUGINS) | ||
|
||
def getPluginInfo(request: empty.Empty): Future[PluginInfo] = | ||
unimplementedUnaryCall(LanguageRuntimeGrpc.METHOD_GET_PLUGIN_INFO) | ||
|
||
def installDependencies(request: InstallDependenciesRequest, responseObserver: StreamObserver[InstallDependenciesResponse]): Unit = | ||
unimplementedUnaryCall(LanguageRuntimeGrpc.METHOD_INSTALL_DEPENDENCIES, responseObserver) | ||
|
||
def about(request: empty.Empty): Future[AboutResponse] = | ||
unimplementedUnaryCall(LanguageRuntimeGrpc.METHOD_ABOUT) | ||
|
||
def getProgramDependencies(request: GetProgramDependenciesRequest): Future[GetProgramDependenciesResponse] = | ||
unimplementedUnaryCall(LanguageRuntimeGrpc.METHOD_GET_PROGRAM_DEPENDENCIES) | ||
|
||
def runPlugin(request: RunPluginRequest, responseObserver: StreamObserver[RunPluginResponse]): Unit = | ||
unimplementedUnaryCall(LanguageRuntimeGrpc.METHOD_RUN_PLUGIN, responseObserver) | ||
|
||
def generateProgram(request: GenerateProgramRequest): Future[GenerateProgramResponse] = | ||
unimplementedUnaryCall(LanguageRuntimeGrpc.METHOD_GENERATE_PROGRAM) | ||
|
||
def generateProject(request: GenerateProjectRequest): Future[GenerateProjectResponse] = | ||
unimplementedUnaryCall(LanguageRuntimeGrpc.METHOD_GENERATE_PROJECT) | ||
|
||
def generatePackage(request: GeneratePackageRequest): Future[GeneratePackageResponse] = | ||
unimplementedUnaryCall(LanguageRuntimeGrpc.METHOD_GENERATE_PACKAGE) | ||
|
||
def pack(request: PackRequest): Future[PackResponse] = | ||
unimplementedUnaryCall(LanguageRuntimeGrpc.METHOD_PACK) | ||
|
||
private def unimplementedUnaryCall[A, B](methodDescriptor: MethodDescriptor[A, B]): Future[B] = | ||
Future.failed( | ||
Status.UNIMPLEMENTED.withDescription(s"Method ${methodDescriptor.getFullMethodName} is unimplemented").asRuntimeException() | ||
) | ||
|
||
private def unimplementedUnaryCall[A, B](methodDescriptor: MethodDescriptor[A, B], responseObserver: StreamObserver[B]): Unit = | ||
responseObserver.onError( | ||
Status.UNIMPLEMENTED.withDescription(s"Method ${methodDescriptor.getFullMethodName} is unimplemented").asRuntimeException() | ||
) | ||
|
||
end LanguageRuntimeService | ||
|
||
object LanguageRuntimeService extends LanguageRuntimeService | ||
|
||
object LanguageRuntimeServer: | ||
def apply(service: LanguageRuntimeService)(using ExecutionContext): LanguageRuntimeServer = | ||
// TODO: detect that nested stack operations are not supported https://github.com/pulumi/pulumi/issues/5058 | ||
val server = NettyServerBuilder | ||
.forPort(0 /* random port */, InsecureServerCredentials.create()) | ||
.addService( | ||
LanguageRuntimeGrpc.bindService(service, summon[ExecutionContext]) | ||
) | ||
.build | ||
new LanguageRuntimeServer(server) | ||
|
||
end LanguageRuntimeServer | ||
|
||
class LanguageRuntimeServer private (server: Server): | ||
self => | ||
|
||
private val ShutdownTimeoutInSeconds = 30 | ||
|
||
def start(): Int = | ||
try server.start() | ||
catch | ||
case e: java.io.IOException => | ||
throw new RuntimeException("Failed to start LanguageRuntimeServer", e) | ||
end try | ||
|
||
val _ = sys.addShutdownHook { | ||
// Use stderr here since the logger may have been reset by its JVM shutdown hook. | ||
System.err.println("Shutting down LanguageRuntimeServer gRPC server since JVM is shutting down") | ||
self.stop() | ||
} | ||
|
||
val port = server.getPort | ||
println(s"LanguageRuntimeServer started, listening on $port") | ||
port | ||
|
||
end start | ||
|
||
def stop(): Unit = | ||
try server.shutdown().awaitTermination(ShutdownTimeoutInSeconds, TimeUnit.SECONDS) | ||
catch | ||
case e: InterruptedException => | ||
throw new RuntimeException("Error while awaiting for termination of LanguageRuntimeServer", e) | ||
end try | ||
println("LanguageRuntimeServer shut down"); | ||
|
||
end stop | ||
|
||
def port: Int = | ||
val port = server.getPort | ||
if (port == -1) throw UnsupportedOperationException("Cannot get LanguageRuntimeServer port, got -1") | ||
port | ||
|
||
end LanguageRuntimeServer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters