CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-quarkus--quarkus-grpc

Quarkus gRPC extension that enables implementing and consuming gRPC services with reactive and imperative programming models.

Pending
Overview
Eval results
Files

configuration.mddocs/

Configuration and Customization

Server and client configuration with customization hooks for advanced use cases including TLS, load balancing, and performance tuning. The configuration system provides comprehensive control over gRPC behavior.

Capabilities

ServerBuilderCustomizer Interface

Allows customization of gRPC server building process. Implement this interface to customize server configuration beyond what's available through standard configuration properties.

/**
 * Allow for customization of Server building.
 * Implement the customize method, depending on which ServerBuilder implementation you're going to use,
 * e.g. Vert.x or Netty.
 * This is an experimental API, subject to change.
 */
public interface ServerBuilderCustomizer<T extends ServerBuilder<T>> {
    
    /**
     * Customize a ServerBuilder instance.
     *
     * @param config server's configuration
     * @param builder Server builder instance
     */
    default void customize(GrpcServerConfiguration config, T builder) {
    }
    
    /**
     * Customize a GrpcServerOptions instance.
     *
     * @param config server's configuration
     * @param options GrpcServerOptions instance
     */
    default void customize(GrpcServerConfiguration config, GrpcServerOptions options) {
    }
    
    /**
     * Priority by which the customizers are applied.
     * Higher priority is applied later.
     *
     * @return the priority
     */
    default int priority() {
        return 0;
    }
}

Usage Examples:

import io.quarkus.grpc.api.ServerBuilderCustomizer;
import io.grpc.netty.NettyServerBuilder;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class CustomServerBuilder implements ServerBuilderCustomizer<NettyServerBuilder> {
    
    @Override
    public void customize(GrpcServerConfiguration config, NettyServerBuilder builder) {
        // Customize Netty server builder
        builder.maxInboundMessageSize(4 * 1024 * 1024) // 4MB
               .maxInboundMetadataSize(8 * 1024) // 8KB
               .keepAliveTime(30, TimeUnit.SECONDS)
               .keepAliveTimeout(10, TimeUnit.SECONDS)
               .permitKeepAliveWithoutCalls(true)
               .maxConnectionIdle(5, TimeUnit.MINUTES);
    }
    
    @Override
    public void customize(GrpcServerConfiguration config, GrpcServerOptions options) {
        // Customize Vert.x gRPC server options
        options.setMaxMessageSize(4 * 1024 * 1024);
        options.setKeepAliveTime(30000); // 30 seconds
        options.setKeepAliveTimeout(10000); // 10 seconds
    }
    
    @Override
    public int priority() {
        return 100; // Higher priority than default customizers
    }
}

ChannelBuilderCustomizer Interface

Allows customization of gRPC channel building process for clients. Implement this interface to customize client configuration beyond standard configuration options.

/**
 * Allow for customization of Channel building.
 * Implement the customize method, depending on which Channel implementation you're going to use,
 * e.g. Vert.x or Netty.
 * This is an experimental API, subject to change.
 */
public interface ChannelBuilderCustomizer<T extends ManagedChannelBuilder<T>> {
    
    /**
     * Customize a ManagedChannelBuilder instance.
     *
     * @param name gRPC client name
     * @param config client's configuration
     * @param builder Channel builder instance
     * @return map of config properties to be used as default service config against the builder
     */
    default Map<String, Object> customize(String name, 
                                         GrpcClientConfiguration config, 
                                         T builder) {
        return Map.of();
    }
    
    /**
     * Customize a GrpcClientOptions instance.
     *
     * @param name gRPC client name
     * @param config client's configuration
     * @param options GrpcClientOptions instance
     */
    default void customize(String name, 
                          GrpcClientConfiguration config, 
                          GrpcClientOptions options) {
    }
    
    /**
     * Priority by which the customizers are applied.
     * Higher priority is applied later.
     *
     * @return the priority
     */
    default int priority() {
        return 0;
    }
}

Usage Examples:

import io.quarkus.grpc.api.ChannelBuilderCustomizer;
import io.grpc.netty.NettyChannelBuilder;
import jakarta.enterprise.context.ApplicationScoped;
import java.util.Map;

@ApplicationScoped
public class CustomChannelBuilder implements ChannelBuilderCustomizer<NettyChannelBuilder> {
    
