CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-google-api--gax-grpc

Google API Extensions for Java providing gRPC-specific functionality for Google Cloud client libraries

Pending
Overview
Eval results
Files

interceptors.mddocs/

Interceptors and Metadata

Comprehensive interceptor support for headers, logging, metadata handling, and custom request/response processing.

Capabilities

GrpcInterceptorProvider

Provider interface for supplying custom gRPC ClientInterceptors to the channel.

/**
 * Provider for custom gRPC ClientInterceptors
 * Allows injection of custom interceptors into the gRPC call chain
 */
public interface GrpcInterceptorProvider {
    /** Get list of client interceptors to apply */
    List<ClientInterceptor> getInterceptors();
}

/**
 * Static factory methods for common interceptor providers
 */
public class GrpcInterceptorProviders {
    /** Create provider with single interceptor */
    public static GrpcInterceptorProvider create(ClientInterceptor interceptor);
    
    /** Create provider with multiple interceptors */
    public static GrpcInterceptorProvider create(List<ClientInterceptor> interceptors);
    
    /** Create empty provider */
    public static GrpcInterceptorProvider empty();
    
    /** Combine multiple providers */
    public static GrpcInterceptorProvider combine(GrpcInterceptorProvider... providers);
}

GrpcHeaderInterceptor

Built-in interceptor for managing request headers with dynamic header injection.

/**
 * Interceptor for managing gRPC request headers
 * Supports static headers and dynamic header providers
 */
public class GrpcHeaderInterceptor implements ClientInterceptor {
    /** Create interceptor with static headers */
    public static GrpcHeaderInterceptor create(Map<String, String> headers);
    
    /** Create interceptor with header provider */
    public static GrpcHeaderInterceptor create(HeaderProvider headerProvider);
    
    /** Intercept gRPC call to add headers */
    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
        MethodDescriptor<ReqT, RespT> method,
        CallOptions callOptions,
        Channel next);
}

GrpcMetadataHandlerInterceptor

Interceptor for extracting and processing response metadata from gRPC calls.

/**
 * Interceptor for handling gRPC response metadata
 * Extracts headers and trailers from responses
 */
public class GrpcMetadataHandlerInterceptor implements ClientInterceptor {
    /** Create metadata handler interceptor */
    public static GrpcMetadataHandlerInterceptor create(ResponseMetadataHandler handler);
    
    /** Intercept call to handle metadata */
    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
        MethodDescriptor<ReqT, RespT> method,
        CallOptions callOptions,
        Channel next);
}

GrpcResponseMetadata

Response metadata handler providing access to gRPC headers and trailers.

/**
 * Handler for gRPC response metadata
 * Provides access to headers and trailers from responses
 */
public class GrpcResponseMetadata implements ResponseMetadata {
    /** Create response metadata handler */
    public static GrpcResponseMetadata create();
    
    /** Get response headers as metadata map */
    public Map<String, List<String>> getMetadata();
    
    /** Get response trailers metadata */
    public List<String> getTrailersMetadata();
    
    /** Get specific header values */
    public List<String> getMetadata(String key);
    
    /** Get trailer value for key */
    public String getTrailerValue(String key);
    
    /** Check if metadata contains key */
    public boolean containsKey(String key);
    
    /** Get all metadata keys */
    public Set<String> getKeys();
}

ResponseMetadataHandler

Handler interface for processing response metadata from gRPC calls.

/**
 * Handler interface for processing response metadata
 * Called when response metadata is received
 */
public interface ResponseMetadataHandler {
    /** Handle response headers */
    void onHeaders(Metadata headers);
    
    /** Handle response trailers */
    void onTrailers(Metadata trailers);
    
    /** Handle both headers and trailers */
    default void onMetadata(Metadata headers, Metadata trailers) {
        onHeaders(headers);
        onTrailers(trailers);
    }
}

GrpcLoggingInterceptor

Built-in interceptor for logging gRPC requests and responses.

/**
 * Interceptor for logging gRPC calls
 * Supports configurable logging levels and content filtering
 */
