or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

call-context.mdcallable-factory.mdchannel-management.mdindex.mdinterceptors.mdoperations.mdtransport-status.md

interceptors.mddocs/

0

# Interceptors and Metadata

1

2

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

3

4

## Capabilities

5

6

### GrpcInterceptorProvider

7

8

Provider interface for supplying custom gRPC ClientInterceptors to the channel.

9

10

```java { .api }

11

/**

12

* Provider for custom gRPC ClientInterceptors

13

* Allows injection of custom interceptors into the gRPC call chain

14

*/

15

public interface GrpcInterceptorProvider {

16

/** Get list of client interceptors to apply */

17

List<ClientInterceptor> getInterceptors();

18

}

19

20

/**

21

* Static factory methods for common interceptor providers

22

*/

23

public class GrpcInterceptorProviders {

24

/** Create provider with single interceptor */

25

public static GrpcInterceptorProvider create(ClientInterceptor interceptor);

26

27

/** Create provider with multiple interceptors */

28

public static GrpcInterceptorProvider create(List<ClientInterceptor> interceptors);

29

30

/** Create empty provider */

31

public static GrpcInterceptorProvider empty();

32

33

/** Combine multiple providers */

34

public static GrpcInterceptorProvider combine(GrpcInterceptorProvider... providers);

35

}

36

```

37

38

### GrpcHeaderInterceptor

39

40

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

41

42

```java { .api }

43

/**

44

* Interceptor for managing gRPC request headers

45

* Supports static headers and dynamic header providers

46

*/

47

public class GrpcHeaderInterceptor implements ClientInterceptor {

48

/** Create interceptor with static headers */

49

public static GrpcHeaderInterceptor create(Map<String, String> headers);

50

51

/** Create interceptor with header provider */

52

public static GrpcHeaderInterceptor create(HeaderProvider headerProvider);

53

54

/** Intercept gRPC call to add headers */

55

public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(

56

MethodDescriptor<ReqT, RespT> method,

57

CallOptions callOptions,

58

Channel next);

59

}

60

```

61

62

### GrpcMetadataHandlerInterceptor

63

64

Interceptor for extracting and processing response metadata from gRPC calls.

65

66

```java { .api }

67

/**

68

* Interceptor for handling gRPC response metadata

69

* Extracts headers and trailers from responses

70

*/

71

public class GrpcMetadataHandlerInterceptor implements ClientInterceptor {

72

/** Create metadata handler interceptor */

73

public static GrpcMetadataHandlerInterceptor create(ResponseMetadataHandler handler);

74

75

/** Intercept call to handle metadata */

76

public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(

77

MethodDescriptor<ReqT, RespT> method,

78

CallOptions callOptions,

79

Channel next);

80

}

81

```

82

83

### GrpcResponseMetadata

84

85

Response metadata handler providing access to gRPC headers and trailers.

86

87

```java { .api }

88

/**

89

* Handler for gRPC response metadata

90

* Provides access to headers and trailers from responses

91

*/

92

public class GrpcResponseMetadata implements ResponseMetadata {

93

/** Create response metadata handler */

94

public static GrpcResponseMetadata create();

95

96

/** Get response headers as metadata map */

97

public Map<String, List<String>> getMetadata();

98

99

/** Get response trailers metadata */

100

public List<String> getTrailersMetadata();

101

102

/** Get specific header values */

103

public List<String> getMetadata(String key);

104

105

/** Get trailer value for key */

106

public String getTrailerValue(String key);

107

108

/** Check if metadata contains key */

109

public boolean containsKey(String key);

110

111

/** Get all metadata keys */

112

public Set<String> getKeys();

113

}

114

```

115

116

### ResponseMetadataHandler

117

118

Handler interface for processing response metadata from gRPC calls.

119

120

```java { .api }

121

/**

122

* Handler interface for processing response metadata

123

* Called when response metadata is received

124

*/

125

public interface ResponseMetadataHandler {

126

/** Handle response headers */

127

void onHeaders(Metadata headers);

128

129

/** Handle response trailers */

130

void onTrailers(Metadata trailers);

131

132

/** Handle both headers and trailers */

133

default void onMetadata(Metadata headers, Metadata trailers) {

134

onHeaders(headers);

135

onTrailers(trailers);

136

}

137

}

138

```

139

140

### GrpcLoggingInterceptor

141

142

Built-in interceptor for logging gRPC requests and responses.

143

144

