The English version of quarkus.io is the official project site. Translated sites are community supported on a best-effort basis.

Consumindo um serviço gRPC

Os clientes gRPC podem ser injectados no código da sua aplicação.

Consumir serviços gRPC requer que as classes gRPC sejam geradas. Coloque seus arquivos proto em src/main/proto e execute mvn compile .

Stubs e Injeção

A geração do gRPC fornece vários stubs, oferecendo diferentes maneiras de consumir um serviço gRPC. Você pode injetar:

  • uma interface de serviço utilizando a API Mutiny,

  • um stub bloqueante utilizando a API gRPC,

  • um stub reativo baseado no Mutiny,

  • o io.grpc.Channel do gRPC, que permite criar outros tipos de stubs.

import io.quarkus.grpc.GrpcClient;

import hello.Greeter;
import hello.GreeterGrpc.GreeterBlockingStub;
import hello.MutinyGreeterGrpc.MutinyGreeterStub;

class MyBean {

   // A service interface using the Mutiny API
   @GrpcClient("helloService")                   (1)
   Greeter greeter;

   // A reactive stub based on Mutiny
   @GrpcClient("helloService")
   MutinyGreeterGrpc.MutinyGreeterStub mutiny;

   // A blocking stub using the gRPC API
   @GrpcClient
   GreeterGrpc.GreeterBlockingStub helloService; (2)

   @GrpcClient("hello-service")
   Channel channel;

}
1 O ponto de injeção do cliente gRPC deve ser anotado com o qualificador @GrpcClient. Este qualificador pode ser usado para especificar o nome que é utilizado para configurar o cliente gRPC subjacente. Por exemplo, se você defini-lo como hello-service, a configuração do host do serviço é feita usando o qualificador quarkus.grpc.clients. hello-service.host.
2 Se o nome não for especificado através do endereço GrpcClient#value(), então o nome do campo é usado em seu lugar, por exemplo, helloService neste caso específico.

Os nomes das classes stub são derivados do nome do serviço usado em seu arquivo proto . Por exemplo, se você usar Greeter como nome de serviço, como no seguinte caso:

option java_package = "hello";

service Greeter {
    rpc SayHello (HelloRequest) returns (HelloReply) {}
}

Nesse caso, o nome da interface do serviço é: hello.Greeter, o nome do stub Mutiny é: hello.MutinyGreeterGrpc.MutinyGreeterStub e o nome do stub bloqueante é: hello.GreeterGrpc.GreeterBlockingStub.

Exemplos

Interface de serviço

import io.quarkus.grpc.GrpcClient;
import io.smallrye.mutiny.Uni;

import hello.Greeter;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/hello")
public class ExampleResource {

   @GrpcClient (1)
   Greeter hello;

   @GET
   @Path("/mutiny/{name}")
   public Uni<String> helloMutiny(String name) {
      return hello.sayHello(HelloRequest.newBuilder().setName(name).build())
            .onItem().transform(HelloReply::getMessage);
   }
}
1 O nome do serviço é derivado do ponto de injeção - o nome do campo é usado. A propriedade quarkus.grpc.clients.hello.host deve ser definida.

Stub Bloqueante

import io.quarkus.grpc.GrpcClient;

import hello.GreeterGrpc.GreeterBlockingStub;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/hello")
public class ExampleResource {

   @GrpcClient("hello") (1)
   GreeterGrpc.GreeterBlockingStub blockingHelloService;

   @GET
   @Path("/blocking/{name}")
   public String helloBlocking(String name) {
      return blockingHelloService.sayHello(HelloRequest.newBuilder().setName(name).build()).getMessage();
   }
}
1 A propriedade quarkus.grpc.clients.hello.host deve ser configurada.

Lidando com fluxos

O gRPC permite o envia e recebimento de fluxos:

service Streaming {
    rpc Source(Empty) returns (stream Item) {} // Returns a stream
    rpc Sink(stream Item) returns (Empty) {}   // Reads a stream
    rpc Pipe(stream Item) returns (stream Item) {}  // Reads a streams and return a streams
}