public class GrpcLoggingInterceptor implements ClientInterceptor {
    /** Create logging interceptor with default settings */
    public static GrpcLoggingInterceptor create();
    
    /** Create logging interceptor with logger */
    public static GrpcLoggingInterceptor create(Logger logger);
    
    /** Create logging interceptor with configuration */
    public static GrpcLoggingInterceptor create(LoggingConfig config);
    
    /** Intercept call for logging */
    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
        MethodDescriptor<ReqT, RespT> method,
        CallOptions callOptions,
        Channel next);
}

/**
 * Configuration for gRPC logging interceptor
 */
public static class GrpcLoggingInterceptor.LoggingConfig {
    /** Set whether to log request payloads */
    public LoggingConfig logRequestPayloads(boolean enabled);
    
    /** Set whether to log response payloads */
    public LoggingConfig logResponsePayloads(boolean enabled);
    
    /** Set whether to log metadata */
    public LoggingConfig logMetadata(boolean enabled);
    
    /** Set logging level */
    public LoggingConfig logLevel(Level level);
    
    /** Set maximum payload size to log */
    public LoggingConfig maxPayloadSize(int maxSize);
    
    /** Set logger instance */
    public LoggingConfig logger(Logger logger);
}

Interceptor Utilities

Interceptor Chain Management

/**
 * Utilities for managing interceptor chains
 */
public class InterceptorChainUtils {
    /** Create interceptor chain from providers */
    public static ClientInterceptor chainInterceptors(List<GrpcInterceptorProvider> providers);
    
    /** Add interceptor to existing chain */
    public static ClientInterceptor addInterceptor(ClientInterceptor chain, ClientInterceptor interceptor);
    
    /** Remove interceptor from chain by type */
    public static ClientInterceptor removeInterceptor(ClientInterceptor chain, Class<?> interceptorType);
    
    /** Get interceptors of specific type from chain */
    public static <T extends ClientInterceptor> List<T> getInterceptors(ClientInterceptor chain, Class<T> type);
}

Custom Interceptor Base Classes

/**
 * Base class for custom interceptors with common functionality
 */
public abstract class BaseGrpcInterceptor implements ClientInterceptor {
    /** Protected constructor for subclasses */
    protected BaseGrpcInterceptor();
    
    /** Template method for call interception */
    public final <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
        MethodDescriptor<ReqT, RespT> method,
        CallOptions callOptions,
        Channel next);
    
    /** Override this method in subclasses */
    protected abstract <ReqT, RespT> ClientCall<ReqT, RespT> doInterceptCall(
        MethodDescriptor<ReqT, RespT> method,
        CallOptions callOptions,
        Channel next);
    
    /** Utility method to create forwarding call */
    protected <ReqT, RespT> ForwardingClientCall<ReqT, RespT> createForwardingCall(
        ClientCall<ReqT, RespT> delegate);
}

/**
 * Base class for simple interceptors that only modify requests
 */
public abstract class SimpleRequestInterceptor extends BaseGrpcInterceptor {
    /** Override to modify requests */
    protected abstract <ReqT> ReqT modifyRequest(ReqT request, MethodDescriptor<ReqT, ?> method);
}

/**
 * Base class for simple interceptors that only modify responses
 */
public abstract class SimpleResponseInterceptor extends BaseGrpcInterceptor {
    /** Override to modify responses */
    protected abstract <RespT> RespT modifyResponse(RespT response, MethodDescriptor<?, RespT> method);
}

Header and Metadata Types

Header Provider Interface

/**
 * Provider for dynamic headers
 * Allows headers to be computed at request time
 */
public interface HeaderProvider {
    /** Get headers map */
    Map<String, String> getHeaders();
    
    /** Get headers for specific method */
    default Map<String, String> getHeaders(MethodDescriptor<?, ?> method) {
        return getHeaders();
    }
}

/**
 * Static header provider implementations
 */
public class HeaderProviders {
    /** Create provider with static headers */
    public static HeaderProvider create(Map<String, String> headers);
    
    /** Create provider with single header */
    public static HeaderProvider create(String key, String value);
    