    @Override
    public Map<String, Object> customize(String name, 
                                        GrpcClientConfiguration config, 
                                        NettyChannelBuilder builder) {
        
        // Customize based on client name
        if ("high-throughput-service".equals(name)) {
            builder.maxInboundMessageSize(16 * 1024 * 1024) // 16MB
                   .maxInboundMetadataSize(16 * 1024) // 16KB
                   .keepAliveTime(15, TimeUnit.SECONDS)
                   .keepAliveWithoutCalls(true);
        } else {
            builder.maxInboundMessageSize(4 * 1024 * 1024) // 4MB
                   .keepAliveTime(30, TimeUnit.SECONDS);
        }
        
        // Return service config for load balancing
        return Map.of(
            "loadBalancingConfig", Map.of(
                "round_robin", Map.of()
            ),
            "retryPolicy", Map.of(
                "maxAttempts", 3,
                "initialBackoff", "1s",
                "maxBackoff", "10s",
                "backoffMultiplier", 2.0,
                "retryableStatusCodes", List.of("UNAVAILABLE", "DEADLINE_EXCEEDED")
            )
        );
    }
    
    @Override
    public void customize(String name, 
                         GrpcClientConfiguration config, 
                         GrpcClientOptions options) {
        // Customize Vert.x gRPC client options
        options.setMaxMessageSize(4 * 1024 * 1024);
        options.setKeepAliveTime(30000);
        
        if ("secure-service".equals(name)) {
            options.setSsl(true);
            options.setTrustAll(false);
        }
    }
    
    @Override
    public int priority() {
        return 50;
    }
}

Configuration Classes

Core configuration classes for gRPC server and client settings:

public class GrpcConfiguration {
    // Root gRPC configuration
}

public class GrpcServerConfiguration {
    // Server-specific configuration including port, TLS, etc.
}

public class GrpcClientConfiguration {
    // Client-specific configuration including host, port, TLS, etc.
}

Configuration Examples

Server Configuration

# Basic server configuration
quarkus.grpc.server.port=9000
quarkus.grpc.server.host=0.0.0.0

# TLS configuration
quarkus.grpc.server.ssl.certificate=path/to/server.crt
quarkus.grpc.server.ssl.key=path/to/server.key
quarkus.grpc.server.ssl.key-store=path/to/keystore.p12
quarkus.grpc.server.ssl.key-store-password=secret

# Performance tuning
quarkus.grpc.server.max-inbound-message-size=4194304
quarkus.grpc.server.max-inbound-metadata-size=8192
quarkus.grpc.server.keep-alive-time=30s
quarkus.grpc.server.keep-alive-timeout=10s

# Development settings
quarkus.grpc.server.reflection.enabled=true
quarkus.grpc.server.health.enabled=true

Client Configuration

# User service client
quarkus.grpc.clients.user-service.host=user-service.example.com
quarkus.grpc.clients.user-service.port=443
quarkus.grpc.clients.user-service.ssl.trust-store=path/to/truststore.p12
quarkus.grpc.clients.user-service.ssl.trust-store-password=secret
quarkus.grpc.clients.user-service.deadline=10s

# Payment service client with load balancing
quarkus.grpc.clients.payment-service.host=payment-service
quarkus.grpc.clients.payment-service.port=9000
quarkus.grpc.clients.payment-service.load-balancing-policy=round_robin
quarkus.grpc.clients.payment-service.max-retry-attempts=3

# Local development client
quarkus.grpc.clients.local-service.host=localhost
quarkus.grpc.clients.local-service.port=9001
quarkus.grpc.clients.local-service.plain-text=true

Advanced TLS Configuration

@ApplicationScoped
public class TlsCustomizer implements ServerBuilderCustomizer<NettyServerBuilder> {
    
    @Override
    public void customize(GrpcServerConfiguration config, NettyServerBuilder builder) {
        try {
            // Custom SSL context
            SslContextBuilder sslContextBuilder = SslContextBuilder.forServer(
                new File("path/to/server.crt"),
                new File("path/to/server.key")
            );
            
            // Configure client authentication
            sslContextBuilder.clientAuth(ClientAuth.REQUIRE);
            
            // Configure trusted client certificates
            sslContextBuilder.trustManager(new File("path/to/client-ca.crt"));
            
            // Configure cipher suites
            sslContextBuilder.ciphers(Arrays.asList(
                "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
                "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
            ));
            
            // Configure protocols
            sslContextBuilder.protocols("TLSv1.2", "TLSv1.3");
            
            builder.sslContext(sslContextBuilder.build());
            
        } catch (Exception e) {
            throw new RuntimeException("Failed to configure TLS", e);
        }
    }
}