Utilizando o stub Mutiny, você pode interagir com eles da seguinte forma:

package io.quarkus.grpc.example.streaming;

import io.grpc.examples.streaming.Empty;
import io.grpc.examples.streaming.Item;
import io.grpc.examples.streaming.MutinyStreamingGrpc;
import io.quarkus.grpc.GrpcClient;

import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.Uni;

import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;

@Path("/streaming")
@Produces(MediaType.APPLICATION_JSON)
public class StreamingEndpoint {

    @GrpcClient
    MutinyStreamingGrpc.MutinyStreamingStub streaming;

    @GET
    public Multi<String> invokeSource() {
        // Retrieve a stream
        return streaming.source(Empty.newBuilder().build())
                .onItem().transform(Item::getValue);
    }

    @GET
    @Path("sink/{max}")
    public Uni<Void> invokeSink(int max) {
        // Send a stream and wait for completion
        Multi<Item> inputs = Multi.createFrom().range(0, max)
                .map(i -> Integer.toString(i))
                .map(i -> Item.newBuilder().setValue(i).build());
        return streaming.sink(inputs).onItem().ignore().andContinueWithNull();
    }

    @GET
    @Path("/{max}")
    public Multi<String> invokePipe(int max) {
        // Send a stream and retrieve a stream
        Multi<Item> inputs = Multi.createFrom().range(0, max)
                .map(i -> Integer.toString(i))
                .map(i -> Item.newBuilder().setValue(i).build());
        return streaming.pipe(inputs).onItem().transform(Item::getValue);
    }

}

Configuração do cliente

Para cada serviço gRPC que você injeta em sua aplicação, você pode configurar os seguintes atributos:

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configures the gRPC clients

Tipo

Padrão

Use new Vert.x gRPC client support. By default, we still use previous Java gRPC support.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__USE_QUARKUS_GRPC_CLIENT

Show more

boolean

false

Explicitly enable use of XDS.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__XDS_ENABLED

Show more

boolean

false

Use secure credentials.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__XDS_SECURE

Show more

boolean

false

Optional explicit target.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__XDS_TARGET

Show more

string

Explicitly enable use of in-process.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__IN_PROCESS_ENABLED

Show more

boolean

false

Set in-process name.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__IN_PROCESS_NAME

Show more

string

quarkus-grpc

Number of threads on a delayed gRPC ClientCall

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__STORK_THREADS

Show more

int

10

Deadline in milliseconds of delayed gRPC call

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__STORK_DEADLINE

Show more

long

5000

Number of retries on a gRPC ClientCall

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__STORK_RETRIES

Show more

int

3

Initial delay in seconds on refresh check

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__STORK_DELAY

Show more

long

60

Refresh period in seconds

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__STORK_PERIOD

Show more

long

120

The gRPC service port.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__PORT

Show more

int

9000

The gRPC service test port.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__TEST_PORT

Show more

int

The host name / IP on which the service is exposed.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__HOST

Show more

string

localhost

The classpath path or file path to a server certificate or certificate chain in PEM format.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__SSL_CERTIFICATE

Show more

path

The classpath path or file path to the corresponding certificate private key file in PEM format.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__SSL_KEY

Show more

path

An optional trust store which holds the certificate information of the certificates to trust The trust store can be either on classpath or in an external file.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__SSL_TRUST_STORE

Show more

path

Whether SSL/TLS is enabled.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__TLS_ENABLED

Show more

boolean

false

Enable trusting all certificates. Disabled by default.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__TLS_TRUST_ALL

Show more

boolean

false

Comma-separated list of the trust certificate files (Pem format).

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__TLS_TRUST_CERTIFICATE_PEM_CERTS

Show more

list of string

Path of the key file (JKS format).

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__TLS_TRUST_CERTIFICATE_JKS_PATH

Show more

string

