grpc / grpc-java

The Java gRPC implementation. HTTP/2 based RPC
https://grpc.io/docs/languages/java/
Apache License 2.0
11.44k stars 3.85k forks source link

rpc method name to java.lang.Method name mapping #8826

Closed jvmlet closed 2 years ago

jvmlet commented 2 years ago

Is your feature request related to a problem?

Currently it's impossible to dynamically map generated grpc java.lang.Method name to original rpc method name defined in proto file : rpc my_method() is generated as myMethod()

Describe the solution you'd like

Either provide API to map from/to rpc method name to/from java.lang.Method name or annotate the generated method with something like

class StubImplBase{
@OriginalRpcMethodName("my_method")
public void myMethod(Request,Response){
}
}
ejona86 commented 2 years ago

Which java.lang.Method are you talking about? What is your use case? Why the reverse mapping? I see the Method ***rpc_method_name*** not found in service ***org.me.MyGrpcService*** error in the other issue, but that would be rpc name → java.lang.Method (which is opposite of what you are requesting).

Assuming we are talking about server-side, bindService() has the code to map to calling to the appropriate method (but that mapping is not exposed, and it is reverse what you are requesting).

Seeing "SecurityInterceptor" I thought that maybe you were using annotations on the java.lang.Method, but that doesn't seem to be the case. It's unclear why you don't use the normal gRPC plumbing and call next. Seems like you are doing something with the message, but you can still do that by intercepting ServerCall.Listener.onMessage().

jvmlet commented 2 years ago

I'm asking to get the original rpc method name/method descriptor from generated method name of stub (dynamically) . Yes, I'm annotating the generated methods with spring security annotations.

jvmlet commented 2 years ago

I've update the description: given java.lang.Method, find original rpc method name/descriptor.

jvmlet commented 2 years ago

It's unclear why you don't use the normal gRPC plumbing and call next

Actually, I do : https://github.com/LogNet/grpc-spring-boot-starter/blob/8b05c32dde9c9027344cfd2ec88c66edee44ce91/grpc-spring-boot-starter/src/main/java/org/lognet/springboot/grpc/security/SecurityInterceptor.java?_pjax=%23js-repo-pjax-container%2C%20div%5Bitemtype%3D%22http%3A%2F%2Fschema.org%2FSoftwareSourceCode%22%5D%20main%2C%20%5Bdata-pjax-container%5D#L151

ejona86 commented 2 years ago

I don't really see a way to do this that make much sense. I think the basic problem is you are using our service stubs but then trying to morph them into your own custom stubs. Any annotations on the implementation should not be processed by an interceptor, as the interceptor only can "see" the very next interceptor in the chain; it can't necessarily see the service. For annotation usage, the code that checks for those annotations really needs to be part of the stub.

I know some people are hesitant to make their own code generators, but you may consider making an Annotation Processor that consumes our generated code and uses its annotations to generate your own stub with power to reflect. You can use ServerCalls to handle most of the interaction with gRPC, and reuse the grpc generated code to create the descriptors.

jvmlet commented 2 years ago

Thanks for the detailed answer and sorry for resurrecting the closed issue, but if we forget about annotation on service methods that derives from stubs... Is there any way to map generated java method name to original rpc method name from proto file?

ejona86 commented 2 years ago

You're the original poster and it was recently closed; both mean it is normal and not a problem.

Would it be accurate to say your question is now "what is the mapping?" As in, "what code would I write to do the mapping?" I think that is MixedLower() in java_generator.cpp (the comment is probably close to right, but do try to glance if the implementation matches): https://github.com/grpc/grpc-java/blob/07567eebe659ea9bb6e8c3ade880e6c207a8cf32/compiler/src/java_plugin/cpp/java_generator.cpp#L115-L119

jvmlet commented 2 years ago

Thanks, yes I saw the code that produces the java method name, I'm after the API (contract provided by grpc java) to get this info.

ejona86 commented 2 years ago

There is no desire to add an API to expose the mapping at runtime. At least for the annotation use-case along with an interceptor. As I mentioned before, I don't think that approach is appropriate given the design of the stubs and interceptors.

Since grpc requires Java 8 now, there should be some changes to the stubs to allow implementing an interface. That work could potentially be coupled with Proxy to get something close to what you want. The annotation processing would stay in the java-world then and you wouldn't need to map to the grpc on-the-wire method names. There wouldn't be an interceptor as well.

ejona86 commented 2 years ago

Created #9320 to track generating interfaces for services. That seems the best way forward here.