Load Balancing Configuration

@ApplicationScoped
public class LoadBalancingCustomizer implements ChannelBuilderCustomizer<NettyChannelBuilder> {
    
    @Override
    public Map<String, Object> customize(String name, 
                                        GrpcClientConfiguration config, 
                                        NettyChannelBuilder builder) {
        
        if ("distributed-service".equals(name)) {
            // Configure service discovery
            builder.nameResolverFactory(new DnsNameResolverProvider())
                   .defaultLoadBalancingPolicy("round_robin");
            
            // Return advanced service config
            return Map.of(
                "loadBalancingConfig", List.of(
                    Map.of("weighted_round_robin", Map.of(
                        "enableOobLoadReport", true,
                        "oobReportingPeriod", "10s"
                    )),
                    Map.of("round_robin", Map.of())
                ),
                "healthCheckConfig", Map.of(
                    "serviceName", "health-check-service"
                )
            );
        }
        
        return Map.of();
    }
}

Custom Interceptor Configuration

@ApplicationScoped
public class InterceptorCustomizer implements ServerBuilderCustomizer<NettyServerBuilder> {
    
    @Inject
    MeterRegistry meterRegistry;
    
    @Inject
    TracingService tracingService;
    
    @Override
    public void customize(GrpcServerConfiguration config, NettyServerBuilder builder) {
        // Add metrics interceptor
        builder.intercept(new MetricsServerInterceptor(meterRegistry));
        
        // Add tracing interceptor
        builder.intercept(new TracingServerInterceptor(tracingService));
        
        // Add rate limiting interceptor
        builder.intercept(new RateLimitingInterceptor(
            RateLimiter.create(100.0))); // 100 requests per second
        
        // Add authentication interceptor for specific services
        builder.intercept(ServerInterceptors.useInputStreamMessages(
            new AuthenticationInterceptor()));
    }
}

Development Mode Configuration

@ApplicationScoped
public class DevelopmentCustomizer implements ServerBuilderCustomizer<NettyServerBuilder> {
    
    @Override
    public void customize(GrpcServerConfiguration config, NettyServerBuilder builder) {
        if (LaunchMode.current() == LaunchMode.DEVELOPMENT) {
            // Enable reflection for development
            builder.addService(ProtoReflectionService.newInstance());
            
            // Add development interceptors
            builder.intercept(new DevelopmentLoggingInterceptor());
            builder.intercept(new RequestDumpingInterceptor());
            
            // Relaxed settings for development
            builder.permitKeepAliveWithoutCalls(true)
                   .permitKeepAliveTime(1, TimeUnit.SECONDS);
        }
    }
}

Health Check Integration

# Enable health checks
quarkus.grpc.server.health.enabled=true

# Configure health check service
quarkus.grpc.server.health.service-name=grpc-health-check
@ApplicationScoped
public class HealthCheckCustomizer implements ServerBuilderCustomizer<NettyServerBuilder> {
    
    @Override
    public void customize(GrpcServerConfiguration config, NettyServerBuilder builder) {
        // Add custom health check service
        HealthStatusManager healthStatusManager = new HealthStatusManager();
        builder.addService(healthStatusManager.getHealthService());
        
        // Set service status
        healthStatusManager.setStatus("", HealthCheckResponse.Status.SERVING);
        healthStatusManager.setStatus("greeting-service", HealthCheckResponse.Status.SERVING);
    }
}

Configuration Priority

  1. Application properties (highest priority)
  2. Environment variables
  3. System properties
  4. Default values (lowest priority)

Configuration customizers are applied in priority order (higher priority applied later), allowing fine-grained control over the final configuration.

Install with Tessl CLI

npx tessl i tessl/maven-io-quarkus--quarkus-grpc

docs

client-usage.md

configuration.md

exception-handling.md

index.md

interceptors.md

reactive-streaming.md

service-implementation.md

tile.json