Password of the key file.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__TLS_TRUST_CERTIFICATE_JKS_PASSWORD

Show more

string

Path to the key file (PFX format).

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__TLS_TRUST_CERTIFICATE_P12_PATH

Show more

string

Password of the key.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__TLS_TRUST_CERTIFICATE_P12_PASSWORD

Show more

string

Comma-separated list of the path to the key files (Pem format).

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__TLS_KEY_CERTIFICATE_PEM_KEYS

Show more

list of string

Comma-separated list of the path to the certificate files (Pem format).

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__TLS_KEY_CERTIFICATE_PEM_CERTS

Show more

list of string

Path of the key file (JKS format).

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__TLS_KEY_CERTIFICATE_JKS_PATH

Show more

string

Password of the key file.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__TLS_KEY_CERTIFICATE_JKS_PASSWORD

Show more

string

Path to the key file (PFX format).

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__TLS_KEY_CERTIFICATE_P12_PATH

Show more

string

Password of the key.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__TLS_KEY_CERTIFICATE_P12_PASSWORD

Show more

string

Whether hostname should be verified in the SSL/TLS handshake.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__TLS_VERIFY_HOSTNAME

Show more

boolean

true

Use a name resolver. Defaults to dns. If set to "stork", host will be treated as SmallRye Stork service name

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__NAME_RESOLVER

Show more

string

dns

Whether plain-text should be used instead of TLS. Enabled by default, except if TLS/SSL is configured. In this case, plain-text is disabled.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__PLAIN_TEXT

Show more

boolean

The duration after which a keep alive ping is sent.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__KEEP_ALIVE_TIME

Show more

Duration

The flow control window in bytes. Default is 1MiB.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__FLOW_CONTROL_WINDOW

Show more

int

The duration without ongoing RPCs before going to idle mode.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__IDLE_TIMEOUT

Show more

Duration

The amount of time the sender of a keep alive ping waits for an acknowledgement.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__KEEP_ALIVE_TIMEOUT

Show more

Duration

Whether keep-alive will be performed when there are no outstanding RPC on a connection.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__KEEP_ALIVE_WITHOUT_CALLS

Show more

boolean

false

The max number of hedged attempts.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__MAX_HEDGED_ATTEMPTS

Show more

int

5

The max number of retry attempts. Retry must be explicitly enabled.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__MAX_RETRY_ATTEMPTS

Show more

int

5

The maximum number of channel trace events to keep in the tracer for each channel or sub-channel.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__MAX_TRACE_EVENTS

Show more

int

The maximum message size allowed for a single gRPC frame (in bytes). Default is 4 MiB.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__MAX_INBOUND_MESSAGE_SIZE

Show more

int

The maximum size of metadata allowed to be received (in bytes). Default is 8192B.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__MAX_INBOUND_METADATA_SIZE

Show more

int

The negotiation type for the HTTP/2 connection. Accepted values are: TLS, PLAINTEXT_UPGRADE, PLAINTEXT

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__NEGOTIATION_TYPE

Show more

string

TLS

Overrides the authority used with TLS and HTTP virtual hosting.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__OVERRIDE_AUTHORITY

Show more

string

The per RPC buffer limit in bytes used for retry.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__PER_RPC_BUFFER_LIMIT

Show more

long

Whether retry is enabled. Note that retry is disabled by default.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__RETRY

Show more

boolean

false

The retry buffer size in bytes.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__RETRY_BUFFER_SIZE

Show more

long

Use a custom user-agent.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__USER_AGENT

Show more

string

Use a custom load balancing policy. Accepted values are: pick_first, round_robin, grpclb. This value is ignored if name-resolver is set to 'stork'.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__LOAD_BALANCING_POLICY

Show more

string

pick_first

The compression to use for each call. The accepted values are gzip and identity.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__COMPRESSION

Show more

string

The deadline used for each call.

Environment variable: QUARKUS_GRPC_CLIENTS__CLIENT_NAME__DEADLINE

Show more

Duration

About the Duration format