```java { .api }

145

/**

146

* Interceptor for logging gRPC calls

147

* Supports configurable logging levels and content filtering

148

*/

149

public class GrpcLoggingInterceptor implements ClientInterceptor {

150

/** Create logging interceptor with default settings */

151

public static GrpcLoggingInterceptor create();

152

153

/** Create logging interceptor with logger */

154

public static GrpcLoggingInterceptor create(Logger logger);

155

156

/** Create logging interceptor with configuration */

157

public static GrpcLoggingInterceptor create(LoggingConfig config);

158

159

/** Intercept call for logging */

160

public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(

161

MethodDescriptor<ReqT, RespT> method,

162

CallOptions callOptions,

163

Channel next);

164

}

165

166

/**

167

* Configuration for gRPC logging interceptor

168

*/

169

public static class GrpcLoggingInterceptor.LoggingConfig {

170

/** Set whether to log request payloads */

171

public LoggingConfig logRequestPayloads(boolean enabled);

172

173

/** Set whether to log response payloads */

174

public LoggingConfig logResponsePayloads(boolean enabled);

175

176

/** Set whether to log metadata */

177

public LoggingConfig logMetadata(boolean enabled);

178

179

/** Set logging level */

180

public LoggingConfig logLevel(Level level);

181

182

/** Set maximum payload size to log */

183

public LoggingConfig maxPayloadSize(int maxSize);

184

185

/** Set logger instance */

186

public LoggingConfig logger(Logger logger);

187

}

188

```

189

190

## Interceptor Utilities

191

192

### Interceptor Chain Management

193

194

```java { .api }

195

/**

196

* Utilities for managing interceptor chains

197

*/

198

public class InterceptorChainUtils {

199

/** Create interceptor chain from providers */

200

public static ClientInterceptor chainInterceptors(List<GrpcInterceptorProvider> providers);

201

202

/** Add interceptor to existing chain */

203

public static ClientInterceptor addInterceptor(ClientInterceptor chain, ClientInterceptor interceptor);

204

205

/** Remove interceptor from chain by type */

206

public static ClientInterceptor removeInterceptor(ClientInterceptor chain, Class<?> interceptorType);

207

208

/** Get interceptors of specific type from chain */

209

public static <T extends ClientInterceptor> List<T> getInterceptors(ClientInterceptor chain, Class<T> type);

210

}

211

```

212

213

### Custom Interceptor Base Classes

214

215

```java { .api }

216

/**

217

* Base class for custom interceptors with common functionality

218

*/

219

public abstract class BaseGrpcInterceptor implements ClientInterceptor {

220

/** Protected constructor for subclasses */

221

protected BaseGrpcInterceptor();

222

223

/** Template method for call interception */

224

public final <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(

225

MethodDescriptor<ReqT, RespT> method,

226

CallOptions callOptions,

227

Channel next);

228

229

/** Override this method in subclasses */

230

protected abstract <ReqT, RespT> ClientCall<ReqT, RespT> doInterceptCall(

231

MethodDescriptor<ReqT, RespT> method,

232

CallOptions callOptions,

233

Channel next);

234

235

/** Utility method to create forwarding call */

236

protected <ReqT, RespT> ForwardingClientCall<ReqT, RespT> createForwardingCall(

237

ClientCall<ReqT, RespT> delegate);

238

}

239

240

/**

241

* Base class for simple interceptors that only modify requests

242

*/

243

public abstract class SimpleRequestInterceptor extends BaseGrpcInterceptor {

244

/** Override to modify requests */

245

protected abstract <ReqT> ReqT modifyRequest(ReqT request, MethodDescriptor<ReqT, ?> method);

246

}

247

248

/**

249

* Base class for simple interceptors that only modify responses

250

*/

251

public abstract class SimpleResponseInterceptor extends BaseGrpcInterceptor {

252

/** Override to modify responses */

253

protected abstract <RespT> RespT modifyResponse(RespT response, MethodDescriptor<?, RespT> method);

254

}

255

```

256

257

## Header and Metadata Types

258

259

### Header Provider Interface

260

261

```java { .api }

262

/**

263

* Provider for dynamic headers

264

* Allows headers to be computed at request time

265

*/

266

public interface HeaderProvider {

267

/** Get headers map */

268

Map<String, String> getHeaders();

269

270

/** Get headers for specific method */

271

default Map<String, String> getHeaders(MethodDescriptor<?, ?> method) {

272

return getHeaders();

273

}

274

}

275

276

/**

277

* Static header provider implementations

278

*/

279

public class HeaderProviders {

280

/** Create provider with static headers */

281

public static HeaderProvider create(Map<String, String> headers);

282

283

/** Create provider with single header */

284

public static HeaderProvider create(String key, String value);

285

286

/** Create empty header provider */

287

public static HeaderProvider empty();

288

289

/** Combine multiple header providers */

290

public static HeaderProvider combine(HeaderProvider... providers);

291

292

/** Create provider from supplier */

293

public static HeaderProvider fromSupplier(Supplier<Map<String, String>> supplier);

294

}

295

```

