/** Returns the span name of the request. Defaults to the full grpc method name. */ protected <ReqT, RespT> String spanName(MethodDescriptor<ReqT, RespT> methodDescriptor) { return methodDescriptor.getFullMethodName(); }
void log(String message) { logger.log( level, "{0}[{1}]: {2}", new Object[] { method.getFullMethodName(), Integer.toHexString(System.identityHashCode(this)), message }); }
/** * Returns a {@link RpcRequest} corresponding to the given {@link MethodDescriptor}. */ public static RpcRequest rpcRequest(MethodDescriptor<?, ?> method, Object message) { // We don't actually use the RpcRequest for request processing since it doesn't fit well with streaming. // We still populate it with a reasonable method name for use in logging. The service type is currently // arbitrarily set as gRPC doesn't use Class<?> to represent services - if this becomes a problem, we // would need to refactor it to take a Object instead. return RpcRequest.of(GrpcLogUtil.class, method.getFullMethodName(), message); }
/** * Returns a {@link RpcRequest} corresponding to the given {@link MethodDescriptor}. */ public static RpcRequest rpcRequest(MethodDescriptor<?, ?> method) { // See below to learn why we use GrpcLogUtil.class here. return RpcRequest.of(GrpcLogUtil.class, method.getFullMethodName()); }
public void removeService(ServerServiceDefinition service) { if (service != null) { for (ServerMethodDefinition<?, ?> method : service.getMethods()) { methods.remove(method.getMethodDescriptor().getFullMethodName()); } } }
@Override public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next) { System.out.println(call.getMethodDescriptor().getFullMethodName()); log.info(call.getMethodDescriptor().getFullMethodName()); return next.startCall(call, headers); } }
HandlerRegistry build() { final ImmutableMap.Builder<String, ServerMethodDefinition<?, ?>> mapBuilder = ImmutableMap.builder(); for (ServerServiceDefinition service : services.values()) { for (ServerMethodDefinition<?, ?> method : service.getMethods()) { mapBuilder.put(method.getMethodDescriptor().getFullMethodName(), method); } } return new HandlerRegistry(ImmutableList.copyOf(services.values()), mapBuilder.build()); } }
/** * {@inheritDoc} */ @Override public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall( final MethodDescriptor<ReqT, RespT> method, final CallOptions callOptions, final Channel next ) { final String methodType = method.getType().toString(); final String methodName = method.getFullMethodName(); final int channelId = next.hashCode(); log.info("gRPC {} call: {} (channel: {})", methodType, methodName, channelId); return next.newCall(method, callOptions); } }
@SuppressWarnings("rawtypes") public static HashMap<String, MethodDescriptor> getMethodDescriptorByAnnotation(Class<?> clazz, String serialization) throws Exception { String clazzName = getGrpcClassName(clazz); HashMap<String, MethodDescriptor> result = serviceMap.get(clazzName); if (result == null) { synchronized (serviceMap) { if (!serviceMap.containsKey(clazzName)) { ServiceDescriptor serviceDesc = getServiceDesc(getGrpcClassName(clazz)); HashMap<String, MethodDescriptor> methodMap = new HashMap<String, MethodDescriptor>(); for (MethodDescriptor<?, ?> methodDesc : serviceDesc.getMethods()) { Method interfaceMethod = getMethod(methodDesc.getFullMethodName(), clazz); if(JSON_CODEC.equals(serialization)){ methodDesc = convertJsonDescriptor(methodDesc, interfaceMethod.getParameterTypes()[0], interfaceMethod.getReturnType()); } methodMap.put(interfaceMethod.getName(), methodDesc); } serviceMap.put(clazzName, methodMap); } result = serviceMap.get(clazzName); } } return result; }
public GrpcClientLimiterBuilder partitionByMethod() { return partitionResolver(context -> context.getMethod().getFullMethodName()); }
/** * Partition the limit by method * @return Chainable builder */ public GrpcServerLimiterBuilder partitionByMethod() { return partitionResolver((GrpcServerRequestContext context) -> context.getCall().getMethodDescriptor().getFullMethodName()); }
public static MethodDescriptor convertJsonDescriptor(MethodDescriptor oldDesc, Class req, Class res){ MethodDescriptor.Marshaller reqMarshaller = getJsonMarshaller(req); MethodDescriptor.Marshaller resMarshaller = getJsonMarshaller(res); if(reqMarshaller != null && resMarshaller != null){ return MethodDescriptor.create(oldDesc.getType(), oldDesc.getFullMethodName(), reqMarshaller, resMarshaller); } return null; }
@SuppressWarnings({"rawtypes", "unchecked"}) public void addService(ServerServiceDefinition service, Provider provider) { for (ServerMethodDefinition<?, ?> method : service.getMethods()) { Method providerMethod = GrpcUtil.getMethod(method.getMethodDescriptor().getFullMethodName(), provider.getInterface()); MotanServerCallHandler handler; if (method.getServerCallHandler() instanceof MotanServerCallHandler) { handler = (MotanServerCallHandler) method.getServerCallHandler(); } else { handler = new MotanServerCallHandler(); method = method.withServerCallHandler(handler); } handler.init(provider, providerMethod); if (GrpcUtil.JSON_CODEC.equals(provider.getUrl().getParameter(URLParamType.serialize.getName()))) { MethodDescriptor jsonDesc = GrpcUtil.convertJsonDescriptor(method.getMethodDescriptor(), providerMethod.getParameterTypes()[0], providerMethod.getReturnType()); if(jsonDesc != null){ method = ServerMethodDefinition.create(jsonDesc, method.getServerCallHandler()); LoggerUtil.info("grpc method " + jsonDesc.getFullMethodName() +" use codec json."); } } methods.put(method.getMethodDescriptor().getFullMethodName(), method); } }
@Test public void interceptorsTest() throws ExecutionException, InterruptedException { GreeterGrpc.newFutureStub(channel) .sayHello(GreeterOuterClass.HelloRequest.newBuilder().setName("name").build()) .get().getMessage(); CalculatorGrpc.newFutureStub(channel) .calculate(CalculatorOuterClass.CalculatorRequest.newBuilder().setNumber1(1).setNumber2(1).build()) .get().getResult(); // global interceptor should be invoked once on each service Mockito.verify(globalInterceptor,Mockito.times(2)).interceptCall(Mockito.any(),Mockito.any(),Mockito.any()); // log interceptor should be invoked only on GreeterService and not CalculatorService outputCapture.expect(containsString(GreeterGrpc.getSayHelloMethod().getFullMethodName())); outputCapture.expect(not(containsString(CalculatorGrpc.getCalculateMethod().getFullMethodName()))); outputCapture.expect(containsString("I'm not Spring bean interceptor and still being invoked...")); }
@Test public void interceptorsTest() throws ExecutionException, InterruptedException { GreeterGrpc.newFutureStub(channel) .sayHello(GreeterOuterClass.HelloRequest.newBuilder().setName("name").build()) .get().getMessage(); CalculatorGrpc.newFutureStub(channel) .calculate(CalculatorOuterClass.CalculatorRequest.newBuilder().setNumber1(1).setNumber2(1).build()) .get().getResult(); // global interceptor should be invoked once on each service Mockito.verify(globalInterceptor,Mockito.times(2)).interceptCall(Mockito.any(),Mockito.any(),Mockito.any()); // log interceptor should be invoked only on GreeterService and not CalculatorService outputCapture.expect(containsString(GreeterGrpc.getSayHelloMethod().getFullMethodName())); outputCapture.expect(not(containsString(CalculatorGrpc.getCalculateMethod().getFullMethodName()))); outputCapture.expect(containsString("I'm not Spring bean interceptor and still being invoked...")); }
@Test public void unframed_noContentType() throws Exception { final HttpClient client = HttpClient.of(server.httpUri("/")); final AggregatedHttpMessage response = client.execute( HttpHeaders.of(HttpMethod.POST, UnitTestServiceGrpc.getStaticUnaryCallMethod().getFullMethodName()), REQUEST_MESSAGE.toByteArray()).aggregate().get(); assertThat(response.status()).isEqualTo(HttpStatus.UNSUPPORTED_MEDIA_TYPE); assertNoRpcContent(); }
@Test public void unframed() throws Exception { final HttpClient client = HttpClient.of(server.httpUri("/")); final AggregatedHttpMessage response = client.execute( HttpHeaders.of(HttpMethod.POST, UnitTestServiceGrpc.getStaticUnaryCallMethod().getFullMethodName()) .set(HttpHeaderNames.CONTENT_TYPE, "application/protobuf"), REQUEST_MESSAGE.toByteArray()).aggregate().get(); final SimpleResponse message = SimpleResponse.parseFrom(response.content().array()); assertThat(message).isEqualTo(RESPONSE_MESSAGE); assertThat(response.headers().getInt(HttpHeaderNames.CONTENT_LENGTH)) .isEqualTo(response.content().length()); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.method()).isEqualTo("armeria.grpc.testing.UnitTestService/StaticUnaryCall"); assertThat(rpcReq.params()).containsExactly(REQUEST_MESSAGE); assertThat(rpcRes.get()).isEqualTo(RESPONSE_MESSAGE); }); }
@Test public void unframed_grpcEncoding() throws Exception { final HttpClient client = HttpClient.of(server.httpUri("/")); final AggregatedHttpMessage response = client.execute( HttpHeaders.of(HttpMethod.POST, UnitTestServiceGrpc.getStaticUnaryCallMethod().getFullMethodName()) .set(HttpHeaderNames.CONTENT_TYPE, "application/protobuf") .set(GrpcHeaderNames.GRPC_ENCODING, "gzip"), REQUEST_MESSAGE.toByteArray()).aggregate().get(); assertThat(response.status()).isEqualTo(HttpStatus.UNSUPPORTED_MEDIA_TYPE); assertNoRpcContent(); }
@Test public void unframed_acceptEncoding() throws Exception { final HttpClient client = HttpClient.of(server.httpUri("/")); final AggregatedHttpMessage response = client.execute( HttpHeaders.of(HttpMethod.POST, UnitTestServiceGrpc.getStaticUnaryCallMethod().getFullMethodName()) .set(HttpHeaderNames.CONTENT_TYPE, "application/protobuf") .set(GrpcHeaderNames.GRPC_ACCEPT_ENCODING, "gzip,none"), REQUEST_MESSAGE.toByteArray()).aggregate().get(); final SimpleResponse message = SimpleResponse.parseFrom(response.content().array()); assertThat(message).isEqualTo(RESPONSE_MESSAGE); assertThat(response.headers().getInt(HttpHeaderNames.CONTENT_LENGTH)) .isEqualTo(response.content().length()); checkRequestLog((rpcReq, rpcRes, grpcStatus) -> { assertThat(rpcReq.method()).isEqualTo("armeria.grpc.testing.UnitTestService/StaticUnaryCall"); assertThat(rpcReq.params()).containsExactly(REQUEST_MESSAGE); assertThat(rpcRes.get()).isEqualTo(RESPONSE_MESSAGE); }); }
@Test public void unframed_streamingApi() throws Exception { final HttpClient client = HttpClient.of(server.httpUri("/")); final AggregatedHttpMessage response = client.execute( HttpHeaders.of(HttpMethod.POST, UnitTestServiceGrpc.getStaticStreamedOutputCallMethod().getFullMethodName()) .set(HttpHeaderNames.CONTENT_TYPE, "application/protobuf"), StreamingOutputCallRequest.getDefaultInstance().toByteArray()).aggregate().get(); assertThat(response.status()).isEqualTo(HttpStatus.BAD_REQUEST); assertNoRpcContent(); }