To write duration values, use the standard java.time.Duration format. See the Duration#parse() Java API documentation for more information.

Você também pode usar um formato simplificado, começando com um número:

  • Se o valor for apenas um número, ele representará o tempo em segundos.

  • Se o valor for um número seguido de 'ms', ele representa o tempo em milissegundos.

Em outros casos, o formato simplificado é traduzido para o formato 'java.time.Duration' para análise:

  • Se o valor for um número seguido de 'h', 'm' ou 's', ele é prefixado com 'PT'.

  • Se o valor for um número seguido de 'd', ele é prefixado com 'P'.

O client-name é o nome definido no @GrpcClient ou derivado do ponto de injeção, se não for explicitamente definido.

Os exemplos a seguir usam hello como o nome do cliente. Não se esqueça de substituí-lo pelo nome que você usou na anotação @GrpcClient .

Quando você habilita quarkus.grpc.clients."client-name".use-quarkus-grpc-client, você está usando a nova implementação do canal gRPC Vert.x, portanto, nem todas as propriedades de configuração podem ser aplicadas. E, atualmente, ainda não existe suporte para o Stork.
Quando você habilita quarkus.grpc.clients."client-name".xds.enabled, é o xDS que deve tratar da maior parte da configuração acima.

Habilitando o TLS

Para habilitar o TLS, use a seguinte configuração. Lembre-se de que todos os caminhos na configuração podem especificar um recurso no classpath (geralmente em src/main/resources ou de sua subpasta) ou um arquivo externo.

quarkus.grpc.clients.hello.host=localhost

# either a path to a classpath resource or to a file:
quarkus.grpc.clients.hello.ssl.trust-store=tls/ca.pem
Quando SSL/TLS é configurado, plain-text é automaticamente desativado.

TLS com autenticação mútua

Para utilizar o TLS com autenticação mútua, utilize a seguinte configuração:

quarkus.grpc.clients.hello.host=localhost
quarkus.grpc.clients.hello.plain-text=false

# all the following may use either a path to a classpath resource or to a file:
quarkus.grpc.clients.hello.ssl.certificate=tls/client.pem
quarkus.grpc.clients.hello.ssl.key=tls/client.key
quarkus.grpc.clients.hello.ssl.trust-store=tls/ca.pem

Prazos (Deadlines) para o Stub do Cliente

Se o senhor precisar configurar um prazo (deadline) para um stub de gRPC, ou seja, para especificar uma duração de tempo após o qual o stub sempre retornará o erro de status DEADLINE_EXCEEDED . Você pode especificar o prazo através da propriedade de configuração quarkus.grpc.clients."service-name".deadline , por exemplo:

quarkus.grpc.clients.hello.host=localhost
quarkus.grpc.clients.hello.deadline=2s (1)
1 Defina o prazo (deadline) para todos os stubs injetados.
Não utilize esse recurso para implementar um tempo limite (timeout) de RPC. Para implementar um timeout de RPC, use Mutiny call.ifNoItem().after(…​) ou Fault Tolerance @Timeout .

Cabeçalhos gRPC

Da mesma forma que no HTTP, chamadas gRPC podem transportar cabeçalhos junto com a mensagem. Cabeçalhos podem ser úteis, por exemplo, para autenticação.

Para definir cabeçalhos para uma chamada gRPC, crie um cliente com cabeçalhos anexados e, em seguida, realize a chamada neste cliente:

import jakarta.enterprise.context.ApplicationScoped;

import examples.Greeter;
import examples.HelloReply;
import examples.HelloRequest;
import io.grpc.Metadata;
import io.quarkus.grpc.GrpcClient;
import io.quarkus.grpc.GrpcClientUtils;
import io.smallrye.mutiny.Uni;

@ApplicationScoped
public class MyService {
    @GrpcClient
    Greeter client;