296

297

### Metadata Utilities

298

299

```java { .api }

300

/**

301

* Utilities for working with gRPC metadata

302

*/

303

public class MetadataUtils {

304

/** Convert map to gRPC Metadata */

305

public static Metadata mapToMetadata(Map<String, String> headers);

306

307

/** Convert gRPC Metadata to map */

308

public static Map<String, List<String>> metadataToMap(Metadata metadata);

309

310

/** Extract specific header from metadata */

311

public static String getHeader(Metadata metadata, String key);

312

313

/** Check if metadata contains header */

314

public static boolean hasHeader(Metadata metadata, String key);

315

316

/** Create metadata key */

317

public static Metadata.Key<String> createKey(String name);

318

319

/** Create binary metadata key */

320

public static Metadata.Key<byte[]> createBinaryKey(String name);

321

}

322

```

323

324

## Usage Examples

325

326

### Basic Header Interceptor

327

328

```java

329

import com.google.api.gax.grpc.GrpcHeaderInterceptor;

330

import java.util.Map;

331

332

// Create header interceptor with static headers

333

Map<String, String> headers = Map.of(

334

"x-custom-header", "custom-value",

335

"x-client-version", "1.0.0"

336

);

337

338

GrpcHeaderInterceptor headerInterceptor = GrpcHeaderInterceptor.create(headers);

339

340

// Use with channel provider

341

InstantiatingGrpcChannelProvider channelProvider =

342

InstantiatingGrpcChannelProvider.newBuilder()

343

.setInterceptorProvider(GrpcInterceptorProviders.create(headerInterceptor))

344

.build();

345

```

346

347

### Dynamic Header Provider

348

349

```java

350

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

351

352

// Create dynamic header provider

353

HeaderProvider dynamicHeaders = new HeaderProvider() {

354

@Override

355

public Map<String, String> getHeaders() {

356

return Map.of(

357

"x-request-id", UUID.randomUUID().toString(),

358

"x-timestamp", String.valueOf(System.currentTimeMillis())

359

);

360

}

361

};

362

363

GrpcHeaderInterceptor headerInterceptor = GrpcHeaderInterceptor.create(dynamicHeaders);

364

```

365

366

### Response Metadata Handling

367

368

```java

369

import com.google.api.gax.grpc.GrpcMetadataHandlerInterceptor;

370

import com.google.api.gax.grpc.ResponseMetadataHandler;

371

import io.grpc.Metadata;

372

373

// Create metadata handler

374

ResponseMetadataHandler metadataHandler = new ResponseMetadataHandler() {

375

@Override

376

public void onHeaders(Metadata headers) {

377

String requestId = headers.get(Metadata.Key.of("x-request-id", Metadata.ASCII_STRING_MARSHALLER));

378

System.out.println("Request ID: " + requestId);

379

}

380

381

@Override

382

public void onTrailers(Metadata trailers) {

383

String processingTime = trailers.get(Metadata.Key.of("x-processing-time", Metadata.ASCII_STRING_MARSHALLER));

384

System.out.println("Processing time: " + processingTime + "ms");

385

}

386

};

387

388

GrpcMetadataHandlerInterceptor metadataInterceptor =

389

GrpcMetadataHandlerInterceptor.create(metadataHandler);

390

```

391

392

### Logging Interceptor Configuration

393

394

```java

395

import com.google.api.gax.grpc.GrpcLoggingInterceptor;

396

import java.util.logging.Level;

397

import java.util.logging.Logger;

398

399

// Create logging interceptor with configuration

400

Logger logger = Logger.getLogger("grpc.calls");

401

GrpcLoggingInterceptor.LoggingConfig config = new GrpcLoggingInterceptor.LoggingConfig()

402

.logRequestPayloads(true)

403

.logResponsePayloads(false)

404

.logMetadata(true)

405

.logLevel(Level.INFO)

406

.maxPayloadSize(1024)

407

.logger(logger);

408

409

GrpcLoggingInterceptor loggingInterceptor = GrpcLoggingInterceptor.create(config);

410

```

