-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
541 additions
and
5 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,69 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<artifactId>quarkus-grpc-parent</artifactId> | ||
<groupId>io.quarkus</groupId> | ||
<version>999-SNAPSHOT</version> | ||
</parent> | ||
|
||
<artifactId>quarkus-grpc-cli</artifactId> | ||
<name>Quarkus - gRPC - CLI</name> | ||
<description>gRPC CLI</description> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>io.vertx</groupId> | ||
<artifactId>vertx-grpc-client</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.google.protobuf</groupId> | ||
<artifactId>protobuf-java-util</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-grpc-reflection</artifactId> | ||
<version>${project.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-core-deployment</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-picocli</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-arc</artifactId> | ||
</dependency> | ||
</dependencies> | ||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-maven-plugin</artifactId> | ||
<extensions>true</extensions> | ||
<executions> | ||
<execution> | ||
<goals> | ||
<goal>build</goal> | ||
<goal>generate-code</goal> | ||
<goal>generate-code-tests</goal> | ||
</goals> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
<plugin> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<configuration> | ||
<compilerArgs> | ||
<arg>-parameters</arg> | ||
</compilerArgs> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</project> |
44 changes: 44 additions & 0 deletions
44
extensions/grpc/cli/src/main/java/io/quarkus/grpc/cli/DescribeCommand.java
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,44 @@ | ||
package io.quarkus.grpc.cli; | ||
|
||
import java.util.List; | ||
|
||
import com.google.protobuf.ByteString; | ||
import com.google.protobuf.DescriptorProtos; | ||
import com.google.protobuf.util.JsonFormat; | ||
|
||
import io.grpc.reflection.v1.MutinyServerReflectionGrpc; | ||
import io.grpc.reflection.v1.ServerReflectionRequest; | ||
import io.grpc.reflection.v1.ServerReflectionResponse; | ||
import io.smallrye.mutiny.Multi; | ||
import picocli.CommandLine; | ||
|
||
@CommandLine.Command(name = "describe", sortOptions = false, header = "grpc describe") | ||
public class DescribeCommand extends GcurlBaseCommand { | ||
|
||
public String getAction() { | ||
return "describe"; | ||
} | ||
|
||
@Override | ||
protected void execute(MutinyServerReflectionGrpc.MutinyServerReflectionStub stub) { | ||
ServerReflectionRequest request = ServerReflectionRequest | ||
.newBuilder() | ||
.setFileContainingSymbol(unmatched.get(1)) | ||
.build(); | ||
Multi<ServerReflectionResponse> response = stub.serverReflectionInfo(Multi.createFrom().item(request)); | ||
response.toUni().map(r -> { | ||
List<ByteString> list = r.getFileDescriptorResponse().getFileDescriptorProtoList(); | ||
for (ByteString bs : list) { | ||
try { | ||
DescriptorProtos.FileDescriptorProto fdp = DescriptorProtos.FileDescriptorProto.parseFrom(bs); | ||
log(JsonFormat.printer().print(fdp)); | ||
} catch (RuntimeException e) { | ||
throw e; | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
return null; | ||
}).await().indefinitely(); | ||
} | ||
} |
132 changes: 132 additions & 0 deletions
132
extensions/grpc/cli/src/main/java/io/quarkus/grpc/cli/GcurlBaseCommand.java
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,132 @@ | ||
package io.quarkus.grpc.cli; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.concurrent.Callable; | ||
import java.util.function.Function; | ||
import java.util.stream.Collectors; | ||
|
||
import com.google.protobuf.ByteString; | ||
import com.google.protobuf.DescriptorProtos; | ||
import com.google.protobuf.Descriptors; | ||
import com.google.protobuf.InvalidProtocolBufferException; | ||
import com.google.protobuf.ProtocolStringList; | ||
|
||
import io.grpc.Channel; | ||
import io.grpc.reflection.v1.MutinyServerReflectionGrpc; | ||
import io.vertx.core.Vertx; | ||
import io.vertx.core.http.HttpClientOptions; | ||
import io.vertx.core.net.SocketAddress; | ||
import io.vertx.grpc.client.GrpcClient; | ||
import io.vertx.grpc.client.GrpcClientChannel; | ||
import picocli.CommandLine; | ||
import picocli.CommandLine.Model.CommandSpec; | ||
import picocli.CommandLine.Spec; | ||
|
||
public abstract class GcurlBaseCommand implements Callable<Integer> { | ||
|
||
@Spec | ||
protected CommandSpec spec; | ||
|
||
@CommandLine.Unmatched | ||
protected List<String> unmatched; | ||
|
||
Vertx vertx = Vertx.vertx(); | ||
|
||
/** | ||
* The grpc subcommand (e.g. list, describe, invoke) | ||
* | ||
* @return the subcommand | ||
*/ | ||
protected abstract String getAction(); | ||
|
||
protected abstract void execute(MutinyServerReflectionGrpc.MutinyServerReflectionStub stub); | ||
|
||
protected void log(String msg) { | ||
System.out.println(msg); | ||
} | ||
|
||
protected void err(String msg) { | ||
System.err.println(msg); | ||
} | ||
|
||
protected static List<Descriptors.FileDescriptor> getFileDescriptorsFromProtos(List<ByteString> protos) { | ||
try { | ||
Map<String, DescriptorProtos.FileDescriptorProto> all = protos | ||
.stream() | ||
.map(bs -> { | ||
try { | ||
return DescriptorProtos.FileDescriptorProto.parseFrom(bs); | ||
} catch (InvalidProtocolBufferException e) { | ||
throw new RuntimeException(e); | ||
} | ||
}) | ||
.collect(Collectors.toMap(DescriptorProtos.FileDescriptorProto::getName, Function.identity(), (a, b) -> a)); | ||
List<Descriptors.FileDescriptor> fds = new ArrayList<>(); | ||
Map<String, Descriptors.FileDescriptor> resolved = new HashMap<>(); | ||
for (DescriptorProtos.FileDescriptorProto fdp : all.values()) { | ||
fds.add(toFileDescriptor(fdp, all, resolved)); | ||
} | ||
return fds; | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
private static Descriptors.FileDescriptor toFileDescriptor(DescriptorProtos.FileDescriptorProto fdp, | ||
Map<String, DescriptorProtos.FileDescriptorProto> all, Map<String, Descriptors.FileDescriptor> resolved) { | ||
int n = fdp.getDependencyCount(); | ||
ProtocolStringList list = fdp.getDependencyList(); | ||
Descriptors.FileDescriptor[] fds = new Descriptors.FileDescriptor[n]; | ||
for (int i = 0; i < n; i++) { | ||
String dep = list.get(i); | ||
// remember resolved FDs, recursively resolve deps | ||
fds[i] = resolved.computeIfAbsent(dep, key -> { | ||
DescriptorProtos.FileDescriptorProto proto = all.get(key); | ||
return toFileDescriptor(proto, all, resolved); | ||
}); | ||
} | ||
try { | ||
return Descriptors.FileDescriptor.buildFrom(fdp, fds); | ||
} catch (Descriptors.DescriptorValidationException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
@Override | ||
public Integer call() { | ||
if (unmatched == null || unmatched.isEmpty()) { | ||
log("Missing host:port"); | ||
return CommandLine.ExitCode.USAGE; | ||
} | ||
|
||
return execute(channel -> { | ||
try { | ||
MutinyServerReflectionGrpc.MutinyServerReflectionStub stub = MutinyServerReflectionGrpc.newMutinyStub(channel); | ||
execute(stub); | ||
return CommandLine.ExitCode.OK; | ||
} catch (Exception e) { | ||
err("Failed to execute grpc " + getAction() + ", due to: " + e.getMessage()); | ||
return CommandLine.ExitCode.SOFTWARE; | ||
} | ||
}); | ||
} | ||
|
||
protected <X> X execute(Function<Channel, X> fn) { | ||
HttpClientOptions options = new HttpClientOptions(); // TODO | ||
options.setHttp2ClearTextUpgrade(false); | ||
|
||
GrpcClient client = GrpcClient.client(vertx, options); | ||
String[] split = unmatched.get(0).split(":"); | ||
String host = split[0]; | ||
int port = Integer.parseInt(split[1]); | ||
Channel channel = new GrpcClientChannel(client, SocketAddress.inetSocketAddress(port, host)); | ||
try { | ||
return fn.apply(channel); | ||
} finally { | ||
client.close().toCompletionStage().toCompletableFuture().join(); | ||
} | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
extensions/grpc/cli/src/main/java/io/quarkus/grpc/cli/GrpcCommand.java
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,27 @@ | ||
package io.quarkus.grpc.cli; | ||
|
||
import java.util.concurrent.Callable; | ||
|
||
import io.quarkus.picocli.runtime.annotations.TopCommand; | ||
import picocli.CommandLine; | ||
import picocli.CommandLine.Command; | ||
import picocli.CommandLine.Model.CommandSpec; | ||
import picocli.CommandLine.Spec; | ||
|
||
@TopCommand | ||
@Command(name = "grpc", sortOptions = false, header = "grpc CLI", subcommands = { | ||
ListCommand.class, DescribeCommand.class, InvokeCommand.class }) | ||
public class GrpcCommand implements Callable<Integer> { | ||
|
||
@Spec | ||
protected CommandSpec spec; | ||
|
||
@CommandLine.Option(names = { "-h", "--help" }, usageHelp = true, description = "Display this help message.") | ||
public boolean help; | ||
|
||
@Override | ||
public Integer call() { | ||
CommandLine schemaCommand = spec.subcommands().get("list"); | ||
return schemaCommand.execute(); | ||
} | ||
} |
Oops, something went wrong.