    public Uni<HelloReply> doTheCall() {
        Metadata extraHeaders = new Metadata();
        if (headers) {
            extraHeaders.put("my-header", "my-interface-value");
        }

        Greeter alteredClient = GrpcClientUtils.attachHeaders(client, extraHeaders); (1)

        return alteredClient.sayHello(HelloRequest.newBuilder().setName(name).build()); (2)
    }
}
1 Alterar o cliente para fazer chamadas com os extraHeaders anexados
2 Realize a chamada com o cliente alterado. O cliente original permanece inalterado.

GrpcClientUtils funciona com todas as variações de clientes.

Interceptores de clientes

Um interceptor de cliente gRPC pode ser implementado por um bean CDI que também implementa a interface io.grpc.ClientInterceptor . Você pode anotar um cliente injetado com @io.quarkus.grpc.RegisterClientInterceptor para registrar o interceptor especificado para a instância específica do cliente. A anotação @RegisterClientInterceptor pode ser repetida. Como alternativa, se você deseja aplicar o interceptador a qualquer cliente injetado, anote o bean do interceptador com @io.quarkus.grpc.GlobalInterceptor .

Exemplo de Interceptor Global de Cliente
import io.quarkus.grpc.GlobalInterceptor;

import io.grpc.ClientInterceptor;

@GlobalInterceptor (1)
@ApplicationScoped
public class MyInterceptor implements ClientInterceptor {

    @Override
    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method,
            CallOptions callOptions, Channel next) {
       // ...
    }
}
1 Este interceptor é aplicado a todos os clientes gRPC injectados.

Também é possível anotar um método produtor como um interceptor global:

import io.quarkus.grpc.GlobalInterceptor;

import jakarta.enterprise.inject.Produces;

public class MyProducer {
    @GlobalInterceptor
    @Produces
    public MyInterceptor myInterceptor() {
        return new MyInterceptor();
    }
}
Consulte o JavaDoc do ClientInterceptor para implementar corretamente o seu interceptor.
Exemplo de @RegisterClientInterceptor
import io.quarkus.grpc.GrpcClient;
import io.quarkus.grpc.RegisterClientInterceptor;

import hello.Greeter;

@ApplicationScoped
class MyBean {

    @RegisterClientInterceptor(MySpecialInterceptor.class) (1)
    @GrpcClient("helloService")
    Greeter greeter;
}
1 Regista o MySpecialInterceptor para este cliente específico.

Quando tem vários interceptadores de clientes, pode ordená-los implementando a interface jakarta.enterprise.inject.spi.Prioritized:

@ApplicationScoped
public class MyInterceptor implements ClientInterceptor, Prioritized {

    @Override
    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(MethodDescriptor<ReqT, RespT> method,
            CallOptions callOptions, Channel next) {
       // ...
    }

    @Override
    public int getPriority() {
        return 10;
    }
}

Os interceptadores com a maior prioridade são chamados primeiro. A prioridade padrão, usada se o interceptador não implementar a interface Prioritized , é 0 .

Métricas de Cliente gRPC

Habilitando a coleta de métricas

As métricas do cliente gRPC são habilitadas automaticamente quando a aplicação também utiliza a extensão quarkus-micrometer. O Micrometer coleta as métricas de todos os clientes gRPC usados pelo aplicação.

Como exemplo, se você exportar as métricas para o Prometheus, obterá:

# HELP grpc_client_responses_received_messages_total The total number of responses received
# TYPE grpc_client_responses_received_messages_total counter
grpc_client_responses_received_messages_total{method="SayHello",methodType="UNARY",service="helloworld.Greeter",} 6.0
# HELP grpc_client_requests_sent_messages_total The total number of requests sent
# TYPE grpc_client_requests_sent_messages_total counter
grpc_client_requests_sent_messages_total{method="SayHello",methodType="UNARY",service="helloworld.Greeter",} 6.0
# HELP grpc_client_processing_duration_seconds The total time taken for the client to complete the call, including network delay
# TYPE grpc_client_processing_duration_seconds summary
grpc_client_processing_duration_seconds_count{method="SayHello",methodType="UNARY",service="helloworld.Greeter",statusCode="OK",} 6.0
grpc_client_processing_duration_seconds_sum{method="SayHello",methodType="UNARY",service="helloworld.Greeter",statusCode="OK",} 0.167411625
# HELP grpc_client_processing_duration_seconds_max The total time taken for the client to complete the call, including network delay
# TYPE grpc_client_processing_duration_seconds_max gauge
grpc_client_processing_duration_seconds_max{method="SayHello",methodType="UNARY",service="helloworld.Greeter",statusCode="OK",} 0.136478028