    /** Create empty header provider */
    public static HeaderProvider empty();
    
    /** Combine multiple header providers */
    public static HeaderProvider combine(HeaderProvider... providers);
    
    /** Create provider from supplier */
    public static HeaderProvider fromSupplier(Supplier<Map<String, String>> supplier);
}

Metadata Utilities

/**
 * Utilities for working with gRPC metadata
 */
public class MetadataUtils {
    /** Convert map to gRPC Metadata */
    public static Metadata mapToMetadata(Map<String, String> headers);
    
    /** Convert gRPC Metadata to map */
    public static Map<String, List<String>> metadataToMap(Metadata metadata);
    
    /** Extract specific header from metadata */
    public static String getHeader(Metadata metadata, String key);
    
    /** Check if metadata contains header */
    public static boolean hasHeader(Metadata metadata, String key);
    
    /** Create metadata key */
    public static Metadata.Key<String> createKey(String name);
    
    /** Create binary metadata key */
    public static Metadata.Key<byte[]> createBinaryKey(String name);
}

Usage Examples

Basic Header Interceptor

import com.google.api.gax.grpc.GrpcHeaderInterceptor;
import java.util.Map;

// Create header interceptor with static headers
Map<String, String> headers = Map.of(
    "x-custom-header", "custom-value",
    "x-client-version", "1.0.0"
);

GrpcHeaderInterceptor headerInterceptor = GrpcHeaderInterceptor.create(headers);

// Use with channel provider
InstantiatingGrpcChannelProvider channelProvider = 
    InstantiatingGrpcChannelProvider.newBuilder()
        .setInterceptorProvider(GrpcInterceptorProviders.create(headerInterceptor))
        .build();

Dynamic Header Provider

import com.google.api.gax.rpc.HeaderProvider;

// Create dynamic header provider
HeaderProvider dynamicHeaders = new HeaderProvider() {
    @Override
    public Map<String, String> getHeaders() {
        return Map.of(
            "x-request-id", UUID.randomUUID().toString(),
            "x-timestamp", String.valueOf(System.currentTimeMillis())
        );
    }
};

GrpcHeaderInterceptor headerInterceptor = GrpcHeaderInterceptor.create(dynamicHeaders);

Response Metadata Handling

import com.google.api.gax.grpc.GrpcMetadataHandlerInterceptor;
import com.google.api.gax.grpc.ResponseMetadataHandler;
import io.grpc.Metadata;

// Create metadata handler
ResponseMetadataHandler metadataHandler = new ResponseMetadataHandler() {
    @Override
    public void onHeaders(Metadata headers) {
        String requestId = headers.get(Metadata.Key.of("x-request-id", Metadata.ASCII_STRING_MARSHALLER));
        System.out.println("Request ID: " + requestId);
    }
    
    @Override
    public void onTrailers(Metadata trailers) {
        String processingTime = trailers.get(Metadata.Key.of("x-processing-time", Metadata.ASCII_STRING_MARSHALLER));
        System.out.println("Processing time: " + processingTime + "ms");
    }
};

GrpcMetadataHandlerInterceptor metadataInterceptor = 
    GrpcMetadataHandlerInterceptor.create(metadataHandler);

Logging Interceptor Configuration

import com.google.api.gax.grpc.GrpcLoggingInterceptor;
import java.util.logging.Level;
import java.util.logging.Logger;

// Create logging interceptor with configuration
Logger logger = Logger.getLogger("grpc.calls");
GrpcLoggingInterceptor.LoggingConfig config = new GrpcLoggingInterceptor.LoggingConfig()
    .logRequestPayloads(true)
    .logResponsePayloads(false)
    .logMetadata(true)
    .logLevel(Level.INFO)
    .maxPayloadSize(1024)
    .logger(logger);

GrpcLoggingInterceptor loggingInterceptor = GrpcLoggingInterceptor.create(config);

Custom Authentication Interceptor