411

412

### Custom Authentication Interceptor

413

414

```java

415

import io.grpc.ClientInterceptor;

416

import io.grpc.CallOptions;

417

import io.grpc.Channel;

418

import io.grpc.ClientCall;

419

import io.grpc.ForwardingClientCall;

420

import io.grpc.Metadata;

421

import io.grpc.MethodDescriptor;

422

423

// Custom authentication interceptor

424

public class AuthenticationInterceptor implements ClientInterceptor {

425

private final String authToken;

426

427

public AuthenticationInterceptor(String authToken) {

428

this.authToken = authToken;

429

}

430

431

@Override

432

public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(

433

MethodDescriptor<ReqT, RespT> method,

434

CallOptions callOptions,

435

Channel next) {

436

437

return new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(

438

next.newCall(method, callOptions)) {

439

440

@Override

441

public void start(Listener<RespT> responseListener, Metadata headers) {

442

// Add authorization header

443

headers.put(Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER),

444

"Bearer " + authToken);

445

super.start(responseListener, headers);

446

}

447

};

448

}

449

}

450

451

// Use the custom interceptor

452

AuthenticationInterceptor authInterceptor = new AuthenticationInterceptor("your-token");

453

GrpcInterceptorProvider interceptorProvider = GrpcInterceptorProviders.create(authInterceptor);

454

```

455

456

### Multiple Interceptors

457

458

```java

459

import java.util.List;

460

461

// Combine multiple interceptors

462

List<ClientInterceptor> interceptors = List.of(

463

new AuthenticationInterceptor("token"),

464

GrpcHeaderInterceptor.create(Map.of("x-client", "java-client")),

465

GrpcLoggingInterceptor.create(),

466

GrpcMetadataHandlerInterceptor.create(metadataHandler)

467

);

468

469

GrpcInterceptorProvider combinedProvider = GrpcInterceptorProviders.create(interceptors);

470

471

// Use with channel provider

472

InstantiatingGrpcChannelProvider channelProvider =

473

InstantiatingGrpcChannelProvider.newBuilder()

474

.setInterceptorProvider(combinedProvider)

475

.build();

476

```

477

478

### Request/Response Transformation Interceptor

479

480

```java

481

// Custom request transformation interceptor

482

public class RequestTransformInterceptor extends SimpleRequestInterceptor {

483

@Override

484

protected <ReqT> ReqT modifyRequest(ReqT request, MethodDescriptor<ReqT, ?> method) {

485

// Transform request (example: add timestamp)

486

if (request instanceof MyRequest) {

487

MyRequest myRequest = (MyRequest) request;

488

return (ReqT) myRequest.toBuilder()

489

.setTimestamp(System.currentTimeMillis())

490

.build();

491

}

492

return request;

493

}

494

}

495

496

// Custom response transformation interceptor

497

public class ResponseTransformInterceptor extends SimpleResponseInterceptor {

498

@Override

499

protected <RespT> RespT modifyResponse(RespT response, MethodDescriptor<?, RespT> method) {

500

// Transform response (example: log response size)

501

if (response instanceof Message) {

502

Message message = (Message) response;

503

System.out.println("Response size: " + message.getSerializedSize() + " bytes");

504

}

505

return response;

506

}

507

}

508

```

509

510

### Conditional Interceptor

511

512

```java

513

// Interceptor that applies conditionally based on method

514

public class ConditionalInterceptor implements ClientInterceptor {

515

private final Set<String> targetMethods;

516

private final ClientInterceptor targetInterceptor;

517

518

public ConditionalInterceptor(Set<String> targetMethods, ClientInterceptor targetInterceptor) {

519

this.targetMethods = targetMethods;

520

this.targetInterceptor = targetInterceptor;

521

}

522

523

@Override

524

public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(

525

MethodDescriptor<ReqT, RespT> method,

526

CallOptions callOptions,

527

Channel next) {

528

529

// Apply interceptor only to target methods

530

if (targetMethods.contains(method.getFullMethodName())) {

531

return targetInterceptor.interceptCall(method, callOptions, next);

532

} else {

533

return next.newCall(method, callOptions);

534

}

535

}

536

}

537

538

// Use conditional interceptor

539

Set<String> criticalMethods = Set.of(

540

"MyService/CriticalMethod1",

541

"MyService/CriticalMethod2"

542

);

543

544

ConditionalInterceptor conditionalInterceptor = new ConditionalInterceptor(

545

criticalMethods,

546

GrpcLoggingInterceptor.create()

547

);

548

```