Skip to content

Commit

Permalink
Force java_generic_services to false for protos gathered from depende…
Browse files Browse the repository at this point in the history
…ncies
  • Loading branch information
scrocquesel committed Jan 30, 2023
1 parent baa1c2f commit d87bd54
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 4 deletions.
4 changes: 4 additions & 0 deletions docs/src/main/asciidoc/grpc-getting-started.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ message HelloReply {

This `proto` file defines a simple service interface with a single method (`SayHello`), and the exchanged messages (`HelloRequest` containing the name and `HelloReply` containing the greeting message).

NOTE: Your `proto` file must not contain `option java_generic_services = true;`. https://developers.google.com/protocol-buffers/docs/reference/java-generated?hl=en#service[Generic services are deprecated] and are not compatible with Quarkus code generation plugins.

Before coding, we need to generate the classes used to implement and consume gRPC services.
In a terminal, run:

Expand Down Expand Up @@ -178,6 +180,8 @@ quarkus.generate-code.grpc.scan-for-proto=<groupId>:<artifactId>
----
The value of the property may be `none`, which is the default value, or a comma separated list of `groupId:artifactId` coordinates.

NOTE: `option java_generic_services = true;` will automatically be removed from proto file containing it.

== Different gRPC implementations / types

Another thing to take note as well is that Quarkus' gRPC support currently includes 3 different types of gRPC usage:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,35 @@ public boolean trigger(CodeGenContext context) throws CodeGenException {
return false;
}

private static void copySanitizedProtoFile(ResolvedDependency artifact, Path protoPath, Path outProtoPath)
throws IOException {
boolean genericServicesFound = false;

try (var reader = Files.newBufferedReader(protoPath);
var writer = Files.newBufferedWriter(outProtoPath)) {

String line = reader.readLine();
while (line != null) {
// filter java_generic_services to avoid "Tried to write the same file twice"
// when set to true. Generic services are deprecated and replaced by classes generated by
// this plugin
if (!line.contains("java_generic_services")) {
writer.write(line);
writer.newLine();
} else {
genericServicesFound = true;
}

line = reader.readLine();
}
}

if (genericServicesFound) {
log.infof("Ignoring option java_generic_services in %s:%s%s.", artifact.getGroupId(), artifact.getArtifactId(),
protoPath);
}
}

private void postprocessing(CodeGenContext context, Path outDir) {
if (TRUE.toString().equalsIgnoreCase(System.getProperties().getProperty(POST_PROCESS_SKIP, "false"))
|| context.config().getOptionalValue(POST_PROCESS_SKIP, Boolean.class).orElse(false)) {
Expand Down Expand Up @@ -179,7 +208,7 @@ private Collection<Path> gatherProtosFromDependencies(Path workDir, Set<String>
if (scanAll
|| dependenciesToScan.contains(
String.format("%s:%s", artifact.getGroupId(), artifact.getArtifactId()))) {
extractProtosFromArtifact(workDir, protoFilesFromDependencies, protoDirectories, artifact);
extractProtosFromArtifact(workDir, protoFilesFromDependencies, protoDirectories, artifact, true);
}
}
return protoFilesFromDependencies;
Expand Down Expand Up @@ -215,14 +244,14 @@ private Collection<String> gatherDirectoriesWithImports(Path workDir, CodeGenCon
if (scanAll
|| dependenciesToScan.contains(
String.format("%s:%s", artifact.getGroupId(), artifact.getArtifactId()))) {
extractProtosFromArtifact(workDir, new ArrayList<>(), importDirectories, artifact);
extractProtosFromArtifact(workDir, new ArrayList<>(), importDirectories, artifact, false);
}
}
return importDirectories;
}

private void extractProtosFromArtifact(Path workDir, Collection<Path> protoFiles,
Set<String> protoDirectories, ResolvedDependency artifact) throws CodeGenException {
Set<String> protoDirectories, ResolvedDependency artifact, boolean isDependency) throws CodeGenException {

try {
artifact.getContentTree().walk(
Expand Down Expand Up @@ -250,7 +279,11 @@ private void extractProtosFromArtifact(Path workDir, Collection<Path> protoFiles
}
try {
Files.createDirectories(outPath.getParent());
Files.copy(path, outPath, StandardCopyOption.REPLACE_EXISTING);
if (isDependency) {
copySanitizedProtoFile(artifact, path, outPath);
} else {
Files.copy(path, outPath, StandardCopyOption.REPLACE_EXISTING);
}
protoFiles.add(outPath);
} catch (IOException e) {
throw new GrpcCodeGenException("Failed to extract proto file" + path + " to target: "
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
syntax = "proto3";

option java_package = "com.test";

// codegen will ignore the line below
option java_generic_services = true;

package com.test;

service MyJavaGenericServicesTest {
rpc DoTest(JavaGenericServices) returns (JavaGenericServices);
}

message JavaGenericServices {}

0 comments on commit d87bd54

Please sign in to comment.