import io.grpc.ClientInterceptor;
import io.grpc.CallOptions;
import io.grpc.Channel;
import io.grpc.ClientCall;
import io.grpc.ForwardingClientCall;
import io.grpc.Metadata;
import io.grpc.MethodDescriptor;

// Custom authentication interceptor
public class AuthenticationInterceptor implements ClientInterceptor {
    private final String authToken;
    
    public AuthenticationInterceptor(String authToken) {
        this.authToken = authToken;
    }
    
    @Override
    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
            MethodDescriptor<ReqT, RespT> method,
            CallOptions callOptions,
            Channel next) {
        
        return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(
                next.newCall(method, callOptions)) {
            
            @Override
            public void start(Listener<RespT> responseListener, Metadata headers) {
                // Add authorization header
                headers.put(Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER), 
                           "Bearer " + authToken);
                super.start(responseListener, headers);
            }
        };
    }
}

// Use the custom interceptor
AuthenticationInterceptor authInterceptor = new AuthenticationInterceptor("your-token");
GrpcInterceptorProvider interceptorProvider = GrpcInterceptorProviders.create(authInterceptor);

Multiple Interceptors

import java.util.List;

// Combine multiple interceptors
List<ClientInterceptor> interceptors = List.of(
    new AuthenticationInterceptor("token"),
    GrpcHeaderInterceptor.create(Map.of("x-client", "java-client")),
    GrpcLoggingInterceptor.create(),
    GrpcMetadataHandlerInterceptor.create(metadataHandler)
);

GrpcInterceptorProvider combinedProvider = GrpcInterceptorProviders.create(interceptors);

// Use with channel provider
InstantiatingGrpcChannelProvider channelProvider = 
    InstantiatingGrpcChannelProvider.newBuilder()
        .setInterceptorProvider(combinedProvider)
        .build();

Request/Response Transformation Interceptor

// Custom request transformation interceptor
public class RequestTransformInterceptor extends SimpleRequestInterceptor {
    @Override
    protected <ReqT> ReqT modifyRequest(ReqT request, MethodDescriptor<ReqT, ?> method) {
        // Transform request (example: add timestamp)
        if (request instanceof MyRequest) {
            MyRequest myRequest = (MyRequest) request;
            return (ReqT) myRequest.toBuilder()
                .setTimestamp(System.currentTimeMillis())
                .build();
        }
        return request;
    }
}

// Custom response transformation interceptor
public class ResponseTransformInterceptor extends SimpleResponseInterceptor {
    @Override
    protected <RespT> RespT modifyResponse(RespT response, MethodDescriptor<?, RespT> method) {
        // Transform response (example: log response size)
        if (response instanceof Message) {
            Message message = (Message) response;
            System.out.println("Response size: " + message.getSerializedSize() + " bytes");
        }
        return response;
    }
}

Conditional Interceptor

// Interceptor that applies conditionally based on method
public class ConditionalInterceptor implements ClientInterceptor {
    private final Set<String> targetMethods;
    private final ClientInterceptor targetInterceptor;
    
    public ConditionalInterceptor(Set<String> targetMethods, ClientInterceptor targetInterceptor) {
        this.targetMethods = targetMethods;
        this.targetInterceptor = targetInterceptor;
    }
    
    @Override
    public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
            MethodDescriptor<ReqT, RespT> method,
            CallOptions callOptions,
            Channel next) {
        
        // Apply interceptor only to target methods
        if (targetMethods.contains(method.getFullMethodName())) {
            return targetInterceptor.interceptCall(method, callOptions, next);
        } else {
            return next.newCall(method, callOptions);
        }
    }
}

// Use conditional interceptor
Set<String> criticalMethods = Set.of(
    "MyService/CriticalMethod1",
    "MyService/CriticalMethod2"
);

ConditionalInterceptor conditionalInterceptor = new ConditionalInterceptor(
    criticalMethods, 
    GrpcLoggingInterceptor.create()
);

Install with Tessl CLI

npx tessl i tessl/maven-com-google-api--gax-grpc

docs

call-context.md

callable-factory.md

channel-management.md

index.md

interceptors.md

operations.md

transport-status.md

tile.json