O nome do serviço, o método e o tipo podem ser encontrados nas tags.

Desativar a coleta de métricas

Para desativar as métricas do cliente gRPC quando se utiliza quarkus-micrometer, adicione a seguinte propriedade à configuração da aplicação:

quarkus.micrometer.binder.grpc-client.enabled=false

Tratamento personalizado de excepções

Se algum dos serviços gRPC ou interceptadores de servidor lançar uma exceção (personalizada), você poderá adicionar seu próprio ExceptionHandlerProvider como um bean CDI em sua aplicação, para fornecer um tratamento personalizado dessas exceções.

por exemplo.

@ApplicationScoped
public class HelloExceptionHandlerProvider implements ExceptionHandlerProvider {
    @Override
    public <ReqT, RespT> ExceptionHandler<ReqT, RespT> createHandler(ServerCall.Listener<ReqT> listener,
            ServerCall<ReqT, RespT> serverCall, Metadata metadata) {
        return new HelloExceptionHandler<>(listener, serverCall, metadata);
    }

    @Override
    public Throwable transform(Throwable t) {
        if (t instanceof HelloException he) {
            return new StatusRuntimeException(Status.ABORTED.withDescription(he.getName()));
        } else {
            return ExceptionHandlerProvider.toStatusException(t, true);
        }
    }

    private static class HelloExceptionHandler<A, B> extends ExceptionHandler<A, B> {
        public HelloExceptionHandler(ServerCall.Listener<A> listener, ServerCall<A, B> call, Metadata metadata) {
            super(listener, call, metadata);
        }

        @Override
        protected void handleException(Throwable t, ServerCall<A, B> call, Metadata metadata) {
            StatusRuntimeException sre = (StatusRuntimeException) ExceptionHandlerProvider.toStatusException(t, true);
            Metadata trailers = sre.getTrailers() != null ? sre.getTrailers() : metadata;
            call.close(sre.getStatus(), trailers);
        }
    }
}

Modo de desenvolvimento

Por padrão, ao iniciar a aplicação no modo de desenvolvimento, um servidor gRPC é iniciado, mesmo que nenhum serviço esteja configurado. Você pode configurar o comportamento do modo de desenvolvimento da extensão gRPC usando as seguintes propriedades.

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property

Tipo

Padrão

Start gRPC server in dev mode even if no gRPC services are implemented. By default set to true to ease incremental development of new services using dev mode.

Environment variable: QUARKUS_GRPC_DEV_MODE_FORCE_SERVER_START

Show more

boolean

true

Injetar clientes falsos

No seu @QuarkusTest, você pode utilizar @InjectMock para injetar o cliente Mutiny de um serviço gRPC:

@QuarkusTest
public class GrpcMockTest {

    @InjectMock
    @GrpcClient("hello")
    Greeter greeter;

    @Test
    void test1() {
        HelloRequest request = HelloRequest.newBuilder().setName("neo").build();
        Mockito.when(greeter.sayHello(Mockito.any(HelloRequest.class)))
                .thenReturn(Uni.createFrom().item(HelloReply.newBuilder().setMessage("hello neo").build()));
        Assertions.assertEquals(greeter.sayHello(request).await().indefinitely().getMessage(), "hello neo");
    }
}
Apenas o cliente Mutiny pode ser mocked (simulado), canais e outros stubs não podem ser simulados.

Conteúdo Relacionado