diff --git a/compiler/src/java_plugin/cpp/java_generator.cpp b/compiler/src/java_plugin/cpp/java_generator.cpp index 34cdb734df..5232f11fa5 100644 --- a/compiler/src/java_plugin/cpp/java_generator.cpp +++ b/compiler/src/java_plugin/cpp/java_generator.cpp @@ -426,7 +426,22 @@ static void PrintMethodFields( " $service_class_name$.$method_new_field_name$ = $method_new_field_name$ =\n" " $MethodDescriptor$.<$input_type$, $output_type$>newBuilder()\n" " .setType($MethodType$.$method_type$)\n" - " .setFullMethodName(generateFullMethodName(SERVICE_NAME, \"$method_name$\"))\n" + " .setFullMethodName(generateFullMethodName(SERVICE_NAME, \"$method_name$\"))\n"); + + bool safe = method->options().idempotency_level() + == google::protobuf::MethodOptions_IdempotencyLevel_NO_SIDE_EFFECTS; + if (safe) { + p->Print(*vars, " .setSafe(true)\n"); + } else { + bool idempotent = method->options().idempotency_level() + == google::protobuf::MethodOptions_IdempotencyLevel_IDEMPOTENT; + if (idempotent) { + p->Print(*vars, " .setIdempotent(true)\n"); + } + } + + p->Print( + *vars, " .setSampledToLocalTracing(true)\n" " .setRequestMarshaller($ProtoUtils$.marshaller(\n" " $input_type$.getDefaultInstance()))\n" diff --git a/compiler/src/test/golden/TestService.java.txt b/compiler/src/test/golden/TestService.java.txt index d3e5e98464..5268ee46b5 100644 --- a/compiler/src/test/golden/TestService.java.txt +++ b/compiler/src/test/golden/TestService.java.txt @@ -216,6 +216,70 @@ public final class TestServiceGrpc { return getImportMethod; } + private static volatile io.grpc.MethodDescriptor getSafeCallMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "SafeCall", + requestType = io.grpc.testing.compiler.Test.SimpleRequest.class, + responseType = io.grpc.testing.compiler.Test.SimpleResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getSafeCallMethod() { + io.grpc.MethodDescriptor getSafeCallMethod; + if ((getSafeCallMethod = TestServiceGrpc.getSafeCallMethod) == null) { + synchronized (TestServiceGrpc.class) { + if ((getSafeCallMethod = TestServiceGrpc.getSafeCallMethod) == null) { + TestServiceGrpc.getSafeCallMethod = getSafeCallMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "SafeCall")) + .setSafe(true) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + io.grpc.testing.compiler.Test.SimpleRequest.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + io.grpc.testing.compiler.Test.SimpleResponse.getDefaultInstance())) + .setSchemaDescriptor(new TestServiceMethodDescriptorSupplier("SafeCall")) + .build(); + } + } + } + return getSafeCallMethod; + } + + private static volatile io.grpc.MethodDescriptor getIdempotentCallMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "IdempotentCall", + requestType = io.grpc.testing.compiler.Test.SimpleRequest.class, + responseType = io.grpc.testing.compiler.Test.SimpleResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getIdempotentCallMethod() { + io.grpc.MethodDescriptor getIdempotentCallMethod; + if ((getIdempotentCallMethod = TestServiceGrpc.getIdempotentCallMethod) == null) { + synchronized (TestServiceGrpc.class) { + if ((getIdempotentCallMethod = TestServiceGrpc.getIdempotentCallMethod) == null) { + TestServiceGrpc.getIdempotentCallMethod = getIdempotentCallMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "IdempotentCall")) + .setIdempotent(true) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + io.grpc.testing.compiler.Test.SimpleRequest.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller( + io.grpc.testing.compiler.Test.SimpleResponse.getDefaultInstance())) + .setSchemaDescriptor(new TestServiceMethodDescriptorSupplier("IdempotentCall")) + .build(); + } + } + } + return getIdempotentCallMethod; + } + /** * Creates a new async stub that supports all call types for the service */ @@ -336,6 +400,26 @@ public final class TestServiceGrpc { return asyncUnimplementedStreamingCall(getImportMethod(), responseObserver); } + /** + *
+     * A unary call that is Safe.
+     * 
+ */ + public void safeCall(io.grpc.testing.compiler.Test.SimpleRequest request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnimplementedUnaryCall(getSafeCallMethod(), responseObserver); + } + + /** + *
+     * A unary call that is Idempotent.
+     * 
+ */ + public void idempotentCall(io.grpc.testing.compiler.Test.SimpleRequest request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnimplementedUnaryCall(getIdempotentCallMethod(), responseObserver); + } + @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) .addMethod( @@ -380,6 +464,20 @@ public final class TestServiceGrpc { io.grpc.testing.compiler.Test.StreamingInputCallRequest, io.grpc.testing.compiler.Test.StreamingInputCallResponse>( this, METHODID_IMPORT))) + .addMethod( + getSafeCallMethod(), + asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.compiler.Test.SimpleRequest, + io.grpc.testing.compiler.Test.SimpleResponse>( + this, METHODID_SAFE_CALL))) + .addMethod( + getIdempotentCallMethod(), + asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.compiler.Test.SimpleRequest, + io.grpc.testing.compiler.Test.SimpleResponse>( + this, METHODID_IDEMPOTENT_CALL))) .build(); } } @@ -475,6 +573,28 @@ public final class TestServiceGrpc { return asyncBidiStreamingCall( getChannel().newCall(getImportMethod(), getCallOptions()), responseObserver); } + + /** + *
+     * A unary call that is Safe.
+     * 
+ */ + public void safeCall(io.grpc.testing.compiler.Test.SimpleRequest request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnaryCall( + getChannel().newCall(getSafeCallMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     * A unary call that is Idempotent.
+     * 
+ */ + public void idempotentCall(io.grpc.testing.compiler.Test.SimpleRequest request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnaryCall( + getChannel().newCall(getIdempotentCallMethod(), getCallOptions()), request, responseObserver); + } } /** @@ -516,6 +636,26 @@ public final class TestServiceGrpc { return blockingServerStreamingCall( getChannel(), getStreamingOutputCallMethod(), getCallOptions(), request); } + + /** + *
+     * A unary call that is Safe.
+     * 
+ */ + public io.grpc.testing.compiler.Test.SimpleResponse safeCall(io.grpc.testing.compiler.Test.SimpleRequest request) { + return blockingUnaryCall( + getChannel(), getSafeCallMethod(), getCallOptions(), request); + } + + /** + *
+     * A unary call that is Idempotent.
+     * 
+ */ + public io.grpc.testing.compiler.Test.SimpleResponse idempotentCall(io.grpc.testing.compiler.Test.SimpleRequest request) { + return blockingUnaryCall( + getChannel(), getIdempotentCallMethod(), getCallOptions(), request); + } } /** @@ -546,14 +686,38 @@ public final class TestServiceGrpc { return futureUnaryCall( getChannel().newCall(getUnaryCallMethod(), getCallOptions()), request); } + + /** + *
+     * A unary call that is Safe.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture safeCall( + io.grpc.testing.compiler.Test.SimpleRequest request) { + return futureUnaryCall( + getChannel().newCall(getSafeCallMethod(), getCallOptions()), request); + } + + /** + *
+     * A unary call that is Idempotent.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture idempotentCall( + io.grpc.testing.compiler.Test.SimpleRequest request) { + return futureUnaryCall( + getChannel().newCall(getIdempotentCallMethod(), getCallOptions()), request); + } } private static final int METHODID_UNARY_CALL = 0; private static final int METHODID_STREAMING_OUTPUT_CALL = 1; - private static final int METHODID_STREAMING_INPUT_CALL = 2; - private static final int METHODID_FULL_BIDI_CALL = 3; - private static final int METHODID_HALF_BIDI_CALL = 4; - private static final int METHODID_IMPORT = 5; + private static final int METHODID_SAFE_CALL = 2; + private static final int METHODID_IDEMPOTENT_CALL = 3; + private static final int METHODID_STREAMING_INPUT_CALL = 4; + private static final int METHODID_FULL_BIDI_CALL = 5; + private static final int METHODID_HALF_BIDI_CALL = 6; + private static final int METHODID_IMPORT = 7; private static final class MethodHandlers implements io.grpc.stub.ServerCalls.UnaryMethod, @@ -580,6 +744,14 @@ public final class TestServiceGrpc { serviceImpl.streamingOutputCall((io.grpc.testing.compiler.Test.StreamingOutputCallRequest) request, (io.grpc.stub.StreamObserver) responseObserver); break; + case METHODID_SAFE_CALL: + serviceImpl.safeCall((io.grpc.testing.compiler.Test.SimpleRequest) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_IDEMPOTENT_CALL: + serviceImpl.idempotentCall((io.grpc.testing.compiler.Test.SimpleRequest) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; default: throw new AssertionError(); } @@ -659,6 +831,8 @@ public final class TestServiceGrpc { .addMethod(getFullBidiCallMethod()) .addMethod(getHalfBidiCallMethod()) .addMethod(getImportMethod()) + .addMethod(getSafeCallMethod()) + .addMethod(getIdempotentCallMethod()) .build(); } } diff --git a/compiler/src/test/proto/grpc/testing/compiler/test.proto b/compiler/src/test/proto/grpc/testing/compiler/test.proto index 62cf6c853a..c1cb557216 100644 --- a/compiler/src/test/proto/grpc/testing/compiler/test.proto +++ b/compiler/src/test/proto/grpc/testing/compiler/test.proto @@ -70,6 +70,16 @@ service TestService { // An RPC method whose Java name collides with a keyword, and whose generated // method should have a '_' appended. rpc Import(stream StreamingInputCallRequest) returns (stream StreamingInputCallResponse); + + // A unary call that is Safe. + rpc SafeCall(SimpleRequest) returns (SimpleResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } + + // A unary call that is Idempotent. + rpc IdempotentCall(SimpleRequest) returns (SimpleResponse) { + option idempotency_level = IDEMPOTENT; + } } // Test service that has been deprecated and should generate with Java's @Deprecated annotation @@ -80,4 +90,4 @@ service TestDeprecatedService { rpc DeprecatedMethod(SimpleRequest) returns (SimpleResponse) { option deprecated = true; } -} \ No newline at end of file +} diff --git a/compiler/src/testLite/golden/TestService.java.txt b/compiler/src/testLite/golden/TestService.java.txt index e79a843236..c0d17510db 100644 --- a/compiler/src/testLite/golden/TestService.java.txt +++ b/compiler/src/testLite/golden/TestService.java.txt @@ -210,6 +210,68 @@ public final class TestServiceGrpc { return getImportMethod; } + private static volatile io.grpc.MethodDescriptor getSafeCallMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "SafeCall", + requestType = io.grpc.testing.compiler.Test.SimpleRequest.class, + responseType = io.grpc.testing.compiler.Test.SimpleResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getSafeCallMethod() { + io.grpc.MethodDescriptor getSafeCallMethod; + if ((getSafeCallMethod = TestServiceGrpc.getSafeCallMethod) == null) { + synchronized (TestServiceGrpc.class) { + if ((getSafeCallMethod = TestServiceGrpc.getSafeCallMethod) == null) { + TestServiceGrpc.getSafeCallMethod = getSafeCallMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "SafeCall")) + .setSafe(true) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( + io.grpc.testing.compiler.Test.SimpleRequest.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( + io.grpc.testing.compiler.Test.SimpleResponse.getDefaultInstance())) + .build(); + } + } + } + return getSafeCallMethod; + } + + private static volatile io.grpc.MethodDescriptor getIdempotentCallMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "IdempotentCall", + requestType = io.grpc.testing.compiler.Test.SimpleRequest.class, + responseType = io.grpc.testing.compiler.Test.SimpleResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getIdempotentCallMethod() { + io.grpc.MethodDescriptor getIdempotentCallMethod; + if ((getIdempotentCallMethod = TestServiceGrpc.getIdempotentCallMethod) == null) { + synchronized (TestServiceGrpc.class) { + if ((getIdempotentCallMethod = TestServiceGrpc.getIdempotentCallMethod) == null) { + TestServiceGrpc.getIdempotentCallMethod = getIdempotentCallMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "IdempotentCall")) + .setIdempotent(true) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( + io.grpc.testing.compiler.Test.SimpleRequest.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( + io.grpc.testing.compiler.Test.SimpleResponse.getDefaultInstance())) + .build(); + } + } + } + return getIdempotentCallMethod; + } + /** * Creates a new async stub that supports all call types for the service */ @@ -330,6 +392,26 @@ public final class TestServiceGrpc { return asyncUnimplementedStreamingCall(getImportMethod(), responseObserver); } + /** + *
+     * A unary call that is Safe.
+     * 
+ */ + public void safeCall(io.grpc.testing.compiler.Test.SimpleRequest request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnimplementedUnaryCall(getSafeCallMethod(), responseObserver); + } + + /** + *
+     * A unary call that is Idempotent.
+     * 
+ */ + public void idempotentCall(io.grpc.testing.compiler.Test.SimpleRequest request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnimplementedUnaryCall(getIdempotentCallMethod(), responseObserver); + } + @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) .addMethod( @@ -374,6 +456,20 @@ public final class TestServiceGrpc { io.grpc.testing.compiler.Test.StreamingInputCallRequest, io.grpc.testing.compiler.Test.StreamingInputCallResponse>( this, METHODID_IMPORT))) + .addMethod( + getSafeCallMethod(), + asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.compiler.Test.SimpleRequest, + io.grpc.testing.compiler.Test.SimpleResponse>( + this, METHODID_SAFE_CALL))) + .addMethod( + getIdempotentCallMethod(), + asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.compiler.Test.SimpleRequest, + io.grpc.testing.compiler.Test.SimpleResponse>( + this, METHODID_IDEMPOTENT_CALL))) .build(); } } @@ -469,6 +565,28 @@ public final class TestServiceGrpc { return asyncBidiStreamingCall( getChannel().newCall(getImportMethod(), getCallOptions()), responseObserver); } + + /** + *
+     * A unary call that is Safe.
+     * 
+ */ + public void safeCall(io.grpc.testing.compiler.Test.SimpleRequest request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnaryCall( + getChannel().newCall(getSafeCallMethod(), getCallOptions()), request, responseObserver); + } + + /** + *
+     * A unary call that is Idempotent.
+     * 
+ */ + public void idempotentCall(io.grpc.testing.compiler.Test.SimpleRequest request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnaryCall( + getChannel().newCall(getIdempotentCallMethod(), getCallOptions()), request, responseObserver); + } } /** @@ -510,6 +628,26 @@ public final class TestServiceGrpc { return blockingServerStreamingCall( getChannel(), getStreamingOutputCallMethod(), getCallOptions(), request); } + + /** + *
+     * A unary call that is Safe.
+     * 
+ */ + public io.grpc.testing.compiler.Test.SimpleResponse safeCall(io.grpc.testing.compiler.Test.SimpleRequest request) { + return blockingUnaryCall( + getChannel(), getSafeCallMethod(), getCallOptions(), request); + } + + /** + *
+     * A unary call that is Idempotent.
+     * 
+ */ + public io.grpc.testing.compiler.Test.SimpleResponse idempotentCall(io.grpc.testing.compiler.Test.SimpleRequest request) { + return blockingUnaryCall( + getChannel(), getIdempotentCallMethod(), getCallOptions(), request); + } } /** @@ -540,14 +678,38 @@ public final class TestServiceGrpc { return futureUnaryCall( getChannel().newCall(getUnaryCallMethod(), getCallOptions()), request); } + + /** + *
+     * A unary call that is Safe.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture safeCall( + io.grpc.testing.compiler.Test.SimpleRequest request) { + return futureUnaryCall( + getChannel().newCall(getSafeCallMethod(), getCallOptions()), request); + } + + /** + *
+     * A unary call that is Idempotent.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture idempotentCall( + io.grpc.testing.compiler.Test.SimpleRequest request) { + return futureUnaryCall( + getChannel().newCall(getIdempotentCallMethod(), getCallOptions()), request); + } } private static final int METHODID_UNARY_CALL = 0; private static final int METHODID_STREAMING_OUTPUT_CALL = 1; - private static final int METHODID_STREAMING_INPUT_CALL = 2; - private static final int METHODID_FULL_BIDI_CALL = 3; - private static final int METHODID_HALF_BIDI_CALL = 4; - private static final int METHODID_IMPORT = 5; + private static final int METHODID_SAFE_CALL = 2; + private static final int METHODID_IDEMPOTENT_CALL = 3; + private static final int METHODID_STREAMING_INPUT_CALL = 4; + private static final int METHODID_FULL_BIDI_CALL = 5; + private static final int METHODID_HALF_BIDI_CALL = 6; + private static final int METHODID_IMPORT = 7; private static final class MethodHandlers implements io.grpc.stub.ServerCalls.UnaryMethod, @@ -574,6 +736,14 @@ public final class TestServiceGrpc { serviceImpl.streamingOutputCall((io.grpc.testing.compiler.Test.StreamingOutputCallRequest) request, (io.grpc.stub.StreamObserver) responseObserver); break; + case METHODID_SAFE_CALL: + serviceImpl.safeCall((io.grpc.testing.compiler.Test.SimpleRequest) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_IDEMPOTENT_CALL: + serviceImpl.idempotentCall((io.grpc.testing.compiler.Test.SimpleRequest) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; default: throw new AssertionError(); } @@ -617,6 +787,8 @@ public final class TestServiceGrpc { .addMethod(getFullBidiCallMethod()) .addMethod(getHalfBidiCallMethod()) .addMethod(getImportMethod()) + .addMethod(getSafeCallMethod()) + .addMethod(getIdempotentCallMethod()) .build(); } } diff --git a/okhttp/src/main/java/io/grpc/okhttp/OkHttpChannelBuilder.java b/okhttp/src/main/java/io/grpc/okhttp/OkHttpChannelBuilder.java index b8071d9cf6..690462ba6a 100644 --- a/okhttp/src/main/java/io/grpc/okhttp/OkHttpChannelBuilder.java +++ b/okhttp/src/main/java/io/grpc/okhttp/OkHttpChannelBuilder.java @@ -133,7 +133,7 @@ public class OkHttpChannelBuilder extends * If true, indicates that the transport may use the GET method for RPCs, and may include the * request body in the query params. */ - private final boolean useGetForSafeMethods = true; + private final boolean useGetForSafeMethods = false; protected OkHttpChannelBuilder(String host, int port) { this(GrpcUtil.authorityFromHostAndPort(host, port));