From 6c2bc599e55dc5b374603c2e5527b0165064b693 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 27 Feb 2024 12:51:38 -0800 Subject: [PATCH 01/55] grpc-js: Run code formatter, fix one lint error --- packages/grpc-js/src/backoff-timeout.ts | 4 +- packages/grpc-js/src/index.ts | 11 +- packages/grpc-js/src/internal-channel.ts | 8 +- .../grpc-js/src/load-balancer-pick-first.ts | 23 +- .../grpc-js/src/load-balancer-round-robin.ts | 4 +- packages/grpc-js/src/load-balancing-call.ts | 4 +- packages/grpc-js/src/logging.ts | 13 +- packages/grpc-js/src/resolver-dns.ts | 9 +- .../grpc-js/src/resolving-load-balancer.ts | 7 +- packages/grpc-js/src/server-call.ts | 15 +- packages/grpc-js/src/server-interceptors.ts | 186 +++++++---- packages/grpc-js/src/server.ts | 305 +++++++++++------- packages/grpc-js/src/service-config.ts | 15 +- packages/grpc-js/src/transport.ts | 7 +- packages/grpc-js/test/common.ts | 5 +- packages/grpc-js/test/test-confg-parsing.ts | 89 ++--- packages/grpc-js/test/test-pick-first.ts | 73 +++-- .../grpc-js/test/test-server-interceptors.ts | 135 +++++--- packages/grpc-js/test/test-server.ts | 139 +++++--- 19 files changed, 698 insertions(+), 354 deletions(-) diff --git a/packages/grpc-js/src/backoff-timeout.ts b/packages/grpc-js/src/backoff-timeout.ts index 78318d1e8..10d347e79 100644 --- a/packages/grpc-js/src/backoff-timeout.ts +++ b/packages/grpc-js/src/backoff-timeout.ts @@ -106,7 +106,9 @@ export class BackoffTimeout { private runTimer(delay: number) { this.endTime = this.startTime; - this.endTime.setMilliseconds(this.endTime.getMilliseconds() + this.nextDelay); + this.endTime.setMilliseconds( + this.endTime.getMilliseconds() + this.nextDelay + ); clearTimeout(this.timerId); this.timerId = setTimeout(() => { this.callback(); diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index b37f61103..c766a3718 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -183,7 +183,7 @@ export { ServiceDefinition, UntypedHandleCall, UntypedServiceImplementation, - VerifyOptions + VerifyOptions, }; /**** Server ****/ @@ -263,7 +263,12 @@ export { getChannelzServiceDefinition, getChannelzHandlers } from './channelz'; export { addAdminServicesToServer } from './admin'; -export { ServiceConfig, LoadBalancingConfig, MethodConfig, RetryPolicy } from './service-config'; +export { + ServiceConfig, + LoadBalancingConfig, + MethodConfig, + RetryPolicy, +} from './service-config'; export { ServerListener, @@ -274,7 +279,7 @@ export { ResponderBuilder, ServerInterceptingCallInterface, ServerInterceptingCall, - ServerInterceptor + ServerInterceptor, } from './server-interceptors'; import * as experimental from './experimental'; diff --git a/packages/grpc-js/src/internal-channel.ts b/packages/grpc-js/src/internal-channel.ts index be140522b..823c935af 100644 --- a/packages/grpc-js/src/internal-channel.ts +++ b/packages/grpc-js/src/internal-channel.ts @@ -583,7 +583,8 @@ export class InternalChannel { return; } const now = new Date(); - const timeSinceLastActivity = now.valueOf() - this.lastActivityTimestamp.valueOf(); + const timeSinceLastActivity = + now.valueOf() - this.lastActivityTimestamp.valueOf(); if (timeSinceLastActivity >= this.idleTimeoutMs) { this.trace( 'Idle timer triggered after ' + @@ -603,7 +604,10 @@ export class InternalChannel { } private maybeStartIdleTimer() { - if (this.connectivityState !== ConnectivityState.SHUTDOWN && !this.idleTimer) { + if ( + this.connectivityState !== ConnectivityState.SHUTDOWN && + !this.idleTimer + ) { this.startIdleTimeout(this.idleTimeoutMs); } } diff --git a/packages/grpc-js/src/load-balancer-pick-first.ts b/packages/grpc-js/src/load-balancer-pick-first.ts index 02796fea0..29bbfbf07 100644 --- a/packages/grpc-js/src/load-balancer-pick-first.ts +++ b/packages/grpc-js/src/load-balancer-pick-first.ts @@ -198,7 +198,12 @@ export class PickFirstLoadBalancer implements LoadBalancer { keepaliveTime, errorMessage ) => { - this.onSubchannelStateUpdate(subchannel, previousState, newState, errorMessage); + this.onSubchannelStateUpdate( + subchannel, + previousState, + newState, + errorMessage + ); }; private pickedSubchannelHealthListener: HealthListener = () => @@ -275,7 +280,9 @@ export class PickFirstLoadBalancer implements LoadBalancer { if (this.stickyTransientFailureMode) { this.updateState( ConnectivityState.TRANSIENT_FAILURE, - new UnavailablePicker({details: `No connection established. Last error: ${this.lastError}`}) + new UnavailablePicker({ + details: `No connection established. Last error: ${this.lastError}`, + }) ); } else { this.updateState(ConnectivityState.CONNECTING, new QueuePicker(this)); @@ -441,7 +448,12 @@ export class PickFirstLoadBalancer implements LoadBalancer { private resetSubchannelList() { for (const child of this.children) { - if (!(this.currentPick && child.subchannel.realSubchannelEquals(this.currentPick))) { + if ( + !( + this.currentPick && + child.subchannel.realSubchannelEquals(this.currentPick) + ) + ) { /* The connectivity state listener is the same whether the subchannel * is in the list of children or it is the currentPick, so if it is in * both, removing it here would cause problems. In particular, that @@ -523,7 +535,10 @@ export class PickFirstLoadBalancer implements LoadBalancer { } exitIdle() { - if (this.currentState === ConnectivityState.IDLE && this.latestAddressList) { + if ( + this.currentState === ConnectivityState.IDLE && + this.latestAddressList + ) { this.connectToAddressList(this.latestAddressList); } } diff --git a/packages/grpc-js/src/load-balancer-round-robin.ts b/packages/grpc-js/src/load-balancer-round-robin.ts index 7c38569e5..7e70c554f 100644 --- a/packages/grpc-js/src/load-balancer-round-robin.ts +++ b/packages/grpc-js/src/load-balancer-round-robin.ts @@ -156,7 +156,9 @@ export class RoundRobinLoadBalancer implements LoadBalancer { ) { this.updateState( ConnectivityState.TRANSIENT_FAILURE, - new UnavailablePicker({details: `No connection established. Last error: ${this.lastError}`}) + new UnavailablePicker({ + details: `No connection established. Last error: ${this.lastError}`, + }) ); } else { this.updateState(ConnectivityState.IDLE, new QueuePicker(this)); diff --git a/packages/grpc-js/src/load-balancing-call.ts b/packages/grpc-js/src/load-balancing-call.ts index 87ef02497..25a36553a 100644 --- a/packages/grpc-js/src/load-balancing-call.ts +++ b/packages/grpc-js/src/load-balancing-call.ts @@ -145,7 +145,9 @@ export class LoadBalancingCall implements Call { * metadata generation finished, we shouldn't do anything with * it. */ if (this.ended) { - this.trace('Credentials metadata generation finished after call ended'); + this.trace( + 'Credentials metadata generation finished after call ended' + ); return; } finalMetadata.merge(credsMetadata); diff --git a/packages/grpc-js/src/logging.ts b/packages/grpc-js/src/logging.ts index e1b396fff..2279d3b65 100644 --- a/packages/grpc-js/src/logging.ts +++ b/packages/grpc-js/src/logging.ts @@ -112,7 +112,18 @@ export function trace( text: string ): void { if (isTracerEnabled(tracer)) { - log(severity, new Date().toISOString() + ' | v' + clientVersion + ' ' + pid + ' | ' + tracer + ' | ' + text); + log( + severity, + new Date().toISOString() + + ' | v' + + clientVersion + + ' ' + + pid + + ' | ' + + tracer + + ' | ' + + text + ); } } diff --git a/packages/grpc-js/src/resolver-dns.ts b/packages/grpc-js/src/resolver-dns.ts index 978f1442a..6652839b0 100644 --- a/packages/grpc-js/src/resolver-dns.ts +++ b/packages/grpc-js/src/resolver-dns.ts @@ -335,9 +335,14 @@ class DnsResolver implements Resolver { if (this.pendingLookupPromise === null) { if (this.isNextResolutionTimerRunning || this.backoff.isRunning()) { if (this.isNextResolutionTimerRunning) { - trace('resolution update delayed by "min time between resolutions" rate limit'); + trace( + 'resolution update delayed by "min time between resolutions" rate limit' + ); } else { - trace('resolution update delayed by backoff timer until ' + this.backoff.getEndTime().toISOString()); + trace( + 'resolution update delayed by backoff timer until ' + + this.backoff.getEndTime().toISOString() + ); } this.continueResolving = true; } else { diff --git a/packages/grpc-js/src/resolving-load-balancer.ts b/packages/grpc-js/src/resolving-load-balancer.ts index a8de2019a..82c4ff436 100644 --- a/packages/grpc-js/src/resolving-load-balancer.ts +++ b/packages/grpc-js/src/resolving-load-balancer.ts @@ -223,8 +223,11 @@ export class ResolvingLoadBalancer implements LoadBalancer { * In that case, the backoff timer callback will call * updateResolution */ if (this.backoffTimeout.isRunning()) { - trace('requestReresolution delayed by backoff timer until ' + this.backoffTimeout.getEndTime().toISOString()); - this.continueResolving = true; + trace( + 'requestReresolution delayed by backoff timer until ' + + this.backoffTimeout.getEndTime().toISOString() + ); + this.continueResolving = true; } else { this.updateResolution(); } diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index edc38e983..95393fba9 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -18,9 +18,7 @@ import { EventEmitter } from 'events'; import { Duplex, Readable, Writable } from 'stream'; -import { - Status, -} from './constants'; +import { Status } from './constants'; import { Deserialize, Serialize } from './make-client'; import { Metadata } from './metadata'; import { ObjectReadable, ObjectWritable } from './object-stream'; @@ -56,11 +54,14 @@ export type ServerDuplexStream = ServerSurfaceCall & ObjectReadable & ObjectWritable & { end: (metadata?: Metadata) => void }; -export function serverErrorToStatus(error: ServerErrorResponse | ServerStatusResponse, overrideTrailers?: Metadata | undefined): PartialStatusObject { +export function serverErrorToStatus( + error: ServerErrorResponse | ServerStatusResponse, + overrideTrailers?: Metadata | undefined +): PartialStatusObject { const status: PartialStatusObject = { code: Status.UNKNOWN, details: 'message' in error ? error.message : 'Unknown Error', - metadata: overrideTrailers ?? error.metadata ?? null + metadata: overrideTrailers ?? error.metadata ?? null, }; if ( @@ -154,7 +155,7 @@ export class ServerWritableStreamImpl private trailingMetadata: Metadata; private pendingStatus: PartialStatusObject = { code: Status.OK, - details: 'OK' + details: 'OK', }; constructor( @@ -224,7 +225,7 @@ export class ServerDuplexStreamImpl private trailingMetadata: Metadata; private pendingStatus: PartialStatusObject = { code: Status.OK, - details: 'OK' + details: 'OK', }; constructor( diff --git a/packages/grpc-js/src/server-interceptors.ts b/packages/grpc-js/src/server-interceptors.ts index c03f3028c..60c5c8865 100644 --- a/packages/grpc-js/src/server-interceptors.ts +++ b/packages/grpc-js/src/server-interceptors.ts @@ -15,19 +15,24 @@ * */ -import { PartialStatusObject} from "./call-interface"; -import { ServerMethodDefinition } from "./make-client"; -import { Metadata } from "./metadata"; -import { ChannelOptions } from "./channel-options"; -import { Handler, ServerErrorResponse } from "./server-call"; -import { Deadline } from "./deadline"; -import { DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH, DEFAULT_MAX_SEND_MESSAGE_LENGTH, LogVerbosity, Status } from "./constants"; +import { PartialStatusObject } from './call-interface'; +import { ServerMethodDefinition } from './make-client'; +import { Metadata } from './metadata'; +import { ChannelOptions } from './channel-options'; +import { Handler, ServerErrorResponse } from './server-call'; +import { Deadline } from './deadline'; +import { + DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH, + DEFAULT_MAX_SEND_MESSAGE_LENGTH, + LogVerbosity, + Status, +} from './constants'; import * as http2 from 'http2'; -import { getErrorMessage } from "./error"; +import { getErrorMessage } from './error'; import * as zlib from 'zlib'; -import { promisify } from "util"; -import { StreamDecoder } from "./stream-decoder"; -import { CallEventTracker } from "./transport"; +import { promisify } from 'util'; +import { StreamDecoder } from './stream-decoder'; +import { CallEventTracker } from './transport'; import * as logging from './logging'; const unzip = promisify(zlib.unzip); @@ -96,7 +101,7 @@ export class ServerListenerBuilder { onReceiveMetadata: this.metadata, onReceiveMessage: this.message, onReceiveHalfClose: this.halfClose, - onCancel: this.cancel + onCancel: this.cancel, }; } } @@ -109,22 +114,30 @@ export interface InterceptingServerListener { onCancel(): void; } -export function isInterceptingServerListener(listener: ServerListener | InterceptingServerListener): listener is InterceptingServerListener { - return listener.onReceiveMetadata !== undefined && listener.onReceiveMetadata.length === 1; +export function isInterceptingServerListener( + listener: ServerListener | InterceptingServerListener +): listener is InterceptingServerListener { + return ( + listener.onReceiveMetadata !== undefined && + listener.onReceiveMetadata.length === 1 + ); } class InterceptingServerListenerImpl implements InterceptingServerListener { /** * Once the call is cancelled, ignore all other events. */ - private cancelled: boolean = false; - private processingMetadata: boolean = false; - private hasPendingMessage: boolean = false; + private cancelled = false; + private processingMetadata = false; + private hasPendingMessage = false; private pendingMessage: any = null; - private processingMessage: boolean = false; - private hasPendingHalfClose: boolean = false; + private processingMessage = false; + private hasPendingHalfClose = false; - constructor(private listener: FullServerListener, private nextListener: InterceptingServerListener) {} + constructor( + private listener: FullServerListener, + private nextListener: InterceptingServerListener + ) {} private processPendingMessage() { if (this.hasPendingMessage) { @@ -195,7 +208,6 @@ class InterceptingServerListenerImpl implements InterceptingServerListener { this.listener.onCancel(); this.nextListener.onCancel(); } - } export interface StartResponder { @@ -212,7 +224,10 @@ export interface MessageResponder { } export interface StatusResponder { - (status: PartialStatusObject, next: (status: PartialStatusObject) => void): void; + ( + status: PartialStatusObject, + next: (status: PartialStatusObject) => void + ): void; } export interface FullResponder { @@ -255,7 +270,7 @@ export class ResponderBuilder { start: this.start, sendMetadata: this.metadata, sendMessage: this.message, - sendStatus: this.status + sendStatus: this.status, }; } } @@ -270,11 +285,11 @@ const defaultServerListener: FullServerListener = { onReceiveHalfClose: next => { next(); }, - onCancel: () => {} + onCancel: () => {}, }; const defaultResponder: FullResponder = { - start: (next) => { + start: next => { next(); }, sendMetadata: (metadata, next) => { @@ -285,7 +300,7 @@ const defaultResponder: FullResponder = { }, sendStatus: (status, next) => { next(status); - } + }, }; export interface ServerInterceptingCallInterface { @@ -321,18 +336,24 @@ export interface ServerInterceptingCallInterface { export class ServerInterceptingCall implements ServerInterceptingCallInterface { private responder: FullResponder; - private processingMetadata: boolean = false; - private processingMessage: boolean = false; + private processingMetadata = false; + private processingMessage = false; private pendingMessage: any = null; private pendingMessageCallback: (() => void) | null = null; private pendingStatus: PartialStatusObject | null = null; - constructor(private nextCall: ServerInterceptingCallInterface, responder?: Responder) { - this.responder = {...defaultResponder, ...responder}; + constructor( + private nextCall: ServerInterceptingCallInterface, + responder?: Responder + ) { + this.responder = { ...defaultResponder, ...responder }; } private processPendingMessage() { if (this.pendingMessageCallback) { - this.nextCall.sendMessage(this.pendingMessage, this.pendingMessageCallback); + this.nextCall.sendMessage( + this.pendingMessage, + this.pendingMessageCallback + ); this.pendingMessage = null; this.pendingMessageCallback = null; } @@ -347,8 +368,14 @@ export class ServerInterceptingCall implements ServerInterceptingCallInterface { start(listener: InterceptingServerListener): void { this.responder.start(interceptedListener => { - const fullInterceptedListener: FullServerListener = {...defaultServerListener, ...interceptedListener}; - const finalInterceptingListener = new InterceptingServerListenerImpl(fullInterceptedListener, listener); + const fullInterceptedListener: FullServerListener = { + ...defaultServerListener, + ...interceptedListener, + }; + const finalInterceptingListener = new InterceptingServerListenerImpl( + fullInterceptedListener, + listener + ); this.nextCall.start(finalInterceptingListener); }); } @@ -394,7 +421,10 @@ export class ServerInterceptingCall implements ServerInterceptingCallInterface { } export interface ServerInterceptor { - (methodDescriptor: ServerMethodDefinition, call: ServerInterceptingCallInterface): ServerInterceptingCall; + ( + methodDescriptor: ServerMethodDefinition, + call: ServerInterceptingCallInterface + ): ServerInterceptingCall; } interface DeadlineUnitIndexSignature { @@ -438,7 +468,9 @@ interface ReadQueueEntry { parsedMessage: any; } -export class BaseServerInterceptingCall implements ServerInterceptingCallInterface { +export class BaseServerInterceptingCall + implements ServerInterceptingCallInterface +{ private listener: InterceptingServerListener | null = null; private metadata: Metadata; private deadlineTimer: NodeJS.Timeout | null = null; @@ -449,7 +481,7 @@ export class BaseServerInterceptingCall implements ServerInterceptingCallInterfa private metadataSent = false; private wantTrailers = false; private cancelNotified = false; - private incomingEncoding: string = 'identity'; + private incomingEncoding = 'identity'; private decoder = new StreamDecoder(); private readQueue: ReadQueueEntry[] = []; private isReadPending = false; @@ -485,7 +517,7 @@ export class BaseServerInterceptingCall implements ServerInterceptingCallInterfa this.callEventTracker.onCallEnd({ code: Status.CANCELLED, details: 'Stream closed before sending status', - metadata: null + metadata: null, }); } @@ -548,7 +580,7 @@ export class BaseServerInterceptingCall implements ServerInterceptingCallInterfa const status: PartialStatusObject = { code: Status.INTERNAL, details: `Invalid ${GRPC_TIMEOUT_HEADER} value "${timeoutHeader}"`, - metadata: null + metadata: null, }; // Wait for the constructor to complete before sending the error. process.nextTick(() => { @@ -565,11 +597,10 @@ export class BaseServerInterceptingCall implements ServerInterceptingCallInterfa const status: PartialStatusObject = { code: Status.DEADLINE_EXCEEDED, details: 'Deadline exceeded', - metadata: null + metadata: null, }; this.sendStatus(status); }, timeout); - } private checkCancelled(): boolean { @@ -650,14 +681,19 @@ export class BaseServerInterceptingCall implements ServerInterceptingCallInterfa } const compressed = queueEntry.compressedMessage!.readUInt8(0) === 1; - const compressedMessageEncoding = compressed ? this.incomingEncoding : 'identity'; - const decompressedMessage = await this.decompressMessage(queueEntry.compressedMessage!, compressedMessageEncoding); + const compressedMessageEncoding = compressed + ? this.incomingEncoding + : 'identity'; + const decompressedMessage = await this.decompressMessage( + queueEntry.compressedMessage!, + compressedMessageEncoding + ); try { queueEntry.parsedMessage = this.handler.deserialize(decompressedMessage); } catch (err) { this.sendStatus({ code: Status.INTERNAL, - details: `Error deserializing request: ${(err as Error).message}` + details: `Error deserializing request: ${(err as Error).message}`, }); return; } @@ -666,7 +702,12 @@ export class BaseServerInterceptingCall implements ServerInterceptingCallInterfa } private maybePushNextMessage() { - if (this.listener && this.isReadPending && this.readQueue.length > 0 && this.readQueue[0].type !== 'COMPRESSED') { + if ( + this.listener && + this.isReadPending && + this.readQueue.length > 0 && + this.readQueue[0].type !== 'COMPRESSED' + ) { this.isReadPending = false; const nextQueueEntry = this.readQueue.shift()!; if (nextQueueEntry.type === 'READABLE') { @@ -682,23 +723,33 @@ export class BaseServerInterceptingCall implements ServerInterceptingCallInterfa if (this.checkCancelled()) { return; } - trace('Request to ' + this.handler.path + ' received data frame of size ' + data.length); + trace( + 'Request to ' + + this.handler.path + + ' received data frame of size ' + + data.length + ); const rawMessages = this.decoder.write(data); for (const messageBytes of rawMessages) { this.stream.pause(); - if (this.maxReceiveMessageSize !== -1 && messageBytes.length - 5 > this.maxReceiveMessageSize) { + if ( + this.maxReceiveMessageSize !== -1 && + messageBytes.length - 5 > this.maxReceiveMessageSize + ) { this.sendStatus({ code: Status.RESOURCE_EXHAUSTED, - details: `Received message larger than max (${messageBytes.length - 5} vs. ${this.maxReceiveMessageSize})`, - metadata: null + details: `Received message larger than max (${ + messageBytes.length - 5 + } vs. ${this.maxReceiveMessageSize})`, + metadata: null, }); return; } const queueEntry: ReadQueueEntry = { type: 'COMPRESSED', compressedMessage: messageBytes, - parsedMessage: null + parsedMessage: null, }; this.readQueue.push(queueEntry); this.decompressAndMaybePush(queueEntry); @@ -709,7 +760,7 @@ export class BaseServerInterceptingCall implements ServerInterceptingCallInterfa this.readQueue.push({ type: 'HALF_CLOSE', compressedMessage: null, - parsedMessage: null + parsedMessage: null, }); this.receivedHalfClose = true; this.maybePushNextMessage(); @@ -751,7 +802,7 @@ export class BaseServerInterceptingCall implements ServerInterceptingCallInterfa this.sendStatus({ code: Status.INTERNAL, details: `Error serializing response: ${getErrorMessage(e)}`, - metadata: null + metadata: null, }); return; } @@ -763,18 +814,23 @@ export class BaseServerInterceptingCall implements ServerInterceptingCallInterfa this.sendStatus({ code: Status.RESOURCE_EXHAUSTED, details: `Sent message larger than max (${response.length} vs. ${this.maxSendMessageSize})`, - metadata: null + metadata: null, }); return; } this.maybeSendMetadata(); - trace('Request to ' + this.handler.path + ' sent data frame of size ' + response.length); + trace( + 'Request to ' + + this.handler.path + + ' sent data frame of size ' + + response.length + ); this.stream.write(response, error => { if (error) { this.sendStatus({ code: Status.INTERNAL, details: `Error writing message: ${getErrorMessage(error)}`, - metadata: null + metadata: null, }); return; } @@ -871,16 +927,24 @@ export function getServerInterceptingCall( handler: Handler, options: ChannelOptions ) { - const methodDefinition: ServerMethodDefinition = { path: handler.path, requestStream: handler.type === 'clientStream' || handler.type === 'bidi', responseStream: handler.type === 'serverStream' || handler.type === 'bidi', requestDeserialize: handler.deserialize, - responseSerialize: handler.serialize - } - const baseCall = new BaseServerInterceptingCall(stream, headers, callEventTracker, handler, options); - return interceptors.reduce((call: ServerInterceptingCallInterface, interceptor: ServerInterceptor) => { - return interceptor(methodDefinition, call); - }, baseCall); + responseSerialize: handler.serialize, + }; + const baseCall = new BaseServerInterceptingCall( + stream, + headers, + callEventTracker, + handler, + options + ); + return interceptors.reduce( + (call: ServerInterceptingCallInterface, interceptor: ServerInterceptor) => { + return interceptor(methodDefinition, call); + }, + baseCall + ); } diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 31851b832..46bd22ead 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -55,7 +55,13 @@ import { subchannelAddressToString, stringToSubchannelAddress, } from './subchannel-address'; -import { GrpcUri, combineHostPort, parseUri, splitHostPort, uriToString } from './uri-parser'; +import { + GrpcUri, + combineHostPort, + parseUri, + splitHostPort, + uriToString, +} from './uri-parser'; import { ChannelzCallTracker, ChannelzChildrenTracker, @@ -70,7 +76,11 @@ import { unregisterChannelzRef, } from './channelz'; import { CipherNameAndProtocol, TLSSocket } from 'tls'; -import { ServerInterceptingCallInterface, ServerInterceptor, getServerInterceptingCall } from './server-interceptors'; +import { + ServerInterceptingCallInterface, + ServerInterceptor, + getServerInterceptingCall, +} from './server-interceptors'; import { PartialStatusObject } from './call-interface'; import { CallEventTracker } from './transport'; @@ -103,9 +113,15 @@ function noop(): void {} * @returns */ function deprecate(message: string) { - return function (target: (this: This, ...args: Args) => Return, context: ClassMethodDecoratorContext Return>) { + return function ( + target: (this: This, ...args: Args) => Return, + context: ClassMethodDecoratorContext< + This, + (this: This, ...args: Args) => Return + > + ) { return util.deprecate(target, message); - } + }; } function getUnimplementedStatusResponse( @@ -209,7 +225,7 @@ interface BoundPort { * that expands to multiple addresses will result in multiple listening * servers. */ - listeningServers: Set + listeningServers: Set; } /** @@ -221,11 +237,11 @@ interface Http2ServerInfo { } export interface ServerOptions extends ChannelOptions { - interceptors?: ServerInterceptor[] + interceptors?: ServerInterceptor[]; } export class Server { - private boundPorts: Map= new Map(); + private boundPorts: Map = new Map(); private http2Servers: Map = new Map(); private handlers: Map = new Map< @@ -526,10 +542,11 @@ export class Server { return http2Server; } - private bindOneAddress(address: SubchannelAddress, boundPortObject: BoundPort): Promise { - this.trace( - 'Attempting to bind ' + subchannelAddressToString(address) - ); + private bindOneAddress( + address: SubchannelAddress, + boundPortObject: BoundPort + ): Promise { + this.trace('Attempting to bind ' + subchannelAddressToString(address)); const http2Server = this.createHttp2Server(boundPortObject.credentials); return new Promise((resolve, reject) => { const onError = (err: Error) => { @@ -541,7 +558,7 @@ export class Server { ); resolve({ port: 'port' in address ? address.port : 1, - error: err.message + error: err.message, }); }; @@ -561,13 +578,15 @@ export class Server { }; } - const channelzRef = this.registerListenerToChannelz(boundSubchannelAddress); + const channelzRef = this.registerListenerToChannelz( + boundSubchannelAddress + ); if (this.channelzEnabled) { this.listenerChildrenTracker.refChild(channelzRef); } this.http2Servers.set(http2Server, { channelzRef: channelzRef, - sessions: new Set() + sessions: new Set(), }); boundPortObject.listeningServers.add(http2Server); this.trace( @@ -575,62 +594,86 @@ export class Server { subchannelAddressToString(boundSubchannelAddress) ); resolve({ - port: 'port' in boundSubchannelAddress - ? boundSubchannelAddress.port - : 1 + port: + 'port' in boundSubchannelAddress ? boundSubchannelAddress.port : 1, }); http2Server.removeListener('error', onError); }); }); } - private async bindManyPorts(addressList: SubchannelAddress[], boundPortObject: BoundPort): Promise { + private async bindManyPorts( + addressList: SubchannelAddress[], + boundPortObject: BoundPort + ): Promise { if (addressList.length === 0) { return { count: 0, port: 0, - errors: [] + errors: [], }; } if (isTcpSubchannelAddress(addressList[0]) && addressList[0].port === 0) { /* If binding to port 0, first try to bind the first address, then bind * the rest of the address list to the specific port that it binds. */ - const firstAddressResult = await this.bindOneAddress(addressList[0], boundPortObject); + const firstAddressResult = await this.bindOneAddress( + addressList[0], + boundPortObject + ); if (firstAddressResult.error) { /* If the first address fails to bind, try the same operation starting * from the second item in the list. */ - const restAddressResult = await this.bindManyPorts(addressList.slice(1), boundPortObject); + const restAddressResult = await this.bindManyPorts( + addressList.slice(1), + boundPortObject + ); return { ...restAddressResult, - errors: [firstAddressResult.error, ...restAddressResult.errors] + errors: [firstAddressResult.error, ...restAddressResult.errors], }; } else { - const restAddresses = addressList.slice(1).map(address => isTcpSubchannelAddress(address) ? {host: address.host, port: firstAddressResult.port} : address) - const restAddressResult = await Promise.all(restAddresses.map(address => this.bindOneAddress(address, boundPortObject))); + const restAddresses = addressList + .slice(1) + .map(address => + isTcpSubchannelAddress(address) + ? { host: address.host, port: firstAddressResult.port } + : address + ); + const restAddressResult = await Promise.all( + restAddresses.map(address => + this.bindOneAddress(address, boundPortObject) + ) + ); const allResults = [firstAddressResult, ...restAddressResult]; return { count: allResults.filter(result => result.error === undefined).length, port: firstAddressResult.port, - errors: allResults.filter(result => result.error).map(result => result.error!) + errors: allResults + .filter(result => result.error) + .map(result => result.error!), }; } } else { - const allResults = await Promise.all(addressList.map(address => this.bindOneAddress(address, boundPortObject))); + const allResults = await Promise.all( + addressList.map(address => + this.bindOneAddress(address, boundPortObject) + ) + ); return { count: allResults.filter(result => result.error === undefined).length, port: allResults[0].port, - errors: allResults.filter(result => result.error).map(result => result.error!) + errors: allResults + .filter(result => result.error) + .map(result => result.error!), }; } } - private async bindAddressList(addressList: SubchannelAddress[], boundPortObject: BoundPort): Promise { - let bindResult: BindResult; - try { - bindResult = await this.bindManyPorts(addressList, boundPortObject); - } catch (error) { - throw error; - } + private async bindAddressList( + addressList: SubchannelAddress[], + boundPortObject: BoundPort + ): Promise { + const bindResult = await this.bindManyPorts(addressList, boundPortObject); if (bindResult.count > 0) { if (bindResult.count < addressList.length) { logging.log( @@ -642,7 +685,9 @@ export class Server { } else { const errorString = `No address added out of total ${addressList.length} resolved`; logging.log(LogVerbosity.ERROR, errorString); - throw new Error(`${errorString} errors: [${bindResult.errors.join(',')}]`); + throw new Error( + `${errorString} errors: [${bindResult.errors.join(',')}]` + ); } } @@ -660,9 +705,7 @@ export class Server { ...endpointList.map(endpoint => endpoint.addresses) ); if (addressList.length === 0) { - reject( - new Error(`No addresses resolved for port ${port}`) - ); + reject(new Error(`No addresses resolved for port ${port}`)); return; } resolve(addressList); @@ -676,7 +719,10 @@ export class Server { }); } - private async bindPort(port: GrpcUri, boundPortObject: BoundPort): Promise { + private async bindPort( + port: GrpcUri, + boundPortObject: BoundPort + ): Promise { const addressList = await this.resolvePort(port); if (boundPortObject.cancelled) { this.completeUnbind(boundPortObject); @@ -691,7 +737,6 @@ export class Server { } private normalizePort(port: string): GrpcUri { - const initialPortUri = parseUri(port); if (initialPortUri === null) { throw new Error(`Could not parse port "${port}"`); @@ -736,14 +781,20 @@ export class Server { let boundPortObject = this.boundPorts.get(uriToString(portUri)); if (boundPortObject) { if (!creds._equals(boundPortObject.credentials)) { - deferredCallback(new Error(`${port} already bound with incompatible credentials`), 0); + deferredCallback( + new Error(`${port} already bound with incompatible credentials`), + 0 + ); return; } /* If that operation has previously been cancelled by an unbind call, * uncancel it. */ boundPortObject.cancelled = false; if (boundPortObject.completionPromise) { - boundPortObject.completionPromise.then(portNum => callback(null, portNum), error => callback(error as Error, 0)); + boundPortObject.completionPromise.then( + portNum => callback(null, portNum), + error => callback(error as Error, 0) + ); } else { deferredCallback(null, boundPortObject.portNumber); } @@ -756,7 +807,7 @@ export class Server { cancelled: false, portNumber: 0, credentials: creds, - listeningServers: new Set() + listeningServers: new Set(), }; const splitPort = splitHostPort(portUri.path); const completionPromise = this.bindPort(portUri, boundPortObject); @@ -765,34 +816,42 @@ export class Server { * bind operation completes and we have a specific port number. Otherwise, * populate it immediately. */ if (splitPort?.port === 0) { - completionPromise.then(portNum => { - const finalUri: GrpcUri = { - scheme: portUri.scheme, - authority: portUri.authority, - path: combineHostPort({host: splitPort.host, port: portNum}) - }; - boundPortObject!.mapKey = uriToString(finalUri); - boundPortObject!.completionPromise = null; - boundPortObject!.portNumber = portNum; - this.boundPorts.set(boundPortObject!.mapKey, boundPortObject!); - callback(null, portNum); - }, error => { - callback(error, 0); - }) + completionPromise.then( + portNum => { + const finalUri: GrpcUri = { + scheme: portUri.scheme, + authority: portUri.authority, + path: combineHostPort({ host: splitPort.host, port: portNum }), + }; + boundPortObject!.mapKey = uriToString(finalUri); + boundPortObject!.completionPromise = null; + boundPortObject!.portNumber = portNum; + this.boundPorts.set(boundPortObject!.mapKey, boundPortObject!); + callback(null, portNum); + }, + error => { + callback(error, 0); + } + ); } else { this.boundPorts.set(boundPortObject.mapKey, boundPortObject); - completionPromise.then(portNum => { - boundPortObject!.completionPromise = null; - boundPortObject!.portNumber = portNum; - callback(null, portNum); - }, error => { - callback(error, 0); - }); + completionPromise.then( + portNum => { + boundPortObject!.completionPromise = null; + boundPortObject!.portNumber = portNum; + callback(null, portNum); + }, + error => { + callback(error, 0); + } + ); } } private closeServer(server: AnyHttp2Server, callback?: () => void) { - this.trace('Closing server with address ' + JSON.stringify(server.address())); + this.trace( + 'Closing server with address ' + JSON.stringify(server.address()) + ); const serverInfo = this.http2Servers.get(server); server.close(() => { if (this.channelzEnabled && serverInfo) { @@ -802,10 +861,12 @@ export class Server { this.http2Servers.delete(server); callback?.(); }); - } - private closeSession(session: http2.ServerHttp2Session, callback?: () => void) { + private closeSession( + session: http2.ServerHttp2Session, + callback?: () => void + ) { this.trace('Closing session initiated by ' + session.socket?.remoteAddress); const sessionInfo = this.sessions.get(session); const closeCallback = () => { @@ -854,7 +915,12 @@ export class Server { } const boundPortObject = this.boundPorts.get(uriToString(portUri)); if (boundPortObject) { - this.trace('unbinding ' + boundPortObject.mapKey + ' originally bound as ' + uriToString(boundPortObject.originalUri)); + this.trace( + 'unbinding ' + + boundPortObject.mapKey + + ' originally bound as ' + + uriToString(boundPortObject.originalUri) + ); /* If the bind operation is pending, the cancelled flag will trigger * the unbind operation later. */ if (boundPortObject.completionPromise) { @@ -964,13 +1030,13 @@ export class Server { /** * @deprecated No longer needed as of version 1.10.x */ - @deprecate('Calling start() is no longer necessary. It can be safely omitted.') + @deprecate( + 'Calling start() is no longer necessary. It can be safely omitted.' + ) start(): void { if ( this.http2Servers.size === 0 || - [...this.http2Servers.keys()].every( - server => !server.listening - ) + [...this.http2Servers.keys()].every(server => !server.listening) ) { throw new Error('server must be bound in order to start'); } @@ -1090,9 +1156,9 @@ export class Server { 'grpc-message': err.details, [http2.constants.HTTP2_HEADER_STATUS]: http2.constants.HTTP_STATUS_OK, [http2.constants.HTTP2_HEADER_CONTENT_TYPE]: 'application/grpc+proto', - ...err.metadata?.toHttp2Headers() + ...err.metadata?.toHttp2Headers(), }; - stream.respond(trailersToSend, {endStream: true}); + stream.respond(trailersToSend, { endStream: true }); if (this.channelzEnabled) { this.callTracker.addCallFailed(); @@ -1129,7 +1195,7 @@ export class Server { return; } - let callEventTracker: CallEventTracker = { + const callEventTracker: CallEventTracker = { addMessageSent: () => { if (channelzSessionInfo) { channelzSessionInfo.messagesSent += 1; @@ -1157,10 +1223,17 @@ export class Server { channelzSessionInfo.streamTracker.addCallFailed(); } } - } - } + }, + }; - const call = getServerInterceptingCall(this.interceptors, stream, headers, callEventTracker, handler, this.options); + const call = getServerInterceptingCall( + this.interceptors, + stream, + headers, + callEventTracker, + handler, + this.options + ); if (!this._runHandlerForCall(call, handler)) { this.callTracker.addCallFailed(); @@ -1193,7 +1266,14 @@ export class Server { return; } - const call = getServerInterceptingCall(this.interceptors, stream, headers, null, handler, this.options); + const call = getServerInterceptingCall( + this.interceptors, + stream, + headers, + null, + handler, + this.options + ); if (!this._runHandlerForCall(call, handler)) { call.sendStatus({ @@ -1207,25 +1287,15 @@ export class Server { call: ServerInterceptingCallInterface, handler: Handler ): boolean { - const { type } = handler; if (type === 'unary') { handleUnary(call, handler as UntypedUnaryHandler); } else if (type === 'clientStream') { - handleClientStreaming( - call, - handler as UntypedClientStreamingHandler - ); + handleClientStreaming(call, handler as UntypedClientStreamingHandler); } else if (type === 'serverStream') { - handleServerStreaming( - call, - handler as UntypedServerStreamingHandler - ); + handleServerStreaming(call, handler as UntypedServerStreamingHandler); } else if (type === 'bidi') { - handleBidiStreaming( - call, - handler as UntypedBidiStreamingHandler - ); + handleBidiStreaming(call, handler as UntypedBidiStreamingHandler); } else { return false; } @@ -1257,7 +1327,6 @@ export class Server { http2Server.on('stream', handler.bind(this)); http2Server.on('session', session => { - const channelzRef = registerChannelzSocket( session.socket.remoteAddress ?? 'unknown', this.getChannelzSessionInfoGetter(session), @@ -1388,7 +1457,7 @@ async function handleUnary( call.sendStatus({ code: Status.OK, details: 'OK', - metadata: trailer ?? null + metadata: trailer ?? null, }); }); } @@ -1405,7 +1474,7 @@ async function handleUnary( call.sendStatus({ code: Status.UNIMPLEMENTED, details: `Received a second request message for server streaming method ${handler.path}`, - metadata: null + metadata: null, }); return; } @@ -1417,18 +1486,25 @@ async function handleUnary( call.sendStatus({ code: Status.UNIMPLEMENTED, details: `Received no request message for server streaming method ${handler.path}`, - metadata: null + metadata: null, }); return; } - stream = new ServerWritableStreamImpl(handler.path, call, requestMetadata, requestMessage); + stream = new ServerWritableStreamImpl( + handler.path, + call, + requestMetadata, + requestMessage + ); try { handler.func(stream, respond); } catch (err) { call.sendStatus({ code: Status.UNKNOWN, - details: `Server method handler threw error ${(err as Error).message}`, - metadata: null + details: `Server method handler threw error ${ + (err as Error).message + }`, + metadata: null, }); } }, @@ -1461,7 +1537,7 @@ function handleClientStreaming( call.sendStatus({ code: Status.OK, details: 'OK', - metadata: trailer ?? null + metadata: trailer ?? null, }); }); } @@ -1474,8 +1550,10 @@ function handleClientStreaming( } catch (err) { call.sendStatus({ code: Status.UNKNOWN, - details: `Server method handler threw error ${(err as Error).message}`, - metadata: null + details: `Server method handler threw error ${ + (err as Error).message + }`, + metadata: null, }); } }, @@ -1513,7 +1591,7 @@ function handleServerStreaming( call.sendStatus({ code: Status.UNIMPLEMENTED, details: `Received a second request message for server streaming method ${handler.path}`, - metadata: null + metadata: null, }); return; } @@ -1525,18 +1603,25 @@ function handleServerStreaming( call.sendStatus({ code: Status.UNIMPLEMENTED, details: `Received no request message for server streaming method ${handler.path}`, - metadata: null + metadata: null, }); return; } - stream = new ServerWritableStreamImpl(handler.path, call, requestMetadata, requestMessage); + stream = new ServerWritableStreamImpl( + handler.path, + call, + requestMetadata, + requestMessage + ); try { handler.func(stream); } catch (err) { call.sendStatus({ code: Status.UNKNOWN, - details: `Server method handler threw error ${(err as Error).message}`, - metadata: null + details: `Server method handler threw error ${ + (err as Error).message + }`, + metadata: null, }); } }, @@ -1564,8 +1649,10 @@ function handleBidiStreaming( } catch (err) { call.sendStatus({ code: Status.UNKNOWN, - details: `Server method handler threw error ${(err as Error).message}`, - metadata: null + details: `Server method handler threw error ${ + (err as Error).message + }`, + metadata: null, }); } }, diff --git a/packages/grpc-js/src/service-config.ts b/packages/grpc-js/src/service-config.ts index 5c2ca0d06..b0d0d5576 100644 --- a/packages/grpc-js/src/service-config.ts +++ b/packages/grpc-js/src/service-config.ts @@ -356,17 +356,23 @@ export function validateRetryThrottling(obj: any): RetryThrottling { function validateLoadBalancingConfig(obj: any): LoadBalancingConfig { if (!(typeof obj === 'object' && obj !== null)) { - throw new Error(`Invalid loadBalancingConfig: unexpected type ${typeof obj}`); + throw new Error( + `Invalid loadBalancingConfig: unexpected type ${typeof obj}` + ); } const keys = Object.keys(obj); if (keys.length > 1) { - throw new Error(`Invalid loadBalancingConfig: unexpected multiple keys ${keys}`); + throw new Error( + `Invalid loadBalancingConfig: unexpected multiple keys ${keys}` + ); } if (keys.length === 0) { - throw new Error('Invalid loadBalancingConfig: load balancing policy name required'); + throw new Error( + 'Invalid loadBalancingConfig: load balancing policy name required' + ); } return { - [keys[0]]: obj[keys[0]] + [keys[0]]: obj[keys[0]], }; } @@ -385,7 +391,6 @@ export function validateServiceConfig(obj: any): ServiceConfig { if ('loadBalancingConfig' in obj) { if (Array.isArray(obj.loadBalancingConfig)) { for (const config of obj.loadBalancingConfig) { - result.loadBalancingConfig.push(validateLoadBalancingConfig(config)); } } else { diff --git a/packages/grpc-js/src/transport.ts b/packages/grpc-js/src/transport.ts index b21581375..c4941b068 100644 --- a/packages/grpc-js/src/transport.ts +++ b/packages/grpc-js/src/transport.ts @@ -205,7 +205,12 @@ class Http2Transport implements Transport { ) { tooManyPings = true; } - this.trace('connection closed by GOAWAY with code ' + errorCode + ' and data ' + opaqueData?.toString()); + this.trace( + 'connection closed by GOAWAY with code ' + + errorCode + + ' and data ' + + opaqueData?.toString() + ); this.reportDisconnectToOwner(tooManyPings); } ); diff --git a/packages/grpc-js/test/common.ts b/packages/grpc-js/test/common.ts index f6aeed103..88aa129aa 100644 --- a/packages/grpc-js/test/common.ts +++ b/packages/grpc-js/test/common.ts @@ -129,7 +129,10 @@ export class TestClient { this.client.echo({}, callback); } - sendRequestWithMetadata(metadata: grpc.Metadata, callback: (error?: grpc.ServiceError) => void) { + sendRequestWithMetadata( + metadata: grpc.Metadata, + callback: (error?: grpc.ServiceError) => void + ) { this.client.echo({}, metadata, callback); } diff --git a/packages/grpc-js/test/test-confg-parsing.ts b/packages/grpc-js/test/test-confg-parsing.ts index 569b83f5e..b5b9832a7 100644 --- a/packages/grpc-js/test/test-confg-parsing.ts +++ b/packages/grpc-js/test/test-confg-parsing.ts @@ -28,7 +28,7 @@ import parseLoadBalancingConfig = experimental.parseLoadBalancingConfig; */ interface TestCase { name: string; - input: object, + input: object; output?: object; error?: RegExp; } @@ -40,52 +40,52 @@ interface TestCase { * Note: some tests have an expected output that is different from the output, * but all non-error tests additionally verify that parsing the output again * produces the same output. */ -const allTestCases: {[lbPolicyName: string]: TestCase[]} = { +const allTestCases: { [lbPolicyName: string]: TestCase[] } = { pick_first: [ { name: 'no fields set', input: {}, output: { - shuffleAddressList: false - } + shuffleAddressList: false, + }, }, { name: 'shuffleAddressList set', input: { - shuffleAddressList: true - } - } + shuffleAddressList: true, + }, + }, ], round_robin: [ { name: 'no fields set', - input: {} - } + input: {}, + }, ], outlier_detection: [ { name: 'only required fields set', input: { - child_policy: [{round_robin: {}}] + child_policy: [{ round_robin: {} }], }, output: { interval: { seconds: 10, - nanos: 0 + nanos: 0, }, base_ejection_time: { seconds: 30, - nanos: 0 + nanos: 0, }, max_ejection_time: { seconds: 300, - nanos: 0 + nanos: 0, }, max_ejection_percent: 10, success_rate_ejection: undefined, failure_percentage_ejection: undefined, - child_policy: [{round_robin: {}}] - } + child_policy: [{ round_robin: {} }], + }, }, { name: 'all optional fields undefined', @@ -96,53 +96,53 @@ const allTestCases: {[lbPolicyName: string]: TestCase[]} = { max_ejection_percent: undefined, success_rate_ejection: undefined, failure_percentage_ejection: undefined, - child_policy: [{round_robin: {}}] + child_policy: [{ round_robin: {} }], }, output: { interval: { seconds: 10, - nanos: 0 + nanos: 0, }, base_ejection_time: { seconds: 30, - nanos: 0 + nanos: 0, }, max_ejection_time: { seconds: 300, - nanos: 0 + nanos: 0, }, max_ejection_percent: 10, success_rate_ejection: undefined, failure_percentage_ejection: undefined, - child_policy: [{round_robin: {}}] - } + child_policy: [{ round_robin: {} }], + }, }, { name: 'empty ejection configs', input: { success_rate_ejection: {}, failure_percentage_ejection: {}, - child_policy: [{round_robin: {}}] + child_policy: [{ round_robin: {} }], }, output: { interval: { seconds: 10, - nanos: 0 + nanos: 0, }, base_ejection_time: { seconds: 30, - nanos: 0 + nanos: 0, }, max_ejection_time: { seconds: 300, - nanos: 0 + nanos: 0, }, max_ejection_percent: 10, success_rate_ejection: { stdev_factor: 1900, enforcement_percentage: 100, minimum_hosts: 5, - request_volume: 100 + request_volume: 100, }, failure_percentage_ejection: { threshold: 85, @@ -150,30 +150,30 @@ const allTestCases: {[lbPolicyName: string]: TestCase[]} = { minimum_hosts: 5, request_volume: 50, }, - child_policy: [{round_robin: {}}] - } + child_policy: [{ round_robin: {} }], + }, }, { name: 'all fields populated', input: { interval: { seconds: 20, - nanos: 0 + nanos: 0, }, base_ejection_time: { seconds: 40, - nanos: 0 + nanos: 0, }, max_ejection_time: { seconds: 400, - nanos: 0 + nanos: 0, }, max_ejection_percent: 20, success_rate_ejection: { stdev_factor: 1800, enforcement_percentage: 90, minimum_hosts: 4, - request_volume: 200 + request_volume: 200, }, failure_percentage_ejection: { threshold: 95, @@ -181,29 +181,34 @@ const allTestCases: {[lbPolicyName: string]: TestCase[]} = { minimum_hosts: 4, request_volume: 60, }, - child_policy: [{round_robin: {}}] - - } - } - ] -} + child_policy: [{ round_robin: {} }], + }, + }, + ], +}; describe('Load balancing policy config parsing', () => { for (const [lbPolicyName, testCases] of Object.entries(allTestCases)) { describe(lbPolicyName, () => { for (const testCase of testCases) { it(testCase.name, () => { - const lbConfigInput = {[lbPolicyName]: testCase.input}; + const lbConfigInput = { [lbPolicyName]: testCase.input }; if (testCase.error) { assert.throws(() => { parseLoadBalancingConfig(lbConfigInput); }, testCase.error); } else { const expectedOutput = testCase.output ?? testCase.input; - const parsedJson = parseLoadBalancingConfig(lbConfigInput).toJsonObject(); - assert.deepStrictEqual(parsedJson, {[lbPolicyName]: expectedOutput}); + const parsedJson = + parseLoadBalancingConfig(lbConfigInput).toJsonObject(); + assert.deepStrictEqual(parsedJson, { + [lbPolicyName]: expectedOutput, + }); // Test idempotency - assert.deepStrictEqual(parseLoadBalancingConfig(parsedJson).toJsonObject(), parsedJson); + assert.deepStrictEqual( + parseLoadBalancingConfig(parsedJson).toJsonObject(), + parsedJson + ); } }); } diff --git a/packages/grpc-js/test/test-pick-first.ts b/packages/grpc-js/test/test-pick-first.ts index df7a3c741..4c2c319e1 100644 --- a/packages/grpc-js/test/test-pick-first.ts +++ b/packages/grpc-js/test/test-pick-first.ts @@ -561,28 +561,43 @@ describe('pick_first load balancing policy', () => { }, updateState: updateStateCallBackForExpectedStateSequence( [ConnectivityState.CONNECTING, ConnectivityState.TRANSIENT_FAILURE], - err => setImmediate(() => { - assert.strictEqual(reresolutionRequestCount, targetReresolutionRequestCount); - done(err); - }) + err => + setImmediate(() => { + assert.strictEqual( + reresolutionRequestCount, + targetReresolutionRequestCount + ); + done(err); + }) ), requestReresolution: () => { reresolutionRequestCount += 1; - } + }, } ); const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {}); - pickFirst.updateAddressList([{ addresses: [{ host: 'localhost', port: 1 }]}], config); + pickFirst.updateAddressList( + [{ addresses: [{ host: 'localhost', port: 1 }] }], + config + ); process.nextTick(() => { subchannels[0].transitionToState(ConnectivityState.TRANSIENT_FAILURE); process.nextTick(() => { - pickFirst.updateAddressList([{ addresses: [{ host: 'localhost', port: 2 }]}], config); + pickFirst.updateAddressList( + [{ addresses: [{ host: 'localhost', port: 2 }] }], + config + ); process.nextTick(() => { subchannels[1].transitionToState(ConnectivityState.TRANSIENT_FAILURE); process.nextTick(() => { - pickFirst.updateAddressList([{ addresses: [{ host: 'localhost', port: 3 }]}], config); + pickFirst.updateAddressList( + [{ addresses: [{ host: 'localhost', port: 3 }] }], + config + ); process.nextTick(() => { - subchannels[2].transitionToState(ConnectivityState.TRANSIENT_FAILURE); + subchannels[2].transitionToState( + ConnectivityState.TRANSIENT_FAILURE + ); }); }); }); @@ -606,22 +621,35 @@ describe('pick_first load balancing policy', () => { }, updateState: updateStateCallBackForExpectedStateSequence( [ConnectivityState.TRANSIENT_FAILURE], - err => setImmediate(() => { - assert.strictEqual(reresolutionRequestCount, targetReresolutionRequestCount); - done(err); - }) + err => + setImmediate(() => { + assert.strictEqual( + reresolutionRequestCount, + targetReresolutionRequestCount + ); + done(err); + }) ), requestReresolution: () => { reresolutionRequestCount += 1; - } + }, } ); const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {}); - pickFirst.updateAddressList([{ addresses: [{ host: 'localhost', port: 1 }]}], config); + pickFirst.updateAddressList( + [{ addresses: [{ host: 'localhost', port: 1 }] }], + config + ); process.nextTick(() => { - pickFirst.updateAddressList([{ addresses: [{ host: 'localhost', port: 2 }]}], config); + pickFirst.updateAddressList( + [{ addresses: [{ host: 'localhost', port: 2 }] }], + config + ); process.nextTick(() => { - pickFirst.updateAddressList([{ addresses: [{ host: 'localhost', port: 2 }]}], config); + pickFirst.updateAddressList( + [{ addresses: [{ host: 'localhost', port: 2 }] }], + config + ); }); }); }); @@ -639,13 +667,20 @@ describe('pick_first load balancing policy', () => { return subchannel; }, updateState: updateStateCallBackForExpectedStateSequence( - [ConnectivityState.READY, ConnectivityState.IDLE, ConnectivityState.READY], + [ + ConnectivityState.READY, + ConnectivityState.IDLE, + ConnectivityState.READY, + ], done ), } ); const pickFirst = new PickFirstLoadBalancer(channelControlHelper, {}); - pickFirst.updateAddressList([{ addresses: [{ host: 'localhost', port: 1 }]}], config); + pickFirst.updateAddressList( + [{ addresses: [{ host: 'localhost', port: 1 }] }], + config + ); process.nextTick(() => { subchannels[0].transitionToState(ConnectivityState.IDLE); process.nextTick(() => { diff --git a/packages/grpc-js/test/test-server-interceptors.ts b/packages/grpc-js/test/test-server-interceptors.ts index b6b5b55f2..5e93d32d2 100644 --- a/packages/grpc-js/test/test-server-interceptors.ts +++ b/packages/grpc-js/test/test-server-interceptors.ts @@ -26,23 +26,28 @@ const echoService = loadProtoFile(protoFile) const AUTH_HEADER_KEY = 'auth'; const AUTH_HEADER_ALLOWED_VALUE = 'allowed'; -const testAuthInterceptor: grpc.ServerInterceptor = (methodDescriptor, call) => { +const testAuthInterceptor: grpc.ServerInterceptor = ( + methodDescriptor, + call +) => { return new grpc.ServerInterceptingCall(call, { start: next => { const authListener: grpc.ServerListener = { onReceiveMetadata: (metadata, mdNext) => { - if (metadata.get(AUTH_HEADER_KEY)?.[0] !== AUTH_HEADER_ALLOWED_VALUE) { + if ( + metadata.get(AUTH_HEADER_KEY)?.[0] !== AUTH_HEADER_ALLOWED_VALUE + ) { call.sendStatus({ code: grpc.status.UNAUTHENTICATED, - details: 'Auth metadata not correct' + details: 'Auth metadata not correct', }); } else { mdNext(metadata); } - } + }, }; next(authListener); - } + }, }); }; @@ -52,7 +57,7 @@ let eventCounts = { receiveHalfClose: 0, sendMetadata: 0, sendMessage: 0, - sendStatus: 0 + sendStatus: 0, }; function resetEventCounts() { @@ -62,7 +67,7 @@ function resetEventCounts() { receiveHalfClose: 0, sendMetadata: 0, sendMessage: 0, - sendStatus: 0 + sendStatus: 0, }; } @@ -72,7 +77,10 @@ function resetEventCounts() { * @param methodDescription * @param call */ -const testLoggingInterceptor: grpc.ServerInterceptor = (methodDescription, call) => { +const testLoggingInterceptor: grpc.ServerInterceptor = ( + methodDescription, + call +) => { return new grpc.ServerInterceptingCall(call, { start: next => { next({ @@ -87,7 +95,7 @@ const testLoggingInterceptor: grpc.ServerInterceptor = (methodDescription, call) onReceiveHalfClose: hcNext => { eventCounts.receiveHalfClose += 1; hcNext(); - } + }, }); }, sendMetadata: (metadata, mdNext) => { @@ -101,21 +109,24 @@ const testLoggingInterceptor: grpc.ServerInterceptor = (methodDescription, call) sendStatus: (status, statusNext) => { eventCounts.sendStatus += 1; statusNext(status); - } + }, }); }; -const testHeaderInjectionInterceptor: grpc.ServerInterceptor = (methodDescriptor, call) => { +const testHeaderInjectionInterceptor: grpc.ServerInterceptor = ( + methodDescriptor, + call +) => { return new grpc.ServerInterceptingCall(call, { start: next => { const authListener: grpc.ServerListener = { onReceiveMetadata: (metadata, mdNext) => { metadata.set('injected-header', 'present'); mdNext(metadata); - } + }, }; next(authListener); - } + }, }); }; @@ -126,22 +137,29 @@ describe('Server interceptors', () => { /* Tests that an interceptor can entirely prevent the handler from being * invoked, based on the contents of the metadata. */ before(done => { - server = new grpc.Server({interceptors: [testAuthInterceptor]}); + server = new grpc.Server({ interceptors: [testAuthInterceptor] }); server.addService(echoService.service, { echo: ( call: grpc.ServerUnaryCall, callback: grpc.sendUnaryData ) => { // A test will fail if a request makes it to the handler without the correct auth header - assert.strictEqual(call.metadata.get(AUTH_HEADER_KEY)?.[0], AUTH_HEADER_ALLOWED_VALUE); + assert.strictEqual( + call.metadata.get(AUTH_HEADER_KEY)?.[0], + AUTH_HEADER_ALLOWED_VALUE + ); callback(null, call.request); }, }); - server.bindAsync('localhost:0', grpc.ServerCredentials.createInsecure(), (error, port) => { - assert.ifError(error); - client = new TestClient(port, false); - done(); - }); + server.bindAsync( + 'localhost:0', + grpc.ServerCredentials.createInsecure(), + (error, port) => { + assert.ifError(error); + client = new TestClient(port, false); + done(); + } + ); }); after(done => { client.close(); @@ -165,7 +183,7 @@ describe('Server interceptors', () => { let server: grpc.Server; let client: TestClient; before(done => { - server = new grpc.Server({interceptors: [testLoggingInterceptor]}); + server = new grpc.Server({ interceptors: [testLoggingInterceptor] }); server.addService(echoService.service, { echo: ( call: grpc.ServerUnaryCall, @@ -175,11 +193,15 @@ describe('Server interceptors', () => { callback(null, call.request); }, }); - server.bindAsync('localhost:0', grpc.ServerCredentials.createInsecure(), (error, port) => { - assert.ifError(error); - client = new TestClient(port, false); - done(); - }); + server.bindAsync( + 'localhost:0', + grpc.ServerCredentials.createInsecure(), + (error, port) => { + assert.ifError(error); + client = new TestClient(port, false); + done(); + } + ); }); after(done => { client.close(); @@ -197,7 +219,7 @@ describe('Server interceptors', () => { receiveHalfClose: 1, sendMetadata: 1, sendMessage: 1, - sendStatus: 1 + sendStatus: 1, }); done(); }); @@ -207,21 +229,30 @@ describe('Server interceptors', () => { let server: grpc.Server; let client: TestClient; before(done => { - server = new grpc.Server({interceptors: [testHeaderInjectionInterceptor]}); + server = new grpc.Server({ + interceptors: [testHeaderInjectionInterceptor], + }); server.addService(echoService.service, { echo: ( call: grpc.ServerUnaryCall, callback: grpc.sendUnaryData ) => { - assert.strictEqual(call.metadata.get('injected-header')?.[0], 'present'); + assert.strictEqual( + call.metadata.get('injected-header')?.[0], + 'present' + ); callback(null, call.request); }, }); - server.bindAsync('localhost:0', grpc.ServerCredentials.createInsecure(), (error, port) => { - assert.ifError(error); - client = new TestClient(port, false); - done(); - }); + server.bindAsync( + 'localhost:0', + grpc.ServerCredentials.createInsecure(), + (error, port) => { + assert.ifError(error); + client = new TestClient(port, false); + done(); + } + ); }); after(done => { client.close(); @@ -235,23 +266,39 @@ describe('Server interceptors', () => { let server: grpc.Server; let client: TestClient; before(done => { - server = new grpc.Server({interceptors: [testAuthInterceptor, testLoggingInterceptor, testHeaderInjectionInterceptor]}); + server = new grpc.Server({ + interceptors: [ + testAuthInterceptor, + testLoggingInterceptor, + testHeaderInjectionInterceptor, + ], + }); server.addService(echoService.service, { echo: ( call: grpc.ServerUnaryCall, callback: grpc.sendUnaryData ) => { - assert.strictEqual(call.metadata.get(AUTH_HEADER_KEY)?.[0], AUTH_HEADER_ALLOWED_VALUE); - assert.strictEqual(call.metadata.get('injected-header')?.[0], 'present'); + assert.strictEqual( + call.metadata.get(AUTH_HEADER_KEY)?.[0], + AUTH_HEADER_ALLOWED_VALUE + ); + assert.strictEqual( + call.metadata.get('injected-header')?.[0], + 'present' + ); call.sendMetadata(new grpc.Metadata()); callback(null, call.request); }, }); - server.bindAsync('localhost:0', grpc.ServerCredentials.createInsecure(), (error, port) => { - assert.ifError(error); - client = new TestClient(port, false); - done(); - }); + server.bindAsync( + 'localhost:0', + grpc.ServerCredentials.createInsecure(), + (error, port) => { + assert.ifError(error); + client = new TestClient(port, false); + done(); + } + ); }); after(done => { client.close(); @@ -271,7 +318,7 @@ describe('Server interceptors', () => { receiveHalfClose: 0, sendMetadata: 0, sendMessage: 0, - sendStatus: 0 + sendStatus: 0, }); done(); }); @@ -287,7 +334,7 @@ describe('Server interceptors', () => { receiveHalfClose: 1, sendMetadata: 1, sendMessage: 1, - sendStatus: 1 + sendStatus: 1, }); done(); }); diff --git a/packages/grpc-js/test/test-server.ts b/packages/grpc-js/test/test-server.ts index 48b305ef4..dbcdad469 100644 --- a/packages/grpc-js/test/test-server.ts +++ b/packages/grpc-js/test/test-server.ts @@ -149,14 +149,22 @@ describe('Server', () => { }); it('succeeds when called with an already bound port', done => { - server.bindAsync('localhost:0', ServerCredentials.createInsecure(), (err, port) => { - assert.ifError(err); - server.bindAsync(`localhost:${port}`, ServerCredentials.createInsecure(), (err2, port2) => { - assert.ifError(err2); - assert.strictEqual(port, port2); - done(); - }); - }); + server.bindAsync( + 'localhost:0', + ServerCredentials.createInsecure(), + (err, port) => { + assert.ifError(err); + server.bindAsync( + `localhost:${port}`, + ServerCredentials.createInsecure(), + (err2, port2) => { + assert.ifError(err2); + assert.strictEqual(port, port2); + done(); + } + ); + } + ); }); it('fails when called on a bound port with different credentials', done => { @@ -165,15 +173,19 @@ describe('Server', () => { [{ private_key: key, cert_chain: cert }], true ); - server.bindAsync('localhost:0', ServerCredentials.createInsecure(), (err, port) => { - assert.ifError(err); - server.bindAsync(`localhost:${port}`, secureCreds, (err2, port2) => { - assert(err2 !== null); - assert.match(err2.message, /credentials/); - done(); - }) - }); - }) + server.bindAsync( + 'localhost:0', + ServerCredentials.createInsecure(), + (err, port) => { + assert.ifError(err); + server.bindAsync(`localhost:${port}`, secureCreds, (err2, port2) => { + assert(err2 !== null); + assert.match(err2.message, /credentials/); + done(); + }); + } + ); + }); }); describe('unbind', () => { @@ -188,42 +200,73 @@ describe('Server', () => { assert.throws(() => { server.unbind('localhost:0'); }, /port 0/); - server.bindAsync('localhost:0', ServerCredentials.createInsecure(), (err, port) => { - assert.ifError(err); - assert.notStrictEqual(port, 0); - assert.throws(() => { - server.unbind('localhost:0'); - }, /port 0/); - done(); - }) + server.bindAsync( + 'localhost:0', + ServerCredentials.createInsecure(), + (err, port) => { + assert.ifError(err); + assert.notStrictEqual(port, 0); + assert.throws(() => { + server.unbind('localhost:0'); + }, /port 0/); + done(); + } + ); }); it('successfully unbinds a bound ephemeral port', done => { - server.bindAsync('localhost:0', ServerCredentials.createInsecure(), (err, port) => { - client = new grpc.Client(`localhost:${port}`, grpc.credentials.createInsecure()); - client.makeUnaryRequest('/math.Math/Div', x => x, x => x, Buffer.from('abc'), (callError1, result) => { - assert(callError1); - // UNIMPLEMENTED means that the request reached the call handling code - assert.strictEqual(callError1.code, grpc.status.UNIMPLEMENTED); - server.unbind(`localhost:${port}`); - const deadline = new Date(); - deadline.setSeconds(deadline.getSeconds() + 1); - client!.makeUnaryRequest('/math.Math/Div', x => x, x => x, Buffer.from('abc'), {deadline: deadline}, (callError2, result) => { - assert(callError2); - // DEADLINE_EXCEEDED means that the server is unreachable - assert(callError2.code === grpc.status.DEADLINE_EXCEEDED || callError2.code === grpc.status.UNAVAILABLE); - done(); - }); - }); - }) + server.bindAsync( + 'localhost:0', + ServerCredentials.createInsecure(), + (err, port) => { + client = new grpc.Client( + `localhost:${port}`, + grpc.credentials.createInsecure() + ); + client.makeUnaryRequest( + '/math.Math/Div', + x => x, + x => x, + Buffer.from('abc'), + (callError1, result) => { + assert(callError1); + // UNIMPLEMENTED means that the request reached the call handling code + assert.strictEqual(callError1.code, grpc.status.UNIMPLEMENTED); + server.unbind(`localhost:${port}`); + const deadline = new Date(); + deadline.setSeconds(deadline.getSeconds() + 1); + client!.makeUnaryRequest( + '/math.Math/Div', + x => x, + x => x, + Buffer.from('abc'), + { deadline: deadline }, + (callError2, result) => { + assert(callError2); + // DEADLINE_EXCEEDED means that the server is unreachable + assert( + callError2.code === grpc.status.DEADLINE_EXCEEDED || + callError2.code === grpc.status.UNAVAILABLE + ); + done(); + } + ); + } + ); + } + ); }); it('cancels a bindAsync in progress', done => { - server.bindAsync('localhost:50051', ServerCredentials.createInsecure(), (err, port) => { - assert(err); - assert.match(err.message, /cancelled by unbind/); - done(); - }); + server.bindAsync( + 'localhost:50051', + ServerCredentials.createInsecure(), + (err, port) => { + assert(err); + assert.match(err.message, /cancelled by unbind/); + done(); + } + ); server.unbind('localhost:50051'); }); }); @@ -282,7 +325,7 @@ describe('Server', () => { call.on('data', () => { server.drain(`localhost:${portNumber!}`, 100); }); - call.write({value: 'abc'}); + call.write({ value: 'abc' }); }); }); From e0b900dd6903922b66bbfd2e17f00450d12f66b6 Mon Sep 17 00:00:00 2001 From: AVVS Date: Tue, 27 Feb 2024 12:27:25 -0800 Subject: [PATCH 02/55] feat: channelz improvements, idle timeout implementation --- packages/grpc-js/.eslintrc | 1 + packages/grpc-js/gulpfile.ts | 33 +- packages/grpc-js/package.json | 37 +- packages/grpc-js/src/channel.ts | 2 +- packages/grpc-js/src/channelz.ts | 468 ++++++------ .../src/load-balancer-child-handler.ts | 2 +- packages/grpc-js/src/load-balancer.ts | 2 +- packages/grpc-js/src/server-call.ts | 18 +- packages/grpc-js/src/server.ts | 678 ++++++++++++------ packages/grpc-js/src/subchannel-interface.ts | 2 +- packages/grpc-js/src/subchannel.ts | 38 +- packages/grpc-js/src/transport.ts | 16 +- packages/grpc-js/test/common.ts | 4 +- 13 files changed, 784 insertions(+), 517 deletions(-) diff --git a/packages/grpc-js/.eslintrc b/packages/grpc-js/.eslintrc index 2f6bfd62d..9a72b31de 100644 --- a/packages/grpc-js/.eslintrc +++ b/packages/grpc-js/.eslintrc @@ -50,6 +50,7 @@ "@typescript-eslint/explicit-module-boundary-types": "off", "@typescript-eslint/ban-types": "off", "@typescript-eslint/camelcase": "off", + "@typescript-eslint/no-explicit-any": "off", "node/no-missing-import": "off", "node/no-empty-function": "off", "node/no-unsupported-features/es-syntax": "off", diff --git a/packages/grpc-js/gulpfile.ts b/packages/grpc-js/gulpfile.ts index d85900364..e4e9071ff 100644 --- a/packages/grpc-js/gulpfile.ts +++ b/packages/grpc-js/gulpfile.ts @@ -35,14 +35,17 @@ const pkgPath = path.resolve(jsCoreDir, 'package.json'); const supportedVersionRange = require(pkgPath).engines.node; const versionNotSupported = () => { console.log(`Skipping grpc-js task for Node ${process.version}`); - return () => { return Promise.resolve(); }; + return () => { + return Promise.resolve(); + }; }; const identity = (value: any): any => value; -const checkTask = semver.satisfies(process.version, supportedVersionRange) ? - identity : versionNotSupported; +const checkTask = semver.satisfies(process.version, supportedVersionRange) + ? identity + : versionNotSupported; const execNpmVerb = (verb: string, ...args: string[]) => - execa('npm', [verb, ...args], {cwd: jsCoreDir, stdio: 'inherit'}); + execa('npm', [verb, ...args], { cwd: jsCoreDir, stdio: 'inherit' }); const execNpmCommand = execNpmVerb.bind(null, 'run'); const install = checkTask(() => execNpmVerb('install', '--unsafe-perm')); @@ -64,22 +67,20 @@ const cleanAll = gulp.parallel(clean); */ const compile = checkTask(() => execNpmCommand('compile')); -const copyTestFixtures = checkTask(() => ncpP(`${jsCoreDir}/test/fixtures`, `${outDir}/test/fixtures`)); +const copyTestFixtures = checkTask(() => + ncpP(`${jsCoreDir}/test/fixtures`, `${outDir}/test/fixtures`) +); const runTests = checkTask(() => { process.env.GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION = 'true'; - return gulp.src(`${outDir}/test/**/*.js`) - .pipe(mocha({reporter: 'mocha-jenkins-reporter', - require: ['ts-node/register']})); + return gulp.src(`${outDir}/test/**/*.js`).pipe( + mocha({ + reporter: 'mocha-jenkins-reporter', + require: ['ts-node/register'], + }) + ); }); const test = gulp.series(install, copyTestFixtures, runTests); -export { - install, - lint, - clean, - cleanAll, - compile, - test -} +export { install, lint, clean, cleanAll, compile, test }; diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index d1cb3d561..34d8b558b 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -6,7 +6,7 @@ "repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js", "main": "build/src/index.js", "engines": { - "node": "^8.13.0 || >=10.10.0" + "node": ">=12.10.0" }, "keywords": [], "author": { @@ -15,17 +15,18 @@ "types": "build/src/index.d.ts", "license": "Apache-2.0", "devDependencies": { - "@types/gulp": "^4.0.6", - "@types/gulp-mocha": "0.0.32", - "@types/lodash": "^4.14.186", - "@types/mocha": "^5.2.6", - "@types/ncp": "^2.0.1", - "@types/pify": "^3.0.2", - "@types/semver": "^7.3.9", - "@typescript-eslint/eslint-plugin": "^5.59.11", - "@typescript-eslint/parser": "^5.59.11", - "@typescript-eslint/typescript-estree": "^5.59.11", - "clang-format": "^1.0.55", + "@types/gulp": "^4.0.17", + "@types/gulp-mocha": "0.0.37", + "@types/lodash": "^4.14.202", + "@types/mocha": "^10.0.6", + "@types/ncp": "^2.0.8", + "@types/pify": "^5.0.4", + "@types/semver": "^7.5.8", + "@types/node": ">=20.11.20", + "@typescript-eslint/eslint-plugin": "^7.1.0", + "@typescript-eslint/parser": "^7.1.0", + "@typescript-eslint/typescript-estree": "^7.1.0", + "clang-format": "^1.8.0", "eslint": "^8.42.0", "eslint-config-prettier": "^8.8.0", "eslint-plugin-node": "^11.1.0", @@ -33,16 +34,16 @@ "execa": "^2.0.3", "gulp": "^4.0.2", "gulp-mocha": "^6.0.0", - "lodash": "^4.17.4", + "lodash": "^4.17.21", "madge": "^5.0.1", "mocha-jenkins-reporter": "^0.4.1", "ncp": "^2.0.0", "pify": "^4.0.1", "prettier": "^2.8.8", "rimraf": "^3.0.2", - "semver": "^7.3.5", - "ts-node": "^10.9.1", - "typescript": "^5.1.3" + "semver": "^7.6.0", + "ts-node": "^10.9.2", + "typescript": "^5.3.3" }, "contributors": [ { @@ -65,8 +66,8 @@ "generate-test-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --include-dirs test/fixtures/ -O test/generated/ --grpcLib ../../src/index test_service.proto" }, "dependencies": { - "@grpc/proto-loader": "^0.7.8", - "@types/node": ">=12.12.47" + "@grpc/proto-loader": "^0.7.10", + "@js-sdsl/ordered-map": "^4.4.2" }, "files": [ "src/**/*.ts", diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 7ce5a15f7..514920c8f 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -20,7 +20,7 @@ import { ChannelOptions } from './channel-options'; import { ServerSurfaceCall } from './server-call'; import { ConnectivityState } from './connectivity-state'; -import { ChannelRef } from './channelz'; +import type { ChannelRef } from './channelz'; import { Call } from './call-interface'; import { InternalChannel } from './internal-channel'; import { Deadline } from './deadline'; diff --git a/packages/grpc-js/src/channelz.ts b/packages/grpc-js/src/channelz.ts index 1e2627a97..6d70b7543 100644 --- a/packages/grpc-js/src/channelz.ts +++ b/packages/grpc-js/src/channelz.ts @@ -16,6 +16,7 @@ */ import { isIPv4, isIPv6 } from 'net'; +import { OrderedMap, type OrderedMapIterator } from '@js-sdsl/ordered-map'; import { ConnectivityState } from './connectivity-state'; import { Status } from './constants'; import { Timestamp } from './generated/google/protobuf/Timestamp'; @@ -66,24 +67,25 @@ export type TraceSeverity = | 'CT_ERROR'; export interface ChannelRef { - kind: 'channel'; + kind: EntityTypes.channel; id: number; name: string; } export interface SubchannelRef { - kind: 'subchannel'; + kind: EntityTypes.subchannel; id: number; name: string; } export interface ServerRef { - kind: 'server'; + kind: EntityTypes.server; id: number; + name: string; } export interface SocketRef { - kind: 'socket'; + kind: EntityTypes.socket; id: number; name: string; } @@ -131,6 +133,21 @@ interface TraceEvent { */ const TARGET_RETAINED_TRACES = 32; +export class ChannelzTraceStub { + readonly events: TraceEvent[] = []; + readonly creationTimestamp: Date = new Date(); + readonly eventsLogged = 0; + + addTrace(): void {} + getTraceMessage(): ChannelTrace { + return { + creation_timestamp: dateToProtoTimestamp(this.creationTimestamp), + num_events_logged: this.eventsLogged, + events: [], + }; + } +} + export class ChannelzTrace { events: TraceEvent[] = []; creationTimestamp: Date; @@ -182,105 +199,64 @@ export class ChannelzTrace { } export class ChannelzChildrenTracker { - private channelChildren: Map = - new Map(); - private subchannelChildren: Map< + private channelChildren = new OrderedMap< + number, + { ref: ChannelRef; count: number } + >(); + private subchannelChildren = new OrderedMap< number, { ref: SubchannelRef; count: number } - > = new Map(); - private socketChildren: Map = - new Map(); + >(); + private socketChildren = new OrderedMap< + number, + { ref: SocketRef; count: number } + >(); + private trackerMap = { + [EntityTypes.channel]: this.channelChildren, + [EntityTypes.subchannel]: this.subchannelChildren, + [EntityTypes.socket]: this.socketChildren, + } as const; refChild(child: ChannelRef | SubchannelRef | SocketRef) { - switch (child.kind) { - case 'channel': { - const trackedChild = this.channelChildren.get(child.id) ?? { - ref: child, - count: 0, - }; - trackedChild.count += 1; - this.channelChildren.set(child.id, trackedChild); - break; - } - case 'subchannel': { - const trackedChild = this.subchannelChildren.get(child.id) ?? { - ref: child, - count: 0, - }; - trackedChild.count += 1; - this.subchannelChildren.set(child.id, trackedChild); - break; - } - case 'socket': { - const trackedChild = this.socketChildren.get(child.id) ?? { - ref: child, - count: 0, - }; - trackedChild.count += 1; - this.socketChildren.set(child.id, trackedChild); - break; - } + const tracker = this.trackerMap[child.kind]; + const trackedChild = tracker.getElementByKey(child.id); + + if (trackedChild === undefined) { + tracker.setElement(child.id, { + // @ts-expect-error union issues + ref: child, + count: 1, + }); + } else { + trackedChild.count += 1; } } unrefChild(child: ChannelRef | SubchannelRef | SocketRef) { - switch (child.kind) { - case 'channel': { - const trackedChild = this.channelChildren.get(child.id); - if (trackedChild !== undefined) { - trackedChild.count -= 1; - if (trackedChild.count === 0) { - this.channelChildren.delete(child.id); - } else { - this.channelChildren.set(child.id, trackedChild); - } - } - break; - } - case 'subchannel': { - const trackedChild = this.subchannelChildren.get(child.id); - if (trackedChild !== undefined) { - trackedChild.count -= 1; - if (trackedChild.count === 0) { - this.subchannelChildren.delete(child.id); - } else { - this.subchannelChildren.set(child.id, trackedChild); - } - } - break; - } - case 'socket': { - const trackedChild = this.socketChildren.get(child.id); - if (trackedChild !== undefined) { - trackedChild.count -= 1; - if (trackedChild.count === 0) { - this.socketChildren.delete(child.id); - } else { - this.socketChildren.set(child.id, trackedChild); - } - } - break; + const tracker = this.trackerMap[child.kind]; + const trackedChild = tracker.getElementByKey(child.id); + if (trackedChild !== undefined) { + trackedChild.count -= 1; + if (trackedChild.count === 0) { + tracker.eraseElementByKey(child.id); } } } getChildLists(): ChannelzChildren { - const channels: ChannelRef[] = []; - for (const { ref } of this.channelChildren.values()) { - channels.push(ref); - } - const subchannels: SubchannelRef[] = []; - for (const { ref } of this.subchannelChildren.values()) { - subchannels.push(ref); - } - const sockets: SocketRef[] = []; - for (const { ref } of this.socketChildren.values()) { - sockets.push(ref); - } - return { channels, subchannels, sockets }; + return { + channels: this.channelChildren, + subchannels: this.subchannelChildren, + sockets: this.socketChildren, + }; } } +export class ChannelzChildrenTrackerStub extends ChannelzChildrenTracker { + override refChild(): void {} + override unrefChild(): void {} +} + export class ChannelzCallTracker { callsStarted = 0; callsSucceeded = 0; @@ -299,17 +275,23 @@ export class ChannelzCallTracker { } } +export class ChannelzCallTrackerStub extends ChannelzCallTracker { + override addCallStarted() {} + override addCallSucceeded() {} + override addCallFailed() {} +} + export interface ChannelzChildren { - channels: ChannelRef[]; - subchannels: SubchannelRef[]; - sockets: SocketRef[]; + channels: OrderedMap; + subchannels: OrderedMap; + sockets: OrderedMap; } export interface ChannelInfo { target: string; state: ConnectivityState; - trace: ChannelzTrace; - callTracker: ChannelzCallTracker; + trace: ChannelzTrace | ChannelzTraceStub; + callTracker: ChannelzCallTracker | ChannelzCallTrackerStub; children: ChannelzChildren; } @@ -348,105 +330,102 @@ export interface SocketInfo { remoteFlowControlWindow: number | null; } -interface ChannelEntry { +type ChannelEntry = { ref: ChannelRef; getInfo(): ChannelInfo; -} +}; -interface SubchannelEntry { +type SubchannelEntry = { ref: SubchannelRef; getInfo(): SubchannelInfo; -} +}; -interface ServerEntry { +type ServerEntry = { ref: ServerRef; getInfo(): ServerInfo; -} +}; -interface SocketEntry { +type SocketEntry = { ref: SocketRef; getInfo(): SocketInfo; -} - -let nextId = 1; - -function getNextId(): number { - return nextId++; -} - -const channels: (ChannelEntry | undefined)[] = []; -const subchannels: (SubchannelEntry | undefined)[] = []; -const servers: (ServerEntry | undefined)[] = []; -const sockets: (SocketEntry | undefined)[] = []; - -export function registerChannelzChannel( - name: string, - getInfo: () => ChannelInfo, - channelzEnabled: boolean -): ChannelRef { - const id = getNextId(); - const ref: ChannelRef = { id, name, kind: 'channel' }; - if (channelzEnabled) { - channels[id] = { ref, getInfo }; - } - return ref; -} - -export function registerChannelzSubchannel( - name: string, - getInfo: () => SubchannelInfo, - channelzEnabled: boolean -): SubchannelRef { - const id = getNextId(); - const ref: SubchannelRef = { id, name, kind: 'subchannel' }; - if (channelzEnabled) { - subchannels[id] = { ref, getInfo }; +}; + +export const enum EntityTypes { + channel = 'channel', + subchannel = 'subchannel', + server = 'server', + socket = 'socket', +} + +const entityMaps = { + [EntityTypes.channel]: new OrderedMap(), + [EntityTypes.subchannel]: new OrderedMap(), + [EntityTypes.server]: new OrderedMap(), + [EntityTypes.socket]: new OrderedMap(), +} as const; + +export type RefByType = T extends EntityTypes.channel + ? ChannelRef + : T extends EntityTypes.server + ? ServerRef + : T extends EntityTypes.socket + ? SocketRef + : T extends EntityTypes.subchannel + ? SubchannelRef + : never; + +export type EntryByType = T extends EntityTypes.channel + ? ChannelEntry + : T extends EntityTypes.server + ? ServerEntry + : T extends EntityTypes.socket + ? SocketEntry + : T extends EntityTypes.subchannel + ? SubchannelEntry + : never; + +export type InfoByType = T extends EntityTypes.channel + ? ChannelInfo + : T extends EntityTypes.subchannel + ? SubchannelInfo + : T extends EntityTypes.server + ? ServerInfo + : T extends EntityTypes.socket + ? SocketInfo + : never; + +const generateRegisterFn = (kind: R) => { + let nextId = 1; + function getNextId(): number { + return nextId++; } - return ref; -} -export function registerChannelzServer( - getInfo: () => ServerInfo, - channelzEnabled: boolean -): ServerRef { - const id = getNextId(); - const ref: ServerRef = { id, kind: 'server' }; - if (channelzEnabled) { - servers[id] = { ref, getInfo }; - } - return ref; -} - -export function registerChannelzSocket( - name: string, - getInfo: () => SocketInfo, - channelzEnabled: boolean -): SocketRef { - const id = getNextId(); - const ref: SocketRef = { id, name, kind: 'socket' }; - if (channelzEnabled) { - sockets[id] = { ref, getInfo }; - } - return ref; -} + return ( + name: string, + getInfo: () => InfoByType, + channelzEnabled: boolean + ): RefByType => { + const id = getNextId(); + const ref = { id, name, kind } as RefByType; + if (channelzEnabled) { + // @ts-expect-error typing issues + entityMaps[kind].setElement(id, { ref, getInfo }); + } + return ref; + }; +}; + +export const registerChannelzChannel = generateRegisterFn(EntityTypes.channel); +export const registerChannelzSubchannel = generateRegisterFn( + EntityTypes.subchannel +); +export const registerChannelzServer = generateRegisterFn(EntityTypes.server); +export const registerChannelzSocket = generateRegisterFn(EntityTypes.socket); export function unregisterChannelzRef( ref: ChannelRef | SubchannelRef | ServerRef | SocketRef ) { - switch (ref.kind) { - case 'channel': - delete channels[ref.id]; - return; - case 'subchannel': - delete subchannels[ref.id]; - return; - case 'server': - delete servers[ref.id]; - return; - case 'socket': - delete sockets[ref.id]; - return; - } + entityMaps[ref.kind].eraseElementByKey(ref.id); } /** @@ -556,6 +535,17 @@ function dateToProtoTimestamp(date?: Date | null): Timestamp | null { function getChannelMessage(channelEntry: ChannelEntry): ChannelMessage { const resolvedInfo = channelEntry.getInfo(); + const channelRef: ChannelRefMessage[] = []; + const subchannelRef: SubchannelRefMessage[] = []; + + resolvedInfo.children.channels.forEach(el => { + channelRef.push(channelRefToMessage(el[1].ref)); + }); + + resolvedInfo.children.subchannels.forEach(el => { + subchannelRef.push(subchannelRefToMessage(el[1].ref)); + }); + return { ref: channelRefToMessage(channelEntry.ref), data: { @@ -569,12 +559,8 @@ function getChannelMessage(channelEntry: ChannelEntry): ChannelMessage { ), trace: resolvedInfo.trace.getTraceMessage(), }, - channel_ref: resolvedInfo.children.channels.map(ref => - channelRefToMessage(ref) - ), - subchannel_ref: resolvedInfo.children.subchannels.map(ref => - subchannelRefToMessage(ref) - ), + channel_ref: channelRef, + subchannel_ref: subchannelRef, }; } @@ -582,8 +568,9 @@ function GetChannel( call: ServerUnaryCall, callback: sendUnaryData ): void { - const channelId = Number.parseInt(call.request.channel_id); - const channelEntry = channels[channelId]; + const channelId = parseInt(call.request.channel_id, 10); + const channelEntry = + entityMaps[EntityTypes.channel].getElementByKey(channelId); if (channelEntry === undefined) { callback({ code: Status.NOT_FOUND, @@ -598,27 +585,34 @@ function GetTopChannels( call: ServerUnaryCall, callback: sendUnaryData ): void { - const maxResults = Number.parseInt(call.request.max_results); + const maxResults = parseInt(call.request.max_results, 10) || 100; const resultList: ChannelMessage[] = []; - let i = Number.parseInt(call.request.start_channel_id); - for (; i < channels.length; i++) { - const channelEntry = channels[i]; - if (channelEntry === undefined) { - continue; - } - resultList.push(getChannelMessage(channelEntry)); - if (resultList.length >= maxResults) { - break; - } + const startId = parseInt(call.request.start_channel_id, 10); + const channelEntries = entityMaps[EntityTypes.channel]; + + let i: OrderedMapIterator; + for ( + i = channelEntries.lowerBound(startId); + !i.equals(channelEntries.end()) && resultList.length < maxResults; + i = i.next() + ) { + resultList.push(getChannelMessage(i.pointer[1])); } + callback(null, { channel: resultList, - end: i >= servers.length, + end: i.equals(channelEntries.end()), }); } function getServerMessage(serverEntry: ServerEntry): ServerMessage { const resolvedInfo = serverEntry.getInfo(); + const listenSocket: SocketRefMessage[] = []; + + resolvedInfo.listenerChildren.sockets.forEach(el => { + listenSocket.push(socketRefToMessage(el[1].ref)); + }); + return { ref: serverRefToMessage(serverEntry.ref), data: { @@ -630,9 +624,7 @@ function getServerMessage(serverEntry: ServerEntry): ServerMessage { ), trace: resolvedInfo.trace.getTraceMessage(), }, - listen_socket: resolvedInfo.listenerChildren.sockets.map(ref => - socketRefToMessage(ref) - ), + listen_socket: listenSocket, }; } @@ -640,8 +632,9 @@ function GetServer( call: ServerUnaryCall, callback: sendUnaryData ): void { - const serverId = Number.parseInt(call.request.server_id); - const serverEntry = servers[serverId]; + const serverId = parseInt(call.request.server_id, 10); + const serverEntries = entityMaps[EntityTypes.server]; + const serverEntry = serverEntries.getElementByKey(serverId); if (serverEntry === undefined) { callback({ code: Status.NOT_FOUND, @@ -656,22 +649,23 @@ function GetServers( call: ServerUnaryCall, callback: sendUnaryData ): void { - const maxResults = Number.parseInt(call.request.max_results); + const maxResults = parseInt(call.request.max_results, 10) || 100; + const startId = parseInt(call.request.start_server_id, 10); + const serverEntries = entityMaps[EntityTypes.server]; const resultList: ServerMessage[] = []; - let i = Number.parseInt(call.request.start_server_id); - for (; i < servers.length; i++) { - const serverEntry = servers[i]; - if (serverEntry === undefined) { - continue; - } - resultList.push(getServerMessage(serverEntry)); - if (resultList.length >= maxResults) { - break; - } + + let i: OrderedMapIterator; + for ( + i = serverEntries.lowerBound(startId); + !i.equals(serverEntries.end()) && resultList.length < maxResults; + i = i.next() + ) { + resultList.push(getServerMessage(i.pointer[1])); } + callback(null, { server: resultList, - end: i >= servers.length, + end: i.equals(serverEntries.end()), }); } @@ -679,8 +673,9 @@ function GetSubchannel( call: ServerUnaryCall, callback: sendUnaryData ): void { - const subchannelId = Number.parseInt(call.request.subchannel_id); - const subchannelEntry = subchannels[subchannelId]; + const subchannelId = parseInt(call.request.subchannel_id, 10); + const subchannelEntry = + entityMaps[EntityTypes.subchannel].getElementByKey(subchannelId); if (subchannelEntry === undefined) { callback({ code: Status.NOT_FOUND, @@ -689,6 +684,12 @@ function GetSubchannel( return; } const resolvedInfo = subchannelEntry.getInfo(); + const listenSocket: SocketRefMessage[] = []; + + resolvedInfo.children.sockets.forEach(el => { + listenSocket.push(socketRefToMessage(el[1].ref)); + }); + const subchannelMessage: SubchannelMessage = { ref: subchannelRefToMessage(subchannelEntry.ref), data: { @@ -702,9 +703,7 @@ function GetSubchannel( ), trace: resolvedInfo.trace.getTraceMessage(), }, - socket_ref: resolvedInfo.children.sockets.map(ref => - socketRefToMessage(ref) - ), + socket_ref: listenSocket, }; callback(null, { subchannel: subchannelMessage }); } @@ -735,8 +734,8 @@ function GetSocket( call: ServerUnaryCall, callback: sendUnaryData ): void { - const socketId = Number.parseInt(call.request.socket_id); - const socketEntry = sockets[socketId]; + const socketId = parseInt(call.request.socket_id, 10); + const socketEntry = entityMaps[EntityTypes.socket].getElementByKey(socketId); if (socketEntry === undefined) { callback({ code: Status.NOT_FOUND, @@ -809,8 +808,9 @@ function GetServerSockets( >, callback: sendUnaryData ): void { - const serverId = Number.parseInt(call.request.server_id); - const serverEntry = servers[serverId]; + const serverId = parseInt(call.request.server_id, 10); + const serverEntry = entityMaps[EntityTypes.server].getElementByKey(serverId); + if (serverEntry === undefined) { callback({ code: Status.NOT_FOUND, @@ -818,28 +818,28 @@ function GetServerSockets( }); return; } - const startId = Number.parseInt(call.request.start_socket_id); - const maxResults = Number.parseInt(call.request.max_results); + + const startId = parseInt(call.request.start_socket_id, 10); + const maxResults = parseInt(call.request.max_results, 10) || 100; const resolvedInfo = serverEntry.getInfo(); // If we wanted to include listener sockets in the result, this line would // instead say // const allSockets = resolvedInfo.listenerChildren.sockets.concat(resolvedInfo.sessionChildren.sockets).sort((ref1, ref2) => ref1.id - ref2.id); - const allSockets = resolvedInfo.sessionChildren.sockets.sort( - (ref1, ref2) => ref1.id - ref2.id - ); + const allSockets = resolvedInfo.sessionChildren.sockets; const resultList: SocketRefMessage[] = []; - let i = 0; - for (; i < allSockets.length; i++) { - if (allSockets[i].id >= startId) { - resultList.push(socketRefToMessage(allSockets[i])); - if (resultList.length >= maxResults) { - break; - } - } + + let i: OrderedMapIterator; + for ( + i = allSockets.lowerBound(startId); + !i.equals(allSockets.end()) && resultList.length < maxResults; + i = i.next() + ) { + resultList.push(socketRefToMessage(i.pointer[1].ref)); } + callback(null, { socket_ref: resultList, - end: i >= allSockets.length, + end: i.equals(allSockets.end()), }); } diff --git a/packages/grpc-js/src/load-balancer-child-handler.ts b/packages/grpc-js/src/load-balancer-child-handler.ts index a29d6c92b..352ea7b81 100644 --- a/packages/grpc-js/src/load-balancer-child-handler.ts +++ b/packages/grpc-js/src/load-balancer-child-handler.ts @@ -25,7 +25,7 @@ import { Endpoint, SubchannelAddress } from './subchannel-address'; import { ChannelOptions } from './channel-options'; import { ConnectivityState } from './connectivity-state'; import { Picker } from './picker'; -import { ChannelRef, SubchannelRef } from './channelz'; +import type { ChannelRef, SubchannelRef } from './channelz'; import { SubchannelInterface } from './subchannel-interface'; const TYPE_NAME = 'child_load_balancer_helper'; diff --git a/packages/grpc-js/src/load-balancer.ts b/packages/grpc-js/src/load-balancer.ts index f8071317a..fb353a59a 100644 --- a/packages/grpc-js/src/load-balancer.ts +++ b/packages/grpc-js/src/load-balancer.ts @@ -19,7 +19,7 @@ import { ChannelOptions } from './channel-options'; import { Endpoint, SubchannelAddress } from './subchannel-address'; import { ConnectivityState } from './connectivity-state'; import { Picker } from './picker'; -import { ChannelRef, SubchannelRef } from './channelz'; +import type { ChannelRef, SubchannelRef } from './channelz'; import { SubchannelInterface } from './subchannel-interface'; import { LoadBalancingConfig } from './service-config'; import { log } from './logging'; diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index 95393fba9..d5aababfa 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -19,12 +19,12 @@ import { EventEmitter } from 'events'; import { Duplex, Readable, Writable } from 'stream'; import { Status } from './constants'; -import { Deserialize, Serialize } from './make-client'; +import type { Deserialize, Serialize } from './make-client'; import { Metadata } from './metadata'; -import { ObjectReadable, ObjectWritable } from './object-stream'; -import { StatusObject, PartialStatusObject } from './call-interface'; -import { Deadline } from './deadline'; -import { ServerInterceptingCallInterface } from './server-interceptors'; +import type { ObjectReadable, ObjectWritable } from './object-stream'; +import type { StatusObject, PartialStatusObject } from './call-interface'; +import type { Deadline } from './deadline'; +import type { ServerInterceptingCallInterface } from './server-interceptors'; export type ServerStatusResponse = Partial; @@ -330,7 +330,7 @@ export interface UnaryHandler { func: handleUnaryCall; serialize: Serialize; deserialize: Deserialize; - type: HandlerType; + type: 'unary'; path: string; } @@ -338,7 +338,7 @@ export interface ClientStreamingHandler { func: handleClientStreamingCall; serialize: Serialize; deserialize: Deserialize; - type: HandlerType; + type: 'clientStream'; path: string; } @@ -346,7 +346,7 @@ export interface ServerStreamingHandler { func: handleServerStreamingCall; serialize: Serialize; deserialize: Deserialize; - type: HandlerType; + type: 'serverStream'; path: string; } @@ -354,7 +354,7 @@ export interface BidiStreamingHandler { func: handleBidiStreamingCall; serialize: Serialize; deserialize: Deserialize; - type: HandlerType; + type: 'bidi'; path: string; } diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 46bd22ead..0a5bc0e9b 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -64,8 +64,11 @@ import { } from './uri-parser'; import { ChannelzCallTracker, + ChannelzCallTrackerStub, ChannelzChildrenTracker, + ChannelzChildrenTrackerStub, ChannelzTrace, + ChannelzTraceStub, registerChannelzServer, registerChannelzSocket, ServerInfo, @@ -87,6 +90,7 @@ import { CallEventTracker } from './transport'; const UNLIMITED_CONNECTION_AGE_MS = ~(1 << 31); const KEEPALIVE_MAX_TIME_MS = ~(1 << 31); const KEEPALIVE_TIMEOUT_MS = 20000; +const MAX_CONNECTION_IDLE_MS = 30 * 60 * 1e3; // 30 min const { HTTP2_HEADER_PATH } = http2.constants; @@ -177,9 +181,10 @@ function getDefaultHandler(handlerType: HandlerType, methodName: string) { interface ChannelzSessionInfo { ref: SocketRef; - streamTracker: ChannelzCallTracker; + streamTracker: ChannelzCallTracker | ChannelzCallTrackerStub; messagesSent: number; messagesReceived: number; + keepAlivesSent: number; lastMessageSentTimestamp: Date | null; lastMessageReceivedTimestamp: Date | null; } @@ -243,6 +248,13 @@ export interface ServerOptions extends ChannelOptions { export class Server { private boundPorts: Map = new Map(); private http2Servers: Map = new Map(); + private sessionIdleTimeouts = new Map< + http2.Http2Session, + { + activeStreams: number; + timeout: NodeJS.Timeout | null; + } + >(); private handlers: Map = new Map< string, @@ -261,10 +273,14 @@ export class Server { // Channelz Info private readonly channelzEnabled: boolean = true; private channelzRef: ServerRef; - private channelzTrace = new ChannelzTrace(); - private callTracker = new ChannelzCallTracker(); - private listenerChildrenTracker = new ChannelzChildrenTracker(); - private sessionChildrenTracker = new ChannelzChildrenTracker(); + private channelzTrace: ChannelzTrace | ChannelzTraceStub; + private callTracker: ChannelzCallTracker | ChannelzCallTrackerStub; + private listenerChildrenTracker: + | ChannelzChildrenTracker + | ChannelzChildrenTrackerStub; + private sessionChildrenTracker: + | ChannelzChildrenTracker + | ChannelzChildrenTrackerStub; private readonly maxConnectionAgeMs: number; private readonly maxConnectionAgeGraceMs: number; @@ -272,6 +288,8 @@ export class Server { private readonly keepaliveTimeMs: number; private readonly keepaliveTimeoutMs: number; + private readonly sessionIdleTimeout: number; + private readonly interceptors: ServerInterceptor[]; /** @@ -284,14 +302,24 @@ export class Server { this.options = options ?? {}; if (this.options['grpc.enable_channelz'] === 0) { this.channelzEnabled = false; + this.channelzTrace = new ChannelzTraceStub(); + this.callTracker = new ChannelzCallTrackerStub(); + this.listenerChildrenTracker = new ChannelzChildrenTrackerStub(); + this.sessionChildrenTracker = new ChannelzChildrenTrackerStub(); + } else { + this.channelzTrace = new ChannelzTrace(); + this.callTracker = new ChannelzCallTracker(); + this.listenerChildrenTracker = new ChannelzChildrenTracker(); + this.sessionChildrenTracker = new ChannelzChildrenTracker(); } + this.channelzRef = registerChannelzServer( + 'server', () => this.getChannelzInfo(), this.channelzEnabled ); - if (this.channelzEnabled) { - this.channelzTrace.addTrace('CT_INFO', 'Server created'); - } + + this.channelzTrace.addTrace('CT_INFO', 'Server created'); this.maxConnectionAgeMs = this.options['grpc.max_connection_age_ms'] ?? UNLIMITED_CONNECTION_AGE_MS; this.maxConnectionAgeGraceMs = @@ -301,6 +329,9 @@ export class Server { this.options['grpc.keepalive_time_ms'] ?? KEEPALIVE_MAX_TIME_MS; this.keepaliveTimeoutMs = this.options['grpc.keepalive_timeout_ms'] ?? KEEPALIVE_TIMEOUT_MS; + this.sessionIdleTimeout = + this.options['grpc.max_connection_idle'] ?? MAX_CONNECTION_IDLE_MS; + this.commonServerOptions = { maxSendHeaderBlockLength: Number.MAX_SAFE_INTEGER, }; @@ -382,7 +413,7 @@ export class Server { streamsFailed: sessionInfo.streamTracker.callsFailed, messagesSent: sessionInfo.messagesSent, messagesReceived: sessionInfo.messagesReceived, - keepAlivesSent: 0, + keepAlivesSent: sessionInfo.keepAlivesSent, lastLocalStreamCreatedTimestamp: null, lastRemoteStreamCreatedTimestamp: sessionInfo.streamTracker.lastCallStartedTimestamp, @@ -581,9 +612,8 @@ export class Server { const channelzRef = this.registerListenerToChannelz( boundSubchannelAddress ); - if (this.channelzEnabled) { - this.listenerChildrenTracker.refChild(channelzRef); - } + this.listenerChildrenTracker.refChild(channelzRef); + this.http2Servers.set(http2Server, { channelzRef: channelzRef, sessions: new Set(), @@ -854,7 +884,7 @@ export class Server { ); const serverInfo = this.http2Servers.get(server); server.close(() => { - if (this.channelzEnabled && serverInfo) { + if (serverInfo) { this.listenerChildrenTracker.unrefChild(serverInfo.channelzRef); unregisterChannelzRef(serverInfo.channelzRef); } @@ -870,15 +900,15 @@ export class Server { this.trace('Closing session initiated by ' + session.socket?.remoteAddress); const sessionInfo = this.sessions.get(session); const closeCallback = () => { - if (this.channelzEnabled && sessionInfo) { + if (sessionInfo) { this.sessionChildrenTracker.unrefChild(sessionInfo.ref); unregisterChannelzRef(sessionInfo.ref); + this.sessions.delete(session); } - this.sessions.delete(session); callback?.(); }; if (session.closed) { - process.nextTick(closeCallback); + queueMicrotask(closeCallback); } else { session.close(closeCallback); } @@ -956,14 +986,13 @@ export class Server { const allSessions: Set = new Set(); for (const http2Server of boundPortObject.listeningServers) { const serverEntry = this.http2Servers.get(http2Server); - if (!serverEntry) { - continue; - } - for (const session of serverEntry.sessions) { - allSessions.add(session); - this.closeSession(session, () => { - allSessions.delete(session); - }); + if (serverEntry) { + for (const session of serverEntry.sessions) { + allSessions.add(session); + this.closeSession(session, () => { + allSessions.delete(session); + }); + } } } /* After the grace time ends, send another goaway to all remaining sessions @@ -995,9 +1024,7 @@ export class Server { session.destroy(http2.constants.NGHTTP2_CANCEL as any); }); this.sessions.clear(); - if (this.channelzEnabled) { - unregisterChannelzRef(this.channelzRef); - } + unregisterChannelzRef(this.channelzRef); this.shutdown = true; } @@ -1049,9 +1076,7 @@ export class Server { tryShutdown(callback: (error?: Error) => void): void { const wrappedCallback = (error?: Error) => { - if (this.channelzEnabled) { - unregisterChannelzRef(this.channelzRef); - } + unregisterChannelzRef(this.channelzRef); callback(error); }; let pendingChecks = 0; @@ -1065,24 +1090,26 @@ export class Server { } this.shutdown = true; - for (const server of this.http2Servers.keys()) { + for (const [serverKey, server] of this.http2Servers.entries()) { pendingChecks++; - const serverString = this.http2Servers.get(server)!.channelzRef.name; + const serverString = server.channelzRef.name; this.trace('Waiting for server ' + serverString + ' to close'); - this.closeServer(server, () => { + this.closeServer(serverKey, () => { this.trace('Server ' + serverString + ' finished closing'); maybeCallback(); }); + + for (const session of server.sessions.keys()) { + pendingChecks++; + const sessionString = session.socket?.remoteAddress; + this.trace('Waiting for session ' + sessionString + ' to close'); + this.closeSession(session, () => { + this.trace('Session ' + sessionString + ' finished closing'); + maybeCallback(); + }); + } } - for (const session of this.sessions.keys()) { - pendingChecks++; - const sessionString = session.socket?.remoteAddress; - this.trace('Waiting for session ' + sessionString + ' to close'); - this.closeSession(session, () => { - this.trace('Session ' + sessionString + ' finished closing'); - maybeCallback(); - }); - } + if (pendingChecks === 0) { wrappedCallback(); } @@ -1160,213 +1187,161 @@ export class Server { }; stream.respond(trailersToSend, { endStream: true }); - if (this.channelzEnabled) { - this.callTracker.addCallFailed(); - channelzSessionInfo?.streamTracker.addCallFailed(); - } + this.callTracker.addCallFailed(); + channelzSessionInfo?.streamTracker.addCallFailed(); } - private _channelzHandler( - stream: http2.ServerHttp2Stream, - headers: http2.IncomingHttpHeaders + private _sessionHandler( + http2Server: http2.Http2Server | http2.Http2SecureServer ) { - const channelzSessionInfo = this.sessions.get( - stream.session as http2.ServerHttp2Session - ); + return (session: http2.ServerHttp2Session) => { + this.http2Servers.get(http2Server)?.sessions.add(session); + + let connectionAgeTimer: NodeJS.Timeout | null = null; + let connectionAgeGraceTimer: NodeJS.Timeout | null = null; + let sessionClosedByServer = false; - this.callTracker.addCallStarted(); - channelzSessionInfo?.streamTracker.addCallStarted(); + const idleTimeoutObj = this.enableIdleTimeout(session); - if (!this._verifyContentType(stream, headers)) { - this.callTracker.addCallFailed(); - channelzSessionInfo?.streamTracker.addCallFailed(); - return; - } + if (this.maxConnectionAgeMs !== UNLIMITED_CONNECTION_AGE_MS) { + // Apply a random jitter within a +/-10% range + const jitterMagnitude = this.maxConnectionAgeMs / 10; + const jitter = Math.random() * jitterMagnitude * 2 - jitterMagnitude; - const path = headers[HTTP2_HEADER_PATH] as string; + connectionAgeTimer = setTimeout(() => { + sessionClosedByServer = true; - const handler = this._retrieveHandler(path); - if (!handler) { - this._respondWithError( - getUnimplementedStatusResponse(path), - stream, - channelzSessionInfo - ); - return; - } + this.trace( + `Connection dropped by max connection age: ${session.socket?.remoteAddress}` + ); - const callEventTracker: CallEventTracker = { - addMessageSent: () => { - if (channelzSessionInfo) { - channelzSessionInfo.messagesSent += 1; - channelzSessionInfo.lastMessageSentTimestamp = new Date(); - } - }, - addMessageReceived: () => { - if (channelzSessionInfo) { - channelzSessionInfo.messagesReceived += 1; - channelzSessionInfo.lastMessageReceivedTimestamp = new Date(); - } - }, - onCallEnd: status => { - if (status.code === Status.OK) { - this.callTracker.addCallSucceeded(); - } else { - this.callTracker.addCallFailed(); - } - }, - onStreamEnd: success => { - if (channelzSessionInfo) { - if (success) { - channelzSessionInfo.streamTracker.addCallSucceeded(); - } else { - channelzSessionInfo.streamTracker.addCallFailed(); + try { + session.goaway( + http2.constants.NGHTTP2_NO_ERROR, + ~(1 << 31), + Buffer.from('max_age') + ); + } catch (e) { + // The goaway can't be sent because the session is already closed + session.destroy(); + return; } - } - }, - }; + session.close(); - const call = getServerInterceptingCall( - this.interceptors, - stream, - headers, - callEventTracker, - handler, - this.options - ); + /* Allow a grace period after sending the GOAWAY before forcibly + * closing the connection. */ + if (this.maxConnectionAgeGraceMs !== UNLIMITED_CONNECTION_AGE_MS) { + connectionAgeGraceTimer = setTimeout(() => { + session.destroy(); + }, this.maxConnectionAgeGraceMs).unref?.(); + } + }, this.maxConnectionAgeMs + jitter).unref?.(); + } - if (!this._runHandlerForCall(call, handler)) { - this.callTracker.addCallFailed(); - channelzSessionInfo?.streamTracker.addCallFailed(); + const keeapliveTimeTimer: NodeJS.Timeout | null = setInterval(() => { + const timeoutTImer = setTimeout(() => { + sessionClosedByServer = true; + session.close(); + }, this.keepaliveTimeoutMs).unref?.(); - call.sendStatus({ - code: Status.INTERNAL, - details: `Unknown handler type: ${handler.type}`, - }); - } - } + try { + session.ping( + (err: Error | null, duration: number, payload: Buffer) => { + clearTimeout(timeoutTImer); - private _streamHandler( - stream: http2.ServerHttp2Stream, - headers: http2.IncomingHttpHeaders - ) { - if (this._verifyContentType(stream, headers) !== true) { - return; - } + if (err) { + sessionClosedByServer = true; + this.trace( + `Connection dropped due to error of a ping frame ${err.message} return in ${duration}` + ); + session.close(); + } + } + ); + } catch (e) { + // The ping can't be sent because the session is already closed + session.destroy(); + } + }, this.keepaliveTimeMs).unref?.(); - const path = headers[HTTP2_HEADER_PATH] as string; + session.on('close', () => { + if (!sessionClosedByServer) { + this.trace( + `Connection dropped by client ${session.socket?.remoteAddress}` + ); + } - const handler = this._retrieveHandler(path); - if (!handler) { - this._respondWithError( - getUnimplementedStatusResponse(path), - stream, - null - ); - return; - } + if (connectionAgeTimer) { + clearTimeout(connectionAgeTimer); + } - const call = getServerInterceptingCall( - this.interceptors, - stream, - headers, - null, - handler, - this.options - ); + if (connectionAgeGraceTimer) { + clearTimeout(connectionAgeGraceTimer); + } - if (!this._runHandlerForCall(call, handler)) { - call.sendStatus({ - code: Status.INTERNAL, - details: `Unknown handler type: ${handler.type}`, - }); - } - } + if (keeapliveTimeTimer) { + clearTimeout(keeapliveTimeTimer); + } - private _runHandlerForCall( - call: ServerInterceptingCallInterface, - handler: Handler - ): boolean { - const { type } = handler; - if (type === 'unary') { - handleUnary(call, handler as UntypedUnaryHandler); - } else if (type === 'clientStream') { - handleClientStreaming(call, handler as UntypedClientStreamingHandler); - } else if (type === 'serverStream') { - handleServerStreaming(call, handler as UntypedServerStreamingHandler); - } else if (type === 'bidi') { - handleBidiStreaming(call, handler as UntypedBidiStreamingHandler); - } else { - return false; - } + clearTimeout(idleTimeoutObj.timeout); + this.sessionIdleTimeouts.delete(session); - return true; + this.http2Servers.get(http2Server)?.sessions.delete(session); + }); + }; } - private _setupHandlers( + private _channelzSessionHandler( http2Server: http2.Http2Server | http2.Http2SecureServer - ): void { - if (http2Server === null) { - return; - } - - const serverAddress = http2Server.address(); - let serverAddressString = 'null'; - if (serverAddress) { - if (typeof serverAddress === 'string') { - serverAddressString = serverAddress; - } else { - serverAddressString = serverAddress.address + ':' + serverAddress.port; - } - } - this.serverAddressString = serverAddressString; - - const handler = this.channelzEnabled - ? this._channelzHandler - : this._streamHandler; - - http2Server.on('stream', handler.bind(this)); - http2Server.on('session', session => { + ) { + return (session: http2.ServerHttp2Session) => { const channelzRef = registerChannelzSocket( - session.socket.remoteAddress ?? 'unknown', + session.socket?.remoteAddress ?? 'unknown', this.getChannelzSessionInfoGetter(session), this.channelzEnabled ); const channelzSessionInfo: ChannelzSessionInfo = { ref: channelzRef, - streamTracker: new ChannelzCallTracker(), + streamTracker: this.channelzEnabled + ? new ChannelzCallTracker() + : new ChannelzCallTrackerStub(), messagesSent: 0, messagesReceived: 0, + keepAlivesSent: 0, lastMessageSentTimestamp: null, lastMessageReceivedTimestamp: null, }; this.http2Servers.get(http2Server)?.sessions.add(session); this.sessions.set(session, channelzSessionInfo); - const clientAddress = session.socket.remoteAddress; - if (this.channelzEnabled) { - this.channelzTrace.addTrace( - 'CT_INFO', - 'Connection established by client ' + clientAddress - ); - this.sessionChildrenTracker.refChild(channelzRef); - } + const clientAddress = `${session.socket.remoteAddress}:${session.socket.remotePort}`; + + this.channelzTrace.addTrace( + 'CT_INFO', + 'Connection established by client ' + clientAddress + ); + this.trace('Connection established by client ' + clientAddress); + this.sessionChildrenTracker.refChild(channelzRef); + let connectionAgeTimer: NodeJS.Timeout | null = null; let connectionAgeGraceTimer: NodeJS.Timeout | null = null; let sessionClosedByServer = false; + + const idleTimeoutObj = this.enableIdleTimeout(session); + if (this.maxConnectionAgeMs !== UNLIMITED_CONNECTION_AGE_MS) { // Apply a random jitter within a +/-10% range const jitterMagnitude = this.maxConnectionAgeMs / 10; const jitter = Math.random() * jitterMagnitude * 2 - jitterMagnitude; + connectionAgeTimer = setTimeout(() => { sessionClosedByServer = true; - if (this.channelzEnabled) { - this.channelzTrace.addTrace( - 'CT_INFO', - 'Connection dropped by max connection age from ' + clientAddress - ); - } + this.channelzTrace.addTrace( + 'CT_INFO', + 'Connection dropped by max connection age from ' + clientAddress + ); + try { session.goaway( http2.constants.NGHTTP2_NO_ERROR, @@ -1379,6 +1354,7 @@ export class Server { return; } session.close(); + /* Allow a grace period after sending the GOAWAY before forcibly * closing the connection. */ if (this.maxConnectionAgeGraceMs !== UNLIMITED_CONNECTION_AGE_MS) { @@ -1388,52 +1364,316 @@ export class Server { } }, this.maxConnectionAgeMs + jitter).unref?.(); } + const keeapliveTimeTimer: NodeJS.Timeout | null = setInterval(() => { const timeoutTImer = setTimeout(() => { sessionClosedByServer = true; - if (this.channelzEnabled) { - this.channelzTrace.addTrace( - 'CT_INFO', - 'Connection dropped by keepalive timeout from ' + clientAddress - ); - } + this.channelzTrace.addTrace( + 'CT_INFO', + 'Connection dropped by keepalive timeout from ' + clientAddress + ); + session.close(); }, this.keepaliveTimeoutMs).unref?.(); try { session.ping( (err: Error | null, duration: number, payload: Buffer) => { clearTimeout(timeoutTImer); + + if (err) { + sessionClosedByServer = true; + this.channelzTrace.addTrace( + 'CT_INFO', + `Connection dropped due to error of a ping frame ${err.message} return in ${duration}` + ); + + session.close(); + } } ); + channelzSessionInfo.keepAlivesSent += 1; } catch (e) { // The ping can't be sent because the session is already closed session.destroy(); } }, this.keepaliveTimeMs).unref?.(); + session.on('close', () => { - if (this.channelzEnabled) { - if (!sessionClosedByServer) { - this.channelzTrace.addTrace( - 'CT_INFO', - 'Connection dropped by client ' + clientAddress - ); - } - this.sessionChildrenTracker.unrefChild(channelzRef); - unregisterChannelzRef(channelzRef); + if (!sessionClosedByServer) { + this.channelzTrace.addTrace( + 'CT_INFO', + 'Connection dropped by client ' + clientAddress + ); } + this.trace( + `DROPPING ${channelzRef.name} - ${channelzRef.kind} - ${channelzRef.id}` + ); + this.sessionChildrenTracker.unrefChild(channelzRef); + unregisterChannelzRef(channelzRef); + if (connectionAgeTimer) { clearTimeout(connectionAgeTimer); } + if (connectionAgeGraceTimer) { clearTimeout(connectionAgeGraceTimer); } + if (keeapliveTimeTimer) { clearTimeout(keeapliveTimeTimer); } + + clearTimeout(idleTimeoutObj.timeout); + this.sessionIdleTimeouts.delete(session); + this.http2Servers.get(http2Server)?.sessions.delete(session); this.sessions.delete(session); }); - }); + }; + } + + private _channelzHandler(http2Server: http2.Http2Server) { + return ( + stream: http2.ServerHttp2Stream, + headers: http2.IncomingHttpHeaders + ) => { + // for handling idle timeout + this.onStreamOpened(stream); + + const channelzSessionInfo = this.sessions.get( + stream.session as http2.ServerHttp2Session + ); + + this.callTracker.addCallStarted(); + channelzSessionInfo?.streamTracker.addCallStarted(); + + if (!this._verifyContentType(stream, headers)) { + this.callTracker.addCallFailed(); + channelzSessionInfo?.streamTracker.addCallFailed(); + return; + } + + const path = headers[HTTP2_HEADER_PATH] as string; + + const handler = this._retrieveHandler(path); + if (!handler) { + this._respondWithError( + getUnimplementedStatusResponse(path), + stream, + channelzSessionInfo + ); + return; + } + + const callEventTracker: CallEventTracker = { + addMessageSent: () => { + if (channelzSessionInfo) { + channelzSessionInfo.messagesSent += 1; + channelzSessionInfo.lastMessageSentTimestamp = new Date(); + } + }, + addMessageReceived: () => { + if (channelzSessionInfo) { + channelzSessionInfo.messagesReceived += 1; + channelzSessionInfo.lastMessageReceivedTimestamp = new Date(); + } + }, + onCallEnd: status => { + if (status.code === Status.OK) { + this.callTracker.addCallSucceeded(); + } else { + this.callTracker.addCallFailed(); + } + }, + onStreamEnd: success => { + if (channelzSessionInfo) { + if (success) { + channelzSessionInfo.streamTracker.addCallSucceeded(); + } else { + channelzSessionInfo.streamTracker.addCallFailed(); + } + } + }, + }; + + const call = getServerInterceptingCall( + this.interceptors, + stream, + headers, + callEventTracker, + handler, + this.options + ); + + if (!this._runHandlerForCall(call, handler)) { + this.callTracker.addCallFailed(); + channelzSessionInfo?.streamTracker.addCallFailed(); + + call.sendStatus({ + code: Status.INTERNAL, + details: `Unknown handler type: ${handler.type}`, + }); + } + }; + } + + private _streamHandler(http2Server: http2.Http2Server) { + return ( + stream: http2.ServerHttp2Stream, + headers: http2.IncomingHttpHeaders + ) => { + // for handling idle timeout + this.onStreamOpened(stream); + + if (this._verifyContentType(stream, headers) !== true) { + return; + } + + const path = headers[HTTP2_HEADER_PATH] as string; + + const handler = this._retrieveHandler(path); + if (!handler) { + this._respondWithError( + getUnimplementedStatusResponse(path), + stream, + null + ); + return; + } + + const call = getServerInterceptingCall( + this.interceptors, + stream, + headers, + null, + handler, + this.options + ); + + if (!this._runHandlerForCall(call, handler)) { + call.sendStatus({ + code: Status.INTERNAL, + details: `Unknown handler type: ${handler.type}`, + }); + } + }; + } + + private _runHandlerForCall( + call: ServerInterceptingCallInterface, + handler: + | UntypedUnaryHandler + | UntypedClientStreamingHandler + | UntypedServerStreamingHandler + | UntypedBidiStreamingHandler + ): boolean { + const { type } = handler; + if (type === 'unary') { + handleUnary(call, handler); + } else if (type === 'clientStream') { + handleClientStreaming(call, handler); + } else if (type === 'serverStream') { + handleServerStreaming(call, handler); + } else if (type === 'bidi') { + handleBidiStreaming(call, handler); + } else { + return false; + } + + return true; + } + + private _setupHandlers( + http2Server: http2.Http2Server | http2.Http2SecureServer + ): void { + if (http2Server === null) { + return; + } + + const serverAddress = http2Server.address(); + let serverAddressString = 'null'; + if (serverAddress) { + if (typeof serverAddress === 'string') { + serverAddressString = serverAddress; + } else { + serverAddressString = serverAddress.address + ':' + serverAddress.port; + } + } + this.serverAddressString = serverAddressString; + + const handler = this.channelzEnabled + ? this._channelzHandler(http2Server) + : this._streamHandler(http2Server); + + const sessionHandler = this.channelzEnabled + ? this._channelzSessionHandler(http2Server) + : this._sessionHandler(http2Server); + + http2Server.on('stream', handler); + http2Server.on('session', sessionHandler); + } + + private enableIdleTimeout(session: http2.ServerHttp2Session) { + const idleTimeoutObj = { + activeStreams: 0, + timeout: setTimeout( + this.onIdleTimeout, + this.sessionIdleTimeout, + this, + session + ).unref(), + }; + this.sessionIdleTimeouts.set(session, idleTimeoutObj); + + this.trace(`Enable idle timeout for ${session.socket?.remoteAddress}`); + + return idleTimeoutObj; + } + + private onIdleTimeout(ctx: Server, session: http2.ServerHttp2Session) { + ctx.trace(`Idle timeout for ${session.socket?.remoteAddress}`); + ctx.closeSession(session); + } + + private onStreamOpened(stream: http2.ServerHttp2Stream) { + const session = stream.session as http2.ServerHttp2Session; + this.trace(`Stream opened for ${session.socket?.remoteAddress}`); + const idleTimeoutObj = this.sessionIdleTimeouts.get(session); + if (idleTimeoutObj) { + idleTimeoutObj.activeStreams += 1; + if (idleTimeoutObj.timeout) { + clearTimeout(idleTimeoutObj.timeout); + idleTimeoutObj.timeout = null; + } + + this.trace( + `onStreamOpened: adding on stream close event for ${session.socket?.remoteAddress}` + ); + stream.once('close', () => this.onStreamClose(session)); + } else { + this.trace( + `onStreamOpened: missing stream for ${session.socket?.remoteAddress}` + ); + } + } + + private onStreamClose(session: http2.ServerHttp2Session) { + this.trace(`Stream closed for ${session.socket?.remoteAddress}`); + const idleTimeoutObj = this.sessionIdleTimeouts.get(session); + if (idleTimeoutObj) { + idleTimeoutObj.activeStreams -= 1; + if (idleTimeoutObj.activeStreams === 0) { + this.trace( + `onStreamClose: set idle timeout for ${this.sessionIdleTimeout}ms ${session.socket?.remoteAddress}` + ); + idleTimeoutObj.timeout = setTimeout( + this.onIdleTimeout, + this.sessionIdleTimeout, + this, + session + ).unref(); + } + } } } diff --git a/packages/grpc-js/src/subchannel-interface.ts b/packages/grpc-js/src/subchannel-interface.ts index c26669ba3..6c314189a 100644 --- a/packages/grpc-js/src/subchannel-interface.ts +++ b/packages/grpc-js/src/subchannel-interface.ts @@ -15,7 +15,7 @@ * */ -import { SubchannelRef } from './channelz'; +import type { SubchannelRef } from './channelz'; import { ConnectivityState } from './connectivity-state'; import { Subchannel } from './subchannel'; diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 63e254cf3..95b600c4c 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -31,10 +31,13 @@ import { SubchannelRef, ChannelzTrace, ChannelzChildrenTracker, + ChannelzChildrenTrackerStub, SubchannelInfo, registerChannelzSubchannel, ChannelzCallTracker, + ChannelzCallTrackerStub, unregisterChannelzRef, + ChannelzTraceStub, } from './channelz'; import { ConnectivityStateListener, @@ -89,12 +92,15 @@ export class Subchannel { // Channelz info private readonly channelzEnabled: boolean = true; private channelzRef: SubchannelRef; - private channelzTrace: ChannelzTrace; - private callTracker = new ChannelzCallTracker(); - private childrenTracker = new ChannelzChildrenTracker(); + + private channelzTrace: ChannelzTrace | ChannelzTraceStub; + private callTracker: ChannelzCallTracker | ChannelzCallTrackerStub; + private childrenTracker: + | ChannelzChildrenTracker + | ChannelzChildrenTrackerStub; // Channelz socket info - private streamTracker = new ChannelzCallTracker(); + private streamTracker: ChannelzCallTracker | ChannelzCallTrackerStub; /** * A class representing a connection to a single backend. @@ -127,16 +133,24 @@ export class Subchannel { if (options['grpc.enable_channelz'] === 0) { this.channelzEnabled = false; + this.channelzTrace = new ChannelzTraceStub(); + this.callTracker = new ChannelzCallTrackerStub(); + this.childrenTracker = new ChannelzChildrenTrackerStub(); + this.streamTracker = new ChannelzCallTrackerStub(); + } else { + this.channelzTrace = new ChannelzTrace(); + this.callTracker = new ChannelzCallTracker(); + this.childrenTracker = new ChannelzChildrenTracker(); + this.streamTracker = new ChannelzCallTracker(); } - this.channelzTrace = new ChannelzTrace(); + this.channelzRef = registerChannelzSubchannel( this.subchannelAddressString, () => this.getChannelzInfo(), this.channelzEnabled ); - if (this.channelzEnabled) { - this.channelzTrace.addTrace('CT_INFO', 'Subchannel created'); - } + + this.channelzTrace.addTrace('CT_INFO', 'Subchannel created'); this.trace( 'Subchannel constructed with options ' + JSON.stringify(options, undefined, 2) @@ -338,12 +352,8 @@ export class Subchannel { this.refTrace('refcount ' + this.refcount + ' -> ' + (this.refcount - 1)); this.refcount -= 1; if (this.refcount === 0) { - if (this.channelzEnabled) { - this.channelzTrace.addTrace('CT_INFO', 'Shutting down'); - } - if (this.channelzEnabled) { - unregisterChannelzRef(this.channelzRef); - } + this.channelzTrace.addTrace('CT_INFO', 'Shutting down'); + unregisterChannelzRef(this.channelzRef); process.nextTick(() => { this.transitionToState( [ConnectivityState.CONNECTING, ConnectivityState.READY], diff --git a/packages/grpc-js/src/transport.ts b/packages/grpc-js/src/transport.ts index c4941b068..620488635 100644 --- a/packages/grpc-js/src/transport.ts +++ b/packages/grpc-js/src/transport.ts @@ -28,6 +28,7 @@ import { ChannelCredentials } from './channel-credentials'; import { ChannelOptions } from './channel-options'; import { ChannelzCallTracker, + ChannelzCallTrackerStub, registerChannelzSocket, SocketInfo, SocketRef, @@ -136,7 +137,7 @@ class Http2Transport implements Transport { // Channelz info private channelzRef: SocketRef; private readonly channelzEnabled: boolean = true; - private streamTracker = new ChannelzCallTracker(); + private streamTracker: ChannelzCallTracker | ChannelzCallTrackerStub; private keepalivesSent = 0; private messagesSent = 0; private messagesReceived = 0; @@ -159,12 +160,17 @@ class Http2Transport implements Transport { if (options['grpc.enable_channelz'] === 0) { this.channelzEnabled = false; + this.streamTracker = new ChannelzCallTrackerStub(); + } else { + this.streamTracker = new ChannelzCallTracker(); } + this.channelzRef = registerChannelzSocket( this.subchannelAddressString, () => this.getChannelzInfo(), this.channelzEnabled ); + // Build user-agent string. this.userAgent = [ options['grpc.primary_user_agent'], @@ -192,6 +198,7 @@ class Http2Transport implements Transport { this.stopKeepalivePings(); this.handleDisconnect(); }); + session.once( 'goaway', (errorCode: number, lastStreamID: number, opaqueData?: Buffer) => { @@ -214,11 +221,13 @@ class Http2Transport implements Transport { this.reportDisconnectToOwner(tooManyPings); } ); + session.once('error', error => { /* Do nothing here. Any error should also trigger a close event, which is * where we want to handle that. */ this.trace('connection closed with error ' + (error as Error).message); }); + if (logging.isTracerEnabled(TRACER_NAME)) { session.on('remoteSettings', (settings: http2.Settings) => { this.trace( @@ -237,6 +246,7 @@ class Http2Transport implements Transport { ); }); } + /* Start the keepalive timer last, because this can trigger trace logs, * which should only happen after everything else is set up. */ if (this.keepaliveWithoutCalls) { @@ -625,6 +635,7 @@ export class Http2SubchannelConnector implements SubchannelConnector { private session: http2.ClientHttp2Session | null = null; private isShutdown = false; constructor(private channelTarget: GrpcUri) {} + private trace(text: string) { logging.trace( LogVerbosity.DEBUG, @@ -632,6 +643,7 @@ export class Http2SubchannelConnector implements SubchannelConnector { uriToString(this.channelTarget) + ' ' + text ); } + private createSession( address: SubchannelAddress, credentials: ChannelCredentials, @@ -641,6 +653,7 @@ export class Http2SubchannelConnector implements SubchannelConnector { if (this.isShutdown) { return Promise.reject(); } + return new Promise((resolve, reject) => { let remoteName: string | null; if (proxyConnectionResult.realTarget) { @@ -767,6 +780,7 @@ export class Http2SubchannelConnector implements SubchannelConnector { }); }); } + connect( address: SubchannelAddress, credentials: ChannelCredentials, diff --git a/packages/grpc-js/test/common.ts b/packages/grpc-js/test/common.ts index 88aa129aa..eaa701f18 100644 --- a/packages/grpc-js/test/common.ts +++ b/packages/grpc-js/test/common.ts @@ -31,7 +31,7 @@ import { HealthListener, SubchannelInterface, } from '../src/subchannel-interface'; -import { SubchannelRef } from '../src/channelz'; +import { EntityTypes, SubchannelRef } from '../src/channelz'; import { Subchannel } from '../src/subchannel'; import { ConnectivityState } from '../src/connectivity-state'; @@ -196,7 +196,7 @@ export class MockSubchannel implements SubchannelInterface { unref(): void {} getChannelzRef(): SubchannelRef { return { - kind: 'subchannel', + kind: EntityTypes.subchannel, id: -1, name: this.address, }; From a4a676d3788976ef3e8bb1049f37b971eb8d8d4d Mon Sep 17 00:00:00 2001 From: AVVS Date: Tue, 27 Feb 2024 14:17:32 -0800 Subject: [PATCH 03/55] chore: move new functions towards the end of the class --- packages/grpc-js/src/server.ts | 362 ++++++++++++++++----------------- 1 file changed, 181 insertions(+), 181 deletions(-) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 0a5bc0e9b..1229b8c6c 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -1191,6 +1191,187 @@ export class Server { channelzSessionInfo?.streamTracker.addCallFailed(); } + private _channelzHandler(http2Server: http2.Http2Server) { + return ( + stream: http2.ServerHttp2Stream, + headers: http2.IncomingHttpHeaders + ) => { + // for handling idle timeout + this.onStreamOpened(stream); + + const channelzSessionInfo = this.sessions.get( + stream.session as http2.ServerHttp2Session + ); + + this.callTracker.addCallStarted(); + channelzSessionInfo?.streamTracker.addCallStarted(); + + if (!this._verifyContentType(stream, headers)) { + this.callTracker.addCallFailed(); + channelzSessionInfo?.streamTracker.addCallFailed(); + return; + } + + const path = headers[HTTP2_HEADER_PATH] as string; + + const handler = this._retrieveHandler(path); + if (!handler) { + this._respondWithError( + getUnimplementedStatusResponse(path), + stream, + channelzSessionInfo + ); + return; + } + + const callEventTracker: CallEventTracker = { + addMessageSent: () => { + if (channelzSessionInfo) { + channelzSessionInfo.messagesSent += 1; + channelzSessionInfo.lastMessageSentTimestamp = new Date(); + } + }, + addMessageReceived: () => { + if (channelzSessionInfo) { + channelzSessionInfo.messagesReceived += 1; + channelzSessionInfo.lastMessageReceivedTimestamp = new Date(); + } + }, + onCallEnd: status => { + if (status.code === Status.OK) { + this.callTracker.addCallSucceeded(); + } else { + this.callTracker.addCallFailed(); + } + }, + onStreamEnd: success => { + if (channelzSessionInfo) { + if (success) { + channelzSessionInfo.streamTracker.addCallSucceeded(); + } else { + channelzSessionInfo.streamTracker.addCallFailed(); + } + } + }, + }; + + const call = getServerInterceptingCall( + this.interceptors, + stream, + headers, + callEventTracker, + handler, + this.options + ); + + if (!this._runHandlerForCall(call, handler)) { + this.callTracker.addCallFailed(); + channelzSessionInfo?.streamTracker.addCallFailed(); + + call.sendStatus({ + code: Status.INTERNAL, + details: `Unknown handler type: ${handler.type}`, + }); + } + }; + } + + private _streamHandler(http2Server: http2.Http2Server) { + return ( + stream: http2.ServerHttp2Stream, + headers: http2.IncomingHttpHeaders + ) => { + // for handling idle timeout + this.onStreamOpened(stream); + + if (this._verifyContentType(stream, headers) !== true) { + return; + } + + const path = headers[HTTP2_HEADER_PATH] as string; + + const handler = this._retrieveHandler(path); + if (!handler) { + this._respondWithError( + getUnimplementedStatusResponse(path), + stream, + null + ); + return; + } + + const call = getServerInterceptingCall( + this.interceptors, + stream, + headers, + null, + handler, + this.options + ); + + if (!this._runHandlerForCall(call, handler)) { + call.sendStatus({ + code: Status.INTERNAL, + details: `Unknown handler type: ${handler.type}`, + }); + } + }; + } + + private _runHandlerForCall( + call: ServerInterceptingCallInterface, + handler: + | UntypedUnaryHandler + | UntypedClientStreamingHandler + | UntypedServerStreamingHandler + | UntypedBidiStreamingHandler + ): boolean { + const { type } = handler; + if (type === 'unary') { + handleUnary(call, handler); + } else if (type === 'clientStream') { + handleClientStreaming(call, handler); + } else if (type === 'serverStream') { + handleServerStreaming(call, handler); + } else if (type === 'bidi') { + handleBidiStreaming(call, handler); + } else { + return false; + } + + return true; + } + + private _setupHandlers( + http2Server: http2.Http2Server | http2.Http2SecureServer + ): void { + if (http2Server === null) { + return; + } + + const serverAddress = http2Server.address(); + let serverAddressString = 'null'; + if (serverAddress) { + if (typeof serverAddress === 'string') { + serverAddressString = serverAddress; + } else { + serverAddressString = serverAddress.address + ':' + serverAddress.port; + } + } + this.serverAddressString = serverAddressString; + + const handler = this.channelzEnabled + ? this._channelzHandler(http2Server) + : this._streamHandler(http2Server); + + const sessionHandler = this.channelzEnabled + ? this._channelzSessionHandler(http2Server) + : this._sessionHandler(http2Server); + + http2Server.on('stream', handler); + http2Server.on('session', sessionHandler); + } + private _sessionHandler( http2Server: http2.Http2Server | http2.Http2SecureServer ) { @@ -1432,187 +1613,6 @@ export class Server { }; } - private _channelzHandler(http2Server: http2.Http2Server) { - return ( - stream: http2.ServerHttp2Stream, - headers: http2.IncomingHttpHeaders - ) => { - // for handling idle timeout - this.onStreamOpened(stream); - - const channelzSessionInfo = this.sessions.get( - stream.session as http2.ServerHttp2Session - ); - - this.callTracker.addCallStarted(); - channelzSessionInfo?.streamTracker.addCallStarted(); - - if (!this._verifyContentType(stream, headers)) { - this.callTracker.addCallFailed(); - channelzSessionInfo?.streamTracker.addCallFailed(); - return; - } - - const path = headers[HTTP2_HEADER_PATH] as string; - - const handler = this._retrieveHandler(path); - if (!handler) { - this._respondWithError( - getUnimplementedStatusResponse(path), - stream, - channelzSessionInfo - ); - return; - } - - const callEventTracker: CallEventTracker = { - addMessageSent: () => { - if (channelzSessionInfo) { - channelzSessionInfo.messagesSent += 1; - channelzSessionInfo.lastMessageSentTimestamp = new Date(); - } - }, - addMessageReceived: () => { - if (channelzSessionInfo) { - channelzSessionInfo.messagesReceived += 1; - channelzSessionInfo.lastMessageReceivedTimestamp = new Date(); - } - }, - onCallEnd: status => { - if (status.code === Status.OK) { - this.callTracker.addCallSucceeded(); - } else { - this.callTracker.addCallFailed(); - } - }, - onStreamEnd: success => { - if (channelzSessionInfo) { - if (success) { - channelzSessionInfo.streamTracker.addCallSucceeded(); - } else { - channelzSessionInfo.streamTracker.addCallFailed(); - } - } - }, - }; - - const call = getServerInterceptingCall( - this.interceptors, - stream, - headers, - callEventTracker, - handler, - this.options - ); - - if (!this._runHandlerForCall(call, handler)) { - this.callTracker.addCallFailed(); - channelzSessionInfo?.streamTracker.addCallFailed(); - - call.sendStatus({ - code: Status.INTERNAL, - details: `Unknown handler type: ${handler.type}`, - }); - } - }; - } - - private _streamHandler(http2Server: http2.Http2Server) { - return ( - stream: http2.ServerHttp2Stream, - headers: http2.IncomingHttpHeaders - ) => { - // for handling idle timeout - this.onStreamOpened(stream); - - if (this._verifyContentType(stream, headers) !== true) { - return; - } - - const path = headers[HTTP2_HEADER_PATH] as string; - - const handler = this._retrieveHandler(path); - if (!handler) { - this._respondWithError( - getUnimplementedStatusResponse(path), - stream, - null - ); - return; - } - - const call = getServerInterceptingCall( - this.interceptors, - stream, - headers, - null, - handler, - this.options - ); - - if (!this._runHandlerForCall(call, handler)) { - call.sendStatus({ - code: Status.INTERNAL, - details: `Unknown handler type: ${handler.type}`, - }); - } - }; - } - - private _runHandlerForCall( - call: ServerInterceptingCallInterface, - handler: - | UntypedUnaryHandler - | UntypedClientStreamingHandler - | UntypedServerStreamingHandler - | UntypedBidiStreamingHandler - ): boolean { - const { type } = handler; - if (type === 'unary') { - handleUnary(call, handler); - } else if (type === 'clientStream') { - handleClientStreaming(call, handler); - } else if (type === 'serverStream') { - handleServerStreaming(call, handler); - } else if (type === 'bidi') { - handleBidiStreaming(call, handler); - } else { - return false; - } - - return true; - } - - private _setupHandlers( - http2Server: http2.Http2Server | http2.Http2SecureServer - ): void { - if (http2Server === null) { - return; - } - - const serverAddress = http2Server.address(); - let serverAddressString = 'null'; - if (serverAddress) { - if (typeof serverAddress === 'string') { - serverAddressString = serverAddress; - } else { - serverAddressString = serverAddress.address + ':' + serverAddress.port; - } - } - this.serverAddressString = serverAddressString; - - const handler = this.channelzEnabled - ? this._channelzHandler(http2Server) - : this._streamHandler(http2Server); - - const sessionHandler = this.channelzEnabled - ? this._channelzSessionHandler(http2Server) - : this._sessionHandler(http2Server); - - http2Server.on('stream', handler); - http2Server.on('session', sessionHandler); - } - private enableIdleTimeout(session: http2.ServerHttp2Session) { const idleTimeoutObj = { activeStreams: 0, From b8f157ed21add2daffe11e320781e345d7cc38fb Mon Sep 17 00:00:00 2001 From: AVVS Date: Tue, 27 Feb 2024 14:30:55 -0800 Subject: [PATCH 04/55] chore: revert interface -> type change in channelz --- packages/grpc-js/src/channelz.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/grpc-js/src/channelz.ts b/packages/grpc-js/src/channelz.ts index 6d70b7543..4eab762a8 100644 --- a/packages/grpc-js/src/channelz.ts +++ b/packages/grpc-js/src/channelz.ts @@ -330,25 +330,25 @@ export interface SocketInfo { remoteFlowControlWindow: number | null; } -type ChannelEntry = { +interface ChannelEntry { ref: ChannelRef; getInfo(): ChannelInfo; -}; +} -type SubchannelEntry = { +interface SubchannelEntry { ref: SubchannelRef; getInfo(): SubchannelInfo; -}; +} -type ServerEntry = { +interface ServerEntry { ref: ServerRef; getInfo(): ServerInfo; -}; +} -type SocketEntry = { +interface SocketEntry { ref: SocketRef; getInfo(): SocketInfo; -}; +} export const enum EntityTypes { channel = 'channel', From 0b79b7420a77564babca5e8718ef95c6aedbea71 Mon Sep 17 00:00:00 2001 From: AVVS Date: Tue, 27 Feb 2024 14:35:02 -0800 Subject: [PATCH 05/55] chore: cleanup traces --- packages/grpc-js/src/server.ts | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 1229b8c6c..67b5fdf73 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -1586,9 +1586,7 @@ export class Server { 'Connection dropped by client ' + clientAddress ); } - this.trace( - `DROPPING ${channelzRef.name} - ${channelzRef.kind} - ${channelzRef.id}` - ); + this.sessionChildrenTracker.unrefChild(channelzRef); unregisterChannelzRef(channelzRef); @@ -1637,7 +1635,7 @@ export class Server { private onStreamOpened(stream: http2.ServerHttp2Stream) { const session = stream.session as http2.ServerHttp2Session; - this.trace(`Stream opened for ${session.socket?.remoteAddress}`); + const idleTimeoutObj = this.sessionIdleTimeouts.get(session); if (idleTimeoutObj) { idleTimeoutObj.activeStreams += 1; @@ -1646,26 +1644,16 @@ export class Server { idleTimeoutObj.timeout = null; } - this.trace( - `onStreamOpened: adding on stream close event for ${session.socket?.remoteAddress}` - ); stream.once('close', () => this.onStreamClose(session)); - } else { - this.trace( - `onStreamOpened: missing stream for ${session.socket?.remoteAddress}` - ); } } private onStreamClose(session: http2.ServerHttp2Session) { - this.trace(`Stream closed for ${session.socket?.remoteAddress}`); const idleTimeoutObj = this.sessionIdleTimeouts.get(session); + if (idleTimeoutObj) { idleTimeoutObj.activeStreams -= 1; if (idleTimeoutObj.activeStreams === 0) { - this.trace( - `onStreamClose: set idle timeout for ${this.sessionIdleTimeout}ms ${session.socket?.remoteAddress}` - ); idleTimeoutObj.timeout = setTimeout( this.onIdleTimeout, this.sessionIdleTimeout, From 74102fcc872759d18a62cf5098256eb521064b0c Mon Sep 17 00:00:00 2001 From: AVVS Date: Tue, 27 Feb 2024 14:39:24 -0800 Subject: [PATCH 06/55] chore: extraneous closure, dont need server ref --- packages/grpc-js/src/server.ts | 216 ++++++++++++++++----------------- 1 file changed, 106 insertions(+), 110 deletions(-) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 67b5fdf73..eed097f83 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -1191,131 +1191,127 @@ export class Server { channelzSessionInfo?.streamTracker.addCallFailed(); } - private _channelzHandler(http2Server: http2.Http2Server) { - return ( - stream: http2.ServerHttp2Stream, - headers: http2.IncomingHttpHeaders - ) => { - // for handling idle timeout - this.onStreamOpened(stream); - - const channelzSessionInfo = this.sessions.get( - stream.session as http2.ServerHttp2Session - ); + private _channelzHandler( + stream: http2.ServerHttp2Stream, + headers: http2.IncomingHttpHeaders + ) { + // for handling idle timeout + this.onStreamOpened(stream); - this.callTracker.addCallStarted(); - channelzSessionInfo?.streamTracker.addCallStarted(); + const channelzSessionInfo = this.sessions.get( + stream.session as http2.ServerHttp2Session + ); - if (!this._verifyContentType(stream, headers)) { - this.callTracker.addCallFailed(); - channelzSessionInfo?.streamTracker.addCallFailed(); - return; - } + this.callTracker.addCallStarted(); + channelzSessionInfo?.streamTracker.addCallStarted(); - const path = headers[HTTP2_HEADER_PATH] as string; + if (!this._verifyContentType(stream, headers)) { + this.callTracker.addCallFailed(); + channelzSessionInfo?.streamTracker.addCallFailed(); + return; + } - const handler = this._retrieveHandler(path); - if (!handler) { - this._respondWithError( - getUnimplementedStatusResponse(path), - stream, - channelzSessionInfo - ); - return; - } + const path = headers[HTTP2_HEADER_PATH] as string; - const callEventTracker: CallEventTracker = { - addMessageSent: () => { - if (channelzSessionInfo) { - channelzSessionInfo.messagesSent += 1; - channelzSessionInfo.lastMessageSentTimestamp = new Date(); - } - }, - addMessageReceived: () => { - if (channelzSessionInfo) { - channelzSessionInfo.messagesReceived += 1; - channelzSessionInfo.lastMessageReceivedTimestamp = new Date(); - } - }, - onCallEnd: status => { - if (status.code === Status.OK) { - this.callTracker.addCallSucceeded(); + const handler = this._retrieveHandler(path); + if (!handler) { + this._respondWithError( + getUnimplementedStatusResponse(path), + stream, + channelzSessionInfo + ); + return; + } + + const callEventTracker: CallEventTracker = { + addMessageSent: () => { + if (channelzSessionInfo) { + channelzSessionInfo.messagesSent += 1; + channelzSessionInfo.lastMessageSentTimestamp = new Date(); + } + }, + addMessageReceived: () => { + if (channelzSessionInfo) { + channelzSessionInfo.messagesReceived += 1; + channelzSessionInfo.lastMessageReceivedTimestamp = new Date(); + } + }, + onCallEnd: status => { + if (status.code === Status.OK) { + this.callTracker.addCallSucceeded(); + } else { + this.callTracker.addCallFailed(); + } + }, + onStreamEnd: success => { + if (channelzSessionInfo) { + if (success) { + channelzSessionInfo.streamTracker.addCallSucceeded(); } else { - this.callTracker.addCallFailed(); - } - }, - onStreamEnd: success => { - if (channelzSessionInfo) { - if (success) { - channelzSessionInfo.streamTracker.addCallSucceeded(); - } else { - channelzSessionInfo.streamTracker.addCallFailed(); - } + channelzSessionInfo.streamTracker.addCallFailed(); } - }, - }; + } + }, + }; - const call = getServerInterceptingCall( - this.interceptors, - stream, - headers, - callEventTracker, - handler, - this.options - ); + const call = getServerInterceptingCall( + this.interceptors, + stream, + headers, + callEventTracker, + handler, + this.options + ); - if (!this._runHandlerForCall(call, handler)) { - this.callTracker.addCallFailed(); - channelzSessionInfo?.streamTracker.addCallFailed(); + if (!this._runHandlerForCall(call, handler)) { + this.callTracker.addCallFailed(); + channelzSessionInfo?.streamTracker.addCallFailed(); - call.sendStatus({ - code: Status.INTERNAL, - details: `Unknown handler type: ${handler.type}`, - }); - } - }; + call.sendStatus({ + code: Status.INTERNAL, + details: `Unknown handler type: ${handler.type}`, + }); + } } - private _streamHandler(http2Server: http2.Http2Server) { - return ( - stream: http2.ServerHttp2Stream, - headers: http2.IncomingHttpHeaders - ) => { - // for handling idle timeout - this.onStreamOpened(stream); - - if (this._verifyContentType(stream, headers) !== true) { - return; - } + private _streamHandler( + stream: http2.ServerHttp2Stream, + headers: http2.IncomingHttpHeaders + ) { + // for handling idle timeout + this.onStreamOpened(stream); - const path = headers[HTTP2_HEADER_PATH] as string; + if (this._verifyContentType(stream, headers) !== true) { + return; + } - const handler = this._retrieveHandler(path); - if (!handler) { - this._respondWithError( - getUnimplementedStatusResponse(path), - stream, - null - ); - return; - } + const path = headers[HTTP2_HEADER_PATH] as string; - const call = getServerInterceptingCall( - this.interceptors, + const handler = this._retrieveHandler(path); + if (!handler) { + this._respondWithError( + getUnimplementedStatusResponse(path), stream, - headers, - null, - handler, - this.options + null ); + return; + } - if (!this._runHandlerForCall(call, handler)) { - call.sendStatus({ - code: Status.INTERNAL, - details: `Unknown handler type: ${handler.type}`, - }); - } - }; + const call = getServerInterceptingCall( + this.interceptors, + stream, + headers, + null, + handler, + this.options + ); + + if (!this._runHandlerForCall(call, handler)) { + call.sendStatus({ + code: Status.INTERNAL, + details: `Unknown handler type: ${handler.type}`, + }); + } } private _runHandlerForCall( @@ -1361,14 +1357,14 @@ export class Server { this.serverAddressString = serverAddressString; const handler = this.channelzEnabled - ? this._channelzHandler(http2Server) - : this._streamHandler(http2Server); + ? this._channelzHandler + : this._streamHandler; const sessionHandler = this.channelzEnabled ? this._channelzSessionHandler(http2Server) : this._sessionHandler(http2Server); - http2Server.on('stream', handler); + http2Server.on('stream', handler.bind(this)); http2Server.on('session', sessionHandler); } From 11a98b5f373ff32ba5f4aceabfa8a98197ec1675 Mon Sep 17 00:00:00 2001 From: AVVS Date: Tue, 27 Feb 2024 16:49:20 -0800 Subject: [PATCH 07/55] chore: updated docs, cached onStreamClose per session --- packages/grpc-js/README.md | 3 + packages/grpc-js/src/channel-options.ts | 1 + packages/grpc-js/src/server.ts | 188 ++++++++++++++---------- 3 files changed, 116 insertions(+), 76 deletions(-) diff --git a/packages/grpc-js/README.md b/packages/grpc-js/README.md index eb04ece2f..f3b682f3c 100644 --- a/packages/grpc-js/README.md +++ b/packages/grpc-js/README.md @@ -60,6 +60,9 @@ Many channel arguments supported in `grpc` are not supported in `@grpc/grpc-js`. - `grpc.enable_channelz` - `grpc.dns_min_time_between_resolutions_ms` - `grpc.enable_retries` + - `grpc.max_connection_age_ms` + - `grpc.max_connection_age_grace_ms` + - `grpc.max_connection_idle_ms` - `grpc.per_rpc_retry_buffer_size` - `grpc.retry_buffer_size` - `grpc.service_config_disable_resolution` diff --git a/packages/grpc-js/src/channel-options.ts b/packages/grpc-js/src/channel-options.ts index aa1e6c83e..6804852e2 100644 --- a/packages/grpc-js/src/channel-options.ts +++ b/packages/grpc-js/src/channel-options.ts @@ -54,6 +54,7 @@ export interface ChannelOptions { 'grpc.retry_buffer_size'?: number; 'grpc.max_connection_age_ms'?: number; 'grpc.max_connection_age_grace_ms'?: number; + 'grpc.max_connection_idle_ms'?: number; 'grpc-node.max_session_memory'?: number; 'grpc.service_config_disable_resolution'?: number; 'grpc.client_idle_timeout_ms'?: number; diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index eed097f83..8a3a29fd8 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -90,7 +90,7 @@ import { CallEventTracker } from './transport'; const UNLIMITED_CONNECTION_AGE_MS = ~(1 << 31); const KEEPALIVE_MAX_TIME_MS = ~(1 << 31); const KEEPALIVE_TIMEOUT_MS = 20000; -const MAX_CONNECTION_IDLE_MS = 30 * 60 * 1e3; // 30 min +const MAX_CONNECTION_IDLE_MS = ~(1 << 31); const { HTTP2_HEADER_PATH } = http2.constants; @@ -241,6 +241,12 @@ interface Http2ServerInfo { sessions: Set; } +interface SessionIdleTimeoutTracker { + activeStreams: number; + timeout: NodeJS.Timeout | null; + onClose: (session: http2.ServerHttp2Session) => void | null; +} + export interface ServerOptions extends ChannelOptions { interceptors?: ServerInterceptor[]; } @@ -249,11 +255,8 @@ export class Server { private boundPorts: Map = new Map(); private http2Servers: Map = new Map(); private sessionIdleTimeouts = new Map< - http2.Http2Session, - { - activeStreams: number; - timeout: NodeJS.Timeout | null; - } + http2.ServerHttp2Session, + SessionIdleTimeoutTracker >(); private handlers: Map = new Map< @@ -330,7 +333,7 @@ export class Server { this.keepaliveTimeoutMs = this.options['grpc.keepalive_timeout_ms'] ?? KEEPALIVE_TIMEOUT_MS; this.sessionIdleTimeout = - this.options['grpc.max_connection_idle'] ?? MAX_CONNECTION_IDLE_MS; + this.options['grpc.max_connection_idle_ms'] ?? MAX_CONNECTION_IDLE_MS; this.commonServerOptions = { maxSendHeaderBlockLength: Number.MAX_SAFE_INTEGER, @@ -903,7 +906,6 @@ export class Server { if (sessionInfo) { this.sessionChildrenTracker.unrefChild(sessionInfo.ref); unregisterChannelzRef(sessionInfo.ref); - this.sessions.delete(session); } callback?.(); }; @@ -1001,7 +1003,7 @@ export class Server { for (const session of allSessions) { session.destroy(http2.constants.NGHTTP2_CANCEL as any); } - }, graceTimeMs).unref?.(); + }, graceTimeMs).unref(); } forceShutdown(): void { @@ -1376,6 +1378,7 @@ export class Server { let connectionAgeTimer: NodeJS.Timeout | null = null; let connectionAgeGraceTimer: NodeJS.Timeout | null = null; + let keeapliveTimeTimer: NodeJS.Timeout | null = null; let sessionClosedByServer = false; const idleTimeoutObj = this.enableIdleTimeout(session); @@ -1389,7 +1392,8 @@ export class Server { sessionClosedByServer = true; this.trace( - `Connection dropped by max connection age: ${session.socket?.remoteAddress}` + 'Connection dropped by max connection age: ' + + session.socket?.remoteAddress ); try { @@ -1410,36 +1414,38 @@ export class Server { if (this.maxConnectionAgeGraceMs !== UNLIMITED_CONNECTION_AGE_MS) { connectionAgeGraceTimer = setTimeout(() => { session.destroy(); - }, this.maxConnectionAgeGraceMs).unref?.(); + }, this.maxConnectionAgeGraceMs).unref(); } - }, this.maxConnectionAgeMs + jitter).unref?.(); + }, this.maxConnectionAgeMs + jitter).unref(); } - const keeapliveTimeTimer: NodeJS.Timeout | null = setInterval(() => { - const timeoutTImer = setTimeout(() => { - sessionClosedByServer = true; - session.close(); - }, this.keepaliveTimeoutMs).unref?.(); - - try { - session.ping( - (err: Error | null, duration: number, payload: Buffer) => { - clearTimeout(timeoutTImer); - - if (err) { - sessionClosedByServer = true; - this.trace( - `Connection dropped due to error of a ping frame ${err.message} return in ${duration}` - ); - session.close(); + if (this.keepaliveTimeMs < KEEPALIVE_MAX_TIME_MS) { + keeapliveTimeTimer = setInterval(() => { + const timeoutTimer = setTimeout(() => { + sessionClosedByServer = true; + session.close(); + }, this.keepaliveTimeoutMs).unref(); + + try { + session.ping( + (err: Error | null, duration: number, payload: Buffer) => { + clearTimeout(timeoutTimer); + + if (err) { + sessionClosedByServer = true; + this.trace( + `Connection dropped due to error of a ping frame ${err.message} return in ${duration}` + ); + session.close(); + } } - } - ); - } catch (e) { - // The ping can't be sent because the session is already closed - session.destroy(); - } - }, this.keepaliveTimeMs).unref?.(); + ); + } catch (e) { + // The ping can't be sent because the session is already closed + session.destroy(); + } + }, this.keepaliveTimeMs).unref(); + } session.on('close', () => { if (!sessionClosedByServer) { @@ -1460,8 +1466,12 @@ export class Server { clearTimeout(keeapliveTimeTimer); } - clearTimeout(idleTimeoutObj.timeout); - this.sessionIdleTimeouts.delete(session); + if (idleTimeoutObj !== null) { + if (idleTimeoutObj.timeout !== null) { + clearTimeout(idleTimeoutObj.timeout); + } + this.sessionIdleTimeouts.delete(session); + } this.http2Servers.get(http2Server)?.sessions.delete(session); }); @@ -1503,6 +1513,7 @@ export class Server { let connectionAgeTimer: NodeJS.Timeout | null = null; let connectionAgeGraceTimer: NodeJS.Timeout | null = null; + let keeapliveTimeTimer: NodeJS.Timeout | null = null; let sessionClosedByServer = false; const idleTimeoutObj = this.enableIdleTimeout(session); @@ -1537,43 +1548,48 @@ export class Server { if (this.maxConnectionAgeGraceMs !== UNLIMITED_CONNECTION_AGE_MS) { connectionAgeGraceTimer = setTimeout(() => { session.destroy(); - }, this.maxConnectionAgeGraceMs).unref?.(); + }, this.maxConnectionAgeGraceMs).unref(); } - }, this.maxConnectionAgeMs + jitter).unref?.(); + }, this.maxConnectionAgeMs + jitter).unref(); } - const keeapliveTimeTimer: NodeJS.Timeout | null = setInterval(() => { - const timeoutTImer = setTimeout(() => { - sessionClosedByServer = true; - this.channelzTrace.addTrace( - 'CT_INFO', - 'Connection dropped by keepalive timeout from ' + clientAddress - ); + if (this.keepaliveTimeMs < KEEPALIVE_MAX_TIME_MS) { + keeapliveTimeTimer = setInterval(() => { + const timeoutTImer = setTimeout(() => { + sessionClosedByServer = true; + this.channelzTrace.addTrace( + 'CT_INFO', + 'Connection dropped by keepalive timeout from ' + clientAddress + ); - session.close(); - }, this.keepaliveTimeoutMs).unref?.(); - try { - session.ping( - (err: Error | null, duration: number, payload: Buffer) => { - clearTimeout(timeoutTImer); - - if (err) { - sessionClosedByServer = true; - this.channelzTrace.addTrace( - 'CT_INFO', - `Connection dropped due to error of a ping frame ${err.message} return in ${duration}` - ); - - session.close(); + session.close(); + }, this.keepaliveTimeoutMs).unref(); + try { + session.ping( + (err: Error | null, duration: number, payload: Buffer) => { + clearTimeout(timeoutTImer); + + if (err) { + sessionClosedByServer = true; + this.channelzTrace.addTrace( + 'CT_INFO', + 'Connection dropped due to error of a ping frame ' + + err.message + + ' return in ' + + duration + ); + + session.close(); + } } - } - ); - channelzSessionInfo.keepAlivesSent += 1; - } catch (e) { - // The ping can't be sent because the session is already closed - session.destroy(); - } - }, this.keepaliveTimeMs).unref?.(); + ); + channelzSessionInfo.keepAlivesSent += 1; + } catch (e) { + // The ping can't be sent because the session is already closed + session.destroy(); + } + }, this.keepaliveTimeMs).unref(); + } session.on('close', () => { if (!sessionClosedByServer) { @@ -1598,8 +1614,12 @@ export class Server { clearTimeout(keeapliveTimeTimer); } - clearTimeout(idleTimeoutObj.timeout); - this.sessionIdleTimeouts.delete(session); + if (idleTimeoutObj !== null) { + if (idleTimeoutObj.timeout !== null) { + clearTimeout(idleTimeoutObj.timeout); + } + this.sessionIdleTimeouts.delete(session); + } this.http2Servers.get(http2Server)?.sessions.delete(session); this.sessions.delete(session); @@ -1607,9 +1627,16 @@ export class Server { }; } - private enableIdleTimeout(session: http2.ServerHttp2Session) { + private enableIdleTimeout( + session: http2.ServerHttp2Session + ): SessionIdleTimeoutTracker | null { + if (this.sessionIdleTimeout >= MAX_CONNECTION_IDLE_MS) { + return null; + } + const idleTimeoutObj = { activeStreams: 0, + onClose: this.onStreamClose.bind(this, session), // so that we don't recreate it each time timeout: setTimeout( this.onIdleTimeout, this.sessionIdleTimeout, @@ -1619,13 +1646,22 @@ export class Server { }; this.sessionIdleTimeouts.set(session, idleTimeoutObj); - this.trace(`Enable idle timeout for ${session.socket?.remoteAddress}`); + const { socket } = session; + this.trace( + 'Enable idle timeout for ' + + socket.remoteAddress + + ':' + + socket.remotePort + ); return idleTimeoutObj; } private onIdleTimeout(ctx: Server, session: http2.ServerHttp2Session) { - ctx.trace(`Idle timeout for ${session.socket?.remoteAddress}`); + const { socket } = session; + ctx.trace( + 'Idle timeout for ' + socket?.remoteAddress + ':' + socket?.remotePort + ); ctx.closeSession(session); } @@ -1640,7 +1676,7 @@ export class Server { idleTimeoutObj.timeout = null; } - stream.once('close', () => this.onStreamClose(session)); + stream.once('close', idleTimeoutObj.onClose); } } From bedb5055e89b39125d9466ee6f3c504f130792f6 Mon Sep 17 00:00:00 2001 From: AVVS Date: Wed, 28 Feb 2024 13:36:24 -0800 Subject: [PATCH 08/55] refactor: no clearTimeout/null timers, use .refresh() + count refs --- packages/grpc-js/src/server.ts | 51 +++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 8a3a29fd8..32c18ea94 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -243,7 +243,8 @@ interface Http2ServerInfo { interface SessionIdleTimeoutTracker { activeStreams: number; - timeout: NodeJS.Timeout | null; + lastIdle: number; + timeout: NodeJS.Timeout; onClose: (session: http2.ServerHttp2Session) => void | null; } @@ -292,6 +293,7 @@ export class Server { private readonly keepaliveTimeoutMs: number; private readonly sessionIdleTimeout: number; + private readonly sessionHalfIdleTimeout: number; private readonly interceptors: ServerInterceptor[]; @@ -334,6 +336,7 @@ export class Server { this.options['grpc.keepalive_timeout_ms'] ?? KEEPALIVE_TIMEOUT_MS; this.sessionIdleTimeout = this.options['grpc.max_connection_idle_ms'] ?? MAX_CONNECTION_IDLE_MS; + this.sessionHalfIdleTimeout = Math.ceil(this.sessionIdleTimeout / 2); this.commonServerOptions = { maxSendHeaderBlockLength: Number.MAX_SAFE_INTEGER, @@ -1467,9 +1470,7 @@ export class Server { } if (idleTimeoutObj !== null) { - if (idleTimeoutObj.timeout !== null) { - clearTimeout(idleTimeoutObj.timeout); - } + clearTimeout(idleTimeoutObj.timeout); this.sessionIdleTimeouts.delete(session); } @@ -1615,9 +1616,7 @@ export class Server { } if (idleTimeoutObj !== null) { - if (idleTimeoutObj.timeout !== null) { - clearTimeout(idleTimeoutObj.timeout); - } + clearTimeout(idleTimeoutObj.timeout); this.sessionIdleTimeouts.delete(session); } @@ -1634,12 +1633,14 @@ export class Server { return null; } - const idleTimeoutObj = { + const idleTimeoutObj: SessionIdleTimeoutTracker = { activeStreams: 0, + lastIdle: Date.now(), onClose: this.onStreamClose.bind(this, session), // so that we don't recreate it each time + // this is 50% of the actual timeout, we will check half-way through and .refresh() for a subsequent check timeout: setTimeout( this.onIdleTimeout, - this.sessionIdleTimeout, + this.sessionHalfIdleTimeout, this, session ).unref(), @@ -1660,9 +1661,25 @@ export class Server { private onIdleTimeout(ctx: Server, session: http2.ServerHttp2Session) { const { socket } = session; ctx.trace( - 'Idle timeout for ' + socket?.remoteAddress + ':' + socket?.remotePort + 'Session idle timeout checkpoint for ' + + socket?.remoteAddress + + ':' + + socket?.remotePort ); - ctx.closeSession(session); + + const sessionInfo = ctx.sessionIdleTimeouts.get(session); + // if it is called while we have activeStreams - timer will not be rescheduled + // until last active stream is closed, then it will call .refresh() on the timer + // important part is to not clearTimeout(timer) or it becomes unusable + // for future refreshes + if (sessionInfo && sessionInfo.activeStreams === 0) { + const idleFor = Date.now() - sessionInfo.lastIdle; + if (idleFor >= this.sessionIdleTimeout) { + ctx.closeSession(session); + } else { + sessionInfo.timeout.refresh(); + } + } } private onStreamOpened(stream: http2.ServerHttp2Stream) { @@ -1671,11 +1688,6 @@ export class Server { const idleTimeoutObj = this.sessionIdleTimeouts.get(session); if (idleTimeoutObj) { idleTimeoutObj.activeStreams += 1; - if (idleTimeoutObj.timeout) { - clearTimeout(idleTimeoutObj.timeout); - idleTimeoutObj.timeout = null; - } - stream.once('close', idleTimeoutObj.onClose); } } @@ -1686,12 +1698,7 @@ export class Server { if (idleTimeoutObj) { idleTimeoutObj.activeStreams -= 1; if (idleTimeoutObj.activeStreams === 0) { - idleTimeoutObj.timeout = setTimeout( - this.onIdleTimeout, - this.sessionIdleTimeout, - this, - session - ).unref(); + idleTimeoutObj.timeout.refresh(); } } } From b873dce908ddfefc42da43be8a612c4cdc2eefcc Mon Sep 17 00:00:00 2001 From: AVVS Date: Wed, 28 Feb 2024 14:26:42 -0800 Subject: [PATCH 09/55] chore: simplify idle timeout further, fix wrong ref --- packages/grpc-js/src/server.ts | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 32c18ea94..46fecc2e3 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -293,7 +293,6 @@ export class Server { private readonly keepaliveTimeoutMs: number; private readonly sessionIdleTimeout: number; - private readonly sessionHalfIdleTimeout: number; private readonly interceptors: ServerInterceptor[]; @@ -336,7 +335,6 @@ export class Server { this.options['grpc.keepalive_timeout_ms'] ?? KEEPALIVE_TIMEOUT_MS; this.sessionIdleTimeout = this.options['grpc.max_connection_idle_ms'] ?? MAX_CONNECTION_IDLE_MS; - this.sessionHalfIdleTimeout = Math.ceil(this.sessionIdleTimeout / 2); this.commonServerOptions = { maxSendHeaderBlockLength: Number.MAX_SAFE_INTEGER, @@ -1636,11 +1634,10 @@ export class Server { const idleTimeoutObj: SessionIdleTimeoutTracker = { activeStreams: 0, lastIdle: Date.now(), - onClose: this.onStreamClose.bind(this, session), // so that we don't recreate it each time - // this is 50% of the actual timeout, we will check half-way through and .refresh() for a subsequent check + onClose: this.onStreamClose.bind(this, session), timeout: setTimeout( this.onIdleTimeout, - this.sessionHalfIdleTimeout, + this.sessionIdleTimeout, this, session ).unref(), @@ -1658,7 +1655,11 @@ export class Server { return idleTimeoutObj; } - private onIdleTimeout(ctx: Server, session: http2.ServerHttp2Session) { + private onIdleTimeout( + this: undefined, + ctx: Server, + session: http2.ServerHttp2Session + ) { const { socket } = session; ctx.trace( 'Session idle timeout checkpoint for ' + @@ -1668,17 +1669,17 @@ export class Server { ); const sessionInfo = ctx.sessionIdleTimeouts.get(session); + // if it is called while we have activeStreams - timer will not be rescheduled // until last active stream is closed, then it will call .refresh() on the timer // important part is to not clearTimeout(timer) or it becomes unusable // for future refreshes - if (sessionInfo && sessionInfo.activeStreams === 0) { - const idleFor = Date.now() - sessionInfo.lastIdle; - if (idleFor >= this.sessionIdleTimeout) { - ctx.closeSession(session); - } else { - sessionInfo.timeout.refresh(); - } + if ( + sessionInfo !== undefined && + sessionInfo.activeStreams === 0 && + Date.now() - sessionInfo.lastIdle >= ctx.sessionIdleTimeout + ) { + ctx.closeSession(session); } } @@ -1698,6 +1699,7 @@ export class Server { if (idleTimeoutObj) { idleTimeoutObj.activeStreams -= 1; if (idleTimeoutObj.activeStreams === 0) { + idleTimeoutObj.lastIdle = Date.now(); idleTimeoutObj.timeout.refresh(); } } From 62e8ea97e659ea3c98ab77a38702fb5e0b67fed8 Mon Sep 17 00:00:00 2001 From: AVVS Date: Sat, 2 Mar 2024 07:58:54 -0800 Subject: [PATCH 10/55] chore: tests & cleanup of unref?.() --- packages/grpc-js/package.json | 2 +- .../grpc-js/src/load-balancer-pick-first.ts | 3 +- packages/grpc-js/src/resolver-dns.ts | 3 +- .../grpc-js/src/resolving-load-balancer.ts | 1 + packages/grpc-js/src/server.ts | 207 ++++++++++-------- packages/grpc-js/src/transport.ts | 3 +- packages/grpc-js/test/common.ts | 21 ++ packages/grpc-js/test/test-idle-timer.ts | 86 ++++++++ 8 files changed, 235 insertions(+), 91 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 34d8b558b..1c7935473 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -20,9 +20,9 @@ "@types/lodash": "^4.14.202", "@types/mocha": "^10.0.6", "@types/ncp": "^2.0.8", + "@types/node": ">=20.11.20", "@types/pify": "^5.0.4", "@types/semver": "^7.5.8", - "@types/node": ">=20.11.20", "@typescript-eslint/eslint-plugin": "^7.1.0", "@typescript-eslint/parser": "^7.1.0", "@typescript-eslint/typescript-estree": "^7.1.0", diff --git a/packages/grpc-js/src/load-balancer-pick-first.ts b/packages/grpc-js/src/load-balancer-pick-first.ts index 29bbfbf07..f6c43b33d 100644 --- a/packages/grpc-js/src/load-balancer-pick-first.ts +++ b/packages/grpc-js/src/load-balancer-pick-first.ts @@ -415,7 +415,8 @@ export class PickFirstLoadBalancer implements LoadBalancer { } this.connectionDelayTimeout = setTimeout(() => { this.startNextSubchannelConnecting(subchannelIndex + 1); - }, CONNECTION_DELAY_INTERVAL_MS).unref?.(); + }, CONNECTION_DELAY_INTERVAL_MS); + this.connectionDelayTimeout.unref?.(); } private pickSubchannel(subchannel: SubchannelInterface) { diff --git a/packages/grpc-js/src/resolver-dns.ts b/packages/grpc-js/src/resolver-dns.ts index 6652839b0..6463c2656 100644 --- a/packages/grpc-js/src/resolver-dns.ts +++ b/packages/grpc-js/src/resolver-dns.ts @@ -309,7 +309,8 @@ class DnsResolver implements Resolver { if (this.continueResolving) { this.startResolutionWithBackoff(); } - }, this.minTimeBetweenResolutionsMs).unref?.(); + }, this.minTimeBetweenResolutionsMs); + this.nextResolutionTimer.unref?.(); this.isNextResolutionTimerRunning = true; } diff --git a/packages/grpc-js/src/resolving-load-balancer.ts b/packages/grpc-js/src/resolving-load-balancer.ts index 82c4ff436..72aef0dfd 100644 --- a/packages/grpc-js/src/resolving-load-balancer.ts +++ b/packages/grpc-js/src/resolving-load-balancer.ts @@ -212,6 +212,7 @@ export class ResolvingLoadBalancer implements LoadBalancer { methodConfig: [], }; } + this.updateState(ConnectivityState.IDLE, new QueuePicker(this)); this.childLoadBalancer = new ChildLoadBalancerHandler( { diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 46fecc2e3..b0fd5e7d3 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -95,6 +95,7 @@ const MAX_CONNECTION_IDLE_MS = ~(1 << 31); const { HTTP2_HEADER_PATH } = http2.constants; const TRACER_NAME = 'server'; +const kMaxAge = Buffer.from('max_age'); type AnyHttp2Server = http2.Http2Server | http2.Http2SecureServer; @@ -369,65 +370,61 @@ export class Server { private getChannelzSessionInfoGetter( session: http2.ServerHttp2Session - ): () => SocketInfo { - return () => { - const sessionInfo = this.sessions.get(session)!; - const sessionSocket = session.socket; - const remoteAddress = sessionSocket.remoteAddress - ? stringToSubchannelAddress( - sessionSocket.remoteAddress, - sessionSocket.remotePort - ) - : null; - const localAddress = sessionSocket.localAddress - ? stringToSubchannelAddress( - sessionSocket.localAddress!, - sessionSocket.localPort - ) - : null; - let tlsInfo: TlsInfo | null; - if (session.encrypted) { - const tlsSocket: TLSSocket = sessionSocket as TLSSocket; - const cipherInfo: CipherNameAndProtocol & { standardName?: string } = - tlsSocket.getCipher(); - const certificate = tlsSocket.getCertificate(); - const peerCertificate = tlsSocket.getPeerCertificate(); - tlsInfo = { - cipherSuiteStandardName: cipherInfo.standardName ?? null, - cipherSuiteOtherName: cipherInfo.standardName - ? null - : cipherInfo.name, - localCertificate: - certificate && 'raw' in certificate ? certificate.raw : null, - remoteCertificate: - peerCertificate && 'raw' in peerCertificate - ? peerCertificate.raw - : null, - }; - } else { - tlsInfo = null; - } - const socketInfo: SocketInfo = { - remoteAddress: remoteAddress, - localAddress: localAddress, - security: tlsInfo, - remoteName: null, - streamsStarted: sessionInfo.streamTracker.callsStarted, - streamsSucceeded: sessionInfo.streamTracker.callsSucceeded, - streamsFailed: sessionInfo.streamTracker.callsFailed, - messagesSent: sessionInfo.messagesSent, - messagesReceived: sessionInfo.messagesReceived, - keepAlivesSent: sessionInfo.keepAlivesSent, - lastLocalStreamCreatedTimestamp: null, - lastRemoteStreamCreatedTimestamp: - sessionInfo.streamTracker.lastCallStartedTimestamp, - lastMessageSentTimestamp: sessionInfo.lastMessageSentTimestamp, - lastMessageReceivedTimestamp: sessionInfo.lastMessageReceivedTimestamp, - localFlowControlWindow: session.state.localWindowSize ?? null, - remoteFlowControlWindow: session.state.remoteWindowSize ?? null, + ): SocketInfo { + const sessionInfo = this.sessions.get(session)!; + const sessionSocket = session.socket; + const remoteAddress = sessionSocket.remoteAddress + ? stringToSubchannelAddress( + sessionSocket.remoteAddress, + sessionSocket.remotePort + ) + : null; + const localAddress = sessionSocket.localAddress + ? stringToSubchannelAddress( + sessionSocket.localAddress!, + sessionSocket.localPort + ) + : null; + let tlsInfo: TlsInfo | null; + if (session.encrypted) { + const tlsSocket: TLSSocket = sessionSocket as TLSSocket; + const cipherInfo: CipherNameAndProtocol & { standardName?: string } = + tlsSocket.getCipher(); + const certificate = tlsSocket.getCertificate(); + const peerCertificate = tlsSocket.getPeerCertificate(); + tlsInfo = { + cipherSuiteStandardName: cipherInfo.standardName ?? null, + cipherSuiteOtherName: cipherInfo.standardName ? null : cipherInfo.name, + localCertificate: + certificate && 'raw' in certificate ? certificate.raw : null, + remoteCertificate: + peerCertificate && 'raw' in peerCertificate + ? peerCertificate.raw + : null, }; - return socketInfo; + } else { + tlsInfo = null; + } + const socketInfo: SocketInfo = { + remoteAddress: remoteAddress, + localAddress: localAddress, + security: tlsInfo, + remoteName: null, + streamsStarted: sessionInfo.streamTracker.callsStarted, + streamsSucceeded: sessionInfo.streamTracker.callsSucceeded, + streamsFailed: sessionInfo.streamTracker.callsFailed, + messagesSent: sessionInfo.messagesSent, + messagesReceived: sessionInfo.messagesReceived, + keepAlivesSent: sessionInfo.keepAlivesSent, + lastLocalStreamCreatedTimestamp: null, + lastRemoteStreamCreatedTimestamp: + sessionInfo.streamTracker.lastCallStartedTimestamp, + lastMessageSentTimestamp: sessionInfo.lastMessageSentTimestamp, + lastMessageReceivedTimestamp: sessionInfo.lastMessageReceivedTimestamp, + localFlowControlWindow: session.state.localWindowSize ?? null, + remoteFlowControlWindow: session.state.remoteWindowSize ?? null, }; + return socketInfo; } private trace(text: string): void { @@ -1004,7 +1001,7 @@ export class Server { for (const session of allSessions) { session.destroy(http2.constants.NGHTTP2_CANCEL as any); } - }, graceTimeMs).unref(); + }, graceTimeMs).unref?.(); } forceShutdown(): void { @@ -1380,6 +1377,7 @@ export class Server { let connectionAgeTimer: NodeJS.Timeout | null = null; let connectionAgeGraceTimer: NodeJS.Timeout | null = null; let keeapliveTimeTimer: NodeJS.Timeout | null = null; + let keepaliveTimeoutTimer: NodeJS.Timeout | null = null; let sessionClosedByServer = false; const idleTimeoutObj = this.enableIdleTimeout(session); @@ -1401,7 +1399,7 @@ export class Server { session.goaway( http2.constants.NGHTTP2_NO_ERROR, ~(1 << 31), - Buffer.from('max_age') + kMaxAge ); } catch (e) { // The goaway can't be sent because the session is already closed @@ -1415,37 +1413,47 @@ export class Server { if (this.maxConnectionAgeGraceMs !== UNLIMITED_CONNECTION_AGE_MS) { connectionAgeGraceTimer = setTimeout(() => { session.destroy(); - }, this.maxConnectionAgeGraceMs).unref(); + }, this.maxConnectionAgeGraceMs); + connectionAgeGraceTimer.unref?.(); } - }, this.maxConnectionAgeMs + jitter).unref(); + }, this.maxConnectionAgeMs + jitter); + connectionAgeTimer.unref?.(); } if (this.keepaliveTimeMs < KEEPALIVE_MAX_TIME_MS) { keeapliveTimeTimer = setInterval(() => { - const timeoutTimer = setTimeout(() => { + keepaliveTimeoutTimer = setTimeout(() => { sessionClosedByServer = true; session.close(); - }, this.keepaliveTimeoutMs).unref(); + }, this.keepaliveTimeoutMs); + keepaliveTimeoutTimer.unref?.(); try { session.ping( (err: Error | null, duration: number, payload: Buffer) => { - clearTimeout(timeoutTimer); + if (keepaliveTimeoutTimer) { + clearTimeout(keepaliveTimeoutTimer); + } if (err) { sessionClosedByServer = true; this.trace( - `Connection dropped due to error of a ping frame ${err.message} return in ${duration}` + 'Connection dropped due to error of a ping frame ' + + err.message + + ' return in ' + + duration ); session.close(); } } ); } catch (e) { + clearTimeout(keepaliveTimeoutTimer); // The ping can't be sent because the session is already closed session.destroy(); } - }, this.keepaliveTimeMs).unref(); + }, this.keepaliveTimeMs); + keeapliveTimeTimer.unref?.(); } session.on('close', () => { @@ -1464,7 +1472,10 @@ export class Server { } if (keeapliveTimeTimer) { - clearTimeout(keeapliveTimeTimer); + clearInterval(keeapliveTimeTimer); + if (keepaliveTimeoutTimer) { + clearTimeout(keepaliveTimeoutTimer); + } } if (idleTimeoutObj !== null) { @@ -1483,15 +1494,13 @@ export class Server { return (session: http2.ServerHttp2Session) => { const channelzRef = registerChannelzSocket( session.socket?.remoteAddress ?? 'unknown', - this.getChannelzSessionInfoGetter(session), + this.getChannelzSessionInfoGetter.bind(this, session), this.channelzEnabled ); const channelzSessionInfo: ChannelzSessionInfo = { ref: channelzRef, - streamTracker: this.channelzEnabled - ? new ChannelzCallTracker() - : new ChannelzCallTrackerStub(), + streamTracker: new ChannelzCallTracker(), messagesSent: 0, messagesReceived: 0, keepAlivesSent: 0, @@ -1513,6 +1522,7 @@ export class Server { let connectionAgeTimer: NodeJS.Timeout | null = null; let connectionAgeGraceTimer: NodeJS.Timeout | null = null; let keeapliveTimeTimer: NodeJS.Timeout | null = null; + let keepaliveTimeoutTimer: NodeJS.Timeout | null = null; let sessionClosedByServer = false; const idleTimeoutObj = this.enableIdleTimeout(session); @@ -1533,7 +1543,7 @@ export class Server { session.goaway( http2.constants.NGHTTP2_NO_ERROR, ~(1 << 31), - Buffer.from('max_age') + kMaxAge ); } catch (e) { // The goaway can't be sent because the session is already closed @@ -1547,14 +1557,16 @@ export class Server { if (this.maxConnectionAgeGraceMs !== UNLIMITED_CONNECTION_AGE_MS) { connectionAgeGraceTimer = setTimeout(() => { session.destroy(); - }, this.maxConnectionAgeGraceMs).unref(); + }, this.maxConnectionAgeGraceMs); + connectionAgeGraceTimer.unref?.(); } - }, this.maxConnectionAgeMs + jitter).unref(); + }, this.maxConnectionAgeMs + jitter); + connectionAgeTimer.unref?.(); } if (this.keepaliveTimeMs < KEEPALIVE_MAX_TIME_MS) { keeapliveTimeTimer = setInterval(() => { - const timeoutTImer = setTimeout(() => { + keepaliveTimeoutTimer = setTimeout(() => { sessionClosedByServer = true; this.channelzTrace.addTrace( 'CT_INFO', @@ -1562,11 +1574,15 @@ export class Server { ); session.close(); - }, this.keepaliveTimeoutMs).unref(); + }, this.keepaliveTimeoutMs); + keepaliveTimeoutTimer.unref?.(); + try { session.ping( (err: Error | null, duration: number, payload: Buffer) => { - clearTimeout(timeoutTImer); + if (keepaliveTimeoutTimer) { + clearTimeout(keepaliveTimeoutTimer); + } if (err) { sessionClosedByServer = true; @@ -1584,10 +1600,12 @@ export class Server { ); channelzSessionInfo.keepAlivesSent += 1; } catch (e) { + clearTimeout(keepaliveTimeoutTimer); // The ping can't be sent because the session is already closed session.destroy(); } - }, this.keepaliveTimeMs).unref(); + }, this.keepaliveTimeMs); + keeapliveTimeTimer.unref?.(); } session.on('close', () => { @@ -1610,7 +1628,10 @@ export class Server { } if (keeapliveTimeTimer) { - clearTimeout(keeapliveTimeTimer); + clearInterval(keeapliveTimeTimer); + if (keepaliveTimeoutTimer) { + clearTimeout(keepaliveTimeoutTimer); + } } if (idleTimeoutObj !== null) { @@ -1640,8 +1661,9 @@ export class Server { this.sessionIdleTimeout, this, session - ).unref(), + ), }; + idleTimeoutObj.timeout.unref?.(); this.sessionIdleTimeouts.set(session, idleTimeoutObj); const { socket } = session; @@ -1661,13 +1683,6 @@ export class Server { session: http2.ServerHttp2Session ) { const { socket } = session; - ctx.trace( - 'Session idle timeout checkpoint for ' + - socket?.remoteAddress + - ':' + - socket?.remotePort - ); - const sessionInfo = ctx.sessionIdleTimeouts.get(session); // if it is called while we have activeStreams - timer will not be rescheduled @@ -1679,6 +1694,15 @@ export class Server { sessionInfo.activeStreams === 0 && Date.now() - sessionInfo.lastIdle >= ctx.sessionIdleTimeout ) { + ctx.trace( + 'Session idle timeout triggered for ' + + socket?.remoteAddress + + ':' + + socket?.remotePort + + ' last idle at ' + + sessionInfo.lastIdle + ); + ctx.closeSession(session); } } @@ -1701,6 +1725,15 @@ export class Server { if (idleTimeoutObj.activeStreams === 0) { idleTimeoutObj.lastIdle = Date.now(); idleTimeoutObj.timeout.refresh(); + + this.trace( + 'Session onStreamClose' + + session.socket?.remoteAddress + + ':' + + session.socket?.remotePort + + ' at ' + + idleTimeoutObj.lastIdle + ); } } } diff --git a/packages/grpc-js/src/transport.ts b/packages/grpc-js/src/transport.ts index 620488635..71d0f26b3 100644 --- a/packages/grpc-js/src/transport.ts +++ b/packages/grpc-js/src/transport.ts @@ -477,7 +477,8 @@ class Http2Transport implements Transport { ); this.keepaliveTimerId = setTimeout(() => { this.maybeSendPing(); - }, this.keepaliveTimeMs).unref?.(); + }, this.keepaliveTimeMs); + this.keepaliveTimerId.unref?.(); } /* Otherwise, there is already either a keepalive timer or a ping pending, * wait for those to resolve. */ diff --git a/packages/grpc-js/test/common.ts b/packages/grpc-js/test/common.ts index eaa701f18..fcdbb4500 100644 --- a/packages/grpc-js/test/common.ts +++ b/packages/grpc-js/test/common.ts @@ -140,6 +140,27 @@ export class TestClient { return this.client.getChannel().getConnectivityState(false); } + waitForClientState( + deadline: grpc.Deadline, + state: ConnectivityState, + callback: (error?: Error) => void + ) { + this.client + .getChannel() + .watchConnectivityState(this.getChannelState(), deadline, err => { + if (err) { + return callback(err); + } + + const currentState = this.getChannelState(); + if (currentState === state) { + callback(); + } else { + return this.waitForClientState(deadline, currentState, callback); + } + }); + } + close() { this.client.close(); } diff --git a/packages/grpc-js/test/test-idle-timer.ts b/packages/grpc-js/test/test-idle-timer.ts index 3fdeb1f64..a8f457e3f 100644 --- a/packages/grpc-js/test/test-idle-timer.ts +++ b/packages/grpc-js/test/test-idle-timer.ts @@ -128,3 +128,89 @@ describe('Channel idle timer', () => { }); }); }); + +describe('Server idle timer', () => { + let server: TestServer; + let client: TestClient | null = null; + before(() => { + server = new TestServer(false, { + 'grpc.max_connection_idle_ms': 500, // small for testing purposes + }); + return server.start(); + }); + afterEach(() => { + if (client) { + client.close(); + client = null; + } + }); + after(() => { + server.shutdown(); + }); + + it('Should go idle after the specified time after a request ends', function (done) { + this.timeout(5000); + client = TestClient.createFromServer(server); + client.sendRequest(error => { + assert.ifError(error); + assert.strictEqual( + client!.getChannelState(), + grpc.connectivityState.READY + ); + client?.waitForClientState( + Date.now() + 600, + grpc.connectivityState.IDLE, + done + ); + }); + }); + + it('Should be able to make a request after going idle', function (done) { + this.timeout(5000); + client = TestClient.createFromServer(server); + client.sendRequest(error => { + assert.ifError(error); + assert.strictEqual( + client!.getChannelState(), + grpc.connectivityState.READY + ); + + client!.waitForClientState( + Date.now() + 600, + grpc.connectivityState.IDLE, + err => { + if (err) return done(err); + + assert.strictEqual( + client!.getChannelState(), + grpc.connectivityState.IDLE + ); + client!.sendRequest(error => { + assert.ifError(error); + done(); + }); + } + ); + }); + }); + + it('Should go idle after the specified time after waitForReady ends', function (done) { + this.timeout(5000); + client = TestClient.createFromServer(server); + const deadline = new Date(); + deadline.setSeconds(deadline.getSeconds() + 3); + client.waitForReady(deadline, error => { + assert.ifError(error); + assert.strictEqual( + client!.getChannelState(), + grpc.connectivityState.READY + ); + + client!.waitForClientState( + Date.now() + 600, + grpc.connectivityState.IDLE, + done + ); + }); + }); +}); From 4a3fefa2b34c96d2f05eb263bbf800bb0dcd36ee Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 4 Mar 2024 09:33:41 -0800 Subject: [PATCH 11/55] grpc-js: pick_first: Don't automatically reconnect after connection drop --- packages/grpc-js/src/load-balancer-pick-first.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/grpc-js/src/load-balancer-pick-first.ts b/packages/grpc-js/src/load-balancer-pick-first.ts index 29bbfbf07..d625339f4 100644 --- a/packages/grpc-js/src/load-balancer-pick-first.ts +++ b/packages/grpc-js/src/load-balancer-pick-first.ts @@ -348,7 +348,6 @@ export class PickFirstLoadBalancer implements LoadBalancer { if (newState !== ConnectivityState.READY) { this.removeCurrentPick(); this.calculateAndReportNewState(); - this.requestReresolution(); } return; } From cf321a80b1918affaa41da9fe7e6424876ca5b48 Mon Sep 17 00:00:00 2001 From: AVVS Date: Mon, 4 Mar 2024 18:25:23 -0800 Subject: [PATCH 12/55] chore: use iterators for tracking map, const for default values --- packages/grpc-js/src/channelz.ts | 61 ++++++++++++++++++-------------- packages/grpc-js/src/server.ts | 4 +-- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/packages/grpc-js/src/channelz.ts b/packages/grpc-js/src/channelz.ts index 4eab762a8..697ea5d8a 100644 --- a/packages/grpc-js/src/channelz.ts +++ b/packages/grpc-js/src/channelz.ts @@ -133,6 +133,11 @@ interface TraceEvent { */ const TARGET_RETAINED_TRACES = 32; +/** + * Default number of sockets/servers/channels/subchannels to return + */ +const DEFAULT_MAX_RESULTS = 100; + export class ChannelzTraceStub { readonly events: TraceEvent[] = []; readonly creationTimestamp: Date = new Date(); @@ -198,19 +203,15 @@ export class ChannelzTrace { } } +type RefOrderedMap = OrderedMap< + number, + { ref: { id: number; kind: EntityTypes; name: string }; count: number } +>; + export class ChannelzChildrenTracker { - private channelChildren = new OrderedMap< - number, - { ref: ChannelRef; count: number } - >(); - private subchannelChildren = new OrderedMap< - number, - { ref: SubchannelRef; count: number } - >(); - private socketChildren = new OrderedMap< - number, - { ref: SocketRef; count: number } - >(); + private channelChildren: RefOrderedMap = new OrderedMap(); + private subchannelChildren: RefOrderedMap = new OrderedMap(); + private socketChildren: RefOrderedMap = new OrderedMap(); private trackerMap = { [EntityTypes.channel]: this.channelChildren, [EntityTypes.subchannel]: this.subchannelChildren, @@ -219,16 +220,19 @@ export class ChannelzChildrenTracker { refChild(child: ChannelRef | SubchannelRef | SocketRef) { const tracker = this.trackerMap[child.kind]; - const trackedChild = tracker.getElementByKey(child.id); - - if (trackedChild === undefined) { - tracker.setElement(child.id, { - // @ts-expect-error union issues - ref: child, - count: 1, - }); + const trackedChild = tracker.find(child.id); + + if (trackedChild.equals(tracker.end())) { + tracker.setElement( + child.id, + { + ref: child, + count: 1, + }, + trackedChild + ); } else { - trackedChild.count += 1; + trackedChild.pointer[1].count += 1; } } @@ -245,9 +249,9 @@ export class ChannelzChildrenTracker { getChildLists(): ChannelzChildren { return { - channels: this.channelChildren, - subchannels: this.subchannelChildren, - sockets: this.socketChildren, + channels: this.channelChildren as ChannelzChildren['channels'], + subchannels: this.subchannelChildren as ChannelzChildren['subchannels'], + sockets: this.socketChildren as ChannelzChildren['sockets'], }; } } @@ -585,7 +589,8 @@ function GetTopChannels( call: ServerUnaryCall, callback: sendUnaryData ): void { - const maxResults = parseInt(call.request.max_results, 10) || 100; + const maxResults = + parseInt(call.request.max_results, 10) || DEFAULT_MAX_RESULTS; const resultList: ChannelMessage[] = []; const startId = parseInt(call.request.start_channel_id, 10); const channelEntries = entityMaps[EntityTypes.channel]; @@ -649,7 +654,8 @@ function GetServers( call: ServerUnaryCall, callback: sendUnaryData ): void { - const maxResults = parseInt(call.request.max_results, 10) || 100; + const maxResults = + parseInt(call.request.max_results, 10) || DEFAULT_MAX_RESULTS; const startId = parseInt(call.request.start_server_id, 10); const serverEntries = entityMaps[EntityTypes.server]; const resultList: ServerMessage[] = []; @@ -820,7 +826,8 @@ function GetServerSockets( } const startId = parseInt(call.request.start_socket_id, 10); - const maxResults = parseInt(call.request.max_results, 10) || 100; + const maxResults = + parseInt(call.request.max_results, 10) || DEFAULT_MAX_RESULTS; const resolvedInfo = serverEntry.getInfo(); // If we wanted to include listener sockets in the result, this line would // instead say diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index b0fd5e7d3..feb511b41 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -368,7 +368,7 @@ export class Server { }; } - private getChannelzSessionInfoGetter( + private getChannelzSessionInfo( session: http2.ServerHttp2Session ): SocketInfo { const sessionInfo = this.sessions.get(session)!; @@ -1494,7 +1494,7 @@ export class Server { return (session: http2.ServerHttp2Session) => { const channelzRef = registerChannelzSocket( session.socket?.remoteAddress ?? 'unknown', - this.getChannelzSessionInfoGetter.bind(this, session), + this.getChannelzSessionInfo.bind(this, session), this.channelzEnabled ); From 07ee52acb04625f08092da59ad823c8651f41bee Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 5 Mar 2024 10:26:39 -0800 Subject: [PATCH 13/55] grpc-js: Rearrange some function calls to revert event order changes --- packages/grpc-js/src/server-call.ts | 4 ++-- packages/grpc-js/src/server-interceptors.ts | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index 95393fba9..77fee7df2 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -200,11 +200,11 @@ export class ServerWritableStreamImpl } _final(callback: Function): void { + callback(null); this.call.sendStatus({ ...this.pendingStatus, metadata: this.pendingStatus.metadata ?? this.trailingMetadata, }); - callback(null); } // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -273,11 +273,11 @@ export class ServerDuplexStreamImpl } _final(callback: Function): void { + callback(null); this.call.sendStatus({ ...this.pendingStatus, metadata: this.pendingStatus.metadata ?? this.trailingMetadata, }); - callback(null); } // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/packages/grpc-js/src/server-interceptors.ts b/packages/grpc-js/src/server-interceptors.ts index 60c5c8865..9dfbbb2ff 100644 --- a/packages/grpc-js/src/server-interceptors.ts +++ b/packages/grpc-js/src/server-interceptors.ts @@ -842,7 +842,6 @@ export class BaseServerInterceptingCall if (this.checkCancelled()) { return; } - this.notifyOnCancel(); trace( 'Request to method ' + @@ -869,8 +868,11 @@ export class BaseServerInterceptingCall }; this.stream.sendTrailers(trailersToSend); + this.notifyOnCancel(); }); this.stream.end(); + } else { + this.notifyOnCancel(); } } else { if (this.callEventTracker && !this.streamEnded) { @@ -886,6 +888,7 @@ export class BaseServerInterceptingCall ...status.metadata?.toHttp2Headers(), }; this.stream.respond(trailersToSend, { endStream: true }); + this.notifyOnCancel(); } } startRead(): void { From 74ddb3bd6fb0d37b716bf6b4f0eb694b8db761ec Mon Sep 17 00:00:00 2001 From: AVVS Date: Tue, 5 Mar 2024 15:34:29 -0800 Subject: [PATCH 14/55] chore: address ts errors --- packages/grpc-js/src/channelz.ts | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/grpc-js/src/channelz.ts b/packages/grpc-js/src/channelz.ts index 697ea5d8a..c207e567c 100644 --- a/packages/grpc-js/src/channelz.ts +++ b/packages/grpc-js/src/channelz.ts @@ -66,28 +66,26 @@ export type TraceSeverity = | 'CT_WARNING' | 'CT_ERROR'; -export interface ChannelRef { - kind: EntityTypes.channel; +interface Ref { + kind: EntityTypes; id: number; name: string; } -export interface SubchannelRef { +export interface ChannelRef extends Ref { + kind: EntityTypes.channel; +} + +export interface SubchannelRef extends Ref { kind: EntityTypes.subchannel; - id: number; - name: string; } -export interface ServerRef { +export interface ServerRef extends Ref { kind: EntityTypes.server; - id: number; - name: string; } -export interface SocketRef { +export interface SocketRef extends Ref { kind: EntityTypes.socket; - id: number; - name: string; } function channelRefToMessage(ref: ChannelRef): ChannelRefMessage { @@ -361,6 +359,8 @@ export const enum EntityTypes { socket = 'socket', } +type EntryOrderedMap = OrderedMap any }>; + const entityMaps = { [EntityTypes.channel]: new OrderedMap(), [EntityTypes.subchannel]: new OrderedMap(), @@ -404,6 +404,8 @@ const generateRegisterFn = (kind: R) => { return nextId++; } + const entityMap: EntryOrderedMap = entityMaps[kind]; + return ( name: string, getInfo: () => InfoByType, @@ -412,8 +414,7 @@ const generateRegisterFn = (kind: R) => { const id = getNextId(); const ref = { id, name, kind } as RefByType; if (channelzEnabled) { - // @ts-expect-error typing issues - entityMaps[kind].setElement(id, { ref, getInfo }); + entityMap.setElement(id, { ref, getInfo }); } return ref; }; From 4d235c339b5dc60efa58d398139c5f57d30ec023 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 7 Mar 2024 09:24:04 -0800 Subject: [PATCH 15/55] grpc-js: Bump to 1.10.2 --- packages/grpc-js/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 1c7935473..839735f6f 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.10.1", + "version": "1.10.2", "description": "gRPC Library for Node - pure JS implementation", "homepage": "https://grpc.io/", "repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js", From d0c20268878f01b3083b3543065b8ea6de50ac26 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 15 Mar 2024 09:23:08 -0700 Subject: [PATCH 16/55] Revert "grpc-js: pick_first: Don't automatically reconnect after connection drop" This reverts commit 4a3fefa2b34c96d2f05eb263bbf800bb0dcd36ee. --- packages/grpc-js/src/load-balancer-pick-first.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/grpc-js/src/load-balancer-pick-first.ts b/packages/grpc-js/src/load-balancer-pick-first.ts index f5339aed8..f6c43b33d 100644 --- a/packages/grpc-js/src/load-balancer-pick-first.ts +++ b/packages/grpc-js/src/load-balancer-pick-first.ts @@ -348,6 +348,7 @@ export class PickFirstLoadBalancer implements LoadBalancer { if (newState !== ConnectivityState.READY) { this.removeCurrentPick(); this.calculateAndReportNewState(); + this.requestReresolution(); } return; } From a8c6c33daa560b1b249f9c6edf975fdbc2d547a0 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 15 Mar 2024 09:24:01 -0700 Subject: [PATCH 17/55] grpc-js: Bump version to 1.10.3 --- packages/grpc-js/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 839735f6f..b2395b59a 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.10.2", + "version": "1.10.3", "description": "gRPC Library for Node - pure JS implementation", "homepage": "https://grpc.io/", "repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js", From d7d171776d686fbecdbf06e83ad278681c86cbda Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 15 Mar 2024 15:16:58 -0700 Subject: [PATCH 18/55] grpc-js: Add more info to deadline exceeded errors --- packages/grpc-js/src/call-interface.ts | 4 +++ packages/grpc-js/src/deadline.ts | 11 ++++++ packages/grpc-js/src/internal-channel.ts | 2 +- packages/grpc-js/src/load-balancing-call.ts | 28 ++++++++++++++-- packages/grpc-js/src/resolving-call.ts | 37 +++++++++++++++++++-- packages/grpc-js/src/retrying-call.ts | 24 +++++++++++-- packages/grpc-js/src/subchannel-address.ts | 8 +++-- packages/grpc-js/src/subchannel-call.ts | 4 +++ 8 files changed, 109 insertions(+), 9 deletions(-) diff --git a/packages/grpc-js/src/call-interface.ts b/packages/grpc-js/src/call-interface.ts index c0c63b957..c93c504f6 100644 --- a/packages/grpc-js/src/call-interface.ts +++ b/packages/grpc-js/src/call-interface.ts @@ -171,3 +171,7 @@ export interface Call { getCallNumber(): number; setCredentials(credentials: CallCredentials): void; } + +export interface DeadlineInfoProvider { + getDeadlineInfo(): string[]; +} diff --git a/packages/grpc-js/src/deadline.ts b/packages/grpc-js/src/deadline.ts index 8f8fe67b7..de05e381e 100644 --- a/packages/grpc-js/src/deadline.ts +++ b/packages/grpc-js/src/deadline.ts @@ -93,3 +93,14 @@ export function deadlineToString(deadline: Deadline): string { } } } + +/** + * Calculate the difference between two dates as a number of seconds and format + * it as a string. + * @param startDate + * @param endDate + * @returns + */ +export function formatDateDifference(startDate: Date, endDate: Date): string { + return ((endDate.getTime() - startDate.getTime()) / 1000).toFixed(3) + 's'; +} diff --git a/packages/grpc-js/src/internal-channel.ts b/packages/grpc-js/src/internal-channel.ts index 823c935af..469ace557 100644 --- a/packages/grpc-js/src/internal-channel.ts +++ b/packages/grpc-js/src/internal-channel.ts @@ -684,7 +684,7 @@ export class InternalChannel { host: string, credentials: CallCredentials, deadline: Deadline - ): Call { + ): LoadBalancingCall | RetryingCall { // Create a RetryingCall if retries are enabled if (this.options['grpc.enable_retries'] === 0) { return this.createLoadBalancingCall( diff --git a/packages/grpc-js/src/load-balancing-call.ts b/packages/grpc-js/src/load-balancing-call.ts index 25a36553a..9940500bc 100644 --- a/packages/grpc-js/src/load-balancing-call.ts +++ b/packages/grpc-js/src/load-balancing-call.ts @@ -18,6 +18,7 @@ import { CallCredentials } from './call-credentials'; import { Call, + DeadlineInfoProvider, InterceptingListener, MessageContext, StatusObject, @@ -25,7 +26,7 @@ import { import { SubchannelCall } from './subchannel-call'; import { ConnectivityState } from './connectivity-state'; import { LogVerbosity, Status } from './constants'; -import { Deadline, getDeadlineTimeoutString } from './deadline'; +import { Deadline, formatDateDifference, getDeadlineTimeoutString } from './deadline'; import { InternalChannel } from './internal-channel'; import { Metadata } from './metadata'; import { PickResultType } from './picker'; @@ -48,7 +49,7 @@ export interface LoadBalancingCallInterceptingListener onReceiveStatus(status: StatusObjectWithProgress): void; } -export class LoadBalancingCall implements Call { +export class LoadBalancingCall implements Call, DeadlineInfoProvider { private child: SubchannelCall | null = null; private readPending = false; private pendingMessage: { context: MessageContext; message: Buffer } | null = @@ -59,6 +60,8 @@ export class LoadBalancingCall implements Call { private metadata: Metadata | null = null; private listener: InterceptingListener | null = null; private onCallEnded: ((statusCode: Status) => void) | null = null; + private startTime: Date; + private childStartTime: Date | null = null; constructor( private readonly channel: InternalChannel, private readonly callConfig: CallConfig, @@ -80,6 +83,26 @@ export class LoadBalancingCall implements Call { /* Currently, call credentials are only allowed on HTTPS connections, so we * can assume that the scheme is "https" */ this.serviceUrl = `https://${hostname}/${serviceName}`; + this.startTime = new Date(); + } + getDeadlineInfo(): string[] { + const deadlineInfo: string[] = []; + if (this.childStartTime) { + if (this.childStartTime > this.startTime) { + if (this.metadata?.getOptions().waitForReady) { + deadlineInfo.push('wait_for_ready'); + } + deadlineInfo.push(`LB pick: ${formatDateDifference(this.startTime, this.childStartTime)}`); + } + deadlineInfo.push(...this.child!.getDeadlineInfo()); + return deadlineInfo; + } else { + if (this.metadata?.getOptions().waitForReady) { + deadlineInfo.push('wait_for_ready'); + } + deadlineInfo.push('Waiting for LB pick'); + } + return deadlineInfo; } private trace(text: string): void { @@ -209,6 +232,7 @@ export class LoadBalancingCall implements Call { } }, }); + this.childStartTime = new Date(); } catch (error) { this.trace( 'Failed to start call on picked subchannel ' + diff --git a/packages/grpc-js/src/resolving-call.ts b/packages/grpc-js/src/resolving-call.ts index 723533dba..2c81e7883 100644 --- a/packages/grpc-js/src/resolving-call.ts +++ b/packages/grpc-js/src/resolving-call.ts @@ -19,6 +19,7 @@ import { CallCredentials } from './call-credentials'; import { Call, CallStreamOptions, + DeadlineInfoProvider, InterceptingListener, MessageContext, StatusObject, @@ -27,6 +28,7 @@ import { LogVerbosity, Propagate, Status } from './constants'; import { Deadline, deadlineToString, + formatDateDifference, getRelativeTimeout, minDeadline, } from './deadline'; @@ -39,7 +41,7 @@ import { restrictControlPlaneStatusCode } from './control-plane-status'; const TRACER_NAME = 'resolving_call'; export class ResolvingCall implements Call { - private child: Call | null = null; + private child: (Call & DeadlineInfoProvider) | null = null; private readPending = false; private pendingMessage: { context: MessageContext; message: Buffer } | null = null; @@ -56,6 +58,10 @@ export class ResolvingCall implements Call { private deadlineTimer: NodeJS.Timeout = setTimeout(() => {}, 0); private filterStack: FilterStack | null = null; + private deadlineStartTime: Date | null = null; + private configReceivedTime: Date | null = null; + private childStartTime: Date | null = null; + constructor( private readonly channel: InternalChannel, private readonly method: string, @@ -97,12 +103,37 @@ export class ResolvingCall implements Call { private runDeadlineTimer() { clearTimeout(this.deadlineTimer); + this.deadlineStartTime = new Date(); this.trace('Deadline: ' + deadlineToString(this.deadline)); const timeout = getRelativeTimeout(this.deadline); if (timeout !== Infinity) { this.trace('Deadline will be reached in ' + timeout + 'ms'); const handleDeadline = () => { - this.cancelWithStatus(Status.DEADLINE_EXCEEDED, 'Deadline exceeded'); + if (!this.deadlineStartTime) { + this.cancelWithStatus(Status.DEADLINE_EXCEEDED, 'Deadline exceeded'); + return; + } + const deadlineInfo: string[] = []; + const deadlineEndTime = new Date(); + deadlineInfo.push(`Deadline exceeded after ${formatDateDifference(this.deadlineStartTime, deadlineEndTime)}`); + if (this.configReceivedTime) { + if (this.configReceivedTime > this.deadlineStartTime) { + deadlineInfo.push(`name resolution: ${formatDateDifference(this.deadlineStartTime, this.configReceivedTime)}`); + } + if (this.childStartTime) { + if (this.childStartTime > this.configReceivedTime) { + deadlineInfo.push(`metadata filters: ${formatDateDifference(this.configReceivedTime, this.childStartTime)}`); + } + } else { + deadlineInfo.push('waiting for metadata filters'); + } + } else { + deadlineInfo.push('waiting for name resolution'); + } + if (this.child) { + deadlineInfo.push(...this.child.getDeadlineInfo()); + } + this.cancelWithStatus(Status.DEADLINE_EXCEEDED, deadlineInfo.join(',')); }; if (timeout <= 0) { process.nextTick(handleDeadline); @@ -176,6 +207,7 @@ export class ResolvingCall implements Call { return; } // configResult.type === 'SUCCESS' + this.configReceivedTime = new Date(); const config = configResult.config; if (config.status !== Status.OK) { const { code, details } = restrictControlPlaneStatusCode( @@ -215,6 +247,7 @@ export class ResolvingCall implements Call { this.deadline ); this.trace('Created child [' + this.child.getCallNumber() + ']'); + this.childStartTime = new Date(); this.child.start(filteredMetadata, { onReceiveMetadata: metadata => { this.trace('Received metadata'); diff --git a/packages/grpc-js/src/retrying-call.ts b/packages/grpc-js/src/retrying-call.ts index e6e1cbb44..14969916e 100644 --- a/packages/grpc-js/src/retrying-call.ts +++ b/packages/grpc-js/src/retrying-call.ts @@ -17,12 +17,13 @@ import { CallCredentials } from './call-credentials'; import { LogVerbosity, Status } from './constants'; -import { Deadline } from './deadline'; +import { Deadline, formatDateDifference } from './deadline'; import { Metadata } from './metadata'; import { CallConfig } from './resolver'; import * as logging from './logging'; import { Call, + DeadlineInfoProvider, InterceptingListener, MessageContext, StatusObject, @@ -121,6 +122,7 @@ interface UnderlyingCall { state: UnderlyingCallState; call: LoadBalancingCall; nextMessageToSend: number; + startTime: Date; } /** @@ -170,7 +172,7 @@ interface WriteBufferEntry { const PREVIONS_RPC_ATTEMPTS_METADATA_KEY = 'grpc-previous-rpc-attempts'; -export class RetryingCall implements Call { +export class RetryingCall implements Call, DeadlineInfoProvider { private state: RetryingCallState; private listener: InterceptingListener | null = null; private initialMetadata: Metadata | null = null; @@ -198,6 +200,7 @@ export class RetryingCall implements Call { private committedCallIndex: number | null = null; private initialRetryBackoffSec = 0; private nextRetryBackoffSec = 0; + private startTime: Date; constructor( private readonly channel: InternalChannel, private readonly callConfig: CallConfig, @@ -223,6 +226,22 @@ export class RetryingCall implements Call { } else { this.state = 'TRANSPARENT_ONLY'; } + this.startTime = new Date(); + } + getDeadlineInfo(): string[] { + if (this.underlyingCalls.length === 0) { + return []; + } + const deadlineInfo: string[] = []; + const latestCall = this.underlyingCalls[this.underlyingCalls.length - 1]; + if (this.underlyingCalls.length > 1) { + deadlineInfo.push(`previous attempts: ${this.underlyingCalls.length - 1}`); + } + if (latestCall.startTime > this.startTime) { + deadlineInfo.push(`time to current attempt start: ${formatDateDifference(this.startTime, latestCall.startTime)}`); + } + deadlineInfo.push(...latestCall.call.getDeadlineInfo()); + return deadlineInfo; } getCallNumber(): number { return this.callNumber; @@ -628,6 +647,7 @@ export class RetryingCall implements Call { state: 'ACTIVE', call: child, nextMessageToSend: 0, + startTime: new Date() }); const previousAttempts = this.attempts - 1; const initialMetadata = this.initialMetadata!.clone(); diff --git a/packages/grpc-js/src/subchannel-address.ts b/packages/grpc-js/src/subchannel-address.ts index 70a7962f7..7e4f3e475 100644 --- a/packages/grpc-js/src/subchannel-address.ts +++ b/packages/grpc-js/src/subchannel-address.ts @@ -15,7 +15,7 @@ * */ -import { isIP } from 'net'; +import { isIP, isIPv6 } from 'net'; export interface TcpSubchannelAddress { port: number; @@ -63,7 +63,11 @@ export function subchannelAddressEqual( export function subchannelAddressToString(address: SubchannelAddress): string { if (isTcpSubchannelAddress(address)) { - return address.host + ':' + address.port; + if (isIPv6(address.host)) { + return '[' + address.host + ']:' + address.port; + } else { + return address.host + ':' + address.port; + } } else { return address.path; } diff --git a/packages/grpc-js/src/subchannel-call.ts b/packages/grpc-js/src/subchannel-call.ts index 3b9b6152f..33cf544d8 100644 --- a/packages/grpc-js/src/subchannel-call.ts +++ b/packages/grpc-js/src/subchannel-call.ts @@ -70,6 +70,7 @@ export interface SubchannelCall { startRead(): void; halfClose(): void; getCallNumber(): number; + getDeadlineInfo(): string[]; } export interface StatusObjectWithRstCode extends StatusObject { @@ -288,6 +289,9 @@ export class Http2SubchannelCall implements SubchannelCall { this.callEventTracker.onStreamEnd(false); }); } + getDeadlineInfo(): string[] { + return [`remote_addr=${this.getPeer()}`]; + } public onDisconnect() { this.endCall({ From 14f1d02c9af266104e896c70fccc144b724461f6 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 20 Mar 2024 15:44:18 -0700 Subject: [PATCH 19/55] grpc-js: Avoid sending redundant RST_STREAMs from the client --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/subchannel-call.ts | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index b2395b59a..a8a9f2d06 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.10.3", + "version": "1.10.4", "description": "gRPC Library for Node - pure JS implementation", "homepage": "https://grpc.io/", "repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js", diff --git a/packages/grpc-js/src/subchannel-call.ts b/packages/grpc-js/src/subchannel-call.ts index 3b9b6152f..fd1cfb454 100644 --- a/packages/grpc-js/src/subchannel-call.ts +++ b/packages/grpc-js/src/subchannel-call.ts @@ -105,6 +105,8 @@ export class Http2SubchannelCall implements SubchannelCall { private internalError: SystemError | null = null; + private serverEndedCall = false; + constructor( private readonly http2Stream: http2.ClientHttp2Stream, private readonly callEventTracker: CallEventTracker, @@ -182,6 +184,7 @@ export class Http2SubchannelCall implements SubchannelCall { this.maybeOutputStatus(); }); http2Stream.on('close', () => { + this.serverEndedCall = true; /* Use process.next tick to ensure that this code happens after any * "error" event that may be emitted at about the same time, so that * we can bubble up the error message from that event. */ @@ -400,6 +403,7 @@ export class Http2SubchannelCall implements SubchannelCall { } private handleTrailers(headers: http2.IncomingHttpHeaders) { + this.serverEndedCall = true; this.callEventTracker.onStreamEnd(true); let headersString = ''; for (const header of Object.keys(headers)) { @@ -445,7 +449,15 @@ export class Http2SubchannelCall implements SubchannelCall { private destroyHttp2Stream() { // The http2 stream could already have been destroyed if cancelWithStatus // is called in response to an internal http2 error. - if (!this.http2Stream.destroyed) { + if (this.http2Stream.destroyed) { + return; + } + /* If the server ended the call, sending an RST_STREAM is redundant, so we + * just half close on the client side instead to finish closing the stream. + */ + if (this.serverEndedCall) { + this.http2Stream.end(); + } else { /* If the call has ended with an OK status, communicate that when closing * the stream, partly to avoid a situation in which we detect an error * RST_STREAM as a result after we have the status */ From f4330f72c940645f910a7a78b3231ceab9cc2619 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 21 Mar 2024 09:49:58 -0700 Subject: [PATCH 20/55] Use call start times in some trace logs --- packages/grpc-js/src/load-balancing-call.ts | 3 ++- packages/grpc-js/src/retrying-call.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/src/load-balancing-call.ts b/packages/grpc-js/src/load-balancing-call.ts index 9940500bc..764769753 100644 --- a/packages/grpc-js/src/load-balancing-call.ts +++ b/packages/grpc-js/src/load-balancing-call.ts @@ -121,7 +121,8 @@ export class LoadBalancingCall implements Call, DeadlineInfoProvider { status.code + ' details="' + status.details + - '"' + '" start time=' + + this.startTime.toISOString() ); const finalStatus = { ...status, progress }; this.listener?.onReceiveStatus(finalStatus); diff --git a/packages/grpc-js/src/retrying-call.ts b/packages/grpc-js/src/retrying-call.ts index 14969916e..1c5ffaa4f 100644 --- a/packages/grpc-js/src/retrying-call.ts +++ b/packages/grpc-js/src/retrying-call.ts @@ -261,7 +261,8 @@ export class RetryingCall implements Call, DeadlineInfoProvider { statusObject.code + ' details="' + statusObject.details + - '"' + '" start time=' + + this.startTime.toISOString() ); this.bufferTracker.freeAll(this.callNumber); this.writeBufferOffset = this.writeBufferOffset + this.writeBuffer.length; From 9948aea5a536c9796ecf54814cab81aeb9c9ff3c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 21 Mar 2024 14:58:37 -0700 Subject: [PATCH 21/55] grpc-js: Ensure server interceptors work with builder utility classes --- packages/grpc-js/src/server-interceptors.ts | 20 +++++++++-- .../grpc-js/test/test-server-interceptors.ts | 35 +++++++++---------- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/packages/grpc-js/src/server-interceptors.ts b/packages/grpc-js/src/server-interceptors.ts index 9dfbbb2ff..c9cfe416b 100644 --- a/packages/grpc-js/src/server-interceptors.ts +++ b/packages/grpc-js/src/server-interceptors.ts @@ -345,7 +345,12 @@ export class ServerInterceptingCall implements ServerInterceptingCallInterface { private nextCall: ServerInterceptingCallInterface, responder?: Responder ) { - this.responder = { ...defaultResponder, ...responder }; + this.responder = { + start: responder?.start ?? defaultResponder.start, + sendMetadata: responder?.sendMetadata ?? defaultResponder.sendMetadata, + sendMessage: responder?.sendMessage ?? defaultResponder.sendMessage, + sendStatus: responder?.sendStatus ?? defaultResponder.sendStatus, + }; } private processPendingMessage() { @@ -369,8 +374,17 @@ export class ServerInterceptingCall implements ServerInterceptingCallInterface { start(listener: InterceptingServerListener): void { this.responder.start(interceptedListener => { const fullInterceptedListener: FullServerListener = { - ...defaultServerListener, - ...interceptedListener, + onReceiveMetadata: + interceptedListener?.onReceiveMetadata ?? + defaultServerListener.onReceiveMetadata, + onReceiveMessage: + interceptedListener?.onReceiveMessage ?? + defaultServerListener.onReceiveMessage, + onReceiveHalfClose: + interceptedListener?.onReceiveHalfClose ?? + defaultServerListener.onReceiveHalfClose, + onCancel: + interceptedListener?.onCancel ?? defaultServerListener.onCancel, }; const finalInterceptingListener = new InterceptingServerListenerImpl( fullInterceptedListener, diff --git a/packages/grpc-js/test/test-server-interceptors.ts b/packages/grpc-js/test/test-server-interceptors.ts index 5e93d32d2..e94169721 100644 --- a/packages/grpc-js/test/test-server-interceptors.ts +++ b/packages/grpc-js/test/test-server-interceptors.ts @@ -30,25 +30,22 @@ const testAuthInterceptor: grpc.ServerInterceptor = ( methodDescriptor, call ) => { - return new grpc.ServerInterceptingCall(call, { - start: next => { - const authListener: grpc.ServerListener = { - onReceiveMetadata: (metadata, mdNext) => { - if ( - metadata.get(AUTH_HEADER_KEY)?.[0] !== AUTH_HEADER_ALLOWED_VALUE - ) { - call.sendStatus({ - code: grpc.status.UNAUTHENTICATED, - details: 'Auth metadata not correct', - }); - } else { - mdNext(metadata); - } - }, - }; - next(authListener); - }, - }); + const authListener = (new grpc.ServerListenerBuilder()) + .withOnReceiveMetadata((metadata, mdNext) => { + if ( + metadata.get(AUTH_HEADER_KEY)?.[0] !== AUTH_HEADER_ALLOWED_VALUE + ) { + call.sendStatus({ + code: grpc.status.UNAUTHENTICATED, + details: 'Auth metadata not correct', + }); + } else { + mdNext(metadata); + } + }).build(); + const responder = (new grpc.ResponderBuilder()) + .withStart(next => next(authListener)).build(); + return new grpc.ServerInterceptingCall(call, responder); }; let eventCounts = { From e1f831a57bff9e5bce48aa80edb5ae527c397ca6 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 1 Apr 2024 09:54:06 -0700 Subject: [PATCH 22/55] grpc-js: Call custom checkServerIdentity when target name override is set --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/transport.ts | 8 +++-- .../grpc-js/test/test-channel-credentials.ts | 30 +++++++++++++++++-- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index a8a9f2d06..09ae217d8 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.10.4", + "version": "1.10.5", "description": "gRPC Library for Node - pure JS implementation", "homepage": "https://grpc.io/", "repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js", diff --git a/packages/grpc-js/src/transport.ts b/packages/grpc-js/src/transport.ts index 71d0f26b3..66a5d4556 100644 --- a/packages/grpc-js/src/transport.ts +++ b/packages/grpc-js/src/transport.ts @@ -694,11 +694,13 @@ export class Http2SubchannelConnector implements SubchannelConnector { if (options['grpc.ssl_target_name_override']) { const sslTargetNameOverride = options['grpc.ssl_target_name_override']!; + const originalCheckServerIdentity = + connectionOptions.checkServerIdentity ?? checkServerIdentity; connectionOptions.checkServerIdentity = ( host: string, cert: PeerCertificate ): Error | undefined => { - return checkServerIdentity(sslTargetNameOverride, cert); + return originalCheckServerIdentity(sslTargetNameOverride, cert); }; connectionOptions.servername = sslTargetNameOverride; } else { @@ -804,11 +806,13 @@ export class Http2SubchannelConnector implements SubchannelConnector { // This option is used for testing only. if (options['grpc.ssl_target_name_override']) { const sslTargetNameOverride = options['grpc.ssl_target_name_override']!; + const originalCheckServerIdentity = + connectionOptions.checkServerIdentity ?? checkServerIdentity; connectionOptions.checkServerIdentity = ( host: string, cert: PeerCertificate ): Error | undefined => { - return checkServerIdentity(sslTargetNameOverride, cert); + return originalCheckServerIdentity(sslTargetNameOverride, cert); }; connectionOptions.servername = sslTargetNameOverride; } else { diff --git a/packages/grpc-js/test/test-channel-credentials.ts b/packages/grpc-js/test/test-channel-credentials.ts index b05b0d048..b5c011581 100644 --- a/packages/grpc-js/test/test-channel-credentials.ts +++ b/packages/grpc-js/test/test-channel-credentials.ts @@ -150,8 +150,12 @@ describe('ChannelCredentials Implementation', () => { describe('ChannelCredentials usage', () => { let client: ServiceClient; let server: grpc.Server; + let portNum: number; + let caCert: Buffer; + const hostnameOverride = 'foo.test.google.fr'; before(async () => { const { ca, key, cert } = await pFixtures; + caCert = ca; const serverCreds = grpc.ServerCredentials.createSsl(null, [ { private_key: key, cert_chain: cert }, ]); @@ -178,9 +182,10 @@ describe('ChannelCredentials usage', () => { reject(err); return; } + portNum = port; client = new echoService(`localhost:${port}`, combinedCreds, { - 'grpc.ssl_target_name_override': 'foo.test.google.fr', - 'grpc.default_authority': 'foo.test.google.fr', + 'grpc.ssl_target_name_override': hostnameOverride, + 'grpc.default_authority': hostnameOverride, }); server.start(); resolve(); @@ -207,4 +212,25 @@ describe('ChannelCredentials usage', () => { ); assert2.afterMustCallsSatisfied(done); }); + + it('Should call the checkServerIdentity callback', done => { + const channelCreds = ChannelCredentials.createSsl(caCert, null, null, { + checkServerIdentity: assert2.mustCall((hostname, cert) => { + assert.strictEqual(hostname, hostnameOverride); + return undefined; + }), + }); + const client = new echoService(`localhost:${portNum}`, channelCreds, { + 'grpc.ssl_target_name_override': hostnameOverride, + 'grpc.default_authority': hostnameOverride, + }); + client.echo( + { value: 'test value', value2: 3 }, + assert2.mustCall((error: ServiceError, response: any) => { + assert.ifError(error); + assert.deepStrictEqual(response, { value: 'test value', value2: 3 }); + }) + ); + assert2.afterMustCallsSatisfied(done); + }); }); From 213230c73b9300ae9fff6b8f2e66f9913439dde7 Mon Sep 17 00:00:00 2001 From: David Fiala Date: Wed, 27 Mar 2024 16:39:45 -0700 Subject: [PATCH 23/55] Resolve exception when Error.stackTraceLimit is undefined Some applications may explicitly set Error.stackTraceLimit = undefined. In this case it is not safe to assume new Error().stack is available. --- packages/grpc-js/src/client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/src/client.ts b/packages/grpc-js/src/client.ts index e122f6cf4..995d5b328 100644 --- a/packages/grpc-js/src/client.ts +++ b/packages/grpc-js/src/client.ts @@ -110,7 +110,7 @@ export type ClientOptions = Partial & { }; function getErrorStackString(error: Error): string { - return error.stack!.split('\n').slice(1).join('\n'); + return error.stack?.split('\n').slice(1).join('\n') || 'no stack trace available'; } /** From 0d9a8c1dcf0f46eda09540518c50d28519201d58 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 3 Apr 2024 09:40:22 -0700 Subject: [PATCH 24/55] grpc-js: Fix check for whether to send a trailers-only response --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/server-interceptors.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 09ae217d8..3b8ccf2c1 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.10.5", + "version": "1.10.6", "description": "gRPC Library for Node - pure JS implementation", "homepage": "https://grpc.io/", "repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js", diff --git a/packages/grpc-js/src/server-interceptors.ts b/packages/grpc-js/src/server-interceptors.ts index c9cfe416b..b62d55108 100644 --- a/packages/grpc-js/src/server-interceptors.ts +++ b/packages/grpc-js/src/server-interceptors.ts @@ -866,7 +866,7 @@ export class BaseServerInterceptingCall status.details ); - if (this.stream.headersSent) { + if (this.metadataSent) { if (!this.wantTrailers) { this.wantTrailers = true; this.stream.once('wantTrailers', () => { From 2af21a55f366416030ec2e58b8b7c16f033a9e8e Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 8 Apr 2024 17:47:26 -0700 Subject: [PATCH 25/55] Merge pull request #2712 from sergiitk/psm-interop-pkg-dev PSM Interop: Migrate to Artifact Registry --- packages/grpc-js-xds/scripts/xds_k8s_lb.sh | 7 ++++--- packages/grpc-js-xds/scripts/xds_k8s_url_map.sh | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh index 504c3ff37..c900a4ea5 100755 --- a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh @@ -19,8 +19,9 @@ set -eo pipefail readonly GITHUB_REPOSITORY_NAME="grpc-node" readonly TEST_DRIVER_INSTALL_SCRIPT_URL="https://raw.githubusercontent.com/${TEST_DRIVER_REPO_OWNER:-grpc}/psm-interop/${TEST_DRIVER_BRANCH:-main}/.kokoro/psm_interop_kokoro_lib.sh" ## xDS test client Docker images -readonly SERVER_IMAGE_NAME="gcr.io/grpc-testing/xds-interop/java-server:558b5b0bfac8e21755c223063274a779b3898afe" -readonly CLIENT_IMAGE_NAME="gcr.io/grpc-testing/xds-interop/node-client" +readonly DOCKER_REGISTRY="us-docker.pkg.dev" +readonly SERVER_IMAGE_NAME="us-docker.pkg.dev/grpc-testing/psm-interop/java-server:canonical" +readonly CLIENT_IMAGE_NAME="us-docker.pkg.dev/grpc-testing/psm-interop/node-client" readonly FORCE_IMAGE_BUILD="${FORCE_IMAGE_BUILD:-0}" readonly BUILD_APP_PATH="packages/grpc-js-xds/interop/Dockerfile" readonly LANGUAGE_NAME="Node" @@ -46,7 +47,7 @@ build_test_app_docker_images() { -t "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \ . - gcloud -q auth configure-docker + gcloud -q auth configure-docker "${DOCKER_REGISTRY}" docker push "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" if is_version_branch "${TESTING_VERSION}"; then tag_and_push_docker_image "${CLIENT_IMAGE_NAME}" "${GIT_COMMIT}" "${TESTING_VERSION}" diff --git a/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh b/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh index 9344d054b..d6e2c7ed4 100644 --- a/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh @@ -19,7 +19,8 @@ set -eo pipefail readonly GITHUB_REPOSITORY_NAME="grpc-node" readonly TEST_DRIVER_INSTALL_SCRIPT_URL="https://raw.githubusercontent.com/${TEST_DRIVER_REPO_OWNER:-grpc}/psm-interop/${TEST_DRIVER_BRANCH:-main}/.kokoro/psm_interop_kokoro_lib.sh" ## xDS test client Docker images -readonly CLIENT_IMAGE_NAME="gcr.io/grpc-testing/xds-interop/node-client" +readonly DOCKER_REGISTRY="us-docker.pkg.dev" +readonly CLIENT_IMAGE_NAME="us-docker.pkg.dev/grpc-testing/psm-interop/node-client" readonly FORCE_IMAGE_BUILD="${FORCE_IMAGE_BUILD:-0}" readonly BUILD_APP_PATH="packages/grpc-js-xds/interop/Dockerfile" readonly LANGUAGE_NAME="Node" @@ -45,7 +46,7 @@ build_test_app_docker_images() { -t "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \ . - gcloud -q auth configure-docker + gcloud -q auth configure-docker "${DOCKER_REGISTRY}" docker push "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" if is_version_branch "${TESTING_VERSION}"; then tag_and_push_docker_image "${CLIENT_IMAGE_NAME}" "${GIT_COMMIT}" "${TESTING_VERSION}" From 8754ccb7dbefa0345a5805092a275f7e6c4cf0d2 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 11 Apr 2024 10:56:18 -0700 Subject: [PATCH 26/55] grpc-js: Improve reporting of HTTP error codes --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/subchannel-call.ts | 121 ++++++++++++++---------- 2 files changed, 73 insertions(+), 50 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 3b8ccf2c1..c9999465c 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.10.6", + "version": "1.10.7", "description": "gRPC Library for Node - pure JS implementation", "homepage": "https://grpc.io/", "repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js", diff --git a/packages/grpc-js/src/subchannel-call.ts b/packages/grpc-js/src/subchannel-call.ts index d54a6bcbf..0ce7d72cb 100644 --- a/packages/grpc-js/src/subchannel-call.ts +++ b/packages/grpc-js/src/subchannel-call.ts @@ -82,6 +82,39 @@ export interface SubchannelCallInterceptingListener onReceiveStatus(status: StatusObjectWithRstCode): void; } +function mapHttpStatusCode(code: number): StatusObject { + const details = `Received HTTP status code ${code}`; + let mappedStatusCode: number; + switch (code) { + // TODO(murgatroid99): handle 100 and 101 + case 400: + mappedStatusCode = Status.INTERNAL; + break; + case 401: + mappedStatusCode = Status.UNAUTHENTICATED; + break; + case 403: + mappedStatusCode = Status.PERMISSION_DENIED; + break; + case 404: + mappedStatusCode = Status.UNIMPLEMENTED; + break; + case 429: + case 502: + case 503: + case 504: + mappedStatusCode = Status.UNAVAILABLE; + break; + default: + mappedStatusCode = Status.UNKNOWN; + } + return { + code: mappedStatusCode, + details: details, + metadata: new Metadata() + }; +} + export class Http2SubchannelCall implements SubchannelCall { private decoder = new StreamDecoder(); @@ -98,8 +131,7 @@ export class Http2SubchannelCall implements SubchannelCall { private unpushedReadMessages: Buffer[] = []; - // Status code mapped from :status. To be used if grpc-status is not received - private mappedStatusCode: Status = Status.UNKNOWN; + private httpStatusCode: number | undefined; // This is populated (non-null) if and only if the call has ended private finalStatus: StatusObject | null = null; @@ -121,29 +153,7 @@ export class Http2SubchannelCall implements SubchannelCall { headersString += '\t\t' + header + ': ' + headers[header] + '\n'; } this.trace('Received server headers:\n' + headersString); - switch (headers[':status']) { - // TODO(murgatroid99): handle 100 and 101 - case 400: - this.mappedStatusCode = Status.INTERNAL; - break; - case 401: - this.mappedStatusCode = Status.UNAUTHENTICATED; - break; - case 403: - this.mappedStatusCode = Status.PERMISSION_DENIED; - break; - case 404: - this.mappedStatusCode = Status.UNIMPLEMENTED; - break; - case 429: - case 502: - case 503: - case 504: - this.mappedStatusCode = Status.UNAVAILABLE; - break; - default: - this.mappedStatusCode = Status.UNKNOWN; - } + this.httpStatusCode = headers[':status']; if (flags & http2.constants.NGHTTP2_FLAG_END_STREAM) { this.handleTrailers(headers); @@ -208,8 +218,14 @@ export class Http2SubchannelCall implements SubchannelCall { if (this.finalStatus !== null) { return; } - code = Status.INTERNAL; - details = `Received RST_STREAM with code ${http2Stream.rstCode}`; + if (this.httpStatusCode && this.httpStatusCode !== 200) { + const mappedStatus = mapHttpStatusCode(this.httpStatusCode); + code = mappedStatus.code; + details = mappedStatus.details; + } else { + code = Status.INTERNAL; + details = `Received RST_STREAM with code ${http2Stream.rstCode} (Call ended without gRPC status)`; + } break; case http2.constants.NGHTTP2_REFUSED_STREAM: code = Status.UNAVAILABLE; @@ -421,31 +437,38 @@ export class Http2SubchannelCall implements SubchannelCall { metadata = new Metadata(); } const metadataMap = metadata.getMap(); - let code: Status = this.mappedStatusCode; - if ( - code === Status.UNKNOWN && - typeof metadataMap['grpc-status'] === 'string' - ) { - const receivedStatus = Number(metadataMap['grpc-status']); - if (receivedStatus in Status) { - code = receivedStatus; - this.trace('received status code ' + receivedStatus + ' from server'); - } + let status: StatusObject; + if (typeof metadataMap['grpc-status'] === 'string') { + const receivedStatus: Status = Number(metadataMap['grpc-status']); + this.trace('received status code ' + receivedStatus + ' from server'); metadata.remove('grpc-status'); - } - let details = ''; - if (typeof metadataMap['grpc-message'] === 'string') { - try { - details = decodeURI(metadataMap['grpc-message']); - } catch (e) { - details = metadataMap['grpc-message']; + let details = ''; + if (typeof metadataMap['grpc-message'] === 'string') { + try { + details = decodeURI(metadataMap['grpc-message']); + } catch (e) { + details = metadataMap['grpc-message']; + } + metadata.remove('grpc-message'); + this.trace( + 'received status details string "' + details + '" from server' + ); } - metadata.remove('grpc-message'); - this.trace( - 'received status details string "' + details + '" from server' - ); + status = { + code: receivedStatus, + details: details, + metadata: metadata + }; + } else if (this.httpStatusCode) { + status = mapHttpStatusCode(this.httpStatusCode); + status.metadata = metadata; + } else { + status = { + code: Status.UNKNOWN, + details: 'No status information received', + metadata: metadata + }; } - const status: StatusObject = { code, details, metadata }; // This is a no-op if the call was already ended when handling headers. this.endCall(status); } From e4f2ecd0537191c3d4c6f27b2faa38daeda7059c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 30 Apr 2024 15:49:20 -0700 Subject: [PATCH 27/55] grpc-js(-xds): Pick up proto-loader update --- .../grpc/testing/ClientConfigureRequest.ts | 30 +- .../generated/grpc/testing/GrpclbRouteType.ts | 45 +- .../LoadBalancerAccumulatedStatsResponse.ts | 8 +- .../grpc/testing/LoadBalancerStatsResponse.ts | 2 +- .../grpc/testing/LoadBalancerStatsService.ts | 38 +- .../interop/generated/grpc/testing/Payload.ts | 6 +- .../generated/grpc/testing/PayloadType.ts | 21 +- .../grpc/testing/ReconnectService.ts | 38 +- .../grpc/testing/ResponseParameters.ts | 4 +- .../generated/grpc/testing/SimpleRequest.ts | 22 +- .../generated/grpc/testing/SimpleResponse.ts | 10 +- .../grpc/testing/StreamingInputCallRequest.ts | 8 +- .../testing/StreamingOutputCallRequest.ts | 14 +- .../testing/StreamingOutputCallResponse.ts | 4 +- .../generated/grpc/testing/TestService.ts | 92 +-- .../grpc/testing/UnimplementedService.ts | 21 +- .../XdsUpdateClientConfigureService.ts | 21 +- .../grpc/testing/XdsUpdateHealthService.ts | 38 +- .../grpc-js-xds/interop/generated/test.ts | 26 +- .../grpc-js-xds/interop/xds-interop-client.ts | 2 +- packages/grpc-js-xds/package.json | 6 +- packages/grpc-js-xds/src/generated/cluster.ts | 9 + .../envoy/admin/v3/BootstrapConfigDump.ts | 32 - .../envoy/admin/v3/ClientResourceStatus.ts | 57 +- .../envoy/admin/v3/ClustersConfigDump.ts | 6 +- .../generated/envoy/admin/v3/ConfigDump.ts | 65 -- .../envoy/admin/v3/EcdsConfigDump.ts | 6 +- .../envoy/admin/v3/EndpointsConfigDump.ts | 6 +- .../envoy/admin/v3/ListenersConfigDump.ts | 6 +- .../envoy/admin/v3/RoutesConfigDump.ts | 6 +- .../envoy/admin/v3/ScopedRoutesConfigDump.ts | 6 +- .../envoy/admin/v3/SecretsConfigDump.ts | 162 ----- .../config/accesslog/v3/ComparisonFilter.ts | 33 +- .../config/accesslog/v3/GrpcStatusFilter.ts | 80 ++- .../config/accesslog/v3/LogTypeFilter.ts | 6 +- .../envoy/config/bootstrap/v3/Admin.ts | 75 -- .../envoy/config/bootstrap/v3/Bootstrap.ts | 642 ------------------ .../config/bootstrap/v3/ClusterManager.ts | 99 --- .../config/bootstrap/v3/CustomInlineHeader.ts | 85 --- .../envoy/config/bootstrap/v3/FatalAction.ts | 39 -- .../config/bootstrap/v3/LayeredRuntime.ts | 25 - .../envoy/config/bootstrap/v3/Runtime.ts | 77 --- .../envoy/config/bootstrap/v3/RuntimeLayer.ts | 142 ---- .../envoy/config/bootstrap/v3/Watchdog.ts | 141 ---- .../envoy/config/bootstrap/v3/Watchdogs.ts | 35 - .../config/cluster/v3/CircuitBreakers.ts | 6 +- .../envoy/config/cluster/v3/Cluster.ts | 469 +++++++++++-- .../config/cluster/v3/UpstreamBindConfig.ts | 25 - .../envoy/config/core/v3/ApiConfigSource.ts | 76 ++- .../envoy/config/core/v3/ApiVersion.ts | 41 +- .../envoy/config/core/v3/BindConfig.ts | 2 + .../envoy/config/core/v3/ConfigSource.ts | 8 +- .../envoy/config/core/v3/Extension.ts | 2 + .../envoy/config/core/v3/HeaderValueOption.ts | 46 +- .../envoy/config/core/v3/HealthCheck.ts | 15 +- .../envoy/config/core/v3/HealthStatus.ts | 61 +- .../envoy/config/core/v3/HealthStatusSet.ts | 6 +- .../config/core/v3/Http2ProtocolOptions.ts | 2 + .../config/core/v3/HttpProtocolOptions.ts | 51 +- .../generated/envoy/config/core/v3/Node.ts | 2 + .../config/core/v3/ProxyProtocolConfig.ts | 26 +- .../core/v3/ProxyProtocolPassThroughTLVs.ts | 26 +- .../envoy/config/core/v3/RequestMethod.ts | 54 +- .../envoy/config/core/v3/RoutingPriority.ts | 34 +- .../envoy/config/core/v3/SelfConfigSource.ts | 6 +- .../envoy/config/core/v3/SocketAddress.ts | 20 +- .../envoy/config/core/v3/SocketOption.ts | 33 +- .../core/v3/SubstitutionFormatString.ts | 2 + .../envoy/config/core/v3/TrafficDirection.ts | 35 +- .../envoy/config/core/v3/UdpSocketConfig.ts | 1 - .../envoy/config/endpoint/v3/LbEndpoint.ts | 6 +- .../envoy/config/listener/v3/FilterChain.ts | 2 + .../config/listener/v3/FilterChainMatch.ts | 33 +- .../envoy/config/listener/v3/Listener.ts | 39 +- .../envoy/config/metrics/v3/DogStatsdSink.ts | 65 -- .../metrics/v3/HistogramBucketSettings.ts | 35 - .../envoy/config/metrics/v3/HystrixSink.ts | 61 -- .../envoy/config/metrics/v3/StatsConfig.ts | 148 ---- .../envoy/config/metrics/v3/StatsMatcher.ts | 47 -- .../envoy/config/metrics/v3/StatsSink.ts | 43 -- .../envoy/config/metrics/v3/StatsdSink.ts | 103 --- .../envoy/config/metrics/v3/TagSpecifier.ts | 174 ----- .../config/overload/v3/BufferFactoryConfig.ts | 50 -- .../config/overload/v3/OverloadAction.ts | 42 -- .../config/overload/v3/OverloadManager.ts | 44 -- .../config/overload/v3/ResourceMonitor.ts | 33 - .../v3/ScaleTimersOverloadActionConfig.ts | 89 --- .../envoy/config/overload/v3/ScaledTrigger.ts | 28 - .../config/overload/v3/ThresholdTrigger.ts | 18 - .../envoy/config/overload/v3/Trigger.ts | 24 - .../envoy/config/route/v3/HeaderMatcher.ts | 11 +- .../envoy/config/route/v3/RateLimit.ts | 28 +- .../envoy/config/route/v3/RedirectAction.ts | 47 +- .../envoy/config/route/v3/RetryPolicy.ts | 20 +- .../envoy/config/route/v3/RouteAction.ts | 86 ++- .../envoy/config/route/v3/VirtualHost.ts | 37 +- .../envoy/config/route/v3/WeightedCluster.ts | 2 + .../data/accesslog/v3/AccessLogCommon.ts | 8 +- .../envoy/data/accesslog/v3/AccessLogType.ts | 52 +- .../data/accesslog/v3/HTTPAccessLogEntry.ts | 38 +- .../accesslog/v3/HTTPRequestProperties.ts | 6 +- .../envoy/data/accesslog/v3/ResponseFlags.ts | 29 +- .../envoy/data/accesslog/v3/TLSProperties.ts | 32 +- .../filters/common/fault/v3/FaultDelay.ts | 15 +- .../v3/HttpConnectionManager.ts | 234 ++++++- .../common/v3/LocalityLbConfig.ts | 1 - .../ring_hash/v3/RingHash.ts | 46 +- .../v3/CertificateProviderPluginInstance.ts | 52 -- .../tls/v3/CertificateValidationContext.ts | 372 ---------- .../transport_sockets/tls/v3/GenericSecret.ts | 17 - .../tls/v3/PrivateKeyProvider.ts | 39 -- .../tls/v3/SdsSecretConfig.ts | 23 - .../transport_sockets/tls/v3/Secret.ts | 36 - .../tls/v3/TlsCertificate.ts | 127 ---- .../transport_sockets/tls/v3/TlsParameters.ts | 211 ------ .../tls/v3/TlsSessionTicketKeys.ts | 61 -- .../envoy/service/status/v3/ClientConfig.ts | 14 +- .../service/status/v3/ClientConfigStatus.ts | 45 +- .../envoy/service/status/v3/ConfigStatus.ts | 52 +- .../envoy/service/status/v3/PerXdsConfig.ts | 14 +- .../envoy/type/matcher/v3/RegexMatcher.ts | 4 + .../envoy/type/v3/CodecClientType.ts | 25 +- .../envoy/type/v3/FractionalPercent.ts | 45 +- .../google/protobuf/FieldDescriptorProto.ts | 108 ++- .../generated/google/protobuf/FieldOptions.ts | 48 +- .../generated/google/protobuf/FileOptions.ts | 30 +- .../generated/google/protobuf/NullValue.ts | 12 +- .../src/generated/google/protobuf/Value.ts | 6 +- .../udpa/annotations/PackageVersionStatus.ts | 37 +- .../udpa/annotations/StatusAnnotation.ts | 6 +- .../src/generated/validate/FieldRules.ts | 1 - .../src/generated/validate/KnownRegex.ts | 32 +- .../src/generated/validate/StringRules.ts | 6 +- .../annotations/v3/PackageVersionStatus.ts | 37 +- .../xds/annotations/v3/StatusAnnotation.ts | 6 +- .../generated/xds/core/v3/ResourceLocator.ts | 24 +- packages/grpc-js/package.json | 2 +- 137 files changed, 2344 insertions(+), 4269 deletions(-) delete mode 100644 packages/grpc-js-xds/src/generated/envoy/admin/v3/BootstrapConfigDump.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/admin/v3/ConfigDump.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/admin/v3/SecretsConfigDump.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Admin.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Bootstrap.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/ClusterManager.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/CustomInlineHeader.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/FatalAction.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/LayeredRuntime.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Runtime.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/RuntimeLayer.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Watchdog.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Watchdogs.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/UpstreamBindConfig.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/DogStatsdSink.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/HistogramBucketSettings.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/HystrixSink.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsConfig.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsMatcher.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsSink.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsdSink.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/TagSpecifier.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/overload/v3/BufferFactoryConfig.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/overload/v3/OverloadAction.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/overload/v3/OverloadManager.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ResourceMonitor.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ScaleTimersOverloadActionConfig.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ScaledTrigger.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ThresholdTrigger.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/overload/v3/Trigger.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/CertificateProviderPluginInstance.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/CertificateValidationContext.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/GenericSecret.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/PrivateKeyProvider.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/SdsSecretConfig.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/Secret.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/TlsCertificate.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/TlsParameters.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/TlsSessionTicketKeys.ts diff --git a/packages/grpc-js-xds/interop/generated/grpc/testing/ClientConfigureRequest.ts b/packages/grpc-js-xds/interop/generated/grpc/testing/ClientConfigureRequest.ts index 7f07e8966..4128fdda4 100644 --- a/packages/grpc-js-xds/interop/generated/grpc/testing/ClientConfigureRequest.ts +++ b/packages/grpc-js-xds/interop/generated/grpc/testing/ClientConfigureRequest.ts @@ -5,7 +5,7 @@ * Metadata to be attached for the given type of RPCs. */ export interface _grpc_testing_ClientConfigureRequest_Metadata { - 'type'?: (_grpc_testing_ClientConfigureRequest_RpcType | keyof typeof _grpc_testing_ClientConfigureRequest_RpcType); + 'type'?: (_grpc_testing_ClientConfigureRequest_RpcType); 'key'?: (string); 'value'?: (string); } @@ -14,7 +14,7 @@ export interface _grpc_testing_ClientConfigureRequest_Metadata { * Metadata to be attached for the given type of RPCs. */ export interface _grpc_testing_ClientConfigureRequest_Metadata__Output { - 'type': (keyof typeof _grpc_testing_ClientConfigureRequest_RpcType); + 'type': (_grpc_testing_ClientConfigureRequest_RpcType__Output); 'key': (string); 'value': (string); } @@ -24,10 +24,24 @@ export interface _grpc_testing_ClientConfigureRequest_Metadata__Output { /** * Type of RPCs to send. */ -export enum _grpc_testing_ClientConfigureRequest_RpcType { - EMPTY_CALL = 0, - UNARY_CALL = 1, -} +export const _grpc_testing_ClientConfigureRequest_RpcType = { + EMPTY_CALL: 'EMPTY_CALL', + UNARY_CALL: 'UNARY_CALL', +} as const; + +/** + * Type of RPCs to send. + */ +export type _grpc_testing_ClientConfigureRequest_RpcType = + | 'EMPTY_CALL' + | 0 + | 'UNARY_CALL' + | 1 + +/** + * Type of RPCs to send. + */ +export type _grpc_testing_ClientConfigureRequest_RpcType__Output = typeof _grpc_testing_ClientConfigureRequest_RpcType[keyof typeof _grpc_testing_ClientConfigureRequest_RpcType] /** * Configurations for a test client. @@ -36,7 +50,7 @@ export interface ClientConfigureRequest { /** * The types of RPCs the client sends. */ - 'types'?: (_grpc_testing_ClientConfigureRequest_RpcType | keyof typeof _grpc_testing_ClientConfigureRequest_RpcType)[]; + 'types'?: (_grpc_testing_ClientConfigureRequest_RpcType)[]; /** * The collection of custom metadata to be attached to RPCs sent by the client. */ @@ -55,7 +69,7 @@ export interface ClientConfigureRequest__Output { /** * The types of RPCs the client sends. */ - 'types': (keyof typeof _grpc_testing_ClientConfigureRequest_RpcType)[]; + 'types': (_grpc_testing_ClientConfigureRequest_RpcType__Output)[]; /** * The collection of custom metadata to be attached to RPCs sent by the client. */ diff --git a/packages/grpc-js-xds/interop/generated/grpc/testing/GrpclbRouteType.ts b/packages/grpc-js-xds/interop/generated/grpc/testing/GrpclbRouteType.ts index 8ab0146b7..667442b41 100644 --- a/packages/grpc-js-xds/interop/generated/grpc/testing/GrpclbRouteType.ts +++ b/packages/grpc-js-xds/interop/generated/grpc/testing/GrpclbRouteType.ts @@ -8,17 +8,52 @@ * the address of this server from the gRPCLB server BalanceLoad RPC). Exactly * how this detection is done is context and server dependent. */ -export enum GrpclbRouteType { +export const GrpclbRouteType = { /** * Server didn't detect the route that a client took to reach it. */ - GRPCLB_ROUTE_TYPE_UNKNOWN = 0, + GRPCLB_ROUTE_TYPE_UNKNOWN: 'GRPCLB_ROUTE_TYPE_UNKNOWN', /** * Indicates that a client reached a server via gRPCLB fallback. */ - GRPCLB_ROUTE_TYPE_FALLBACK = 1, + GRPCLB_ROUTE_TYPE_FALLBACK: 'GRPCLB_ROUTE_TYPE_FALLBACK', /** * Indicates that a client reached a server as a gRPCLB-given backend. */ - GRPCLB_ROUTE_TYPE_BACKEND = 2, -} + GRPCLB_ROUTE_TYPE_BACKEND: 'GRPCLB_ROUTE_TYPE_BACKEND', +} as const; + +/** + * The type of route that a client took to reach a server w.r.t. gRPCLB. + * The server must fill in "fallback" if it detects that the RPC reached + * the server via the "gRPCLB fallback" path, and "backend" if it detects + * that the RPC reached the server via "gRPCLB backend" path (i.e. if it got + * the address of this server from the gRPCLB server BalanceLoad RPC). Exactly + * how this detection is done is context and server dependent. + */ +export type GrpclbRouteType = + /** + * Server didn't detect the route that a client took to reach it. + */ + | 'GRPCLB_ROUTE_TYPE_UNKNOWN' + | 0 + /** + * Indicates that a client reached a server via gRPCLB fallback. + */ + | 'GRPCLB_ROUTE_TYPE_FALLBACK' + | 1 + /** + * Indicates that a client reached a server as a gRPCLB-given backend. + */ + | 'GRPCLB_ROUTE_TYPE_BACKEND' + | 2 + +/** + * The type of route that a client took to reach a server w.r.t. gRPCLB. + * The server must fill in "fallback" if it detects that the RPC reached + * the server via the "gRPCLB fallback" path, and "backend" if it detects + * that the RPC reached the server via "gRPCLB backend" path (i.e. if it got + * the address of this server from the gRPCLB server BalanceLoad RPC). Exactly + * how this detection is done is context and server dependent. + */ +export type GrpclbRouteType__Output = typeof GrpclbRouteType[keyof typeof GrpclbRouteType] diff --git a/packages/grpc-js-xds/interop/generated/grpc/testing/LoadBalancerAccumulatedStatsResponse.ts b/packages/grpc-js-xds/interop/generated/grpc/testing/LoadBalancerAccumulatedStatsResponse.ts index 91157ac4e..000ef9ecf 100644 --- a/packages/grpc-js-xds/interop/generated/grpc/testing/LoadBalancerAccumulatedStatsResponse.ts +++ b/packages/grpc-js-xds/interop/generated/grpc/testing/LoadBalancerAccumulatedStatsResponse.ts @@ -32,16 +32,19 @@ export interface LoadBalancerAccumulatedStatsResponse { /** * The total number of RPCs have ever issued for each type. * Deprecated: use stats_per_method.rpcs_started instead. + * @deprecated */ 'num_rpcs_started_by_method'?: ({[key: string]: number}); /** * The total number of RPCs have ever completed successfully for each type. * Deprecated: use stats_per_method.result instead. + * @deprecated */ 'num_rpcs_succeeded_by_method'?: ({[key: string]: number}); /** * The total number of RPCs have ever failed for each type. * Deprecated: use stats_per_method.result instead. + * @deprecated */ 'num_rpcs_failed_by_method'?: ({[key: string]: number}); /** @@ -58,21 +61,24 @@ export interface LoadBalancerAccumulatedStatsResponse__Output { /** * The total number of RPCs have ever issued for each type. * Deprecated: use stats_per_method.rpcs_started instead. + * @deprecated */ 'num_rpcs_started_by_method': ({[key: string]: number}); /** * The total number of RPCs have ever completed successfully for each type. * Deprecated: use stats_per_method.result instead. + * @deprecated */ 'num_rpcs_succeeded_by_method': ({[key: string]: number}); /** * The total number of RPCs have ever failed for each type. * Deprecated: use stats_per_method.result instead. + * @deprecated */ 'num_rpcs_failed_by_method': ({[key: string]: number}); /** * Per-method RPC statistics. The key is the RpcType in string form; e.g. * 'EMPTY_CALL' or 'UNARY_CALL' */ - 'stats_per_method'?: ({[key: string]: _grpc_testing_LoadBalancerAccumulatedStatsResponse_MethodStats__Output}); + 'stats_per_method': ({[key: string]: _grpc_testing_LoadBalancerAccumulatedStatsResponse_MethodStats__Output}); } diff --git a/packages/grpc-js-xds/interop/generated/grpc/testing/LoadBalancerStatsResponse.ts b/packages/grpc-js-xds/interop/generated/grpc/testing/LoadBalancerStatsResponse.ts index 184a6e258..ab33612c3 100644 --- a/packages/grpc-js-xds/interop/generated/grpc/testing/LoadBalancerStatsResponse.ts +++ b/packages/grpc-js-xds/interop/generated/grpc/testing/LoadBalancerStatsResponse.ts @@ -36,5 +36,5 @@ export interface LoadBalancerStatsResponse__Output { * The number of RPCs that failed to record a remote peer. */ 'num_failures': (number); - 'rpcs_by_method'?: ({[key: string]: _grpc_testing_LoadBalancerStatsResponse_RpcsByPeer__Output}); + 'rpcs_by_method': ({[key: string]: _grpc_testing_LoadBalancerStatsResponse_RpcsByPeer__Output}); } diff --git a/packages/grpc-js-xds/interop/generated/grpc/testing/LoadBalancerStatsService.ts b/packages/grpc-js-xds/interop/generated/grpc/testing/LoadBalancerStatsService.ts index 26cfee9d7..9d11d9418 100644 --- a/packages/grpc-js-xds/interop/generated/grpc/testing/LoadBalancerStatsService.ts +++ b/packages/grpc-js-xds/interop/generated/grpc/testing/LoadBalancerStatsService.ts @@ -1,6 +1,7 @@ // Original file: proto/grpc/testing/test.proto import type * as grpc from '@grpc/grpc-js' +import type { MethodDefinition } from '@grpc/proto-loader' import type { LoadBalancerAccumulatedStatsRequest as _grpc_testing_LoadBalancerAccumulatedStatsRequest, LoadBalancerAccumulatedStatsRequest__Output as _grpc_testing_LoadBalancerAccumulatedStatsRequest__Output } from '../../grpc/testing/LoadBalancerAccumulatedStatsRequest'; import type { LoadBalancerAccumulatedStatsResponse as _grpc_testing_LoadBalancerAccumulatedStatsResponse, LoadBalancerAccumulatedStatsResponse__Output as _grpc_testing_LoadBalancerAccumulatedStatsResponse__Output } from '../../grpc/testing/LoadBalancerAccumulatedStatsResponse'; import type { LoadBalancerStatsRequest as _grpc_testing_LoadBalancerStatsRequest, LoadBalancerStatsRequest__Output as _grpc_testing_LoadBalancerStatsRequest__Output } from '../../grpc/testing/LoadBalancerStatsRequest'; @@ -13,32 +14,32 @@ export interface LoadBalancerStatsServiceClient extends grpc.Client { /** * Gets the accumulated stats for RPCs sent by a test client. */ - GetClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerAccumulatedStatsResponse__Output) => void): grpc.ClientUnaryCall; - GetClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerAccumulatedStatsResponse__Output) => void): grpc.ClientUnaryCall; - GetClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerAccumulatedStatsResponse__Output) => void): grpc.ClientUnaryCall; - GetClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerAccumulatedStatsResponse__Output) => void): grpc.ClientUnaryCall; + GetClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_LoadBalancerAccumulatedStatsResponse__Output>): grpc.ClientUnaryCall; + GetClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_LoadBalancerAccumulatedStatsResponse__Output>): grpc.ClientUnaryCall; + GetClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_LoadBalancerAccumulatedStatsResponse__Output>): grpc.ClientUnaryCall; + GetClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, callback: grpc.requestCallback<_grpc_testing_LoadBalancerAccumulatedStatsResponse__Output>): grpc.ClientUnaryCall; /** * Gets the accumulated stats for RPCs sent by a test client. */ - getClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerAccumulatedStatsResponse__Output) => void): grpc.ClientUnaryCall; - getClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerAccumulatedStatsResponse__Output) => void): grpc.ClientUnaryCall; - getClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerAccumulatedStatsResponse__Output) => void): grpc.ClientUnaryCall; - getClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerAccumulatedStatsResponse__Output) => void): grpc.ClientUnaryCall; + getClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_LoadBalancerAccumulatedStatsResponse__Output>): grpc.ClientUnaryCall; + getClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_LoadBalancerAccumulatedStatsResponse__Output>): grpc.ClientUnaryCall; + getClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_LoadBalancerAccumulatedStatsResponse__Output>): grpc.ClientUnaryCall; + getClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, callback: grpc.requestCallback<_grpc_testing_LoadBalancerAccumulatedStatsResponse__Output>): grpc.ClientUnaryCall; /** * Gets the backend distribution for RPCs sent by a test client. */ - GetClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerStatsResponse__Output) => void): grpc.ClientUnaryCall; - GetClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerStatsResponse__Output) => void): grpc.ClientUnaryCall; - GetClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerStatsResponse__Output) => void): grpc.ClientUnaryCall; - GetClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerStatsResponse__Output) => void): grpc.ClientUnaryCall; + GetClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_LoadBalancerStatsResponse__Output>): grpc.ClientUnaryCall; + GetClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_LoadBalancerStatsResponse__Output>): grpc.ClientUnaryCall; + GetClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_LoadBalancerStatsResponse__Output>): grpc.ClientUnaryCall; + GetClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, callback: grpc.requestCallback<_grpc_testing_LoadBalancerStatsResponse__Output>): grpc.ClientUnaryCall; /** * Gets the backend distribution for RPCs sent by a test client. */ - getClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerStatsResponse__Output) => void): grpc.ClientUnaryCall; - getClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerStatsResponse__Output) => void): grpc.ClientUnaryCall; - getClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerStatsResponse__Output) => void): grpc.ClientUnaryCall; - getClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerStatsResponse__Output) => void): grpc.ClientUnaryCall; + getClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_LoadBalancerStatsResponse__Output>): grpc.ClientUnaryCall; + getClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_LoadBalancerStatsResponse__Output>): grpc.ClientUnaryCall; + getClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_LoadBalancerStatsResponse__Output>): grpc.ClientUnaryCall; + getClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, callback: grpc.requestCallback<_grpc_testing_LoadBalancerStatsResponse__Output>): grpc.ClientUnaryCall; } @@ -57,3 +58,8 @@ export interface LoadBalancerStatsServiceHandlers extends grpc.UntypedServiceImp GetClientStats: grpc.handleUnaryCall<_grpc_testing_LoadBalancerStatsRequest__Output, _grpc_testing_LoadBalancerStatsResponse>; } + +export interface LoadBalancerStatsServiceDefinition extends grpc.ServiceDefinition { + GetClientAccumulatedStats: MethodDefinition<_grpc_testing_LoadBalancerAccumulatedStatsRequest, _grpc_testing_LoadBalancerAccumulatedStatsResponse, _grpc_testing_LoadBalancerAccumulatedStatsRequest__Output, _grpc_testing_LoadBalancerAccumulatedStatsResponse__Output> + GetClientStats: MethodDefinition<_grpc_testing_LoadBalancerStatsRequest, _grpc_testing_LoadBalancerStatsResponse, _grpc_testing_LoadBalancerStatsRequest__Output, _grpc_testing_LoadBalancerStatsResponse__Output> +} diff --git a/packages/grpc-js-xds/interop/generated/grpc/testing/Payload.ts b/packages/grpc-js-xds/interop/generated/grpc/testing/Payload.ts index 79102d2bf..17eb9e60a 100644 --- a/packages/grpc-js-xds/interop/generated/grpc/testing/Payload.ts +++ b/packages/grpc-js-xds/interop/generated/grpc/testing/Payload.ts @@ -1,6 +1,6 @@ // Original file: proto/grpc/testing/messages.proto -import type { PayloadType as _grpc_testing_PayloadType } from '../../grpc/testing/PayloadType'; +import type { PayloadType as _grpc_testing_PayloadType, PayloadType__Output as _grpc_testing_PayloadType__Output } from '../../grpc/testing/PayloadType'; /** * A block of data, to simply increase gRPC message size. @@ -9,7 +9,7 @@ export interface Payload { /** * The type of data in body. */ - 'type'?: (_grpc_testing_PayloadType | keyof typeof _grpc_testing_PayloadType); + 'type'?: (_grpc_testing_PayloadType); /** * Primary contents of payload. */ @@ -23,7 +23,7 @@ export interface Payload__Output { /** * The type of data in body. */ - 'type': (keyof typeof _grpc_testing_PayloadType); + 'type': (_grpc_testing_PayloadType__Output); /** * Primary contents of payload. */ diff --git a/packages/grpc-js-xds/interop/generated/grpc/testing/PayloadType.ts b/packages/grpc-js-xds/interop/generated/grpc/testing/PayloadType.ts index 3cf9d375a..64e526090 100644 --- a/packages/grpc-js-xds/interop/generated/grpc/testing/PayloadType.ts +++ b/packages/grpc-js-xds/interop/generated/grpc/testing/PayloadType.ts @@ -3,9 +3,24 @@ /** * The type of payload that should be returned. */ -export enum PayloadType { +export const PayloadType = { /** * Compressable text format. */ - COMPRESSABLE = 0, -} + COMPRESSABLE: 'COMPRESSABLE', +} as const; + +/** + * The type of payload that should be returned. + */ +export type PayloadType = + /** + * Compressable text format. + */ + | 'COMPRESSABLE' + | 0 + +/** + * The type of payload that should be returned. + */ +export type PayloadType__Output = typeof PayloadType[keyof typeof PayloadType] diff --git a/packages/grpc-js-xds/interop/generated/grpc/testing/ReconnectService.ts b/packages/grpc-js-xds/interop/generated/grpc/testing/ReconnectService.ts index e489e2849..2e3f25680 100644 --- a/packages/grpc-js-xds/interop/generated/grpc/testing/ReconnectService.ts +++ b/packages/grpc-js-xds/interop/generated/grpc/testing/ReconnectService.ts @@ -1,6 +1,7 @@ // Original file: proto/grpc/testing/test.proto import type * as grpc from '@grpc/grpc-js' +import type { MethodDefinition } from '@grpc/proto-loader' import type { Empty as _grpc_testing_Empty, Empty__Output as _grpc_testing_Empty__Output } from '../../grpc/testing/Empty'; import type { ReconnectInfo as _grpc_testing_ReconnectInfo, ReconnectInfo__Output as _grpc_testing_ReconnectInfo__Output } from '../../grpc/testing/ReconnectInfo'; import type { ReconnectParams as _grpc_testing_ReconnectParams, ReconnectParams__Output as _grpc_testing_ReconnectParams__Output } from '../../grpc/testing/ReconnectParams'; @@ -9,23 +10,23 @@ import type { ReconnectParams as _grpc_testing_ReconnectParams, ReconnectParams_ * A service used to control reconnect server. */ export interface ReconnectServiceClient extends grpc.Client { - Start(argument: _grpc_testing_ReconnectParams, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - Start(argument: _grpc_testing_ReconnectParams, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - Start(argument: _grpc_testing_ReconnectParams, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - Start(argument: _grpc_testing_ReconnectParams, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - start(argument: _grpc_testing_ReconnectParams, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - start(argument: _grpc_testing_ReconnectParams, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - start(argument: _grpc_testing_ReconnectParams, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - start(argument: _grpc_testing_ReconnectParams, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; + Start(argument: _grpc_testing_ReconnectParams, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + Start(argument: _grpc_testing_ReconnectParams, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + Start(argument: _grpc_testing_ReconnectParams, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + Start(argument: _grpc_testing_ReconnectParams, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + start(argument: _grpc_testing_ReconnectParams, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + start(argument: _grpc_testing_ReconnectParams, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + start(argument: _grpc_testing_ReconnectParams, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + start(argument: _grpc_testing_ReconnectParams, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; - Stop(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ReconnectInfo__Output) => void): grpc.ClientUnaryCall; - Stop(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ReconnectInfo__Output) => void): grpc.ClientUnaryCall; - Stop(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ReconnectInfo__Output) => void): grpc.ClientUnaryCall; - Stop(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ReconnectInfo__Output) => void): grpc.ClientUnaryCall; - stop(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ReconnectInfo__Output) => void): grpc.ClientUnaryCall; - stop(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ReconnectInfo__Output) => void): grpc.ClientUnaryCall; - stop(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ReconnectInfo__Output) => void): grpc.ClientUnaryCall; - stop(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ReconnectInfo__Output) => void): grpc.ClientUnaryCall; + Stop(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_ReconnectInfo__Output>): grpc.ClientUnaryCall; + Stop(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_ReconnectInfo__Output>): grpc.ClientUnaryCall; + Stop(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_ReconnectInfo__Output>): grpc.ClientUnaryCall; + Stop(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_ReconnectInfo__Output>): grpc.ClientUnaryCall; + stop(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_ReconnectInfo__Output>): grpc.ClientUnaryCall; + stop(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_ReconnectInfo__Output>): grpc.ClientUnaryCall; + stop(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_ReconnectInfo__Output>): grpc.ClientUnaryCall; + stop(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_ReconnectInfo__Output>): grpc.ClientUnaryCall; } @@ -38,3 +39,8 @@ export interface ReconnectServiceHandlers extends grpc.UntypedServiceImplementat Stop: grpc.handleUnaryCall<_grpc_testing_Empty__Output, _grpc_testing_ReconnectInfo>; } + +export interface ReconnectServiceDefinition extends grpc.ServiceDefinition { + Start: MethodDefinition<_grpc_testing_ReconnectParams, _grpc_testing_Empty, _grpc_testing_ReconnectParams__Output, _grpc_testing_Empty__Output> + Stop: MethodDefinition<_grpc_testing_Empty, _grpc_testing_ReconnectInfo, _grpc_testing_Empty__Output, _grpc_testing_ReconnectInfo__Output> +} diff --git a/packages/grpc-js-xds/interop/generated/grpc/testing/ResponseParameters.ts b/packages/grpc-js-xds/interop/generated/grpc/testing/ResponseParameters.ts index 04ca94ced..15f2f01f4 100644 --- a/packages/grpc-js-xds/interop/generated/grpc/testing/ResponseParameters.ts +++ b/packages/grpc-js-xds/interop/generated/grpc/testing/ResponseParameters.ts @@ -21,7 +21,7 @@ export interface ResponseParameters { * implement the full compression tests by introspecting the call to verify * the response's compression status. */ - 'compressed'?: (_grpc_testing_BoolValue); + 'compressed'?: (_grpc_testing_BoolValue | null); } /** @@ -43,5 +43,5 @@ export interface ResponseParameters__Output { * implement the full compression tests by introspecting the call to verify * the response's compression status. */ - 'compressed'?: (_grpc_testing_BoolValue__Output); + 'compressed': (_grpc_testing_BoolValue__Output | null); } diff --git a/packages/grpc-js-xds/interop/generated/grpc/testing/SimpleRequest.ts b/packages/grpc-js-xds/interop/generated/grpc/testing/SimpleRequest.ts index 056eb10b2..21843af69 100644 --- a/packages/grpc-js-xds/interop/generated/grpc/testing/SimpleRequest.ts +++ b/packages/grpc-js-xds/interop/generated/grpc/testing/SimpleRequest.ts @@ -1,6 +1,6 @@ // Original file: proto/grpc/testing/messages.proto -import type { PayloadType as _grpc_testing_PayloadType } from '../../grpc/testing/PayloadType'; +import type { PayloadType as _grpc_testing_PayloadType, PayloadType__Output as _grpc_testing_PayloadType__Output } from '../../grpc/testing/PayloadType'; import type { Payload as _grpc_testing_Payload, Payload__Output as _grpc_testing_Payload__Output } from '../../grpc/testing/Payload'; import type { BoolValue as _grpc_testing_BoolValue, BoolValue__Output as _grpc_testing_BoolValue__Output } from '../../grpc/testing/BoolValue'; import type { EchoStatus as _grpc_testing_EchoStatus, EchoStatus__Output as _grpc_testing_EchoStatus__Output } from '../../grpc/testing/EchoStatus'; @@ -13,7 +13,7 @@ export interface SimpleRequest { * Desired payload type in the response from the server. * If response_type is RANDOM, server randomly chooses one from other formats. */ - 'response_type'?: (_grpc_testing_PayloadType | keyof typeof _grpc_testing_PayloadType); + 'response_type'?: (_grpc_testing_PayloadType); /** * Desired payload size in the response from the server. */ @@ -21,7 +21,7 @@ export interface SimpleRequest { /** * Optional input payload sent along with the request. */ - 'payload'?: (_grpc_testing_Payload); + 'payload'?: (_grpc_testing_Payload | null); /** * Whether SimpleResponse should include username. */ @@ -36,15 +36,15 @@ export interface SimpleRequest { * implement the full compression tests by introspecting the call to verify * the response's compression status. */ - 'response_compressed'?: (_grpc_testing_BoolValue); + 'response_compressed'?: (_grpc_testing_BoolValue | null); /** * Whether server should return a given status */ - 'response_status'?: (_grpc_testing_EchoStatus); + 'response_status'?: (_grpc_testing_EchoStatus | null); /** * Whether the server should expect this request to be compressed. */ - 'expect_compressed'?: (_grpc_testing_BoolValue); + 'expect_compressed'?: (_grpc_testing_BoolValue | null); /** * Whether SimpleResponse should include server_id. */ @@ -63,7 +63,7 @@ export interface SimpleRequest__Output { * Desired payload type in the response from the server. * If response_type is RANDOM, server randomly chooses one from other formats. */ - 'response_type': (keyof typeof _grpc_testing_PayloadType); + 'response_type': (_grpc_testing_PayloadType__Output); /** * Desired payload size in the response from the server. */ @@ -71,7 +71,7 @@ export interface SimpleRequest__Output { /** * Optional input payload sent along with the request. */ - 'payload'?: (_grpc_testing_Payload__Output); + 'payload': (_grpc_testing_Payload__Output | null); /** * Whether SimpleResponse should include username. */ @@ -86,15 +86,15 @@ export interface SimpleRequest__Output { * implement the full compression tests by introspecting the call to verify * the response's compression status. */ - 'response_compressed'?: (_grpc_testing_BoolValue__Output); + 'response_compressed': (_grpc_testing_BoolValue__Output | null); /** * Whether server should return a given status */ - 'response_status'?: (_grpc_testing_EchoStatus__Output); + 'response_status': (_grpc_testing_EchoStatus__Output | null); /** * Whether the server should expect this request to be compressed. */ - 'expect_compressed'?: (_grpc_testing_BoolValue__Output); + 'expect_compressed': (_grpc_testing_BoolValue__Output | null); /** * Whether SimpleResponse should include server_id. */ diff --git a/packages/grpc-js-xds/interop/generated/grpc/testing/SimpleResponse.ts b/packages/grpc-js-xds/interop/generated/grpc/testing/SimpleResponse.ts index 661f336ce..b737c31fa 100644 --- a/packages/grpc-js-xds/interop/generated/grpc/testing/SimpleResponse.ts +++ b/packages/grpc-js-xds/interop/generated/grpc/testing/SimpleResponse.ts @@ -1,7 +1,7 @@ // Original file: proto/grpc/testing/messages.proto import type { Payload as _grpc_testing_Payload, Payload__Output as _grpc_testing_Payload__Output } from '../../grpc/testing/Payload'; -import type { GrpclbRouteType as _grpc_testing_GrpclbRouteType } from '../../grpc/testing/GrpclbRouteType'; +import type { GrpclbRouteType as _grpc_testing_GrpclbRouteType, GrpclbRouteType__Output as _grpc_testing_GrpclbRouteType__Output } from '../../grpc/testing/GrpclbRouteType'; /** * Unary response, as configured by the request. @@ -10,7 +10,7 @@ export interface SimpleResponse { /** * Payload to increase message size. */ - 'payload'?: (_grpc_testing_Payload); + 'payload'?: (_grpc_testing_Payload | null); /** * The user the request came from, for verifying authentication was * successful when the client expected it. @@ -28,7 +28,7 @@ export interface SimpleResponse { /** * gRPCLB Path. */ - 'grpclb_route_type'?: (_grpc_testing_GrpclbRouteType | keyof typeof _grpc_testing_GrpclbRouteType); + 'grpclb_route_type'?: (_grpc_testing_GrpclbRouteType); /** * Server hostname. */ @@ -42,7 +42,7 @@ export interface SimpleResponse__Output { /** * Payload to increase message size. */ - 'payload'?: (_grpc_testing_Payload__Output); + 'payload': (_grpc_testing_Payload__Output | null); /** * The user the request came from, for verifying authentication was * successful when the client expected it. @@ -60,7 +60,7 @@ export interface SimpleResponse__Output { /** * gRPCLB Path. */ - 'grpclb_route_type': (keyof typeof _grpc_testing_GrpclbRouteType); + 'grpclb_route_type': (_grpc_testing_GrpclbRouteType__Output); /** * Server hostname. */ diff --git a/packages/grpc-js-xds/interop/generated/grpc/testing/StreamingInputCallRequest.ts b/packages/grpc-js-xds/interop/generated/grpc/testing/StreamingInputCallRequest.ts index 56ad2b217..f45568849 100644 --- a/packages/grpc-js-xds/interop/generated/grpc/testing/StreamingInputCallRequest.ts +++ b/packages/grpc-js-xds/interop/generated/grpc/testing/StreamingInputCallRequest.ts @@ -10,14 +10,14 @@ export interface StreamingInputCallRequest { /** * Optional input payload sent along with the request. */ - 'payload'?: (_grpc_testing_Payload); + 'payload'?: (_grpc_testing_Payload | null); /** * Whether the server should expect this request to be compressed. This field * is "nullable" in order to interoperate seamlessly with servers not able to * implement the full compression tests by introspecting the call to verify * the request's compression status. */ - 'expect_compressed'?: (_grpc_testing_BoolValue); + 'expect_compressed'?: (_grpc_testing_BoolValue | null); } /** @@ -27,12 +27,12 @@ export interface StreamingInputCallRequest__Output { /** * Optional input payload sent along with the request. */ - 'payload'?: (_grpc_testing_Payload__Output); + 'payload': (_grpc_testing_Payload__Output | null); /** * Whether the server should expect this request to be compressed. This field * is "nullable" in order to interoperate seamlessly with servers not able to * implement the full compression tests by introspecting the call to verify * the request's compression status. */ - 'expect_compressed'?: (_grpc_testing_BoolValue__Output); + 'expect_compressed': (_grpc_testing_BoolValue__Output | null); } diff --git a/packages/grpc-js-xds/interop/generated/grpc/testing/StreamingOutputCallRequest.ts b/packages/grpc-js-xds/interop/generated/grpc/testing/StreamingOutputCallRequest.ts index 52922062d..0d812b74f 100644 --- a/packages/grpc-js-xds/interop/generated/grpc/testing/StreamingOutputCallRequest.ts +++ b/packages/grpc-js-xds/interop/generated/grpc/testing/StreamingOutputCallRequest.ts @@ -1,6 +1,6 @@ // Original file: proto/grpc/testing/messages.proto -import type { PayloadType as _grpc_testing_PayloadType } from '../../grpc/testing/PayloadType'; +import type { PayloadType as _grpc_testing_PayloadType, PayloadType__Output as _grpc_testing_PayloadType__Output } from '../../grpc/testing/PayloadType'; import type { ResponseParameters as _grpc_testing_ResponseParameters, ResponseParameters__Output as _grpc_testing_ResponseParameters__Output } from '../../grpc/testing/ResponseParameters'; import type { Payload as _grpc_testing_Payload, Payload__Output as _grpc_testing_Payload__Output } from '../../grpc/testing/Payload'; import type { EchoStatus as _grpc_testing_EchoStatus, EchoStatus__Output as _grpc_testing_EchoStatus__Output } from '../../grpc/testing/EchoStatus'; @@ -15,7 +15,7 @@ export interface StreamingOutputCallRequest { * might be of different types. This is to simulate a mixed type of payload * stream. */ - 'response_type'?: (_grpc_testing_PayloadType | keyof typeof _grpc_testing_PayloadType); + 'response_type'?: (_grpc_testing_PayloadType); /** * Configuration for each expected response message. */ @@ -23,11 +23,11 @@ export interface StreamingOutputCallRequest { /** * Optional input payload sent along with the request. */ - 'payload'?: (_grpc_testing_Payload); + 'payload'?: (_grpc_testing_Payload | null); /** * Whether server should return a given status */ - 'response_status'?: (_grpc_testing_EchoStatus); + 'response_status'?: (_grpc_testing_EchoStatus | null); } /** @@ -40,7 +40,7 @@ export interface StreamingOutputCallRequest__Output { * might be of different types. This is to simulate a mixed type of payload * stream. */ - 'response_type': (keyof typeof _grpc_testing_PayloadType); + 'response_type': (_grpc_testing_PayloadType__Output); /** * Configuration for each expected response message. */ @@ -48,9 +48,9 @@ export interface StreamingOutputCallRequest__Output { /** * Optional input payload sent along with the request. */ - 'payload'?: (_grpc_testing_Payload__Output); + 'payload': (_grpc_testing_Payload__Output | null); /** * Whether server should return a given status */ - 'response_status'?: (_grpc_testing_EchoStatus__Output); + 'response_status': (_grpc_testing_EchoStatus__Output | null); } diff --git a/packages/grpc-js-xds/interop/generated/grpc/testing/StreamingOutputCallResponse.ts b/packages/grpc-js-xds/interop/generated/grpc/testing/StreamingOutputCallResponse.ts index 19ab306dd..e2eb435cd 100644 --- a/packages/grpc-js-xds/interop/generated/grpc/testing/StreamingOutputCallResponse.ts +++ b/packages/grpc-js-xds/interop/generated/grpc/testing/StreamingOutputCallResponse.ts @@ -9,7 +9,7 @@ export interface StreamingOutputCallResponse { /** * Payload to increase response size. */ - 'payload'?: (_grpc_testing_Payload); + 'payload'?: (_grpc_testing_Payload | null); } /** @@ -19,5 +19,5 @@ export interface StreamingOutputCallResponse__Output { /** * Payload to increase response size. */ - 'payload'?: (_grpc_testing_Payload__Output); + 'payload': (_grpc_testing_Payload__Output | null); } diff --git a/packages/grpc-js-xds/interop/generated/grpc/testing/TestService.ts b/packages/grpc-js-xds/interop/generated/grpc/testing/TestService.ts index dbb606c83..139d3c0ef 100644 --- a/packages/grpc-js-xds/interop/generated/grpc/testing/TestService.ts +++ b/packages/grpc-js-xds/interop/generated/grpc/testing/TestService.ts @@ -1,6 +1,7 @@ // Original file: proto/grpc/testing/test.proto import type * as grpc from '@grpc/grpc-js' +import type { MethodDefinition } from '@grpc/proto-loader' import type { Empty as _grpc_testing_Empty, Empty__Output as _grpc_testing_Empty__Output } from '../../grpc/testing/Empty'; import type { SimpleRequest as _grpc_testing_SimpleRequest, SimpleRequest__Output as _grpc_testing_SimpleRequest__Output } from '../../grpc/testing/SimpleRequest'; import type { SimpleResponse as _grpc_testing_SimpleResponse, SimpleResponse__Output as _grpc_testing_SimpleResponse__Output } from '../../grpc/testing/SimpleResponse'; @@ -19,34 +20,34 @@ export interface TestServiceClient extends grpc.Client { * headers set such that a caching HTTP proxy (such as GFE) can * satisfy subsequent requests. */ - CacheableUnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall; - CacheableUnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall; - CacheableUnaryCall(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall; - CacheableUnaryCall(argument: _grpc_testing_SimpleRequest, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall; + CacheableUnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + CacheableUnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + CacheableUnaryCall(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + CacheableUnaryCall(argument: _grpc_testing_SimpleRequest, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; /** * One request followed by one response. Response has cache control * headers set such that a caching HTTP proxy (such as GFE) can * satisfy subsequent requests. */ - cacheableUnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall; - cacheableUnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall; - cacheableUnaryCall(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall; - cacheableUnaryCall(argument: _grpc_testing_SimpleRequest, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall; + cacheableUnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + cacheableUnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + cacheableUnaryCall(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + cacheableUnaryCall(argument: _grpc_testing_SimpleRequest, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; /** * One empty request followed by one empty response. */ - EmptyCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - EmptyCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - EmptyCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - EmptyCall(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; + EmptyCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + EmptyCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + EmptyCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + EmptyCall(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; /** * One empty request followed by one empty response. */ - emptyCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - emptyCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - emptyCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - emptyCall(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; + emptyCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + emptyCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + emptyCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + emptyCall(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; /** * A sequence of requests with each request served by the server immediately. @@ -84,18 +85,18 @@ export interface TestServiceClient extends grpc.Client { * A sequence of requests followed by one response (streamed upload). * The server returns the aggregated size of client payload as the result. */ - StreamingInputCall(metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_StreamingInputCallResponse__Output) => void): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>; - StreamingInputCall(metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_StreamingInputCallResponse__Output) => void): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>; - StreamingInputCall(options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_StreamingInputCallResponse__Output) => void): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>; - StreamingInputCall(callback: (error?: grpc.ServiceError, result?: _grpc_testing_StreamingInputCallResponse__Output) => void): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>; + StreamingInputCall(metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_StreamingInputCallResponse__Output>): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>; + StreamingInputCall(metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_StreamingInputCallResponse__Output>): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>; + StreamingInputCall(options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_StreamingInputCallResponse__Output>): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>; + StreamingInputCall(callback: grpc.requestCallback<_grpc_testing_StreamingInputCallResponse__Output>): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>; /** * A sequence of requests followed by one response (streamed upload). * The server returns the aggregated size of client payload as the result. */ - streamingInputCall(metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_StreamingInputCallResponse__Output) => void): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>; - streamingInputCall(metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_StreamingInputCallResponse__Output) => void): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>; - streamingInputCall(options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_StreamingInputCallResponse__Output) => void): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>; - streamingInputCall(callback: (error?: grpc.ServiceError, result?: _grpc_testing_StreamingInputCallResponse__Output) => void): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>; + streamingInputCall(metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_StreamingInputCallResponse__Output>): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>; + streamingInputCall(metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_StreamingInputCallResponse__Output>): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>; + streamingInputCall(options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_StreamingInputCallResponse__Output>): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>; + streamingInputCall(callback: grpc.requestCallback<_grpc_testing_StreamingInputCallResponse__Output>): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>; /** * One request followed by a sequence of responses (streamed download). @@ -113,34 +114,34 @@ export interface TestServiceClient extends grpc.Client { /** * One request followed by one response. */ - UnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall; - UnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall; - UnaryCall(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall; - UnaryCall(argument: _grpc_testing_SimpleRequest, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall; + UnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + UnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + UnaryCall(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + UnaryCall(argument: _grpc_testing_SimpleRequest, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; /** * One request followed by one response. */ - unaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall; - unaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall; - unaryCall(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall; - unaryCall(argument: _grpc_testing_SimpleRequest, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall; + unaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + unaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + unaryCall(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + unaryCall(argument: _grpc_testing_SimpleRequest, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; /** * The test server will not implement this method. It will be used * to test the behavior when clients call unimplemented methods. */ - UnimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - UnimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - UnimplementedCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - UnimplementedCall(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; + UnimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + UnimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + UnimplementedCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + UnimplementedCall(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; /** * The test server will not implement this method. It will be used * to test the behavior when clients call unimplemented methods. */ - unimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - unimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - unimplementedCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - unimplementedCall(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; + unimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + unimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + unimplementedCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + unimplementedCall(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; } @@ -200,3 +201,14 @@ export interface TestServiceHandlers extends grpc.UntypedServiceImplementation { UnimplementedCall: grpc.handleUnaryCall<_grpc_testing_Empty__Output, _grpc_testing_Empty>; } + +export interface TestServiceDefinition extends grpc.ServiceDefinition { + CacheableUnaryCall: MethodDefinition<_grpc_testing_SimpleRequest, _grpc_testing_SimpleResponse, _grpc_testing_SimpleRequest__Output, _grpc_testing_SimpleResponse__Output> + EmptyCall: MethodDefinition<_grpc_testing_Empty, _grpc_testing_Empty, _grpc_testing_Empty__Output, _grpc_testing_Empty__Output> + FullDuplexCall: MethodDefinition<_grpc_testing_StreamingOutputCallRequest, _grpc_testing_StreamingOutputCallResponse, _grpc_testing_StreamingOutputCallRequest__Output, _grpc_testing_StreamingOutputCallResponse__Output> + HalfDuplexCall: MethodDefinition<_grpc_testing_StreamingOutputCallRequest, _grpc_testing_StreamingOutputCallResponse, _grpc_testing_StreamingOutputCallRequest__Output, _grpc_testing_StreamingOutputCallResponse__Output> + StreamingInputCall: MethodDefinition<_grpc_testing_StreamingInputCallRequest, _grpc_testing_StreamingInputCallResponse, _grpc_testing_StreamingInputCallRequest__Output, _grpc_testing_StreamingInputCallResponse__Output> + StreamingOutputCall: MethodDefinition<_grpc_testing_StreamingOutputCallRequest, _grpc_testing_StreamingOutputCallResponse, _grpc_testing_StreamingOutputCallRequest__Output, _grpc_testing_StreamingOutputCallResponse__Output> + UnaryCall: MethodDefinition<_grpc_testing_SimpleRequest, _grpc_testing_SimpleResponse, _grpc_testing_SimpleRequest__Output, _grpc_testing_SimpleResponse__Output> + UnimplementedCall: MethodDefinition<_grpc_testing_Empty, _grpc_testing_Empty, _grpc_testing_Empty__Output, _grpc_testing_Empty__Output> +} diff --git a/packages/grpc-js-xds/interop/generated/grpc/testing/UnimplementedService.ts b/packages/grpc-js-xds/interop/generated/grpc/testing/UnimplementedService.ts index d21dfcd0f..aea5d8b4a 100644 --- a/packages/grpc-js-xds/interop/generated/grpc/testing/UnimplementedService.ts +++ b/packages/grpc-js-xds/interop/generated/grpc/testing/UnimplementedService.ts @@ -1,6 +1,7 @@ // Original file: proto/grpc/testing/test.proto import type * as grpc from '@grpc/grpc-js' +import type { MethodDefinition } from '@grpc/proto-loader' import type { Empty as _grpc_testing_Empty, Empty__Output as _grpc_testing_Empty__Output } from '../../grpc/testing/Empty'; /** @@ -11,17 +12,17 @@ export interface UnimplementedServiceClient extends grpc.Client { /** * A call that no server should implement */ - UnimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - UnimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - UnimplementedCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - UnimplementedCall(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; + UnimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + UnimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + UnimplementedCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + UnimplementedCall(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; /** * A call that no server should implement */ - unimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - unimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - unimplementedCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - unimplementedCall(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; + unimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + unimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + unimplementedCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + unimplementedCall(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; } @@ -36,3 +37,7 @@ export interface UnimplementedServiceHandlers extends grpc.UntypedServiceImpleme UnimplementedCall: grpc.handleUnaryCall<_grpc_testing_Empty__Output, _grpc_testing_Empty>; } + +export interface UnimplementedServiceDefinition extends grpc.ServiceDefinition { + UnimplementedCall: MethodDefinition<_grpc_testing_Empty, _grpc_testing_Empty, _grpc_testing_Empty__Output, _grpc_testing_Empty__Output> +} diff --git a/packages/grpc-js-xds/interop/generated/grpc/testing/XdsUpdateClientConfigureService.ts b/packages/grpc-js-xds/interop/generated/grpc/testing/XdsUpdateClientConfigureService.ts index 22947619c..76826b812 100644 --- a/packages/grpc-js-xds/interop/generated/grpc/testing/XdsUpdateClientConfigureService.ts +++ b/packages/grpc-js-xds/interop/generated/grpc/testing/XdsUpdateClientConfigureService.ts @@ -1,6 +1,7 @@ // Original file: proto/grpc/testing/test.proto import type * as grpc from '@grpc/grpc-js' +import type { MethodDefinition } from '@grpc/proto-loader' import type { ClientConfigureRequest as _grpc_testing_ClientConfigureRequest, ClientConfigureRequest__Output as _grpc_testing_ClientConfigureRequest__Output } from '../../grpc/testing/ClientConfigureRequest'; import type { ClientConfigureResponse as _grpc_testing_ClientConfigureResponse, ClientConfigureResponse__Output as _grpc_testing_ClientConfigureResponse__Output } from '../../grpc/testing/ClientConfigureResponse'; @@ -11,17 +12,17 @@ export interface XdsUpdateClientConfigureServiceClient extends grpc.Client { /** * Update the tes client's configuration. */ - Configure(argument: _grpc_testing_ClientConfigureRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ClientConfigureResponse__Output) => void): grpc.ClientUnaryCall; - Configure(argument: _grpc_testing_ClientConfigureRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ClientConfigureResponse__Output) => void): grpc.ClientUnaryCall; - Configure(argument: _grpc_testing_ClientConfigureRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ClientConfigureResponse__Output) => void): grpc.ClientUnaryCall; - Configure(argument: _grpc_testing_ClientConfigureRequest, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ClientConfigureResponse__Output) => void): grpc.ClientUnaryCall; + Configure(argument: _grpc_testing_ClientConfigureRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_ClientConfigureResponse__Output>): grpc.ClientUnaryCall; + Configure(argument: _grpc_testing_ClientConfigureRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_ClientConfigureResponse__Output>): grpc.ClientUnaryCall; + Configure(argument: _grpc_testing_ClientConfigureRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_ClientConfigureResponse__Output>): grpc.ClientUnaryCall; + Configure(argument: _grpc_testing_ClientConfigureRequest, callback: grpc.requestCallback<_grpc_testing_ClientConfigureResponse__Output>): grpc.ClientUnaryCall; /** * Update the tes client's configuration. */ - configure(argument: _grpc_testing_ClientConfigureRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ClientConfigureResponse__Output) => void): grpc.ClientUnaryCall; - configure(argument: _grpc_testing_ClientConfigureRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ClientConfigureResponse__Output) => void): grpc.ClientUnaryCall; - configure(argument: _grpc_testing_ClientConfigureRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ClientConfigureResponse__Output) => void): grpc.ClientUnaryCall; - configure(argument: _grpc_testing_ClientConfigureRequest, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ClientConfigureResponse__Output) => void): grpc.ClientUnaryCall; + configure(argument: _grpc_testing_ClientConfigureRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_ClientConfigureResponse__Output>): grpc.ClientUnaryCall; + configure(argument: _grpc_testing_ClientConfigureRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_ClientConfigureResponse__Output>): grpc.ClientUnaryCall; + configure(argument: _grpc_testing_ClientConfigureRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_ClientConfigureResponse__Output>): grpc.ClientUnaryCall; + configure(argument: _grpc_testing_ClientConfigureRequest, callback: grpc.requestCallback<_grpc_testing_ClientConfigureResponse__Output>): grpc.ClientUnaryCall; } @@ -35,3 +36,7 @@ export interface XdsUpdateClientConfigureServiceHandlers extends grpc.UntypedSer Configure: grpc.handleUnaryCall<_grpc_testing_ClientConfigureRequest__Output, _grpc_testing_ClientConfigureResponse>; } + +export interface XdsUpdateClientConfigureServiceDefinition extends grpc.ServiceDefinition { + Configure: MethodDefinition<_grpc_testing_ClientConfigureRequest, _grpc_testing_ClientConfigureResponse, _grpc_testing_ClientConfigureRequest__Output, _grpc_testing_ClientConfigureResponse__Output> +} diff --git a/packages/grpc-js-xds/interop/generated/grpc/testing/XdsUpdateHealthService.ts b/packages/grpc-js-xds/interop/generated/grpc/testing/XdsUpdateHealthService.ts index aa1e35dca..aa3d6e9c6 100644 --- a/packages/grpc-js-xds/interop/generated/grpc/testing/XdsUpdateHealthService.ts +++ b/packages/grpc-js-xds/interop/generated/grpc/testing/XdsUpdateHealthService.ts @@ -1,29 +1,30 @@ // Original file: proto/grpc/testing/test.proto import type * as grpc from '@grpc/grpc-js' +import type { MethodDefinition } from '@grpc/proto-loader' import type { Empty as _grpc_testing_Empty, Empty__Output as _grpc_testing_Empty__Output } from '../../grpc/testing/Empty'; /** * A service to remotely control health status of an xDS test server. */ export interface XdsUpdateHealthServiceClient extends grpc.Client { - SetNotServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - SetNotServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - SetNotServing(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - SetNotServing(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - setNotServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - setNotServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - setNotServing(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - setNotServing(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; + SetNotServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + SetNotServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + SetNotServing(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + SetNotServing(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + setNotServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + setNotServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + setNotServing(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + setNotServing(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; - SetServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - SetServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - SetServing(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - SetServing(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - setServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - setServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - setServing(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; - setServing(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall; + SetServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + SetServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + SetServing(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + SetServing(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + setServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + setServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + setServing(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; + setServing(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall; } @@ -36,3 +37,8 @@ export interface XdsUpdateHealthServiceHandlers extends grpc.UntypedServiceImple SetServing: grpc.handleUnaryCall<_grpc_testing_Empty__Output, _grpc_testing_Empty>; } + +export interface XdsUpdateHealthServiceDefinition extends grpc.ServiceDefinition { + SetNotServing: MethodDefinition<_grpc_testing_Empty, _grpc_testing_Empty, _grpc_testing_Empty__Output, _grpc_testing_Empty__Output> + SetServing: MethodDefinition<_grpc_testing_Empty, _grpc_testing_Empty, _grpc_testing_Empty__Output, _grpc_testing_Empty__Output> +} diff --git a/packages/grpc-js-xds/interop/generated/test.ts b/packages/grpc-js-xds/interop/generated/test.ts index f91f0c970..722f8fe28 100644 --- a/packages/grpc-js-xds/interop/generated/test.ts +++ b/packages/grpc-js-xds/interop/generated/test.ts @@ -1,12 +1,12 @@ import type * as grpc from '@grpc/grpc-js'; -import type { ServiceDefinition, EnumTypeDefinition, MessageTypeDefinition } from '@grpc/proto-loader'; +import type { EnumTypeDefinition, MessageTypeDefinition } from '@grpc/proto-loader'; -import type { LoadBalancerStatsServiceClient as _grpc_testing_LoadBalancerStatsServiceClient } from './grpc/testing/LoadBalancerStatsService'; -import type { ReconnectServiceClient as _grpc_testing_ReconnectServiceClient } from './grpc/testing/ReconnectService'; -import type { TestServiceClient as _grpc_testing_TestServiceClient } from './grpc/testing/TestService'; -import type { UnimplementedServiceClient as _grpc_testing_UnimplementedServiceClient } from './grpc/testing/UnimplementedService'; -import type { XdsUpdateClientConfigureServiceClient as _grpc_testing_XdsUpdateClientConfigureServiceClient } from './grpc/testing/XdsUpdateClientConfigureService'; -import type { XdsUpdateHealthServiceClient as _grpc_testing_XdsUpdateHealthServiceClient } from './grpc/testing/XdsUpdateHealthService'; +import type { LoadBalancerStatsServiceClient as _grpc_testing_LoadBalancerStatsServiceClient, LoadBalancerStatsServiceDefinition as _grpc_testing_LoadBalancerStatsServiceDefinition } from './grpc/testing/LoadBalancerStatsService'; +import type { ReconnectServiceClient as _grpc_testing_ReconnectServiceClient, ReconnectServiceDefinition as _grpc_testing_ReconnectServiceDefinition } from './grpc/testing/ReconnectService'; +import type { TestServiceClient as _grpc_testing_TestServiceClient, TestServiceDefinition as _grpc_testing_TestServiceDefinition } from './grpc/testing/TestService'; +import type { UnimplementedServiceClient as _grpc_testing_UnimplementedServiceClient, UnimplementedServiceDefinition as _grpc_testing_UnimplementedServiceDefinition } from './grpc/testing/UnimplementedService'; +import type { XdsUpdateClientConfigureServiceClient as _grpc_testing_XdsUpdateClientConfigureServiceClient, XdsUpdateClientConfigureServiceDefinition as _grpc_testing_XdsUpdateClientConfigureServiceDefinition } from './grpc/testing/XdsUpdateClientConfigureService'; +import type { XdsUpdateHealthServiceClient as _grpc_testing_XdsUpdateHealthServiceClient, XdsUpdateHealthServiceDefinition as _grpc_testing_XdsUpdateHealthServiceDefinition } from './grpc/testing/XdsUpdateHealthService'; type SubtypeConstructor any, Subtype> = { new(...args: ConstructorParameters): Subtype; @@ -28,7 +28,7 @@ export interface ProtoGrpcType { /** * A service used to obtain stats for verifying LB behavior. */ - LoadBalancerStatsService: SubtypeConstructor & { service: ServiceDefinition } + LoadBalancerStatsService: SubtypeConstructor & { service: _grpc_testing_LoadBalancerStatsServiceDefinition } Payload: MessageTypeDefinition PayloadType: EnumTypeDefinition ReconnectInfo: MessageTypeDefinition @@ -36,7 +36,7 @@ export interface ProtoGrpcType { /** * A service used to control reconnect server. */ - ReconnectService: SubtypeConstructor & { service: ServiceDefinition } + ReconnectService: SubtypeConstructor & { service: _grpc_testing_ReconnectServiceDefinition } ResponseParameters: MessageTypeDefinition SimpleRequest: MessageTypeDefinition SimpleResponse: MessageTypeDefinition @@ -48,20 +48,20 @@ export interface ProtoGrpcType { * A simple service to test the various types of RPCs and experiment with * performance with various types of payload. */ - TestService: SubtypeConstructor & { service: ServiceDefinition } + TestService: SubtypeConstructor & { service: _grpc_testing_TestServiceDefinition } /** * A simple service NOT implemented at servers so clients can test for * that case. */ - UnimplementedService: SubtypeConstructor & { service: ServiceDefinition } + UnimplementedService: SubtypeConstructor & { service: _grpc_testing_UnimplementedServiceDefinition } /** * A service to dynamically update the configuration of an xDS test client. */ - XdsUpdateClientConfigureService: SubtypeConstructor & { service: ServiceDefinition } + XdsUpdateClientConfigureService: SubtypeConstructor & { service: _grpc_testing_XdsUpdateClientConfigureServiceDefinition } /** * A service to remotely control health status of an xDS test server. */ - XdsUpdateHealthService: SubtypeConstructor & { service: ServiceDefinition } + XdsUpdateHealthService: SubtypeConstructor & { service: _grpc_testing_XdsUpdateHealthServiceDefinition } } } } diff --git a/packages/grpc-js-xds/interop/xds-interop-client.ts b/packages/grpc-js-xds/interop/xds-interop-client.ts index 1fdaa3a69..a245ad09f 100644 --- a/packages/grpc-js-xds/interop/xds-interop-client.ts +++ b/packages/grpc-js-xds/interop/xds-interop-client.ts @@ -398,7 +398,7 @@ function makeSingleRequest(client: TestServiceClient, type: CallType, failOnFail const startTime = process.hrtime.bigint(); const deadline = new Date(); deadline.setSeconds(deadline.getSeconds() + currentConfig.timeoutSec); - const callback = (error: grpc.ServiceError | undefined, value: Empty__Output | undefined) => { + const callback = (error: grpc.ServiceError | null, value: Empty__Output | undefined) => { const statusCode = error?.code ?? grpc.status.OK; const duration = process.hrtime.bigint() - startTime; const durationSeconds = Number(duration / TIMESTAMP_ONE_SECOND) | 0; diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index 1286a16a8..9e7d2f18a 100644 --- a/packages/grpc-js-xds/package.json +++ b/packages/grpc-js-xds/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js-xds", - "version": "1.10.0", + "version": "1.10.1", "description": "Plugin for @grpc/grpc-js. Adds the xds:// URL scheme and associated features.", "main": "build/src/index.js", "scripts": { @@ -12,7 +12,7 @@ "prepare": "npm run generate-types && npm run compile", "pretest": "npm run compile", "posttest": "npm run check", - "generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs deps/envoy-api/ deps/xds/ deps/googleapis/ deps/protoc-gen-validate/ -O src/generated/ --grpcLib @grpc/grpc-js envoy/service/discovery/v3/ads.proto envoy/service/load_stats/v3/lrs.proto envoy/config/listener/v3/listener.proto envoy/config/route/v3/route.proto envoy/config/cluster/v3/cluster.proto envoy/config/endpoint/v3/endpoint.proto envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto udpa/type/v1/typed_struct.proto xds/type/v3/typed_struct.proto envoy/extensions/filters/http/fault/v3/fault.proto envoy/service/status/v3/csds.proto envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.proto envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.proto envoy/extensions/load_balancing_policies/pick_first/v3/pick_first.proto", + "generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs deps/envoy-api/ deps/xds/ deps/googleapis/ deps/protoc-gen-validate/ -O src/generated/ --grpcLib @grpc/grpc-js envoy/service/discovery/v3/ads.proto envoy/service/load_stats/v3/lrs.proto envoy/config/listener/v3/listener.proto envoy/config/route/v3/route.proto envoy/config/cluster/v3/cluster.proto envoy/config/endpoint/v3/endpoint.proto envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto udpa/type/v1/typed_struct.proto xds/type/v3/typed_struct.proto envoy/extensions/filters/http/fault/v3/fault.proto envoy/service/status/v3/csds.proto envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.proto envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.proto envoy/extensions/load_balancing_policies/pick_first/v3/pick_first.proto envoy/extensions/clusters/aggregate/v3/cluster.proto", "generate-interop-types": "proto-loader-gen-types --keep-case --longs String --enums String --defaults --oneofs --json --includeComments --includeDirs proto/ -O interop/generated --grpcLib @grpc/grpc-js grpc/testing/test.proto", "generate-test-types": "proto-loader-gen-types --keep-case --longs String --enums String --defaults --oneofs --json --includeComments --includeDirs proto/ -O test/generated --grpcLib @grpc/grpc-js grpc/testing/echo.proto" }, @@ -43,7 +43,7 @@ "yargs": "^15.4.1" }, "dependencies": { - "@grpc/proto-loader": "^0.6.0", + "@grpc/proto-loader": "^0.7.13", "google-auth-library": "^7.0.2", "re2-wasm": "^1.0.1", "vscode-uri": "^3.0.7", diff --git a/packages/grpc-js-xds/src/generated/cluster.ts b/packages/grpc-js-xds/src/generated/cluster.ts index 1aa37589b..6e8c5f985 100644 --- a/packages/grpc-js-xds/src/generated/cluster.ts +++ b/packages/grpc-js-xds/src/generated/cluster.ts @@ -101,6 +101,15 @@ export interface ProtoGrpcType { } } } + extensions: { + clusters: { + aggregate: { + v3: { + ClusterConfig: MessageTypeDefinition + } + } + } + } type: { matcher: { v3: { diff --git a/packages/grpc-js-xds/src/generated/envoy/admin/v3/BootstrapConfigDump.ts b/packages/grpc-js-xds/src/generated/envoy/admin/v3/BootstrapConfigDump.ts deleted file mode 100644 index d47f00ef3..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/admin/v3/BootstrapConfigDump.ts +++ /dev/null @@ -1,32 +0,0 @@ -// Original file: deps/envoy-api/envoy/admin/v3/config_dump.proto - -import type { Bootstrap as _envoy_config_bootstrap_v3_Bootstrap, Bootstrap__Output as _envoy_config_bootstrap_v3_Bootstrap__Output } from '../../../envoy/config/bootstrap/v3/Bootstrap'; -import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp'; - -/** - * This message describes the bootstrap configuration that Envoy was started with. This includes - * any CLI overrides that were merged. Bootstrap configuration information can be used to recreate - * the static portions of an Envoy configuration by reusing the output as the bootstrap - * configuration for another Envoy. - */ -export interface BootstrapConfigDump { - 'bootstrap'?: (_envoy_config_bootstrap_v3_Bootstrap | null); - /** - * The timestamp when the BootstrapConfig was last updated. - */ - 'last_updated'?: (_google_protobuf_Timestamp | null); -} - -/** - * This message describes the bootstrap configuration that Envoy was started with. This includes - * any CLI overrides that were merged. Bootstrap configuration information can be used to recreate - * the static portions of an Envoy configuration by reusing the output as the bootstrap - * configuration for another Envoy. - */ -export interface BootstrapConfigDump__Output { - 'bootstrap': (_envoy_config_bootstrap_v3_Bootstrap__Output | null); - /** - * The timestamp when the BootstrapConfig was last updated. - */ - 'last_updated': (_google_protobuf_Timestamp__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/admin/v3/ClientResourceStatus.ts b/packages/grpc-js-xds/src/generated/envoy/admin/v3/ClientResourceStatus.ts index 8488bbdd7..b7a78a338 100644 --- a/packages/grpc-js-xds/src/generated/envoy/admin/v3/ClientResourceStatus.ts +++ b/packages/grpc-js-xds/src/generated/envoy/admin/v3/ClientResourceStatus.ts @@ -4,17 +4,17 @@ * Resource status from the view of a xDS client, which tells the synchronization * status between the xDS client and the xDS server. */ -export enum ClientResourceStatus { +export const ClientResourceStatus = { /** * Resource status is not available/unknown. */ - UNKNOWN = 0, + UNKNOWN: 'UNKNOWN', /** * Client requested this resource but hasn't received any update from management * server. The client will not fail requests, but will queue them until update * arrives or the client times out waiting for the resource. */ - REQUESTED = 1, + REQUESTED: 'REQUESTED', /** * This resource has been requested by the client but has either not been * delivered by the server or was previously delivered by the server and then @@ -22,13 +22,56 @@ export enum ClientResourceStatus { * information, please refer to the :ref:`"Knowing When a Requested Resource * Does Not Exist" ` section. */ - DOES_NOT_EXIST = 2, + DOES_NOT_EXIST: 'DOES_NOT_EXIST', /** * Client received this resource and replied with ACK. */ - ACKED = 3, + ACKED: 'ACKED', /** * Client received this resource and replied with NACK. */ - NACKED = 4, -} + NACKED: 'NACKED', +} as const; + +/** + * Resource status from the view of a xDS client, which tells the synchronization + * status between the xDS client and the xDS server. + */ +export type ClientResourceStatus = + /** + * Resource status is not available/unknown. + */ + | 'UNKNOWN' + | 0 + /** + * Client requested this resource but hasn't received any update from management + * server. The client will not fail requests, but will queue them until update + * arrives or the client times out waiting for the resource. + */ + | 'REQUESTED' + | 1 + /** + * This resource has been requested by the client but has either not been + * delivered by the server or was previously delivered by the server and then + * subsequently removed from resources provided by the server. For more + * information, please refer to the :ref:`"Knowing When a Requested Resource + * Does Not Exist" ` section. + */ + | 'DOES_NOT_EXIST' + | 2 + /** + * Client received this resource and replied with ACK. + */ + | 'ACKED' + | 3 + /** + * Client received this resource and replied with NACK. + */ + | 'NACKED' + | 4 + +/** + * Resource status from the view of a xDS client, which tells the synchronization + * status between the xDS client and the xDS server. + */ +export type ClientResourceStatus__Output = typeof ClientResourceStatus[keyof typeof ClientResourceStatus] diff --git a/packages/grpc-js-xds/src/generated/envoy/admin/v3/ClustersConfigDump.ts b/packages/grpc-js-xds/src/generated/envoy/admin/v3/ClustersConfigDump.ts index aabcd212a..2c3b4f8a5 100644 --- a/packages/grpc-js-xds/src/generated/envoy/admin/v3/ClustersConfigDump.ts +++ b/packages/grpc-js-xds/src/generated/envoy/admin/v3/ClustersConfigDump.ts @@ -3,7 +3,7 @@ import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any'; import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp'; import type { UpdateFailureState as _envoy_admin_v3_UpdateFailureState, UpdateFailureState__Output as _envoy_admin_v3_UpdateFailureState__Output } from '../../../envoy/admin/v3/UpdateFailureState'; -import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus } from '../../../envoy/admin/v3/ClientResourceStatus'; +import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus, ClientResourceStatus__Output as _envoy_admin_v3_ClientResourceStatus__Output } from '../../../envoy/admin/v3/ClientResourceStatus'; /** * Describes a dynamically loaded cluster via the CDS API. @@ -37,7 +37,7 @@ export interface _envoy_admin_v3_ClustersConfigDump_DynamicCluster { * The client status of this resource. * [#not-implemented-hide:] */ - 'client_status'?: (_envoy_admin_v3_ClientResourceStatus | keyof typeof _envoy_admin_v3_ClientResourceStatus); + 'client_status'?: (_envoy_admin_v3_ClientResourceStatus); } /** @@ -72,7 +72,7 @@ export interface _envoy_admin_v3_ClustersConfigDump_DynamicCluster__Output { * The client status of this resource. * [#not-implemented-hide:] */ - 'client_status': (keyof typeof _envoy_admin_v3_ClientResourceStatus); + 'client_status': (_envoy_admin_v3_ClientResourceStatus__Output); } /** diff --git a/packages/grpc-js-xds/src/generated/envoy/admin/v3/ConfigDump.ts b/packages/grpc-js-xds/src/generated/envoy/admin/v3/ConfigDump.ts deleted file mode 100644 index 8a0ab65c2..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/admin/v3/ConfigDump.ts +++ /dev/null @@ -1,65 +0,0 @@ -// Original file: deps/envoy-api/envoy/admin/v3/config_dump.proto - -import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any'; - -/** - * The :ref:`/config_dump ` admin endpoint uses this wrapper - * message to maintain and serve arbitrary configuration information from any component in Envoy. - */ -export interface ConfigDump { - /** - * This list is serialized and dumped in its entirety at the - * :ref:`/config_dump ` endpoint. - * - * The following configurations are currently supported and will be dumped in the order given - * below: - * - * * *bootstrap*: :ref:`BootstrapConfigDump ` - * * *clusters*: :ref:`ClustersConfigDump ` - * * *endpoints*: :ref:`EndpointsConfigDump ` - * * *listeners*: :ref:`ListenersConfigDump ` - * * *scoped_routes*: :ref:`ScopedRoutesConfigDump ` - * * *routes*: :ref:`RoutesConfigDump ` - * * *secrets*: :ref:`SecretsConfigDump ` - * - * EDS Configuration will only be dumped by using parameter `?include_eds` - * - * You can filter output with the resource and mask query parameters. - * See :ref:`/config_dump?resource={} `, - * :ref:`/config_dump?mask={} `, - * or :ref:`/config_dump?resource={},mask={} - * ` for more information. - */ - 'configs'?: (_google_protobuf_Any)[]; -} - -/** - * The :ref:`/config_dump ` admin endpoint uses this wrapper - * message to maintain and serve arbitrary configuration information from any component in Envoy. - */ -export interface ConfigDump__Output { - /** - * This list is serialized and dumped in its entirety at the - * :ref:`/config_dump ` endpoint. - * - * The following configurations are currently supported and will be dumped in the order given - * below: - * - * * *bootstrap*: :ref:`BootstrapConfigDump ` - * * *clusters*: :ref:`ClustersConfigDump ` - * * *endpoints*: :ref:`EndpointsConfigDump ` - * * *listeners*: :ref:`ListenersConfigDump ` - * * *scoped_routes*: :ref:`ScopedRoutesConfigDump ` - * * *routes*: :ref:`RoutesConfigDump ` - * * *secrets*: :ref:`SecretsConfigDump ` - * - * EDS Configuration will only be dumped by using parameter `?include_eds` - * - * You can filter output with the resource and mask query parameters. - * See :ref:`/config_dump?resource={} `, - * :ref:`/config_dump?mask={} `, - * or :ref:`/config_dump?resource={},mask={} - * ` for more information. - */ - 'configs': (_google_protobuf_Any__Output)[]; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/admin/v3/EcdsConfigDump.ts b/packages/grpc-js-xds/src/generated/envoy/admin/v3/EcdsConfigDump.ts index e63307cb5..70562962b 100644 --- a/packages/grpc-js-xds/src/generated/envoy/admin/v3/EcdsConfigDump.ts +++ b/packages/grpc-js-xds/src/generated/envoy/admin/v3/EcdsConfigDump.ts @@ -3,7 +3,7 @@ import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any'; import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp'; import type { UpdateFailureState as _envoy_admin_v3_UpdateFailureState, UpdateFailureState__Output as _envoy_admin_v3_UpdateFailureState__Output } from '../../../envoy/admin/v3/UpdateFailureState'; -import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus } from '../../../envoy/admin/v3/ClientResourceStatus'; +import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus, ClientResourceStatus__Output as _envoy_admin_v3_ClientResourceStatus__Output } from '../../../envoy/admin/v3/ClientResourceStatus'; /** * [#next-free-field: 6] @@ -36,7 +36,7 @@ export interface _envoy_admin_v3_EcdsConfigDump_EcdsFilterConfig { * The client status of this resource. * [#not-implemented-hide:] */ - 'client_status'?: (_envoy_admin_v3_ClientResourceStatus | keyof typeof _envoy_admin_v3_ClientResourceStatus); + 'client_status'?: (_envoy_admin_v3_ClientResourceStatus); } /** @@ -70,7 +70,7 @@ export interface _envoy_admin_v3_EcdsConfigDump_EcdsFilterConfig__Output { * The client status of this resource. * [#not-implemented-hide:] */ - 'client_status': (keyof typeof _envoy_admin_v3_ClientResourceStatus); + 'client_status': (_envoy_admin_v3_ClientResourceStatus__Output); } /** diff --git a/packages/grpc-js-xds/src/generated/envoy/admin/v3/EndpointsConfigDump.ts b/packages/grpc-js-xds/src/generated/envoy/admin/v3/EndpointsConfigDump.ts index ab5485dbe..3f362c5c3 100644 --- a/packages/grpc-js-xds/src/generated/envoy/admin/v3/EndpointsConfigDump.ts +++ b/packages/grpc-js-xds/src/generated/envoy/admin/v3/EndpointsConfigDump.ts @@ -3,7 +3,7 @@ import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any'; import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp'; import type { UpdateFailureState as _envoy_admin_v3_UpdateFailureState, UpdateFailureState__Output as _envoy_admin_v3_UpdateFailureState__Output } from '../../../envoy/admin/v3/UpdateFailureState'; -import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus } from '../../../envoy/admin/v3/ClientResourceStatus'; +import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus, ClientResourceStatus__Output as _envoy_admin_v3_ClientResourceStatus__Output } from '../../../envoy/admin/v3/ClientResourceStatus'; /** * [#next-free-field: 6] @@ -35,7 +35,7 @@ export interface _envoy_admin_v3_EndpointsConfigDump_DynamicEndpointConfig { * The client status of this resource. * [#not-implemented-hide:] */ - 'client_status'?: (_envoy_admin_v3_ClientResourceStatus | keyof typeof _envoy_admin_v3_ClientResourceStatus); + 'client_status'?: (_envoy_admin_v3_ClientResourceStatus); } /** @@ -68,7 +68,7 @@ export interface _envoy_admin_v3_EndpointsConfigDump_DynamicEndpointConfig__Outp * The client status of this resource. * [#not-implemented-hide:] */ - 'client_status': (keyof typeof _envoy_admin_v3_ClientResourceStatus); + 'client_status': (_envoy_admin_v3_ClientResourceStatus__Output); } export interface _envoy_admin_v3_EndpointsConfigDump_StaticEndpointConfig { diff --git a/packages/grpc-js-xds/src/generated/envoy/admin/v3/ListenersConfigDump.ts b/packages/grpc-js-xds/src/generated/envoy/admin/v3/ListenersConfigDump.ts index 946e37953..a90338fdf 100644 --- a/packages/grpc-js-xds/src/generated/envoy/admin/v3/ListenersConfigDump.ts +++ b/packages/grpc-js-xds/src/generated/envoy/admin/v3/ListenersConfigDump.ts @@ -3,7 +3,7 @@ import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any'; import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp'; import type { UpdateFailureState as _envoy_admin_v3_UpdateFailureState, UpdateFailureState__Output as _envoy_admin_v3_UpdateFailureState__Output } from '../../../envoy/admin/v3/UpdateFailureState'; -import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus } from '../../../envoy/admin/v3/ClientResourceStatus'; +import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus, ClientResourceStatus__Output as _envoy_admin_v3_ClientResourceStatus__Output } from '../../../envoy/admin/v3/ClientResourceStatus'; /** * Describes a dynamically loaded listener via the LDS API. @@ -44,7 +44,7 @@ export interface _envoy_admin_v3_ListenersConfigDump_DynamicListener { * The client status of this resource. * [#not-implemented-hide:] */ - 'client_status'?: (_envoy_admin_v3_ClientResourceStatus | keyof typeof _envoy_admin_v3_ClientResourceStatus); + 'client_status'?: (_envoy_admin_v3_ClientResourceStatus); } /** @@ -86,7 +86,7 @@ export interface _envoy_admin_v3_ListenersConfigDump_DynamicListener__Output { * The client status of this resource. * [#not-implemented-hide:] */ - 'client_status': (keyof typeof _envoy_admin_v3_ClientResourceStatus); + 'client_status': (_envoy_admin_v3_ClientResourceStatus__Output); } export interface _envoy_admin_v3_ListenersConfigDump_DynamicListenerState { diff --git a/packages/grpc-js-xds/src/generated/envoy/admin/v3/RoutesConfigDump.ts b/packages/grpc-js-xds/src/generated/envoy/admin/v3/RoutesConfigDump.ts index 7b9bb29d0..6de43f0eb 100644 --- a/packages/grpc-js-xds/src/generated/envoy/admin/v3/RoutesConfigDump.ts +++ b/packages/grpc-js-xds/src/generated/envoy/admin/v3/RoutesConfigDump.ts @@ -3,7 +3,7 @@ import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any'; import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp'; import type { UpdateFailureState as _envoy_admin_v3_UpdateFailureState, UpdateFailureState__Output as _envoy_admin_v3_UpdateFailureState__Output } from '../../../envoy/admin/v3/UpdateFailureState'; -import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus } from '../../../envoy/admin/v3/ClientResourceStatus'; +import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus, ClientResourceStatus__Output as _envoy_admin_v3_ClientResourceStatus__Output } from '../../../envoy/admin/v3/ClientResourceStatus'; /** * [#next-free-field: 6] @@ -35,7 +35,7 @@ export interface _envoy_admin_v3_RoutesConfigDump_DynamicRouteConfig { * The client status of this resource. * [#not-implemented-hide:] */ - 'client_status'?: (_envoy_admin_v3_ClientResourceStatus | keyof typeof _envoy_admin_v3_ClientResourceStatus); + 'client_status'?: (_envoy_admin_v3_ClientResourceStatus); } /** @@ -68,7 +68,7 @@ export interface _envoy_admin_v3_RoutesConfigDump_DynamicRouteConfig__Output { * The client status of this resource. * [#not-implemented-hide:] */ - 'client_status': (keyof typeof _envoy_admin_v3_ClientResourceStatus); + 'client_status': (_envoy_admin_v3_ClientResourceStatus__Output); } export interface _envoy_admin_v3_RoutesConfigDump_StaticRouteConfig { diff --git a/packages/grpc-js-xds/src/generated/envoy/admin/v3/ScopedRoutesConfigDump.ts b/packages/grpc-js-xds/src/generated/envoy/admin/v3/ScopedRoutesConfigDump.ts index c0723ce69..1ce3934cc 100644 --- a/packages/grpc-js-xds/src/generated/envoy/admin/v3/ScopedRoutesConfigDump.ts +++ b/packages/grpc-js-xds/src/generated/envoy/admin/v3/ScopedRoutesConfigDump.ts @@ -3,7 +3,7 @@ import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any'; import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp'; import type { UpdateFailureState as _envoy_admin_v3_UpdateFailureState, UpdateFailureState__Output as _envoy_admin_v3_UpdateFailureState__Output } from '../../../envoy/admin/v3/UpdateFailureState'; -import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus } from '../../../envoy/admin/v3/ClientResourceStatus'; +import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus, ClientResourceStatus__Output as _envoy_admin_v3_ClientResourceStatus__Output } from '../../../envoy/admin/v3/ClientResourceStatus'; /** * [#next-free-field: 7] @@ -39,7 +39,7 @@ export interface _envoy_admin_v3_ScopedRoutesConfigDump_DynamicScopedRouteConfig * The client status of this resource. * [#not-implemented-hide:] */ - 'client_status'?: (_envoy_admin_v3_ClientResourceStatus | keyof typeof _envoy_admin_v3_ClientResourceStatus); + 'client_status'?: (_envoy_admin_v3_ClientResourceStatus); } /** @@ -76,7 +76,7 @@ export interface _envoy_admin_v3_ScopedRoutesConfigDump_DynamicScopedRouteConfig * The client status of this resource. * [#not-implemented-hide:] */ - 'client_status': (keyof typeof _envoy_admin_v3_ClientResourceStatus); + 'client_status': (_envoy_admin_v3_ClientResourceStatus__Output); } export interface _envoy_admin_v3_ScopedRoutesConfigDump_InlineScopedRouteConfigs { diff --git a/packages/grpc-js-xds/src/generated/envoy/admin/v3/SecretsConfigDump.ts b/packages/grpc-js-xds/src/generated/envoy/admin/v3/SecretsConfigDump.ts deleted file mode 100644 index 21921edec..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/admin/v3/SecretsConfigDump.ts +++ /dev/null @@ -1,162 +0,0 @@ -// Original file: deps/envoy-api/envoy/admin/v3/config_dump.proto - -import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp'; -import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any'; -import type { UpdateFailureState as _envoy_admin_v3_UpdateFailureState, UpdateFailureState__Output as _envoy_admin_v3_UpdateFailureState__Output } from '../../../envoy/admin/v3/UpdateFailureState'; -import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus } from '../../../envoy/admin/v3/ClientResourceStatus'; - -/** - * DynamicSecret contains secret information fetched via SDS. - * [#next-free-field: 7] - */ -export interface _envoy_admin_v3_SecretsConfigDump_DynamicSecret { - /** - * The name assigned to the secret. - */ - 'name'?: (string); - /** - * This is the per-resource version information. - */ - 'version_info'?: (string); - /** - * The timestamp when the secret was last updated. - */ - 'last_updated'?: (_google_protobuf_Timestamp | null); - /** - * The actual secret information. - * Security sensitive information is redacted (replaced with "[redacted]") for - * private keys and passwords in TLS certificates. - */ - 'secret'?: (_google_protobuf_Any | null); - /** - * Set if the last update failed, cleared after the next successful update. - * The *error_state* field contains the rejected version of this particular - * resource along with the reason and timestamp. For successfully updated or - * acknowledged resource, this field should be empty. - * [#not-implemented-hide:] - */ - 'error_state'?: (_envoy_admin_v3_UpdateFailureState | null); - /** - * The client status of this resource. - * [#not-implemented-hide:] - */ - 'client_status'?: (_envoy_admin_v3_ClientResourceStatus | keyof typeof _envoy_admin_v3_ClientResourceStatus); -} - -/** - * DynamicSecret contains secret information fetched via SDS. - * [#next-free-field: 7] - */ -export interface _envoy_admin_v3_SecretsConfigDump_DynamicSecret__Output { - /** - * The name assigned to the secret. - */ - 'name': (string); - /** - * This is the per-resource version information. - */ - 'version_info': (string); - /** - * The timestamp when the secret was last updated. - */ - 'last_updated': (_google_protobuf_Timestamp__Output | null); - /** - * The actual secret information. - * Security sensitive information is redacted (replaced with "[redacted]") for - * private keys and passwords in TLS certificates. - */ - 'secret': (_google_protobuf_Any__Output | null); - /** - * Set if the last update failed, cleared after the next successful update. - * The *error_state* field contains the rejected version of this particular - * resource along with the reason and timestamp. For successfully updated or - * acknowledged resource, this field should be empty. - * [#not-implemented-hide:] - */ - 'error_state': (_envoy_admin_v3_UpdateFailureState__Output | null); - /** - * The client status of this resource. - * [#not-implemented-hide:] - */ - 'client_status': (keyof typeof _envoy_admin_v3_ClientResourceStatus); -} - -/** - * StaticSecret specifies statically loaded secret in bootstrap. - */ -export interface _envoy_admin_v3_SecretsConfigDump_StaticSecret { - /** - * The name assigned to the secret. - */ - 'name'?: (string); - /** - * The timestamp when the secret was last updated. - */ - 'last_updated'?: (_google_protobuf_Timestamp | null); - /** - * The actual secret information. - * Security sensitive information is redacted (replaced with "[redacted]") for - * private keys and passwords in TLS certificates. - */ - 'secret'?: (_google_protobuf_Any | null); -} - -/** - * StaticSecret specifies statically loaded secret in bootstrap. - */ -export interface _envoy_admin_v3_SecretsConfigDump_StaticSecret__Output { - /** - * The name assigned to the secret. - */ - 'name': (string); - /** - * The timestamp when the secret was last updated. - */ - 'last_updated': (_google_protobuf_Timestamp__Output | null); - /** - * The actual secret information. - * Security sensitive information is redacted (replaced with "[redacted]") for - * private keys and passwords in TLS certificates. - */ - 'secret': (_google_protobuf_Any__Output | null); -} - -/** - * Envoys SDS implementation fills this message with all secrets fetched dynamically via SDS. - */ -export interface SecretsConfigDump { - /** - * The statically loaded secrets. - */ - 'static_secrets'?: (_envoy_admin_v3_SecretsConfigDump_StaticSecret)[]; - /** - * The dynamically loaded active secrets. These are secrets that are available to service - * clusters or listeners. - */ - 'dynamic_active_secrets'?: (_envoy_admin_v3_SecretsConfigDump_DynamicSecret)[]; - /** - * The dynamically loaded warming secrets. These are secrets that are currently undergoing - * warming in preparation to service clusters or listeners. - */ - 'dynamic_warming_secrets'?: (_envoy_admin_v3_SecretsConfigDump_DynamicSecret)[]; -} - -/** - * Envoys SDS implementation fills this message with all secrets fetched dynamically via SDS. - */ -export interface SecretsConfigDump__Output { - /** - * The statically loaded secrets. - */ - 'static_secrets': (_envoy_admin_v3_SecretsConfigDump_StaticSecret__Output)[]; - /** - * The dynamically loaded active secrets. These are secrets that are available to service - * clusters or listeners. - */ - 'dynamic_active_secrets': (_envoy_admin_v3_SecretsConfigDump_DynamicSecret__Output)[]; - /** - * The dynamically loaded warming secrets. These are secrets that are currently undergoing - * warming in preparation to service clusters or listeners. - */ - 'dynamic_warming_secrets': (_envoy_admin_v3_SecretsConfigDump_DynamicSecret__Output)[]; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/ComparisonFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/ComparisonFilter.ts index 07893f2dd..68c8f1b65 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/ComparisonFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/ComparisonFilter.ts @@ -4,20 +4,39 @@ import type { RuntimeUInt32 as _envoy_config_core_v3_RuntimeUInt32, RuntimeUInt3 // Original file: deps/envoy-api/envoy/config/accesslog/v3/accesslog.proto -export enum _envoy_config_accesslog_v3_ComparisonFilter_Op { +export const _envoy_config_accesslog_v3_ComparisonFilter_Op = { /** * = */ - EQ = 0, + EQ: 'EQ', /** * >= */ - GE = 1, + GE: 'GE', /** * <= */ - LE = 2, -} + LE: 'LE', +} as const; + +export type _envoy_config_accesslog_v3_ComparisonFilter_Op = + /** + * = + */ + | 'EQ' + | 0 + /** + * >= + */ + | 'GE' + | 1 + /** + * <= + */ + | 'LE' + | 2 + +export type _envoy_config_accesslog_v3_ComparisonFilter_Op__Output = typeof _envoy_config_accesslog_v3_ComparisonFilter_Op[keyof typeof _envoy_config_accesslog_v3_ComparisonFilter_Op] /** * Filter on an integer comparison. @@ -26,7 +45,7 @@ export interface ComparisonFilter { /** * Comparison operator. */ - 'op'?: (_envoy_config_accesslog_v3_ComparisonFilter_Op | keyof typeof _envoy_config_accesslog_v3_ComparisonFilter_Op); + 'op'?: (_envoy_config_accesslog_v3_ComparisonFilter_Op); /** * Value to compare against. */ @@ -40,7 +59,7 @@ export interface ComparisonFilter__Output { /** * Comparison operator. */ - 'op': (keyof typeof _envoy_config_accesslog_v3_ComparisonFilter_Op); + 'op': (_envoy_config_accesslog_v3_ComparisonFilter_Op__Output); /** * Value to compare against. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/GrpcStatusFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/GrpcStatusFilter.ts index f7ccc8052..ec18bde8a 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/GrpcStatusFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/GrpcStatusFilter.ts @@ -3,25 +3,63 @@ // Original file: deps/envoy-api/envoy/config/accesslog/v3/accesslog.proto -export enum _envoy_config_accesslog_v3_GrpcStatusFilter_Status { - OK = 0, - CANCELED = 1, - UNKNOWN = 2, - INVALID_ARGUMENT = 3, - DEADLINE_EXCEEDED = 4, - NOT_FOUND = 5, - ALREADY_EXISTS = 6, - PERMISSION_DENIED = 7, - RESOURCE_EXHAUSTED = 8, - FAILED_PRECONDITION = 9, - ABORTED = 10, - OUT_OF_RANGE = 11, - UNIMPLEMENTED = 12, - INTERNAL = 13, - UNAVAILABLE = 14, - DATA_LOSS = 15, - UNAUTHENTICATED = 16, -} +export const _envoy_config_accesslog_v3_GrpcStatusFilter_Status = { + OK: 'OK', + CANCELED: 'CANCELED', + UNKNOWN: 'UNKNOWN', + INVALID_ARGUMENT: 'INVALID_ARGUMENT', + DEADLINE_EXCEEDED: 'DEADLINE_EXCEEDED', + NOT_FOUND: 'NOT_FOUND', + ALREADY_EXISTS: 'ALREADY_EXISTS', + PERMISSION_DENIED: 'PERMISSION_DENIED', + RESOURCE_EXHAUSTED: 'RESOURCE_EXHAUSTED', + FAILED_PRECONDITION: 'FAILED_PRECONDITION', + ABORTED: 'ABORTED', + OUT_OF_RANGE: 'OUT_OF_RANGE', + UNIMPLEMENTED: 'UNIMPLEMENTED', + INTERNAL: 'INTERNAL', + UNAVAILABLE: 'UNAVAILABLE', + DATA_LOSS: 'DATA_LOSS', + UNAUTHENTICATED: 'UNAUTHENTICATED', +} as const; + +export type _envoy_config_accesslog_v3_GrpcStatusFilter_Status = + | 'OK' + | 0 + | 'CANCELED' + | 1 + | 'UNKNOWN' + | 2 + | 'INVALID_ARGUMENT' + | 3 + | 'DEADLINE_EXCEEDED' + | 4 + | 'NOT_FOUND' + | 5 + | 'ALREADY_EXISTS' + | 6 + | 'PERMISSION_DENIED' + | 7 + | 'RESOURCE_EXHAUSTED' + | 8 + | 'FAILED_PRECONDITION' + | 9 + | 'ABORTED' + | 10 + | 'OUT_OF_RANGE' + | 11 + | 'UNIMPLEMENTED' + | 12 + | 'INTERNAL' + | 13 + | 'UNAVAILABLE' + | 14 + | 'DATA_LOSS' + | 15 + | 'UNAUTHENTICATED' + | 16 + +export type _envoy_config_accesslog_v3_GrpcStatusFilter_Status__Output = typeof _envoy_config_accesslog_v3_GrpcStatusFilter_Status[keyof typeof _envoy_config_accesslog_v3_GrpcStatusFilter_Status] /** * Filters gRPC requests based on their response status. If a gRPC status is not @@ -31,7 +69,7 @@ export interface GrpcStatusFilter { /** * Logs only responses that have any one of the gRPC statuses in this field. */ - 'statuses'?: (_envoy_config_accesslog_v3_GrpcStatusFilter_Status | keyof typeof _envoy_config_accesslog_v3_GrpcStatusFilter_Status)[]; + 'statuses'?: (_envoy_config_accesslog_v3_GrpcStatusFilter_Status)[]; /** * If included and set to true, the filter will instead block all responses * with a gRPC status or inferred gRPC status enumerated in statuses, and @@ -48,7 +86,7 @@ export interface GrpcStatusFilter__Output { /** * Logs only responses that have any one of the gRPC statuses in this field. */ - 'statuses': (keyof typeof _envoy_config_accesslog_v3_GrpcStatusFilter_Status)[]; + 'statuses': (_envoy_config_accesslog_v3_GrpcStatusFilter_Status__Output)[]; /** * If included and set to true, the filter will instead block all responses * with a gRPC status or inferred gRPC status enumerated in statuses, and diff --git a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/LogTypeFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/LogTypeFilter.ts index 8d51cd33f..59ad8e308 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/LogTypeFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/LogTypeFilter.ts @@ -1,6 +1,6 @@ // Original file: deps/envoy-api/envoy/config/accesslog/v3/accesslog.proto -import type { AccessLogType as _envoy_data_accesslog_v3_AccessLogType } from '../../../../envoy/data/accesslog/v3/AccessLogType'; +import type { AccessLogType as _envoy_data_accesslog_v3_AccessLogType, AccessLogType__Output as _envoy_data_accesslog_v3_AccessLogType__Output } from '../../../../envoy/data/accesslog/v3/AccessLogType'; /** * Filters based on access log type. @@ -9,7 +9,7 @@ export interface LogTypeFilter { /** * Logs only records which their type is one of the types defined in this field. */ - 'types'?: (_envoy_data_accesslog_v3_AccessLogType | keyof typeof _envoy_data_accesslog_v3_AccessLogType)[]; + 'types'?: (_envoy_data_accesslog_v3_AccessLogType)[]; /** * If this field is set to true, the filter will instead block all records * with a access log type in types field, and allow all other records. @@ -24,7 +24,7 @@ export interface LogTypeFilter__Output { /** * Logs only records which their type is one of the types defined in this field. */ - 'types': (keyof typeof _envoy_data_accesslog_v3_AccessLogType)[]; + 'types': (_envoy_data_accesslog_v3_AccessLogType__Output)[]; /** * If this field is set to true, the filter will instead block all records * with a access log type in types field, and allow all other records. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Admin.ts b/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Admin.ts deleted file mode 100644 index a7f3826a1..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Admin.ts +++ /dev/null @@ -1,75 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/bootstrap/v3/bootstrap.proto - -import type { Address as _envoy_config_core_v3_Address, Address__Output as _envoy_config_core_v3_Address__Output } from '../../../../envoy/config/core/v3/Address'; -import type { SocketOption as _envoy_config_core_v3_SocketOption, SocketOption__Output as _envoy_config_core_v3_SocketOption__Output } from '../../../../envoy/config/core/v3/SocketOption'; -import type { AccessLog as _envoy_config_accesslog_v3_AccessLog, AccessLog__Output as _envoy_config_accesslog_v3_AccessLog__Output } from '../../../../envoy/config/accesslog/v3/AccessLog'; - -/** - * Administration interface :ref:`operations documentation - * `. - * [#next-free-field: 6] - */ -export interface Admin { - /** - * The path to write the access log for the administration server. If no - * access log is desired specify ‘/dev/null’. This is only required if - * :ref:`address ` is set. - * Deprecated in favor of *access_log* which offers more options. - */ - 'access_log_path'?: (string); - /** - * The cpu profiler output path for the administration server. If no profile - * path is specified, the default is ‘/var/log/envoy/envoy.prof’. - */ - 'profile_path'?: (string); - /** - * The TCP address that the administration server will listen on. - * If not specified, Envoy will not start an administration server. - */ - 'address'?: (_envoy_config_core_v3_Address | null); - /** - * Additional socket options that may not be present in Envoy source code or - * precompiled binaries. - */ - 'socket_options'?: (_envoy_config_core_v3_SocketOption)[]; - /** - * Configuration for :ref:`access logs ` - * emitted by the administration server. - */ - 'access_log'?: (_envoy_config_accesslog_v3_AccessLog)[]; -} - -/** - * Administration interface :ref:`operations documentation - * `. - * [#next-free-field: 6] - */ -export interface Admin__Output { - /** - * The path to write the access log for the administration server. If no - * access log is desired specify ‘/dev/null’. This is only required if - * :ref:`address ` is set. - * Deprecated in favor of *access_log* which offers more options. - */ - 'access_log_path': (string); - /** - * The cpu profiler output path for the administration server. If no profile - * path is specified, the default is ‘/var/log/envoy/envoy.prof’. - */ - 'profile_path': (string); - /** - * The TCP address that the administration server will listen on. - * If not specified, Envoy will not start an administration server. - */ - 'address': (_envoy_config_core_v3_Address__Output | null); - /** - * Additional socket options that may not be present in Envoy source code or - * precompiled binaries. - */ - 'socket_options': (_envoy_config_core_v3_SocketOption__Output)[]; - /** - * Configuration for :ref:`access logs ` - * emitted by the administration server. - */ - 'access_log': (_envoy_config_accesslog_v3_AccessLog__Output)[]; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Bootstrap.ts b/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Bootstrap.ts deleted file mode 100644 index 797148675..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Bootstrap.ts +++ /dev/null @@ -1,642 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/bootstrap/v3/bootstrap.proto - -import type { Node as _envoy_config_core_v3_Node, Node__Output as _envoy_config_core_v3_Node__Output } from '../../../../envoy/config/core/v3/Node'; -import type { ClusterManager as _envoy_config_bootstrap_v3_ClusterManager, ClusterManager__Output as _envoy_config_bootstrap_v3_ClusterManager__Output } from '../../../../envoy/config/bootstrap/v3/ClusterManager'; -import type { StatsSink as _envoy_config_metrics_v3_StatsSink, StatsSink__Output as _envoy_config_metrics_v3_StatsSink__Output } from '../../../../envoy/config/metrics/v3/StatsSink'; -import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; -import type { Watchdog as _envoy_config_bootstrap_v3_Watchdog, Watchdog__Output as _envoy_config_bootstrap_v3_Watchdog__Output } from '../../../../envoy/config/bootstrap/v3/Watchdog'; -import type { Tracing as _envoy_config_trace_v3_Tracing, Tracing__Output as _envoy_config_trace_v3_Tracing__Output } from '../../../../envoy/config/trace/v3/Tracing'; -import type { Admin as _envoy_config_bootstrap_v3_Admin, Admin__Output as _envoy_config_bootstrap_v3_Admin__Output } from '../../../../envoy/config/bootstrap/v3/Admin'; -import type { StatsConfig as _envoy_config_metrics_v3_StatsConfig, StatsConfig__Output as _envoy_config_metrics_v3_StatsConfig__Output } from '../../../../envoy/config/metrics/v3/StatsConfig'; -import type { ApiConfigSource as _envoy_config_core_v3_ApiConfigSource, ApiConfigSource__Output as _envoy_config_core_v3_ApiConfigSource__Output } from '../../../../envoy/config/core/v3/ApiConfigSource'; -import type { OverloadManager as _envoy_config_overload_v3_OverloadManager, OverloadManager__Output as _envoy_config_overload_v3_OverloadManager__Output } from '../../../../envoy/config/overload/v3/OverloadManager'; -import type { LayeredRuntime as _envoy_config_bootstrap_v3_LayeredRuntime, LayeredRuntime__Output as _envoy_config_bootstrap_v3_LayeredRuntime__Output } from '../../../../envoy/config/bootstrap/v3/LayeredRuntime'; -import type { UInt64Value as _google_protobuf_UInt64Value, UInt64Value__Output as _google_protobuf_UInt64Value__Output } from '../../../../google/protobuf/UInt64Value'; -import type { TypedExtensionConfig as _envoy_config_core_v3_TypedExtensionConfig, TypedExtensionConfig__Output as _envoy_config_core_v3_TypedExtensionConfig__Output } from '../../../../envoy/config/core/v3/TypedExtensionConfig'; -import type { ConfigSource as _envoy_config_core_v3_ConfigSource, ConfigSource__Output as _envoy_config_core_v3_ConfigSource__Output } from '../../../../envoy/config/core/v3/ConfigSource'; -import type { Watchdogs as _envoy_config_bootstrap_v3_Watchdogs, Watchdogs__Output as _envoy_config_bootstrap_v3_Watchdogs__Output } from '../../../../envoy/config/bootstrap/v3/Watchdogs'; -import type { FatalAction as _envoy_config_bootstrap_v3_FatalAction, FatalAction__Output as _envoy_config_bootstrap_v3_FatalAction__Output } from '../../../../envoy/config/bootstrap/v3/FatalAction'; -import type { DnsResolutionConfig as _envoy_config_core_v3_DnsResolutionConfig, DnsResolutionConfig__Output as _envoy_config_core_v3_DnsResolutionConfig__Output } from '../../../../envoy/config/core/v3/DnsResolutionConfig'; -import type { CustomInlineHeader as _envoy_config_bootstrap_v3_CustomInlineHeader, CustomInlineHeader__Output as _envoy_config_bootstrap_v3_CustomInlineHeader__Output } from '../../../../envoy/config/bootstrap/v3/CustomInlineHeader'; -import type { Listener as _envoy_config_listener_v3_Listener, Listener__Output as _envoy_config_listener_v3_Listener__Output } from '../../../../envoy/config/listener/v3/Listener'; -import type { Cluster as _envoy_config_cluster_v3_Cluster, Cluster__Output as _envoy_config_cluster_v3_Cluster__Output } from '../../../../envoy/config/cluster/v3/Cluster'; -import type { Secret as _envoy_extensions_transport_sockets_tls_v3_Secret, Secret__Output as _envoy_extensions_transport_sockets_tls_v3_Secret__Output } from '../../../../envoy/extensions/transport_sockets/tls/v3/Secret'; -import type { Long } from '@grpc/proto-loader'; - -/** - * [#next-free-field: 7] - */ -export interface _envoy_config_bootstrap_v3_Bootstrap_DynamicResources { - /** - * All :ref:`Listeners ` are provided by a single - * :ref:`LDS ` configuration source. - */ - 'lds_config'?: (_envoy_config_core_v3_ConfigSource | null); - /** - * xdstp:// resource locator for listener collection. - * [#not-implemented-hide:] - */ - 'lds_resources_locator'?: (string); - /** - * All post-bootstrap :ref:`Cluster ` definitions are - * provided by a single :ref:`CDS ` - * configuration source. - */ - 'cds_config'?: (_envoy_config_core_v3_ConfigSource | null); - /** - * xdstp:// resource locator for cluster collection. - * [#not-implemented-hide:] - */ - 'cds_resources_locator'?: (string); - /** - * A single :ref:`ADS ` source may be optionally - * specified. This must have :ref:`api_type - * ` :ref:`GRPC - * `. Only - * :ref:`ConfigSources ` that have - * the :ref:`ads ` field set will be - * streamed on the ADS channel. - */ - 'ads_config'?: (_envoy_config_core_v3_ApiConfigSource | null); -} - -/** - * [#next-free-field: 7] - */ -export interface _envoy_config_bootstrap_v3_Bootstrap_DynamicResources__Output { - /** - * All :ref:`Listeners ` are provided by a single - * :ref:`LDS ` configuration source. - */ - 'lds_config': (_envoy_config_core_v3_ConfigSource__Output | null); - /** - * xdstp:// resource locator for listener collection. - * [#not-implemented-hide:] - */ - 'lds_resources_locator': (string); - /** - * All post-bootstrap :ref:`Cluster ` definitions are - * provided by a single :ref:`CDS ` - * configuration source. - */ - 'cds_config': (_envoy_config_core_v3_ConfigSource__Output | null); - /** - * xdstp:// resource locator for cluster collection. - * [#not-implemented-hide:] - */ - 'cds_resources_locator': (string); - /** - * A single :ref:`ADS ` source may be optionally - * specified. This must have :ref:`api_type - * ` :ref:`GRPC - * `. Only - * :ref:`ConfigSources ` that have - * the :ref:`ads ` field set will be - * streamed on the ADS channel. - */ - 'ads_config': (_envoy_config_core_v3_ApiConfigSource__Output | null); -} - -export interface _envoy_config_bootstrap_v3_Bootstrap_StaticResources { - /** - * Static :ref:`Listeners `. These listeners are - * available regardless of LDS configuration. - */ - 'listeners'?: (_envoy_config_listener_v3_Listener)[]; - /** - * If a network based configuration source is specified for :ref:`cds_config - * `, it's necessary - * to have some initial cluster definitions available to allow Envoy to know - * how to speak to the management server. These cluster definitions may not - * use :ref:`EDS ` (i.e. they should be static - * IP or DNS-based). - */ - 'clusters'?: (_envoy_config_cluster_v3_Cluster)[]; - /** - * These static secrets can be used by :ref:`SdsSecretConfig - * ` - */ - 'secrets'?: (_envoy_extensions_transport_sockets_tls_v3_Secret)[]; -} - -export interface _envoy_config_bootstrap_v3_Bootstrap_StaticResources__Output { - /** - * Static :ref:`Listeners `. These listeners are - * available regardless of LDS configuration. - */ - 'listeners': (_envoy_config_listener_v3_Listener__Output)[]; - /** - * If a network based configuration source is specified for :ref:`cds_config - * `, it's necessary - * to have some initial cluster definitions available to allow Envoy to know - * how to speak to the management server. These cluster definitions may not - * use :ref:`EDS ` (i.e. they should be static - * IP or DNS-based). - */ - 'clusters': (_envoy_config_cluster_v3_Cluster__Output)[]; - /** - * These static secrets can be used by :ref:`SdsSecretConfig - * ` - */ - 'secrets': (_envoy_extensions_transport_sockets_tls_v3_Secret__Output)[]; -} - -/** - * Bootstrap :ref:`configuration overview `. - * [#next-free-field: 33] - */ -export interface Bootstrap { - /** - * Node identity to present to the management server and for instance - * identification purposes (e.g. in generated headers). - */ - 'node'?: (_envoy_config_core_v3_Node | null); - /** - * Statically specified resources. - */ - 'static_resources'?: (_envoy_config_bootstrap_v3_Bootstrap_StaticResources | null); - /** - * xDS configuration sources. - */ - 'dynamic_resources'?: (_envoy_config_bootstrap_v3_Bootstrap_DynamicResources | null); - /** - * Configuration for the cluster manager which owns all upstream clusters - * within the server. - */ - 'cluster_manager'?: (_envoy_config_bootstrap_v3_ClusterManager | null); - /** - * Optional file system path to search for startup flag files. - */ - 'flags_path'?: (string); - /** - * Optional set of stats sinks. - */ - 'stats_sinks'?: (_envoy_config_metrics_v3_StatsSink)[]; - /** - * Optional duration between flushes to configured stats sinks. For - * performance reasons Envoy latches counters and only flushes counters and - * gauges at a periodic interval. If not specified the default is 5000ms (5 - * seconds). Only one of `stats_flush_interval` or `stats_flush_on_admin` - * can be set. - * Duration must be at least 1ms and at most 5 min. - */ - 'stats_flush_interval'?: (_google_protobuf_Duration | null); - /** - * Optional watchdog configuration. - * This is for a single watchdog configuration for the entire system. - * Deprecated in favor of *watchdogs* which has finer granularity. - */ - 'watchdog'?: (_envoy_config_bootstrap_v3_Watchdog | null); - /** - * Configuration for an external tracing provider. - * - * .. attention:: - * This field has been deprecated in favor of :ref:`HttpConnectionManager.Tracing.provider - * `. - */ - 'tracing'?: (_envoy_config_trace_v3_Tracing | null); - /** - * Configuration for the local administration HTTP server. - */ - 'admin'?: (_envoy_config_bootstrap_v3_Admin | null); - /** - * Configuration for internal processing of stats. - */ - 'stats_config'?: (_envoy_config_metrics_v3_StatsConfig | null); - /** - * Health discovery service config option. - * (:ref:`core.ApiConfigSource `) - */ - 'hds_config'?: (_envoy_config_core_v3_ApiConfigSource | null); - /** - * Optional overload manager configuration. - */ - 'overload_manager'?: (_envoy_config_overload_v3_OverloadManager | null); - /** - * Enable :ref:`stats for event dispatcher `, defaults to false. - * Note that this records a value for each iteration of the event loop on every thread. This - * should normally be minimal overhead, but when using - * :ref:`statsd `, it will send each observed value - * over the wire individually because the statsd protocol doesn't have any way to represent a - * histogram summary. Be aware that this can be a very large volume of data. - */ - 'enable_dispatcher_stats'?: (boolean); - /** - * Configuration for the runtime configuration provider. If not - * specified, a “null” provider will be used which will result in all defaults - * being used. - */ - 'layered_runtime'?: (_envoy_config_bootstrap_v3_LayeredRuntime | null); - /** - * Optional string which will be used in lieu of x-envoy in prefixing headers. - * - * For example, if this string is present and set to X-Foo, then x-envoy-retry-on will be - * transformed into x-foo-retry-on etc. - * - * Note this applies to the headers Envoy will generate, the headers Envoy will sanitize, and the - * headers Envoy will trust for core code and core extensions only. Be VERY careful making - * changes to this string, especially in multi-layer Envoy deployments or deployments using - * extensions which are not upstream. - */ - 'header_prefix'?: (string); - /** - * Optional proxy version which will be used to set the value of :ref:`server.version statistic - * ` if specified. Envoy will not process this value, it will be sent as is to - * :ref:`stats sinks `. - */ - 'stats_server_version_override'?: (_google_protobuf_UInt64Value | null); - /** - * Always use TCP queries instead of UDP queries for DNS lookups. - * This may be overridden on a per-cluster basis in cds_config, - * when :ref:`dns_resolvers ` and - * :ref:`use_tcp_for_dns_lookups ` are - * specified. - * Setting this value causes failure if the - * ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during - * server startup. Apple' API only uses UDP for DNS resolution. - * This field is deprecated in favor of *dns_resolution_config* - * which aggregates all of the DNS resolver configuration in a single message. - */ - 'use_tcp_for_dns_lookups'?: (boolean); - /** - * Specifies optional bootstrap extensions to be instantiated at startup time. - * Each item contains extension specific configuration. - * [#extension-category: envoy.bootstrap] - */ - 'bootstrap_extensions'?: (_envoy_config_core_v3_TypedExtensionConfig)[]; - /** - * Configuration sources that will participate in - * xdstp:// URL authority resolution. The algorithm is as - * follows: - * 1. The authority field is taken from the xdstp:// URL, call - * this *resource_authority*. - * 2. *resource_authority* is compared against the authorities in any peer - * *ConfigSource*. The peer *ConfigSource* is the configuration source - * message which would have been used unconditionally for resolution - * with opaque resource names. If there is a match with an authority, the - * peer *ConfigSource* message is used. - * 3. *resource_authority* is compared sequentially with the authorities in - * each configuration source in *config_sources*. The first *ConfigSource* - * to match wins. - * 4. As a fallback, if no configuration source matches, then - * *default_config_source* is used. - * 5. If *default_config_source* is not specified, resolution fails. - * [#not-implemented-hide:] - */ - 'config_sources'?: (_envoy_config_core_v3_ConfigSource)[]; - /** - * Default configuration source for xdstp:// URLs if all - * other resolution fails. - * [#not-implemented-hide:] - */ - 'default_config_source'?: (_envoy_config_core_v3_ConfigSource | null); - /** - * Optional overriding of default socket interface. The value must be the name of one of the - * socket interface factories initialized through a bootstrap extension - */ - 'default_socket_interface'?: (string); - /** - * Global map of CertificateProvider instances. These instances are referred to by name in the - * :ref:`CommonTlsContext.CertificateProviderInstance.instance_name - * ` - * field. - * [#not-implemented-hide:] - */ - 'certificate_provider_instances'?: ({[key: string]: _envoy_config_core_v3_TypedExtensionConfig}); - /** - * A list of :ref:`Node ` field names - * that will be included in the context parameters of the effective - * xdstp:// URL that is sent in a discovery request when resource - * locators are used for LDS/CDS. Any non-string field will have its JSON - * encoding set as the context parameter value, with the exception of - * metadata, which will be flattened (see example below). The supported field - * names are: - * - "cluster" - * - "id" - * - "locality.region" - * - "locality.sub_zone" - * - "locality.zone" - * - "metadata" - * - "user_agent_build_version.metadata" - * - "user_agent_build_version.version" - * - "user_agent_name" - * - "user_agent_version" - * - * The node context parameters act as a base layer dictionary for the context - * parameters (i.e. more specific resource specific context parameters will - * override). Field names will be prefixed with “udpa.node.” when included in - * context parameters. - * - * For example, if node_context_params is ``["user_agent_name", "metadata"]``, - * the implied context parameters might be:: - * - * node.user_agent_name: "envoy" - * node.metadata.foo: "{\"bar\": \"baz\"}" - * node.metadata.some: "42" - * node.metadata.thing: "\"thing\"" - * - * [#not-implemented-hide:] - */ - 'node_context_params'?: (string)[]; - /** - * Optional watchdogs configuration. - * This is used for specifying different watchdogs for the different subsystems. - * [#extension-category: envoy.guarddog_actions] - */ - 'watchdogs'?: (_envoy_config_bootstrap_v3_Watchdogs | null); - /** - * Specifies optional extensions instantiated at startup time and - * invoked during crash time on the request that caused the crash. - */ - 'fatal_actions'?: (_envoy_config_bootstrap_v3_FatalAction)[]; - /** - * Flush stats to sinks only when queried for on the admin interface. If set, - * a flush timer is not created. Only one of `stats_flush_on_admin` or - * `stats_flush_interval` can be set. - */ - 'stats_flush_on_admin'?: (boolean); - /** - * DNS resolution configuration which includes the underlying dns resolver addresses and options. - * This may be overridden on a per-cluster basis in cds_config, when - * :ref:`dns_resolution_config ` - * is specified. - * *dns_resolution_config* will be deprecated once - * :ref:'typed_dns_resolver_config ' - * is fully supported. - */ - 'dns_resolution_config'?: (_envoy_config_core_v3_DnsResolutionConfig | null); - /** - * DNS resolver type configuration extension. This extension can be used to configure c-ares, apple, - * or any other DNS resolver types and the related parameters. - * For example, an object of :ref:`DnsResolutionConfig ` - * can be packed into this *typed_dns_resolver_config*. This configuration will replace the - * :ref:'dns_resolution_config ' - * configuration eventually. - * TODO(yanjunxiang): Investigate the deprecation plan for *dns_resolution_config*. - * During the transition period when both *dns_resolution_config* and *typed_dns_resolver_config* exists, - * this configuration is optional. - * When *typed_dns_resolver_config* is in place, Envoy will use it and ignore *dns_resolution_config*. - * When *typed_dns_resolver_config* is missing, the default behavior is in place. - * [#not-implemented-hide:] - */ - 'typed_dns_resolver_config'?: (_envoy_config_core_v3_TypedExtensionConfig | null); - /** - * Specifies a set of headers that need to be registered as inline header. This configuration - * allows users to customize the inline headers on-demand at Envoy startup without modifying - * Envoy's source code. - * - * Note that the 'set-cookie' header cannot be registered as inline header. - */ - 'inline_headers'?: (_envoy_config_bootstrap_v3_CustomInlineHeader)[]; - 'stats_flush'?: "stats_flush_on_admin"; -} - -/** - * Bootstrap :ref:`configuration overview `. - * [#next-free-field: 33] - */ -export interface Bootstrap__Output { - /** - * Node identity to present to the management server and for instance - * identification purposes (e.g. in generated headers). - */ - 'node': (_envoy_config_core_v3_Node__Output | null); - /** - * Statically specified resources. - */ - 'static_resources': (_envoy_config_bootstrap_v3_Bootstrap_StaticResources__Output | null); - /** - * xDS configuration sources. - */ - 'dynamic_resources': (_envoy_config_bootstrap_v3_Bootstrap_DynamicResources__Output | null); - /** - * Configuration for the cluster manager which owns all upstream clusters - * within the server. - */ - 'cluster_manager': (_envoy_config_bootstrap_v3_ClusterManager__Output | null); - /** - * Optional file system path to search for startup flag files. - */ - 'flags_path': (string); - /** - * Optional set of stats sinks. - */ - 'stats_sinks': (_envoy_config_metrics_v3_StatsSink__Output)[]; - /** - * Optional duration between flushes to configured stats sinks. For - * performance reasons Envoy latches counters and only flushes counters and - * gauges at a periodic interval. If not specified the default is 5000ms (5 - * seconds). Only one of `stats_flush_interval` or `stats_flush_on_admin` - * can be set. - * Duration must be at least 1ms and at most 5 min. - */ - 'stats_flush_interval': (_google_protobuf_Duration__Output | null); - /** - * Optional watchdog configuration. - * This is for a single watchdog configuration for the entire system. - * Deprecated in favor of *watchdogs* which has finer granularity. - */ - 'watchdog': (_envoy_config_bootstrap_v3_Watchdog__Output | null); - /** - * Configuration for an external tracing provider. - * - * .. attention:: - * This field has been deprecated in favor of :ref:`HttpConnectionManager.Tracing.provider - * `. - */ - 'tracing': (_envoy_config_trace_v3_Tracing__Output | null); - /** - * Configuration for the local administration HTTP server. - */ - 'admin': (_envoy_config_bootstrap_v3_Admin__Output | null); - /** - * Configuration for internal processing of stats. - */ - 'stats_config': (_envoy_config_metrics_v3_StatsConfig__Output | null); - /** - * Health discovery service config option. - * (:ref:`core.ApiConfigSource `) - */ - 'hds_config': (_envoy_config_core_v3_ApiConfigSource__Output | null); - /** - * Optional overload manager configuration. - */ - 'overload_manager': (_envoy_config_overload_v3_OverloadManager__Output | null); - /** - * Enable :ref:`stats for event dispatcher `, defaults to false. - * Note that this records a value for each iteration of the event loop on every thread. This - * should normally be minimal overhead, but when using - * :ref:`statsd `, it will send each observed value - * over the wire individually because the statsd protocol doesn't have any way to represent a - * histogram summary. Be aware that this can be a very large volume of data. - */ - 'enable_dispatcher_stats': (boolean); - /** - * Configuration for the runtime configuration provider. If not - * specified, a “null” provider will be used which will result in all defaults - * being used. - */ - 'layered_runtime': (_envoy_config_bootstrap_v3_LayeredRuntime__Output | null); - /** - * Optional string which will be used in lieu of x-envoy in prefixing headers. - * - * For example, if this string is present and set to X-Foo, then x-envoy-retry-on will be - * transformed into x-foo-retry-on etc. - * - * Note this applies to the headers Envoy will generate, the headers Envoy will sanitize, and the - * headers Envoy will trust for core code and core extensions only. Be VERY careful making - * changes to this string, especially in multi-layer Envoy deployments or deployments using - * extensions which are not upstream. - */ - 'header_prefix': (string); - /** - * Optional proxy version which will be used to set the value of :ref:`server.version statistic - * ` if specified. Envoy will not process this value, it will be sent as is to - * :ref:`stats sinks `. - */ - 'stats_server_version_override': (_google_protobuf_UInt64Value__Output | null); - /** - * Always use TCP queries instead of UDP queries for DNS lookups. - * This may be overridden on a per-cluster basis in cds_config, - * when :ref:`dns_resolvers ` and - * :ref:`use_tcp_for_dns_lookups ` are - * specified. - * Setting this value causes failure if the - * ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during - * server startup. Apple' API only uses UDP for DNS resolution. - * This field is deprecated in favor of *dns_resolution_config* - * which aggregates all of the DNS resolver configuration in a single message. - */ - 'use_tcp_for_dns_lookups': (boolean); - /** - * Specifies optional bootstrap extensions to be instantiated at startup time. - * Each item contains extension specific configuration. - * [#extension-category: envoy.bootstrap] - */ - 'bootstrap_extensions': (_envoy_config_core_v3_TypedExtensionConfig__Output)[]; - /** - * Configuration sources that will participate in - * xdstp:// URL authority resolution. The algorithm is as - * follows: - * 1. The authority field is taken from the xdstp:// URL, call - * this *resource_authority*. - * 2. *resource_authority* is compared against the authorities in any peer - * *ConfigSource*. The peer *ConfigSource* is the configuration source - * message which would have been used unconditionally for resolution - * with opaque resource names. If there is a match with an authority, the - * peer *ConfigSource* message is used. - * 3. *resource_authority* is compared sequentially with the authorities in - * each configuration source in *config_sources*. The first *ConfigSource* - * to match wins. - * 4. As a fallback, if no configuration source matches, then - * *default_config_source* is used. - * 5. If *default_config_source* is not specified, resolution fails. - * [#not-implemented-hide:] - */ - 'config_sources': (_envoy_config_core_v3_ConfigSource__Output)[]; - /** - * Default configuration source for xdstp:// URLs if all - * other resolution fails. - * [#not-implemented-hide:] - */ - 'default_config_source': (_envoy_config_core_v3_ConfigSource__Output | null); - /** - * Optional overriding of default socket interface. The value must be the name of one of the - * socket interface factories initialized through a bootstrap extension - */ - 'default_socket_interface': (string); - /** - * Global map of CertificateProvider instances. These instances are referred to by name in the - * :ref:`CommonTlsContext.CertificateProviderInstance.instance_name - * ` - * field. - * [#not-implemented-hide:] - */ - 'certificate_provider_instances': ({[key: string]: _envoy_config_core_v3_TypedExtensionConfig__Output}); - /** - * A list of :ref:`Node ` field names - * that will be included in the context parameters of the effective - * xdstp:// URL that is sent in a discovery request when resource - * locators are used for LDS/CDS. Any non-string field will have its JSON - * encoding set as the context parameter value, with the exception of - * metadata, which will be flattened (see example below). The supported field - * names are: - * - "cluster" - * - "id" - * - "locality.region" - * - "locality.sub_zone" - * - "locality.zone" - * - "metadata" - * - "user_agent_build_version.metadata" - * - "user_agent_build_version.version" - * - "user_agent_name" - * - "user_agent_version" - * - * The node context parameters act as a base layer dictionary for the context - * parameters (i.e. more specific resource specific context parameters will - * override). Field names will be prefixed with “udpa.node.” when included in - * context parameters. - * - * For example, if node_context_params is ``["user_agent_name", "metadata"]``, - * the implied context parameters might be:: - * - * node.user_agent_name: "envoy" - * node.metadata.foo: "{\"bar\": \"baz\"}" - * node.metadata.some: "42" - * node.metadata.thing: "\"thing\"" - * - * [#not-implemented-hide:] - */ - 'node_context_params': (string)[]; - /** - * Optional watchdogs configuration. - * This is used for specifying different watchdogs for the different subsystems. - * [#extension-category: envoy.guarddog_actions] - */ - 'watchdogs': (_envoy_config_bootstrap_v3_Watchdogs__Output | null); - /** - * Specifies optional extensions instantiated at startup time and - * invoked during crash time on the request that caused the crash. - */ - 'fatal_actions': (_envoy_config_bootstrap_v3_FatalAction__Output)[]; - /** - * Flush stats to sinks only when queried for on the admin interface. If set, - * a flush timer is not created. Only one of `stats_flush_on_admin` or - * `stats_flush_interval` can be set. - */ - 'stats_flush_on_admin'?: (boolean); - /** - * DNS resolution configuration which includes the underlying dns resolver addresses and options. - * This may be overridden on a per-cluster basis in cds_config, when - * :ref:`dns_resolution_config ` - * is specified. - * *dns_resolution_config* will be deprecated once - * :ref:'typed_dns_resolver_config ' - * is fully supported. - */ - 'dns_resolution_config': (_envoy_config_core_v3_DnsResolutionConfig__Output | null); - /** - * DNS resolver type configuration extension. This extension can be used to configure c-ares, apple, - * or any other DNS resolver types and the related parameters. - * For example, an object of :ref:`DnsResolutionConfig ` - * can be packed into this *typed_dns_resolver_config*. This configuration will replace the - * :ref:'dns_resolution_config ' - * configuration eventually. - * TODO(yanjunxiang): Investigate the deprecation plan for *dns_resolution_config*. - * During the transition period when both *dns_resolution_config* and *typed_dns_resolver_config* exists, - * this configuration is optional. - * When *typed_dns_resolver_config* is in place, Envoy will use it and ignore *dns_resolution_config*. - * When *typed_dns_resolver_config* is missing, the default behavior is in place. - * [#not-implemented-hide:] - */ - 'typed_dns_resolver_config': (_envoy_config_core_v3_TypedExtensionConfig__Output | null); - /** - * Specifies a set of headers that need to be registered as inline header. This configuration - * allows users to customize the inline headers on-demand at Envoy startup without modifying - * Envoy's source code. - * - * Note that the 'set-cookie' header cannot be registered as inline header. - */ - 'inline_headers': (_envoy_config_bootstrap_v3_CustomInlineHeader__Output)[]; - 'stats_flush': "stats_flush_on_admin"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/ClusterManager.ts b/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/ClusterManager.ts deleted file mode 100644 index 571b96fb7..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/ClusterManager.ts +++ /dev/null @@ -1,99 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/bootstrap/v3/bootstrap.proto - -import type { BindConfig as _envoy_config_core_v3_BindConfig, BindConfig__Output as _envoy_config_core_v3_BindConfig__Output } from '../../../../envoy/config/core/v3/BindConfig'; -import type { ApiConfigSource as _envoy_config_core_v3_ApiConfigSource, ApiConfigSource__Output as _envoy_config_core_v3_ApiConfigSource__Output } from '../../../../envoy/config/core/v3/ApiConfigSource'; -import type { EventServiceConfig as _envoy_config_core_v3_EventServiceConfig, EventServiceConfig__Output as _envoy_config_core_v3_EventServiceConfig__Output } from '../../../../envoy/config/core/v3/EventServiceConfig'; - -export interface _envoy_config_bootstrap_v3_ClusterManager_OutlierDetection { - /** - * Specifies the path to the outlier event log. - */ - 'event_log_path'?: (string); - /** - * [#not-implemented-hide:] - * The gRPC service for the outlier detection event service. - * If empty, outlier detection events won't be sent to a remote endpoint. - */ - 'event_service'?: (_envoy_config_core_v3_EventServiceConfig | null); -} - -export interface _envoy_config_bootstrap_v3_ClusterManager_OutlierDetection__Output { - /** - * Specifies the path to the outlier event log. - */ - 'event_log_path': (string); - /** - * [#not-implemented-hide:] - * The gRPC service for the outlier detection event service. - * If empty, outlier detection events won't be sent to a remote endpoint. - */ - 'event_service': (_envoy_config_core_v3_EventServiceConfig__Output | null); -} - -/** - * Cluster manager :ref:`architecture overview `. - */ -export interface ClusterManager { - /** - * Name of the local cluster (i.e., the cluster that owns the Envoy running - * this configuration). In order to enable :ref:`zone aware routing - * ` this option must be set. - * If *local_cluster_name* is defined then :ref:`clusters - * ` must be defined in the :ref:`Bootstrap - * static cluster resources - * `. This is unrelated to - * the :option:`--service-cluster` option which does not `affect zone aware - * routing `_. - */ - 'local_cluster_name'?: (string); - /** - * Optional global configuration for outlier detection. - */ - 'outlier_detection'?: (_envoy_config_bootstrap_v3_ClusterManager_OutlierDetection | null); - /** - * Optional configuration used to bind newly established upstream connections. - * This may be overridden on a per-cluster basis by upstream_bind_config in the cds_config. - */ - 'upstream_bind_config'?: (_envoy_config_core_v3_BindConfig | null); - /** - * A management server endpoint to stream load stats to via - * *StreamLoadStats*. This must have :ref:`api_type - * ` :ref:`GRPC - * `. - */ - 'load_stats_config'?: (_envoy_config_core_v3_ApiConfigSource | null); -} - -/** - * Cluster manager :ref:`architecture overview `. - */ -export interface ClusterManager__Output { - /** - * Name of the local cluster (i.e., the cluster that owns the Envoy running - * this configuration). In order to enable :ref:`zone aware routing - * ` this option must be set. - * If *local_cluster_name* is defined then :ref:`clusters - * ` must be defined in the :ref:`Bootstrap - * static cluster resources - * `. This is unrelated to - * the :option:`--service-cluster` option which does not `affect zone aware - * routing `_. - */ - 'local_cluster_name': (string); - /** - * Optional global configuration for outlier detection. - */ - 'outlier_detection': (_envoy_config_bootstrap_v3_ClusterManager_OutlierDetection__Output | null); - /** - * Optional configuration used to bind newly established upstream connections. - * This may be overridden on a per-cluster basis by upstream_bind_config in the cds_config. - */ - 'upstream_bind_config': (_envoy_config_core_v3_BindConfig__Output | null); - /** - * A management server endpoint to stream load stats to via - * *StreamLoadStats*. This must have :ref:`api_type - * ` :ref:`GRPC - * `. - */ - 'load_stats_config': (_envoy_config_core_v3_ApiConfigSource__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/CustomInlineHeader.ts b/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/CustomInlineHeader.ts deleted file mode 100644 index f0e2d29aa..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/CustomInlineHeader.ts +++ /dev/null @@ -1,85 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/bootstrap/v3/bootstrap.proto - - -// Original file: deps/envoy-api/envoy/config/bootstrap/v3/bootstrap.proto - -export enum _envoy_config_bootstrap_v3_CustomInlineHeader_InlineHeaderType { - REQUEST_HEADER = 0, - REQUEST_TRAILER = 1, - RESPONSE_HEADER = 2, - RESPONSE_TRAILER = 3, -} - -/** - * Used to specify the header that needs to be registered as an inline header. - * - * If request or response contain multiple headers with the same name and the header - * name is registered as an inline header. Then multiple headers will be folded - * into one, and multiple header values will be concatenated by a suitable delimiter. - * The delimiter is generally a comma. - * - * For example, if 'foo' is registered as an inline header, and the headers contains - * the following two headers: - * - * .. code-block:: text - * - * foo: bar - * foo: eep - * - * Then they will eventually be folded into: - * - * .. code-block:: text - * - * foo: bar, eep - * - * Inline headers provide O(1) search performance, but each inline header imposes - * an additional memory overhead on all instances of the corresponding type of - * HeaderMap or TrailerMap. - */ -export interface CustomInlineHeader { - /** - * The name of the header that is expected to be set as the inline header. - */ - 'inline_header_name'?: (string); - /** - * The type of the header that is expected to be set as the inline header. - */ - 'inline_header_type'?: (_envoy_config_bootstrap_v3_CustomInlineHeader_InlineHeaderType | keyof typeof _envoy_config_bootstrap_v3_CustomInlineHeader_InlineHeaderType); -} - -/** - * Used to specify the header that needs to be registered as an inline header. - * - * If request or response contain multiple headers with the same name and the header - * name is registered as an inline header. Then multiple headers will be folded - * into one, and multiple header values will be concatenated by a suitable delimiter. - * The delimiter is generally a comma. - * - * For example, if 'foo' is registered as an inline header, and the headers contains - * the following two headers: - * - * .. code-block:: text - * - * foo: bar - * foo: eep - * - * Then they will eventually be folded into: - * - * .. code-block:: text - * - * foo: bar, eep - * - * Inline headers provide O(1) search performance, but each inline header imposes - * an additional memory overhead on all instances of the corresponding type of - * HeaderMap or TrailerMap. - */ -export interface CustomInlineHeader__Output { - /** - * The name of the header that is expected to be set as the inline header. - */ - 'inline_header_name': (string); - /** - * The type of the header that is expected to be set as the inline header. - */ - 'inline_header_type': (keyof typeof _envoy_config_bootstrap_v3_CustomInlineHeader_InlineHeaderType); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/FatalAction.ts b/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/FatalAction.ts deleted file mode 100644 index 236afded5..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/FatalAction.ts +++ /dev/null @@ -1,39 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/bootstrap/v3/bootstrap.proto - -import type { TypedExtensionConfig as _envoy_config_core_v3_TypedExtensionConfig, TypedExtensionConfig__Output as _envoy_config_core_v3_TypedExtensionConfig__Output } from '../../../../envoy/config/core/v3/TypedExtensionConfig'; - -/** - * Fatal actions to run while crashing. Actions can be safe (meaning they are - * async-signal safe) or unsafe. We run all safe actions before we run unsafe actions. - * If using an unsafe action that could get stuck or deadlock, it important to - * have an out of band system to terminate the process. - * - * The interface for the extension is ``Envoy::Server::Configuration::FatalAction``. - * *FatalAction* extensions live in the ``envoy.extensions.fatal_actions`` API - * namespace. - */ -export interface FatalAction { - /** - * Extension specific configuration for the action. It's expected to conform - * to the ``Envoy::Server::Configuration::FatalAction`` interface. - */ - 'config'?: (_envoy_config_core_v3_TypedExtensionConfig | null); -} - -/** - * Fatal actions to run while crashing. Actions can be safe (meaning they are - * async-signal safe) or unsafe. We run all safe actions before we run unsafe actions. - * If using an unsafe action that could get stuck or deadlock, it important to - * have an out of band system to terminate the process. - * - * The interface for the extension is ``Envoy::Server::Configuration::FatalAction``. - * *FatalAction* extensions live in the ``envoy.extensions.fatal_actions`` API - * namespace. - */ -export interface FatalAction__Output { - /** - * Extension specific configuration for the action. It's expected to conform - * to the ``Envoy::Server::Configuration::FatalAction`` interface. - */ - 'config': (_envoy_config_core_v3_TypedExtensionConfig__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/LayeredRuntime.ts b/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/LayeredRuntime.ts deleted file mode 100644 index 3514d3140..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/LayeredRuntime.ts +++ /dev/null @@ -1,25 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/bootstrap/v3/bootstrap.proto - -import type { RuntimeLayer as _envoy_config_bootstrap_v3_RuntimeLayer, RuntimeLayer__Output as _envoy_config_bootstrap_v3_RuntimeLayer__Output } from '../../../../envoy/config/bootstrap/v3/RuntimeLayer'; - -/** - * Runtime :ref:`configuration overview `. - */ -export interface LayeredRuntime { - /** - * The :ref:`layers ` of the runtime. This is ordered - * such that later layers in the list overlay earlier entries. - */ - 'layers'?: (_envoy_config_bootstrap_v3_RuntimeLayer)[]; -} - -/** - * Runtime :ref:`configuration overview `. - */ -export interface LayeredRuntime__Output { - /** - * The :ref:`layers ` of the runtime. This is ordered - * such that later layers in the list overlay earlier entries. - */ - 'layers': (_envoy_config_bootstrap_v3_RuntimeLayer__Output)[]; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Runtime.ts b/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Runtime.ts deleted file mode 100644 index 4f7713bcf..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Runtime.ts +++ /dev/null @@ -1,77 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/bootstrap/v3/bootstrap.proto - -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; - -/** - * Runtime :ref:`configuration overview ` (deprecated). - */ -export interface Runtime { - /** - * The implementation assumes that the file system tree is accessed via a - * symbolic link. An atomic link swap is used when a new tree should be - * switched to. This parameter specifies the path to the symbolic link. Envoy - * will watch the location for changes and reload the file system tree when - * they happen. If this parameter is not set, there will be no disk based - * runtime. - */ - 'symlink_root'?: (string); - /** - * Specifies the subdirectory to load within the root directory. This is - * useful if multiple systems share the same delivery mechanism. Envoy - * configuration elements can be contained in a dedicated subdirectory. - */ - 'subdirectory'?: (string); - /** - * Specifies an optional subdirectory to load within the root directory. If - * specified and the directory exists, configuration values within this - * directory will override those found in the primary subdirectory. This is - * useful when Envoy is deployed across many different types of servers. - * Sometimes it is useful to have a per service cluster directory for runtime - * configuration. See below for exactly how the override directory is used. - */ - 'override_subdirectory'?: (string); - /** - * Static base runtime. This will be :ref:`overridden - * ` by other runtime layers, e.g. - * disk or admin. This follows the :ref:`runtime protobuf JSON representation - * encoding `. - */ - 'base'?: (_google_protobuf_Struct | null); -} - -/** - * Runtime :ref:`configuration overview ` (deprecated). - */ -export interface Runtime__Output { - /** - * The implementation assumes that the file system tree is accessed via a - * symbolic link. An atomic link swap is used when a new tree should be - * switched to. This parameter specifies the path to the symbolic link. Envoy - * will watch the location for changes and reload the file system tree when - * they happen. If this parameter is not set, there will be no disk based - * runtime. - */ - 'symlink_root': (string); - /** - * Specifies the subdirectory to load within the root directory. This is - * useful if multiple systems share the same delivery mechanism. Envoy - * configuration elements can be contained in a dedicated subdirectory. - */ - 'subdirectory': (string); - /** - * Specifies an optional subdirectory to load within the root directory. If - * specified and the directory exists, configuration values within this - * directory will override those found in the primary subdirectory. This is - * useful when Envoy is deployed across many different types of servers. - * Sometimes it is useful to have a per service cluster directory for runtime - * configuration. See below for exactly how the override directory is used. - */ - 'override_subdirectory': (string); - /** - * Static base runtime. This will be :ref:`overridden - * ` by other runtime layers, e.g. - * disk or admin. This follows the :ref:`runtime protobuf JSON representation - * encoding `. - */ - 'base': (_google_protobuf_Struct__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/RuntimeLayer.ts b/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/RuntimeLayer.ts deleted file mode 100644 index b072bfa7d..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/RuntimeLayer.ts +++ /dev/null @@ -1,142 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/bootstrap/v3/bootstrap.proto - -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; -import type { ConfigSource as _envoy_config_core_v3_ConfigSource, ConfigSource__Output as _envoy_config_core_v3_ConfigSource__Output } from '../../../../envoy/config/core/v3/ConfigSource'; - -/** - * :ref:`Admin console runtime ` layer. - */ -export interface _envoy_config_bootstrap_v3_RuntimeLayer_AdminLayer { -} - -/** - * :ref:`Admin console runtime ` layer. - */ -export interface _envoy_config_bootstrap_v3_RuntimeLayer_AdminLayer__Output { -} - -/** - * :ref:`Disk runtime ` layer. - */ -export interface _envoy_config_bootstrap_v3_RuntimeLayer_DiskLayer { - /** - * The implementation assumes that the file system tree is accessed via a - * symbolic link. An atomic link swap is used when a new tree should be - * switched to. This parameter specifies the path to the symbolic link. - * Envoy will watch the location for changes and reload the file system tree - * when they happen. See documentation on runtime :ref:`atomicity - * ` for further details on how reloads are - * treated. - */ - 'symlink_root'?: (string); - /** - * Specifies the subdirectory to load within the root directory. This is - * useful if multiple systems share the same delivery mechanism. Envoy - * configuration elements can be contained in a dedicated subdirectory. - */ - 'subdirectory'?: (string); - /** - * :ref:`Append ` the - * service cluster to the path under symlink root. - */ - 'append_service_cluster'?: (boolean); -} - -/** - * :ref:`Disk runtime ` layer. - */ -export interface _envoy_config_bootstrap_v3_RuntimeLayer_DiskLayer__Output { - /** - * The implementation assumes that the file system tree is accessed via a - * symbolic link. An atomic link swap is used when a new tree should be - * switched to. This parameter specifies the path to the symbolic link. - * Envoy will watch the location for changes and reload the file system tree - * when they happen. See documentation on runtime :ref:`atomicity - * ` for further details on how reloads are - * treated. - */ - 'symlink_root': (string); - /** - * Specifies the subdirectory to load within the root directory. This is - * useful if multiple systems share the same delivery mechanism. Envoy - * configuration elements can be contained in a dedicated subdirectory. - */ - 'subdirectory': (string); - /** - * :ref:`Append ` the - * service cluster to the path under symlink root. - */ - 'append_service_cluster': (boolean); -} - -/** - * :ref:`Runtime Discovery Service (RTDS) ` layer. - */ -export interface _envoy_config_bootstrap_v3_RuntimeLayer_RtdsLayer { - /** - * Resource to subscribe to at *rtds_config* for the RTDS layer. - */ - 'name'?: (string); - /** - * RTDS configuration source. - */ - 'rtds_config'?: (_envoy_config_core_v3_ConfigSource | null); -} - -/** - * :ref:`Runtime Discovery Service (RTDS) ` layer. - */ -export interface _envoy_config_bootstrap_v3_RuntimeLayer_RtdsLayer__Output { - /** - * Resource to subscribe to at *rtds_config* for the RTDS layer. - */ - 'name': (string); - /** - * RTDS configuration source. - */ - 'rtds_config': (_envoy_config_core_v3_ConfigSource__Output | null); -} - -/** - * [#next-free-field: 6] - */ -export interface RuntimeLayer { - /** - * Descriptive name for the runtime layer. This is only used for the runtime - * :http:get:`/runtime` output. - */ - 'name'?: (string); - /** - * :ref:`Static runtime ` layer. - * This follows the :ref:`runtime protobuf JSON representation encoding - * `. Unlike static xDS resources, this static - * layer is overridable by later layers in the runtime virtual filesystem. - */ - 'static_layer'?: (_google_protobuf_Struct | null); - 'disk_layer'?: (_envoy_config_bootstrap_v3_RuntimeLayer_DiskLayer | null); - 'admin_layer'?: (_envoy_config_bootstrap_v3_RuntimeLayer_AdminLayer | null); - 'rtds_layer'?: (_envoy_config_bootstrap_v3_RuntimeLayer_RtdsLayer | null); - 'layer_specifier'?: "static_layer"|"disk_layer"|"admin_layer"|"rtds_layer"; -} - -/** - * [#next-free-field: 6] - */ -export interface RuntimeLayer__Output { - /** - * Descriptive name for the runtime layer. This is only used for the runtime - * :http:get:`/runtime` output. - */ - 'name': (string); - /** - * :ref:`Static runtime ` layer. - * This follows the :ref:`runtime protobuf JSON representation encoding - * `. Unlike static xDS resources, this static - * layer is overridable by later layers in the runtime virtual filesystem. - */ - 'static_layer'?: (_google_protobuf_Struct__Output | null); - 'disk_layer'?: (_envoy_config_bootstrap_v3_RuntimeLayer_DiskLayer__Output | null); - 'admin_layer'?: (_envoy_config_bootstrap_v3_RuntimeLayer_AdminLayer__Output | null); - 'rtds_layer'?: (_envoy_config_bootstrap_v3_RuntimeLayer_RtdsLayer__Output | null); - 'layer_specifier': "static_layer"|"disk_layer"|"admin_layer"|"rtds_layer"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Watchdog.ts b/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Watchdog.ts deleted file mode 100644 index 8cd743b56..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Watchdog.ts +++ /dev/null @@ -1,141 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/bootstrap/v3/bootstrap.proto - -import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; -import type { Percent as _envoy_type_v3_Percent, Percent__Output as _envoy_type_v3_Percent__Output } from '../../../../envoy/type/v3/Percent'; -import type { TypedExtensionConfig as _envoy_config_core_v3_TypedExtensionConfig, TypedExtensionConfig__Output as _envoy_config_core_v3_TypedExtensionConfig__Output } from '../../../../envoy/config/core/v3/TypedExtensionConfig'; - -export interface _envoy_config_bootstrap_v3_Watchdog_WatchdogAction { - /** - * Extension specific configuration for the action. - */ - 'config'?: (_envoy_config_core_v3_TypedExtensionConfig | null); - 'event'?: (_envoy_config_bootstrap_v3_Watchdog_WatchdogAction_WatchdogEvent | keyof typeof _envoy_config_bootstrap_v3_Watchdog_WatchdogAction_WatchdogEvent); -} - -export interface _envoy_config_bootstrap_v3_Watchdog_WatchdogAction__Output { - /** - * Extension specific configuration for the action. - */ - 'config': (_envoy_config_core_v3_TypedExtensionConfig__Output | null); - 'event': (keyof typeof _envoy_config_bootstrap_v3_Watchdog_WatchdogAction_WatchdogEvent); -} - -// Original file: deps/envoy-api/envoy/config/bootstrap/v3/bootstrap.proto - -/** - * The events are fired in this order: KILL, MULTIKILL, MEGAMISS, MISS. - * Within an event type, actions execute in the order they are configured. - * For KILL/MULTIKILL there is a default PANIC that will run after the - * registered actions and kills the process if it wasn't already killed. - * It might be useful to specify several debug actions, and possibly an - * alternate FATAL action. - */ -export enum _envoy_config_bootstrap_v3_Watchdog_WatchdogAction_WatchdogEvent { - UNKNOWN = 0, - KILL = 1, - MULTIKILL = 2, - MEGAMISS = 3, - MISS = 4, -} - -/** - * Envoy process watchdog configuration. When configured, this monitors for - * nonresponsive threads and kills the process after the configured thresholds. - * See the :ref:`watchdog documentation ` for more information. - * [#next-free-field: 8] - */ -export interface Watchdog { - /** - * The duration after which Envoy counts a nonresponsive thread in the - * *watchdog_miss* statistic. If not specified the default is 200ms. - */ - 'miss_timeout'?: (_google_protobuf_Duration | null); - /** - * The duration after which Envoy counts a nonresponsive thread in the - * *watchdog_mega_miss* statistic. If not specified the default is - * 1000ms. - */ - 'megamiss_timeout'?: (_google_protobuf_Duration | null); - /** - * If a watched thread has been nonresponsive for this duration, assume a - * programming error and kill the entire Envoy process. Set to 0 to disable - * kill behavior. If not specified the default is 0 (disabled). - */ - 'kill_timeout'?: (_google_protobuf_Duration | null); - /** - * If max(2, ceil(registered_threads * Fraction(*multikill_threshold*))) - * threads have been nonresponsive for at least this duration kill the entire - * Envoy process. Set to 0 to disable this behavior. If not specified the - * default is 0 (disabled). - */ - 'multikill_timeout'?: (_google_protobuf_Duration | null); - /** - * Sets the threshold for *multikill_timeout* in terms of the percentage of - * nonresponsive threads required for the *multikill_timeout*. - * If not specified the default is 0. - */ - 'multikill_threshold'?: (_envoy_type_v3_Percent | null); - /** - * Defines the maximum jitter used to adjust the *kill_timeout* if *kill_timeout* is - * enabled. Enabling this feature would help to reduce risk of synchronized - * watchdog kill events across proxies due to external triggers. Set to 0 to - * disable. If not specified the default is 0 (disabled). - */ - 'max_kill_timeout_jitter'?: (_google_protobuf_Duration | null); - /** - * Register actions that will fire on given WatchDog events. - * See *WatchDogAction* for priority of events. - */ - 'actions'?: (_envoy_config_bootstrap_v3_Watchdog_WatchdogAction)[]; -} - -/** - * Envoy process watchdog configuration. When configured, this monitors for - * nonresponsive threads and kills the process after the configured thresholds. - * See the :ref:`watchdog documentation ` for more information. - * [#next-free-field: 8] - */ -export interface Watchdog__Output { - /** - * The duration after which Envoy counts a nonresponsive thread in the - * *watchdog_miss* statistic. If not specified the default is 200ms. - */ - 'miss_timeout': (_google_protobuf_Duration__Output | null); - /** - * The duration after which Envoy counts a nonresponsive thread in the - * *watchdog_mega_miss* statistic. If not specified the default is - * 1000ms. - */ - 'megamiss_timeout': (_google_protobuf_Duration__Output | null); - /** - * If a watched thread has been nonresponsive for this duration, assume a - * programming error and kill the entire Envoy process. Set to 0 to disable - * kill behavior. If not specified the default is 0 (disabled). - */ - 'kill_timeout': (_google_protobuf_Duration__Output | null); - /** - * If max(2, ceil(registered_threads * Fraction(*multikill_threshold*))) - * threads have been nonresponsive for at least this duration kill the entire - * Envoy process. Set to 0 to disable this behavior. If not specified the - * default is 0 (disabled). - */ - 'multikill_timeout': (_google_protobuf_Duration__Output | null); - /** - * Sets the threshold for *multikill_timeout* in terms of the percentage of - * nonresponsive threads required for the *multikill_timeout*. - * If not specified the default is 0. - */ - 'multikill_threshold': (_envoy_type_v3_Percent__Output | null); - /** - * Defines the maximum jitter used to adjust the *kill_timeout* if *kill_timeout* is - * enabled. Enabling this feature would help to reduce risk of synchronized - * watchdog kill events across proxies due to external triggers. Set to 0 to - * disable. If not specified the default is 0 (disabled). - */ - 'max_kill_timeout_jitter': (_google_protobuf_Duration__Output | null); - /** - * Register actions that will fire on given WatchDog events. - * See *WatchDogAction* for priority of events. - */ - 'actions': (_envoy_config_bootstrap_v3_Watchdog_WatchdogAction__Output)[]; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Watchdogs.ts b/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Watchdogs.ts deleted file mode 100644 index b478615ea..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Watchdogs.ts +++ /dev/null @@ -1,35 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/bootstrap/v3/bootstrap.proto - -import type { Watchdog as _envoy_config_bootstrap_v3_Watchdog, Watchdog__Output as _envoy_config_bootstrap_v3_Watchdog__Output } from '../../../../envoy/config/bootstrap/v3/Watchdog'; - -/** - * Allows you to specify different watchdog configs for different subsystems. - * This allows finer tuned policies for the watchdog. If a subsystem is omitted - * the default values for that system will be used. - */ -export interface Watchdogs { - /** - * Watchdog for the main thread. - */ - 'main_thread_watchdog'?: (_envoy_config_bootstrap_v3_Watchdog | null); - /** - * Watchdog for the worker threads. - */ - 'worker_watchdog'?: (_envoy_config_bootstrap_v3_Watchdog | null); -} - -/** - * Allows you to specify different watchdog configs for different subsystems. - * This allows finer tuned policies for the watchdog. If a subsystem is omitted - * the default values for that system will be used. - */ -export interface Watchdogs__Output { - /** - * Watchdog for the main thread. - */ - 'main_thread_watchdog': (_envoy_config_bootstrap_v3_Watchdog__Output | null); - /** - * Watchdog for the worker threads. - */ - 'worker_watchdog': (_envoy_config_bootstrap_v3_Watchdog__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/CircuitBreakers.ts b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/CircuitBreakers.ts index 4a8a4be36..61f473134 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/CircuitBreakers.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/CircuitBreakers.ts @@ -1,6 +1,6 @@ // Original file: deps/envoy-api/envoy/config/cluster/v3/circuit_breaker.proto -import type { RoutingPriority as _envoy_config_core_v3_RoutingPriority } from '../../../../envoy/config/core/v3/RoutingPriority'; +import type { RoutingPriority as _envoy_config_core_v3_RoutingPriority, RoutingPriority__Output as _envoy_config_core_v3_RoutingPriority__Output } from '../../../../envoy/config/core/v3/RoutingPriority'; import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; import type { Percent as _envoy_type_v3_Percent, Percent__Output as _envoy_type_v3_Percent__Output } from '../../../../envoy/type/v3/Percent'; @@ -50,7 +50,7 @@ export interface _envoy_config_cluster_v3_CircuitBreakers_Thresholds { * The :ref:`RoutingPriority` * the specified CircuitBreaker settings apply to. */ - 'priority'?: (_envoy_config_core_v3_RoutingPriority | keyof typeof _envoy_config_core_v3_RoutingPriority); + 'priority'?: (_envoy_config_core_v3_RoutingPriority); /** * The maximum number of connections that Envoy will make to the upstream * cluster. If not specified, the default is 1024. @@ -114,7 +114,7 @@ export interface _envoy_config_cluster_v3_CircuitBreakers_Thresholds__Output { * The :ref:`RoutingPriority` * the specified CircuitBreaker settings apply to. */ - 'priority': (keyof typeof _envoy_config_core_v3_RoutingPriority); + 'priority': (_envoy_config_core_v3_RoutingPriority__Output); /** * The maximum number of connections that Envoy will make to the upstream * cluster. If not specified, the default is 1024. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/Cluster.ts b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/Cluster.ts index be30d8212..8cab36301 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/Cluster.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/Cluster.ts @@ -29,22 +29,37 @@ import type { Percent as _envoy_type_v3_Percent, Percent__Output as _envoy_type_ import type { UInt64Value as _google_protobuf_UInt64Value, UInt64Value__Output as _google_protobuf_UInt64Value__Output } from '../../../../google/protobuf/UInt64Value'; import type { HealthStatusSet as _envoy_config_core_v3_HealthStatusSet, HealthStatusSet__Output as _envoy_config_core_v3_HealthStatusSet__Output } from '../../../../envoy/config/core/v3/HealthStatusSet'; import type { DoubleValue as _google_protobuf_DoubleValue, DoubleValue__Output as _google_protobuf_DoubleValue__Output } from '../../../../google/protobuf/DoubleValue'; -import type { Long } from '@grpc/proto-loader'; // Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto -export enum _envoy_config_cluster_v3_Cluster_ClusterProtocolSelection { +export const _envoy_config_cluster_v3_Cluster_ClusterProtocolSelection = { /** * Cluster can only operate on one of the possible upstream protocols (HTTP1.1, HTTP2). * If :ref:`http2_protocol_options ` are * present, HTTP2 will be used, otherwise HTTP1.1 will be used. */ - USE_CONFIGURED_PROTOCOL = 0, + USE_CONFIGURED_PROTOCOL: 'USE_CONFIGURED_PROTOCOL', /** * Use HTTP1.1 or HTTP2, depending on which one is used on the downstream connection. */ - USE_DOWNSTREAM_PROTOCOL = 1, -} + USE_DOWNSTREAM_PROTOCOL: 'USE_DOWNSTREAM_PROTOCOL', +} as const; + +export type _envoy_config_cluster_v3_Cluster_ClusterProtocolSelection = + /** + * Cluster can only operate on one of the possible upstream protocols (HTTP1.1, HTTP2). + * If :ref:`http2_protocol_options ` are + * present, HTTP2 will be used, otherwise HTTP1.1 will be used. + */ + | 'USE_CONFIGURED_PROTOCOL' + | 0 + /** + * Use HTTP1.1 or HTTP2, depending on which one is used on the downstream connection. + */ + | 'USE_DOWNSTREAM_PROTOCOL' + | 1 + +export type _envoy_config_cluster_v3_Cluster_ClusterProtocolSelection__Output = typeof _envoy_config_cluster_v3_Cluster_ClusterProtocolSelection[keyof typeof _envoy_config_cluster_v3_Cluster_ClusterProtocolSelection] /** * Common configuration for all load balancer implementations. @@ -268,36 +283,81 @@ export interface _envoy_config_cluster_v3_Cluster_CustomClusterType__Output { * Refer to :ref:`service discovery type ` * for an explanation on each type. */ -export enum _envoy_config_cluster_v3_Cluster_DiscoveryType { +export const _envoy_config_cluster_v3_Cluster_DiscoveryType = { /** * Refer to the :ref:`static discovery type` * for an explanation. */ - STATIC = 0, + STATIC: 'STATIC', /** * Refer to the :ref:`strict DNS discovery * type` * for an explanation. */ - STRICT_DNS = 1, + STRICT_DNS: 'STRICT_DNS', /** * Refer to the :ref:`logical DNS discovery * type` * for an explanation. */ - LOGICAL_DNS = 2, + LOGICAL_DNS: 'LOGICAL_DNS', /** * Refer to the :ref:`service discovery type` * for an explanation. */ - EDS = 3, + EDS: 'EDS', /** * Refer to the :ref:`original destination discovery * type` * for an explanation. */ - ORIGINAL_DST = 4, -} + ORIGINAL_DST: 'ORIGINAL_DST', +} as const; + +/** + * Refer to :ref:`service discovery type ` + * for an explanation on each type. + */ +export type _envoy_config_cluster_v3_Cluster_DiscoveryType = + /** + * Refer to the :ref:`static discovery type` + * for an explanation. + */ + | 'STATIC' + | 0 + /** + * Refer to the :ref:`strict DNS discovery + * type` + * for an explanation. + */ + | 'STRICT_DNS' + | 1 + /** + * Refer to the :ref:`logical DNS discovery + * type` + * for an explanation. + */ + | 'LOGICAL_DNS' + | 2 + /** + * Refer to the :ref:`service discovery type` + * for an explanation. + */ + | 'EDS' + | 3 + /** + * Refer to the :ref:`original destination discovery + * type` + * for an explanation. + */ + | 'ORIGINAL_DST' + | 4 + +/** + * Refer to :ref:`service discovery type ` + * for an explanation on each type. + */ +export type _envoy_config_cluster_v3_Cluster_DiscoveryType__Output = typeof _envoy_config_cluster_v3_Cluster_DiscoveryType[keyof typeof _envoy_config_cluster_v3_Cluster_DiscoveryType] // Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto @@ -324,13 +384,73 @@ export enum _envoy_config_cluster_v3_Cluster_DiscoveryType { * ignored. * [#next-major-version: deprecate AUTO in favor of a V6_PREFERRED option.] */ -export enum _envoy_config_cluster_v3_Cluster_DnsLookupFamily { - AUTO = 0, - V4_ONLY = 1, - V6_ONLY = 2, - V4_PREFERRED = 3, - ALL = 4, -} +export const _envoy_config_cluster_v3_Cluster_DnsLookupFamily = { + AUTO: 'AUTO', + V4_ONLY: 'V4_ONLY', + V6_ONLY: 'V6_ONLY', + V4_PREFERRED: 'V4_PREFERRED', + ALL: 'ALL', +} as const; + +/** + * When V4_ONLY is selected, the DNS resolver will only perform a lookup for + * addresses in the IPv4 family. If V6_ONLY is selected, the DNS resolver will + * only perform a lookup for addresses in the IPv6 family. If AUTO is + * specified, the DNS resolver will first perform a lookup for addresses in + * the IPv6 family and fallback to a lookup for addresses in the IPv4 family. + * This is semantically equivalent to a non-existent V6_PREFERRED option. + * AUTO is a legacy name that is more opaque than + * necessary and will be deprecated in favor of V6_PREFERRED in a future major version of the API. + * If V4_PREFERRED is specified, the DNS resolver will first perform a lookup for addresses in the + * IPv4 family and fallback to a lookup for addresses in the IPv6 family. i.e., the callback + * target will only get v6 addresses if there were NO v4 addresses to return. + * If ALL is specified, the DNS resolver will perform a lookup for both IPv4 and IPv6 families, + * and return all resolved addresses. When this is used, Happy Eyeballs will be enabled for + * upstream connections. Refer to :ref:`Happy Eyeballs Support ` + * for more information. + * For cluster types other than + * :ref:`STRICT_DNS` and + * :ref:`LOGICAL_DNS`, + * this setting is + * ignored. + * [#next-major-version: deprecate AUTO in favor of a V6_PREFERRED option.] + */ +export type _envoy_config_cluster_v3_Cluster_DnsLookupFamily = + | 'AUTO' + | 0 + | 'V4_ONLY' + | 1 + | 'V6_ONLY' + | 2 + | 'V4_PREFERRED' + | 3 + | 'ALL' + | 4 + +/** + * When V4_ONLY is selected, the DNS resolver will only perform a lookup for + * addresses in the IPv4 family. If V6_ONLY is selected, the DNS resolver will + * only perform a lookup for addresses in the IPv6 family. If AUTO is + * specified, the DNS resolver will first perform a lookup for addresses in + * the IPv6 family and fallback to a lookup for addresses in the IPv4 family. + * This is semantically equivalent to a non-existent V6_PREFERRED option. + * AUTO is a legacy name that is more opaque than + * necessary and will be deprecated in favor of V6_PREFERRED in a future major version of the API. + * If V4_PREFERRED is specified, the DNS resolver will first perform a lookup for addresses in the + * IPv4 family and fallback to a lookup for addresses in the IPv6 family. i.e., the callback + * target will only get v6 addresses if there were NO v4 addresses to return. + * If ALL is specified, the DNS resolver will perform a lookup for both IPv4 and IPv6 families, + * and return all resolved addresses. When this is used, Happy Eyeballs will be enabled for + * upstream connections. Refer to :ref:`Happy Eyeballs Support ` + * for more information. + * For cluster types other than + * :ref:`STRICT_DNS` and + * :ref:`LOGICAL_DNS`, + * this setting is + * ignored. + * [#next-major-version: deprecate AUTO in favor of a V6_PREFERRED option.] + */ +export type _envoy_config_cluster_v3_Cluster_DnsLookupFamily__Output = typeof _envoy_config_cluster_v3_Cluster_DnsLookupFamily[keyof typeof _envoy_config_cluster_v3_Cluster_DnsLookupFamily] /** * Only valid when discovery type is EDS. @@ -369,18 +489,40 @@ export interface _envoy_config_cluster_v3_Cluster_EdsClusterConfig__Output { /** * The hash function used to hash hosts onto the ketama ring. */ -export enum _envoy_config_cluster_v3_Cluster_RingHashLbConfig_HashFunction { +export const _envoy_config_cluster_v3_Cluster_RingHashLbConfig_HashFunction = { /** * Use `xxHash `_, this is the default hash function. */ - XX_HASH = 0, + XX_HASH: 'XX_HASH', /** * Use `MurmurHash2 `_, this is compatible with * std:hash in GNU libstdc++ 3.4.20 or above. This is typically the case when compiled * on Linux and not macOS. */ - MURMUR_HASH_2 = 1, -} + MURMUR_HASH_2: 'MURMUR_HASH_2', +} as const; + +/** + * The hash function used to hash hosts onto the ketama ring. + */ +export type _envoy_config_cluster_v3_Cluster_RingHashLbConfig_HashFunction = + /** + * Use `xxHash `_, this is the default hash function. + */ + | 'XX_HASH' + | 0 + /** + * Use `MurmurHash2 `_, this is compatible with + * std:hash in GNU libstdc++ 3.4.20 or above. This is typically the case when compiled + * on Linux and not macOS. + */ + | 'MURMUR_HASH_2' + | 1 + +/** + * The hash function used to hash hosts onto the ketama ring. + */ +export type _envoy_config_cluster_v3_Cluster_RingHashLbConfig_HashFunction__Output = typeof _envoy_config_cluster_v3_Cluster_RingHashLbConfig_HashFunction[keyof typeof _envoy_config_cluster_v3_Cluster_RingHashLbConfig_HashFunction] // Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto @@ -388,42 +530,42 @@ export enum _envoy_config_cluster_v3_Cluster_RingHashLbConfig_HashFunction { * Refer to :ref:`load balancer type ` architecture * overview section for information on each type. */ -export enum _envoy_config_cluster_v3_Cluster_LbPolicy { +export const _envoy_config_cluster_v3_Cluster_LbPolicy = { /** * Refer to the :ref:`round robin load balancing * policy` * for an explanation. */ - ROUND_ROBIN = 0, + ROUND_ROBIN: 'ROUND_ROBIN', /** * Refer to the :ref:`least request load balancing * policy` * for an explanation. */ - LEAST_REQUEST = 1, + LEAST_REQUEST: 'LEAST_REQUEST', /** * Refer to the :ref:`ring hash load balancing * policy` * for an explanation. */ - RING_HASH = 2, + RING_HASH: 'RING_HASH', /** * Refer to the :ref:`random load balancing * policy` * for an explanation. */ - RANDOM = 3, + RANDOM: 'RANDOM', /** * Refer to the :ref:`Maglev load balancing policy` * for an explanation. */ - MAGLEV = 5, + MAGLEV: 'MAGLEV', /** * This load balancer type must be specified if the configured cluster provides a cluster * specific load balancer. Consult the configured cluster's documentation for whether to set * this option or not. */ - CLUSTER_PROVIDED = 6, + CLUSTER_PROVIDED: 'CLUSTER_PROVIDED', /** * Use the new :ref:`load_balancing_policy * ` field to determine the LB policy. @@ -431,8 +573,70 @@ export enum _envoy_config_cluster_v3_Cluster_LbPolicy { * ` field without * setting any value in :ref:`lb_policy`. */ - LOAD_BALANCING_POLICY_CONFIG = 7, -} + LOAD_BALANCING_POLICY_CONFIG: 'LOAD_BALANCING_POLICY_CONFIG', +} as const; + +/** + * Refer to :ref:`load balancer type ` architecture + * overview section for information on each type. + */ +export type _envoy_config_cluster_v3_Cluster_LbPolicy = + /** + * Refer to the :ref:`round robin load balancing + * policy` + * for an explanation. + */ + | 'ROUND_ROBIN' + | 0 + /** + * Refer to the :ref:`least request load balancing + * policy` + * for an explanation. + */ + | 'LEAST_REQUEST' + | 1 + /** + * Refer to the :ref:`ring hash load balancing + * policy` + * for an explanation. + */ + | 'RING_HASH' + | 2 + /** + * Refer to the :ref:`random load balancing + * policy` + * for an explanation. + */ + | 'RANDOM' + | 3 + /** + * Refer to the :ref:`Maglev load balancing policy` + * for an explanation. + */ + | 'MAGLEV' + | 5 + /** + * This load balancer type must be specified if the configured cluster provides a cluster + * specific load balancer. Consult the configured cluster's documentation for whether to set + * this option or not. + */ + | 'CLUSTER_PROVIDED' + | 6 + /** + * Use the new :ref:`load_balancing_policy + * ` field to determine the LB policy. + * This has been deprecated in favor of using the :ref:`load_balancing_policy + * ` field without + * setting any value in :ref:`lb_policy`. + */ + | 'LOAD_BALANCING_POLICY_CONFIG' + | 7 + +/** + * Refer to :ref:`load balancer type ` architecture + * overview section for information on each type. + */ +export type _envoy_config_cluster_v3_Cluster_LbPolicy__Output = typeof _envoy_config_cluster_v3_Cluster_LbPolicy[keyof typeof _envoy_config_cluster_v3_Cluster_LbPolicy] /** * Optionally divide the endpoints in this cluster into subsets defined by @@ -445,7 +649,7 @@ export interface _envoy_config_cluster_v3_Cluster_LbSubsetConfig { * metadata. The value defaults to * :ref:`NO_FALLBACK`. */ - 'fallback_policy'?: (_envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy | keyof typeof _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy); + 'fallback_policy'?: (_envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy); /** * Specifies the default subset of endpoints used during fallback if * fallback_policy is @@ -518,7 +722,7 @@ export interface _envoy_config_cluster_v3_Cluster_LbSubsetConfig { * The value defaults to * :ref:`METADATA_NO_FALLBACK`. */ - 'metadata_fallback_policy'?: (_envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetMetadataFallbackPolicy | keyof typeof _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetMetadataFallbackPolicy); + 'metadata_fallback_policy'?: (_envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetMetadataFallbackPolicy); } /** @@ -532,7 +736,7 @@ export interface _envoy_config_cluster_v3_Cluster_LbSubsetConfig__Output { * metadata. The value defaults to * :ref:`NO_FALLBACK`. */ - 'fallback_policy': (keyof typeof _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy); + 'fallback_policy': (_envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy__Output); /** * Specifies the default subset of endpoints used during fallback if * fallback_policy is @@ -605,7 +809,7 @@ export interface _envoy_config_cluster_v3_Cluster_LbSubsetConfig__Output { * The value defaults to * :ref:`METADATA_NO_FALLBACK`. */ - 'metadata_fallback_policy': (keyof typeof _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetMetadataFallbackPolicy); + 'metadata_fallback_policy': (_envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetMetadataFallbackPolicy__Output); } // Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto @@ -617,19 +821,43 @@ export interface _envoy_config_cluster_v3_Cluster_LbSubsetConfig__Output { * etc). If DEFAULT_SUBSET is selected, load balancing is performed over the * endpoints matching the values from the default_subset field. */ -export enum _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy { - NO_FALLBACK = 0, - ANY_ENDPOINT = 1, - DEFAULT_SUBSET = 2, -} +export const _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy = { + NO_FALLBACK: 'NO_FALLBACK', + ANY_ENDPOINT: 'ANY_ENDPOINT', + DEFAULT_SUBSET: 'DEFAULT_SUBSET', +} as const; + +/** + * If NO_FALLBACK is selected, a result + * equivalent to no healthy hosts is reported. If ANY_ENDPOINT is selected, + * any cluster endpoint may be returned (subject to policy, health checks, + * etc). If DEFAULT_SUBSET is selected, load balancing is performed over the + * endpoints matching the values from the default_subset field. + */ +export type _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy = + | 'NO_FALLBACK' + | 0 + | 'ANY_ENDPOINT' + | 1 + | 'DEFAULT_SUBSET' + | 2 + +/** + * If NO_FALLBACK is selected, a result + * equivalent to no healthy hosts is reported. If ANY_ENDPOINT is selected, + * any cluster endpoint may be returned (subject to policy, health checks, + * etc). If DEFAULT_SUBSET is selected, load balancing is performed over the + * endpoints matching the values from the default_subset field. + */ +export type _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy__Output = typeof _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy[keyof typeof _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy] // Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto -export enum _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetMetadataFallbackPolicy { +export const _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetMetadataFallbackPolicy = { /** * No fallback. Route metadata will be used as-is. */ - METADATA_NO_FALLBACK = 0, + METADATA_NO_FALLBACK: 'METADATA_NO_FALLBACK', /** * A special metadata key ``fallback_list`` will be used to provide variants of metadata to try. * Value of ``fallback_list`` key has to be a list. Every list element has to be a struct - it will @@ -671,8 +899,60 @@ export enum _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetMetadataFall * * is used. */ - FALLBACK_LIST = 1, -} + FALLBACK_LIST: 'FALLBACK_LIST', +} as const; + +export type _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetMetadataFallbackPolicy = + /** + * No fallback. Route metadata will be used as-is. + */ + | 'METADATA_NO_FALLBACK' + | 0 + /** + * A special metadata key ``fallback_list`` will be used to provide variants of metadata to try. + * Value of ``fallback_list`` key has to be a list. Every list element has to be a struct - it will + * be merged with route metadata, overriding keys that appear in both places. + * ``fallback_list`` entries will be used in order until a host is found. + * + * ``fallback_list`` key itself is removed from metadata before subset load balancing is performed. + * + * Example: + * + * for metadata: + * + * .. code-block:: yaml + * + * version: 1.0 + * fallback_list: + * - version: 2.0 + * hardware: c64 + * - hardware: c32 + * - version: 3.0 + * + * at first, metadata: + * + * .. code-block:: json + * + * {"version": "2.0", "hardware": "c64"} + * + * will be used for load balancing. If no host is found, metadata: + * + * .. code-block:: json + * + * {"version": "1.0", "hardware": "c32"} + * + * is next to try. If it still results in no host, finally metadata: + * + * .. code-block:: json + * + * {"version": "3.0"} + * + * is used. + */ + | 'FALLBACK_LIST' + | 1 + +export type _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetMetadataFallbackPolicy__Output = typeof _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetMetadataFallbackPolicy[keyof typeof _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetMetadataFallbackPolicy] /** * Specifications for subsets. @@ -698,7 +978,7 @@ export interface _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelecto * The behavior used when no endpoint subset matches the selected route's * metadata. */ - 'fallback_policy'?: (_envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy | keyof typeof _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy); + 'fallback_policy'?: (_envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy); /** * Subset of * :ref:`keys` used by @@ -737,7 +1017,7 @@ export interface _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelecto * The behavior used when no endpoint subset matches the selected route's * metadata. */ - 'fallback_policy': (keyof typeof _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy); + 'fallback_policy': (_envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy__Output); /** * Subset of * :ref:`keys` used by @@ -757,25 +1037,25 @@ export interface _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelecto /** * Allows to override top level fallback policy per selector. */ -export enum _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy { +export const _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy = { /** * If NOT_DEFINED top level config fallback policy is used instead. */ - NOT_DEFINED = 0, + NOT_DEFINED: 'NOT_DEFINED', /** * If NO_FALLBACK is selected, a result equivalent to no healthy hosts is reported. */ - NO_FALLBACK = 1, + NO_FALLBACK: 'NO_FALLBACK', /** * If ANY_ENDPOINT is selected, any cluster endpoint may be returned * (subject to policy, health checks, etc). */ - ANY_ENDPOINT = 2, + ANY_ENDPOINT: 'ANY_ENDPOINT', /** * If DEFAULT_SUBSET is selected, load balancing is performed over the * endpoints matching the values from the default_subset field. */ - DEFAULT_SUBSET = 3, + DEFAULT_SUBSET: 'DEFAULT_SUBSET', /** * If KEYS_SUBSET is selected, subset selector matching is performed again with metadata * keys reduced to @@ -783,8 +1063,49 @@ export enum _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_LbS * It allows for a fallback to a different, less specific selector if some of the keys of * the selector are considered optional. */ - KEYS_SUBSET = 4, -} + KEYS_SUBSET: 'KEYS_SUBSET', +} as const; + +/** + * Allows to override top level fallback policy per selector. + */ +export type _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy = + /** + * If NOT_DEFINED top level config fallback policy is used instead. + */ + | 'NOT_DEFINED' + | 0 + /** + * If NO_FALLBACK is selected, a result equivalent to no healthy hosts is reported. + */ + | 'NO_FALLBACK' + | 1 + /** + * If ANY_ENDPOINT is selected, any cluster endpoint may be returned + * (subject to policy, health checks, etc). + */ + | 'ANY_ENDPOINT' + | 2 + /** + * If DEFAULT_SUBSET is selected, load balancing is performed over the + * endpoints matching the values from the default_subset field. + */ + | 'DEFAULT_SUBSET' + | 3 + /** + * If KEYS_SUBSET is selected, subset selector matching is performed again with metadata + * keys reduced to + * :ref:`fallback_keys_subset`. + * It allows for a fallback to a different, less specific selector if some of the keys of + * the selector are considered optional. + */ + | 'KEYS_SUBSET' + | 4 + +/** + * Allows to override top level fallback policy per selector. + */ +export type _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy__Output = typeof _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy[keyof typeof _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy] /** * Specific configuration for the LeastRequest load balancing policy. @@ -1138,7 +1459,7 @@ export interface _envoy_config_cluster_v3_Cluster_RingHashLbConfig { * The hash function used to hash hosts onto the ketama ring. The value defaults to * :ref:`XX_HASH`. */ - 'hash_function'?: (_envoy_config_cluster_v3_Cluster_RingHashLbConfig_HashFunction | keyof typeof _envoy_config_cluster_v3_Cluster_RingHashLbConfig_HashFunction); + 'hash_function'?: (_envoy_config_cluster_v3_Cluster_RingHashLbConfig_HashFunction); /** * Maximum hash ring size. Defaults to 8M entries, and limited to 8M entries, but can be lowered * to further constrain resource use. See also @@ -1163,7 +1484,7 @@ export interface _envoy_config_cluster_v3_Cluster_RingHashLbConfig__Output { * The hash function used to hash hosts onto the ketama ring. The value defaults to * :ref:`XX_HASH`. */ - 'hash_function': (keyof typeof _envoy_config_cluster_v3_Cluster_RingHashLbConfig_HashFunction); + 'hash_function': (_envoy_config_cluster_v3_Cluster_RingHashLbConfig_HashFunction__Output); /** * Maximum hash ring size. Defaults to 8M entries, and limited to 8M entries, but can be lowered * to further constrain resource use. See also @@ -1383,7 +1704,7 @@ export interface Cluster { * The :ref:`service discovery type ` * to use for resolving the cluster. */ - 'type'?: (_envoy_config_cluster_v3_Cluster_DiscoveryType | keyof typeof _envoy_config_cluster_v3_Cluster_DiscoveryType); + 'type'?: (_envoy_config_cluster_v3_Cluster_DiscoveryType); /** * Configuration to use for EDS updates for the Cluster. */ @@ -1402,7 +1723,7 @@ export interface Cluster { * The :ref:`load balancer type ` to use * when picking a host in the cluster. */ - 'lb_policy'?: (_envoy_config_cluster_v3_Cluster_LbPolicy | keyof typeof _envoy_config_cluster_v3_Cluster_LbPolicy); + 'lb_policy'?: (_envoy_config_cluster_v3_Cluster_LbPolicy); /** * Optional :ref:`active health checking ` * configuration for the cluster. If no @@ -1418,6 +1739,7 @@ export interface Cluster { * * .. attention:: * This field has been deprecated in favor of the :ref:`max_requests_per_connection ` field. + * @deprecated */ 'max_requests_per_connection'?: (_google_protobuf_UInt32Value | null); /** @@ -1433,6 +1755,7 @@ export interface Cluster { * See :ref:`upstream_http_protocol_options * ` * for example usage. + * @deprecated */ 'http_protocol_options'?: (_envoy_config_core_v3_Http1ProtocolOptions | null); /** @@ -1449,6 +1772,7 @@ export interface Cluster { * See :ref:`upstream_http_protocol_options * ` * for example usage. + * @deprecated */ 'http2_protocol_options'?: (_envoy_config_core_v3_Http2ProtocolOptions | null); /** @@ -1468,7 +1792,7 @@ export interface Cluster { * value defaults to * :ref:`AUTO`. */ - 'dns_lookup_family'?: (_envoy_config_cluster_v3_Cluster_DnsLookupFamily | keyof typeof _envoy_config_cluster_v3_Cluster_DnsLookupFamily); + 'dns_lookup_family'?: (_envoy_config_cluster_v3_Cluster_DnsLookupFamily); /** * If DNS resolvers are specified and the cluster type is either * :ref:`STRICT_DNS`, @@ -1482,6 +1806,7 @@ export interface Cluster { * this setting is ignored. * This field is deprecated in favor of ``dns_resolution_config`` * which aggregates all of the DNS resolver configuration in a single message. + * @deprecated */ 'dns_resolvers'?: (_envoy_config_core_v3_Address)[]; /** @@ -1543,8 +1868,9 @@ export interface Cluster { * ` message. * http_protocol_options can be set via the cluster's * :ref:`extension_protocol_options`. + * @deprecated */ - 'protocol_selection'?: (_envoy_config_cluster_v3_Cluster_ClusterProtocolSelection | keyof typeof _envoy_config_cluster_v3_Cluster_ClusterProtocolSelection); + 'protocol_selection'?: (_envoy_config_cluster_v3_Cluster_ClusterProtocolSelection); /** * Common configuration for all load balancer implementations. */ @@ -1570,6 +1896,7 @@ export interface Cluster { * See :ref:`upstream_http_protocol_options * ` * for example usage. + * @deprecated */ 'common_http_protocol_options'?: (_envoy_config_core_v3_HttpProtocolOptions | null); /** @@ -1732,6 +2059,7 @@ export interface Cluster { * Always use TCP queries instead of UDP queries for DNS lookups. * This field is deprecated in favor of ``dns_resolution_config`` * which aggregates all of the DNS resolver configuration in a single message. + * @deprecated */ 'use_tcp_for_dns_lookups'?: (boolean); /** @@ -1745,6 +2073,7 @@ export interface Cluster { * See :ref:`upstream_http_protocol_options * ` * for example usage. + * @deprecated */ 'upstream_http_protocol_options'?: (_envoy_config_core_v3_UpstreamHttpProtocolOptions | null); /** @@ -1758,6 +2087,7 @@ export interface Cluster { * * This field has been deprecated in favor of ``timeout_budgets``, part of * :ref:`track_cluster_stats `. + * @deprecated */ 'track_timeout_budgets'?: (boolean); /** @@ -1802,6 +2132,7 @@ export interface Cluster { * DNS resolution configuration which includes the underlying dns resolver addresses and options. * This field is deprecated in favor of * :ref:`typed_dns_resolver_config `. + * @deprecated */ 'dns_resolution_config'?: (_envoy_config_core_v3_DnsResolutionConfig | null); /** @@ -1862,7 +2193,7 @@ export interface Cluster__Output { * The :ref:`service discovery type ` * to use for resolving the cluster. */ - 'type'?: (keyof typeof _envoy_config_cluster_v3_Cluster_DiscoveryType); + 'type'?: (_envoy_config_cluster_v3_Cluster_DiscoveryType__Output); /** * Configuration to use for EDS updates for the Cluster. */ @@ -1881,7 +2212,7 @@ export interface Cluster__Output { * The :ref:`load balancer type ` to use * when picking a host in the cluster. */ - 'lb_policy': (keyof typeof _envoy_config_cluster_v3_Cluster_LbPolicy); + 'lb_policy': (_envoy_config_cluster_v3_Cluster_LbPolicy__Output); /** * Optional :ref:`active health checking ` * configuration for the cluster. If no @@ -1897,6 +2228,7 @@ export interface Cluster__Output { * * .. attention:: * This field has been deprecated in favor of the :ref:`max_requests_per_connection ` field. + * @deprecated */ 'max_requests_per_connection': (_google_protobuf_UInt32Value__Output | null); /** @@ -1912,6 +2244,7 @@ export interface Cluster__Output { * See :ref:`upstream_http_protocol_options * ` * for example usage. + * @deprecated */ 'http_protocol_options': (_envoy_config_core_v3_Http1ProtocolOptions__Output | null); /** @@ -1928,6 +2261,7 @@ export interface Cluster__Output { * See :ref:`upstream_http_protocol_options * ` * for example usage. + * @deprecated */ 'http2_protocol_options': (_envoy_config_core_v3_Http2ProtocolOptions__Output | null); /** @@ -1947,7 +2281,7 @@ export interface Cluster__Output { * value defaults to * :ref:`AUTO`. */ - 'dns_lookup_family': (keyof typeof _envoy_config_cluster_v3_Cluster_DnsLookupFamily); + 'dns_lookup_family': (_envoy_config_cluster_v3_Cluster_DnsLookupFamily__Output); /** * If DNS resolvers are specified and the cluster type is either * :ref:`STRICT_DNS`, @@ -1961,6 +2295,7 @@ export interface Cluster__Output { * this setting is ignored. * This field is deprecated in favor of ``dns_resolution_config`` * which aggregates all of the DNS resolver configuration in a single message. + * @deprecated */ 'dns_resolvers': (_envoy_config_core_v3_Address__Output)[]; /** @@ -2022,8 +2357,9 @@ export interface Cluster__Output { * ` message. * http_protocol_options can be set via the cluster's * :ref:`extension_protocol_options`. + * @deprecated */ - 'protocol_selection': (keyof typeof _envoy_config_cluster_v3_Cluster_ClusterProtocolSelection); + 'protocol_selection': (_envoy_config_cluster_v3_Cluster_ClusterProtocolSelection__Output); /** * Common configuration for all load balancer implementations. */ @@ -2049,6 +2385,7 @@ export interface Cluster__Output { * See :ref:`upstream_http_protocol_options * ` * for example usage. + * @deprecated */ 'common_http_protocol_options': (_envoy_config_core_v3_HttpProtocolOptions__Output | null); /** @@ -2211,6 +2548,7 @@ export interface Cluster__Output { * Always use TCP queries instead of UDP queries for DNS lookups. * This field is deprecated in favor of ``dns_resolution_config`` * which aggregates all of the DNS resolver configuration in a single message. + * @deprecated */ 'use_tcp_for_dns_lookups': (boolean); /** @@ -2224,6 +2562,7 @@ export interface Cluster__Output { * See :ref:`upstream_http_protocol_options * ` * for example usage. + * @deprecated */ 'upstream_http_protocol_options': (_envoy_config_core_v3_UpstreamHttpProtocolOptions__Output | null); /** @@ -2237,6 +2576,7 @@ export interface Cluster__Output { * * This field has been deprecated in favor of ``timeout_budgets``, part of * :ref:`track_cluster_stats `. + * @deprecated */ 'track_timeout_budgets': (boolean); /** @@ -2281,6 +2621,7 @@ export interface Cluster__Output { * DNS resolution configuration which includes the underlying dns resolver addresses and options. * This field is deprecated in favor of * :ref:`typed_dns_resolver_config `. + * @deprecated */ 'dns_resolution_config': (_envoy_config_core_v3_DnsResolutionConfig__Output | null); /** diff --git a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/UpstreamBindConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/UpstreamBindConfig.ts deleted file mode 100644 index f2dbd0608..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/UpstreamBindConfig.ts +++ /dev/null @@ -1,25 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto - -import type { Address as _envoy_config_core_v3_Address, Address__Output as _envoy_config_core_v3_Address__Output } from '../../../../envoy/config/core/v3/Address'; - -/** - * An extensible structure containing the address Envoy should bind to when - * establishing upstream connections. - */ -export interface UpstreamBindConfig { - /** - * The address Envoy should bind to when establishing upstream connections. - */ - 'source_address'?: (_envoy_config_core_v3_Address | null); -} - -/** - * An extensible structure containing the address Envoy should bind to when - * establishing upstream connections. - */ -export interface UpstreamBindConfig__Output { - /** - * The address Envoy should bind to when establishing upstream connections. - */ - 'source_address': (_envoy_config_core_v3_Address__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ApiConfigSource.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ApiConfigSource.ts index 691ab93ba..0a2f11bdf 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ApiConfigSource.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ApiConfigSource.ts @@ -3,7 +3,7 @@ import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; import type { GrpcService as _envoy_config_core_v3_GrpcService, GrpcService__Output as _envoy_config_core_v3_GrpcService__Output } from '../../../../envoy/config/core/v3/GrpcService'; import type { RateLimitSettings as _envoy_config_core_v3_RateLimitSettings, RateLimitSettings__Output as _envoy_config_core_v3_RateLimitSettings__Output } from '../../../../envoy/config/core/v3/RateLimitSettings'; -import type { ApiVersion as _envoy_config_core_v3_ApiVersion } from '../../../../envoy/config/core/v3/ApiVersion'; +import type { ApiVersion as _envoy_config_core_v3_ApiVersion, ApiVersion__Output as _envoy_config_core_v3_ApiVersion__Output } from '../../../../envoy/config/core/v3/ApiVersion'; import type { TypedExtensionConfig as _envoy_config_core_v3_TypedExtensionConfig, TypedExtensionConfig__Output as _envoy_config_core_v3_TypedExtensionConfig__Output } from '../../../../envoy/config/core/v3/TypedExtensionConfig'; // Original file: deps/envoy-api/envoy/config/core/v3/config_source.proto @@ -11,41 +11,91 @@ import type { TypedExtensionConfig as _envoy_config_core_v3_TypedExtensionConfig /** * APIs may be fetched via either REST or gRPC. */ -export enum _envoy_config_core_v3_ApiConfigSource_ApiType { +export const _envoy_config_core_v3_ApiConfigSource_ApiType = { /** * Ideally this would be 'reserved 0' but one can't reserve the default * value. Instead we throw an exception if this is ever used. + * @deprecated */ - DEPRECATED_AND_UNAVAILABLE_DO_NOT_USE = 0, + DEPRECATED_AND_UNAVAILABLE_DO_NOT_USE: 'DEPRECATED_AND_UNAVAILABLE_DO_NOT_USE', /** * REST-JSON v2 API. The `canonical JSON encoding * `_ for * the v2 protos is used. */ - REST = 1, + REST: 'REST', /** * SotW gRPC service. */ - GRPC = 2, + GRPC: 'GRPC', /** * Using the delta xDS gRPC service, i.e. DeltaDiscovery{Request,Response} * rather than Discovery{Request,Response}. Rather than sending Envoy the entire state * with every update, the xDS server only sends what has changed since the last update. */ - DELTA_GRPC = 3, + DELTA_GRPC: 'DELTA_GRPC', /** * SotW xDS gRPC with ADS. All resources which resolve to this configuration source will be * multiplexed on a single connection to an ADS endpoint. * [#not-implemented-hide:] */ - AGGREGATED_GRPC = 5, + AGGREGATED_GRPC: 'AGGREGATED_GRPC', /** * Delta xDS gRPC with ADS. All resources which resolve to this configuration source will be * multiplexed on a single connection to an ADS endpoint. * [#not-implemented-hide:] */ - AGGREGATED_DELTA_GRPC = 6, -} + AGGREGATED_DELTA_GRPC: 'AGGREGATED_DELTA_GRPC', +} as const; + +/** + * APIs may be fetched via either REST or gRPC. + */ +export type _envoy_config_core_v3_ApiConfigSource_ApiType = + /** + * Ideally this would be 'reserved 0' but one can't reserve the default + * value. Instead we throw an exception if this is ever used. + */ + | 'DEPRECATED_AND_UNAVAILABLE_DO_NOT_USE' + | 0 + /** + * REST-JSON v2 API. The `canonical JSON encoding + * `_ for + * the v2 protos is used. + */ + | 'REST' + | 1 + /** + * SotW gRPC service. + */ + | 'GRPC' + | 2 + /** + * Using the delta xDS gRPC service, i.e. DeltaDiscovery{Request,Response} + * rather than Discovery{Request,Response}. Rather than sending Envoy the entire state + * with every update, the xDS server only sends what has changed since the last update. + */ + | 'DELTA_GRPC' + | 3 + /** + * SotW xDS gRPC with ADS. All resources which resolve to this configuration source will be + * multiplexed on a single connection to an ADS endpoint. + * [#not-implemented-hide:] + */ + | 'AGGREGATED_GRPC' + | 5 + /** + * Delta xDS gRPC with ADS. All resources which resolve to this configuration source will be + * multiplexed on a single connection to an ADS endpoint. + * [#not-implemented-hide:] + */ + | 'AGGREGATED_DELTA_GRPC' + | 6 + +/** + * APIs may be fetched via either REST or gRPC. + */ +export type _envoy_config_core_v3_ApiConfigSource_ApiType__Output = typeof _envoy_config_core_v3_ApiConfigSource_ApiType[keyof typeof _envoy_config_core_v3_ApiConfigSource_ApiType] /** * API configuration source. This identifies the API type and cluster that Envoy @@ -56,7 +106,7 @@ export interface ApiConfigSource { /** * API type (gRPC, REST, delta gRPC) */ - 'api_type'?: (_envoy_config_core_v3_ApiConfigSource_ApiType | keyof typeof _envoy_config_core_v3_ApiConfigSource_ApiType); + 'api_type'?: (_envoy_config_core_v3_ApiConfigSource_ApiType); /** * Cluster names should be used only with REST. If > 1 * cluster is defined, clusters will be cycled through if any kind of failure @@ -94,7 +144,7 @@ export interface ApiConfigSource { * API version for xDS transport protocol. This describes the xDS gRPC/REST * endpoint and version of [Delta]DiscoveryRequest/Response used on the wire. */ - 'transport_api_version'?: (_envoy_config_core_v3_ApiVersion | keyof typeof _envoy_config_core_v3_ApiVersion); + 'transport_api_version'?: (_envoy_config_core_v3_ApiVersion); /** * A list of config validators that will be executed when a new update is * received from the ApiConfigSource. Note that each validator handles a @@ -117,7 +167,7 @@ export interface ApiConfigSource__Output { /** * API type (gRPC, REST, delta gRPC) */ - 'api_type': (keyof typeof _envoy_config_core_v3_ApiConfigSource_ApiType); + 'api_type': (_envoy_config_core_v3_ApiConfigSource_ApiType__Output); /** * Cluster names should be used only with REST. If > 1 * cluster is defined, clusters will be cycled through if any kind of failure @@ -155,7 +205,7 @@ export interface ApiConfigSource__Output { * API version for xDS transport protocol. This describes the xDS gRPC/REST * endpoint and version of [Delta]DiscoveryRequest/Response used on the wire. */ - 'transport_api_version': (keyof typeof _envoy_config_core_v3_ApiVersion); + 'transport_api_version': (_envoy_config_core_v3_ApiVersion__Output); /** * A list of config validators that will be executed when a new update is * received from the ApiConfigSource. Note that each validator handles a diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ApiVersion.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ApiVersion.ts index b46f6ec43..d3bad5d4e 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ApiVersion.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ApiVersion.ts @@ -4,19 +4,50 @@ * xDS API and non-xDS services version. This is used to describe both resource and transport * protocol versions (in distinct configuration fields). */ -export enum ApiVersion { +export const ApiVersion = { /** * When not specified, we assume v2, to ease migration to Envoy's stable API * versioning. If a client does not support v2 (e.g. due to deprecation), this * is an invalid value. + * @deprecated */ - AUTO = 0, + AUTO: 'AUTO', /** * Use xDS v2 API. + * @deprecated */ - V2 = 1, + V2: 'V2', /** * Use xDS v3 API. */ - V3 = 2, -} + V3: 'V3', +} as const; + +/** + * xDS API and non-xDS services version. This is used to describe both resource and transport + * protocol versions (in distinct configuration fields). + */ +export type ApiVersion = + /** + * When not specified, we assume v2, to ease migration to Envoy's stable API + * versioning. If a client does not support v2 (e.g. due to deprecation), this + * is an invalid value. + */ + | 'AUTO' + | 0 + /** + * Use xDS v2 API. + */ + | 'V2' + | 1 + /** + * Use xDS v3 API. + */ + | 'V3' + | 2 + +/** + * xDS API and non-xDS services version. This is used to describe both resource and transport + * protocol versions (in distinct configuration fields). + */ +export type ApiVersion__Output = typeof ApiVersion[keyof typeof ApiVersion] diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BindConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BindConfig.ts index 733c609b1..54543facc 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BindConfig.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BindConfig.ts @@ -31,6 +31,7 @@ export interface BindConfig { /** * Deprecated by * :ref:`extra_source_addresses ` + * @deprecated */ 'additional_source_addresses'?: (_envoy_config_core_v3_SocketAddress)[]; /** @@ -72,6 +73,7 @@ export interface BindConfig__Output { /** * Deprecated by * :ref:`extra_source_addresses ` + * @deprecated */ 'additional_source_addresses': (_envoy_config_core_v3_SocketAddress__Output)[]; /** diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ConfigSource.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ConfigSource.ts index 5438b6e7d..1b98848ef 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ConfigSource.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ConfigSource.ts @@ -4,7 +4,7 @@ import type { ApiConfigSource as _envoy_config_core_v3_ApiConfigSource, ApiConfi import type { AggregatedConfigSource as _envoy_config_core_v3_AggregatedConfigSource, AggregatedConfigSource__Output as _envoy_config_core_v3_AggregatedConfigSource__Output } from '../../../../envoy/config/core/v3/AggregatedConfigSource'; import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; import type { SelfConfigSource as _envoy_config_core_v3_SelfConfigSource, SelfConfigSource__Output as _envoy_config_core_v3_SelfConfigSource__Output } from '../../../../envoy/config/core/v3/SelfConfigSource'; -import type { ApiVersion as _envoy_config_core_v3_ApiVersion } from '../../../../envoy/config/core/v3/ApiVersion'; +import type { ApiVersion as _envoy_config_core_v3_ApiVersion, ApiVersion__Output as _envoy_config_core_v3_ApiVersion__Output } from '../../../../envoy/config/core/v3/ApiVersion'; import type { Authority as _xds_core_v3_Authority, Authority__Output as _xds_core_v3_Authority__Output } from '../../../../xds/core/v3/Authority'; import type { PathConfigSource as _envoy_config_core_v3_PathConfigSource, PathConfigSource__Output as _envoy_config_core_v3_PathConfigSource__Output } from '../../../../envoy/config/core/v3/PathConfigSource'; @@ -20,6 +20,7 @@ import type { PathConfigSource as _envoy_config_core_v3_PathConfigSource, PathCo export interface ConfigSource { /** * Deprecated in favor of ``path_config_source``. Use that field instead. + * @deprecated */ 'path'?: (string); /** @@ -60,7 +61,7 @@ export interface ConfigSource { * will request for resources and the resource type that the client will in * turn expect to be delivered. */ - 'resource_api_version'?: (_envoy_config_core_v3_ApiVersion | keyof typeof _envoy_config_core_v3_ApiVersion); + 'resource_api_version'?: (_envoy_config_core_v3_ApiVersion); /** * Authorities that this config source may be used for. An authority specified in a xdstp:// URL * is resolved to a ``ConfigSource`` prior to configuration fetch. This field provides the @@ -87,6 +88,7 @@ export interface ConfigSource { export interface ConfigSource__Output { /** * Deprecated in favor of ``path_config_source``. Use that field instead. + * @deprecated */ 'path'?: (string); /** @@ -127,7 +129,7 @@ export interface ConfigSource__Output { * will request for resources and the resource type that the client will in * turn expect to be delivered. */ - 'resource_api_version': (keyof typeof _envoy_config_core_v3_ApiVersion); + 'resource_api_version': (_envoy_config_core_v3_ApiVersion__Output); /** * Authorities that this config source may be used for. An authority specified in a xdstp:// URL * is resolved to a ``ConfigSource`` prior to configuration fetch. This field provides the diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Extension.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Extension.ts index b25c15cce..dbbdb0cee 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Extension.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Extension.ts @@ -24,6 +24,7 @@ export interface Extension { * [#not-implemented-hide:] Type descriptor of extension configuration proto. * [#comment:TODO(yanavlasov): Link to the doc with existing configuration protos.] * [#comment:TODO(yanavlasov): Add tests when PR #9391 lands.] + * @deprecated */ 'type_descriptor'?: (string); /** @@ -64,6 +65,7 @@ export interface Extension__Output { * [#not-implemented-hide:] Type descriptor of extension configuration proto. * [#comment:TODO(yanavlasov): Link to the doc with existing configuration protos.] * [#comment:TODO(yanavlasov): Add tests when PR #9391 lands.] + * @deprecated */ 'type_descriptor': (string); /** diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HeaderValueOption.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HeaderValueOption.ts index efb656303..e7a0a8d87 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HeaderValueOption.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HeaderValueOption.ts @@ -8,25 +8,55 @@ import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _goo /** * Describes the supported actions types for header append action. */ -export enum _envoy_config_core_v3_HeaderValueOption_HeaderAppendAction { +export const _envoy_config_core_v3_HeaderValueOption_HeaderAppendAction = { /** * This action will append the specified value to the existing values if the header * already exists. If the header doesn't exist then this will add the header with * specified key and value. */ - APPEND_IF_EXISTS_OR_ADD = 0, + APPEND_IF_EXISTS_OR_ADD: 'APPEND_IF_EXISTS_OR_ADD', /** * This action will add the header if it doesn't already exist. If the header * already exists then this will be a no-op. */ - ADD_IF_ABSENT = 1, + ADD_IF_ABSENT: 'ADD_IF_ABSENT', /** * This action will overwrite the specified value by discarding any existing values if * the header already exists. If the header doesn't exist then this will add the header * with specified key and value. */ - OVERWRITE_IF_EXISTS_OR_ADD = 2, -} + OVERWRITE_IF_EXISTS_OR_ADD: 'OVERWRITE_IF_EXISTS_OR_ADD', +} as const; + +/** + * Describes the supported actions types for header append action. + */ +export type _envoy_config_core_v3_HeaderValueOption_HeaderAppendAction = + /** + * This action will append the specified value to the existing values if the header + * already exists. If the header doesn't exist then this will add the header with + * specified key and value. + */ + | 'APPEND_IF_EXISTS_OR_ADD' + | 0 + /** + * This action will add the header if it doesn't already exist. If the header + * already exists then this will be a no-op. + */ + | 'ADD_IF_ABSENT' + | 1 + /** + * This action will overwrite the specified value by discarding any existing values if + * the header already exists. If the header doesn't exist then this will add the header + * with specified key and value. + */ + | 'OVERWRITE_IF_EXISTS_OR_ADD' + | 2 + +/** + * Describes the supported actions types for header append action. + */ +export type _envoy_config_core_v3_HeaderValueOption_HeaderAppendAction__Output = typeof _envoy_config_core_v3_HeaderValueOption_HeaderAppendAction[keyof typeof _envoy_config_core_v3_HeaderValueOption_HeaderAppendAction] /** * Header name/value pair plus option to control append behavior. @@ -46,6 +76,7 @@ export interface HeaderValueOption { * The :ref:`external authorization service ` and * :ref:`external processor service ` have * default value (``false``) for this field. + * @deprecated */ 'append'?: (_google_protobuf_BoolValue | null); /** @@ -54,7 +85,7 @@ export interface HeaderValueOption { * Value defaults to :ref:`APPEND_IF_EXISTS_OR_ADD * `. */ - 'append_action'?: (_envoy_config_core_v3_HeaderValueOption_HeaderAppendAction | keyof typeof _envoy_config_core_v3_HeaderValueOption_HeaderAppendAction); + 'append_action'?: (_envoy_config_core_v3_HeaderValueOption_HeaderAppendAction); /** * Is the header value allowed to be empty? If false (default), custom headers with empty values are dropped, * otherwise they are added. @@ -80,6 +111,7 @@ export interface HeaderValueOption__Output { * The :ref:`external authorization service ` and * :ref:`external processor service ` have * default value (``false``) for this field. + * @deprecated */ 'append': (_google_protobuf_BoolValue__Output | null); /** @@ -88,7 +120,7 @@ export interface HeaderValueOption__Output { * Value defaults to :ref:`APPEND_IF_EXISTS_OR_ADD * `. */ - 'append_action': (keyof typeof _envoy_config_core_v3_HeaderValueOption_HeaderAppendAction); + 'append_action': (_envoy_config_core_v3_HeaderValueOption_HeaderAppendAction__Output); /** * Is the header value allowed to be empty? If false (default), custom headers with empty values are dropped, * otherwise they are added. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HealthCheck.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HealthCheck.ts index e0638df7d..f6605412e 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HealthCheck.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HealthCheck.ts @@ -9,11 +9,10 @@ import type { TypedExtensionConfig as _envoy_config_core_v3_TypedExtensionConfig import type { UInt64Value as _google_protobuf_UInt64Value, UInt64Value__Output as _google_protobuf_UInt64Value__Output } from '../../../../google/protobuf/UInt64Value'; import type { HeaderValueOption as _envoy_config_core_v3_HeaderValueOption, HeaderValueOption__Output as _envoy_config_core_v3_HeaderValueOption__Output } from '../../../../envoy/config/core/v3/HeaderValueOption'; import type { Int64Range as _envoy_type_v3_Int64Range, Int64Range__Output as _envoy_type_v3_Int64Range__Output } from '../../../../envoy/type/v3/Int64Range'; -import type { CodecClientType as _envoy_type_v3_CodecClientType } from '../../../../envoy/type/v3/CodecClientType'; +import type { CodecClientType as _envoy_type_v3_CodecClientType, CodecClientType__Output as _envoy_type_v3_CodecClientType__Output } from '../../../../envoy/type/v3/CodecClientType'; import type { StringMatcher as _envoy_type_matcher_v3_StringMatcher, StringMatcher__Output as _envoy_type_matcher_v3_StringMatcher__Output } from '../../../../envoy/type/matcher/v3/StringMatcher'; -import type { RequestMethod as _envoy_config_core_v3_RequestMethod } from '../../../../envoy/config/core/v3/RequestMethod'; +import type { RequestMethod as _envoy_config_core_v3_RequestMethod, RequestMethod__Output as _envoy_config_core_v3_RequestMethod__Output } from '../../../../envoy/config/core/v3/RequestMethod'; import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; -import type { Long } from '@grpc/proto-loader'; /** * Custom health check. @@ -183,7 +182,7 @@ export interface _envoy_config_core_v3_HealthCheck_HttpHealthCheck { /** * Use specified application protocol for health checks. */ - 'codec_client_type'?: (_envoy_type_v3_CodecClientType | keyof typeof _envoy_type_v3_CodecClientType); + 'codec_client_type'?: (_envoy_type_v3_CodecClientType); /** * An optional service name parameter which is used to validate the identity of * the health checked cluster using a :ref:`StringMatcher @@ -197,7 +196,7 @@ export interface _envoy_config_core_v3_HealthCheck_HttpHealthCheck { * CONNECT method is disallowed because it is not appropriate for health check request. * If a non-200 response is expected by the method, it needs to be set in :ref:`expected_statuses `. */ - 'method'?: (_envoy_config_core_v3_RequestMethod | keyof typeof _envoy_config_core_v3_RequestMethod); + 'method'?: (_envoy_config_core_v3_RequestMethod); } /** @@ -272,7 +271,7 @@ export interface _envoy_config_core_v3_HealthCheck_HttpHealthCheck__Output { /** * Use specified application protocol for health checks. */ - 'codec_client_type': (keyof typeof _envoy_type_v3_CodecClientType); + 'codec_client_type': (_envoy_type_v3_CodecClientType__Output); /** * An optional service name parameter which is used to validate the identity of * the health checked cluster using a :ref:`StringMatcher @@ -286,7 +285,7 @@ export interface _envoy_config_core_v3_HealthCheck_HttpHealthCheck__Output { * CONNECT method is disallowed because it is not appropriate for health check request. * If a non-200 response is expected by the method, it needs to be set in :ref:`expected_statuses `. */ - 'method': (keyof typeof _envoy_config_core_v3_RequestMethod); + 'method': (_envoy_config_core_v3_RequestMethod__Output); } /** @@ -497,6 +496,7 @@ export interface HealthCheck { * in the file sink extension. * * Specifies the path to the :ref:`health check event log `. + * @deprecated */ 'event_log_path'?: (string); /** @@ -687,6 +687,7 @@ export interface HealthCheck__Output { * in the file sink extension. * * Specifies the path to the :ref:`health check event log `. + * @deprecated */ 'event_log_path': (string); /** diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HealthStatus.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HealthStatus.ts index 7d3d76569..54298f59b 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HealthStatus.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HealthStatus.ts @@ -3,19 +3,19 @@ /** * Endpoint health status. */ -export enum HealthStatus { +export const HealthStatus = { /** * The health status is not known. This is interpreted by Envoy as ``HEALTHY``. */ - UNKNOWN = 0, + UNKNOWN: 'UNKNOWN', /** * Healthy. */ - HEALTHY = 1, + HEALTHY: 'HEALTHY', /** * Unhealthy. */ - UNHEALTHY = 2, + UNHEALTHY: 'UNHEALTHY', /** * Connection draining in progress. E.g., * ``_ @@ -23,14 +23,59 @@ export enum HealthStatus { * ``_. * This is interpreted by Envoy as ``UNHEALTHY``. */ - DRAINING = 3, + DRAINING: 'DRAINING', /** * Health check timed out. This is part of HDS and is interpreted by Envoy as * ``UNHEALTHY``. */ - TIMEOUT = 4, + TIMEOUT: 'TIMEOUT', /** * Degraded. */ - DEGRADED = 5, -} + DEGRADED: 'DEGRADED', +} as const; + +/** + * Endpoint health status. + */ +export type HealthStatus = + /** + * The health status is not known. This is interpreted by Envoy as ``HEALTHY``. + */ + | 'UNKNOWN' + | 0 + /** + * Healthy. + */ + | 'HEALTHY' + | 1 + /** + * Unhealthy. + */ + | 'UNHEALTHY' + | 2 + /** + * Connection draining in progress. E.g., + * ``_ + * or + * ``_. + * This is interpreted by Envoy as ``UNHEALTHY``. + */ + | 'DRAINING' + | 3 + /** + * Health check timed out. This is part of HDS and is interpreted by Envoy as + * ``UNHEALTHY``. + */ + | 'TIMEOUT' + | 4 + /** + * Degraded. + */ + | 'DEGRADED' + | 5 + +/** + * Endpoint health status. + */ +export type HealthStatus__Output = typeof HealthStatus[keyof typeof HealthStatus] diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HealthStatusSet.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HealthStatusSet.ts index c518192d7..c94bf049c 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HealthStatusSet.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HealthStatusSet.ts @@ -1,17 +1,17 @@ // Original file: deps/envoy-api/envoy/config/core/v3/health_check.proto -import type { HealthStatus as _envoy_config_core_v3_HealthStatus } from '../../../../envoy/config/core/v3/HealthStatus'; +import type { HealthStatus as _envoy_config_core_v3_HealthStatus, HealthStatus__Output as _envoy_config_core_v3_HealthStatus__Output } from '../../../../envoy/config/core/v3/HealthStatus'; export interface HealthStatusSet { /** * An order-independent set of health status. */ - 'statuses'?: (_envoy_config_core_v3_HealthStatus | keyof typeof _envoy_config_core_v3_HealthStatus)[]; + 'statuses'?: (_envoy_config_core_v3_HealthStatus)[]; } export interface HealthStatusSet__Output { /** * An order-independent set of health status. */ - 'statuses': (keyof typeof _envoy_config_core_v3_HealthStatus)[]; + 'statuses': (_envoy_config_core_v3_HealthStatus__Output)[]; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http2ProtocolOptions.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http2ProtocolOptions.ts index cc22ce44c..9e0ae3d6e 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http2ProtocolOptions.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http2ProtocolOptions.ts @@ -159,6 +159,7 @@ export interface Http2ProtocolOptions { * ` * * See `RFC7540, sec. 8.1 `_ for details. + * @deprecated */ 'stream_error_on_invalid_http_messaging'?: (boolean); /** @@ -339,6 +340,7 @@ export interface Http2ProtocolOptions__Output { * ` * * See `RFC7540, sec. 8.1 `_ for details. + * @deprecated */ 'stream_error_on_invalid_http_messaging': (boolean); /** diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HttpProtocolOptions.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HttpProtocolOptions.ts index a3064110f..dfa800c3b 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HttpProtocolOptions.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HttpProtocolOptions.ts @@ -12,24 +12,61 @@ import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output a * as a security measure due to systems that treat '_' and '-' as interchangeable. Envoy by default allows client request headers with underscore * characters. */ -export enum _envoy_config_core_v3_HttpProtocolOptions_HeadersWithUnderscoresAction { +export const _envoy_config_core_v3_HttpProtocolOptions_HeadersWithUnderscoresAction = { /** * Allow headers with underscores. This is the default behavior. */ - ALLOW = 0, + ALLOW: 'ALLOW', /** * Reject client request. HTTP/1 requests are rejected with the 400 status. HTTP/2 requests * end with the stream reset. The "httpN.requests_rejected_with_underscores_in_headers" counter * is incremented for each rejected request. */ - REJECT_REQUEST = 1, + REJECT_REQUEST: 'REJECT_REQUEST', /** * Drop the client header with name containing underscores. The header is dropped before the filter chain is * invoked and as such filters will not see dropped headers. The * "httpN.dropped_headers_with_underscores" is incremented for each dropped header. */ - DROP_HEADER = 2, -} + DROP_HEADER: 'DROP_HEADER', +} as const; + +/** + * Action to take when Envoy receives client request with header names containing underscore + * characters. + * Underscore character is allowed in header names by the RFC-7230 and this behavior is implemented + * as a security measure due to systems that treat '_' and '-' as interchangeable. Envoy by default allows client request headers with underscore + * characters. + */ +export type _envoy_config_core_v3_HttpProtocolOptions_HeadersWithUnderscoresAction = + /** + * Allow headers with underscores. This is the default behavior. + */ + | 'ALLOW' + | 0 + /** + * Reject client request. HTTP/1 requests are rejected with the 400 status. HTTP/2 requests + * end with the stream reset. The "httpN.requests_rejected_with_underscores_in_headers" counter + * is incremented for each rejected request. + */ + | 'REJECT_REQUEST' + | 1 + /** + * Drop the client header with name containing underscores. The header is dropped before the filter chain is + * invoked and as such filters will not see dropped headers. The + * "httpN.dropped_headers_with_underscores" is incremented for each dropped header. + */ + | 'DROP_HEADER' + | 2 + +/** + * Action to take when Envoy receives client request with header names containing underscore + * characters. + * Underscore character is allowed in header names by the RFC-7230 and this behavior is implemented + * as a security measure due to systems that treat '_' and '-' as interchangeable. Envoy by default allows client request headers with underscore + * characters. + */ +export type _envoy_config_core_v3_HttpProtocolOptions_HeadersWithUnderscoresAction__Output = typeof _envoy_config_core_v3_HttpProtocolOptions_HeadersWithUnderscoresAction[keyof typeof _envoy_config_core_v3_HttpProtocolOptions_HeadersWithUnderscoresAction] /** * [#next-free-field: 7] @@ -81,7 +118,7 @@ export interface HttpProtocolOptions { * Note: this only affects client headers. It does not affect headers added * by Envoy filters and does not have any impact if added to cluster config. */ - 'headers_with_underscores_action'?: (_envoy_config_core_v3_HttpProtocolOptions_HeadersWithUnderscoresAction | keyof typeof _envoy_config_core_v3_HttpProtocolOptions_HeadersWithUnderscoresAction); + 'headers_with_underscores_action'?: (_envoy_config_core_v3_HttpProtocolOptions_HeadersWithUnderscoresAction); /** * Optional maximum requests for both upstream and downstream connections. * If not specified, there is no limit. @@ -141,7 +178,7 @@ export interface HttpProtocolOptions__Output { * Note: this only affects client headers. It does not affect headers added * by Envoy filters and does not have any impact if added to cluster config. */ - 'headers_with_underscores_action': (keyof typeof _envoy_config_core_v3_HttpProtocolOptions_HeadersWithUnderscoresAction); + 'headers_with_underscores_action': (_envoy_config_core_v3_HttpProtocolOptions_HeadersWithUnderscoresAction__Output); /** * Optional maximum requests for both upstream and downstream connections. * If not specified, there is no limit. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Node.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Node.ts index 6aef94d8e..b29b68502 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Node.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Node.ts @@ -78,6 +78,7 @@ export interface Node { * for filtering :ref:`listeners ` to be returned. For example, * if there is a listener bound to port 80, the list can optionally contain the * SocketAddress ``(0.0.0.0,80)``. The field is optional and just a hint. + * @deprecated */ 'listening_addresses'?: (_envoy_config_core_v3_Address)[]; /** @@ -162,6 +163,7 @@ export interface Node__Output { * for filtering :ref:`listeners ` to be returned. For example, * if there is a listener bound to port 80, the list can optionally contain the * SocketAddress ``(0.0.0.0,80)``. The field is optional and just a hint. + * @deprecated */ 'listening_addresses': (_envoy_config_core_v3_Address__Output)[]; /** diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ProxyProtocolConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ProxyProtocolConfig.ts index 7da9d569e..34cf7475f 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ProxyProtocolConfig.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ProxyProtocolConfig.ts @@ -4,22 +4,36 @@ import type { ProxyProtocolPassThroughTLVs as _envoy_config_core_v3_ProxyProtoco // Original file: deps/envoy-api/envoy/config/core/v3/proxy_protocol.proto -export enum _envoy_config_core_v3_ProxyProtocolConfig_Version { +export const _envoy_config_core_v3_ProxyProtocolConfig_Version = { /** * PROXY protocol version 1. Human readable format. */ - V1 = 0, + V1: 'V1', /** * PROXY protocol version 2. Binary format. */ - V2 = 1, -} + V2: 'V2', +} as const; + +export type _envoy_config_core_v3_ProxyProtocolConfig_Version = + /** + * PROXY protocol version 1. Human readable format. + */ + | 'V1' + | 0 + /** + * PROXY protocol version 2. Binary format. + */ + | 'V2' + | 1 + +export type _envoy_config_core_v3_ProxyProtocolConfig_Version__Output = typeof _envoy_config_core_v3_ProxyProtocolConfig_Version[keyof typeof _envoy_config_core_v3_ProxyProtocolConfig_Version] export interface ProxyProtocolConfig { /** * The PROXY protocol version to use. See https://www.haproxy.org/download/2.1/doc/proxy-protocol.txt for details */ - 'version'?: (_envoy_config_core_v3_ProxyProtocolConfig_Version | keyof typeof _envoy_config_core_v3_ProxyProtocolConfig_Version); + 'version'?: (_envoy_config_core_v3_ProxyProtocolConfig_Version); /** * This config controls which TLVs can be passed to upstream if it is Proxy Protocol * V2 header. If there is no setting for this field, no TLVs will be passed through. @@ -31,7 +45,7 @@ export interface ProxyProtocolConfig__Output { /** * The PROXY protocol version to use. See https://www.haproxy.org/download/2.1/doc/proxy-protocol.txt for details */ - 'version': (keyof typeof _envoy_config_core_v3_ProxyProtocolConfig_Version); + 'version': (_envoy_config_core_v3_ProxyProtocolConfig_Version__Output); /** * This config controls which TLVs can be passed to upstream if it is Proxy Protocol * V2 header. If there is no setting for this field, no TLVs will be passed through. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ProxyProtocolPassThroughTLVs.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ProxyProtocolPassThroughTLVs.ts index 0dddbf79f..9f253ceff 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ProxyProtocolPassThroughTLVs.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ProxyProtocolPassThroughTLVs.ts @@ -3,23 +3,37 @@ // Original file: deps/envoy-api/envoy/config/core/v3/proxy_protocol.proto -export enum _envoy_config_core_v3_ProxyProtocolPassThroughTLVs_PassTLVsMatchType { +export const _envoy_config_core_v3_ProxyProtocolPassThroughTLVs_PassTLVsMatchType = { /** * Pass all TLVs. */ - INCLUDE_ALL = 0, + INCLUDE_ALL: 'INCLUDE_ALL', /** * Pass specific TLVs defined in tlv_type. */ - INCLUDE = 1, -} + INCLUDE: 'INCLUDE', +} as const; + +export type _envoy_config_core_v3_ProxyProtocolPassThroughTLVs_PassTLVsMatchType = + /** + * Pass all TLVs. + */ + | 'INCLUDE_ALL' + | 0 + /** + * Pass specific TLVs defined in tlv_type. + */ + | 'INCLUDE' + | 1 + +export type _envoy_config_core_v3_ProxyProtocolPassThroughTLVs_PassTLVsMatchType__Output = typeof _envoy_config_core_v3_ProxyProtocolPassThroughTLVs_PassTLVsMatchType[keyof typeof _envoy_config_core_v3_ProxyProtocolPassThroughTLVs_PassTLVsMatchType] export interface ProxyProtocolPassThroughTLVs { /** * The strategy to pass through TLVs. Default is INCLUDE_ALL. * If INCLUDE_ALL is set, all TLVs will be passed through no matter the tlv_type field. */ - 'match_type'?: (_envoy_config_core_v3_ProxyProtocolPassThroughTLVs_PassTLVsMatchType | keyof typeof _envoy_config_core_v3_ProxyProtocolPassThroughTLVs_PassTLVsMatchType); + 'match_type'?: (_envoy_config_core_v3_ProxyProtocolPassThroughTLVs_PassTLVsMatchType); /** * The TLV types that are applied based on match_type. * TLV type is defined as uint8_t in proxy protocol. See `the spec @@ -33,7 +47,7 @@ export interface ProxyProtocolPassThroughTLVs__Output { * The strategy to pass through TLVs. Default is INCLUDE_ALL. * If INCLUDE_ALL is set, all TLVs will be passed through no matter the tlv_type field. */ - 'match_type': (keyof typeof _envoy_config_core_v3_ProxyProtocolPassThroughTLVs_PassTLVsMatchType); + 'match_type': (_envoy_config_core_v3_ProxyProtocolPassThroughTLVs_PassTLVsMatchType__Output); /** * The TLV types that are applied based on match_type. * TLV type is defined as uint8_t in proxy protocol. See `the spec diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RequestMethod.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RequestMethod.ts index 9be1aa6d1..67d40fda6 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RequestMethod.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RequestMethod.ts @@ -3,15 +3,45 @@ /** * HTTP request method. */ -export enum RequestMethod { - METHOD_UNSPECIFIED = 0, - GET = 1, - HEAD = 2, - POST = 3, - PUT = 4, - DELETE = 5, - CONNECT = 6, - OPTIONS = 7, - TRACE = 8, - PATCH = 9, -} +export const RequestMethod = { + METHOD_UNSPECIFIED: 'METHOD_UNSPECIFIED', + GET: 'GET', + HEAD: 'HEAD', + POST: 'POST', + PUT: 'PUT', + DELETE: 'DELETE', + CONNECT: 'CONNECT', + OPTIONS: 'OPTIONS', + TRACE: 'TRACE', + PATCH: 'PATCH', +} as const; + +/** + * HTTP request method. + */ +export type RequestMethod = + | 'METHOD_UNSPECIFIED' + | 0 + | 'GET' + | 1 + | 'HEAD' + | 2 + | 'POST' + | 3 + | 'PUT' + | 4 + | 'DELETE' + | 5 + | 'CONNECT' + | 6 + | 'OPTIONS' + | 7 + | 'TRACE' + | 8 + | 'PATCH' + | 9 + +/** + * HTTP request method. + */ +export type RequestMethod__Output = typeof RequestMethod[keyof typeof RequestMethod] diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RoutingPriority.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RoutingPriority.ts index 917d8a3df..41172d92f 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RoutingPriority.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RoutingPriority.ts @@ -9,7 +9,33 @@ * upstream host. In the future Envoy will likely support true HTTP/2 priority * over a single upstream connection. */ -export enum RoutingPriority { - DEFAULT = 0, - HIGH = 1, -} +export const RoutingPriority = { + DEFAULT: 'DEFAULT', + HIGH: 'HIGH', +} as const; + +/** + * Envoy supports :ref:`upstream priority routing + * ` both at the route and the virtual + * cluster level. The current priority implementation uses different connection + * pool and circuit breaking settings for each priority level. This means that + * even for HTTP/2 requests, two physical connections will be used to an + * upstream host. In the future Envoy will likely support true HTTP/2 priority + * over a single upstream connection. + */ +export type RoutingPriority = + | 'DEFAULT' + | 0 + | 'HIGH' + | 1 + +/** + * Envoy supports :ref:`upstream priority routing + * ` both at the route and the virtual + * cluster level. The current priority implementation uses different connection + * pool and circuit breaking settings for each priority level. This means that + * even for HTTP/2 requests, two physical connections will be used to an + * upstream host. In the future Envoy will likely support true HTTP/2 priority + * over a single upstream connection. + */ +export type RoutingPriority__Output = typeof RoutingPriority[keyof typeof RoutingPriority] diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SelfConfigSource.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SelfConfigSource.ts index 3912fd1cf..939c4fd3d 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SelfConfigSource.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SelfConfigSource.ts @@ -1,6 +1,6 @@ // Original file: deps/envoy-api/envoy/config/core/v3/config_source.proto -import type { ApiVersion as _envoy_config_core_v3_ApiVersion } from '../../../../envoy/config/core/v3/ApiVersion'; +import type { ApiVersion as _envoy_config_core_v3_ApiVersion, ApiVersion__Output as _envoy_config_core_v3_ApiVersion__Output } from '../../../../envoy/config/core/v3/ApiVersion'; /** * [#not-implemented-hide:] @@ -13,7 +13,7 @@ export interface SelfConfigSource { * API version for xDS transport protocol. This describes the xDS gRPC/REST * endpoint and version of [Delta]DiscoveryRequest/Response used on the wire. */ - 'transport_api_version'?: (_envoy_config_core_v3_ApiVersion | keyof typeof _envoy_config_core_v3_ApiVersion); + 'transport_api_version'?: (_envoy_config_core_v3_ApiVersion); } /** @@ -27,5 +27,5 @@ export interface SelfConfigSource__Output { * API version for xDS transport protocol. This describes the xDS gRPC/REST * endpoint and version of [Delta]DiscoveryRequest/Response used on the wire. */ - 'transport_api_version': (keyof typeof _envoy_config_core_v3_ApiVersion); + 'transport_api_version': (_envoy_config_core_v3_ApiVersion__Output); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SocketAddress.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SocketAddress.ts index ae87b9edd..f939393fb 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SocketAddress.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SocketAddress.ts @@ -3,16 +3,24 @@ // Original file: deps/envoy-api/envoy/config/core/v3/address.proto -export enum _envoy_config_core_v3_SocketAddress_Protocol { - TCP = 0, - UDP = 1, -} +export const _envoy_config_core_v3_SocketAddress_Protocol = { + TCP: 'TCP', + UDP: 'UDP', +} as const; + +export type _envoy_config_core_v3_SocketAddress_Protocol = + | 'TCP' + | 0 + | 'UDP' + | 1 + +export type _envoy_config_core_v3_SocketAddress_Protocol__Output = typeof _envoy_config_core_v3_SocketAddress_Protocol[keyof typeof _envoy_config_core_v3_SocketAddress_Protocol] /** * [#next-free-field: 7] */ export interface SocketAddress { - 'protocol'?: (_envoy_config_core_v3_SocketAddress_Protocol | keyof typeof _envoy_config_core_v3_SocketAddress_Protocol); + 'protocol'?: (_envoy_config_core_v3_SocketAddress_Protocol); /** * The address for this socket. :ref:`Listeners ` will bind * to the address. An empty address is not allowed. Specify ``0.0.0.0`` or ``::`` @@ -56,7 +64,7 @@ export interface SocketAddress { * [#next-free-field: 7] */ export interface SocketAddress__Output { - 'protocol': (keyof typeof _envoy_config_core_v3_SocketAddress_Protocol); + 'protocol': (_envoy_config_core_v3_SocketAddress_Protocol__Output); /** * The address for this socket. :ref:`Listeners ` will bind * to the address. An empty address is not allowed. Specify ``0.0.0.0`` or ``::`` diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SocketOption.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SocketOption.ts index edff50a63..9b3bc0019 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SocketOption.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SocketOption.ts @@ -4,20 +4,39 @@ import type { Long } from '@grpc/proto-loader'; // Original file: deps/envoy-api/envoy/config/core/v3/socket_option.proto -export enum _envoy_config_core_v3_SocketOption_SocketState { +export const _envoy_config_core_v3_SocketOption_SocketState = { /** * Socket options are applied after socket creation but before binding the socket to a port */ - STATE_PREBIND = 0, + STATE_PREBIND: 'STATE_PREBIND', /** * Socket options are applied after binding the socket to a port but before calling listen() */ - STATE_BOUND = 1, + STATE_BOUND: 'STATE_BOUND', /** * Socket options are applied after calling listen() */ - STATE_LISTENING = 2, -} + STATE_LISTENING: 'STATE_LISTENING', +} as const; + +export type _envoy_config_core_v3_SocketOption_SocketState = + /** + * Socket options are applied after socket creation but before binding the socket to a port + */ + | 'STATE_PREBIND' + | 0 + /** + * Socket options are applied after binding the socket to a port but before calling listen() + */ + | 'STATE_BOUND' + | 1 + /** + * Socket options are applied after calling listen() + */ + | 'STATE_LISTENING' + | 2 + +export type _envoy_config_core_v3_SocketOption_SocketState__Output = typeof _envoy_config_core_v3_SocketOption_SocketState[keyof typeof _envoy_config_core_v3_SocketOption_SocketState] /** * Generic socket option message. This would be used to set socket options that @@ -70,7 +89,7 @@ export interface SocketOption { * The state in which the option will be applied. When used in BindConfig * STATE_PREBIND is currently the only valid value. */ - 'state'?: (_envoy_config_core_v3_SocketOption_SocketState | keyof typeof _envoy_config_core_v3_SocketOption_SocketState); + 'state'?: (_envoy_config_core_v3_SocketOption_SocketState); 'value'?: "int_value"|"buf_value"; } @@ -125,6 +144,6 @@ export interface SocketOption__Output { * The state in which the option will be applied. When used in BindConfig * STATE_PREBIND is currently the only valid value. */ - 'state': (keyof typeof _envoy_config_core_v3_SocketOption_SocketState); + 'state': (_envoy_config_core_v3_SocketOption_SocketState__Output); 'value': "int_value"|"buf_value"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SubstitutionFormatString.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SubstitutionFormatString.ts index be0237e38..01a97441c 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SubstitutionFormatString.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SubstitutionFormatString.ts @@ -28,6 +28,7 @@ export interface SubstitutionFormatString { * upstream connect error:503:path=/foo * * Deprecated in favor of :ref:`text_format_source `. To migrate text format strings, use the :ref:`inline_string ` field. + * @deprecated */ 'text_format'?: (string); /** @@ -125,6 +126,7 @@ export interface SubstitutionFormatString__Output { * upstream connect error:503:path=/foo * * Deprecated in favor of :ref:`text_format_source `. To migrate text format strings, use the :ref:`inline_string ` field. + * @deprecated */ 'text_format'?: (string); /** diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TrafficDirection.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TrafficDirection.ts index b68323b09..e450d43cb 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TrafficDirection.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TrafficDirection.ts @@ -3,17 +3,42 @@ /** * Identifies the direction of the traffic relative to the local Envoy. */ -export enum TrafficDirection { +export const TrafficDirection = { /** * Default option is unspecified. */ - UNSPECIFIED = 0, + UNSPECIFIED: 'UNSPECIFIED', /** * The transport is used for incoming traffic. */ - INBOUND = 1, + INBOUND: 'INBOUND', /** * The transport is used for outgoing traffic. */ - OUTBOUND = 2, -} + OUTBOUND: 'OUTBOUND', +} as const; + +/** + * Identifies the direction of the traffic relative to the local Envoy. + */ +export type TrafficDirection = + /** + * Default option is unspecified. + */ + | 'UNSPECIFIED' + | 0 + /** + * The transport is used for incoming traffic. + */ + | 'INBOUND' + | 1 + /** + * The transport is used for outgoing traffic. + */ + | 'OUTBOUND' + | 2 + +/** + * Identifies the direction of the traffic relative to the local Envoy. + */ +export type TrafficDirection__Output = typeof TrafficDirection[keyof typeof TrafficDirection] diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/UdpSocketConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/UdpSocketConfig.ts index fe1b038db..f5e38b2b4 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/UdpSocketConfig.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/UdpSocketConfig.ts @@ -2,7 +2,6 @@ import type { UInt64Value as _google_protobuf_UInt64Value, UInt64Value__Output as _google_protobuf_UInt64Value__Output } from '../../../../google/protobuf/UInt64Value'; import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; -import type { Long } from '@grpc/proto-loader'; /** * Generic UDP socket configuration. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LbEndpoint.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LbEndpoint.ts index 8d184b8a0..4130eb838 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LbEndpoint.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LbEndpoint.ts @@ -1,7 +1,7 @@ // Original file: deps/envoy-api/envoy/config/endpoint/v3/endpoint_components.proto import type { Endpoint as _envoy_config_endpoint_v3_Endpoint, Endpoint__Output as _envoy_config_endpoint_v3_Endpoint__Output } from '../../../../envoy/config/endpoint/v3/Endpoint'; -import type { HealthStatus as _envoy_config_core_v3_HealthStatus } from '../../../../envoy/config/core/v3/HealthStatus'; +import type { HealthStatus as _envoy_config_core_v3_HealthStatus, HealthStatus__Output as _envoy_config_core_v3_HealthStatus__Output } from '../../../../envoy/config/core/v3/HealthStatus'; import type { Metadata as _envoy_config_core_v3_Metadata, Metadata__Output as _envoy_config_core_v3_Metadata__Output } from '../../../../envoy/config/core/v3/Metadata'; import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; @@ -14,7 +14,7 @@ export interface LbEndpoint { /** * Optional health status when known and supplied by EDS server. */ - 'health_status'?: (_envoy_config_core_v3_HealthStatus | keyof typeof _envoy_config_core_v3_HealthStatus); + 'health_status'?: (_envoy_config_core_v3_HealthStatus); /** * The endpoint metadata specifies values that may be used by the load * balancer to select endpoints in a cluster for a given request. The filter @@ -56,7 +56,7 @@ export interface LbEndpoint__Output { /** * Optional health status when known and supplied by EDS server. */ - 'health_status': (keyof typeof _envoy_config_core_v3_HealthStatus); + 'health_status': (_envoy_config_core_v3_HealthStatus__Output); /** * The endpoint metadata specifies values that may be used by the load * balancer to select endpoints in a cluster for a given request. The filter diff --git a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/FilterChain.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/FilterChain.ts index f27000d71..77b08f48e 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/FilterChain.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/FilterChain.ts @@ -79,6 +79,7 @@ export interface FilterChain { * This field is deprecated. Add a * :ref:`PROXY protocol listener filter ` * explicitly instead. + * @deprecated */ 'use_proxy_proto'?: (_google_protobuf_BoolValue | null); /** @@ -149,6 +150,7 @@ export interface FilterChain__Output { * This field is deprecated. Add a * :ref:`PROXY protocol listener filter ` * explicitly instead. + * @deprecated */ 'use_proxy_proto': (_google_protobuf_BoolValue__Output | null); /** diff --git a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/FilterChainMatch.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/FilterChainMatch.ts index 87b1503cb..fcbfc1b3e 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/FilterChainMatch.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/FilterChainMatch.ts @@ -5,20 +5,39 @@ import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output a // Original file: deps/envoy-api/envoy/config/listener/v3/listener_components.proto -export enum _envoy_config_listener_v3_FilterChainMatch_ConnectionSourceType { +export const _envoy_config_listener_v3_FilterChainMatch_ConnectionSourceType = { /** * Any connection source matches. */ - ANY = 0, + ANY: 'ANY', /** * Match a connection originating from the same host. */ - SAME_IP_OR_LOOPBACK = 1, + SAME_IP_OR_LOOPBACK: 'SAME_IP_OR_LOOPBACK', /** * Match a connection originating from a different host. */ - EXTERNAL = 2, -} + EXTERNAL: 'EXTERNAL', +} as const; + +export type _envoy_config_listener_v3_FilterChainMatch_ConnectionSourceType = + /** + * Any connection source matches. + */ + | 'ANY' + | 0 + /** + * Match a connection originating from the same host. + */ + | 'SAME_IP_OR_LOOPBACK' + | 1 + /** + * Match a connection originating from a different host. + */ + | 'EXTERNAL' + | 2 + +export type _envoy_config_listener_v3_FilterChainMatch_ConnectionSourceType__Output = typeof _envoy_config_listener_v3_FilterChainMatch_ConnectionSourceType[keyof typeof _envoy_config_listener_v3_FilterChainMatch_ConnectionSourceType] /** * Specifies the match criteria for selecting a specific filter chain for a @@ -154,7 +173,7 @@ export interface FilterChainMatch { /** * Specifies the connection source IP match type. Can be any, local or external network. */ - 'source_type'?: (_envoy_config_listener_v3_FilterChainMatch_ConnectionSourceType | keyof typeof _envoy_config_listener_v3_FilterChainMatch_ConnectionSourceType); + 'source_type'?: (_envoy_config_listener_v3_FilterChainMatch_ConnectionSourceType); /** * The criteria is satisfied if the directly connected source IP address of the downstream * connection is contained in at least one of the specified subnets. If the parameter is not @@ -297,7 +316,7 @@ export interface FilterChainMatch__Output { /** * Specifies the connection source IP match type. Can be any, local or external network. */ - 'source_type': (keyof typeof _envoy_config_listener_v3_FilterChainMatch_ConnectionSourceType); + 'source_type': (_envoy_config_listener_v3_FilterChainMatch_ConnectionSourceType__Output); /** * The criteria is satisfied if the directly connected source IP address of the downstream * connection is contained in at least one of the specified subnets. If the parameter is not diff --git a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/Listener.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/Listener.ts index ca12fc6de..8897eacf5 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/Listener.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/Listener.ts @@ -8,7 +8,7 @@ import type { Metadata as _envoy_config_core_v3_Metadata, Metadata__Output as _e import type { ListenerFilter as _envoy_config_listener_v3_ListenerFilter, ListenerFilter__Output as _envoy_config_listener_v3_ListenerFilter__Output } from '../../../../envoy/config/listener/v3/ListenerFilter'; import type { SocketOption as _envoy_config_core_v3_SocketOption, SocketOption__Output as _envoy_config_core_v3_SocketOption__Output } from '../../../../envoy/config/core/v3/SocketOption'; import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; -import type { TrafficDirection as _envoy_config_core_v3_TrafficDirection } from '../../../../envoy/config/core/v3/TrafficDirection'; +import type { TrafficDirection as _envoy_config_core_v3_TrafficDirection, TrafficDirection__Output as _envoy_config_core_v3_TrafficDirection__Output } from '../../../../envoy/config/core/v3/TrafficDirection'; import type { UdpListenerConfig as _envoy_config_listener_v3_UdpListenerConfig, UdpListenerConfig__Output as _envoy_config_listener_v3_UdpListenerConfig__Output } from '../../../../envoy/config/listener/v3/UdpListenerConfig'; import type { ApiListener as _envoy_config_listener_v3_ApiListener, ApiListener__Output as _envoy_config_listener_v3_ApiListener__Output } from '../../../../envoy/config/listener/v3/ApiListener'; import type { AccessLog as _envoy_config_accesslog_v3_AccessLog, AccessLog__Output as _envoy_config_accesslog_v3_AccessLog__Output } from '../../../../envoy/config/accesslog/v3/AccessLog'; @@ -82,19 +82,36 @@ export interface _envoy_config_listener_v3_Listener_DeprecatedV1__Output { // Original file: deps/envoy-api/envoy/config/listener/v3/listener.proto -export enum _envoy_config_listener_v3_Listener_DrainType { +export const _envoy_config_listener_v3_Listener_DrainType = { /** * Drain in response to calling /healthcheck/fail admin endpoint (along with the health check * filter), listener removal/modification, and hot restart. */ - DEFAULT = 0, + DEFAULT: 'DEFAULT', /** * Drain in response to listener removal/modification and hot restart. This setting does not * include /healthcheck/fail. This setting may be desirable if Envoy is hosting both ingress * and egress listeners. */ - MODIFY_ONLY = 1, -} + MODIFY_ONLY: 'MODIFY_ONLY', +} as const; + +export type _envoy_config_listener_v3_Listener_DrainType = + /** + * Drain in response to calling /healthcheck/fail admin endpoint (along with the health check + * filter), listener removal/modification, and hot restart. + */ + | 'DEFAULT' + | 0 + /** + * Drain in response to listener removal/modification and hot restart. This setting does not + * include /healthcheck/fail. This setting may be desirable if Envoy is hosting both ingress + * and egress listeners. + */ + | 'MODIFY_ONLY' + | 1 + +export type _envoy_config_listener_v3_Listener_DrainType__Output = typeof _envoy_config_listener_v3_Listener_DrainType[keyof typeof _envoy_config_listener_v3_Listener_DrainType] /** * A connection balancer implementation that does exact balancing. This means that a lock is @@ -176,12 +193,13 @@ export interface Listener { 'metadata'?: (_envoy_config_core_v3_Metadata | null); /** * [#not-implemented-hide:] + * @deprecated */ 'deprecated_v1'?: (_envoy_config_listener_v3_Listener_DeprecatedV1 | null); /** * The type of draining to perform at a listener-wide level. */ - 'drain_type'?: (_envoy_config_listener_v3_Listener_DrainType | keyof typeof _envoy_config_listener_v3_Listener_DrainType); + 'drain_type'?: (_envoy_config_listener_v3_Listener_DrainType); /** * Listener filters have the opportunity to manipulate and augment the connection metadata that * is used in connection filter chain matching, for example. These filters are run before any in @@ -256,7 +274,7 @@ export interface Listener { * This property is required on Windows for listeners using the original destination filter, * see :ref:`Original Destination `. */ - 'traffic_direction'?: (_envoy_config_core_v3_TrafficDirection | keyof typeof _envoy_config_core_v3_TrafficDirection); + 'traffic_direction'?: (_envoy_config_core_v3_TrafficDirection); /** * Whether a connection should be created when listener filters timeout. Default is false. * @@ -307,6 +325,7 @@ export interface Listener { 'connection_balance_config'?: (_envoy_config_listener_v3_Listener_ConnectionBalanceConfig | null); /** * Deprecated. Use ``enable_reuse_port`` instead. + * @deprecated */ 'reuse_port'?: (boolean); /** @@ -466,12 +485,13 @@ export interface Listener__Output { 'metadata': (_envoy_config_core_v3_Metadata__Output | null); /** * [#not-implemented-hide:] + * @deprecated */ 'deprecated_v1': (_envoy_config_listener_v3_Listener_DeprecatedV1__Output | null); /** * The type of draining to perform at a listener-wide level. */ - 'drain_type': (keyof typeof _envoy_config_listener_v3_Listener_DrainType); + 'drain_type': (_envoy_config_listener_v3_Listener_DrainType__Output); /** * Listener filters have the opportunity to manipulate and augment the connection metadata that * is used in connection filter chain matching, for example. These filters are run before any in @@ -546,7 +566,7 @@ export interface Listener__Output { * This property is required on Windows for listeners using the original destination filter, * see :ref:`Original Destination `. */ - 'traffic_direction': (keyof typeof _envoy_config_core_v3_TrafficDirection); + 'traffic_direction': (_envoy_config_core_v3_TrafficDirection__Output); /** * Whether a connection should be created when listener filters timeout. Default is false. * @@ -597,6 +617,7 @@ export interface Listener__Output { 'connection_balance_config': (_envoy_config_listener_v3_Listener_ConnectionBalanceConfig__Output | null); /** * Deprecated. Use ``enable_reuse_port`` instead. + * @deprecated */ 'reuse_port': (boolean); /** diff --git a/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/DogStatsdSink.ts b/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/DogStatsdSink.ts deleted file mode 100644 index 4cf705f10..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/DogStatsdSink.ts +++ /dev/null @@ -1,65 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/metrics/v3/stats.proto - -import type { Address as _envoy_config_core_v3_Address, Address__Output as _envoy_config_core_v3_Address__Output } from '../../../../envoy/config/core/v3/Address'; -import type { UInt64Value as _google_protobuf_UInt64Value, UInt64Value__Output as _google_protobuf_UInt64Value__Output } from '../../../../google/protobuf/UInt64Value'; -import type { Long } from '@grpc/proto-loader'; - -/** - * Stats configuration proto schema for built-in *envoy.stat_sinks.dog_statsd* sink. - * The sink emits stats with `DogStatsD `_ - * compatible tags. Tags are configurable via :ref:`StatsConfig - * `. - * [#extension: envoy.stat_sinks.dog_statsd] - */ -export interface DogStatsdSink { - /** - * The UDP address of a running DogStatsD compliant listener. If specified, - * statistics will be flushed to this address. - */ - 'address'?: (_envoy_config_core_v3_Address | null); - /** - * Optional custom metric name prefix. See :ref:`StatsdSink's prefix field - * ` for more details. - */ - 'prefix'?: (string); - /** - * Optional max datagram size to use when sending UDP messages. By default Envoy - * will emit one metric per datagram. By specifying a max-size larger than a single - * metric, Envoy will emit multiple, new-line separated metrics. The max datagram - * size should not exceed your network's MTU. - * - * Note that this value may not be respected if smaller than a single metric. - */ - 'max_bytes_per_datagram'?: (_google_protobuf_UInt64Value | null); - 'dog_statsd_specifier'?: "address"; -} - -/** - * Stats configuration proto schema for built-in *envoy.stat_sinks.dog_statsd* sink. - * The sink emits stats with `DogStatsD `_ - * compatible tags. Tags are configurable via :ref:`StatsConfig - * `. - * [#extension: envoy.stat_sinks.dog_statsd] - */ -export interface DogStatsdSink__Output { - /** - * The UDP address of a running DogStatsD compliant listener. If specified, - * statistics will be flushed to this address. - */ - 'address'?: (_envoy_config_core_v3_Address__Output | null); - /** - * Optional custom metric name prefix. See :ref:`StatsdSink's prefix field - * ` for more details. - */ - 'prefix': (string); - /** - * Optional max datagram size to use when sending UDP messages. By default Envoy - * will emit one metric per datagram. By specifying a max-size larger than a single - * metric, Envoy will emit multiple, new-line separated metrics. The max datagram - * size should not exceed your network's MTU. - * - * Note that this value may not be respected if smaller than a single metric. - */ - 'max_bytes_per_datagram': (_google_protobuf_UInt64Value__Output | null); - 'dog_statsd_specifier': "address"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/HistogramBucketSettings.ts b/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/HistogramBucketSettings.ts deleted file mode 100644 index 036958a49..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/HistogramBucketSettings.ts +++ /dev/null @@ -1,35 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/metrics/v3/stats.proto - -import type { StringMatcher as _envoy_type_matcher_v3_StringMatcher, StringMatcher__Output as _envoy_type_matcher_v3_StringMatcher__Output } from '../../../../envoy/type/matcher/v3/StringMatcher'; - -/** - * Specifies a matcher for stats and the buckets that matching stats should use. - */ -export interface HistogramBucketSettings { - /** - * The stats that this rule applies to. The match is applied to the original stat name - * before tag-extraction, for example `cluster.exampleclustername.upstream_cx_length_ms`. - */ - 'match'?: (_envoy_type_matcher_v3_StringMatcher | null); - /** - * Each value is the upper bound of a bucket. Each bucket must be greater than 0 and unique. - * The order of the buckets does not matter. - */ - 'buckets'?: (number | string)[]; -} - -/** - * Specifies a matcher for stats and the buckets that matching stats should use. - */ -export interface HistogramBucketSettings__Output { - /** - * The stats that this rule applies to. The match is applied to the original stat name - * before tag-extraction, for example `cluster.exampleclustername.upstream_cx_length_ms`. - */ - 'match': (_envoy_type_matcher_v3_StringMatcher__Output | null); - /** - * Each value is the upper bound of a bucket. Each bucket must be greater than 0 and unique. - * The order of the buckets does not matter. - */ - 'buckets': (number)[]; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/HystrixSink.ts b/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/HystrixSink.ts deleted file mode 100644 index b8fb2ed8e..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/HystrixSink.ts +++ /dev/null @@ -1,61 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/metrics/v3/stats.proto - -import type { Long } from '@grpc/proto-loader'; - -/** - * Stats configuration proto schema for built-in *envoy.stat_sinks.hystrix* sink. - * The sink emits stats in `text/event-stream - * `_ - * formatted stream for use by `Hystrix dashboard - * `_. - * - * Note that only a single HystrixSink should be configured. - * - * Streaming is started through an admin endpoint :http:get:`/hystrix_event_stream`. - * [#extension: envoy.stat_sinks.hystrix] - */ -export interface HystrixSink { - /** - * The number of buckets the rolling statistical window is divided into. - * - * Each time the sink is flushed, all relevant Envoy statistics are sampled and - * added to the rolling window (removing the oldest samples in the window - * in the process). The sink then outputs the aggregate statistics across the - * current rolling window to the event stream(s). - * - * rolling_window(ms) = stats_flush_interval(ms) * num_of_buckets - * - * More detailed explanation can be found in `Hystrix wiki - * `_. - */ - 'num_buckets'?: (number | string | Long); -} - -/** - * Stats configuration proto schema for built-in *envoy.stat_sinks.hystrix* sink. - * The sink emits stats in `text/event-stream - * `_ - * formatted stream for use by `Hystrix dashboard - * `_. - * - * Note that only a single HystrixSink should be configured. - * - * Streaming is started through an admin endpoint :http:get:`/hystrix_event_stream`. - * [#extension: envoy.stat_sinks.hystrix] - */ -export interface HystrixSink__Output { - /** - * The number of buckets the rolling statistical window is divided into. - * - * Each time the sink is flushed, all relevant Envoy statistics are sampled and - * added to the rolling window (removing the oldest samples in the window - * in the process). The sink then outputs the aggregate statistics across the - * current rolling window to the event stream(s). - * - * rolling_window(ms) = stats_flush_interval(ms) * num_of_buckets - * - * More detailed explanation can be found in `Hystrix wiki - * `_. - */ - 'num_buckets': (string); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsConfig.ts deleted file mode 100644 index df5d7c7e4..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsConfig.ts +++ /dev/null @@ -1,148 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/metrics/v3/stats.proto - -import type { TagSpecifier as _envoy_config_metrics_v3_TagSpecifier, TagSpecifier__Output as _envoy_config_metrics_v3_TagSpecifier__Output } from '../../../../envoy/config/metrics/v3/TagSpecifier'; -import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; -import type { StatsMatcher as _envoy_config_metrics_v3_StatsMatcher, StatsMatcher__Output as _envoy_config_metrics_v3_StatsMatcher__Output } from '../../../../envoy/config/metrics/v3/StatsMatcher'; -import type { HistogramBucketSettings as _envoy_config_metrics_v3_HistogramBucketSettings, HistogramBucketSettings__Output as _envoy_config_metrics_v3_HistogramBucketSettings__Output } from '../../../../envoy/config/metrics/v3/HistogramBucketSettings'; - -/** - * Statistics configuration such as tagging. - */ -export interface StatsConfig { - /** - * Each stat name is iteratively processed through these tag specifiers. - * When a tag is matched, the first capture group is removed from the name so - * later :ref:`TagSpecifiers ` cannot match that - * same portion of the match. - */ - 'stats_tags'?: (_envoy_config_metrics_v3_TagSpecifier)[]; - /** - * Use all default tag regexes specified in Envoy. These can be combined with - * custom tags specified in :ref:`stats_tags - * `. They will be processed before - * the custom tags. - * - * .. note:: - * - * If any default tags are specified twice, the config will be considered - * invalid. - * - * See :repo:`well_known_names.h ` for a list of the - * default tags in Envoy. - * - * If not provided, the value is assumed to be true. - */ - 'use_all_default_tags'?: (_google_protobuf_BoolValue | null); - /** - * Inclusion/exclusion matcher for stat name creation. If not provided, all stats are instantiated - * as normal. Preventing the instantiation of certain families of stats can improve memory - * performance for Envoys running especially large configs. - * - * .. warning:: - * Excluding stats may affect Envoy's behavior in undocumented ways. See - * `issue #8771 `_ for more information. - * If any unexpected behavior changes are observed, please open a new issue immediately. - */ - 'stats_matcher'?: (_envoy_config_metrics_v3_StatsMatcher | null); - /** - * Defines rules for setting the histogram buckets. Rules are evaluated in order, and the first - * match is applied. If no match is found (or if no rules are set), the following default buckets - * are used: - * - * .. code-block:: json - * - * [ - * 0.5, - * 1, - * 5, - * 10, - * 25, - * 50, - * 100, - * 250, - * 500, - * 1000, - * 2500, - * 5000, - * 10000, - * 30000, - * 60000, - * 300000, - * 600000, - * 1800000, - * 3600000 - * ] - */ - 'histogram_bucket_settings'?: (_envoy_config_metrics_v3_HistogramBucketSettings)[]; -} - -/** - * Statistics configuration such as tagging. - */ -export interface StatsConfig__Output { - /** - * Each stat name is iteratively processed through these tag specifiers. - * When a tag is matched, the first capture group is removed from the name so - * later :ref:`TagSpecifiers ` cannot match that - * same portion of the match. - */ - 'stats_tags': (_envoy_config_metrics_v3_TagSpecifier__Output)[]; - /** - * Use all default tag regexes specified in Envoy. These can be combined with - * custom tags specified in :ref:`stats_tags - * `. They will be processed before - * the custom tags. - * - * .. note:: - * - * If any default tags are specified twice, the config will be considered - * invalid. - * - * See :repo:`well_known_names.h ` for a list of the - * default tags in Envoy. - * - * If not provided, the value is assumed to be true. - */ - 'use_all_default_tags': (_google_protobuf_BoolValue__Output | null); - /** - * Inclusion/exclusion matcher for stat name creation. If not provided, all stats are instantiated - * as normal. Preventing the instantiation of certain families of stats can improve memory - * performance for Envoys running especially large configs. - * - * .. warning:: - * Excluding stats may affect Envoy's behavior in undocumented ways. See - * `issue #8771 `_ for more information. - * If any unexpected behavior changes are observed, please open a new issue immediately. - */ - 'stats_matcher': (_envoy_config_metrics_v3_StatsMatcher__Output | null); - /** - * Defines rules for setting the histogram buckets. Rules are evaluated in order, and the first - * match is applied. If no match is found (or if no rules are set), the following default buckets - * are used: - * - * .. code-block:: json - * - * [ - * 0.5, - * 1, - * 5, - * 10, - * 25, - * 50, - * 100, - * 250, - * 500, - * 1000, - * 2500, - * 5000, - * 10000, - * 30000, - * 60000, - * 300000, - * 600000, - * 1800000, - * 3600000 - * ] - */ - 'histogram_bucket_settings': (_envoy_config_metrics_v3_HistogramBucketSettings__Output)[]; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsMatcher.ts deleted file mode 100644 index 9df9e9529..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsMatcher.ts +++ /dev/null @@ -1,47 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/metrics/v3/stats.proto - -import type { ListStringMatcher as _envoy_type_matcher_v3_ListStringMatcher, ListStringMatcher__Output as _envoy_type_matcher_v3_ListStringMatcher__Output } from '../../../../envoy/type/matcher/v3/ListStringMatcher'; - -/** - * Configuration for disabling stat instantiation. - */ -export interface StatsMatcher { - /** - * If `reject_all` is true, then all stats are disabled. If `reject_all` is false, then all - * stats are enabled. - */ - 'reject_all'?: (boolean); - /** - * Exclusive match. All stats are enabled except for those matching one of the supplied - * StringMatcher protos. - */ - 'exclusion_list'?: (_envoy_type_matcher_v3_ListStringMatcher | null); - /** - * Inclusive match. No stats are enabled except for those matching one of the supplied - * StringMatcher protos. - */ - 'inclusion_list'?: (_envoy_type_matcher_v3_ListStringMatcher | null); - 'stats_matcher'?: "reject_all"|"exclusion_list"|"inclusion_list"; -} - -/** - * Configuration for disabling stat instantiation. - */ -export interface StatsMatcher__Output { - /** - * If `reject_all` is true, then all stats are disabled. If `reject_all` is false, then all - * stats are enabled. - */ - 'reject_all'?: (boolean); - /** - * Exclusive match. All stats are enabled except for those matching one of the supplied - * StringMatcher protos. - */ - 'exclusion_list'?: (_envoy_type_matcher_v3_ListStringMatcher__Output | null); - /** - * Inclusive match. No stats are enabled except for those matching one of the supplied - * StringMatcher protos. - */ - 'inclusion_list'?: (_envoy_type_matcher_v3_ListStringMatcher__Output | null); - 'stats_matcher': "reject_all"|"exclusion_list"|"inclusion_list"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsSink.ts b/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsSink.ts deleted file mode 100644 index 3eb8926fa..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsSink.ts +++ /dev/null @@ -1,43 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/metrics/v3/stats.proto - -import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; - -/** - * Configuration for pluggable stats sinks. - */ -export interface StatsSink { - /** - * The name of the stats sink to instantiate. The name must match a supported - * stats sink. - * See the :ref:`extensions listed in typed_config below ` for the default list of available stats sink. - * Sinks optionally support tagged/multiple dimensional metrics. - */ - 'name'?: (string); - 'typed_config'?: (_google_protobuf_Any | null); - /** - * Stats sink specific configuration which depends on the sink being instantiated. See - * :ref:`StatsdSink ` for an example. - * [#extension-category: envoy.stats_sinks] - */ - 'config_type'?: "typed_config"; -} - -/** - * Configuration for pluggable stats sinks. - */ -export interface StatsSink__Output { - /** - * The name of the stats sink to instantiate. The name must match a supported - * stats sink. - * See the :ref:`extensions listed in typed_config below ` for the default list of available stats sink. - * Sinks optionally support tagged/multiple dimensional metrics. - */ - 'name': (string); - 'typed_config'?: (_google_protobuf_Any__Output | null); - /** - * Stats sink specific configuration which depends on the sink being instantiated. See - * :ref:`StatsdSink ` for an example. - * [#extension-category: envoy.stats_sinks] - */ - 'config_type': "typed_config"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsdSink.ts b/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsdSink.ts deleted file mode 100644 index 69d978920..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsdSink.ts +++ /dev/null @@ -1,103 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/metrics/v3/stats.proto - -import type { Address as _envoy_config_core_v3_Address, Address__Output as _envoy_config_core_v3_Address__Output } from '../../../../envoy/config/core/v3/Address'; - -/** - * Stats configuration proto schema for built-in *envoy.stat_sinks.statsd* sink. This sink does not support - * tagged metrics. - * [#extension: envoy.stat_sinks.statsd] - */ -export interface StatsdSink { - /** - * The UDP address of a running `statsd `_ - * compliant listener. If specified, statistics will be flushed to this - * address. - */ - 'address'?: (_envoy_config_core_v3_Address | null); - /** - * The name of a cluster that is running a TCP `statsd - * `_ compliant listener. If specified, - * Envoy will connect to this cluster to flush statistics. - */ - 'tcp_cluster_name'?: (string); - /** - * Optional custom prefix for StatsdSink. If - * specified, this will override the default prefix. - * For example: - * - * .. code-block:: json - * - * { - * "prefix" : "envoy-prod" - * } - * - * will change emitted stats to - * - * .. code-block:: cpp - * - * envoy-prod.test_counter:1|c - * envoy-prod.test_timer:5|ms - * - * Note that the default prefix, "envoy", will be used if a prefix is not - * specified. - * - * Stats with default prefix: - * - * .. code-block:: cpp - * - * envoy.test_counter:1|c - * envoy.test_timer:5|ms - */ - 'prefix'?: (string); - 'statsd_specifier'?: "address"|"tcp_cluster_name"; -} - -/** - * Stats configuration proto schema for built-in *envoy.stat_sinks.statsd* sink. This sink does not support - * tagged metrics. - * [#extension: envoy.stat_sinks.statsd] - */ -export interface StatsdSink__Output { - /** - * The UDP address of a running `statsd `_ - * compliant listener. If specified, statistics will be flushed to this - * address. - */ - 'address'?: (_envoy_config_core_v3_Address__Output | null); - /** - * The name of a cluster that is running a TCP `statsd - * `_ compliant listener. If specified, - * Envoy will connect to this cluster to flush statistics. - */ - 'tcp_cluster_name'?: (string); - /** - * Optional custom prefix for StatsdSink. If - * specified, this will override the default prefix. - * For example: - * - * .. code-block:: json - * - * { - * "prefix" : "envoy-prod" - * } - * - * will change emitted stats to - * - * .. code-block:: cpp - * - * envoy-prod.test_counter:1|c - * envoy-prod.test_timer:5|ms - * - * Note that the default prefix, "envoy", will be used if a prefix is not - * specified. - * - * Stats with default prefix: - * - * .. code-block:: cpp - * - * envoy.test_counter:1|c - * envoy.test_timer:5|ms - */ - 'prefix': (string); - 'statsd_specifier': "address"|"tcp_cluster_name"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/TagSpecifier.ts b/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/TagSpecifier.ts deleted file mode 100644 index 9b0bb2467..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/TagSpecifier.ts +++ /dev/null @@ -1,174 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/metrics/v3/stats.proto - - -/** - * Designates a tag name and value pair. The value may be either a fixed value - * or a regex providing the value via capture groups. The specified tag will be - * unconditionally set if a fixed value, otherwise it will only be set if one - * or more capture groups in the regex match. - */ -export interface TagSpecifier { - /** - * Attaches an identifier to the tag values to identify the tag being in the - * sink. Envoy has a set of default names and regexes to extract dynamic - * portions of existing stats, which can be found in :repo:`well_known_names.h - * ` in the Envoy repository. If a :ref:`tag_name - * ` is provided in the config and - * neither :ref:`regex ` or - * :ref:`fixed_value ` were specified, - * Envoy will attempt to find that name in its set of defaults and use the accompanying regex. - * - * .. note:: - * - * It is invalid to specify the same tag name twice in a config. - */ - 'tag_name'?: (string); - /** - * Designates a tag to strip from the tag extracted name and provide as a named - * tag value for all statistics. This will only occur if any part of the name - * matches the regex provided with one or more capture groups. - * - * The first capture group identifies the portion of the name to remove. The - * second capture group (which will normally be nested inside the first) will - * designate the value of the tag for the statistic. If no second capture - * group is provided, the first will also be used to set the value of the tag. - * All other capture groups will be ignored. - * - * Example 1. a stat name ``cluster.foo_cluster.upstream_rq_timeout`` and - * one tag specifier: - * - * .. code-block:: json - * - * { - * "tag_name": "envoy.cluster_name", - * "regex": "^cluster\\.((.+?)\\.)" - * } - * - * Note that the regex will remove ``foo_cluster.`` making the tag extracted - * name ``cluster.upstream_rq_timeout`` and the tag value for - * ``envoy.cluster_name`` will be ``foo_cluster`` (note: there will be no - * ``.`` character because of the second capture group). - * - * Example 2. a stat name - * ``http.connection_manager_1.user_agent.ios.downstream_cx_total`` and two - * tag specifiers: - * - * .. code-block:: json - * - * [ - * { - * "tag_name": "envoy.http_user_agent", - * "regex": "^http(?=\\.).*?\\.user_agent\\.((.+?)\\.)\\w+?$" - * }, - * { - * "tag_name": "envoy.http_conn_manager_prefix", - * "regex": "^http\\.((.*?)\\.)" - * } - * ] - * - * The two regexes of the specifiers will be processed in the definition order. - * - * The first regex will remove ``ios.``, leaving the tag extracted name - * ``http.connection_manager_1.user_agent.downstream_cx_total``. The tag - * ``envoy.http_user_agent`` will be added with tag value ``ios``. - * - * The second regex will remove ``connection_manager_1.`` from the tag - * extracted name produced by the first regex - * ``http.connection_manager_1.user_agent.downstream_cx_total``, leaving - * ``http.user_agent.downstream_cx_total`` as the tag extracted name. The tag - * ``envoy.http_conn_manager_prefix`` will be added with the tag value - * ``connection_manager_1``. - */ - 'regex'?: (string); - /** - * Specifies a fixed tag value for the ``tag_name``. - */ - 'fixed_value'?: (string); - 'tag_value'?: "regex"|"fixed_value"; -} - -/** - * Designates a tag name and value pair. The value may be either a fixed value - * or a regex providing the value via capture groups. The specified tag will be - * unconditionally set if a fixed value, otherwise it will only be set if one - * or more capture groups in the regex match. - */ -export interface TagSpecifier__Output { - /** - * Attaches an identifier to the tag values to identify the tag being in the - * sink. Envoy has a set of default names and regexes to extract dynamic - * portions of existing stats, which can be found in :repo:`well_known_names.h - * ` in the Envoy repository. If a :ref:`tag_name - * ` is provided in the config and - * neither :ref:`regex ` or - * :ref:`fixed_value ` were specified, - * Envoy will attempt to find that name in its set of defaults and use the accompanying regex. - * - * .. note:: - * - * It is invalid to specify the same tag name twice in a config. - */ - 'tag_name': (string); - /** - * Designates a tag to strip from the tag extracted name and provide as a named - * tag value for all statistics. This will only occur if any part of the name - * matches the regex provided with one or more capture groups. - * - * The first capture group identifies the portion of the name to remove. The - * second capture group (which will normally be nested inside the first) will - * designate the value of the tag for the statistic. If no second capture - * group is provided, the first will also be used to set the value of the tag. - * All other capture groups will be ignored. - * - * Example 1. a stat name ``cluster.foo_cluster.upstream_rq_timeout`` and - * one tag specifier: - * - * .. code-block:: json - * - * { - * "tag_name": "envoy.cluster_name", - * "regex": "^cluster\\.((.+?)\\.)" - * } - * - * Note that the regex will remove ``foo_cluster.`` making the tag extracted - * name ``cluster.upstream_rq_timeout`` and the tag value for - * ``envoy.cluster_name`` will be ``foo_cluster`` (note: there will be no - * ``.`` character because of the second capture group). - * - * Example 2. a stat name - * ``http.connection_manager_1.user_agent.ios.downstream_cx_total`` and two - * tag specifiers: - * - * .. code-block:: json - * - * [ - * { - * "tag_name": "envoy.http_user_agent", - * "regex": "^http(?=\\.).*?\\.user_agent\\.((.+?)\\.)\\w+?$" - * }, - * { - * "tag_name": "envoy.http_conn_manager_prefix", - * "regex": "^http\\.((.*?)\\.)" - * } - * ] - * - * The two regexes of the specifiers will be processed in the definition order. - * - * The first regex will remove ``ios.``, leaving the tag extracted name - * ``http.connection_manager_1.user_agent.downstream_cx_total``. The tag - * ``envoy.http_user_agent`` will be added with tag value ``ios``. - * - * The second regex will remove ``connection_manager_1.`` from the tag - * extracted name produced by the first regex - * ``http.connection_manager_1.user_agent.downstream_cx_total``, leaving - * ``http.user_agent.downstream_cx_total`` as the tag extracted name. The tag - * ``envoy.http_conn_manager_prefix`` will be added with the tag value - * ``connection_manager_1``. - */ - 'regex'?: (string); - /** - * Specifies a fixed tag value for the ``tag_name``. - */ - 'fixed_value'?: (string); - 'tag_value': "regex"|"fixed_value"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/BufferFactoryConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/BufferFactoryConfig.ts deleted file mode 100644 index b3fbe1459..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/BufferFactoryConfig.ts +++ /dev/null @@ -1,50 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/overload/v3/overload.proto - - -/** - * Configuration for which accounts the WatermarkBuffer Factories should - * track. - */ -export interface BufferFactoryConfig { - /** - * The minimum power of two at which Envoy starts tracking an account. - * - * Envoy has 8 power of two buckets starting with the provided exponent below. - * Concretely the 1st bucket contains accounts for streams that use - * [2^minimum_account_to_track_power_of_two, - * 2^(minimum_account_to_track_power_of_two + 1)) bytes. - * With the 8th bucket tracking accounts - * >= 128 * 2^minimum_account_to_track_power_of_two. - * - * The maximum value is 56, since we're using uint64_t for bytes counting, - * and that's the last value that would use the 8 buckets. In practice, - * we don't expect the proxy to be holding 2^56 bytes. - * - * If omitted, Envoy should not do any tracking. - */ - 'minimum_account_to_track_power_of_two'?: (number); -} - -/** - * Configuration for which accounts the WatermarkBuffer Factories should - * track. - */ -export interface BufferFactoryConfig__Output { - /** - * The minimum power of two at which Envoy starts tracking an account. - * - * Envoy has 8 power of two buckets starting with the provided exponent below. - * Concretely the 1st bucket contains accounts for streams that use - * [2^minimum_account_to_track_power_of_two, - * 2^(minimum_account_to_track_power_of_two + 1)) bytes. - * With the 8th bucket tracking accounts - * >= 128 * 2^minimum_account_to_track_power_of_two. - * - * The maximum value is 56, since we're using uint64_t for bytes counting, - * and that's the last value that would use the 8 buckets. In practice, - * we don't expect the proxy to be holding 2^56 bytes. - * - * If omitted, Envoy should not do any tracking. - */ - 'minimum_account_to_track_power_of_two': (number); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/OverloadAction.ts b/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/OverloadAction.ts deleted file mode 100644 index 84f4db34b..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/OverloadAction.ts +++ /dev/null @@ -1,42 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/overload/v3/overload.proto - -import type { Trigger as _envoy_config_overload_v3_Trigger, Trigger__Output as _envoy_config_overload_v3_Trigger__Output } from '../../../../envoy/config/overload/v3/Trigger'; -import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; - -export interface OverloadAction { - /** - * The name of the overload action. This is just a well-known string that listeners can - * use for registering callbacks. Custom overload actions should be named using reverse - * DNS to ensure uniqueness. - */ - 'name'?: (string); - /** - * A set of triggers for this action. The state of the action is the maximum - * state of all triggers, which can be scaling between 0 and 1 or saturated. Listeners - * are notified when the overload action changes state. - */ - 'triggers'?: (_envoy_config_overload_v3_Trigger)[]; - /** - * Configuration for the action being instantiated. - */ - 'typed_config'?: (_google_protobuf_Any | null); -} - -export interface OverloadAction__Output { - /** - * The name of the overload action. This is just a well-known string that listeners can - * use for registering callbacks. Custom overload actions should be named using reverse - * DNS to ensure uniqueness. - */ - 'name': (string); - /** - * A set of triggers for this action. The state of the action is the maximum - * state of all triggers, which can be scaling between 0 and 1 or saturated. Listeners - * are notified when the overload action changes state. - */ - 'triggers': (_envoy_config_overload_v3_Trigger__Output)[]; - /** - * Configuration for the action being instantiated. - */ - 'typed_config': (_google_protobuf_Any__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/OverloadManager.ts b/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/OverloadManager.ts deleted file mode 100644 index e7f75b8e9..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/OverloadManager.ts +++ /dev/null @@ -1,44 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/overload/v3/overload.proto - -import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; -import type { ResourceMonitor as _envoy_config_overload_v3_ResourceMonitor, ResourceMonitor__Output as _envoy_config_overload_v3_ResourceMonitor__Output } from '../../../../envoy/config/overload/v3/ResourceMonitor'; -import type { OverloadAction as _envoy_config_overload_v3_OverloadAction, OverloadAction__Output as _envoy_config_overload_v3_OverloadAction__Output } from '../../../../envoy/config/overload/v3/OverloadAction'; -import type { BufferFactoryConfig as _envoy_config_overload_v3_BufferFactoryConfig, BufferFactoryConfig__Output as _envoy_config_overload_v3_BufferFactoryConfig__Output } from '../../../../envoy/config/overload/v3/BufferFactoryConfig'; - -export interface OverloadManager { - /** - * The interval for refreshing resource usage. - */ - 'refresh_interval'?: (_google_protobuf_Duration | null); - /** - * The set of resources to monitor. - */ - 'resource_monitors'?: (_envoy_config_overload_v3_ResourceMonitor)[]; - /** - * The set of overload actions. - */ - 'actions'?: (_envoy_config_overload_v3_OverloadAction)[]; - /** - * Configuration for buffer factory. - */ - 'buffer_factory_config'?: (_envoy_config_overload_v3_BufferFactoryConfig | null); -} - -export interface OverloadManager__Output { - /** - * The interval for refreshing resource usage. - */ - 'refresh_interval': (_google_protobuf_Duration__Output | null); - /** - * The set of resources to monitor. - */ - 'resource_monitors': (_envoy_config_overload_v3_ResourceMonitor__Output)[]; - /** - * The set of overload actions. - */ - 'actions': (_envoy_config_overload_v3_OverloadAction__Output)[]; - /** - * Configuration for buffer factory. - */ - 'buffer_factory_config': (_envoy_config_overload_v3_BufferFactoryConfig__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ResourceMonitor.ts b/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ResourceMonitor.ts deleted file mode 100644 index 02fde2411..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ResourceMonitor.ts +++ /dev/null @@ -1,33 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/overload/v3/overload.proto - -import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; - -export interface ResourceMonitor { - /** - * The name of the resource monitor to instantiate. Must match a registered - * resource monitor type. - * See the :ref:`extensions listed in typed_config below ` for the default list of available resource monitor. - */ - 'name'?: (string); - 'typed_config'?: (_google_protobuf_Any | null); - /** - * Configuration for the resource monitor being instantiated. - * [#extension-category: envoy.resource_monitors] - */ - 'config_type'?: "typed_config"; -} - -export interface ResourceMonitor__Output { - /** - * The name of the resource monitor to instantiate. Must match a registered - * resource monitor type. - * See the :ref:`extensions listed in typed_config below ` for the default list of available resource monitor. - */ - 'name': (string); - 'typed_config'?: (_google_protobuf_Any__Output | null); - /** - * Configuration for the resource monitor being instantiated. - * [#extension-category: envoy.resource_monitors] - */ - 'config_type': "typed_config"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ScaleTimersOverloadActionConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ScaleTimersOverloadActionConfig.ts deleted file mode 100644 index bb48fe3f6..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ScaleTimersOverloadActionConfig.ts +++ /dev/null @@ -1,89 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/overload/v3/overload.proto - -import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; -import type { Percent as _envoy_type_v3_Percent, Percent__Output as _envoy_type_v3_Percent__Output } from '../../../../envoy/type/v3/Percent'; - -export interface _envoy_config_overload_v3_ScaleTimersOverloadActionConfig_ScaleTimer { - /** - * The type of timer this minimum applies to. - */ - 'timer'?: (_envoy_config_overload_v3_ScaleTimersOverloadActionConfig_TimerType | keyof typeof _envoy_config_overload_v3_ScaleTimersOverloadActionConfig_TimerType); - /** - * Sets the minimum duration as an absolute value. - */ - 'min_timeout'?: (_google_protobuf_Duration | null); - /** - * Sets the minimum duration as a percentage of the maximum value. - */ - 'min_scale'?: (_envoy_type_v3_Percent | null); - 'overload_adjust'?: "min_timeout"|"min_scale"; -} - -export interface _envoy_config_overload_v3_ScaleTimersOverloadActionConfig_ScaleTimer__Output { - /** - * The type of timer this minimum applies to. - */ - 'timer': (keyof typeof _envoy_config_overload_v3_ScaleTimersOverloadActionConfig_TimerType); - /** - * Sets the minimum duration as an absolute value. - */ - 'min_timeout'?: (_google_protobuf_Duration__Output | null); - /** - * Sets the minimum duration as a percentage of the maximum value. - */ - 'min_scale'?: (_envoy_type_v3_Percent__Output | null); - 'overload_adjust': "min_timeout"|"min_scale"; -} - -// Original file: deps/envoy-api/envoy/config/overload/v3/overload.proto - -export enum _envoy_config_overload_v3_ScaleTimersOverloadActionConfig_TimerType { - /** - * Unsupported value; users must explicitly specify the timer they want scaled. - */ - UNSPECIFIED = 0, - /** - * Adjusts the idle timer for downstream HTTP connections that takes effect when there are no active streams. - * This affects the value of :ref:`HttpConnectionManager.common_http_protocol_options.idle_timeout - * ` - */ - HTTP_DOWNSTREAM_CONNECTION_IDLE = 1, - /** - * Adjusts the idle timer for HTTP streams initiated by downstream clients. - * This affects the value of :ref:`RouteAction.idle_timeout ` and - * :ref:`HttpConnectionManager.stream_idle_timeout - * ` - */ - HTTP_DOWNSTREAM_STREAM_IDLE = 2, - /** - * Adjusts the timer for how long downstream clients have to finish transport-level negotiations - * before the connection is closed. - * This affects the value of - * :ref:`FilterChain.transport_socket_connect_timeout `. - */ - TRANSPORT_SOCKET_CONNECT = 3, -} - -/** - * Typed configuration for the "envoy.overload_actions.reduce_timeouts" action. See - * :ref:`the docs ` for an example of how to configure - * the action with different timeouts and minimum values. - */ -export interface ScaleTimersOverloadActionConfig { - /** - * A set of timer scaling rules to be applied. - */ - 'timer_scale_factors'?: (_envoy_config_overload_v3_ScaleTimersOverloadActionConfig_ScaleTimer)[]; -} - -/** - * Typed configuration for the "envoy.overload_actions.reduce_timeouts" action. See - * :ref:`the docs ` for an example of how to configure - * the action with different timeouts and minimum values. - */ -export interface ScaleTimersOverloadActionConfig__Output { - /** - * A set of timer scaling rules to be applied. - */ - 'timer_scale_factors': (_envoy_config_overload_v3_ScaleTimersOverloadActionConfig_ScaleTimer__Output)[]; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ScaledTrigger.ts b/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ScaledTrigger.ts deleted file mode 100644 index 8c6574f56..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ScaledTrigger.ts +++ /dev/null @@ -1,28 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/overload/v3/overload.proto - - -export interface ScaledTrigger { - /** - * If the resource pressure is greater than this value, the trigger will be in the - * :ref:`scaling ` state with value - * `(pressure - scaling_threshold) / (saturation_threshold - scaling_threshold)`. - */ - 'scaling_threshold'?: (number | string); - /** - * If the resource pressure is greater than this value, the trigger will enter saturation. - */ - 'saturation_threshold'?: (number | string); -} - -export interface ScaledTrigger__Output { - /** - * If the resource pressure is greater than this value, the trigger will be in the - * :ref:`scaling ` state with value - * `(pressure - scaling_threshold) / (saturation_threshold - scaling_threshold)`. - */ - 'scaling_threshold': (number); - /** - * If the resource pressure is greater than this value, the trigger will enter saturation. - */ - 'saturation_threshold': (number); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ThresholdTrigger.ts b/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ThresholdTrigger.ts deleted file mode 100644 index b02ddd47d..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ThresholdTrigger.ts +++ /dev/null @@ -1,18 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/overload/v3/overload.proto - - -export interface ThresholdTrigger { - /** - * If the resource pressure is greater than or equal to this value, the trigger - * will enter saturation. - */ - 'value'?: (number | string); -} - -export interface ThresholdTrigger__Output { - /** - * If the resource pressure is greater than or equal to this value, the trigger - * will enter saturation. - */ - 'value': (number); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/Trigger.ts b/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/Trigger.ts deleted file mode 100644 index 38f360ee7..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/Trigger.ts +++ /dev/null @@ -1,24 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/overload/v3/overload.proto - -import type { ThresholdTrigger as _envoy_config_overload_v3_ThresholdTrigger, ThresholdTrigger__Output as _envoy_config_overload_v3_ThresholdTrigger__Output } from '../../../../envoy/config/overload/v3/ThresholdTrigger'; -import type { ScaledTrigger as _envoy_config_overload_v3_ScaledTrigger, ScaledTrigger__Output as _envoy_config_overload_v3_ScaledTrigger__Output } from '../../../../envoy/config/overload/v3/ScaledTrigger'; - -export interface Trigger { - /** - * The name of the resource this is a trigger for. - */ - 'name'?: (string); - 'threshold'?: (_envoy_config_overload_v3_ThresholdTrigger | null); - 'scaled'?: (_envoy_config_overload_v3_ScaledTrigger | null); - 'trigger_oneof'?: "threshold"|"scaled"; -} - -export interface Trigger__Output { - /** - * The name of the resource this is a trigger for. - */ - 'name': (string); - 'threshold'?: (_envoy_config_overload_v3_ThresholdTrigger__Output | null); - 'scaled'?: (_envoy_config_overload_v3_ScaledTrigger__Output | null); - 'trigger_oneof': "threshold"|"scaled"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/HeaderMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/HeaderMatcher.ts index e073a8f13..b5b085ae7 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/HeaderMatcher.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/HeaderMatcher.ts @@ -3,7 +3,6 @@ import type { Int64Range as _envoy_type_v3_Int64Range, Int64Range__Output as _envoy_type_v3_Int64Range__Output } from '../../../../envoy/type/v3/Int64Range'; import type { RegexMatcher as _envoy_type_matcher_v3_RegexMatcher, RegexMatcher__Output as _envoy_type_matcher_v3_RegexMatcher__Output } from '../../../../envoy/type/matcher/v3/RegexMatcher'; import type { StringMatcher as _envoy_type_matcher_v3_StringMatcher, StringMatcher__Output as _envoy_type_matcher_v3_StringMatcher__Output } from '../../../../envoy/type/matcher/v3/StringMatcher'; -import type { Long } from '@grpc/proto-loader'; /** * .. attention:: @@ -42,6 +41,7 @@ export interface HeaderMatcher { /** * If specified, header match will be performed based on the value of the header. * This field is deprecated. Please use :ref:`string_match `. + * @deprecated */ 'exact_match'?: (string); /** @@ -80,6 +80,7 @@ export interface HeaderMatcher { * Examples: * * * The prefix ``abcd`` matches the value ``abcdxyz``, but not for ``abcxyz``. + * @deprecated */ 'prefix_match'?: (string); /** @@ -90,6 +91,7 @@ export interface HeaderMatcher { * Examples: * * * The suffix ``abcd`` matches the value ``xyzabcd``, but not for ``xyzbcd``. + * @deprecated */ 'suffix_match'?: (string); /** @@ -97,6 +99,7 @@ export interface HeaderMatcher { * header value must match the regex. The rule will not match if only a subsequence of the * request header value matches the regex. * This field is deprecated. Please use :ref:`string_match `. + * @deprecated */ 'safe_regex_match'?: (_envoy_type_matcher_v3_RegexMatcher | null); /** @@ -108,6 +111,7 @@ export interface HeaderMatcher { * Examples: * * * The value ``abcd`` matches the value ``xyzabcdpqr``, but not for ``xyzbcdpqr``. + * @deprecated */ 'contains_match'?: (string); /** @@ -186,6 +190,7 @@ export interface HeaderMatcher__Output { /** * If specified, header match will be performed based on the value of the header. * This field is deprecated. Please use :ref:`string_match `. + * @deprecated */ 'exact_match'?: (string); /** @@ -224,6 +229,7 @@ export interface HeaderMatcher__Output { * Examples: * * * The prefix ``abcd`` matches the value ``abcdxyz``, but not for ``abcxyz``. + * @deprecated */ 'prefix_match'?: (string); /** @@ -234,6 +240,7 @@ export interface HeaderMatcher__Output { * Examples: * * * The suffix ``abcd`` matches the value ``xyzabcd``, but not for ``xyzbcd``. + * @deprecated */ 'suffix_match'?: (string); /** @@ -241,6 +248,7 @@ export interface HeaderMatcher__Output { * header value must match the regex. The rule will not match if only a subsequence of the * request header value matches the regex. * This field is deprecated. Please use :ref:`string_match `. + * @deprecated */ 'safe_regex_match'?: (_envoy_type_matcher_v3_RegexMatcher__Output | null); /** @@ -252,6 +260,7 @@ export interface HeaderMatcher__Output { * Examples: * * * The value ``abcd`` matches the value ``xyzabcdpqr``, but not for ``xyzbcdpqr``. + * @deprecated */ 'contains_match'?: (string); /** diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RateLimit.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RateLimit.ts index cd47e471a..28d17667f 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RateLimit.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RateLimit.ts @@ -40,6 +40,7 @@ export interface _envoy_config_route_v3_RateLimit_Action { * * .. attention:: * This field has been deprecated in favor of the :ref:`metadata ` field + * @deprecated */ 'dynamic_metadata'?: (_envoy_config_route_v3_RateLimit_Action_DynamicMetaData | null); /** @@ -101,6 +102,7 @@ export interface _envoy_config_route_v3_RateLimit_Action__Output { * * .. attention:: * This field has been deprecated in favor of the :ref:`metadata ` field + * @deprecated */ 'dynamic_metadata'?: (_envoy_config_route_v3_RateLimit_Action_DynamicMetaData__Output | null); /** @@ -438,7 +440,7 @@ export interface _envoy_config_route_v3_RateLimit_Action_MetaData { /** * Source of metadata */ - 'source'?: (_envoy_config_route_v3_RateLimit_Action_MetaData_Source | keyof typeof _envoy_config_route_v3_RateLimit_Action_MetaData_Source); + 'source'?: (_envoy_config_route_v3_RateLimit_Action_MetaData_Source); /** * If set to true, Envoy skips the descriptor while calling rate limiting service * when ``metadata_key`` is empty and ``default_value`` is not set. By default it skips calling the @@ -474,7 +476,7 @@ export interface _envoy_config_route_v3_RateLimit_Action_MetaData__Output { /** * Source of metadata */ - 'source': (keyof typeof _envoy_config_route_v3_RateLimit_Action_MetaData_Source); + 'source': (_envoy_config_route_v3_RateLimit_Action_MetaData_Source__Output); /** * If set to true, Envoy skips the descriptor while calling rate limiting service * when ``metadata_key`` is empty and ``default_value`` is not set. By default it skips calling the @@ -643,16 +645,30 @@ export interface _envoy_config_route_v3_RateLimit_Action_RequestHeaders__Output // Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto -export enum _envoy_config_route_v3_RateLimit_Action_MetaData_Source { +export const _envoy_config_route_v3_RateLimit_Action_MetaData_Source = { /** * Query :ref:`dynamic metadata ` */ - DYNAMIC = 0, + DYNAMIC: 'DYNAMIC', /** * Query :ref:`route entry metadata ` */ - ROUTE_ENTRY = 1, -} + ROUTE_ENTRY: 'ROUTE_ENTRY', +} as const; + +export type _envoy_config_route_v3_RateLimit_Action_MetaData_Source = + /** + * Query :ref:`dynamic metadata ` + */ + | 'DYNAMIC' + | 0 + /** + * Query :ref:`route entry metadata ` + */ + | 'ROUTE_ENTRY' + | 1 + +export type _envoy_config_route_v3_RateLimit_Action_MetaData_Source__Output = typeof _envoy_config_route_v3_RateLimit_Action_MetaData_Source[keyof typeof _envoy_config_route_v3_RateLimit_Action_MetaData_Source] /** * The following descriptor entry is appended to the descriptor: diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RedirectAction.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RedirectAction.ts index fd11a681b..070470af3 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RedirectAction.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RedirectAction.ts @@ -4,28 +4,57 @@ import type { RegexMatchAndSubstitute as _envoy_type_matcher_v3_RegexMatchAndSub // Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto -export enum _envoy_config_route_v3_RedirectAction_RedirectResponseCode { +export const _envoy_config_route_v3_RedirectAction_RedirectResponseCode = { /** * Moved Permanently HTTP Status Code - 301. */ - MOVED_PERMANENTLY = 0, + MOVED_PERMANENTLY: 'MOVED_PERMANENTLY', /** * Found HTTP Status Code - 302. */ - FOUND = 1, + FOUND: 'FOUND', /** * See Other HTTP Status Code - 303. */ - SEE_OTHER = 2, + SEE_OTHER: 'SEE_OTHER', /** * Temporary Redirect HTTP Status Code - 307. */ - TEMPORARY_REDIRECT = 3, + TEMPORARY_REDIRECT: 'TEMPORARY_REDIRECT', /** * Permanent Redirect HTTP Status Code - 308. */ - PERMANENT_REDIRECT = 4, -} + PERMANENT_REDIRECT: 'PERMANENT_REDIRECT', +} as const; + +export type _envoy_config_route_v3_RedirectAction_RedirectResponseCode = + /** + * Moved Permanently HTTP Status Code - 301. + */ + | 'MOVED_PERMANENTLY' + | 0 + /** + * Found HTTP Status Code - 302. + */ + | 'FOUND' + | 1 + /** + * See Other HTTP Status Code - 303. + */ + | 'SEE_OTHER' + | 2 + /** + * Temporary Redirect HTTP Status Code - 307. + */ + | 'TEMPORARY_REDIRECT' + | 3 + /** + * Permanent Redirect HTTP Status Code - 308. + */ + | 'PERMANENT_REDIRECT' + | 4 + +export type _envoy_config_route_v3_RedirectAction_RedirectResponseCode__Output = typeof _envoy_config_route_v3_RedirectAction_RedirectResponseCode[keyof typeof _envoy_config_route_v3_RedirectAction_RedirectResponseCode] /** * [#next-free-field: 10] @@ -58,7 +87,7 @@ export interface RedirectAction { * The HTTP status code to use in the redirect response. The default response * code is MOVED_PERMANENTLY (301). */ - 'response_code'?: (_envoy_config_route_v3_RedirectAction_RedirectResponseCode | keyof typeof _envoy_config_route_v3_RedirectAction_RedirectResponseCode); + 'response_code'?: (_envoy_config_route_v3_RedirectAction_RedirectResponseCode); /** * The scheme portion of the URL will be swapped with "https". */ @@ -155,7 +184,7 @@ export interface RedirectAction__Output { * The HTTP status code to use in the redirect response. The default response * code is MOVED_PERMANENTLY (301). */ - 'response_code': (keyof typeof _envoy_config_route_v3_RedirectAction_RedirectResponseCode); + 'response_code': (_envoy_config_route_v3_RedirectAction_RedirectResponseCode__Output); /** * The scheme portion of the URL will be swapped with "https". */ diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RetryPolicy.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RetryPolicy.ts index d60458728..773943b7f 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RetryPolicy.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RetryPolicy.ts @@ -141,7 +141,7 @@ export interface _envoy_config_route_v3_RetryPolicy_ResetHeader { /** * The format of the reset header. */ - 'format'?: (_envoy_config_route_v3_RetryPolicy_ResetHeaderFormat | keyof typeof _envoy_config_route_v3_RetryPolicy_ResetHeaderFormat); + 'format'?: (_envoy_config_route_v3_RetryPolicy_ResetHeaderFormat); } export interface _envoy_config_route_v3_RetryPolicy_ResetHeader__Output { @@ -156,15 +156,23 @@ export interface _envoy_config_route_v3_RetryPolicy_ResetHeader__Output { /** * The format of the reset header. */ - 'format': (keyof typeof _envoy_config_route_v3_RetryPolicy_ResetHeaderFormat); + 'format': (_envoy_config_route_v3_RetryPolicy_ResetHeaderFormat__Output); } // Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto -export enum _envoy_config_route_v3_RetryPolicy_ResetHeaderFormat { - SECONDS = 0, - UNIX_TIMESTAMP = 1, -} +export const _envoy_config_route_v3_RetryPolicy_ResetHeaderFormat = { + SECONDS: 'SECONDS', + UNIX_TIMESTAMP: 'UNIX_TIMESTAMP', +} as const; + +export type _envoy_config_route_v3_RetryPolicy_ResetHeaderFormat = + | 'SECONDS' + | 0 + | 'UNIX_TIMESTAMP' + | 1 + +export type _envoy_config_route_v3_RetryPolicy_ResetHeaderFormat__Output = typeof _envoy_config_route_v3_RetryPolicy_ResetHeaderFormat[keyof typeof _envoy_config_route_v3_RetryPolicy_ResetHeaderFormat] export interface _envoy_config_route_v3_RetryPolicy_RetryBackOff { /** diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteAction.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteAction.ts index 9dd8b7c2c..fd38da92e 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteAction.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteAction.ts @@ -5,7 +5,7 @@ import type { Metadata as _envoy_config_core_v3_Metadata, Metadata__Output as _e import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; import type { RetryPolicy as _envoy_config_route_v3_RetryPolicy, RetryPolicy__Output as _envoy_config_route_v3_RetryPolicy__Output } from '../../../../envoy/config/route/v3/RetryPolicy'; -import type { RoutingPriority as _envoy_config_core_v3_RoutingPriority } from '../../../../envoy/config/core/v3/RoutingPriority'; +import type { RoutingPriority as _envoy_config_core_v3_RoutingPriority, RoutingPriority__Output as _envoy_config_core_v3_RoutingPriority__Output } from '../../../../envoy/config/core/v3/RoutingPriority'; import type { RateLimit as _envoy_config_route_v3_RateLimit, RateLimit__Output as _envoy_config_route_v3_RateLimit__Output } from '../../../../envoy/config/route/v3/RateLimit'; import type { CorsPolicy as _envoy_config_route_v3_CorsPolicy, CorsPolicy__Output as _envoy_config_route_v3_CorsPolicy__Output } from '../../../../envoy/config/route/v3/CorsPolicy'; import type { HedgePolicy as _envoy_config_route_v3_HedgePolicy, HedgePolicy__Output as _envoy_config_route_v3_HedgePolicy__Output } from '../../../../envoy/config/route/v3/HedgePolicy'; @@ -20,20 +20,39 @@ import type { ProxyProtocolConfig as _envoy_config_core_v3_ProxyProtocolConfig, // Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto -export enum _envoy_config_route_v3_RouteAction_ClusterNotFoundResponseCode { +export const _envoy_config_route_v3_RouteAction_ClusterNotFoundResponseCode = { /** * HTTP status code - 503 Service Unavailable. */ - SERVICE_UNAVAILABLE = 0, + SERVICE_UNAVAILABLE: 'SERVICE_UNAVAILABLE', /** * HTTP status code - 404 Not Found. */ - NOT_FOUND = 1, + NOT_FOUND: 'NOT_FOUND', /** * HTTP status code - 500 Internal Server Error. */ - INTERNAL_SERVER_ERROR = 2, -} + INTERNAL_SERVER_ERROR: 'INTERNAL_SERVER_ERROR', +} as const; + +export type _envoy_config_route_v3_RouteAction_ClusterNotFoundResponseCode = + /** + * HTTP status code - 503 Service Unavailable. + */ + | 'SERVICE_UNAVAILABLE' + | 0 + /** + * HTTP status code - 404 Not Found. + */ + | 'NOT_FOUND' + | 1 + /** + * HTTP status code - 500 Internal Server Error. + */ + | 'INTERNAL_SERVER_ERROR' + | 2 + +export type _envoy_config_route_v3_RouteAction_ClusterNotFoundResponseCode__Output = typeof _envoy_config_route_v3_RouteAction_ClusterNotFoundResponseCode[keyof typeof _envoy_config_route_v3_RouteAction_ClusterNotFoundResponseCode] /** * Configuration for sending data upstream as a raw data payload. This is used for @@ -302,11 +321,30 @@ export interface _envoy_config_route_v3_RouteAction_HashPolicy_Header__Output { /** * Configures :ref:`internal redirect ` behavior. * [#next-major-version: remove this definition - it's defined in the InternalRedirectPolicy message.] + * @deprecated */ -export enum _envoy_config_route_v3_RouteAction_InternalRedirectAction { - PASS_THROUGH_INTERNAL_REDIRECT = 0, - HANDLE_INTERNAL_REDIRECT = 1, -} +export const _envoy_config_route_v3_RouteAction_InternalRedirectAction = { + PASS_THROUGH_INTERNAL_REDIRECT: 'PASS_THROUGH_INTERNAL_REDIRECT', + HANDLE_INTERNAL_REDIRECT: 'HANDLE_INTERNAL_REDIRECT', +} as const; + +/** + * Configures :ref:`internal redirect ` behavior. + * [#next-major-version: remove this definition - it's defined in the InternalRedirectPolicy message.] + * @deprecated + */ +export type _envoy_config_route_v3_RouteAction_InternalRedirectAction = + | 'PASS_THROUGH_INTERNAL_REDIRECT' + | 0 + | 'HANDLE_INTERNAL_REDIRECT' + | 1 + +/** + * Configures :ref:`internal redirect ` behavior. + * [#next-major-version: remove this definition - it's defined in the InternalRedirectPolicy message.] + * @deprecated + */ +export type _envoy_config_route_v3_RouteAction_InternalRedirectAction__Output = typeof _envoy_config_route_v3_RouteAction_InternalRedirectAction[keyof typeof _envoy_config_route_v3_RouteAction_InternalRedirectAction] export interface _envoy_config_route_v3_RouteAction_MaxStreamDuration { /** @@ -679,7 +717,7 @@ export interface RouteAction { /** * Optionally specifies the :ref:`routing priority `. */ - 'priority'?: (_envoy_config_core_v3_RoutingPriority | keyof typeof _envoy_config_core_v3_RoutingPriority); + 'priority'?: (_envoy_config_core_v3_RoutingPriority); /** * Specifies a set of rate limit configurations that could be applied to the * route. @@ -692,6 +730,7 @@ export interface RouteAction { * request. * * This field is deprecated. Please use :ref:`vh_rate_limits ` + * @deprecated */ 'include_vh_rate_limits'?: (_google_protobuf_BoolValue | null); /** @@ -720,13 +759,14 @@ export interface RouteAction { * :ref:`Route.typed_per_filter_config` or * :ref:`WeightedCluster.ClusterWeight.typed_per_filter_config` * to configure the CORS HTTP filter. + * @deprecated */ 'cors'?: (_envoy_config_route_v3_CorsPolicy | null); /** * The HTTP status code to use when configured cluster is not found. * The default response code is 503 Service Unavailable. */ - 'cluster_not_found_response_code'?: (_envoy_config_route_v3_RouteAction_ClusterNotFoundResponseCode | keyof typeof _envoy_config_route_v3_RouteAction_ClusterNotFoundResponseCode); + 'cluster_not_found_response_code'?: (_envoy_config_route_v3_RouteAction_ClusterNotFoundResponseCode); /** * Deprecated by :ref:`grpc_timeout_header_max ` * If present, and the request is a gRPC request, use the @@ -748,6 +788,7 @@ export interface RouteAction { * :ref:`config_http_filters_router_x-envoy-upstream-rq-timeout-ms`, * :ref:`config_http_filters_router_x-envoy-upstream-rq-per-try-timeout-ms`, and the * :ref:`retry overview `. + * @deprecated */ 'max_grpc_timeout'?: (_google_protobuf_Duration | null); /** @@ -776,7 +817,10 @@ export interface RouteAction { */ 'idle_timeout'?: (_google_protobuf_Duration | null); 'upgrade_configs'?: (_envoy_config_route_v3_RouteAction_UpgradeConfig)[]; - 'internal_redirect_action'?: (_envoy_config_route_v3_RouteAction_InternalRedirectAction | keyof typeof _envoy_config_route_v3_RouteAction_InternalRedirectAction); + /** + * @deprecated + */ + 'internal_redirect_action'?: (_envoy_config_route_v3_RouteAction_InternalRedirectAction); /** * Indicates that the route has a hedge policy. Note that if this is set, * it'll take precedence over the virtual host level hedge policy entirely @@ -792,6 +836,7 @@ export interface RouteAction { * The offset will only be applied if the provided grpc_timeout is greater than the offset. This * ensures that the offset will only ever decrease the timeout and never set it to 0 (meaning * infinity). + * @deprecated */ 'grpc_timeout_offset'?: (_google_protobuf_Duration | null); /** @@ -833,6 +878,7 @@ export interface RouteAction { * will pass the redirect back to downstream. * * If not specified, at most one redirect will be followed. + * @deprecated */ 'max_internal_redirects'?: (_google_protobuf_UInt32Value | null); /** @@ -1063,7 +1109,7 @@ export interface RouteAction__Output { /** * Optionally specifies the :ref:`routing priority `. */ - 'priority': (keyof typeof _envoy_config_core_v3_RoutingPriority); + 'priority': (_envoy_config_core_v3_RoutingPriority__Output); /** * Specifies a set of rate limit configurations that could be applied to the * route. @@ -1076,6 +1122,7 @@ export interface RouteAction__Output { * request. * * This field is deprecated. Please use :ref:`vh_rate_limits ` + * @deprecated */ 'include_vh_rate_limits': (_google_protobuf_BoolValue__Output | null); /** @@ -1104,13 +1151,14 @@ export interface RouteAction__Output { * :ref:`Route.typed_per_filter_config` or * :ref:`WeightedCluster.ClusterWeight.typed_per_filter_config` * to configure the CORS HTTP filter. + * @deprecated */ 'cors': (_envoy_config_route_v3_CorsPolicy__Output | null); /** * The HTTP status code to use when configured cluster is not found. * The default response code is 503 Service Unavailable. */ - 'cluster_not_found_response_code': (keyof typeof _envoy_config_route_v3_RouteAction_ClusterNotFoundResponseCode); + 'cluster_not_found_response_code': (_envoy_config_route_v3_RouteAction_ClusterNotFoundResponseCode__Output); /** * Deprecated by :ref:`grpc_timeout_header_max ` * If present, and the request is a gRPC request, use the @@ -1132,6 +1180,7 @@ export interface RouteAction__Output { * :ref:`config_http_filters_router_x-envoy-upstream-rq-timeout-ms`, * :ref:`config_http_filters_router_x-envoy-upstream-rq-per-try-timeout-ms`, and the * :ref:`retry overview `. + * @deprecated */ 'max_grpc_timeout': (_google_protobuf_Duration__Output | null); /** @@ -1160,7 +1209,10 @@ export interface RouteAction__Output { */ 'idle_timeout': (_google_protobuf_Duration__Output | null); 'upgrade_configs': (_envoy_config_route_v3_RouteAction_UpgradeConfig__Output)[]; - 'internal_redirect_action': (keyof typeof _envoy_config_route_v3_RouteAction_InternalRedirectAction); + /** + * @deprecated + */ + 'internal_redirect_action': (_envoy_config_route_v3_RouteAction_InternalRedirectAction__Output); /** * Indicates that the route has a hedge policy. Note that if this is set, * it'll take precedence over the virtual host level hedge policy entirely @@ -1176,6 +1228,7 @@ export interface RouteAction__Output { * The offset will only be applied if the provided grpc_timeout is greater than the offset. This * ensures that the offset will only ever decrease the timeout and never set it to 0 (meaning * infinity). + * @deprecated */ 'grpc_timeout_offset': (_google_protobuf_Duration__Output | null); /** @@ -1217,6 +1270,7 @@ export interface RouteAction__Output { * will pass the redirect back to downstream. * * If not specified, at most one redirect will be followed. + * @deprecated */ 'max_internal_redirects': (_google_protobuf_UInt32Value__Output | null); /** diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/VirtualHost.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/VirtualHost.ts index b2c344fff..5109be872 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/VirtualHost.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/VirtualHost.ts @@ -14,22 +14,43 @@ import type { _envoy_config_route_v3_RouteAction_RequestMirrorPolicy, _envoy_con // Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto -export enum _envoy_config_route_v3_VirtualHost_TlsRequirementType { +export const _envoy_config_route_v3_VirtualHost_TlsRequirementType = { /** * No TLS requirement for the virtual host. */ - NONE = 0, + NONE: 'NONE', /** * External requests must use TLS. If a request is external and it is not * using TLS, a 301 redirect will be sent telling the client to use HTTPS. */ - EXTERNAL_ONLY = 1, + EXTERNAL_ONLY: 'EXTERNAL_ONLY', /** * All requests must use TLS. If a request is not using TLS, a 301 redirect * will be sent telling the client to use HTTPS. */ - ALL = 2, -} + ALL: 'ALL', +} as const; + +export type _envoy_config_route_v3_VirtualHost_TlsRequirementType = + /** + * No TLS requirement for the virtual host. + */ + | 'NONE' + | 0 + /** + * External requests must use TLS. If a request is external and it is not + * using TLS, a 301 redirect will be sent telling the client to use HTTPS. + */ + | 'EXTERNAL_ONLY' + | 1 + /** + * All requests must use TLS. If a request is not using TLS, a 301 redirect + * will be sent telling the client to use HTTPS. + */ + | 'ALL' + | 2 + +export type _envoy_config_route_v3_VirtualHost_TlsRequirementType__Output = typeof _envoy_config_route_v3_VirtualHost_TlsRequirementType[keyof typeof _envoy_config_route_v3_VirtualHost_TlsRequirementType] /** * The top level element in the routing configuration is a virtual host. Each virtual host has @@ -76,7 +97,7 @@ export interface VirtualHost { * Specifies the type of TLS enforcement the virtual host expects. If this option is not * specified, there is no TLS requirement for the virtual host. */ - 'require_tls'?: (_envoy_config_route_v3_VirtualHost_TlsRequirementType | keyof typeof _envoy_config_route_v3_VirtualHost_TlsRequirementType); + 'require_tls'?: (_envoy_config_route_v3_VirtualHost_TlsRequirementType); /** * A list of virtual clusters defined for this virtual host. Virtual clusters * are used for additional statistics gathering. @@ -106,6 +127,7 @@ export interface VirtualHost { * This option has been deprecated. Please use * :ref:`VirtualHost.typed_per_filter_config` * to configure the CORS HTTP filter. + * @deprecated */ 'cors'?: (_envoy_config_route_v3_CorsPolicy | null); /** @@ -256,7 +278,7 @@ export interface VirtualHost__Output { * Specifies the type of TLS enforcement the virtual host expects. If this option is not * specified, there is no TLS requirement for the virtual host. */ - 'require_tls': (keyof typeof _envoy_config_route_v3_VirtualHost_TlsRequirementType); + 'require_tls': (_envoy_config_route_v3_VirtualHost_TlsRequirementType__Output); /** * A list of virtual clusters defined for this virtual host. Virtual clusters * are used for additional statistics gathering. @@ -286,6 +308,7 @@ export interface VirtualHost__Output { * This option has been deprecated. Please use * :ref:`VirtualHost.typed_per_filter_config` * to configure the CORS HTTP filter. + * @deprecated */ 'cors': (_envoy_config_route_v3_CorsPolicy__Output | null); /** diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/WeightedCluster.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/WeightedCluster.ts index cc820654d..91f4c6aeb 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/WeightedCluster.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/WeightedCluster.ts @@ -232,6 +232,7 @@ export interface WeightedCluster { * value, if this is greater than 0. * This field is now deprecated, and the client will use the sum of all * cluster weights. It is up to the management server to supply the correct weights. + * @deprecated */ 'total_weight'?: (_google_protobuf_UInt32Value | null); /** @@ -274,6 +275,7 @@ export interface WeightedCluster__Output { * value, if this is greater than 0. * This field is now deprecated, and the client will use the sum of all * cluster weights. It is up to the management server to supply the correct weights. + * @deprecated */ 'total_weight': (_google_protobuf_UInt32Value__Output | null); /** diff --git a/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/AccessLogCommon.ts b/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/AccessLogCommon.ts index 7679dfac1..7ca3c5b19 100644 --- a/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/AccessLogCommon.ts +++ b/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/AccessLogCommon.ts @@ -7,7 +7,7 @@ import type { Duration as _google_protobuf_Duration, Duration__Output as _google import type { ResponseFlags as _envoy_data_accesslog_v3_ResponseFlags, ResponseFlags__Output as _envoy_data_accesslog_v3_ResponseFlags__Output } from '../../../../envoy/data/accesslog/v3/ResponseFlags'; import type { Metadata as _envoy_config_core_v3_Metadata, Metadata__Output as _envoy_config_core_v3_Metadata__Output } from '../../../../envoy/config/core/v3/Metadata'; import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; -import type { AccessLogType as _envoy_data_accesslog_v3_AccessLogType } from '../../../../envoy/data/accesslog/v3/AccessLogType'; +import type { AccessLogType as _envoy_data_accesslog_v3_AccessLogType, AccessLogType__Output as _envoy_data_accesslog_v3_AccessLogType__Output } from '../../../../envoy/data/accesslog/v3/AccessLogType'; import type { Long } from '@grpc/proto-loader'; /** @@ -176,6 +176,7 @@ export interface AccessLogCommon { * * This field is deprecated in favor of ``access_log_type`` for better indication of the * type of the access log record. + * @deprecated */ 'intermediate_log_entry'?: (boolean); /** @@ -212,7 +213,7 @@ export interface AccessLogCommon { * For more information about how access log behaves and when it is being recorded, * please refer to :ref:`access logging `. */ - 'access_log_type'?: (_envoy_data_accesslog_v3_AccessLogType | keyof typeof _envoy_data_accesslog_v3_AccessLogType); + 'access_log_type'?: (_envoy_data_accesslog_v3_AccessLogType); } /** @@ -381,6 +382,7 @@ export interface AccessLogCommon__Output { * * This field is deprecated in favor of ``access_log_type`` for better indication of the * type of the access log record. + * @deprecated */ 'intermediate_log_entry': (boolean); /** @@ -417,5 +419,5 @@ export interface AccessLogCommon__Output { * For more information about how access log behaves and when it is being recorded, * please refer to :ref:`access logging `. */ - 'access_log_type': (keyof typeof _envoy_data_accesslog_v3_AccessLogType); + 'access_log_type': (_envoy_data_accesslog_v3_AccessLogType__Output); } diff --git a/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/AccessLogType.ts b/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/AccessLogType.ts index a50bb42c1..29ee32f5a 100644 --- a/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/AccessLogType.ts +++ b/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/AccessLogType.ts @@ -1,15 +1,41 @@ // Original file: deps/envoy-api/envoy/data/accesslog/v3/accesslog.proto -export enum AccessLogType { - NotSet = 0, - TcpUpstreamConnected = 1, - TcpPeriodic = 2, - TcpConnectionEnd = 3, - DownstreamStart = 4, - DownstreamPeriodic = 5, - DownstreamEnd = 6, - UpstreamPoolReady = 7, - UpstreamPeriodic = 8, - UpstreamEnd = 9, - DownstreamTunnelSuccessfullyEstablished = 10, -} +export const AccessLogType = { + NotSet: 'NotSet', + TcpUpstreamConnected: 'TcpUpstreamConnected', + TcpPeriodic: 'TcpPeriodic', + TcpConnectionEnd: 'TcpConnectionEnd', + DownstreamStart: 'DownstreamStart', + DownstreamPeriodic: 'DownstreamPeriodic', + DownstreamEnd: 'DownstreamEnd', + UpstreamPoolReady: 'UpstreamPoolReady', + UpstreamPeriodic: 'UpstreamPeriodic', + UpstreamEnd: 'UpstreamEnd', + DownstreamTunnelSuccessfullyEstablished: 'DownstreamTunnelSuccessfullyEstablished', +} as const; + +export type AccessLogType = + | 'NotSet' + | 0 + | 'TcpUpstreamConnected' + | 1 + | 'TcpPeriodic' + | 2 + | 'TcpConnectionEnd' + | 3 + | 'DownstreamStart' + | 4 + | 'DownstreamPeriodic' + | 5 + | 'DownstreamEnd' + | 6 + | 'UpstreamPoolReady' + | 7 + | 'UpstreamPeriodic' + | 8 + | 'UpstreamEnd' + | 9 + | 'DownstreamTunnelSuccessfullyEstablished' + | 10 + +export type AccessLogType__Output = typeof AccessLogType[keyof typeof AccessLogType] diff --git a/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/HTTPAccessLogEntry.ts b/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/HTTPAccessLogEntry.ts index 760954bb1..31daac364 100644 --- a/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/HTTPAccessLogEntry.ts +++ b/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/HTTPAccessLogEntry.ts @@ -9,20 +9,40 @@ import type { HTTPResponseProperties as _envoy_data_accesslog_v3_HTTPResponsePro /** * HTTP version */ -export enum _envoy_data_accesslog_v3_HTTPAccessLogEntry_HTTPVersion { - PROTOCOL_UNSPECIFIED = 0, - HTTP10 = 1, - HTTP11 = 2, - HTTP2 = 3, - HTTP3 = 4, -} +export const _envoy_data_accesslog_v3_HTTPAccessLogEntry_HTTPVersion = { + PROTOCOL_UNSPECIFIED: 'PROTOCOL_UNSPECIFIED', + HTTP10: 'HTTP10', + HTTP11: 'HTTP11', + HTTP2: 'HTTP2', + HTTP3: 'HTTP3', +} as const; + +/** + * HTTP version + */ +export type _envoy_data_accesslog_v3_HTTPAccessLogEntry_HTTPVersion = + | 'PROTOCOL_UNSPECIFIED' + | 0 + | 'HTTP10' + | 1 + | 'HTTP11' + | 2 + | 'HTTP2' + | 3 + | 'HTTP3' + | 4 + +/** + * HTTP version + */ +export type _envoy_data_accesslog_v3_HTTPAccessLogEntry_HTTPVersion__Output = typeof _envoy_data_accesslog_v3_HTTPAccessLogEntry_HTTPVersion[keyof typeof _envoy_data_accesslog_v3_HTTPAccessLogEntry_HTTPVersion] export interface HTTPAccessLogEntry { /** * Common properties shared by all Envoy access logs. */ 'common_properties'?: (_envoy_data_accesslog_v3_AccessLogCommon | null); - 'protocol_version'?: (_envoy_data_accesslog_v3_HTTPAccessLogEntry_HTTPVersion | keyof typeof _envoy_data_accesslog_v3_HTTPAccessLogEntry_HTTPVersion); + 'protocol_version'?: (_envoy_data_accesslog_v3_HTTPAccessLogEntry_HTTPVersion); /** * Description of the incoming HTTP request. */ @@ -38,7 +58,7 @@ export interface HTTPAccessLogEntry__Output { * Common properties shared by all Envoy access logs. */ 'common_properties': (_envoy_data_accesslog_v3_AccessLogCommon__Output | null); - 'protocol_version': (keyof typeof _envoy_data_accesslog_v3_HTTPAccessLogEntry_HTTPVersion); + 'protocol_version': (_envoy_data_accesslog_v3_HTTPAccessLogEntry_HTTPVersion__Output); /** * Description of the incoming HTTP request. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/HTTPRequestProperties.ts b/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/HTTPRequestProperties.ts index 9e145503c..f1271ba16 100644 --- a/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/HTTPRequestProperties.ts +++ b/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/HTTPRequestProperties.ts @@ -1,6 +1,6 @@ // Original file: deps/envoy-api/envoy/data/accesslog/v3/accesslog.proto -import type { RequestMethod as _envoy_config_core_v3_RequestMethod } from '../../../../envoy/config/core/v3/RequestMethod'; +import type { RequestMethod as _envoy_config_core_v3_RequestMethod, RequestMethod__Output as _envoy_config_core_v3_RequestMethod__Output } from '../../../../envoy/config/core/v3/RequestMethod'; import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; import type { Long } from '@grpc/proto-loader'; @@ -11,7 +11,7 @@ export interface HTTPRequestProperties { /** * The request method (RFC 7231/2616). */ - 'request_method'?: (_envoy_config_core_v3_RequestMethod | keyof typeof _envoy_config_core_v3_RequestMethod); + 'request_method'?: (_envoy_config_core_v3_RequestMethod); /** * The scheme portion of the incoming request URI. */ @@ -90,7 +90,7 @@ export interface HTTPRequestProperties__Output { /** * The request method (RFC 7231/2616). */ - 'request_method': (keyof typeof _envoy_config_core_v3_RequestMethod); + 'request_method': (_envoy_config_core_v3_RequestMethod__Output); /** * The scheme portion of the incoming request URI. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/ResponseFlags.ts b/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/ResponseFlags.ts index ec45824b3..f42e11ee3 100644 --- a/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/ResponseFlags.ts +++ b/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/ResponseFlags.ts @@ -6,20 +6,37 @@ /** * Reasons why the request was unauthorized */ -export enum _envoy_data_accesslog_v3_ResponseFlags_Unauthorized_Reason { - REASON_UNSPECIFIED = 0, +export const _envoy_data_accesslog_v3_ResponseFlags_Unauthorized_Reason = { + REASON_UNSPECIFIED: 'REASON_UNSPECIFIED', /** * The request was denied by the external authorization service. */ - EXTERNAL_SERVICE = 1, -} + EXTERNAL_SERVICE: 'EXTERNAL_SERVICE', +} as const; + +/** + * Reasons why the request was unauthorized + */ +export type _envoy_data_accesslog_v3_ResponseFlags_Unauthorized_Reason = + | 'REASON_UNSPECIFIED' + | 0 + /** + * The request was denied by the external authorization service. + */ + | 'EXTERNAL_SERVICE' + | 1 + +/** + * Reasons why the request was unauthorized + */ +export type _envoy_data_accesslog_v3_ResponseFlags_Unauthorized_Reason__Output = typeof _envoy_data_accesslog_v3_ResponseFlags_Unauthorized_Reason[keyof typeof _envoy_data_accesslog_v3_ResponseFlags_Unauthorized_Reason] export interface _envoy_data_accesslog_v3_ResponseFlags_Unauthorized { - 'reason'?: (_envoy_data_accesslog_v3_ResponseFlags_Unauthorized_Reason | keyof typeof _envoy_data_accesslog_v3_ResponseFlags_Unauthorized_Reason); + 'reason'?: (_envoy_data_accesslog_v3_ResponseFlags_Unauthorized_Reason); } export interface _envoy_data_accesslog_v3_ResponseFlags_Unauthorized__Output { - 'reason': (keyof typeof _envoy_data_accesslog_v3_ResponseFlags_Unauthorized_Reason); + 'reason': (_envoy_data_accesslog_v3_ResponseFlags_Unauthorized_Reason__Output); } /** diff --git a/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/TLSProperties.ts b/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/TLSProperties.ts index 106d24d09..ddeb9a1ae 100644 --- a/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/TLSProperties.ts +++ b/packages/grpc-js-xds/src/generated/envoy/data/accesslog/v3/TLSProperties.ts @@ -44,13 +44,27 @@ export interface _envoy_data_accesslog_v3_TLSProperties_CertificateProperties_Su // Original file: deps/envoy-api/envoy/data/accesslog/v3/accesslog.proto -export enum _envoy_data_accesslog_v3_TLSProperties_TLSVersion { - VERSION_UNSPECIFIED = 0, - TLSv1 = 1, - TLSv1_1 = 2, - TLSv1_2 = 3, - TLSv1_3 = 4, -} +export const _envoy_data_accesslog_v3_TLSProperties_TLSVersion = { + VERSION_UNSPECIFIED: 'VERSION_UNSPECIFIED', + TLSv1: 'TLSv1', + TLSv1_1: 'TLSv1_1', + TLSv1_2: 'TLSv1_2', + TLSv1_3: 'TLSv1_3', +} as const; + +export type _envoy_data_accesslog_v3_TLSProperties_TLSVersion = + | 'VERSION_UNSPECIFIED' + | 0 + | 'TLSv1' + | 1 + | 'TLSv1_1' + | 2 + | 'TLSv1_2' + | 3 + | 'TLSv1_3' + | 4 + +export type _envoy_data_accesslog_v3_TLSProperties_TLSVersion__Output = typeof _envoy_data_accesslog_v3_TLSProperties_TLSVersion[keyof typeof _envoy_data_accesslog_v3_TLSProperties_TLSVersion] /** * Properties of a negotiated TLS connection. @@ -60,7 +74,7 @@ export interface TLSProperties { /** * Version of TLS that was negotiated. */ - 'tls_version'?: (_envoy_data_accesslog_v3_TLSProperties_TLSVersion | keyof typeof _envoy_data_accesslog_v3_TLSProperties_TLSVersion); + 'tls_version'?: (_envoy_data_accesslog_v3_TLSProperties_TLSVersion); /** * TLS cipher suite negotiated during handshake. The value is a * four-digit hex code defined by the IANA TLS Cipher Suite Registry @@ -99,7 +113,7 @@ export interface TLSProperties__Output { /** * Version of TLS that was negotiated. */ - 'tls_version': (keyof typeof _envoy_data_accesslog_v3_TLSProperties_TLSVersion); + 'tls_version': (_envoy_data_accesslog_v3_TLSProperties_TLSVersion__Output); /** * TLS cipher suite negotiated during handshake. The value is a * four-digit hex code defined by the IANA TLS Cipher Suite Registry diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/common/fault/v3/FaultDelay.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/common/fault/v3/FaultDelay.ts index bec0403e4..e070ae913 100644 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/common/fault/v3/FaultDelay.ts +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/common/fault/v3/FaultDelay.ts @@ -5,12 +5,21 @@ import type { FractionalPercent as _envoy_type_v3_FractionalPercent, FractionalP // Original file: deps/envoy-api/envoy/extensions/filters/common/fault/v3/fault.proto -export enum _envoy_extensions_filters_common_fault_v3_FaultDelay_FaultDelayType { +export const _envoy_extensions_filters_common_fault_v3_FaultDelay_FaultDelayType = { /** * Unused and deprecated. */ - FIXED = 0, -} + FIXED: 'FIXED', +} as const; + +export type _envoy_extensions_filters_common_fault_v3_FaultDelay_FaultDelayType = + /** + * Unused and deprecated. + */ + | 'FIXED' + | 0 + +export type _envoy_extensions_filters_common_fault_v3_FaultDelay_FaultDelayType__Output = typeof _envoy_extensions_filters_common_fault_v3_FaultDelay_FaultDelayType[keyof typeof _envoy_extensions_filters_common_fault_v3_FaultDelay_FaultDelayType] /** * Fault delays are controlled via an HTTP header (if applicable). See the diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpConnectionManager.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpConnectionManager.ts index 1b4f36fd8..1a452635c 100644 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpConnectionManager.ts +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpConnectionManager.ts @@ -24,7 +24,7 @@ import type { PathTransformation as _envoy_type_http_v3_PathTransformation, Path // Original file: deps/envoy-api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto -export enum _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_CodecType { +export const _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_CodecType = { /** * For every new connection, the connection manager will determine which * codec to use. This mode supports both ALPN for TLS listeners as well as @@ -32,24 +32,56 @@ export enum _envoy_extensions_filters_network_http_connection_manager_v3_HttpCon * is preferred, otherwise protocol inference is used. In almost all cases, * this is the right option to choose for this setting. */ - AUTO = 0, + AUTO: 'AUTO', /** * The connection manager will assume that the client is speaking HTTP/1.1. */ - HTTP1 = 1, + HTTP1: 'HTTP1', /** * The connection manager will assume that the client is speaking HTTP/2 * (Envoy does not require HTTP/2 to take place over TLS or to use ALPN. * Prior knowledge is allowed). */ - HTTP2 = 2, + HTTP2: 'HTTP2', /** * [#not-implemented-hide:] QUIC implementation is not production ready yet. Use this enum with * caution to prevent accidental execution of QUIC code. I.e. `!= HTTP2` is no longer sufficient * to distinguish HTTP1 and HTTP2 traffic. */ - HTTP3 = 3, -} + HTTP3: 'HTTP3', +} as const; + +export type _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_CodecType = + /** + * For every new connection, the connection manager will determine which + * codec to use. This mode supports both ALPN for TLS listeners as well as + * protocol inference for plaintext listeners. If ALPN data is available, it + * is preferred, otherwise protocol inference is used. In almost all cases, + * this is the right option to choose for this setting. + */ + | 'AUTO' + | 0 + /** + * The connection manager will assume that the client is speaking HTTP/1.1. + */ + | 'HTTP1' + | 1 + /** + * The connection manager will assume that the client is speaking HTTP/2 + * (Envoy does not require HTTP/2 to take place over TLS or to use ALPN. + * Prior knowledge is allowed). + */ + | 'HTTP2' + | 2 + /** + * [#not-implemented-hide:] QUIC implementation is not production ready yet. Use this enum with + * caution to prevent accidental execution of QUIC code. I.e. `!= HTTP2` is no longer sufficient + * to distinguish HTTP1 and HTTP2 traffic. + */ + | 'HTTP3' + | 3 + +export type _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_CodecType__Output = typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_CodecType[keyof typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_CodecType] // Original file: deps/envoy-api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -57,32 +89,73 @@ export enum _envoy_extensions_filters_network_http_connection_manager_v3_HttpCon * How to handle the :ref:`config_http_conn_man_headers_x-forwarded-client-cert` (XFCC) HTTP * header. */ -export enum _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ForwardClientCertDetails { +export const _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ForwardClientCertDetails = { /** * Do not send the XFCC header to the next hop. This is the default value. */ - SANITIZE = 0, + SANITIZE: 'SANITIZE', /** * When the client connection is mTLS (Mutual TLS), forward the XFCC header * in the request. */ - FORWARD_ONLY = 1, + FORWARD_ONLY: 'FORWARD_ONLY', /** * When the client connection is mTLS, append the client certificate * information to the request’s XFCC header and forward it. */ - APPEND_FORWARD = 2, + APPEND_FORWARD: 'APPEND_FORWARD', /** * When the client connection is mTLS, reset the XFCC header with the client * certificate information and send it to the next hop. */ - SANITIZE_SET = 3, + SANITIZE_SET: 'SANITIZE_SET', /** * Always forward the XFCC header in the request, regardless of whether the * client connection is mTLS. */ - ALWAYS_FORWARD_ONLY = 4, -} + ALWAYS_FORWARD_ONLY: 'ALWAYS_FORWARD_ONLY', +} as const; + +/** + * How to handle the :ref:`config_http_conn_man_headers_x-forwarded-client-cert` (XFCC) HTTP + * header. + */ +export type _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ForwardClientCertDetails = + /** + * Do not send the XFCC header to the next hop. This is the default value. + */ + | 'SANITIZE' + | 0 + /** + * When the client connection is mTLS (Mutual TLS), forward the XFCC header + * in the request. + */ + | 'FORWARD_ONLY' + | 1 + /** + * When the client connection is mTLS, append the client certificate + * information to the request’s XFCC header and forward it. + */ + | 'APPEND_FORWARD' + | 2 + /** + * When the client connection is mTLS, reset the XFCC header with the client + * certificate information and send it to the next hop. + */ + | 'SANITIZE_SET' + | 3 + /** + * Always forward the XFCC header in the request, regardless of whether the + * client connection is mTLS. + */ + | 'ALWAYS_FORWARD_ONLY' + | 4 + +/** + * How to handle the :ref:`config_http_conn_man_headers_x-forwarded-client-cert` (XFCC) HTTP + * header. + */ +export type _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ForwardClientCertDetails__Output = typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ForwardClientCertDetails[keyof typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ForwardClientCertDetails] export interface _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_HcmAccessLogOptions { /** @@ -162,16 +235,30 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Ht // Original file: deps/envoy-api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto -export enum _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_OperationName { +export const _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_OperationName = { /** * The HTTP listener is used for ingress/incoming requests. */ - INGRESS = 0, + INGRESS: 'INGRESS', /** * The HTTP listener is used for egress/outgoing requests. */ - EGRESS = 1, -} + EGRESS: 'EGRESS', +} as const; + +export type _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_OperationName = + /** + * The HTTP listener is used for ingress/incoming requests. + */ + | 'INGRESS' + | 0 + /** + * The HTTP listener is used for egress/outgoing requests. + */ + | 'EGRESS' + | 1 + +export type _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_OperationName__Output = typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_OperationName[keyof typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_OperationName] /** * [#not-implemented-hide:] Transformations that apply to path headers. Transformations are applied @@ -253,22 +340,22 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Ht * Determines the action for request that contain %2F, %2f, %5C or %5c sequences in the URI path. * This operation occurs before URL normalization and the merge slashes transformations if they were enabled. */ -export enum _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_PathWithEscapedSlashesAction { +export const _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_PathWithEscapedSlashesAction = { /** * Default behavior specific to implementation (i.e. Envoy) of this configuration option. * Envoy, by default, takes the KEEP_UNCHANGED action. * NOTE: the implementation may change the default behavior at-will. */ - IMPLEMENTATION_SPECIFIC_DEFAULT = 0, + IMPLEMENTATION_SPECIFIC_DEFAULT: 'IMPLEMENTATION_SPECIFIC_DEFAULT', /** * Keep escaped slashes. */ - KEEP_UNCHANGED = 1, + KEEP_UNCHANGED: 'KEEP_UNCHANGED', /** * Reject client request with the 400 status. gRPC requests will be rejected with the INTERNAL (13) error code. * The "httpN.downstream_rq_failed_path_normalization" counter is incremented for each rejected request. */ - REJECT_REQUEST = 2, + REJECT_REQUEST: 'REJECT_REQUEST', /** * Unescape %2F and %5C sequences and redirect request to the new path if these sequences were present. * Redirect occurs after path normalization and merge slashes transformations if they were configured. @@ -278,14 +365,62 @@ export enum _envoy_extensions_filters_network_http_connection_manager_v3_HttpCon * The "httpN.downstream_rq_redirected_with_normalized_path" counter is incremented for each * redirected request. */ - UNESCAPE_AND_REDIRECT = 3, + UNESCAPE_AND_REDIRECT: 'UNESCAPE_AND_REDIRECT', /** * Unescape %2F and %5C sequences. * Note: this option should not be enabled if intermediaries perform path based access control as * it may lead to path confusion vulnerabilities. */ - UNESCAPE_AND_FORWARD = 4, -} + UNESCAPE_AND_FORWARD: 'UNESCAPE_AND_FORWARD', +} as const; + +/** + * Determines the action for request that contain %2F, %2f, %5C or %5c sequences in the URI path. + * This operation occurs before URL normalization and the merge slashes transformations if they were enabled. + */ +export type _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_PathWithEscapedSlashesAction = + /** + * Default behavior specific to implementation (i.e. Envoy) of this configuration option. + * Envoy, by default, takes the KEEP_UNCHANGED action. + * NOTE: the implementation may change the default behavior at-will. + */ + | 'IMPLEMENTATION_SPECIFIC_DEFAULT' + | 0 + /** + * Keep escaped slashes. + */ + | 'KEEP_UNCHANGED' + | 1 + /** + * Reject client request with the 400 status. gRPC requests will be rejected with the INTERNAL (13) error code. + * The "httpN.downstream_rq_failed_path_normalization" counter is incremented for each rejected request. + */ + | 'REJECT_REQUEST' + | 2 + /** + * Unescape %2F and %5C sequences and redirect request to the new path if these sequences were present. + * Redirect occurs after path normalization and merge slashes transformations if they were configured. + * NOTE: gRPC requests will be rejected with the INTERNAL (13) error code. + * This option minimizes possibility of path confusion exploits by forcing request with unescaped slashes to + * traverse all parties: downstream client, intermediate proxies, Envoy and upstream server. + * The "httpN.downstream_rq_redirected_with_normalized_path" counter is incremented for each + * redirected request. + */ + | 'UNESCAPE_AND_REDIRECT' + | 3 + /** + * Unescape %2F and %5C sequences. + * Note: this option should not be enabled if intermediaries perform path based access control as + * it may lead to path confusion vulnerabilities. + */ + | 'UNESCAPE_AND_FORWARD' + | 4 + +/** + * Determines the action for request that contain %2F, %2f, %5C or %5c sequences in the URI path. + * This operation occurs before URL normalization and the merge slashes transformations if they were enabled. + */ +export type _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_PathWithEscapedSlashesAction__Output = typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_PathWithEscapedSlashesAction[keyof typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_PathWithEscapedSlashesAction] /** * Configures the manner in which the Proxy-Status HTTP response header is @@ -405,22 +540,43 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Ht // Original file: deps/envoy-api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto -export enum _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ServerHeaderTransformation { +export const _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ServerHeaderTransformation = { /** * Overwrite any Server header with the contents of server_name. */ - OVERWRITE = 0, + OVERWRITE: 'OVERWRITE', /** * If no Server header is present, append Server server_name * If a Server header is present, pass it through. */ - APPEND_IF_ABSENT = 1, + APPEND_IF_ABSENT: 'APPEND_IF_ABSENT', /** * Pass through the value of the server header, and do not append a header * if none is present. */ - PASS_THROUGH = 2, -} + PASS_THROUGH: 'PASS_THROUGH', +} as const; + +export type _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ServerHeaderTransformation = + /** + * Overwrite any Server header with the contents of server_name. + */ + | 'OVERWRITE' + | 0 + /** + * If no Server header is present, append Server server_name + * If a Server header is present, pass it through. + */ + | 'APPEND_IF_ABSENT' + | 1 + /** + * Pass through the value of the server header, and do not append a header + * if none is present. + */ + | 'PASS_THROUGH' + | 2 + +export type _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ServerHeaderTransformation__Output = typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ServerHeaderTransformation[keyof typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ServerHeaderTransformation] /** * [#next-free-field: 7] @@ -693,7 +849,7 @@ export interface HttpConnectionManager { /** * Supplies the type of codec that the connection manager should use. */ - 'codec_type'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_CodecType | keyof typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_CodecType); + 'codec_type'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_CodecType); /** * The human readable prefix to use when emitting statistics for the * connection manager. See the :ref:`statistics documentation ` for @@ -781,7 +937,7 @@ export interface HttpConnectionManager { * How to handle the :ref:`config_http_conn_man_headers_x-forwarded-client-cert` (XFCC) HTTP * header. */ - 'forward_client_cert_details'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ForwardClientCertDetails | keyof typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ForwardClientCertDetails); + 'forward_client_cert_details'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ForwardClientCertDetails); /** * This field is valid only when :ref:`forward_client_cert_details * ` @@ -981,7 +1137,7 @@ export interface HttpConnectionManager { * By default, Envoy will overwrite the header with the value specified in * server_name. */ - 'server_header_transformation'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ServerHeaderTransformation | keyof typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ServerHeaderTransformation); + 'server_header_transformation'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ServerHeaderTransformation); /** * Additional settings for HTTP requests handled by the connection manager. These will be * applicable to both HTTP1 and HTTP2 requests. @@ -1092,7 +1248,7 @@ export interface HttpConnectionManager { * :ref:`header validation configuration ` * is present.] */ - 'path_with_escaped_slashes_action'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_PathWithEscapedSlashesAction | keyof typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_PathWithEscapedSlashesAction); + 'path_with_escaped_slashes_action'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_PathWithEscapedSlashesAction); /** * The configuration for the original IP detection extensions. * @@ -1190,6 +1346,7 @@ export interface HttpConnectionManager { * Note that if both this field and :ref:`access_log_flush_interval * ` * are specified, the former (deprecated field) is ignored. + * @deprecated */ 'access_log_flush_interval'?: (_google_protobuf_Duration | null); /** @@ -1200,6 +1357,7 @@ export interface HttpConnectionManager { * Note that if both this field and :ref:`flush_access_log_on_new_request * ` * are specified, the former (deprecated field) is ignored. + * @deprecated */ 'flush_access_log_on_new_request'?: (boolean); /** @@ -1217,7 +1375,7 @@ export interface HttpConnectionManager__Output { /** * Supplies the type of codec that the connection manager should use. */ - 'codec_type': (keyof typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_CodecType); + 'codec_type': (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_CodecType__Output); /** * The human readable prefix to use when emitting statistics for the * connection manager. See the :ref:`statistics documentation ` for @@ -1305,7 +1463,7 @@ export interface HttpConnectionManager__Output { * How to handle the :ref:`config_http_conn_man_headers_x-forwarded-client-cert` (XFCC) HTTP * header. */ - 'forward_client_cert_details': (keyof typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ForwardClientCertDetails); + 'forward_client_cert_details': (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ForwardClientCertDetails__Output); /** * This field is valid only when :ref:`forward_client_cert_details * ` @@ -1505,7 +1663,7 @@ export interface HttpConnectionManager__Output { * By default, Envoy will overwrite the header with the value specified in * server_name. */ - 'server_header_transformation': (keyof typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ServerHeaderTransformation); + 'server_header_transformation': (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ServerHeaderTransformation__Output); /** * Additional settings for HTTP requests handled by the connection manager. These will be * applicable to both HTTP1 and HTTP2 requests. @@ -1616,7 +1774,7 @@ export interface HttpConnectionManager__Output { * :ref:`header validation configuration ` * is present.] */ - 'path_with_escaped_slashes_action': (keyof typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_PathWithEscapedSlashesAction); + 'path_with_escaped_slashes_action': (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_PathWithEscapedSlashesAction__Output); /** * The configuration for the original IP detection extensions. * @@ -1714,6 +1872,7 @@ export interface HttpConnectionManager__Output { * Note that if both this field and :ref:`access_log_flush_interval * ` * are specified, the former (deprecated field) is ignored. + * @deprecated */ 'access_log_flush_interval': (_google_protobuf_Duration__Output | null); /** @@ -1724,6 +1883,7 @@ export interface HttpConnectionManager__Output { * Note that if both this field and :ref:`flush_access_log_on_new_request * ` * are specified, the former (deprecated field) is ignored. + * @deprecated */ 'flush_access_log_on_new_request': (boolean); /** diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/load_balancing_policies/common/v3/LocalityLbConfig.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/load_balancing_policies/common/v3/LocalityLbConfig.ts index d6fecd36b..4e3d9659e 100644 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/load_balancing_policies/common/v3/LocalityLbConfig.ts +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/load_balancing_policies/common/v3/LocalityLbConfig.ts @@ -2,7 +2,6 @@ import type { Percent as _envoy_type_v3_Percent, Percent__Output as _envoy_type_v3_Percent__Output } from '../../../../../envoy/type/v3/Percent'; import type { UInt64Value as _google_protobuf_UInt64Value, UInt64Value__Output as _google_protobuf_UInt64Value__Output } from '../../../../../google/protobuf/UInt64Value'; -import type { Long } from '@grpc/proto-loader'; /** * Configuration for :ref:`locality weighted load balancing diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/load_balancing_policies/ring_hash/v3/RingHash.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/load_balancing_policies/ring_hash/v3/RingHash.ts index 4e2a73031..d8156fe0f 100644 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/load_balancing_policies/ring_hash/v3/RingHash.ts +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/load_balancing_policies/ring_hash/v3/RingHash.ts @@ -4,29 +4,55 @@ import type { UInt64Value as _google_protobuf_UInt64Value, UInt64Value__Output a import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../../google/protobuf/UInt32Value'; import type { ConsistentHashingLbConfig as _envoy_extensions_load_balancing_policies_common_v3_ConsistentHashingLbConfig, ConsistentHashingLbConfig__Output as _envoy_extensions_load_balancing_policies_common_v3_ConsistentHashingLbConfig__Output } from '../../../../../envoy/extensions/load_balancing_policies/common/v3/ConsistentHashingLbConfig'; import type { _envoy_extensions_load_balancing_policies_common_v3_LocalityLbConfig_LocalityWeightedLbConfig, _envoy_extensions_load_balancing_policies_common_v3_LocalityLbConfig_LocalityWeightedLbConfig__Output } from '../../../../../envoy/extensions/load_balancing_policies/common/v3/LocalityLbConfig'; -import type { Long } from '@grpc/proto-loader'; // Original file: deps/envoy-api/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.proto /** * The hash function used to hash hosts onto the ketama ring. */ -export enum _envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_HashFunction { +export const _envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_HashFunction = { /** * Currently defaults to XX_HASH. */ - DEFAULT_HASH = 0, + DEFAULT_HASH: 'DEFAULT_HASH', /** * Use `xxHash `_. */ - XX_HASH = 1, + XX_HASH: 'XX_HASH', /** * Use `MurmurHash2 `_, this is compatible with * std:hash in GNU libstdc++ 3.4.20 or above. This is typically the case when compiled * on Linux and not macOS. */ - MURMUR_HASH_2 = 2, -} + MURMUR_HASH_2: 'MURMUR_HASH_2', +} as const; + +/** + * The hash function used to hash hosts onto the ketama ring. + */ +export type _envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_HashFunction = + /** + * Currently defaults to XX_HASH. + */ + | 'DEFAULT_HASH' + | 0 + /** + * Use `xxHash `_. + */ + | 'XX_HASH' + | 1 + /** + * Use `MurmurHash2 `_, this is compatible with + * std:hash in GNU libstdc++ 3.4.20 or above. This is typically the case when compiled + * on Linux and not macOS. + */ + | 'MURMUR_HASH_2' + | 2 + +/** + * The hash function used to hash hosts onto the ketama ring. + */ +export type _envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_HashFunction__Output = typeof _envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_HashFunction[keyof typeof _envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_HashFunction] /** * This configuration allows the built-in RING_HASH LB policy to be configured via the LB policy @@ -39,7 +65,7 @@ export interface RingHash { * The hash function used to hash hosts onto the ketama ring. The value defaults to * :ref:`XX_HASH`. */ - 'hash_function'?: (_envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_HashFunction | keyof typeof _envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_HashFunction); + 'hash_function'?: (_envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_HashFunction); /** * Minimum hash ring size. The larger the ring is (that is, the more hashes there are for each * provided host) the better the request distribution will reflect the desired weights. Defaults @@ -60,6 +86,7 @@ export interface RingHash { * ..note:: * This is deprecated and please use :ref:`consistent_hashing_lb_config * ` instead. + * @deprecated */ 'use_hostname_for_hashing'?: (boolean); /** @@ -83,6 +110,7 @@ export interface RingHash { * ..note:: * This is deprecated and please use :ref:`consistent_hashing_lb_config * ` instead. + * @deprecated */ 'hash_balance_factor'?: (_google_protobuf_UInt32Value | null); /** @@ -106,7 +134,7 @@ export interface RingHash__Output { * The hash function used to hash hosts onto the ketama ring. The value defaults to * :ref:`XX_HASH`. */ - 'hash_function': (keyof typeof _envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_HashFunction); + 'hash_function': (_envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_HashFunction__Output); /** * Minimum hash ring size. The larger the ring is (that is, the more hashes there are for each * provided host) the better the request distribution will reflect the desired weights. Defaults @@ -127,6 +155,7 @@ export interface RingHash__Output { * ..note:: * This is deprecated and please use :ref:`consistent_hashing_lb_config * ` instead. + * @deprecated */ 'use_hostname_for_hashing': (boolean); /** @@ -150,6 +179,7 @@ export interface RingHash__Output { * ..note:: * This is deprecated and please use :ref:`consistent_hashing_lb_config * ` instead. + * @deprecated */ 'hash_balance_factor': (_google_protobuf_UInt32Value__Output | null); /** diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/CertificateProviderPluginInstance.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/CertificateProviderPluginInstance.ts deleted file mode 100644 index 3a3100f55..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/CertificateProviderPluginInstance.ts +++ /dev/null @@ -1,52 +0,0 @@ -// Original file: deps/envoy-api/envoy/extensions/transport_sockets/tls/v3/common.proto - - -/** - * Indicates a certificate to be obtained from a named CertificateProvider plugin instance. - * The plugin instances are defined in the client's bootstrap file. - * The plugin allows certificates to be fetched/refreshed over the network asynchronously with - * respect to the TLS handshake. - * [#not-implemented-hide:] - */ -export interface CertificateProviderPluginInstance { - /** - * Provider instance name. If not present, defaults to "default". - * - * Instance names should generally be defined not in terms of the underlying provider - * implementation (e.g., "file_watcher") but rather in terms of the function of the - * certificates (e.g., "foo_deployment_identity"). - */ - 'instance_name'?: (string); - /** - * Opaque name used to specify certificate instances or types. For example, "ROOTCA" to specify - * a root-certificate (validation context) or "example.com" to specify a certificate for a - * particular domain. Not all provider instances will actually use this field, so the value - * defaults to the empty string. - */ - 'certificate_name'?: (string); -} - -/** - * Indicates a certificate to be obtained from a named CertificateProvider plugin instance. - * The plugin instances are defined in the client's bootstrap file. - * The plugin allows certificates to be fetched/refreshed over the network asynchronously with - * respect to the TLS handshake. - * [#not-implemented-hide:] - */ -export interface CertificateProviderPluginInstance__Output { - /** - * Provider instance name. If not present, defaults to "default". - * - * Instance names should generally be defined not in terms of the underlying provider - * implementation (e.g., "file_watcher") but rather in terms of the function of the - * certificates (e.g., "foo_deployment_identity"). - */ - 'instance_name': (string); - /** - * Opaque name used to specify certificate instances or types. For example, "ROOTCA" to specify - * a root-certificate (validation context) or "example.com" to specify a certificate for a - * particular domain. Not all provider instances will actually use this field, so the value - * defaults to the empty string. - */ - 'certificate_name': (string); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/CertificateValidationContext.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/CertificateValidationContext.ts deleted file mode 100644 index 379320086..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/CertificateValidationContext.ts +++ /dev/null @@ -1,372 +0,0 @@ -// Original file: deps/envoy-api/envoy/extensions/transport_sockets/tls/v3/common.proto - -import type { DataSource as _envoy_config_core_v3_DataSource, DataSource__Output as _envoy_config_core_v3_DataSource__Output } from '../../../../../envoy/config/core/v3/DataSource'; -import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../../google/protobuf/BoolValue'; -import type { StringMatcher as _envoy_type_matcher_v3_StringMatcher, StringMatcher__Output as _envoy_type_matcher_v3_StringMatcher__Output } from '../../../../../envoy/type/matcher/v3/StringMatcher'; -import type { WatchedDirectory as _envoy_config_core_v3_WatchedDirectory, WatchedDirectory__Output as _envoy_config_core_v3_WatchedDirectory__Output } from '../../../../../envoy/config/core/v3/WatchedDirectory'; -import type { TypedExtensionConfig as _envoy_config_core_v3_TypedExtensionConfig, TypedExtensionConfig__Output as _envoy_config_core_v3_TypedExtensionConfig__Output } from '../../../../../envoy/config/core/v3/TypedExtensionConfig'; -import type { CertificateProviderPluginInstance as _envoy_extensions_transport_sockets_tls_v3_CertificateProviderPluginInstance, CertificateProviderPluginInstance__Output as _envoy_extensions_transport_sockets_tls_v3_CertificateProviderPluginInstance__Output } from '../../../../../envoy/extensions/transport_sockets/tls/v3/CertificateProviderPluginInstance'; - -// Original file: deps/envoy-api/envoy/extensions/transport_sockets/tls/v3/common.proto - -/** - * Peer certificate verification mode. - */ -export enum _envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_TrustChainVerification { - /** - * Perform default certificate verification (e.g., against CA / verification lists) - */ - VERIFY_TRUST_CHAIN = 0, - /** - * Connections where the certificate fails verification will be permitted. - * For HTTP connections, the result of certificate verification can be used in route matching. ( - * see :ref:`validated ` ). - */ - ACCEPT_UNTRUSTED = 1, -} - -/** - * [#next-free-field: 14] - */ -export interface CertificateValidationContext { - /** - * TLS certificate data containing certificate authority certificates to use in verifying - * a presented peer certificate (e.g. server certificate for clusters or client certificate - * for listeners). If not specified and a peer certificate is presented it will not be - * verified. By default, a client certificate is optional, unless one of the additional - * options (:ref:`require_client_certificate - * `, - * :ref:`verify_certificate_spki - * `, - * :ref:`verify_certificate_hash - * `, or - * :ref:`match_subject_alt_names - * `) is also - * specified. - * - * It can optionally contain certificate revocation lists, in which case Envoy will verify - * that the presented peer certificate has not been revoked by one of the included CRLs. Note - * that if a CRL is provided for any certificate authority in a trust chain, a CRL must be - * provided for all certificate authorities in that chain. Failure to do so will result in - * verification failure for both revoked and unrevoked certificates from that chain. - * - * See :ref:`the TLS overview ` for a list of common - * system CA locations. - * - * If *trusted_ca* is a filesystem path, a watch will be added to the parent - * directory for any file moves to support rotation. This currently only - * applies to dynamic secrets, when the *CertificateValidationContext* is - * delivered via SDS. - * - * Only one of *trusted_ca* and *ca_certificate_provider_instance* may be specified. - * - * [#next-major-version: This field and watched_directory below should ideally be moved into a - * separate sub-message, since there's no point in specifying the latter field without this one.] - */ - 'trusted_ca'?: (_envoy_config_core_v3_DataSource | null); - /** - * An optional list of hex-encoded SHA-256 hashes. If specified, Envoy will verify that - * the SHA-256 of the DER-encoded presented certificate matches one of the specified values. - * - * A hex-encoded SHA-256 of the certificate can be generated with the following command: - * - * .. code-block:: bash - * - * $ openssl x509 -in path/to/client.crt -outform DER | openssl dgst -sha256 | cut -d" " -f2 - * df6ff72fe9116521268f6f2dd4966f51df479883fe7037b39f75916ac3049d1a - * - * A long hex-encoded and colon-separated SHA-256 (a.k.a. "fingerprint") of the certificate - * can be generated with the following command: - * - * .. code-block:: bash - * - * $ openssl x509 -in path/to/client.crt -noout -fingerprint -sha256 | cut -d"=" -f2 - * DF:6F:F7:2F:E9:11:65:21:26:8F:6F:2D:D4:96:6F:51:DF:47:98:83:FE:70:37:B3:9F:75:91:6A:C3:04:9D:1A - * - * Both of those formats are acceptable. - * - * When both: - * :ref:`verify_certificate_hash - * ` and - * :ref:`verify_certificate_spki - * ` are specified, - * a hash matching value from either of the lists will result in the certificate being accepted. - */ - 'verify_certificate_hash'?: (string)[]; - /** - * An optional list of base64-encoded SHA-256 hashes. If specified, Envoy will verify that the - * SHA-256 of the DER-encoded Subject Public Key Information (SPKI) of the presented certificate - * matches one of the specified values. - * - * A base64-encoded SHA-256 of the Subject Public Key Information (SPKI) of the certificate - * can be generated with the following command: - * - * .. code-block:: bash - * - * $ openssl x509 -in path/to/client.crt -noout -pubkey - * | openssl pkey -pubin -outform DER - * | openssl dgst -sha256 -binary - * | openssl enc -base64 - * NvqYIYSbgK2vCJpQhObf77vv+bQWtc5ek5RIOwPiC9A= - * - * This is the format used in HTTP Public Key Pinning. - * - * When both: - * :ref:`verify_certificate_hash - * ` and - * :ref:`verify_certificate_spki - * ` are specified, - * a hash matching value from either of the lists will result in the certificate being accepted. - * - * .. attention:: - * - * This option is preferred over :ref:`verify_certificate_hash - * `, - * because SPKI is tied to a private key, so it doesn't change when the certificate - * is renewed using the same private key. - */ - 'verify_certificate_spki'?: (string)[]; - /** - * [#not-implemented-hide:] Must present signed certificate time-stamp. - */ - 'require_signed_certificate_timestamp'?: (_google_protobuf_BoolValue | null); - /** - * An optional `certificate revocation list - * `_ - * (in PEM format). If specified, Envoy will verify that the presented peer - * certificate has not been revoked by this CRL. If this DataSource contains - * multiple CRLs, all of them will be used. Note that if a CRL is provided - * for any certificate authority in a trust chain, a CRL must be provided - * for all certificate authorities in that chain. Failure to do so will - * result in verification failure for both revoked and unrevoked certificates - * from that chain. - */ - 'crl'?: (_envoy_config_core_v3_DataSource | null); - /** - * If specified, Envoy will not reject expired certificates. - */ - 'allow_expired_certificate'?: (boolean); - /** - * An optional list of Subject Alternative name matchers. If specified, Envoy will verify that the - * Subject Alternative Name of the presented certificate matches one of the specified matchers. - * - * When a certificate has wildcard DNS SAN entries, to match a specific client, it should be - * configured with exact match type in the :ref:`string matcher `. - * For example if the certificate has "\*.example.com" as DNS SAN entry, to allow only "api.example.com", - * it should be configured as shown below. - * - * .. code-block:: yaml - * - * match_subject_alt_names: - * exact: "api.example.com" - * - * .. attention:: - * - * Subject Alternative Names are easily spoofable and verifying only them is insecure, - * therefore this option must be used together with :ref:`trusted_ca - * `. - */ - 'match_subject_alt_names'?: (_envoy_type_matcher_v3_StringMatcher)[]; - /** - * Certificate trust chain verification mode. - */ - 'trust_chain_verification'?: (_envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_TrustChainVerification | keyof typeof _envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_TrustChainVerification); - /** - * If specified, updates of a file-based *trusted_ca* source will be triggered - * by this watch. This allows explicit control over the path watched, by - * default the parent directory of the filesystem path in *trusted_ca* is - * watched if this field is not specified. This only applies when a - * *CertificateValidationContext* is delivered by SDS with references to - * filesystem paths. See the :ref:`SDS key rotation ` - * documentation for further details. - */ - 'watched_directory'?: (_envoy_config_core_v3_WatchedDirectory | null); - /** - * The configuration of an extension specific certificate validator. - * If specified, all validation is done by the specified validator, - * and the behavior of all other validation settings is defined by the specified validator (and may be entirely ignored, unused, and unvalidated). - * Refer to the documentation for the specified validator. If you do not want a custom validation algorithm, do not set this field. - * [#extension-category: envoy.tls.cert_validator] - */ - 'custom_validator_config'?: (_envoy_config_core_v3_TypedExtensionConfig | null); - /** - * Certificate provider instance for fetching TLS certificates. - * - * Only one of *trusted_ca* and *ca_certificate_provider_instance* may be specified. - * [#not-implemented-hide:] - */ - 'ca_certificate_provider_instance'?: (_envoy_extensions_transport_sockets_tls_v3_CertificateProviderPluginInstance | null); -} - -/** - * [#next-free-field: 14] - */ -export interface CertificateValidationContext__Output { - /** - * TLS certificate data containing certificate authority certificates to use in verifying - * a presented peer certificate (e.g. server certificate for clusters or client certificate - * for listeners). If not specified and a peer certificate is presented it will not be - * verified. By default, a client certificate is optional, unless one of the additional - * options (:ref:`require_client_certificate - * `, - * :ref:`verify_certificate_spki - * `, - * :ref:`verify_certificate_hash - * `, or - * :ref:`match_subject_alt_names - * `) is also - * specified. - * - * It can optionally contain certificate revocation lists, in which case Envoy will verify - * that the presented peer certificate has not been revoked by one of the included CRLs. Note - * that if a CRL is provided for any certificate authority in a trust chain, a CRL must be - * provided for all certificate authorities in that chain. Failure to do so will result in - * verification failure for both revoked and unrevoked certificates from that chain. - * - * See :ref:`the TLS overview ` for a list of common - * system CA locations. - * - * If *trusted_ca* is a filesystem path, a watch will be added to the parent - * directory for any file moves to support rotation. This currently only - * applies to dynamic secrets, when the *CertificateValidationContext* is - * delivered via SDS. - * - * Only one of *trusted_ca* and *ca_certificate_provider_instance* may be specified. - * - * [#next-major-version: This field and watched_directory below should ideally be moved into a - * separate sub-message, since there's no point in specifying the latter field without this one.] - */ - 'trusted_ca': (_envoy_config_core_v3_DataSource__Output | null); - /** - * An optional list of hex-encoded SHA-256 hashes. If specified, Envoy will verify that - * the SHA-256 of the DER-encoded presented certificate matches one of the specified values. - * - * A hex-encoded SHA-256 of the certificate can be generated with the following command: - * - * .. code-block:: bash - * - * $ openssl x509 -in path/to/client.crt -outform DER | openssl dgst -sha256 | cut -d" " -f2 - * df6ff72fe9116521268f6f2dd4966f51df479883fe7037b39f75916ac3049d1a - * - * A long hex-encoded and colon-separated SHA-256 (a.k.a. "fingerprint") of the certificate - * can be generated with the following command: - * - * .. code-block:: bash - * - * $ openssl x509 -in path/to/client.crt -noout -fingerprint -sha256 | cut -d"=" -f2 - * DF:6F:F7:2F:E9:11:65:21:26:8F:6F:2D:D4:96:6F:51:DF:47:98:83:FE:70:37:B3:9F:75:91:6A:C3:04:9D:1A - * - * Both of those formats are acceptable. - * - * When both: - * :ref:`verify_certificate_hash - * ` and - * :ref:`verify_certificate_spki - * ` are specified, - * a hash matching value from either of the lists will result in the certificate being accepted. - */ - 'verify_certificate_hash': (string)[]; - /** - * An optional list of base64-encoded SHA-256 hashes. If specified, Envoy will verify that the - * SHA-256 of the DER-encoded Subject Public Key Information (SPKI) of the presented certificate - * matches one of the specified values. - * - * A base64-encoded SHA-256 of the Subject Public Key Information (SPKI) of the certificate - * can be generated with the following command: - * - * .. code-block:: bash - * - * $ openssl x509 -in path/to/client.crt -noout -pubkey - * | openssl pkey -pubin -outform DER - * | openssl dgst -sha256 -binary - * | openssl enc -base64 - * NvqYIYSbgK2vCJpQhObf77vv+bQWtc5ek5RIOwPiC9A= - * - * This is the format used in HTTP Public Key Pinning. - * - * When both: - * :ref:`verify_certificate_hash - * ` and - * :ref:`verify_certificate_spki - * ` are specified, - * a hash matching value from either of the lists will result in the certificate being accepted. - * - * .. attention:: - * - * This option is preferred over :ref:`verify_certificate_hash - * `, - * because SPKI is tied to a private key, so it doesn't change when the certificate - * is renewed using the same private key. - */ - 'verify_certificate_spki': (string)[]; - /** - * [#not-implemented-hide:] Must present signed certificate time-stamp. - */ - 'require_signed_certificate_timestamp': (_google_protobuf_BoolValue__Output | null); - /** - * An optional `certificate revocation list - * `_ - * (in PEM format). If specified, Envoy will verify that the presented peer - * certificate has not been revoked by this CRL. If this DataSource contains - * multiple CRLs, all of them will be used. Note that if a CRL is provided - * for any certificate authority in a trust chain, a CRL must be provided - * for all certificate authorities in that chain. Failure to do so will - * result in verification failure for both revoked and unrevoked certificates - * from that chain. - */ - 'crl': (_envoy_config_core_v3_DataSource__Output | null); - /** - * If specified, Envoy will not reject expired certificates. - */ - 'allow_expired_certificate': (boolean); - /** - * An optional list of Subject Alternative name matchers. If specified, Envoy will verify that the - * Subject Alternative Name of the presented certificate matches one of the specified matchers. - * - * When a certificate has wildcard DNS SAN entries, to match a specific client, it should be - * configured with exact match type in the :ref:`string matcher `. - * For example if the certificate has "\*.example.com" as DNS SAN entry, to allow only "api.example.com", - * it should be configured as shown below. - * - * .. code-block:: yaml - * - * match_subject_alt_names: - * exact: "api.example.com" - * - * .. attention:: - * - * Subject Alternative Names are easily spoofable and verifying only them is insecure, - * therefore this option must be used together with :ref:`trusted_ca - * `. - */ - 'match_subject_alt_names': (_envoy_type_matcher_v3_StringMatcher__Output)[]; - /** - * Certificate trust chain verification mode. - */ - 'trust_chain_verification': (keyof typeof _envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext_TrustChainVerification); - /** - * If specified, updates of a file-based *trusted_ca* source will be triggered - * by this watch. This allows explicit control over the path watched, by - * default the parent directory of the filesystem path in *trusted_ca* is - * watched if this field is not specified. This only applies when a - * *CertificateValidationContext* is delivered by SDS with references to - * filesystem paths. See the :ref:`SDS key rotation ` - * documentation for further details. - */ - 'watched_directory': (_envoy_config_core_v3_WatchedDirectory__Output | null); - /** - * The configuration of an extension specific certificate validator. - * If specified, all validation is done by the specified validator, - * and the behavior of all other validation settings is defined by the specified validator (and may be entirely ignored, unused, and unvalidated). - * Refer to the documentation for the specified validator. If you do not want a custom validation algorithm, do not set this field. - * [#extension-category: envoy.tls.cert_validator] - */ - 'custom_validator_config': (_envoy_config_core_v3_TypedExtensionConfig__Output | null); - /** - * Certificate provider instance for fetching TLS certificates. - * - * Only one of *trusted_ca* and *ca_certificate_provider_instance* may be specified. - * [#not-implemented-hide:] - */ - 'ca_certificate_provider_instance': (_envoy_extensions_transport_sockets_tls_v3_CertificateProviderPluginInstance__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/GenericSecret.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/GenericSecret.ts deleted file mode 100644 index b206fb13a..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/GenericSecret.ts +++ /dev/null @@ -1,17 +0,0 @@ -// Original file: deps/envoy-api/envoy/extensions/transport_sockets/tls/v3/secret.proto - -import type { DataSource as _envoy_config_core_v3_DataSource, DataSource__Output as _envoy_config_core_v3_DataSource__Output } from '../../../../../envoy/config/core/v3/DataSource'; - -export interface GenericSecret { - /** - * Secret of generic type and is available to filters. - */ - 'secret'?: (_envoy_config_core_v3_DataSource | null); -} - -export interface GenericSecret__Output { - /** - * Secret of generic type and is available to filters. - */ - 'secret': (_envoy_config_core_v3_DataSource__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/PrivateKeyProvider.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/PrivateKeyProvider.ts deleted file mode 100644 index b4a2ad933..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/PrivateKeyProvider.ts +++ /dev/null @@ -1,39 +0,0 @@ -// Original file: deps/envoy-api/envoy/extensions/transport_sockets/tls/v3/common.proto - -import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../../google/protobuf/Any'; - -/** - * BoringSSL private key method configuration. The private key methods are used for external - * (potentially asynchronous) signing and decryption operations. Some use cases for private key - * methods would be TPM support and TLS acceleration. - */ -export interface PrivateKeyProvider { - /** - * Private key method provider name. The name must match a - * supported private key method provider type. - */ - 'provider_name'?: (string); - 'typed_config'?: (_google_protobuf_Any | null); - /** - * Private key method provider specific configuration. - */ - 'config_type'?: "typed_config"; -} - -/** - * BoringSSL private key method configuration. The private key methods are used for external - * (potentially asynchronous) signing and decryption operations. Some use cases for private key - * methods would be TPM support and TLS acceleration. - */ -export interface PrivateKeyProvider__Output { - /** - * Private key method provider name. The name must match a - * supported private key method provider type. - */ - 'provider_name': (string); - 'typed_config'?: (_google_protobuf_Any__Output | null); - /** - * Private key method provider specific configuration. - */ - 'config_type': "typed_config"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/SdsSecretConfig.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/SdsSecretConfig.ts deleted file mode 100644 index 38b850c50..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/SdsSecretConfig.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Original file: deps/envoy-api/envoy/extensions/transport_sockets/tls/v3/secret.proto - -import type { ConfigSource as _envoy_config_core_v3_ConfigSource, ConfigSource__Output as _envoy_config_core_v3_ConfigSource__Output } from '../../../../../envoy/config/core/v3/ConfigSource'; - -export interface SdsSecretConfig { - /** - * Name by which the secret can be uniquely referred to. When both name and config are specified, - * then secret can be fetched and/or reloaded via SDS. When only name is specified, then secret - * will be loaded from static resources. - */ - 'name'?: (string); - 'sds_config'?: (_envoy_config_core_v3_ConfigSource | null); -} - -export interface SdsSecretConfig__Output { - /** - * Name by which the secret can be uniquely referred to. When both name and config are specified, - * then secret can be fetched and/or reloaded via SDS. When only name is specified, then secret - * will be loaded from static resources. - */ - 'name': (string); - 'sds_config': (_envoy_config_core_v3_ConfigSource__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/Secret.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/Secret.ts deleted file mode 100644 index c86957da5..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/Secret.ts +++ /dev/null @@ -1,36 +0,0 @@ -// Original file: deps/envoy-api/envoy/extensions/transport_sockets/tls/v3/secret.proto - -import type { TlsCertificate as _envoy_extensions_transport_sockets_tls_v3_TlsCertificate, TlsCertificate__Output as _envoy_extensions_transport_sockets_tls_v3_TlsCertificate__Output } from '../../../../../envoy/extensions/transport_sockets/tls/v3/TlsCertificate'; -import type { TlsSessionTicketKeys as _envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys, TlsSessionTicketKeys__Output as _envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys__Output } from '../../../../../envoy/extensions/transport_sockets/tls/v3/TlsSessionTicketKeys'; -import type { CertificateValidationContext as _envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext, CertificateValidationContext__Output as _envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext__Output } from '../../../../../envoy/extensions/transport_sockets/tls/v3/CertificateValidationContext'; -import type { GenericSecret as _envoy_extensions_transport_sockets_tls_v3_GenericSecret, GenericSecret__Output as _envoy_extensions_transport_sockets_tls_v3_GenericSecret__Output } from '../../../../../envoy/extensions/transport_sockets/tls/v3/GenericSecret'; - -/** - * [#next-free-field: 6] - */ -export interface Secret { - /** - * Name (FQDN, UUID, SPKI, SHA256, etc.) by which the secret can be uniquely referred to. - */ - 'name'?: (string); - 'tls_certificate'?: (_envoy_extensions_transport_sockets_tls_v3_TlsCertificate | null); - 'session_ticket_keys'?: (_envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys | null); - 'validation_context'?: (_envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext | null); - 'generic_secret'?: (_envoy_extensions_transport_sockets_tls_v3_GenericSecret | null); - 'type'?: "tls_certificate"|"session_ticket_keys"|"validation_context"|"generic_secret"; -} - -/** - * [#next-free-field: 6] - */ -export interface Secret__Output { - /** - * Name (FQDN, UUID, SPKI, SHA256, etc.) by which the secret can be uniquely referred to. - */ - 'name': (string); - 'tls_certificate'?: (_envoy_extensions_transport_sockets_tls_v3_TlsCertificate__Output | null); - 'session_ticket_keys'?: (_envoy_extensions_transport_sockets_tls_v3_TlsSessionTicketKeys__Output | null); - 'validation_context'?: (_envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext__Output | null); - 'generic_secret'?: (_envoy_extensions_transport_sockets_tls_v3_GenericSecret__Output | null); - 'type': "tls_certificate"|"session_ticket_keys"|"validation_context"|"generic_secret"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/TlsCertificate.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/TlsCertificate.ts deleted file mode 100644 index ce8046e95..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/TlsCertificate.ts +++ /dev/null @@ -1,127 +0,0 @@ -// Original file: deps/envoy-api/envoy/extensions/transport_sockets/tls/v3/common.proto - -import type { DataSource as _envoy_config_core_v3_DataSource, DataSource__Output as _envoy_config_core_v3_DataSource__Output } from '../../../../../envoy/config/core/v3/DataSource'; -import type { PrivateKeyProvider as _envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider, PrivateKeyProvider__Output as _envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider__Output } from '../../../../../envoy/extensions/transport_sockets/tls/v3/PrivateKeyProvider'; -import type { WatchedDirectory as _envoy_config_core_v3_WatchedDirectory, WatchedDirectory__Output as _envoy_config_core_v3_WatchedDirectory__Output } from '../../../../../envoy/config/core/v3/WatchedDirectory'; - -/** - * [#next-free-field: 8] - */ -export interface TlsCertificate { - /** - * The TLS certificate chain. - * - * If *certificate_chain* is a filesystem path, a watch will be added to the - * parent directory for any file moves to support rotation. This currently - * only applies to dynamic secrets, when the *TlsCertificate* is delivered via - * SDS. - */ - 'certificate_chain'?: (_envoy_config_core_v3_DataSource | null); - /** - * The TLS private key. - * - * If *private_key* is a filesystem path, a watch will be added to the parent - * directory for any file moves to support rotation. This currently only - * applies to dynamic secrets, when the *TlsCertificate* is delivered via SDS. - */ - 'private_key'?: (_envoy_config_core_v3_DataSource | null); - /** - * The password to decrypt the TLS private key. If this field is not set, it is assumed that the - * TLS private key is not password encrypted. - */ - 'password'?: (_envoy_config_core_v3_DataSource | null); - /** - * The OCSP response to be stapled with this certificate during the handshake. - * The response must be DER-encoded and may only be provided via ``filename`` or - * ``inline_bytes``. The response may pertain to only one certificate. - */ - 'ocsp_staple'?: (_envoy_config_core_v3_DataSource | null); - /** - * [#not-implemented-hide:] - */ - 'signed_certificate_timestamp'?: (_envoy_config_core_v3_DataSource)[]; - /** - * BoringSSL private key method provider. This is an alternative to :ref:`private_key - * ` field. This can't be - * marked as ``oneof`` due to API compatibility reasons. Setting both :ref:`private_key - * ` and - * :ref:`private_key_provider - * ` fields will result in an - * error. - */ - 'private_key_provider'?: (_envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider | null); - /** - * If specified, updates of file-based *certificate_chain* and *private_key* - * sources will be triggered by this watch. The certificate/key pair will be - * read together and validated for atomic read consistency (i.e. no - * intervening modification occurred between cert/key read, verified by file - * hash comparisons). This allows explicit control over the path watched, by - * default the parent directories of the filesystem paths in - * *certificate_chain* and *private_key* are watched if this field is not - * specified. This only applies when a *TlsCertificate* is delivered by SDS - * with references to filesystem paths. See the :ref:`SDS key rotation - * ` documentation for further details. - */ - 'watched_directory'?: (_envoy_config_core_v3_WatchedDirectory | null); -} - -/** - * [#next-free-field: 8] - */ -export interface TlsCertificate__Output { - /** - * The TLS certificate chain. - * - * If *certificate_chain* is a filesystem path, a watch will be added to the - * parent directory for any file moves to support rotation. This currently - * only applies to dynamic secrets, when the *TlsCertificate* is delivered via - * SDS. - */ - 'certificate_chain': (_envoy_config_core_v3_DataSource__Output | null); - /** - * The TLS private key. - * - * If *private_key* is a filesystem path, a watch will be added to the parent - * directory for any file moves to support rotation. This currently only - * applies to dynamic secrets, when the *TlsCertificate* is delivered via SDS. - */ - 'private_key': (_envoy_config_core_v3_DataSource__Output | null); - /** - * The password to decrypt the TLS private key. If this field is not set, it is assumed that the - * TLS private key is not password encrypted. - */ - 'password': (_envoy_config_core_v3_DataSource__Output | null); - /** - * The OCSP response to be stapled with this certificate during the handshake. - * The response must be DER-encoded and may only be provided via ``filename`` or - * ``inline_bytes``. The response may pertain to only one certificate. - */ - 'ocsp_staple': (_envoy_config_core_v3_DataSource__Output | null); - /** - * [#not-implemented-hide:] - */ - 'signed_certificate_timestamp': (_envoy_config_core_v3_DataSource__Output)[]; - /** - * BoringSSL private key method provider. This is an alternative to :ref:`private_key - * ` field. This can't be - * marked as ``oneof`` due to API compatibility reasons. Setting both :ref:`private_key - * ` and - * :ref:`private_key_provider - * ` fields will result in an - * error. - */ - 'private_key_provider': (_envoy_extensions_transport_sockets_tls_v3_PrivateKeyProvider__Output | null); - /** - * If specified, updates of file-based *certificate_chain* and *private_key* - * sources will be triggered by this watch. The certificate/key pair will be - * read together and validated for atomic read consistency (i.e. no - * intervening modification occurred between cert/key read, verified by file - * hash comparisons). This allows explicit control over the path watched, by - * default the parent directories of the filesystem paths in - * *certificate_chain* and *private_key* are watched if this field is not - * specified. This only applies when a *TlsCertificate* is delivered by SDS - * with references to filesystem paths. See the :ref:`SDS key rotation - * ` documentation for further details. - */ - 'watched_directory': (_envoy_config_core_v3_WatchedDirectory__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/TlsParameters.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/TlsParameters.ts deleted file mode 100644 index e68464c8b..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/TlsParameters.ts +++ /dev/null @@ -1,211 +0,0 @@ -// Original file: deps/envoy-api/envoy/extensions/transport_sockets/tls/v3/common.proto - - -// Original file: deps/envoy-api/envoy/extensions/transport_sockets/tls/v3/common.proto - -export enum _envoy_extensions_transport_sockets_tls_v3_TlsParameters_TlsProtocol { - /** - * Envoy will choose the optimal TLS version. - */ - TLS_AUTO = 0, - /** - * TLS 1.0 - */ - TLSv1_0 = 1, - /** - * TLS 1.1 - */ - TLSv1_1 = 2, - /** - * TLS 1.2 - */ - TLSv1_2 = 3, - /** - * TLS 1.3 - */ - TLSv1_3 = 4, -} - -export interface TlsParameters { - /** - * Minimum TLS protocol version. By default, it's ``TLSv1_2`` for clients and ``TLSv1_0`` for - * servers. - */ - 'tls_minimum_protocol_version'?: (_envoy_extensions_transport_sockets_tls_v3_TlsParameters_TlsProtocol | keyof typeof _envoy_extensions_transport_sockets_tls_v3_TlsParameters_TlsProtocol); - /** - * Maximum TLS protocol version. By default, it's ``TLSv1_2`` for clients and ``TLSv1_3`` for - * servers. - */ - 'tls_maximum_protocol_version'?: (_envoy_extensions_transport_sockets_tls_v3_TlsParameters_TlsProtocol | keyof typeof _envoy_extensions_transport_sockets_tls_v3_TlsParameters_TlsProtocol); - /** - * If specified, the TLS listener will only support the specified `cipher list - * `_ - * when negotiating TLS 1.0-1.2 (this setting has no effect when negotiating TLS 1.3). - * - * If not specified, a default list will be used. Defaults are different for server (downstream) and - * client (upstream) TLS configurations. - * - * In non-FIPS builds, the default server cipher list is: - * - * .. code-block:: none - * - * [ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305] - * [ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305] - * ECDHE-ECDSA-AES128-SHA - * ECDHE-RSA-AES128-SHA - * AES128-GCM-SHA256 - * AES128-SHA - * ECDHE-ECDSA-AES256-GCM-SHA384 - * ECDHE-RSA-AES256-GCM-SHA384 - * ECDHE-ECDSA-AES256-SHA - * ECDHE-RSA-AES256-SHA - * AES256-GCM-SHA384 - * AES256-SHA - * - * In builds using :ref:`BoringSSL FIPS `, the default server cipher list is: - * - * .. code-block:: none - * - * ECDHE-ECDSA-AES128-GCM-SHA256 - * ECDHE-RSA-AES128-GCM-SHA256 - * ECDHE-ECDSA-AES128-SHA - * ECDHE-RSA-AES128-SHA - * AES128-GCM-SHA256 - * AES128-SHA - * ECDHE-ECDSA-AES256-GCM-SHA384 - * ECDHE-RSA-AES256-GCM-SHA384 - * ECDHE-ECDSA-AES256-SHA - * ECDHE-RSA-AES256-SHA - * AES256-GCM-SHA384 - * AES256-SHA - * - * In non-FIPS builds, the default client cipher list is: - * - * .. code-block:: none - * - * [ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305] - * [ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305] - * ECDHE-ECDSA-AES256-GCM-SHA384 - * ECDHE-RSA-AES256-GCM-SHA384 - * - * In builds using :ref:`BoringSSL FIPS `, the default client cipher list is: - * - * .. code-block:: none - * - * ECDHE-ECDSA-AES128-GCM-SHA256 - * ECDHE-RSA-AES128-GCM-SHA256 - * ECDHE-ECDSA-AES256-GCM-SHA384 - * ECDHE-RSA-AES256-GCM-SHA384 - */ - 'cipher_suites'?: (string)[]; - /** - * If specified, the TLS connection will only support the specified ECDH - * curves. If not specified, the default curves will be used. - * - * In non-FIPS builds, the default curves are: - * - * .. code-block:: none - * - * X25519 - * P-256 - * - * In builds using :ref:`BoringSSL FIPS `, the default curve is: - * - * .. code-block:: none - * - * P-256 - */ - 'ecdh_curves'?: (string)[]; -} - -export interface TlsParameters__Output { - /** - * Minimum TLS protocol version. By default, it's ``TLSv1_2`` for clients and ``TLSv1_0`` for - * servers. - */ - 'tls_minimum_protocol_version': (keyof typeof _envoy_extensions_transport_sockets_tls_v3_TlsParameters_TlsProtocol); - /** - * Maximum TLS protocol version. By default, it's ``TLSv1_2`` for clients and ``TLSv1_3`` for - * servers. - */ - 'tls_maximum_protocol_version': (keyof typeof _envoy_extensions_transport_sockets_tls_v3_TlsParameters_TlsProtocol); - /** - * If specified, the TLS listener will only support the specified `cipher list - * `_ - * when negotiating TLS 1.0-1.2 (this setting has no effect when negotiating TLS 1.3). - * - * If not specified, a default list will be used. Defaults are different for server (downstream) and - * client (upstream) TLS configurations. - * - * In non-FIPS builds, the default server cipher list is: - * - * .. code-block:: none - * - * [ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305] - * [ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305] - * ECDHE-ECDSA-AES128-SHA - * ECDHE-RSA-AES128-SHA - * AES128-GCM-SHA256 - * AES128-SHA - * ECDHE-ECDSA-AES256-GCM-SHA384 - * ECDHE-RSA-AES256-GCM-SHA384 - * ECDHE-ECDSA-AES256-SHA - * ECDHE-RSA-AES256-SHA - * AES256-GCM-SHA384 - * AES256-SHA - * - * In builds using :ref:`BoringSSL FIPS `, the default server cipher list is: - * - * .. code-block:: none - * - * ECDHE-ECDSA-AES128-GCM-SHA256 - * ECDHE-RSA-AES128-GCM-SHA256 - * ECDHE-ECDSA-AES128-SHA - * ECDHE-RSA-AES128-SHA - * AES128-GCM-SHA256 - * AES128-SHA - * ECDHE-ECDSA-AES256-GCM-SHA384 - * ECDHE-RSA-AES256-GCM-SHA384 - * ECDHE-ECDSA-AES256-SHA - * ECDHE-RSA-AES256-SHA - * AES256-GCM-SHA384 - * AES256-SHA - * - * In non-FIPS builds, the default client cipher list is: - * - * .. code-block:: none - * - * [ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305] - * [ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305] - * ECDHE-ECDSA-AES256-GCM-SHA384 - * ECDHE-RSA-AES256-GCM-SHA384 - * - * In builds using :ref:`BoringSSL FIPS `, the default client cipher list is: - * - * .. code-block:: none - * - * ECDHE-ECDSA-AES128-GCM-SHA256 - * ECDHE-RSA-AES128-GCM-SHA256 - * ECDHE-ECDSA-AES256-GCM-SHA384 - * ECDHE-RSA-AES256-GCM-SHA384 - */ - 'cipher_suites': (string)[]; - /** - * If specified, the TLS connection will only support the specified ECDH - * curves. If not specified, the default curves will be used. - * - * In non-FIPS builds, the default curves are: - * - * .. code-block:: none - * - * X25519 - * P-256 - * - * In builds using :ref:`BoringSSL FIPS `, the default curve is: - * - * .. code-block:: none - * - * P-256 - */ - 'ecdh_curves': (string)[]; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/TlsSessionTicketKeys.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/TlsSessionTicketKeys.ts deleted file mode 100644 index 152bccac7..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/TlsSessionTicketKeys.ts +++ /dev/null @@ -1,61 +0,0 @@ -// Original file: deps/envoy-api/envoy/extensions/transport_sockets/tls/v3/common.proto - -import type { DataSource as _envoy_config_core_v3_DataSource, DataSource__Output as _envoy_config_core_v3_DataSource__Output } from '../../../../../envoy/config/core/v3/DataSource'; - -export interface TlsSessionTicketKeys { - /** - * Keys for encrypting and decrypting TLS session tickets. The - * first key in the array contains the key to encrypt all new sessions created by this context. - * All keys are candidates for decrypting received tickets. This allows for easy rotation of keys - * by, for example, putting the new key first, and the previous key second. - * - * If :ref:`session_ticket_keys ` - * is not specified, the TLS library will still support resuming sessions via tickets, but it will - * use an internally-generated and managed key, so sessions cannot be resumed across hot restarts - * or on different hosts. - * - * Each key must contain exactly 80 bytes of cryptographically-secure random data. For - * example, the output of ``openssl rand 80``. - * - * .. attention:: - * - * Using this feature has serious security considerations and risks. Improper handling of keys - * may result in loss of secrecy in connections, even if ciphers supporting perfect forward - * secrecy are used. See https://www.imperialviolet.org/2013/06/27/botchingpfs.html for some - * discussion. To minimize the risk, you must: - * - * * Keep the session ticket keys at least as secure as your TLS certificate private keys - * * Rotate session ticket keys at least daily, and preferably hourly - * * Always generate keys using a cryptographically-secure random data source - */ - 'keys'?: (_envoy_config_core_v3_DataSource)[]; -} - -export interface TlsSessionTicketKeys__Output { - /** - * Keys for encrypting and decrypting TLS session tickets. The - * first key in the array contains the key to encrypt all new sessions created by this context. - * All keys are candidates for decrypting received tickets. This allows for easy rotation of keys - * by, for example, putting the new key first, and the previous key second. - * - * If :ref:`session_ticket_keys ` - * is not specified, the TLS library will still support resuming sessions via tickets, but it will - * use an internally-generated and managed key, so sessions cannot be resumed across hot restarts - * or on different hosts. - * - * Each key must contain exactly 80 bytes of cryptographically-secure random data. For - * example, the output of ``openssl rand 80``. - * - * .. attention:: - * - * Using this feature has serious security considerations and risks. Improper handling of keys - * may result in loss of secrecy in connections, even if ciphers supporting perfect forward - * secrecy are used. See https://www.imperialviolet.org/2013/06/27/botchingpfs.html for some - * discussion. To minimize the risk, you must: - * - * * Keep the session ticket keys at least as secure as your TLS certificate private keys - * * Rotate session ticket keys at least daily, and preferably hourly - * * Always generate keys using a cryptographically-secure random data source - */ - 'keys': (_envoy_config_core_v3_DataSource__Output)[]; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientConfig.ts b/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientConfig.ts index ba6b25b4c..506547d1e 100644 --- a/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientConfig.ts +++ b/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientConfig.ts @@ -4,8 +4,8 @@ import type { Node as _envoy_config_core_v3_Node, Node__Output as _envoy_config_ import type { PerXdsConfig as _envoy_service_status_v3_PerXdsConfig, PerXdsConfig__Output as _envoy_service_status_v3_PerXdsConfig__Output } from '../../../../envoy/service/status/v3/PerXdsConfig'; import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../../google/protobuf/Timestamp'; -import type { ConfigStatus as _envoy_service_status_v3_ConfigStatus } from '../../../../envoy/service/status/v3/ConfigStatus'; -import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus } from '../../../../envoy/admin/v3/ClientResourceStatus'; +import type { ConfigStatus as _envoy_service_status_v3_ConfigStatus, ConfigStatus__Output as _envoy_service_status_v3_ConfigStatus__Output } from '../../../../envoy/service/status/v3/ConfigStatus'; +import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus, ClientResourceStatus__Output as _envoy_admin_v3_ClientResourceStatus__Output } from '../../../../envoy/admin/v3/ClientResourceStatus'; import type { UpdateFailureState as _envoy_admin_v3_UpdateFailureState, UpdateFailureState__Output as _envoy_admin_v3_UpdateFailureState__Output } from '../../../../envoy/admin/v3/UpdateFailureState'; /** @@ -42,11 +42,11 @@ export interface _envoy_service_status_v3_ClientConfig_GenericXdsConfig { * Per xDS resource config status. It is generated by management servers. * It will not be present if the CSDS server is an xDS client. */ - 'config_status'?: (_envoy_service_status_v3_ConfigStatus | keyof typeof _envoy_service_status_v3_ConfigStatus); + 'config_status'?: (_envoy_service_status_v3_ConfigStatus); /** * Per xDS resource status from the view of a xDS client */ - 'client_status'?: (_envoy_admin_v3_ClientResourceStatus | keyof typeof _envoy_admin_v3_ClientResourceStatus); + 'client_status'?: (_envoy_admin_v3_ClientResourceStatus); /** * Set if the last update failed, cleared after the next successful * update. The *error_state* field contains the rejected version of @@ -97,11 +97,11 @@ export interface _envoy_service_status_v3_ClientConfig_GenericXdsConfig__Output * Per xDS resource config status. It is generated by management servers. * It will not be present if the CSDS server is an xDS client. */ - 'config_status': (keyof typeof _envoy_service_status_v3_ConfigStatus); + 'config_status': (_envoy_service_status_v3_ConfigStatus__Output); /** * Per xDS resource status from the view of a xDS client */ - 'client_status': (keyof typeof _envoy_admin_v3_ClientResourceStatus); + 'client_status': (_envoy_admin_v3_ClientResourceStatus__Output); /** * Set if the last update failed, cleared after the next successful * update. The *error_state* field contains the rejected version of @@ -129,6 +129,7 @@ export interface ClientConfig { /** * This field is deprecated in favor of generic_xds_configs which is * much simpler and uniform in structure. + * @deprecated */ 'xds_config'?: (_envoy_service_status_v3_PerXdsConfig)[]; /** @@ -149,6 +150,7 @@ export interface ClientConfig__Output { /** * This field is deprecated in favor of generic_xds_configs which is * much simpler and uniform in structure. + * @deprecated */ 'xds_config': (_envoy_service_status_v3_PerXdsConfig__Output)[]; /** diff --git a/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientConfigStatus.ts b/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientConfigStatus.ts index 104445a3f..be7a7afd0 100644 --- a/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientConfigStatus.ts +++ b/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientConfigStatus.ts @@ -3,24 +3,57 @@ /** * Config status from a client-side view. */ -export enum ClientConfigStatus { +export const ClientConfigStatus = { /** * Config status is not available/unknown. */ - CLIENT_UNKNOWN = 0, + CLIENT_UNKNOWN: 'CLIENT_UNKNOWN', /** * Client requested the config but hasn't received any config from management * server yet. */ - CLIENT_REQUESTED = 1, + CLIENT_REQUESTED: 'CLIENT_REQUESTED', /** * Client received the config and replied with ACK. */ - CLIENT_ACKED = 2, + CLIENT_ACKED: 'CLIENT_ACKED', /** * Client received the config and replied with NACK. Notably, the attached * config dump is not the NACKed version, but the most recent accepted one. If * no config is accepted yet, the attached config dump will be empty. */ - CLIENT_NACKED = 3, -} + CLIENT_NACKED: 'CLIENT_NACKED', +} as const; + +/** + * Config status from a client-side view. + */ +export type ClientConfigStatus = + /** + * Config status is not available/unknown. + */ + | 'CLIENT_UNKNOWN' + | 0 + /** + * Client requested the config but hasn't received any config from management + * server yet. + */ + | 'CLIENT_REQUESTED' + | 1 + /** + * Client received the config and replied with ACK. + */ + | 'CLIENT_ACKED' + | 2 + /** + * Client received the config and replied with NACK. Notably, the attached + * config dump is not the NACKed version, but the most recent accepted one. If + * no config is accepted yet, the attached config dump will be empty. + */ + | 'CLIENT_NACKED' + | 3 + +/** + * Config status from a client-side view. + */ +export type ClientConfigStatus__Output = typeof ClientConfigStatus[keyof typeof ClientConfigStatus] diff --git a/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ConfigStatus.ts b/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ConfigStatus.ts index 71db302c3..15a8359e8 100644 --- a/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ConfigStatus.ts +++ b/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ConfigStatus.ts @@ -3,28 +3,66 @@ /** * Status of a config from a management server view. */ -export enum ConfigStatus { +export const ConfigStatus = { /** * Status info is not available/unknown. */ - UNKNOWN = 0, + UNKNOWN: 'UNKNOWN', /** * Management server has sent the config to client and received ACK. */ - SYNCED = 1, + SYNCED: 'SYNCED', /** * Config is not sent. */ - NOT_SENT = 2, + NOT_SENT: 'NOT_SENT', /** * Management server has sent the config to client but hasn’t received * ACK/NACK. */ - STALE = 3, + STALE: 'STALE', /** * Management server has sent the config to client but received NACK. The * attached config dump will be the latest config (the rejected one), since * it is the persisted version in the management server. */ - ERROR = 4, -} + ERROR: 'ERROR', +} as const; + +/** + * Status of a config from a management server view. + */ +export type ConfigStatus = + /** + * Status info is not available/unknown. + */ + | 'UNKNOWN' + | 0 + /** + * Management server has sent the config to client and received ACK. + */ + | 'SYNCED' + | 1 + /** + * Config is not sent. + */ + | 'NOT_SENT' + | 2 + /** + * Management server has sent the config to client but hasn’t received + * ACK/NACK. + */ + | 'STALE' + | 3 + /** + * Management server has sent the config to client but received NACK. The + * attached config dump will be the latest config (the rejected one), since + * it is the persisted version in the management server. + */ + | 'ERROR' + | 4 + +/** + * Status of a config from a management server view. + */ +export type ConfigStatus__Output = typeof ConfigStatus[keyof typeof ConfigStatus] diff --git a/packages/grpc-js-xds/src/generated/envoy/service/status/v3/PerXdsConfig.ts b/packages/grpc-js-xds/src/generated/envoy/service/status/v3/PerXdsConfig.ts index 947f1c81a..d921f3b1c 100644 --- a/packages/grpc-js-xds/src/generated/envoy/service/status/v3/PerXdsConfig.ts +++ b/packages/grpc-js-xds/src/generated/envoy/service/status/v3/PerXdsConfig.ts @@ -1,12 +1,12 @@ // Original file: deps/envoy-api/envoy/service/status/v3/csds.proto -import type { ConfigStatus as _envoy_service_status_v3_ConfigStatus } from '../../../../envoy/service/status/v3/ConfigStatus'; +import type { ConfigStatus as _envoy_service_status_v3_ConfigStatus, ConfigStatus__Output as _envoy_service_status_v3_ConfigStatus__Output } from '../../../../envoy/service/status/v3/ConfigStatus'; import type { ListenersConfigDump as _envoy_admin_v3_ListenersConfigDump, ListenersConfigDump__Output as _envoy_admin_v3_ListenersConfigDump__Output } from '../../../../envoy/admin/v3/ListenersConfigDump'; import type { ClustersConfigDump as _envoy_admin_v3_ClustersConfigDump, ClustersConfigDump__Output as _envoy_admin_v3_ClustersConfigDump__Output } from '../../../../envoy/admin/v3/ClustersConfigDump'; import type { RoutesConfigDump as _envoy_admin_v3_RoutesConfigDump, RoutesConfigDump__Output as _envoy_admin_v3_RoutesConfigDump__Output } from '../../../../envoy/admin/v3/RoutesConfigDump'; import type { ScopedRoutesConfigDump as _envoy_admin_v3_ScopedRoutesConfigDump, ScopedRoutesConfigDump__Output as _envoy_admin_v3_ScopedRoutesConfigDump__Output } from '../../../../envoy/admin/v3/ScopedRoutesConfigDump'; import type { EndpointsConfigDump as _envoy_admin_v3_EndpointsConfigDump, EndpointsConfigDump__Output as _envoy_admin_v3_EndpointsConfigDump__Output } from '../../../../envoy/admin/v3/EndpointsConfigDump'; -import type { ClientConfigStatus as _envoy_service_status_v3_ClientConfigStatus } from '../../../../envoy/service/status/v3/ClientConfigStatus'; +import type { ClientConfigStatus as _envoy_service_status_v3_ClientConfigStatus, ClientConfigStatus__Output as _envoy_service_status_v3_ClientConfigStatus__Output } from '../../../../envoy/service/status/v3/ClientConfigStatus'; /** * Detailed config (per xDS) with status. @@ -17,7 +17,7 @@ export interface PerXdsConfig { * Config status generated by management servers. Will not be present if the * CSDS server is an xDS client. */ - 'status'?: (_envoy_service_status_v3_ConfigStatus | keyof typeof _envoy_service_status_v3_ConfigStatus); + 'status'?: (_envoy_service_status_v3_ConfigStatus); 'listener_config'?: (_envoy_admin_v3_ListenersConfigDump | null); 'cluster_config'?: (_envoy_admin_v3_ClustersConfigDump | null); 'route_config'?: (_envoy_admin_v3_RoutesConfigDump | null); @@ -32,8 +32,9 @@ export interface PerXdsConfig { * This field is deprecated. Use :ref:`ClientResourceStatus * ` for per-resource * config status instead. + * @deprecated */ - 'client_status'?: (_envoy_service_status_v3_ClientConfigStatus | keyof typeof _envoy_service_status_v3_ClientConfigStatus); + 'client_status'?: (_envoy_service_status_v3_ClientConfigStatus); 'per_xds_config'?: "listener_config"|"cluster_config"|"route_config"|"scoped_route_config"|"endpoint_config"; } @@ -46,7 +47,7 @@ export interface PerXdsConfig__Output { * Config status generated by management servers. Will not be present if the * CSDS server is an xDS client. */ - 'status': (keyof typeof _envoy_service_status_v3_ConfigStatus); + 'status': (_envoy_service_status_v3_ConfigStatus__Output); 'listener_config'?: (_envoy_admin_v3_ListenersConfigDump__Output | null); 'cluster_config'?: (_envoy_admin_v3_ClustersConfigDump__Output | null); 'route_config'?: (_envoy_admin_v3_RoutesConfigDump__Output | null); @@ -61,7 +62,8 @@ export interface PerXdsConfig__Output { * This field is deprecated. Use :ref:`ClientResourceStatus * ` for per-resource * config status instead. + * @deprecated */ - 'client_status': (keyof typeof _envoy_service_status_v3_ClientConfigStatus); + 'client_status': (_envoy_service_status_v3_ClientConfigStatus__Output); 'per_xds_config': "listener_config"|"cluster_config"|"route_config"|"scoped_route_config"|"endpoint_config"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/RegexMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/RegexMatcher.ts index c83f8b473..19517678f 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/RegexMatcher.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/RegexMatcher.ts @@ -31,6 +31,7 @@ export interface _envoy_type_matcher_v3_RegexMatcher_GoogleRE2 { * * Although this field is deprecated, the program size will still be checked against the * global ``re2.max_program_size.error_level`` runtime value. + * @deprecated */ 'max_program_size'?: (_google_protobuf_UInt32Value | null); } @@ -64,6 +65,7 @@ export interface _envoy_type_matcher_v3_RegexMatcher_GoogleRE2__Output { * * Although this field is deprecated, the program size will still be checked against the * global ``re2.max_program_size.error_level`` runtime value. + * @deprecated */ 'max_program_size': (_google_protobuf_UInt32Value__Output | null); } @@ -74,6 +76,7 @@ export interface _envoy_type_matcher_v3_RegexMatcher_GoogleRE2__Output { export interface RegexMatcher { /** * Google's RE2 regex engine. + * @deprecated */ 'google_re2'?: (_envoy_type_matcher_v3_RegexMatcher_GoogleRE2 | null); /** @@ -90,6 +93,7 @@ export interface RegexMatcher { export interface RegexMatcher__Output { /** * Google's RE2 regex engine. + * @deprecated */ 'google_re2'?: (_envoy_type_matcher_v3_RegexMatcher_GoogleRE2__Output | null); /** diff --git a/packages/grpc-js-xds/src/generated/envoy/type/v3/CodecClientType.ts b/packages/grpc-js-xds/src/generated/envoy/type/v3/CodecClientType.ts index 308f14446..e05cdfb96 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/v3/CodecClientType.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/v3/CodecClientType.ts @@ -1,12 +1,27 @@ // Original file: deps/envoy-api/envoy/type/v3/http.proto -export enum CodecClientType { - HTTP1 = 0, - HTTP2 = 1, +export const CodecClientType = { + HTTP1: 'HTTP1', + HTTP2: 'HTTP2', /** * [#not-implemented-hide:] QUIC implementation is not production ready yet. Use this enum with * caution to prevent accidental execution of QUIC code. I.e. `!= HTTP2` is no longer sufficient * to distinguish HTTP1 and HTTP2 traffic. */ - HTTP3 = 2, -} + HTTP3: 'HTTP3', +} as const; + +export type CodecClientType = + | 'HTTP1' + | 0 + | 'HTTP2' + | 1 + /** + * [#not-implemented-hide:] QUIC implementation is not production ready yet. Use this enum with + * caution to prevent accidental execution of QUIC code. I.e. `!= HTTP2` is no longer sufficient + * to distinguish HTTP1 and HTTP2 traffic. + */ + | 'HTTP3' + | 2 + +export type CodecClientType__Output = typeof CodecClientType[keyof typeof CodecClientType] diff --git a/packages/grpc-js-xds/src/generated/envoy/type/v3/FractionalPercent.ts b/packages/grpc-js-xds/src/generated/envoy/type/v3/FractionalPercent.ts index 564af9a0f..c45441a79 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/v3/FractionalPercent.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/v3/FractionalPercent.ts @@ -6,26 +6,57 @@ /** * Fraction percentages support several fixed denominator values. */ -export enum _envoy_type_v3_FractionalPercent_DenominatorType { +export const _envoy_type_v3_FractionalPercent_DenominatorType = { /** * 100. * * **Example**: 1/100 = 1%. */ - HUNDRED = 0, + HUNDRED: 'HUNDRED', /** * 10,000. * * **Example**: 1/10000 = 0.01%. */ - TEN_THOUSAND = 1, + TEN_THOUSAND: 'TEN_THOUSAND', /** * 1,000,000. * * **Example**: 1/1000000 = 0.0001%. */ - MILLION = 2, -} + MILLION: 'MILLION', +} as const; + +/** + * Fraction percentages support several fixed denominator values. + */ +export type _envoy_type_v3_FractionalPercent_DenominatorType = + /** + * 100. + * + * **Example**: 1/100 = 1%. + */ + | 'HUNDRED' + | 0 + /** + * 10,000. + * + * **Example**: 1/10000 = 0.01%. + */ + | 'TEN_THOUSAND' + | 1 + /** + * 1,000,000. + * + * **Example**: 1/1000000 = 0.0001%. + */ + | 'MILLION' + | 2 + +/** + * Fraction percentages support several fixed denominator values. + */ +export type _envoy_type_v3_FractionalPercent_DenominatorType__Output = typeof _envoy_type_v3_FractionalPercent_DenominatorType[keyof typeof _envoy_type_v3_FractionalPercent_DenominatorType] /** * A fractional percentage is used in cases in which for performance reasons performing floating @@ -44,7 +75,7 @@ export interface FractionalPercent { * Specifies the denominator. If the denominator specified is less than the numerator, the final * fractional percentage is capped at 1 (100%). */ - 'denominator'?: (_envoy_type_v3_FractionalPercent_DenominatorType | keyof typeof _envoy_type_v3_FractionalPercent_DenominatorType); + 'denominator'?: (_envoy_type_v3_FractionalPercent_DenominatorType); } /** @@ -64,5 +95,5 @@ export interface FractionalPercent__Output { * Specifies the denominator. If the denominator specified is less than the numerator, the final * fractional percentage is capped at 1 (100%). */ - 'denominator': (keyof typeof _envoy_type_v3_FractionalPercent_DenominatorType); + 'denominator': (_envoy_type_v3_FractionalPercent_DenominatorType__Output); } diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/FieldDescriptorProto.ts b/packages/grpc-js-xds/src/generated/google/protobuf/FieldDescriptorProto.ts index c511e2eff..4951919fd 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/FieldDescriptorProto.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/FieldDescriptorProto.ts @@ -4,41 +4,91 @@ import type { FieldOptions as _google_protobuf_FieldOptions, FieldOptions__Outpu // Original file: null -export enum _google_protobuf_FieldDescriptorProto_Label { - LABEL_OPTIONAL = 1, - LABEL_REQUIRED = 2, - LABEL_REPEATED = 3, -} +export const _google_protobuf_FieldDescriptorProto_Label = { + LABEL_OPTIONAL: 'LABEL_OPTIONAL', + LABEL_REQUIRED: 'LABEL_REQUIRED', + LABEL_REPEATED: 'LABEL_REPEATED', +} as const; + +export type _google_protobuf_FieldDescriptorProto_Label = + | 'LABEL_OPTIONAL' + | 1 + | 'LABEL_REQUIRED' + | 2 + | 'LABEL_REPEATED' + | 3 + +export type _google_protobuf_FieldDescriptorProto_Label__Output = typeof _google_protobuf_FieldDescriptorProto_Label[keyof typeof _google_protobuf_FieldDescriptorProto_Label] // Original file: null -export enum _google_protobuf_FieldDescriptorProto_Type { - TYPE_DOUBLE = 1, - TYPE_FLOAT = 2, - TYPE_INT64 = 3, - TYPE_UINT64 = 4, - TYPE_INT32 = 5, - TYPE_FIXED64 = 6, - TYPE_FIXED32 = 7, - TYPE_BOOL = 8, - TYPE_STRING = 9, - TYPE_GROUP = 10, - TYPE_MESSAGE = 11, - TYPE_BYTES = 12, - TYPE_UINT32 = 13, - TYPE_ENUM = 14, - TYPE_SFIXED32 = 15, - TYPE_SFIXED64 = 16, - TYPE_SINT32 = 17, - TYPE_SINT64 = 18, -} +export const _google_protobuf_FieldDescriptorProto_Type = { + TYPE_DOUBLE: 'TYPE_DOUBLE', + TYPE_FLOAT: 'TYPE_FLOAT', + TYPE_INT64: 'TYPE_INT64', + TYPE_UINT64: 'TYPE_UINT64', + TYPE_INT32: 'TYPE_INT32', + TYPE_FIXED64: 'TYPE_FIXED64', + TYPE_FIXED32: 'TYPE_FIXED32', + TYPE_BOOL: 'TYPE_BOOL', + TYPE_STRING: 'TYPE_STRING', + TYPE_GROUP: 'TYPE_GROUP', + TYPE_MESSAGE: 'TYPE_MESSAGE', + TYPE_BYTES: 'TYPE_BYTES', + TYPE_UINT32: 'TYPE_UINT32', + TYPE_ENUM: 'TYPE_ENUM', + TYPE_SFIXED32: 'TYPE_SFIXED32', + TYPE_SFIXED64: 'TYPE_SFIXED64', + TYPE_SINT32: 'TYPE_SINT32', + TYPE_SINT64: 'TYPE_SINT64', +} as const; + +export type _google_protobuf_FieldDescriptorProto_Type = + | 'TYPE_DOUBLE' + | 1 + | 'TYPE_FLOAT' + | 2 + | 'TYPE_INT64' + | 3 + | 'TYPE_UINT64' + | 4 + | 'TYPE_INT32' + | 5 + | 'TYPE_FIXED64' + | 6 + | 'TYPE_FIXED32' + | 7 + | 'TYPE_BOOL' + | 8 + | 'TYPE_STRING' + | 9 + | 'TYPE_GROUP' + | 10 + | 'TYPE_MESSAGE' + | 11 + | 'TYPE_BYTES' + | 12 + | 'TYPE_UINT32' + | 13 + | 'TYPE_ENUM' + | 14 + | 'TYPE_SFIXED32' + | 15 + | 'TYPE_SFIXED64' + | 16 + | 'TYPE_SINT32' + | 17 + | 'TYPE_SINT64' + | 18 + +export type _google_protobuf_FieldDescriptorProto_Type__Output = typeof _google_protobuf_FieldDescriptorProto_Type[keyof typeof _google_protobuf_FieldDescriptorProto_Type] export interface FieldDescriptorProto { 'name'?: (string); 'extendee'?: (string); 'number'?: (number); - 'label'?: (_google_protobuf_FieldDescriptorProto_Label | keyof typeof _google_protobuf_FieldDescriptorProto_Label); - 'type'?: (_google_protobuf_FieldDescriptorProto_Type | keyof typeof _google_protobuf_FieldDescriptorProto_Type); + 'label'?: (_google_protobuf_FieldDescriptorProto_Label); + 'type'?: (_google_protobuf_FieldDescriptorProto_Type); 'typeName'?: (string); 'defaultValue'?: (string); 'options'?: (_google_protobuf_FieldOptions | null); @@ -50,8 +100,8 @@ export interface FieldDescriptorProto__Output { 'name': (string); 'extendee': (string); 'number': (number); - 'label': (keyof typeof _google_protobuf_FieldDescriptorProto_Label); - 'type': (keyof typeof _google_protobuf_FieldDescriptorProto_Type); + 'label': (_google_protobuf_FieldDescriptorProto_Label__Output); + 'type': (_google_protobuf_FieldDescriptorProto_Type__Output); 'typeName': (string); 'defaultValue': (string); 'options': (_google_protobuf_FieldOptions__Output | null); diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/FieldOptions.ts b/packages/grpc-js-xds/src/generated/google/protobuf/FieldOptions.ts index 3c3b446c9..b301f2958 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/FieldOptions.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/FieldOptions.ts @@ -4,36 +4,56 @@ import type { UninterpretedOption as _google_protobuf_UninterpretedOption, Unint // Original file: null -export enum _google_protobuf_FieldOptions_CType { - STRING = 0, - CORD = 1, - STRING_PIECE = 2, -} +export const _google_protobuf_FieldOptions_CType = { + STRING: 'STRING', + CORD: 'CORD', + STRING_PIECE: 'STRING_PIECE', +} as const; + +export type _google_protobuf_FieldOptions_CType = + | 'STRING' + | 0 + | 'CORD' + | 1 + | 'STRING_PIECE' + | 2 + +export type _google_protobuf_FieldOptions_CType__Output = typeof _google_protobuf_FieldOptions_CType[keyof typeof _google_protobuf_FieldOptions_CType] // Original file: null -export enum _google_protobuf_FieldOptions_JSType { - JS_NORMAL = 0, - JS_STRING = 1, - JS_NUMBER = 2, -} +export const _google_protobuf_FieldOptions_JSType = { + JS_NORMAL: 'JS_NORMAL', + JS_STRING: 'JS_STRING', + JS_NUMBER: 'JS_NUMBER', +} as const; + +export type _google_protobuf_FieldOptions_JSType = + | 'JS_NORMAL' + | 0 + | 'JS_STRING' + | 1 + | 'JS_NUMBER' + | 2 + +export type _google_protobuf_FieldOptions_JSType__Output = typeof _google_protobuf_FieldOptions_JSType[keyof typeof _google_protobuf_FieldOptions_JSType] export interface FieldOptions { - 'ctype'?: (_google_protobuf_FieldOptions_CType | keyof typeof _google_protobuf_FieldOptions_CType); + 'ctype'?: (_google_protobuf_FieldOptions_CType); 'packed'?: (boolean); 'deprecated'?: (boolean); 'lazy'?: (boolean); - 'jstype'?: (_google_protobuf_FieldOptions_JSType | keyof typeof _google_protobuf_FieldOptions_JSType); + 'jstype'?: (_google_protobuf_FieldOptions_JSType); 'weak'?: (boolean); 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; } export interface FieldOptions__Output { - 'ctype': (keyof typeof _google_protobuf_FieldOptions_CType); + 'ctype': (_google_protobuf_FieldOptions_CType__Output); 'packed': (boolean); 'deprecated': (boolean); 'lazy': (boolean); - 'jstype': (keyof typeof _google_protobuf_FieldOptions_JSType); + 'jstype': (_google_protobuf_FieldOptions_JSType__Output); 'weak': (boolean); 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; } diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/FileOptions.ts b/packages/grpc-js-xds/src/generated/google/protobuf/FileOptions.ts index 84500fc30..6fab1a84b 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/FileOptions.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/FileOptions.ts @@ -5,21 +5,34 @@ import type { StatusAnnotation as _udpa_annotations_StatusAnnotation, StatusAnno // Original file: null -export enum _google_protobuf_FileOptions_OptimizeMode { - SPEED = 1, - CODE_SIZE = 2, - LITE_RUNTIME = 3, -} +export const _google_protobuf_FileOptions_OptimizeMode = { + SPEED: 'SPEED', + CODE_SIZE: 'CODE_SIZE', + LITE_RUNTIME: 'LITE_RUNTIME', +} as const; + +export type _google_protobuf_FileOptions_OptimizeMode = + | 'SPEED' + | 1 + | 'CODE_SIZE' + | 2 + | 'LITE_RUNTIME' + | 3 + +export type _google_protobuf_FileOptions_OptimizeMode__Output = typeof _google_protobuf_FileOptions_OptimizeMode[keyof typeof _google_protobuf_FileOptions_OptimizeMode] export interface FileOptions { 'javaPackage'?: (string); 'javaOuterClassname'?: (string); - 'optimizeFor'?: (_google_protobuf_FileOptions_OptimizeMode | keyof typeof _google_protobuf_FileOptions_OptimizeMode); + 'optimizeFor'?: (_google_protobuf_FileOptions_OptimizeMode); 'javaMultipleFiles'?: (boolean); 'goPackage'?: (string); 'ccGenericServices'?: (boolean); 'javaGenericServices'?: (boolean); 'pyGenericServices'?: (boolean); + /** + * @deprecated + */ 'javaGenerateEqualsAndHash'?: (boolean); 'deprecated'?: (boolean); 'javaStringCheckUtf8'?: (boolean); @@ -33,12 +46,15 @@ export interface FileOptions { export interface FileOptions__Output { 'javaPackage': (string); 'javaOuterClassname': (string); - 'optimizeFor': (keyof typeof _google_protobuf_FileOptions_OptimizeMode); + 'optimizeFor': (_google_protobuf_FileOptions_OptimizeMode__Output); 'javaMultipleFiles': (boolean); 'goPackage': (string); 'ccGenericServices': (boolean); 'javaGenericServices': (boolean); 'pyGenericServices': (boolean); + /** + * @deprecated + */ 'javaGenerateEqualsAndHash': (boolean); 'deprecated': (boolean); 'javaStringCheckUtf8': (boolean); diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/NullValue.ts b/packages/grpc-js-xds/src/generated/google/protobuf/NullValue.ts index 377aab885..c66dacc7b 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/NullValue.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/NullValue.ts @@ -1,5 +1,11 @@ // Original file: null -export enum NullValue { - NULL_VALUE = 0, -} +export const NullValue = { + NULL_VALUE: 'NULL_VALUE', +} as const; + +export type NullValue = + | 'NULL_VALUE' + | 0 + +export type NullValue__Output = typeof NullValue[keyof typeof NullValue] diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/Value.ts b/packages/grpc-js-xds/src/generated/google/protobuf/Value.ts index b1a942a56..67cc03fff 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/Value.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/Value.ts @@ -1,11 +1,11 @@ // Original file: null -import type { NullValue as _google_protobuf_NullValue } from '../../google/protobuf/NullValue'; +import type { NullValue as _google_protobuf_NullValue, NullValue__Output as _google_protobuf_NullValue__Output } from '../../google/protobuf/NullValue'; import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../google/protobuf/Struct'; import type { ListValue as _google_protobuf_ListValue, ListValue__Output as _google_protobuf_ListValue__Output } from '../../google/protobuf/ListValue'; export interface Value { - 'nullValue'?: (_google_protobuf_NullValue | keyof typeof _google_protobuf_NullValue); + 'nullValue'?: (_google_protobuf_NullValue); 'numberValue'?: (number | string); 'stringValue'?: (string); 'boolValue'?: (boolean); @@ -15,7 +15,7 @@ export interface Value { } export interface Value__Output { - 'nullValue'?: (keyof typeof _google_protobuf_NullValue); + 'nullValue'?: (_google_protobuf_NullValue__Output); 'numberValue'?: (number); 'stringValue'?: (string); 'boolValue'?: (boolean); diff --git a/packages/grpc-js-xds/src/generated/udpa/annotations/PackageVersionStatus.ts b/packages/grpc-js-xds/src/generated/udpa/annotations/PackageVersionStatus.ts index d0e181aa5..4d15df739 100644 --- a/packages/grpc-js-xds/src/generated/udpa/annotations/PackageVersionStatus.ts +++ b/packages/grpc-js-xds/src/generated/udpa/annotations/PackageVersionStatus.ts @@ -1,21 +1,46 @@ // Original file: deps/xds/udpa/annotations/status.proto -export enum PackageVersionStatus { +export const PackageVersionStatus = { /** * Unknown package version status. */ - UNKNOWN = 0, + UNKNOWN: 'UNKNOWN', /** * This version of the package is frozen. */ - FROZEN = 1, + FROZEN: 'FROZEN', /** * This version of the package is the active development version. */ - ACTIVE = 2, + ACTIVE: 'ACTIVE', /** * This version of the package is the candidate for the next major version. It * is typically machine generated from the active development version. */ - NEXT_MAJOR_VERSION_CANDIDATE = 3, -} + NEXT_MAJOR_VERSION_CANDIDATE: 'NEXT_MAJOR_VERSION_CANDIDATE', +} as const; + +export type PackageVersionStatus = + /** + * Unknown package version status. + */ + | 'UNKNOWN' + | 0 + /** + * This version of the package is frozen. + */ + | 'FROZEN' + | 1 + /** + * This version of the package is the active development version. + */ + | 'ACTIVE' + | 2 + /** + * This version of the package is the candidate for the next major version. It + * is typically machine generated from the active development version. + */ + | 'NEXT_MAJOR_VERSION_CANDIDATE' + | 3 + +export type PackageVersionStatus__Output = typeof PackageVersionStatus[keyof typeof PackageVersionStatus] diff --git a/packages/grpc-js-xds/src/generated/udpa/annotations/StatusAnnotation.ts b/packages/grpc-js-xds/src/generated/udpa/annotations/StatusAnnotation.ts index f01b45063..f129c3c94 100644 --- a/packages/grpc-js-xds/src/generated/udpa/annotations/StatusAnnotation.ts +++ b/packages/grpc-js-xds/src/generated/udpa/annotations/StatusAnnotation.ts @@ -1,6 +1,6 @@ // Original file: deps/xds/udpa/annotations/status.proto -import type { PackageVersionStatus as _udpa_annotations_PackageVersionStatus } from '../../udpa/annotations/PackageVersionStatus'; +import type { PackageVersionStatus as _udpa_annotations_PackageVersionStatus, PackageVersionStatus__Output as _udpa_annotations_PackageVersionStatus__Output } from '../../udpa/annotations/PackageVersionStatus'; export interface StatusAnnotation { /** @@ -10,7 +10,7 @@ export interface StatusAnnotation { /** * The entity belongs to a package with the given version status. */ - 'package_version_status'?: (_udpa_annotations_PackageVersionStatus | keyof typeof _udpa_annotations_PackageVersionStatus); + 'package_version_status'?: (_udpa_annotations_PackageVersionStatus); } export interface StatusAnnotation__Output { @@ -21,5 +21,5 @@ export interface StatusAnnotation__Output { /** * The entity belongs to a package with the given version status. */ - 'package_version_status': (keyof typeof _udpa_annotations_PackageVersionStatus); + 'package_version_status': (_udpa_annotations_PackageVersionStatus__Output); } diff --git a/packages/grpc-js-xds/src/generated/validate/FieldRules.ts b/packages/grpc-js-xds/src/generated/validate/FieldRules.ts index 067125775..ce6f313e7 100644 --- a/packages/grpc-js-xds/src/generated/validate/FieldRules.ts +++ b/packages/grpc-js-xds/src/generated/validate/FieldRules.ts @@ -22,7 +22,6 @@ import type { MapRules as _validate_MapRules, MapRules__Output as _validate_MapR import type { AnyRules as _validate_AnyRules, AnyRules__Output as _validate_AnyRules__Output } from '../validate/AnyRules'; import type { DurationRules as _validate_DurationRules, DurationRules__Output as _validate_DurationRules__Output } from '../validate/DurationRules'; import type { TimestampRules as _validate_TimestampRules, TimestampRules__Output as _validate_TimestampRules__Output } from '../validate/TimestampRules'; -import type { Long } from '@grpc/proto-loader'; /** * FieldRules encapsulates the rules for each type of field. Depending on the diff --git a/packages/grpc-js-xds/src/generated/validate/KnownRegex.ts b/packages/grpc-js-xds/src/generated/validate/KnownRegex.ts index 5880b5baf..8f1e20b4c 100644 --- a/packages/grpc-js-xds/src/generated/validate/KnownRegex.ts +++ b/packages/grpc-js-xds/src/generated/validate/KnownRegex.ts @@ -3,14 +3,36 @@ /** * WellKnownRegex contain some well-known patterns. */ -export enum KnownRegex { - UNKNOWN = 0, +export const KnownRegex = { + UNKNOWN: 'UNKNOWN', /** * HTTP header name as defined by RFC 7230. */ - HTTP_HEADER_NAME = 1, + HTTP_HEADER_NAME: 'HTTP_HEADER_NAME', /** * HTTP header value as defined by RFC 7230. */ - HTTP_HEADER_VALUE = 2, -} + HTTP_HEADER_VALUE: 'HTTP_HEADER_VALUE', +} as const; + +/** + * WellKnownRegex contain some well-known patterns. + */ +export type KnownRegex = + | 'UNKNOWN' + | 0 + /** + * HTTP header name as defined by RFC 7230. + */ + | 'HTTP_HEADER_NAME' + | 1 + /** + * HTTP header value as defined by RFC 7230. + */ + | 'HTTP_HEADER_VALUE' + | 2 + +/** + * WellKnownRegex contain some well-known patterns. + */ +export type KnownRegex__Output = typeof KnownRegex[keyof typeof KnownRegex] diff --git a/packages/grpc-js-xds/src/generated/validate/StringRules.ts b/packages/grpc-js-xds/src/generated/validate/StringRules.ts index b6bb1e460..8bca6dffa 100644 --- a/packages/grpc-js-xds/src/generated/validate/StringRules.ts +++ b/packages/grpc-js-xds/src/generated/validate/StringRules.ts @@ -1,6 +1,6 @@ // Original file: deps/protoc-gen-validate/validate/validate.proto -import type { KnownRegex as _validate_KnownRegex } from '../validate/KnownRegex'; +import type { KnownRegex as _validate_KnownRegex, KnownRegex__Output as _validate_KnownRegex__Output } from '../validate/KnownRegex'; import type { Long } from '@grpc/proto-loader'; /** @@ -129,7 +129,7 @@ export interface StringRules { /** * WellKnownRegex specifies a common well known pattern defined as a regex. */ - 'well_known_regex'?: (_validate_KnownRegex | keyof typeof _validate_KnownRegex); + 'well_known_regex'?: (_validate_KnownRegex); /** * This applies to regexes HTTP_HEADER_NAME and HTTP_HEADER_VALUE to enable * strict header validation. @@ -271,7 +271,7 @@ export interface StringRules__Output { /** * WellKnownRegex specifies a common well known pattern defined as a regex. */ - 'well_known_regex'?: (keyof typeof _validate_KnownRegex); + 'well_known_regex'?: (_validate_KnownRegex__Output); /** * This applies to regexes HTTP_HEADER_NAME and HTTP_HEADER_VALUE to enable * strict header validation. diff --git a/packages/grpc-js-xds/src/generated/xds/annotations/v3/PackageVersionStatus.ts b/packages/grpc-js-xds/src/generated/xds/annotations/v3/PackageVersionStatus.ts index e76e2848f..e85074eae 100644 --- a/packages/grpc-js-xds/src/generated/xds/annotations/v3/PackageVersionStatus.ts +++ b/packages/grpc-js-xds/src/generated/xds/annotations/v3/PackageVersionStatus.ts @@ -1,21 +1,46 @@ // Original file: deps/xds/xds/annotations/v3/status.proto -export enum PackageVersionStatus { +export const PackageVersionStatus = { /** * Unknown package version status. */ - UNKNOWN = 0, + UNKNOWN: 'UNKNOWN', /** * This version of the package is frozen. */ - FROZEN = 1, + FROZEN: 'FROZEN', /** * This version of the package is the active development version. */ - ACTIVE = 2, + ACTIVE: 'ACTIVE', /** * This version of the package is the candidate for the next major version. It * is typically machine generated from the active development version. */ - NEXT_MAJOR_VERSION_CANDIDATE = 3, -} + NEXT_MAJOR_VERSION_CANDIDATE: 'NEXT_MAJOR_VERSION_CANDIDATE', +} as const; + +export type PackageVersionStatus = + /** + * Unknown package version status. + */ + | 'UNKNOWN' + | 0 + /** + * This version of the package is frozen. + */ + | 'FROZEN' + | 1 + /** + * This version of the package is the active development version. + */ + | 'ACTIVE' + | 2 + /** + * This version of the package is the candidate for the next major version. It + * is typically machine generated from the active development version. + */ + | 'NEXT_MAJOR_VERSION_CANDIDATE' + | 3 + +export type PackageVersionStatus__Output = typeof PackageVersionStatus[keyof typeof PackageVersionStatus] diff --git a/packages/grpc-js-xds/src/generated/xds/annotations/v3/StatusAnnotation.ts b/packages/grpc-js-xds/src/generated/xds/annotations/v3/StatusAnnotation.ts index 58efbd8f7..678d6a6bf 100644 --- a/packages/grpc-js-xds/src/generated/xds/annotations/v3/StatusAnnotation.ts +++ b/packages/grpc-js-xds/src/generated/xds/annotations/v3/StatusAnnotation.ts @@ -1,6 +1,6 @@ // Original file: deps/xds/xds/annotations/v3/status.proto -import type { PackageVersionStatus as _xds_annotations_v3_PackageVersionStatus } from '../../../xds/annotations/v3/PackageVersionStatus'; +import type { PackageVersionStatus as _xds_annotations_v3_PackageVersionStatus, PackageVersionStatus__Output as _xds_annotations_v3_PackageVersionStatus__Output } from '../../../xds/annotations/v3/PackageVersionStatus'; export interface StatusAnnotation { /** @@ -10,7 +10,7 @@ export interface StatusAnnotation { /** * The entity belongs to a package with the given version status. */ - 'package_version_status'?: (_xds_annotations_v3_PackageVersionStatus | keyof typeof _xds_annotations_v3_PackageVersionStatus); + 'package_version_status'?: (_xds_annotations_v3_PackageVersionStatus); } export interface StatusAnnotation__Output { @@ -21,5 +21,5 @@ export interface StatusAnnotation__Output { /** * The entity belongs to a package with the given version status. */ - 'package_version_status': (keyof typeof _xds_annotations_v3_PackageVersionStatus); + 'package_version_status': (_xds_annotations_v3_PackageVersionStatus__Output); } diff --git a/packages/grpc-js-xds/src/generated/xds/core/v3/ResourceLocator.ts b/packages/grpc-js-xds/src/generated/xds/core/v3/ResourceLocator.ts index bb1f822b8..28f981dd5 100644 --- a/packages/grpc-js-xds/src/generated/xds/core/v3/ResourceLocator.ts +++ b/packages/grpc-js-xds/src/generated/xds/core/v3/ResourceLocator.ts @@ -97,11 +97,21 @@ export interface _xds_core_v3_ResourceLocator_Directive__Output { // Original file: deps/xds/xds/core/v3/resource_locator.proto -export enum _xds_core_v3_ResourceLocator_Scheme { - XDSTP = 0, - HTTP = 1, - FILE = 2, -} +export const _xds_core_v3_ResourceLocator_Scheme = { + XDSTP: 'XDSTP', + HTTP: 'HTTP', + FILE: 'FILE', +} as const; + +export type _xds_core_v3_ResourceLocator_Scheme = + | 'XDSTP' + | 0 + | 'HTTP' + | 1 + | 'FILE' + | 2 + +export type _xds_core_v3_ResourceLocator_Scheme__Output = typeof _xds_core_v3_ResourceLocator_Scheme[keyof typeof _xds_core_v3_ResourceLocator_Scheme] /** * xDS resource locators identify a xDS resource name and instruct the @@ -125,7 +135,7 @@ export interface ResourceLocator { /** * URI scheme. */ - 'scheme'?: (_xds_core_v3_ResourceLocator_Scheme | keyof typeof _xds_core_v3_ResourceLocator_Scheme); + 'scheme'?: (_xds_core_v3_ResourceLocator_Scheme); /** * Opaque identifier for the resource. Any '/' will not be escaped during URI * encoding and will form part of the URI path. This may end @@ -183,7 +193,7 @@ export interface ResourceLocator__Output { /** * URI scheme. */ - 'scheme': (keyof typeof _xds_core_v3_ResourceLocator_Scheme); + 'scheme': (_xds_core_v3_ResourceLocator_Scheme__Output); /** * Opaque identifier for the resource. Any '/' will not be escaped during URI * encoding and will form part of the URI path. This may end diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 3b8ccf2c1..41594561d 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -66,7 +66,7 @@ "generate-test-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --include-dirs test/fixtures/ -O test/generated/ --grpcLib ../../src/index test_service.proto" }, "dependencies": { - "@grpc/proto-loader": "^0.7.10", + "@grpc/proto-loader": "^0.7.13", "@js-sdsl/ordered-map": "^4.4.2" }, "files": [ From d5edf49f6c59fd8f6e9ead2836bc30af8284284e Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 3 May 2024 14:24:44 -0700 Subject: [PATCH 28/55] Merge pull request #2735 from murgatroid99/grpc-js_linkify-it_fix root: Update dependency on jsdoc to avoid linkify-it compilation error --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index a1fd3d59e..a5733f377 100644 --- a/package.json +++ b/package.json @@ -20,14 +20,13 @@ "del": "^3.0.0", "execa": "^0.8.0", "gulp": "^4.0.1", - "gulp-jsdoc3": "^1.0.1", "gulp-jshint": "^2.0.4", "gulp-mocha": "^4.3.1", "gulp-sourcemaps": "^2.6.1", "gulp-tslint": "^8.1.1", "gulp-typescript": "^3.2.2", "gulp-util": "^3.0.8", - "jsdoc": "^3.3.2", + "jsdoc": "^4.0.3", "jshint": "^2.9.5", "make-dir": "^1.1.0", "merge2": "^1.1.0", From fec135a9800ce884b8dd414782f4bd0014821a0c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 6 May 2024 15:20:11 -0700 Subject: [PATCH 29/55] Merge pull request #2729 from sergiitk/psm-interop-common-prod-tests PSM Interop: simplify Kokoro buildscripts --- .../scripts/psm-interop-build-node.sh | 38 ++++ .../scripts/psm-interop-test-node.sh | 40 ++++ packages/grpc-js-xds/scripts/xds_k8s_lb.sh | 186 ------------------ .../grpc-js-xds/scripts/xds_k8s_url_map.sh | 163 --------------- test/kokoro/xds-interop.cfg | 24 --- test/kokoro/xds_k8s_lb.cfg | 6 +- test/kokoro/xds_k8s_url_map.cfg | 6 +- 7 files changed, 88 insertions(+), 375 deletions(-) create mode 100755 packages/grpc-js-xds/scripts/psm-interop-build-node.sh create mode 100755 packages/grpc-js-xds/scripts/psm-interop-test-node.sh delete mode 100755 packages/grpc-js-xds/scripts/xds_k8s_lb.sh delete mode 100644 packages/grpc-js-xds/scripts/xds_k8s_url_map.sh delete mode 100644 test/kokoro/xds-interop.cfg diff --git a/packages/grpc-js-xds/scripts/psm-interop-build-node.sh b/packages/grpc-js-xds/scripts/psm-interop-build-node.sh new file mode 100755 index 000000000..d52206f0e --- /dev/null +++ b/packages/grpc-js-xds/scripts/psm-interop-build-node.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Copyright 2024 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +set -eo pipefail + +####################################### +# Builds test app Docker images and pushes them to GCR. +# Called from psm_interop_kokoro_lib.sh. +# +# Globals: +# SRC_DIR: Absolute path to the source repo on Kokoro VM +# SERVER_IMAGE_NAME: Test server Docker image name +# CLIENT_IMAGE_NAME: Test client Docker image name +# GIT_COMMIT: SHA-1 of git commit being built +# DOCKER_REGISTRY: Docker registry to push to +# Outputs: +# Writes the output of docker image build stdout, stderr +####################################### +psm::lang::build_docker_images() { + local client_dockerfile="packages/grpc-js-xds/interop/Dockerfile" + + cd "${SRC_DIR}" + psm::tools::run_verbose git submodule update --init --recursive + psm::tools::run_verbose git submodule status + + psm::build::docker_images_generic "${client_dockerfile}" +} diff --git a/packages/grpc-js-xds/scripts/psm-interop-test-node.sh b/packages/grpc-js-xds/scripts/psm-interop-test-node.sh new file mode 100755 index 000000000..169cf06f2 --- /dev/null +++ b/packages/grpc-js-xds/scripts/psm-interop-test-node.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +# Copyright 2024 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +set -eo pipefail + +# Input parameters to psm:: methods of the install script. +readonly GRPC_LANGUAGE="node" +readonly BUILD_SCRIPT_DIR="$(dirname "$0")" + +# Used locally. +readonly TEST_DRIVER_INSTALL_SCRIPT_URL="https://raw.githubusercontent.com/${TEST_DRIVER_REPO_OWNER:-grpc}/psm-interop/${TEST_DRIVER_BRANCH:-main}/.kokoro/psm_interop_kokoro_lib.sh" + +psm::lang::source_install_lib() { + echo "Sourcing test driver install script from: ${TEST_DRIVER_INSTALL_SCRIPT_URL}" + local install_lib + # Download to a tmp file. + install_lib="$(mktemp -d)/psm_interop_kokoro_lib.sh" + curl -s --retry-connrefused --retry 5 -o "${install_lib}" "${TEST_DRIVER_INSTALL_SCRIPT_URL}" + # Checksum. + if command -v sha256sum &> /dev/null; then + echo "Install script checksum:" + sha256sum "${install_lib}" + fi + source "${install_lib}" +} + +psm::lang::source_install_lib +source "${BUILD_SCRIPT_DIR}/psm-interop-build-${GRPC_LANGUAGE}.sh" +psm::run "${PSM_TEST_SUITE}" diff --git a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh deleted file mode 100755 index c900a4ea5..000000000 --- a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh +++ /dev/null @@ -1,186 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2022 gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -eo pipefail - -# Constants -readonly GITHUB_REPOSITORY_NAME="grpc-node" -readonly TEST_DRIVER_INSTALL_SCRIPT_URL="https://raw.githubusercontent.com/${TEST_DRIVER_REPO_OWNER:-grpc}/psm-interop/${TEST_DRIVER_BRANCH:-main}/.kokoro/psm_interop_kokoro_lib.sh" -## xDS test client Docker images -readonly DOCKER_REGISTRY="us-docker.pkg.dev" -readonly SERVER_IMAGE_NAME="us-docker.pkg.dev/grpc-testing/psm-interop/java-server:canonical" -readonly CLIENT_IMAGE_NAME="us-docker.pkg.dev/grpc-testing/psm-interop/node-client" -readonly FORCE_IMAGE_BUILD="${FORCE_IMAGE_BUILD:-0}" -readonly BUILD_APP_PATH="packages/grpc-js-xds/interop/Dockerfile" -readonly LANGUAGE_NAME="Node" - -####################################### -# Builds test app Docker images and pushes them to GCR -# Globals: -# BUILD_APP_PATH -# CLIENT_IMAGE_NAME: Test client Docker image name -# GIT_COMMIT: SHA-1 of git commit being built -# TESTING_VERSION: version branch under test, f.e. v1.42.x, master -# Arguments: -# None -# Outputs: -# Writes the output of `gcloud builds submit` to stdout, stderr -####################################### -build_test_app_docker_images() { - echo "Building ${LANGUAGE_NAME} xDS interop test app Docker images" - - pushd "${SRC_DIR}" - docker build \ - -f "${BUILD_APP_PATH}" \ - -t "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \ - . - - gcloud -q auth configure-docker "${DOCKER_REGISTRY}" - docker push "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" - if is_version_branch "${TESTING_VERSION}"; then - tag_and_push_docker_image "${CLIENT_IMAGE_NAME}" "${GIT_COMMIT}" "${TESTING_VERSION}" - fi - popd -} - -####################################### -# Builds test app and its docker images unless they already exist -# Globals: -# CLIENT_IMAGE_NAME: Test client Docker image name -# GIT_COMMIT: SHA-1 of git commit being built -# FORCE_IMAGE_BUILD -# Arguments: -# None -# Outputs: -# Writes the output to stdout, stderr -####################################### -build_docker_images_if_needed() { - # Check if images already exist - client_tags="$(gcloud_gcr_list_image_tags "${CLIENT_IMAGE_NAME}" "${GIT_COMMIT}")" - printf "Client image: %s:%s\n" "${CLIENT_IMAGE_NAME}" "${GIT_COMMIT}" - echo "${client_tags:-Client image not found}" - - # Build if any of the images are missing, or FORCE_IMAGE_BUILD=1 - if [[ "${FORCE_IMAGE_BUILD}" == "1" || -z "${client_tags}" ]]; then - build_test_app_docker_images - else - echo "Skipping ${LANGUAGE_NAME} test app build" - fi -} - -####################################### -# Executes the test case -# Globals: -# TEST_DRIVER_FLAGFILE: Relative path to test driver flagfile -# KUBE_CONTEXT: The name of kubectl context with GKE cluster access -# SECONDARY_KUBE_CONTEXT: The name of kubectl context with secondary GKE cluster access, if any -# TEST_XML_OUTPUT_DIR: Output directory for the test xUnit XML report -# CLIENT_IMAGE_NAME: Test client Docker image name -# GIT_COMMIT: SHA-1 of git commit being built -# Arguments: -# Test case name -# Outputs: -# Writes the output of test execution to stdout, stderr -# Test xUnit report to ${TEST_XML_OUTPUT_DIR}/${test_name}/sponge_log.xml -####################################### -run_test() { - # Test driver usage: - # https://github.com/grpc/grpc/tree/master/tools/run_tests/xds_k8s_test_driver#basic-usage - local test_name="${1:?Usage: run_test test_name}" - local out_dir="${TEST_XML_OUTPUT_DIR}/${test_name}" - mkdir -pv "${out_dir}" - # testing_version is used by the framework to determine the supported PSM - # features. It's captured from Kokoro job name of the Node repo, which takes - # the form: - # grpc/node// - python3 -m "tests.${test_name}" \ - --flagfile="${TEST_DRIVER_FLAGFILE}" \ - --kube_context="${KUBE_CONTEXT}" \ - --secondary_kube_context="${SECONDARY_KUBE_CONTEXT}" \ - --client_image="${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \ - --server_image="${SERVER_IMAGE_NAME}" \ - --testing_version="${TESTING_VERSION}" \ - --force_cleanup \ - --collect_app_logs \ - --log_dir="${out_dir}" \ - --xml_output_file="${out_dir}/sponge_log.xml" \ - |& tee "${out_dir}/sponge_log.log" -} - -####################################### -# Main function: provision software necessary to execute tests, and run them -# Globals: -# KOKORO_ARTIFACTS_DIR -# GITHUB_REPOSITORY_NAME -# SRC_DIR: Populated with absolute path to the source repo -# TEST_DRIVER_REPO_DIR: Populated with the path to the repo containing -# the test driver -# TEST_DRIVER_FULL_DIR: Populated with the path to the test driver source code -# TEST_DRIVER_FLAGFILE: Populated with relative path to test driver flagfile -# TEST_XML_OUTPUT_DIR: Populated with the path to test xUnit XML report -# GIT_ORIGIN_URL: Populated with the origin URL of git repo used for the build -# GIT_COMMIT: Populated with the SHA-1 of git commit being built -# GIT_COMMIT_SHORT: Populated with the short SHA-1 of git commit being built -# KUBE_CONTEXT: Populated with name of kubectl context with GKE cluster access -# SECONDARY_KUBE_CONTEXT: Populated with name of kubectl context with secondary GKE cluster access, if any -# Arguments: -# None -# Outputs: -# Writes the output of test execution to stdout, stderr -####################################### -main() { - local script_dir - script_dir="$(dirname "$0")" - - cd "${script_dir}" - - git submodule update --init --recursive - - # Source the test driver from the master branch. - echo "Sourcing test driver install script from: ${TEST_DRIVER_INSTALL_SCRIPT_URL}" - source /dev/stdin <<< "$(curl -s "${TEST_DRIVER_INSTALL_SCRIPT_URL}")" - - activate_gke_cluster GKE_CLUSTER_PSM_LB - activate_secondary_gke_cluster GKE_CLUSTER_PSM_LB - - set -x - if [[ -n "${KOKORO_ARTIFACTS_DIR}" ]]; then - kokoro_setup_test_driver "${GITHUB_REPOSITORY_NAME}" - else - local_setup_test_driver "${script_dir}" - fi - build_docker_images_if_needed - - # Run tests - cd "${TEST_DRIVER_FULL_DIR}" - local failed_tests=0 - test_suites=( - "affinity_test" - "api_listener_test" - "baseline_test" - "change_backend_service_test" - "custom_lb_test" - "failover_test" - "outlier_detection_test" - "remove_neg_test" - "round_robin_test" - ) - for test in "${test_suites[@]}"; do - run_test $test || (( ++failed_tests )) - done - echo "Failed test suites: ${failed_tests}" -} - -main "$@" diff --git a/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh b/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh deleted file mode 100644 index d6e2c7ed4..000000000 --- a/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh +++ /dev/null @@ -1,163 +0,0 @@ -#!/usr/bin/env bash -# Copyright 2022 gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -eo pipefail - -# Constants -readonly GITHUB_REPOSITORY_NAME="grpc-node" -readonly TEST_DRIVER_INSTALL_SCRIPT_URL="https://raw.githubusercontent.com/${TEST_DRIVER_REPO_OWNER:-grpc}/psm-interop/${TEST_DRIVER_BRANCH:-main}/.kokoro/psm_interop_kokoro_lib.sh" -## xDS test client Docker images -readonly DOCKER_REGISTRY="us-docker.pkg.dev" -readonly CLIENT_IMAGE_NAME="us-docker.pkg.dev/grpc-testing/psm-interop/node-client" -readonly FORCE_IMAGE_BUILD="${FORCE_IMAGE_BUILD:-0}" -readonly BUILD_APP_PATH="packages/grpc-js-xds/interop/Dockerfile" -readonly LANGUAGE_NAME="Node" - -####################################### -# Builds test app Docker images and pushes them to GCR -# Globals: -# BUILD_APP_PATH -# CLIENT_IMAGE_NAME: Test client Docker image name -# GIT_COMMIT: SHA-1 of git commit being built -# TESTING_VERSION: version branch under test, f.e. v1.42.x, master -# Arguments: -# None -# Outputs: -# Writes the output of `gcloud builds submit` to stdout, stderr -####################################### -build_test_app_docker_images() { - echo "Building ${LANGUAGE_NAME} xDS interop test app Docker images" - - pushd "${SRC_DIR}" - docker build \ - -f "${BUILD_APP_PATH}" \ - -t "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \ - . - - gcloud -q auth configure-docker "${DOCKER_REGISTRY}" - docker push "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" - if is_version_branch "${TESTING_VERSION}"; then - tag_and_push_docker_image "${CLIENT_IMAGE_NAME}" "${GIT_COMMIT}" "${TESTING_VERSION}" - fi - popd -} - -####################################### -# Builds test app and its docker images unless they already exist -# Globals: -# CLIENT_IMAGE_NAME: Test client Docker image name -# GIT_COMMIT: SHA-1 of git commit being built -# FORCE_IMAGE_BUILD -# Arguments: -# None -# Outputs: -# Writes the output to stdout, stderr -####################################### -build_docker_images_if_needed() { - # Check if images already exist - client_tags="$(gcloud_gcr_list_image_tags "${CLIENT_IMAGE_NAME}" "${GIT_COMMIT}")" - printf "Client image: %s:%s\n" "${CLIENT_IMAGE_NAME}" "${GIT_COMMIT}" - echo "${client_tags:-Client image not found}" - - # Build if any of the images are missing, or FORCE_IMAGE_BUILD=1 - if [[ "${FORCE_IMAGE_BUILD}" == "1" || -z "${client_tags}" ]]; then - build_test_app_docker_images - else - echo "Skipping ${LANGUAGE_NAME} test app build" - fi -} - -####################################### -# Executes the test case -# Globals: -# TEST_DRIVER_FLAGFILE: Relative path to test driver flagfile -# KUBE_CONTEXT: The name of kubectl context with GKE cluster access -# TEST_XML_OUTPUT_DIR: Output directory for the test xUnit XML report -# CLIENT_IMAGE_NAME: Test client Docker image name -# GIT_COMMIT: SHA-1 of git commit being built -# TESTING_VERSION: version branch under test: used by the framework to determine the supported PSM -# features. -# Arguments: -# Test case name -# Outputs: -# Writes the output of test execution to stdout, stderr -# Test xUnit report to ${TEST_XML_OUTPUT_DIR}/${test_name}/sponge_log.xml -####################################### -run_test() { - # Test driver usage: - # https://github.com/grpc/grpc/tree/master/tools/run_tests/xds_k8s_test_driver#basic-usage - local test_name="${1:?Usage: run_test test_name}" - local out_dir="${TEST_XML_OUTPUT_DIR}/${test_name}" - mkdir -pv "${out_dir}" - set -x - python3 -m "tests.${test_name}" \ - --flagfile="${TEST_DRIVER_FLAGFILE}" \ - --flagfile="config/url-map.cfg" \ - --kube_context="${KUBE_CONTEXT}" \ - --client_image="${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \ - --testing_version="${TESTING_VERSION}" \ - --collect_app_logs \ - --log_dir="${out_dir}" \ - --xml_output_file="${out_dir}/sponge_log.xml" \ - |& tee "${out_dir}/sponge_log.log" -} - -####################################### -# Main function: provision software necessary to execute tests, and run them -# Globals: -# KOKORO_ARTIFACTS_DIR -# GITHUB_REPOSITORY_NAME -# SRC_DIR: Populated with absolute path to the source repo -# TEST_DRIVER_REPO_DIR: Populated with the path to the repo containing -# the test driver -# TEST_DRIVER_FULL_DIR: Populated with the path to the test driver source code -# TEST_DRIVER_FLAGFILE: Populated with relative path to test driver flagfile -# TEST_XML_OUTPUT_DIR: Populated with the path to test xUnit XML report -# GIT_ORIGIN_URL: Populated with the origin URL of git repo used for the build -# GIT_COMMIT: Populated with the SHA-1 of git commit being built -# GIT_COMMIT_SHORT: Populated with the short SHA-1 of git commit being built -# KUBE_CONTEXT: Populated with name of kubectl context with GKE cluster access -# Arguments: -# None -# Outputs: -# Writes the output of test execution to stdout, stderr -####################################### -main() { - local script_dir - script_dir="$(dirname "$0")" - - cd "${script_dir}" - - git submodule update --init --recursive - - # Source the test driver from the master branch. - echo "Sourcing test driver install script from: ${TEST_DRIVER_INSTALL_SCRIPT_URL}" - source /dev/stdin <<< "$(curl -s "${TEST_DRIVER_INSTALL_SCRIPT_URL}")" - - activate_gke_cluster GKE_CLUSTER_PSM_BASIC - - set -x - if [[ -n "${KOKORO_ARTIFACTS_DIR}" ]]; then - kokoro_setup_test_driver "${GITHUB_REPOSITORY_NAME}" - else - local_setup_test_driver "${script_dir}" - fi - build_docker_images_if_needed - # Run tests - cd "${TEST_DRIVER_FULL_DIR}" - run_test url_map || echo "Failed url_map test" -} - -main "$@" diff --git a/test/kokoro/xds-interop.cfg b/test/kokoro/xds-interop.cfg deleted file mode 100644 index 866cb4b58..000000000 --- a/test/kokoro/xds-interop.cfg +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2017 gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# Config file for Kokoro (in protobuf text format) - -# Location of the continuous shell script in repository. -build_file: "grpc-node/packages/grpc-js-xds/scripts/xds.sh" -timeout_mins: 360 -action { - define_artifacts { - regex: "github/grpc/reports/**" - } -} diff --git a/test/kokoro/xds_k8s_lb.cfg b/test/kokoro/xds_k8s_lb.cfg index 09aa3d17d..3efb62f29 100644 --- a/test/kokoro/xds_k8s_lb.cfg +++ b/test/kokoro/xds_k8s_lb.cfg @@ -15,7 +15,7 @@ # Config file for Kokoro (in protobuf text format) # Location of the continuous shell script in repository. -build_file: "grpc-node/packages/grpc-js-xds/scripts/xds_k8s_lb.sh" +build_file: "grpc-node/packages/grpc-js-xds/scripts/psm-interop-test-node.sh" timeout_mins: 180 action { define_artifacts { @@ -24,3 +24,7 @@ action { strip_prefix: "artifacts" } } +env_vars { + key: "PSM_TEST_SUITE" + value: "lb" +} diff --git a/test/kokoro/xds_k8s_url_map.cfg b/test/kokoro/xds_k8s_url_map.cfg index 50d523b66..bb6e6baf1 100644 --- a/test/kokoro/xds_k8s_url_map.cfg +++ b/test/kokoro/xds_k8s_url_map.cfg @@ -15,7 +15,7 @@ # Config file for Kokoro (in protobuf text format) # Location of the continuous shell script in repository. -build_file: "grpc-node/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh" +build_file: "grpc-node/packages/grpc-js-xds/scripts/psm-interop-test-node.sh" timeout_mins: 180 action { define_artifacts { @@ -24,3 +24,7 @@ action { strip_prefix: "artifacts" } } +env_vars { + key: "PSM_TEST_SUITE" + value: "url_map" +} From 87a35414021f627f01591cade9b1f9a7dcaaf5d3 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 14 May 2024 14:47:53 -0700 Subject: [PATCH 30/55] grpc-js: Fix UDS channels not reconnecting after going idle --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/resolver-uds.ts | 2 +- packages/grpc-js/test/common.ts | 51 ++++++++++++++----- packages/grpc-js/test/test-idle-timer.ts | 41 +++++++++++++++ packages/grpc-js/test/test-pick-first.ts | 2 +- .../grpc-js/test/test-server-interceptors.ts | 8 +-- 6 files changed, 86 insertions(+), 20 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index fdfab0d21..f8b070353 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.10.7", + "version": "1.10.8", "description": "gRPC Library for Node - pure JS implementation", "homepage": "https://grpc.io/", "repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js", diff --git a/packages/grpc-js/src/resolver-uds.ts b/packages/grpc-js/src/resolver-uds.ts index 3a42b18c4..4d84de9d5 100644 --- a/packages/grpc-js/src/resolver-uds.ts +++ b/packages/grpc-js/src/resolver-uds.ts @@ -50,7 +50,7 @@ class UdsResolver implements Resolver { } destroy() { - // This resolver owns no resources, so we do nothing here. + this.hasReturnedResult = false; } static getDefaultAuthority(target: GrpcUri): string { diff --git a/packages/grpc-js/test/common.ts b/packages/grpc-js/test/common.ts index fcdbb4500..5efbf9808 100644 --- a/packages/grpc-js/test/common.ts +++ b/packages/grpc-js/test/common.ts @@ -19,6 +19,8 @@ import * as loader from '@grpc/proto-loader'; import * as assert2 from './assert2'; import * as path from 'path'; import * as grpc from '../src'; +import * as fsPromises from 'fs/promises'; +import * as os from 'os'; import { GrpcObject, @@ -71,54 +73,77 @@ const serviceImpl = { export class TestServer { private server: grpc.Server; - public port: number | null = null; + private target: string | null = null; constructor(public useTls: boolean, options?: grpc.ServerOptions) { this.server = new grpc.Server(options); this.server.addService(echoService.service, serviceImpl); } - start(): Promise { - let credentials: grpc.ServerCredentials; + + private getCredentials(): grpc.ServerCredentials { if (this.useTls) { - credentials = grpc.ServerCredentials.createSsl(null, [ + return grpc.ServerCredentials.createSsl(null, [ { private_key: key, cert_chain: cert }, ]); } else { - credentials = grpc.ServerCredentials.createInsecure(); + return grpc.ServerCredentials.createInsecure(); } + } + + start(): Promise { return new Promise((resolve, reject) => { - this.server.bindAsync('localhost:0', credentials, (error, port) => { + this.server.bindAsync('localhost:0', this.getCredentials(), (error, port) => { if (error) { reject(error); return; } - this.port = port; + this.target = `localhost:${port}`; resolve(); }); }); } + startUds(): Promise { + return fsPromises.mkdtemp(path.join(os.tmpdir(), 'uds')).then(dir => { + return new Promise((resolve, reject) => { + const target = `unix://${dir}/socket`; + this.server.bindAsync(target, this.getCredentials(), (error, port) => { + if (error) { + reject(error); + return; + } + this.target = target; + resolve(); + }); + }); + }); + } + shutdown() { this.server.forceShutdown(); } + + getTarget() { + if (this.target === null) { + throw new Error('Server not yet started'); + } + return this.target; + } } export class TestClient { private client: ServiceClient; - constructor(port: number, useTls: boolean, options?: grpc.ChannelOptions) { + constructor(target: string, useTls: boolean, options?: grpc.ChannelOptions) { let credentials: grpc.ChannelCredentials; if (useTls) { credentials = grpc.credentials.createSsl(ca); } else { credentials = grpc.credentials.createInsecure(); } - this.client = new echoService(`localhost:${port}`, credentials, options); + this.client = new echoService(target, credentials, options); } static createFromServer(server: TestServer, options?: grpc.ChannelOptions) { - if (server.port === null) { - throw new Error('Cannot create client, server not started'); - } - return new TestClient(server.port, server.useTls, options); + return new TestClient(server.getTarget(), server.useTls, options); } waitForReady(deadline: grpc.Deadline, callback: (error?: Error) => void) { diff --git a/packages/grpc-js/test/test-idle-timer.ts b/packages/grpc-js/test/test-idle-timer.ts index a8f457e3f..3f2a8ed20 100644 --- a/packages/grpc-js/test/test-idle-timer.ts +++ b/packages/grpc-js/test/test-idle-timer.ts @@ -129,6 +129,47 @@ describe('Channel idle timer', () => { }); }); +describe('Channel idle timer with UDS', () => { + let server: TestServer; + let client: TestClient | null = null; + before(() => { + server = new TestServer(false); + return server.startUds(); + }); + afterEach(() => { + if (client) { + client.close(); + client = null; + } + }); + after(() => { + server.shutdown(); + }); + it('Should be able to make a request after going idle', function (done) { + this.timeout(5000); + client = TestClient.createFromServer(server, { + 'grpc.client_idle_timeout_ms': 1000, + }); + client.sendRequest(error => { + assert.ifError(error); + assert.strictEqual( + client!.getChannelState(), + grpc.connectivityState.READY + ); + setTimeout(() => { + assert.strictEqual( + client!.getChannelState(), + grpc.connectivityState.IDLE + ); + client!.sendRequest(error => { + assert.ifError(error); + done(); + }); + }, 1100); + }); + }); +}); + describe('Server idle timer', () => { let server: TestServer; let client: TestClient | null = null; diff --git a/packages/grpc-js/test/test-pick-first.ts b/packages/grpc-js/test/test-pick-first.ts index 4c2c319e1..9803a5853 100644 --- a/packages/grpc-js/test/test-pick-first.ts +++ b/packages/grpc-js/test/test-pick-first.ts @@ -811,7 +811,7 @@ describe('pick_first load balancing policy', () => { before(async () => { server = new TestServer(false); await server.start(); - client = new TestClient(server.port!, false, { + client = TestClient.createFromServer(server, { 'grpc.service_config': JSON.stringify(serviceConfig), }); }); diff --git a/packages/grpc-js/test/test-server-interceptors.ts b/packages/grpc-js/test/test-server-interceptors.ts index e94169721..5d4038599 100644 --- a/packages/grpc-js/test/test-server-interceptors.ts +++ b/packages/grpc-js/test/test-server-interceptors.ts @@ -153,7 +153,7 @@ describe('Server interceptors', () => { grpc.ServerCredentials.createInsecure(), (error, port) => { assert.ifError(error); - client = new TestClient(port, false); + client = new TestClient(`localhost:${port}`, false); done(); } ); @@ -195,7 +195,7 @@ describe('Server interceptors', () => { grpc.ServerCredentials.createInsecure(), (error, port) => { assert.ifError(error); - client = new TestClient(port, false); + client = new TestClient(`localhost:${port}`, false); done(); } ); @@ -246,7 +246,7 @@ describe('Server interceptors', () => { grpc.ServerCredentials.createInsecure(), (error, port) => { assert.ifError(error); - client = new TestClient(port, false); + client = new TestClient(`localhost:${port}`, false); done(); } ); @@ -292,7 +292,7 @@ describe('Server interceptors', () => { grpc.ServerCredentials.createInsecure(), (error, port) => { assert.ifError(error); - client = new TestClient(port, false); + client = new TestClient(`localhost:${port}`, false); done(); } ); From ad598ecbe494680cf5db170406f5862df54f848e Mon Sep 17 00:00:00 2001 From: David Fiala Date: Tue, 28 May 2024 14:53:46 -0700 Subject: [PATCH 31/55] Serverside keepalive error detection and cleanups - Bugfix: Ensure that if session.ping returns false we correctly identify fail the keepalive and connection - Bugfix: Ensure that if the interval between keepalives being sent occurs faster than the prior keepalive's timeout that we do not overwrite the reference to the prior timeout. Prior implementation could have in theory prevented a valid keepalive timeout from clearing itself. This rewrite keeps every timeout as a local (vs a shared state per session). Even if the timeout outlives the lifetime of a session, we still guard against errors by checking that the parent interval is not false-y. I reckon this could result in a short-term memory leak per session which is bounded for a maximum of keepaliveTimeoutMs. On the other hand even with that potential for a short reference hold, this implementation proposed here is more correct I think. One alternative we could do is keep a list of pending timeouts.. which is complex for a rare situation that will self resolve anyhow when keepaliveTimeoutMs is reached. - Bug Fix: keepalive intervals were being cleared with an incorrect clearTimeout before. Not sure if this was causing intervals leaks in some nodejs impls or not. (v20.13.1 seems to accept this mismatch without issue) - Rename variables for clarity, to prevent future bugs like swapping clearInterval vs clearTimeout. - Implementation is repeated in two places, per warning from https://github.com/grpc/grpc-node/pull/2756#issuecomment-2136031256 - This commit supercedes the prior PR on a master branch which was out of date. https://github.com/grpc/grpc-node/pull/2756 --- packages/grpc-js/src/server.ts | 205 +++++++++++++++++++++------------ 1 file changed, 134 insertions(+), 71 deletions(-) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index feb511b41..c4d87af38 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -1376,8 +1376,7 @@ export class Server { let connectionAgeTimer: NodeJS.Timeout | null = null; let connectionAgeGraceTimer: NodeJS.Timeout | null = null; - let keeapliveTimeTimer: NodeJS.Timeout | null = null; - let keepaliveTimeoutTimer: NodeJS.Timeout | null = null; + let keepaliveInterval: NodeJS.Timeout | null = null; let sessionClosedByServer = false; const idleTimeoutObj = this.enableIdleTimeout(session); @@ -1421,41 +1420,74 @@ export class Server { } if (this.keepaliveTimeMs < KEEPALIVE_MAX_TIME_MS) { - keeapliveTimeTimer = setInterval(() => { - keepaliveTimeoutTimer = setTimeout(() => { - sessionClosedByServer = true; - session.close(); + keepaliveInterval = setInterval(() => { + // NOTE to self: document in PR that prior implementation would overwrite the prior pending timeout + // if the timeout had not occurred before the prior interval had elapsed (bad bug) + const keepaliveTimeout = setTimeout(() => { + if (keepaliveInterval) { + clearInterval(keepaliveInterval); + keepaliveInterval = null; + sessionClosedByServer = true; + this.trace('Connection dropped by keepalive timeout'); + session.close(); + } }, this.keepaliveTimeoutMs); - keepaliveTimeoutTimer.unref?.(); + keepaliveTimeout.unref?.(); try { - session.ping( - (err: Error | null, duration: number, payload: Buffer) => { - if (keepaliveTimeoutTimer) { - clearTimeout(keepaliveTimeoutTimer); + if ( + !session.ping( + (err: Error | null, duration: number, payload: Buffer) => { + clearTimeout(keepaliveTimeout); + if (err) { + if (keepaliveInterval) { + clearInterval(keepaliveInterval); + keepaliveInterval = null; + } + sessionClosedByServer = true; + this.trace( + 'Connection dropped due to error with ping frame ' + + err.message + + ' return in ' + + duration + ); + session.close(); + } } - - if (err) { - sessionClosedByServer = true; - this.trace( - 'Connection dropped due to error of a ping frame ' + - err.message + - ' return in ' + - duration - ); - session.close(); - } - } - ); + ) + ) { + throw new Error('Server keepalive ping send failed'); + } } catch (e) { - clearTimeout(keepaliveTimeoutTimer); - // The ping can't be sent because the session is already closed + // The ping can't be sent because the session is already closed, max outstanding pings reached, etc + clearTimeout(keepaliveTimeout); + if (keepaliveInterval) { + clearInterval(keepaliveInterval); + keepaliveInterval = null; + } + this.trace( + 'Connection dropped due to error sending ping frame ' + + (e instanceof Error ? e.message : 'unknown error') + ); session.destroy(); } }, this.keepaliveTimeMs); - keeapliveTimeTimer.unref?.(); + keepaliveInterval.unref?.(); } + session.once('goaway', (errorCode, lastStreamID, opaqueData) => { + if (errorCode === http2.constants.NGHTTP2_ENHANCE_YOUR_CALM) { + this.trace('Connection dropped by client due to ENHANCE_YOUR_CALM'); + } else { + this.trace( + 'Connection dropped by client via GOAWAY with error code ' + + errorCode + ); + } + sessionClosedByServer = true; + session.destroy(); + }); + session.on('close', () => { if (!sessionClosedByServer) { this.trace( @@ -1471,11 +1503,9 @@ export class Server { clearTimeout(connectionAgeGraceTimer); } - if (keeapliveTimeTimer) { - clearInterval(keeapliveTimeTimer); - if (keepaliveTimeoutTimer) { - clearTimeout(keepaliveTimeoutTimer); - } + if (keepaliveInterval) { + clearInterval(keepaliveInterval); + keepaliveInterval = null; } if (idleTimeoutObj !== null) { @@ -1521,8 +1551,7 @@ export class Server { let connectionAgeTimer: NodeJS.Timeout | null = null; let connectionAgeGraceTimer: NodeJS.Timeout | null = null; - let keeapliveTimeTimer: NodeJS.Timeout | null = null; - let keepaliveTimeoutTimer: NodeJS.Timeout | null = null; + let keepaliveInterval: NodeJS.Timeout | null = null; let sessionClosedByServer = false; const idleTimeoutObj = this.enableIdleTimeout(session); @@ -1565,49 +1594,85 @@ export class Server { } if (this.keepaliveTimeMs < KEEPALIVE_MAX_TIME_MS) { - keeapliveTimeTimer = setInterval(() => { - keepaliveTimeoutTimer = setTimeout(() => { - sessionClosedByServer = true; - this.channelzTrace.addTrace( - 'CT_INFO', - 'Connection dropped by keepalive timeout from ' + clientAddress - ); - - session.close(); + keepaliveInterval = setInterval(() => { + const keepaliveTimeout = setTimeout(() => { + if (keepaliveInterval) { + clearInterval(keepaliveInterval); + keepaliveInterval = null; + sessionClosedByServer = true; + this.channelzTrace.addTrace( + 'CT_INFO', + 'Connection dropped by keepalive timeout from ' + clientAddress + ); + session.close(); + } }, this.keepaliveTimeoutMs); - keepaliveTimeoutTimer.unref?.(); + keepaliveTimeout.unref?.(); try { - session.ping( - (err: Error | null, duration: number, payload: Buffer) => { - if (keepaliveTimeoutTimer) { - clearTimeout(keepaliveTimeoutTimer); - } - - if (err) { - sessionClosedByServer = true; - this.channelzTrace.addTrace( - 'CT_INFO', - 'Connection dropped due to error of a ping frame ' + - err.message + - ' return in ' + - duration - ); - - session.close(); + if ( + !session.ping( + (err: Error | null, duration: number, payload: Buffer) => { + clearTimeout(keepaliveTimeout); + if (err) { + if (keepaliveInterval) { + clearInterval(keepaliveInterval); + keepaliveInterval = null; + } + sessionClosedByServer = true; + this.channelzTrace.addTrace( + 'CT_INFO', + 'Connection dropped due to error with ping frame ' + + err.message + + ' return in ' + + duration + ); + session.close(); + } } - } - ); + ) + ) { + throw new Error('Server keepalive ping send failed'); + } channelzSessionInfo.keepAlivesSent += 1; } catch (e) { - clearTimeout(keepaliveTimeoutTimer); - // The ping can't be sent because the session is already closed + // The ping can't be sent because the session is already closed, max outstanding pings reached, etc + clearTimeout(keepaliveTimeout); + if (keepaliveInterval) { + clearInterval(keepaliveInterval); + keepaliveInterval = null; + } + this.channelzTrace.addTrace( + 'CT_INFO', + 'Connection dropped due to error sending ping frame ' + + (e instanceof Error ? e.message : 'unknown error') + ); session.destroy(); } }, this.keepaliveTimeMs); - keeapliveTimeTimer.unref?.(); + keepaliveInterval.unref?.(); } + session.once('goaway', (errorCode, lastStreamID, opaqueData) => { + if (errorCode === http2.constants.NGHTTP2_ENHANCE_YOUR_CALM) { + this.channelzTrace.addTrace( + 'CT_INFO', + 'Connection dropped by client due GOAWAY of ENHANCE_YOUR_CALM from ' + + clientAddress + ); + } else { + this.channelzTrace.addTrace( + 'CT_INFO', + 'Connection dropped by client via GOAWAY with error code ' + + errorCode + + ' from ' + + clientAddress + ); + } + sessionClosedByServer = true; + session.destroy(); + }); + session.on('close', () => { if (!sessionClosedByServer) { this.channelzTrace.addTrace( @@ -1627,11 +1692,9 @@ export class Server { clearTimeout(connectionAgeGraceTimer); } - if (keeapliveTimeTimer) { - clearInterval(keeapliveTimeTimer); - if (keepaliveTimeoutTimer) { - clearTimeout(keepaliveTimeoutTimer); - } + if (keepaliveInterval) { + clearInterval(keepaliveInterval); + keepaliveInterval = null; } if (idleTimeoutObj !== null) { From 334f0dcdb5ecec9c7ece114f6d5cf8c7b0ca7ebc Mon Sep 17 00:00:00 2001 From: David Fiala Date: Tue, 28 May 2024 14:58:59 -0700 Subject: [PATCH 32/55] remove comment --- packages/grpc-js/src/server.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index c4d87af38..aed65bbb0 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -1421,8 +1421,6 @@ export class Server { if (this.keepaliveTimeMs < KEEPALIVE_MAX_TIME_MS) { keepaliveInterval = setInterval(() => { - // NOTE to self: document in PR that prior implementation would overwrite the prior pending timeout - // if the timeout had not occurred before the prior interval had elapsed (bad bug) const keepaliveTimeout = setTimeout(() => { if (keepaliveInterval) { clearInterval(keepaliveInterval); From d799a7a5bdd372cabe5e3fdadbaf728448c9045b Mon Sep 17 00:00:00 2001 From: David Fiala Date: Tue, 28 May 2024 22:26:25 -0700 Subject: [PATCH 33/55] unify server and client keepalive matching comments and discussion on first round of review from https://github.com/grpc/grpc-node/pull/2760 --- packages/grpc-js/src/server.ts | 284 ++++++++++++++++-------------- packages/grpc-js/src/transport.ts | 105 ++++++----- 2 files changed, 197 insertions(+), 192 deletions(-) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index aed65bbb0..ae3ae29ca 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -435,6 +435,14 @@ export class Server { ); } + private keepaliveTrace(text: string): void { + logging.trace( + LogVerbosity.DEBUG, + 'keepalive', + '(' + this.channelzRef.id + ') ' + text + ); + } + addProtoService(): never { throw new Error('Not implemented. Use addService() instead'); } @@ -1376,7 +1384,8 @@ export class Server { let connectionAgeTimer: NodeJS.Timeout | null = null; let connectionAgeGraceTimer: NodeJS.Timeout | null = null; - let keepaliveInterval: NodeJS.Timeout | null = null; + let keepaliveTimeout: NodeJS.Timeout | null = null; + let keepaliveDisabled = false; let sessionClosedByServer = false; const idleTimeoutObj = this.enableIdleTimeout(session); @@ -1419,72 +1428,73 @@ export class Server { connectionAgeTimer.unref?.(); } - if (this.keepaliveTimeMs < KEEPALIVE_MAX_TIME_MS) { - keepaliveInterval = setInterval(() => { - const keepaliveTimeout = setTimeout(() => { - if (keepaliveInterval) { - clearInterval(keepaliveInterval); - keepaliveInterval = null; + const clearKeepaliveTimeout = () => { + if (keepaliveTimeout) { + clearTimeout(keepaliveTimeout); + keepaliveTimeout = null; + } + }; + + const canSendPing = () => { + return ( + !keepaliveDisabled && + this.keepaliveTimeMs < KEEPALIVE_MAX_TIME_MS && + this.keepaliveTimeMs > 0 + ); + }; + + const maybeStartKeepalivePingTimer = () => { + if (!canSendPing()) { + return; + } + this.keepaliveTrace( + 'Starting keepalive timer for ' + this.keepaliveTimeMs + 'ms' + ); + keepaliveTimeout = setTimeout(() => { + clearKeepaliveTimeout(); + sendPing(); + }, this.keepaliveTimeMs); + keepaliveTimeout.unref?.(); + }; + + const sendPing = () => { + if (!canSendPing()) { + return; + } + this.keepaliveTrace( + 'Sending ping with timeout ' + this.keepaliveTimeoutMs + 'ms' + ); + const pingSentSuccessfully = session.ping( + (err: Error | null, duration: number, payload: Buffer) => { + clearKeepaliveTimeout(); + if (err) { + this.keepaliveTrace('Ping failed with error: ' + err.message); sessionClosedByServer = true; - this.trace('Connection dropped by keepalive timeout'); session.close(); + } else { + this.keepaliveTrace('Received ping response'); + maybeStartKeepalivePingTimer(); } - }, this.keepaliveTimeoutMs); - keepaliveTimeout.unref?.(); - - try { - if ( - !session.ping( - (err: Error | null, duration: number, payload: Buffer) => { - clearTimeout(keepaliveTimeout); - if (err) { - if (keepaliveInterval) { - clearInterval(keepaliveInterval); - keepaliveInterval = null; - } - sessionClosedByServer = true; - this.trace( - 'Connection dropped due to error with ping frame ' + - err.message + - ' return in ' + - duration - ); - session.close(); - } - } - ) - ) { - throw new Error('Server keepalive ping send failed'); - } - } catch (e) { - // The ping can't be sent because the session is already closed, max outstanding pings reached, etc - clearTimeout(keepaliveTimeout); - if (keepaliveInterval) { - clearInterval(keepaliveInterval); - keepaliveInterval = null; - } - this.trace( - 'Connection dropped due to error sending ping frame ' + - (e instanceof Error ? e.message : 'unknown error') - ); - session.destroy(); } - }, this.keepaliveTimeMs); - keepaliveInterval.unref?.(); - } + ); - session.once('goaway', (errorCode, lastStreamID, opaqueData) => { - if (errorCode === http2.constants.NGHTTP2_ENHANCE_YOUR_CALM) { - this.trace('Connection dropped by client due to ENHANCE_YOUR_CALM'); - } else { - this.trace( - 'Connection dropped by client via GOAWAY with error code ' + - errorCode - ); + if (!pingSentSuccessfully) { + this.keepaliveTrace('Ping failed to send'); + sessionClosedByServer = true; + session.close(); + return; } - sessionClosedByServer = true; - session.destroy(); - }); + + keepaliveTimeout = setTimeout(() => { + clearKeepaliveTimeout(); + this.keepaliveTrace('Ping timeout passed without response'); + sessionClosedByServer = true; + session.close(); + }, this.keepaliveTimeoutMs); + keepaliveTimeout.unref?.(); + }; + + maybeStartKeepalivePingTimer(); session.on('close', () => { if (!sessionClosedByServer) { @@ -1501,10 +1511,8 @@ export class Server { clearTimeout(connectionAgeGraceTimer); } - if (keepaliveInterval) { - clearInterval(keepaliveInterval); - keepaliveInterval = null; - } + keepaliveDisabled = true; + clearKeepaliveTimeout(); if (idleTimeoutObj !== null) { clearTimeout(idleTimeoutObj.timeout); @@ -1549,7 +1557,8 @@ export class Server { let connectionAgeTimer: NodeJS.Timeout | null = null; let connectionAgeGraceTimer: NodeJS.Timeout | null = null; - let keepaliveInterval: NodeJS.Timeout | null = null; + let keepaliveTimeout: NodeJS.Timeout | null = null; + let keepaliveDisabled = false; let sessionClosedByServer = false; const idleTimeoutObj = this.enableIdleTimeout(session); @@ -1591,85 +1600,90 @@ export class Server { connectionAgeTimer.unref?.(); } - if (this.keepaliveTimeMs < KEEPALIVE_MAX_TIME_MS) { - keepaliveInterval = setInterval(() => { - const keepaliveTimeout = setTimeout(() => { - if (keepaliveInterval) { - clearInterval(keepaliveInterval); - keepaliveInterval = null; - sessionClosedByServer = true; + const clearKeepaliveTimeout = () => { + if (keepaliveTimeout) { + clearTimeout(keepaliveTimeout); + keepaliveTimeout = null; + } + }; + + const canSendPing = () => { + return ( + !keepaliveDisabled && + this.keepaliveTimeMs < KEEPALIVE_MAX_TIME_MS && + this.keepaliveTimeMs > 0 + ); + }; + + const maybeStartKeepalivePingTimer = () => { + if (!canSendPing()) { + return; + } + this.keepaliveTrace( + 'Starting keepalive timer for ' + this.keepaliveTimeMs + 'ms' + ); + keepaliveTimeout = setTimeout(() => { + clearKeepaliveTimeout(); + sendPing(); + }, this.keepaliveTimeMs); + keepaliveTimeout.unref?.(); + }; + + const sendPing = () => { + if (!canSendPing()) { + return; + } + this.keepaliveTrace( + 'Sending ping with timeout ' + this.keepaliveTimeoutMs + 'ms' + ); + const pingSentSuccessfully = session.ping( + (err: Error | null, duration: number, payload: Buffer) => { + clearKeepaliveTimeout(); + if (err) { + this.keepaliveTrace('Ping failed with error: ' + err.message); this.channelzTrace.addTrace( 'CT_INFO', - 'Connection dropped by keepalive timeout from ' + clientAddress + 'Connection dropped due to error of a ping frame ' + + err.message + + ' return in ' + + duration ); + sessionClosedByServer = true; session.close(); + } else { + this.keepaliveTrace('Received ping response'); + maybeStartKeepalivePingTimer(); } - }, this.keepaliveTimeoutMs); - keepaliveTimeout.unref?.(); - - try { - if ( - !session.ping( - (err: Error | null, duration: number, payload: Buffer) => { - clearTimeout(keepaliveTimeout); - if (err) { - if (keepaliveInterval) { - clearInterval(keepaliveInterval); - keepaliveInterval = null; - } - sessionClosedByServer = true; - this.channelzTrace.addTrace( - 'CT_INFO', - 'Connection dropped due to error with ping frame ' + - err.message + - ' return in ' + - duration - ); - session.close(); - } - } - ) - ) { - throw new Error('Server keepalive ping send failed'); - } - channelzSessionInfo.keepAlivesSent += 1; - } catch (e) { - // The ping can't be sent because the session is already closed, max outstanding pings reached, etc - clearTimeout(keepaliveTimeout); - if (keepaliveInterval) { - clearInterval(keepaliveInterval); - keepaliveInterval = null; - } - this.channelzTrace.addTrace( - 'CT_INFO', - 'Connection dropped due to error sending ping frame ' + - (e instanceof Error ? e.message : 'unknown error') - ); - session.destroy(); } - }, this.keepaliveTimeMs); - keepaliveInterval.unref?.(); - } + ); - session.once('goaway', (errorCode, lastStreamID, opaqueData) => { - if (errorCode === http2.constants.NGHTTP2_ENHANCE_YOUR_CALM) { + if (!pingSentSuccessfully) { + this.keepaliveTrace('Ping failed to send'); this.channelzTrace.addTrace( 'CT_INFO', - 'Connection dropped by client due GOAWAY of ENHANCE_YOUR_CALM from ' + - clientAddress + 'Connection dropped due failure to send ping frame' ); - } else { + sessionClosedByServer = true; + session.close(); + return; + } + + channelzSessionInfo.keepAlivesSent += 1; + + keepaliveTimeout = setTimeout(() => { + clearKeepaliveTimeout(); + this.keepaliveTrace('Ping timeout passed without response'); this.channelzTrace.addTrace( 'CT_INFO', - 'Connection dropped by client via GOAWAY with error code ' + - errorCode + - ' from ' + - clientAddress + 'Connection dropped by keepalive timeout from ' + clientAddress ); - } - sessionClosedByServer = true; - session.destroy(); - }); + sessionClosedByServer = true; + session.close(); + }, this.keepaliveTimeoutMs); + keepaliveTimeout.unref?.(); + }; + + maybeStartKeepalivePingTimer(); session.on('close', () => { if (!sessionClosedByServer) { @@ -1690,10 +1704,8 @@ export class Server { clearTimeout(connectionAgeGraceTimer); } - if (keepaliveInterval) { - clearInterval(keepaliveInterval); - keepaliveInterval = null; - } + keepaliveDisabled = true; + clearKeepaliveTimeout(); if (idleTimeoutObj !== null) { clearTimeout(idleTimeoutObj.timeout); diff --git a/packages/grpc-js/src/transport.ts b/packages/grpc-js/src/transport.ts index 71d0f26b3..b56cd5b85 100644 --- a/packages/grpc-js/src/transport.ts +++ b/packages/grpc-js/src/transport.ts @@ -101,28 +101,29 @@ class Http2Transport implements Transport { /** * The amount of time in between sending pings */ - private keepaliveTimeMs = -1; + private readonly keepaliveTimeMs: number; /** * The amount of time to wait for an acknowledgement after sending a ping */ - private keepaliveTimeoutMs: number = KEEPALIVE_TIMEOUT_MS; + private readonly keepaliveTimeoutMs: number; /** - * Timer reference for timeout that indicates when to send the next ping + * Indicates whether keepalive pings should be sent without any active calls + */ + private readonly keepaliveWithoutCalls: boolean; + /** + * Timer reference indicating when to send the next ping or when the most recent ping will be considered lost. */ - private keepaliveTimerId: NodeJS.Timeout | null = null; + private keepaliveTimeout: NodeJS.Timeout | null = null; /** * Indicates that the keepalive timer ran out while there were no active * calls, and a ping should be sent the next time a call starts. */ private pendingSendKeepalivePing = false; /** - * Timer reference tracking when the most recent ping will be considered lost + * Indicates when keepalives should no longer be performed for this transport. Used to prevent a race where a + * latent session.ping(..) callback is called after the transport has been notified to disconnect. */ - private keepaliveTimeoutId: NodeJS.Timeout | null = null; - /** - * Indicates whether keepalive pings should be sent without any active calls - */ - private keepaliveWithoutCalls = false; + private keepaliveDisabled = false; private userAgent: string; @@ -182,9 +183,13 @@ class Http2Transport implements Transport { if ('grpc.keepalive_time_ms' in options) { this.keepaliveTimeMs = options['grpc.keepalive_time_ms']!; + } else { + this.keepaliveTimeMs = -1; } if ('grpc.keepalive_timeout_ms' in options) { this.keepaliveTimeoutMs = options['grpc.keepalive_timeout_ms']!; + } else { + this.keepaliveTimeoutMs = KEEPALIVE_TIMEOUT_MS; } if ('grpc.keepalive_permit_without_calls' in options) { this.keepaliveWithoutCalls = @@ -195,7 +200,6 @@ class Http2Transport implements Transport { session.once('close', () => { this.trace('session closed'); - this.stopKeepalivePings(); this.handleDisconnect(); }); @@ -383,6 +387,8 @@ class Http2Transport implements Transport { * Handle connection drops, but not GOAWAYs. */ private handleDisconnect() { + this.keepaliveDisabled = true; + this.clearKeepaliveTimeout(); this.reportDisconnectToOwner(false); /* Give calls an event loop cycle to finish naturally before reporting the * disconnnection to them. */ @@ -397,63 +403,48 @@ class Http2Transport implements Transport { this.disconnectListeners.push(listener); } - private clearKeepaliveTimer() { - if (!this.keepaliveTimerId) { - return; - } - clearTimeout(this.keepaliveTimerId); - this.keepaliveTimerId = null; - } - - private clearKeepaliveTimeout() { - if (!this.keepaliveTimeoutId) { - return; - } - clearTimeout(this.keepaliveTimeoutId); - this.keepaliveTimeoutId = null; - } - private canSendPing() { return ( + !this.keepaliveDisabled && this.keepaliveTimeMs > 0 && (this.keepaliveWithoutCalls || this.activeCalls.size > 0) ); } private maybeSendPing() { - this.clearKeepaliveTimer(); if (!this.canSendPing()) { this.pendingSendKeepalivePing = true; return; } + if (this.keepaliveTimeout) { + console.error('keepaliveTimeout is not null'); + return; + } if (this.channelzEnabled) { this.keepalivesSent += 1; } this.keepaliveTrace( 'Sending ping with timeout ' + this.keepaliveTimeoutMs + 'ms' ); - if (!this.keepaliveTimeoutId) { - this.keepaliveTimeoutId = setTimeout(() => { - this.keepaliveTrace('Ping timeout passed without response'); - this.handleDisconnect(); - }, this.keepaliveTimeoutMs); - this.keepaliveTimeoutId.unref?.(); - } - try { - this.session!.ping( - (err: Error | null, duration: number, payload: Buffer) => { - if (err) { - this.keepaliveTrace('Ping failed with error ' + err.message); - this.handleDisconnect(); - } + this.keepaliveTimeout = setTimeout(() => { + this.keepaliveTrace('Ping timeout passed without response'); + this.handleDisconnect(); + }, this.keepaliveTimeoutMs); + this.keepaliveTimeout.unref?.(); + const pingSentSuccessfully = this.session.ping( + (err: Error | null, duration: number, payload: Buffer) => { + this.clearKeepaliveTimeout(); + if (err) { + this.keepaliveTrace('Ping failed with error ' + err.message); + this.handleDisconnect(); + } else { this.keepaliveTrace('Received ping response'); - this.clearKeepaliveTimeout(); this.maybeStartKeepalivePingTimer(); } - ); - } catch (e) { - /* If we fail to send a ping, the connection is no longer functional, so - * we should discard it. */ + } + ); + if (!pingSentSuccessfully) { + this.keepaliveTrace('Ping failed to send'); this.handleDisconnect(); } } @@ -471,25 +462,27 @@ class Http2Transport implements Transport { if (this.pendingSendKeepalivePing) { this.pendingSendKeepalivePing = false; this.maybeSendPing(); - } else if (!this.keepaliveTimerId && !this.keepaliveTimeoutId) { + } else if (!this.keepaliveTimeout) { this.keepaliveTrace( 'Starting keepalive timer for ' + this.keepaliveTimeMs + 'ms' ); - this.keepaliveTimerId = setTimeout(() => { + this.keepaliveTimeout = setTimeout(() => { this.maybeSendPing(); }, this.keepaliveTimeMs); - this.keepaliveTimerId.unref?.(); + this.keepaliveTimeout.unref?.(); } /* Otherwise, there is already either a keepalive timer or a ping pending, * wait for those to resolve. */ } - private stopKeepalivePings() { - if (this.keepaliveTimerId) { - clearTimeout(this.keepaliveTimerId); - this.keepaliveTimerId = null; + /** + * Clears whichever keepalive timeout is currently active, if any. + */ + private clearKeepaliveTimeout() { + if (this.keepaliveTimeout) { + clearTimeout(this.keepaliveTimeout); + this.keepaliveTimeout = null; } - this.clearKeepaliveTimeout(); } private removeActiveCall(call: Http2SubchannelCall) { @@ -533,7 +526,7 @@ class Http2Transport implements Transport { * error here. */ try { - http2Stream = this.session!.request(headers); + http2Stream = this.session.request(headers); } catch (e) { this.handleDisconnect(); throw e; From 577b4b4748fbd12e2576e465d837f1ae320a096f Mon Sep 17 00:00:00 2001 From: David Fiala Date: Tue, 28 May 2024 22:32:09 -0700 Subject: [PATCH 34/55] add keepalive server trace back in to match channelz vs non-channelz trace behavior --- packages/grpc-js/src/server.ts | 77 ++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index ae3ae29ca..88846eaf5 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -18,43 +18,67 @@ import * as http2 from 'http2'; import * as util from 'util'; +import { CipherNameAndProtocol, TLSSocket } from 'tls'; import { ServiceError } from './call'; -import { Status, LogVerbosity } from './constants'; +import { PartialStatusObject } from './call-interface'; +import { ChannelOptions } from './channel-options'; +import { + ChannelzCallTracker, + ChannelzCallTrackerStub, + ChannelzChildrenTracker, + ChannelzChildrenTrackerStub, + ChannelzTrace, + ChannelzTraceStub, + ServerInfo, + ServerRef, + SocketInfo, + SocketRef, + TlsInfo, + registerChannelzServer, + registerChannelzSocket, + unregisterChannelzRef, +} from './channelz'; +import { LogVerbosity, Status } from './constants'; +import * as logging from './logging'; import { Deserialize, Serialize, ServiceDefinition } from './make-client'; import { Metadata } from './metadata'; +import { + ResolverListener, + createResolver, + mapUriDefaultScheme, +} from './resolver'; import { BidiStreamingHandler, ClientStreamingHandler, HandleCall, Handler, HandlerType, - sendUnaryData, ServerDuplexStream, ServerDuplexStreamImpl, + ServerErrorResponse, ServerReadableStream, + ServerStatusResponse, ServerStreamingHandler, ServerUnaryCall, ServerWritableStream, ServerWritableStreamImpl, UnaryHandler, - ServerErrorResponse, - ServerStatusResponse, + sendUnaryData, serverErrorToStatus, } from './server-call'; import { ServerCredentials } from './server-credentials'; -import { ChannelOptions } from './channel-options'; import { - createResolver, - ResolverListener, - mapUriDefaultScheme, -} from './resolver'; -import * as logging from './logging'; + ServerInterceptingCallInterface, + ServerInterceptor, + getServerInterceptingCall, +} from './server-interceptors'; import { SubchannelAddress, isTcpSubchannelAddress, - subchannelAddressToString, stringToSubchannelAddress, + subchannelAddressToString, } from './subchannel-address'; +import { CallEventTracker } from './transport'; import { GrpcUri, combineHostPort, @@ -62,30 +86,6 @@ import { splitHostPort, uriToString, } from './uri-parser'; -import { - ChannelzCallTracker, - ChannelzCallTrackerStub, - ChannelzChildrenTracker, - ChannelzChildrenTrackerStub, - ChannelzTrace, - ChannelzTraceStub, - registerChannelzServer, - registerChannelzSocket, - ServerInfo, - ServerRef, - SocketInfo, - SocketRef, - TlsInfo, - unregisterChannelzRef, -} from './channelz'; -import { CipherNameAndProtocol, TLSSocket } from 'tls'; -import { - ServerInterceptingCallInterface, - ServerInterceptor, - getServerInterceptingCall, -} from './server-interceptors'; -import { PartialStatusObject } from './call-interface'; -import { CallEventTracker } from './transport'; const UNLIMITED_CONNECTION_AGE_MS = ~(1 << 31); const KEEPALIVE_MAX_TIME_MS = ~(1 << 31); @@ -1469,6 +1469,12 @@ export class Server { clearKeepaliveTimeout(); if (err) { this.keepaliveTrace('Ping failed with error: ' + err.message); + this.trace( + 'Connection dropped due to error of a ping frame ' + + err.message + + ' return in ' + + duration + ); sessionClosedByServer = true; session.close(); } else { @@ -1480,6 +1486,7 @@ export class Server { if (!pingSentSuccessfully) { this.keepaliveTrace('Ping failed to send'); + this.trace('Connection dropped due to failure to send ping frame'); sessionClosedByServer = true; session.close(); return; From 7883164137c4994af074201818a81108bda8204a Mon Sep 17 00:00:00 2001 From: David Fiala Date: Tue, 28 May 2024 22:35:40 -0700 Subject: [PATCH 35/55] return imports back to original order --- packages/grpc-js/src/server.ts | 70 +++++++++++++++++----------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 88846eaf5..ad463b957 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -18,67 +18,43 @@ import * as http2 from 'http2'; import * as util from 'util'; -import { CipherNameAndProtocol, TLSSocket } from 'tls'; import { ServiceError } from './call'; -import { PartialStatusObject } from './call-interface'; -import { ChannelOptions } from './channel-options'; -import { - ChannelzCallTracker, - ChannelzCallTrackerStub, - ChannelzChildrenTracker, - ChannelzChildrenTrackerStub, - ChannelzTrace, - ChannelzTraceStub, - ServerInfo, - ServerRef, - SocketInfo, - SocketRef, - TlsInfo, - registerChannelzServer, - registerChannelzSocket, - unregisterChannelzRef, -} from './channelz'; -import { LogVerbosity, Status } from './constants'; -import * as logging from './logging'; +import { Status, LogVerbosity } from './constants'; import { Deserialize, Serialize, ServiceDefinition } from './make-client'; import { Metadata } from './metadata'; -import { - ResolverListener, - createResolver, - mapUriDefaultScheme, -} from './resolver'; import { BidiStreamingHandler, ClientStreamingHandler, HandleCall, Handler, HandlerType, + sendUnaryData, ServerDuplexStream, ServerDuplexStreamImpl, - ServerErrorResponse, ServerReadableStream, - ServerStatusResponse, ServerStreamingHandler, ServerUnaryCall, ServerWritableStream, ServerWritableStreamImpl, UnaryHandler, - sendUnaryData, + ServerErrorResponse, + ServerStatusResponse, serverErrorToStatus, } from './server-call'; import { ServerCredentials } from './server-credentials'; +import { ChannelOptions } from './channel-options'; import { - ServerInterceptingCallInterface, - ServerInterceptor, - getServerInterceptingCall, -} from './server-interceptors'; + createResolver, + ResolverListener, + mapUriDefaultScheme, +} from './resolver'; +import * as logging from './logging'; import { SubchannelAddress, isTcpSubchannelAddress, - stringToSubchannelAddress, subchannelAddressToString, + stringToSubchannelAddress, } from './subchannel-address'; -import { CallEventTracker } from './transport'; import { GrpcUri, combineHostPort, @@ -86,6 +62,30 @@ import { splitHostPort, uriToString, } from './uri-parser'; +import { + ChannelzCallTracker, + ChannelzCallTrackerStub, + ChannelzChildrenTracker, + ChannelzChildrenTrackerStub, + ChannelzTrace, + ChannelzTraceStub, + registerChannelzServer, + registerChannelzSocket, + ServerInfo, + ServerRef, + SocketInfo, + SocketRef, + TlsInfo, + unregisterChannelzRef, +} from './channelz'; +import { CipherNameAndProtocol, TLSSocket } from 'tls'; +import { + ServerInterceptingCallInterface, + ServerInterceptor, + getServerInterceptingCall, +} from './server-interceptors'; +import { PartialStatusObject } from './call-interface'; +import { CallEventTracker } from './transport'; const UNLIMITED_CONNECTION_AGE_MS = ~(1 << 31); const KEEPALIVE_MAX_TIME_MS = ~(1 << 31); From 19cdc1233c40b4586d29fc6454e95152af4661f6 Mon Sep 17 00:00:00 2001 From: David Fiala Date: Tue, 28 May 2024 22:37:24 -0700 Subject: [PATCH 36/55] another missing trace message for parity --- packages/grpc-js/src/server.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index ad463b957..9ed9b8d7e 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -1495,6 +1495,7 @@ export class Server { keepaliveTimeout = setTimeout(() => { clearKeepaliveTimeout(); this.keepaliveTrace('Ping timeout passed without response'); + this.trace('Connection dropped by keepalive timeout'); sessionClosedByServer = true; session.close(); }, this.keepaliveTimeoutMs); From bed5e85af9b5214c5827d9cb7c1465a8ee57ee7c Mon Sep 17 00:00:00 2001 From: David Fiala Date: Tue, 28 May 2024 22:43:51 -0700 Subject: [PATCH 37/55] resolve hoisting --- packages/grpc-js/src/server.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 9ed9b8d7e..2dc3c2f3d 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -1623,6 +1623,9 @@ export class Server { ); }; + /* eslint-disable-next-line prefer-const */ + let sendPing: () => void; // hoisted for use in maybeStartKeepalivePingTimer + const maybeStartKeepalivePingTimer = () => { if (!canSendPing()) { return; @@ -1637,7 +1640,7 @@ export class Server { keepaliveTimeout.unref?.(); }; - const sendPing = () => { + sendPing = () => { if (!canSendPing()) { return; } From d325b5fff38a240cb3b43a70e0c7ce326c1f692e Mon Sep 17 00:00:00 2001 From: David Fiala Date: Tue, 28 May 2024 22:46:48 -0700 Subject: [PATCH 38/55] hoist in second location --- packages/grpc-js/src/server.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 2dc3c2f3d..b749740d4 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -1443,6 +1443,9 @@ export class Server { ); }; + /* eslint-disable-next-line prefer-const */ + let sendPing: () => void; // hoisted for use in maybeStartKeepalivePingTimer + const maybeStartKeepalivePingTimer = () => { if (!canSendPing()) { return; @@ -1457,7 +1460,7 @@ export class Server { keepaliveTimeout.unref?.(); }; - const sendPing = () => { + sendPing = () => { if (!canSendPing()) { return; } From a77d94f7c62045253343349d6b140795b8db73a4 Mon Sep 17 00:00:00 2001 From: David Fiala Date: Wed, 29 May 2024 10:37:40 -0700 Subject: [PATCH 39/55] Based on grpc/grpc-node#2139 I wrapped http2session.ping in a try-catch block again --- packages/grpc-js/src/server.ts | 98 ++++++++++++++++++------------- packages/grpc-js/src/transport.ts | 33 +++++++---- 2 files changed, 78 insertions(+), 53 deletions(-) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index b749740d4..8db0aac5a 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -1467,29 +1467,35 @@ export class Server { this.keepaliveTrace( 'Sending ping with timeout ' + this.keepaliveTimeoutMs + 'ms' ); - const pingSentSuccessfully = session.ping( - (err: Error | null, duration: number, payload: Buffer) => { - clearKeepaliveTimeout(); - if (err) { - this.keepaliveTrace('Ping failed with error: ' + err.message); - this.trace( - 'Connection dropped due to error of a ping frame ' + - err.message + - ' return in ' + - duration - ); - sessionClosedByServer = true; - session.close(); - } else { - this.keepaliveTrace('Received ping response'); - maybeStartKeepalivePingTimer(); + let pingSendError = ''; + try { + const pingSentSuccessfully = session.ping( + (err: Error | null, duration: number, payload: Buffer) => { + clearKeepaliveTimeout(); + if (err) { + this.keepaliveTrace('Ping failed with error: ' + err.message); + sessionClosedByServer = true; + session.close(); + } else { + this.keepaliveTrace('Received ping response'); + maybeStartKeepalivePingTimer(); + } } + ); + if (!pingSentSuccessfully) { + pingSendError = 'Ping returned false'; } - ); + } catch (e) { + // grpc/grpc-node#2139 + pingSendError = + (e instanceof Error ? e.message : '') || 'Unknown error'; + } - if (!pingSentSuccessfully) { - this.keepaliveTrace('Ping failed to send'); - this.trace('Connection dropped due to failure to send ping frame'); + if (pingSendError) { + this.keepaliveTrace('Ping send failed: ' + pingSendError); + this.trace( + 'Connection dropped due to ping send error: ' + pingSendError + ); sessionClosedByServer = true; session.close(); return; @@ -1650,32 +1656,42 @@ export class Server { this.keepaliveTrace( 'Sending ping with timeout ' + this.keepaliveTimeoutMs + 'ms' ); - const pingSentSuccessfully = session.ping( - (err: Error | null, duration: number, payload: Buffer) => { - clearKeepaliveTimeout(); - if (err) { - this.keepaliveTrace('Ping failed with error: ' + err.message); - this.channelzTrace.addTrace( - 'CT_INFO', - 'Connection dropped due to error of a ping frame ' + - err.message + - ' return in ' + - duration - ); - sessionClosedByServer = true; - session.close(); - } else { - this.keepaliveTrace('Received ping response'); - maybeStartKeepalivePingTimer(); + let pingSendError = ''; + try { + const pingSentSuccessfully = session.ping( + (err: Error | null, duration: number, payload: Buffer) => { + clearKeepaliveTimeout(); + if (err) { + this.keepaliveTrace('Ping failed with error: ' + err.message); + this.channelzTrace.addTrace( + 'CT_INFO', + 'Connection dropped due to error of a ping frame ' + + err.message + + ' return in ' + + duration + ); + sessionClosedByServer = true; + session.close(); + } else { + this.keepaliveTrace('Received ping response'); + maybeStartKeepalivePingTimer(); + } } + ); + if (!pingSentSuccessfully) { + pingSendError = 'Ping returned false'; } - ); + } catch (e) { + // grpc/grpc-node#2139 + pingSendError = + (e instanceof Error ? e.message : '') || 'Unknown error'; + } - if (!pingSentSuccessfully) { - this.keepaliveTrace('Ping failed to send'); + if (pingSendError) { + this.keepaliveTrace('Ping send failed: ' + pingSendError); this.channelzTrace.addTrace( 'CT_INFO', - 'Connection dropped due failure to send ping frame' + 'Connection dropped due to ping send error: ' + pingSendError ); sessionClosedByServer = true; session.close(); diff --git a/packages/grpc-js/src/transport.ts b/packages/grpc-js/src/transport.ts index b56cd5b85..a3f5a78f5 100644 --- a/packages/grpc-js/src/transport.ts +++ b/packages/grpc-js/src/transport.ts @@ -431,20 +431,29 @@ class Http2Transport implements Transport { this.handleDisconnect(); }, this.keepaliveTimeoutMs); this.keepaliveTimeout.unref?.(); - const pingSentSuccessfully = this.session.ping( - (err: Error | null, duration: number, payload: Buffer) => { - this.clearKeepaliveTimeout(); - if (err) { - this.keepaliveTrace('Ping failed with error ' + err.message); - this.handleDisconnect(); - } else { - this.keepaliveTrace('Received ping response'); - this.maybeStartKeepalivePingTimer(); + let pingSendError = ''; + try { + const pingSentSuccessfully = this.session.ping( + (err: Error | null, duration: number, payload: Buffer) => { + this.clearKeepaliveTimeout(); + if (err) { + this.keepaliveTrace('Ping failed with error ' + err.message); + this.handleDisconnect(); + } else { + this.keepaliveTrace('Received ping response'); + this.maybeStartKeepalivePingTimer(); + } } + ); + if (!pingSentSuccessfully) { + pingSendError = 'Ping returned false'; } - ); - if (!pingSentSuccessfully) { - this.keepaliveTrace('Ping failed to send'); + } catch (e) { + // grpc/grpc-node#2139 + pingSendError = (e instanceof Error ? e.message : '') || 'Unknown error'; + } + if (pingSendError) { + this.keepaliveTrace('Ping send failed: ' + pingSendError); this.handleDisconnect(); } } From c2da436a8e089c9168c8a430347819442e86ac6a Mon Sep 17 00:00:00 2001 From: David Fiala Date: Wed, 29 May 2024 15:09:55 -0700 Subject: [PATCH 40/55] remove keepaliveDisabled from server.ts. rename keepaliveTimer. --- packages/grpc-js/src/server.ts | 24 ++++++++++-------------- packages/grpc-js/src/transport.ts | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 8db0aac5a..33db41004 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -1384,8 +1384,7 @@ export class Server { let connectionAgeTimer: NodeJS.Timeout | null = null; let connectionAgeGraceTimer: NodeJS.Timeout | null = null; - let keepaliveTimeout: NodeJS.Timeout | null = null; - let keepaliveDisabled = false; + let keepaliveTimer: NodeJS.Timeout | null = null; let sessionClosedByServer = false; const idleTimeoutObj = this.enableIdleTimeout(session); @@ -1429,15 +1428,15 @@ export class Server { } const clearKeepaliveTimeout = () => { - if (keepaliveTimeout) { - clearTimeout(keepaliveTimeout); - keepaliveTimeout = null; + if (keepaliveTimer) { + clearTimeout(keepaliveTimer); + keepaliveTimer = null; } }; const canSendPing = () => { return ( - !keepaliveDisabled && + !session.destroyed && this.keepaliveTimeMs < KEEPALIVE_MAX_TIME_MS && this.keepaliveTimeMs > 0 ); @@ -1453,11 +1452,11 @@ export class Server { this.keepaliveTrace( 'Starting keepalive timer for ' + this.keepaliveTimeMs + 'ms' ); - keepaliveTimeout = setTimeout(() => { + keepaliveTimer = setTimeout(() => { clearKeepaliveTimeout(); sendPing(); }, this.keepaliveTimeMs); - keepaliveTimeout.unref?.(); + keepaliveTimer.unref?.(); }; sendPing = () => { @@ -1501,14 +1500,14 @@ export class Server { return; } - keepaliveTimeout = setTimeout(() => { + keepaliveTimer = setTimeout(() => { clearKeepaliveTimeout(); this.keepaliveTrace('Ping timeout passed without response'); this.trace('Connection dropped by keepalive timeout'); sessionClosedByServer = true; session.close(); }, this.keepaliveTimeoutMs); - keepaliveTimeout.unref?.(); + keepaliveTimer.unref?.(); }; maybeStartKeepalivePingTimer(); @@ -1528,7 +1527,6 @@ export class Server { clearTimeout(connectionAgeGraceTimer); } - keepaliveDisabled = true; clearKeepaliveTimeout(); if (idleTimeoutObj !== null) { @@ -1575,7 +1573,6 @@ export class Server { let connectionAgeTimer: NodeJS.Timeout | null = null; let connectionAgeGraceTimer: NodeJS.Timeout | null = null; let keepaliveTimeout: NodeJS.Timeout | null = null; - let keepaliveDisabled = false; let sessionClosedByServer = false; const idleTimeoutObj = this.enableIdleTimeout(session); @@ -1626,7 +1623,7 @@ export class Server { const canSendPing = () => { return ( - !keepaliveDisabled && + !session.destroyed && this.keepaliveTimeMs < KEEPALIVE_MAX_TIME_MS && this.keepaliveTimeMs > 0 ); @@ -1734,7 +1731,6 @@ export class Server { clearTimeout(connectionAgeGraceTimer); } - keepaliveDisabled = true; clearKeepaliveTimeout(); if (idleTimeoutObj !== null) { diff --git a/packages/grpc-js/src/transport.ts b/packages/grpc-js/src/transport.ts index a3f5a78f5..b7ac2df7b 100644 --- a/packages/grpc-js/src/transport.ts +++ b/packages/grpc-js/src/transport.ts @@ -113,7 +113,7 @@ class Http2Transport implements Transport { /** * Timer reference indicating when to send the next ping or when the most recent ping will be considered lost. */ - private keepaliveTimeout: NodeJS.Timeout | null = null; + private keepaliveTimer: NodeJS.Timeout | null = null; /** * Indicates that the keepalive timer ran out while there were no active * calls, and a ping should be sent the next time a call starts. @@ -416,7 +416,7 @@ class Http2Transport implements Transport { this.pendingSendKeepalivePing = true; return; } - if (this.keepaliveTimeout) { + if (this.keepaliveTimer) { console.error('keepaliveTimeout is not null'); return; } @@ -426,11 +426,11 @@ class Http2Transport implements Transport { this.keepaliveTrace( 'Sending ping with timeout ' + this.keepaliveTimeoutMs + 'ms' ); - this.keepaliveTimeout = setTimeout(() => { + this.keepaliveTimer = setTimeout(() => { this.keepaliveTrace('Ping timeout passed without response'); this.handleDisconnect(); }, this.keepaliveTimeoutMs); - this.keepaliveTimeout.unref?.(); + this.keepaliveTimer.unref?.(); let pingSendError = ''; try { const pingSentSuccessfully = this.session.ping( @@ -471,14 +471,14 @@ class Http2Transport implements Transport { if (this.pendingSendKeepalivePing) { this.pendingSendKeepalivePing = false; this.maybeSendPing(); - } else if (!this.keepaliveTimeout) { + } else if (!this.keepaliveTimer) { this.keepaliveTrace( 'Starting keepalive timer for ' + this.keepaliveTimeMs + 'ms' ); - this.keepaliveTimeout = setTimeout(() => { + this.keepaliveTimer = setTimeout(() => { this.maybeSendPing(); }, this.keepaliveTimeMs); - this.keepaliveTimeout.unref?.(); + this.keepaliveTimer.unref?.(); } /* Otherwise, there is already either a keepalive timer or a ping pending, * wait for those to resolve. */ @@ -488,9 +488,9 @@ class Http2Transport implements Transport { * Clears whichever keepalive timeout is currently active, if any. */ private clearKeepaliveTimeout() { - if (this.keepaliveTimeout) { - clearTimeout(this.keepaliveTimeout); - this.keepaliveTimeout = null; + if (this.keepaliveTimer) { + clearTimeout(this.keepaliveTimer); + this.keepaliveTimer = null; } } From 7719e37c8310bc4a278078ae5b018445454ae006 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 5 Jun 2024 17:55:56 -0700 Subject: [PATCH 41/55] grpc-js: Fix client hang when receiving extra messages for a unary response --- packages/grpc-js/src/client.ts | 9 +- packages/grpc-js/test/test-server-errors.ts | 92 +++++++++++++++++++++ 2 files changed, 97 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js/src/client.ts b/packages/grpc-js/src/client.ts index 995d5b328..dc75ac482 100644 --- a/packages/grpc-js/src/client.ts +++ b/packages/grpc-js/src/client.ts @@ -330,7 +330,7 @@ export class Client { // eslint-disable-next-line @typescript-eslint/no-explicit-any onReceiveMessage(message: any) { if (responseMessage !== null) { - call.cancelWithStatus(Status.INTERNAL, 'Too many responses received'); + call.cancelWithStatus(Status.UNIMPLEMENTED, 'Too many responses received'); } responseMessage = message; }, @@ -345,7 +345,7 @@ export class Client { callProperties.callback!( callErrorFromStatus( { - code: Status.INTERNAL, + code: Status.UNIMPLEMENTED, details: 'No message received', metadata: status.metadata, }, @@ -463,9 +463,10 @@ export class Client { // eslint-disable-next-line @typescript-eslint/no-explicit-any onReceiveMessage(message: any) { if (responseMessage !== null) { - call.cancelWithStatus(Status.INTERNAL, 'Too many responses received'); + call.cancelWithStatus(Status.UNIMPLEMENTED, 'Too many responses received'); } responseMessage = message; + call.startRead(); }, onReceiveStatus(status: StatusObject) { if (receivedStatus) { @@ -478,7 +479,7 @@ export class Client { callProperties.callback!( callErrorFromStatus( { - code: Status.INTERNAL, + code: Status.UNIMPLEMENTED, details: 'No message received', metadata: status.metadata, }, diff --git a/packages/grpc-js/test/test-server-errors.ts b/packages/grpc-js/test/test-server-errors.ts index 24ccfeef3..7367a907c 100644 --- a/packages/grpc-js/test/test-server-errors.ts +++ b/packages/grpc-js/test/test-server-errors.ts @@ -286,6 +286,98 @@ describe('Server serialization failure handling', () => { }); }); +describe('Cardinality violations', () => { + let client: ServiceClient; + let server: Server; + let responseCount: number = 1; + const testMessage = Buffer.from([]); + before(done => { + const serverServiceDefinition = { + testMethod: { + path: '/TestService/TestMethod/', + requestStream: false, + responseStream: true, + requestSerialize: identity, + requestDeserialize: identity, + responseDeserialize: identity, + responseSerialize: identity + } + }; + const clientServiceDefinition = { + testMethod: { + path: '/TestService/TestMethod/', + requestStream: true, + responseStream: false, + requestSerialize: identity, + requestDeserialize: identity, + responseDeserialize: identity, + responseSerialize: identity + } + }; + const TestClient = grpc.makeClientConstructor(clientServiceDefinition, 'TestService'); + server = new grpc.Server(); + server.addService(serverServiceDefinition, { + testMethod(stream: ServerWritableStream) { + for (let i = 0; i < responseCount; i++) { + stream.write(testMessage); + } + stream.end(); + } + }); + server.bindAsync('localhost:0', serverInsecureCreds, (error, port) => { + assert.ifError(error); + client = new TestClient(`localhost:${port}`, clientInsecureCreds); + done(); + }); + }); + beforeEach(() => { + responseCount = 1; + }); + after(done => { + client.close(); + server.tryShutdown(done); + }); + it('Should fail if the client sends too few messages', done => { + const call = client.testMethod((err: ServiceError, data: any) => { + assert(err); + assert.strictEqual(err.code, grpc.status.UNIMPLEMENTED); + done(); + }); + call.end(); + }); + it('Should fail if the client sends too many messages', done => { + const call = client.testMethod((err: ServiceError, data: any) => { + assert(err); + assert.strictEqual(err.code, grpc.status.UNIMPLEMENTED); + done(); + }); + call.write(testMessage); + call.write(testMessage); + call.end(); + }); + it('Should fail if the server sends too few messages', done => { + responseCount = 0; + const call = client.testMethod((err: ServiceError, data: any) => { + assert(err); + assert.strictEqual(err.code, grpc.status.UNIMPLEMENTED); + done(); + }); + call.write(testMessage); + call.end(); + }); + it('Should fail if the server sends too many messages', done => { + responseCount = 2; + const call = client.testMethod((err: ServiceError, data: any) => { + assert(err); + assert.strictEqual(err.code, grpc.status.UNIMPLEMENTED); + done(); + }); + call.write(testMessage); + call.end(); + }); + +}); + describe('Other conditions', () => { let client: ServiceClient; let server: Server; From 3c5ab229b1838f624ace174eef850f7cb611df9e Mon Sep 17 00:00:00 2001 From: David Fiala Date: Wed, 5 Jun 2024 19:01:02 -0700 Subject: [PATCH 42/55] per discussion, avoid tracking keepalive disabled state and instead depend on whether the session is destroyed --- packages/grpc-js/src/transport.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/grpc-js/src/transport.ts b/packages/grpc-js/src/transport.ts index b7ac2df7b..ab5438211 100644 --- a/packages/grpc-js/src/transport.ts +++ b/packages/grpc-js/src/transport.ts @@ -119,11 +119,6 @@ class Http2Transport implements Transport { * calls, and a ping should be sent the next time a call starts. */ private pendingSendKeepalivePing = false; - /** - * Indicates when keepalives should no longer be performed for this transport. Used to prevent a race where a - * latent session.ping(..) callback is called after the transport has been notified to disconnect. - */ - private keepaliveDisabled = false; private userAgent: string; @@ -387,7 +382,6 @@ class Http2Transport implements Transport { * Handle connection drops, but not GOAWAYs. */ private handleDisconnect() { - this.keepaliveDisabled = true; this.clearKeepaliveTimeout(); this.reportDisconnectToOwner(false); /* Give calls an event loop cycle to finish naturally before reporting the @@ -396,6 +390,7 @@ class Http2Transport implements Transport { for (const call of this.activeCalls) { call.onDisconnect(); } + this.session.destroy(); }); } @@ -405,7 +400,7 @@ class Http2Transport implements Transport { private canSendPing() { return ( - !this.keepaliveDisabled && + !this.session.destroyed && this.keepaliveTimeMs > 0 && (this.keepaliveWithoutCalls || this.activeCalls.size > 0) ); From e64d816d7df6d6cde62314beb67d11f1e0a8c79e Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 5 Jun 2024 11:22:23 -0700 Subject: [PATCH 43/55] grpc-js: Avoid buffering significantly more than max_receive_message_size per received message (1.10.x) --- packages/grpc-js/src/compression-filter.ts | 67 ++++++++++---- packages/grpc-js/src/internal-channel.ts | 2 - .../grpc-js/src/max-message-size-filter.ts | 88 ------------------- packages/grpc-js/src/server-interceptors.ts | 88 ++++++++++++------- packages/grpc-js/src/stream-decoder.ts | 5 ++ packages/grpc-js/src/subchannel-call.ts | 14 ++- packages/grpc-js/src/transport.ts | 7 +- .../grpc-js/test/fixtures/test_service.proto | 1 + packages/grpc-js/test/test-server-errors.ts | 49 ++++++++++- 9 files changed, 173 insertions(+), 148 deletions(-) delete mode 100644 packages/grpc-js/src/max-message-size-filter.ts diff --git a/packages/grpc-js/src/compression-filter.ts b/packages/grpc-js/src/compression-filter.ts index 136311ad5..f1600b36d 100644 --- a/packages/grpc-js/src/compression-filter.ts +++ b/packages/grpc-js/src/compression-filter.ts @@ -21,7 +21,7 @@ import { WriteObject, WriteFlags } from './call-interface'; import { Channel } from './channel'; import { ChannelOptions } from './channel-options'; import { CompressionAlgorithms } from './compression-algorithms'; -import { LogVerbosity } from './constants'; +import { DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH, LogVerbosity, Status } from './constants'; import { BaseFilter, Filter, FilterFactory } from './filter'; import * as logging from './logging'; import { Metadata, MetadataValue } from './metadata'; @@ -98,6 +98,10 @@ class IdentityHandler extends CompressionHandler { } class DeflateHandler extends CompressionHandler { + constructor(private maxRecvMessageLength: number) { + super(); + } + compressMessage(message: Buffer) { return new Promise((resolve, reject) => { zlib.deflate(message, (err, output) => { @@ -112,18 +116,34 @@ class DeflateHandler extends CompressionHandler { decompressMessage(message: Buffer) { return new Promise((resolve, reject) => { - zlib.inflate(message, (err, output) => { - if (err) { - reject(err); - } else { - resolve(output); + let totalLength = 0; + const messageParts: Buffer[] = []; + const decompresser = zlib.createInflate(); + decompresser.on('data', (chunk: Buffer) => { + messageParts.push(chunk); + totalLength += chunk.byteLength; + if (this.maxRecvMessageLength !== -1 && totalLength > this.maxRecvMessageLength) { + decompresser.destroy(); + reject({ + code: Status.RESOURCE_EXHAUSTED, + details: `Received message that decompresses to a size larger than ${this.maxRecvMessageLength}` + }); } }); + decompresser.on('end', () => { + resolve(Buffer.concat(messageParts)); + }); + decompresser.write(message); + decompresser.end(); }); } } class GzipHandler extends CompressionHandler { + constructor(private maxRecvMessageLength: number) { + super(); + } + compressMessage(message: Buffer) { return new Promise((resolve, reject) => { zlib.gzip(message, (err, output) => { @@ -138,13 +158,25 @@ class GzipHandler extends CompressionHandler { decompressMessage(message: Buffer) { return new Promise((resolve, reject) => { - zlib.unzip(message, (err, output) => { - if (err) { - reject(err); - } else { - resolve(output); + let totalLength = 0; + const messageParts: Buffer[] = []; + const decompresser = zlib.createGunzip(); + decompresser.on('data', (chunk: Buffer) => { + messageParts.push(chunk); + totalLength += chunk.byteLength; + if (this.maxRecvMessageLength !== -1 && totalLength > this.maxRecvMessageLength) { + decompresser.destroy(); + reject({ + code: Status.RESOURCE_EXHAUSTED, + details: `Received message that decompresses to a size larger than ${this.maxRecvMessageLength}` + }); } }); + decompresser.on('end', () => { + resolve(Buffer.concat(messageParts)); + }); + decompresser.write(message); + decompresser.end(); }); } } @@ -169,14 +201,14 @@ class UnknownHandler extends CompressionHandler { } } -function getCompressionHandler(compressionName: string): CompressionHandler { +function getCompressionHandler(compressionName: string, maxReceiveMessageSize: number): CompressionHandler { switch (compressionName) { case 'identity': return new IdentityHandler(); case 'deflate': - return new DeflateHandler(); + return new DeflateHandler(maxReceiveMessageSize); case 'gzip': - return new GzipHandler(); + return new GzipHandler(maxReceiveMessageSize); default: return new UnknownHandler(compressionName); } @@ -186,6 +218,7 @@ export class CompressionFilter extends BaseFilter implements Filter { private sendCompression: CompressionHandler = new IdentityHandler(); private receiveCompression: CompressionHandler = new IdentityHandler(); private currentCompressionAlgorithm: CompressionAlgorithm = 'identity'; + private maxReceiveMessageLength: number; constructor( channelOptions: ChannelOptions, @@ -195,6 +228,7 @@ export class CompressionFilter extends BaseFilter implements Filter { const compressionAlgorithmKey = channelOptions['grpc.default_compression_algorithm']; + this.maxReceiveMessageLength = channelOptions['grpc.max_receive_message_length'] ?? DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH if (compressionAlgorithmKey !== undefined) { if (isCompressionAlgorithmKey(compressionAlgorithmKey)) { const clientSelectedEncoding = CompressionAlgorithms[ @@ -215,7 +249,8 @@ export class CompressionFilter extends BaseFilter implements Filter { ) { this.currentCompressionAlgorithm = clientSelectedEncoding; this.sendCompression = getCompressionHandler( - this.currentCompressionAlgorithm + this.currentCompressionAlgorithm, + -1 ); } } else { @@ -247,7 +282,7 @@ export class CompressionFilter extends BaseFilter implements Filter { if (receiveEncoding.length > 0) { const encoding: MetadataValue = receiveEncoding[0]; if (typeof encoding === 'string') { - this.receiveCompression = getCompressionHandler(encoding); + this.receiveCompression = getCompressionHandler(encoding, this.maxReceiveMessageLength); } } metadata.remove('grpc-encoding'); diff --git a/packages/grpc-js/src/internal-channel.ts b/packages/grpc-js/src/internal-channel.ts index 469ace557..e0cebd469 100644 --- a/packages/grpc-js/src/internal-channel.ts +++ b/packages/grpc-js/src/internal-channel.ts @@ -33,7 +33,6 @@ import { } from './resolver'; import { trace } from './logging'; import { SubchannelAddress } from './subchannel-address'; -import { MaxMessageSizeFilterFactory } from './max-message-size-filter'; import { mapProxyName } from './http_proxy'; import { GrpcUri, parseUri, uriToString } from './uri-parser'; import { ServerSurfaceCall } from './server-call'; @@ -402,7 +401,6 @@ export class InternalChannel { } ); this.filterStackFactory = new FilterStackFactory([ - new MaxMessageSizeFilterFactory(this.options), new CompressionFilterFactory(this, this.options), ]); this.trace( diff --git a/packages/grpc-js/src/max-message-size-filter.ts b/packages/grpc-js/src/max-message-size-filter.ts deleted file mode 100644 index b6df374b2..000000000 --- a/packages/grpc-js/src/max-message-size-filter.ts +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2020 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -import { BaseFilter, Filter, FilterFactory } from './filter'; -import { WriteObject } from './call-interface'; -import { - Status, - DEFAULT_MAX_SEND_MESSAGE_LENGTH, - DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH, -} from './constants'; -import { ChannelOptions } from './channel-options'; -import { Metadata } from './metadata'; - -export class MaxMessageSizeFilter extends BaseFilter implements Filter { - private maxSendMessageSize: number = DEFAULT_MAX_SEND_MESSAGE_LENGTH; - private maxReceiveMessageSize: number = DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH; - constructor(options: ChannelOptions) { - super(); - if ('grpc.max_send_message_length' in options) { - this.maxSendMessageSize = options['grpc.max_send_message_length']!; - } - if ('grpc.max_receive_message_length' in options) { - this.maxReceiveMessageSize = options['grpc.max_receive_message_length']!; - } - } - - async sendMessage(message: Promise): Promise { - /* A configured size of -1 means that there is no limit, so skip the check - * entirely */ - if (this.maxSendMessageSize === -1) { - return message; - } else { - const concreteMessage = await message; - if (concreteMessage.message.length > this.maxSendMessageSize) { - throw { - code: Status.RESOURCE_EXHAUSTED, - details: `Sent message larger than max (${concreteMessage.message.length} vs. ${this.maxSendMessageSize})`, - metadata: new Metadata(), - }; - } else { - return concreteMessage; - } - } - } - - async receiveMessage(message: Promise): Promise { - /* A configured size of -1 means that there is no limit, so skip the check - * entirely */ - if (this.maxReceiveMessageSize === -1) { - return message; - } else { - const concreteMessage = await message; - if (concreteMessage.length > this.maxReceiveMessageSize) { - throw { - code: Status.RESOURCE_EXHAUSTED, - details: `Received message larger than max (${concreteMessage.length} vs. ${this.maxReceiveMessageSize})`, - metadata: new Metadata(), - }; - } else { - return concreteMessage; - } - } - } -} - -export class MaxMessageSizeFilterFactory - implements FilterFactory -{ - constructor(private readonly options: ChannelOptions) {} - - createFilter(): MaxMessageSizeFilter { - return new MaxMessageSizeFilter(this.options); - } -} diff --git a/packages/grpc-js/src/server-interceptors.ts b/packages/grpc-js/src/server-interceptors.ts index b62d55108..c2d985a6a 100644 --- a/packages/grpc-js/src/server-interceptors.ts +++ b/packages/grpc-js/src/server-interceptors.ts @@ -30,14 +30,10 @@ import { import * as http2 from 'http2'; import { getErrorMessage } from './error'; import * as zlib from 'zlib'; -import { promisify } from 'util'; import { StreamDecoder } from './stream-decoder'; import { CallEventTracker } from './transport'; import * as logging from './logging'; -const unzip = promisify(zlib.unzip); -const inflate = promisify(zlib.inflate); - const TRACER_NAME = 'server_call'; function trace(text: string) { @@ -496,7 +492,7 @@ export class BaseServerInterceptingCall private wantTrailers = false; private cancelNotified = false; private incomingEncoding = 'identity'; - private decoder = new StreamDecoder(); + private decoder: StreamDecoder; private readQueue: ReadQueueEntry[] = []; private isReadPending = false; private receivedHalfClose = false; @@ -554,6 +550,8 @@ export class BaseServerInterceptingCall this.maxReceiveMessageSize = options['grpc.max_receive_message_length']!; } + this.decoder = new StreamDecoder(this.maxReceiveMessageSize); + const metadata = Metadata.fromHttp2Headers(headers); if (logging.isTracerEnabled(TRACER_NAME)) { @@ -674,18 +672,41 @@ export class BaseServerInterceptingCall message: Buffer, encoding: string ): Buffer | Promise { - switch (encoding) { - case 'deflate': - return inflate(message.subarray(5)); - case 'gzip': - return unzip(message.subarray(5)); - case 'identity': - return message.subarray(5); - default: - return Promise.reject({ - code: Status.UNIMPLEMENTED, - details: `Received message compressed with unsupported encoding "${encoding}"`, + const messageContents = message.subarray(5); + if (encoding === 'identity') { + return messageContents; + } else if (encoding === 'deflate' || encoding === 'gzip') { + let decompresser: zlib.Gunzip | zlib.Deflate; + if (encoding === 'deflate') { + decompresser = zlib.createInflate(); + } else { + decompresser = zlib.createGunzip(); + } + return new Promise((resolve, reject) => { + let totalLength = 0 + const messageParts: Buffer[] = []; + decompresser.on('data', (chunk: Buffer) => { + messageParts.push(chunk); + totalLength += chunk.byteLength; + if (this.maxReceiveMessageSize !== -1 && totalLength > this.maxReceiveMessageSize) { + decompresser.destroy(); + reject({ + code: Status.RESOURCE_EXHAUSTED, + details: `Received message that decompresses to a size larger than ${this.maxReceiveMessageSize}` + }); + } + }); + decompresser.on('end', () => { + resolve(Buffer.concat(messageParts)); }); + decompresser.write(messageContents); + decompresser.end(); + }); + } else { + return Promise.reject({ + code: Status.UNIMPLEMENTED, + details: `Received message compressed with unsupported encoding "${encoding}"`, + }); } } @@ -698,10 +719,16 @@ export class BaseServerInterceptingCall const compressedMessageEncoding = compressed ? this.incomingEncoding : 'identity'; - const decompressedMessage = await this.decompressMessage( - queueEntry.compressedMessage!, - compressedMessageEncoding - ); + let decompressedMessage: Buffer; + try { + decompressedMessage = await this.decompressMessage( + queueEntry.compressedMessage!, + compressedMessageEncoding + ); + } catch (err) { + this.sendStatus(err as PartialStatusObject); + return; + } try { queueEntry.parsedMessage = this.handler.deserialize(decompressedMessage); } catch (err) { @@ -743,23 +770,16 @@ export class BaseServerInterceptingCall ' received data frame of size ' + data.length ); - const rawMessages = this.decoder.write(data); + let rawMessages: Buffer[]; + try { + rawMessages = this.decoder.write(data); + } catch (e) { + this.sendStatus({ code: Status.RESOURCE_EXHAUSTED, details: (e as Error).message }); + return; + } for (const messageBytes of rawMessages) { this.stream.pause(); - if ( - this.maxReceiveMessageSize !== -1 && - messageBytes.length - 5 > this.maxReceiveMessageSize - ) { - this.sendStatus({ - code: Status.RESOURCE_EXHAUSTED, - details: `Received message larger than max (${ - messageBytes.length - 5 - } vs. ${this.maxReceiveMessageSize})`, - metadata: null, - }); - return; - } const queueEntry: ReadQueueEntry = { type: 'COMPRESSED', compressedMessage: messageBytes, diff --git a/packages/grpc-js/src/stream-decoder.ts b/packages/grpc-js/src/stream-decoder.ts index 671ad41ae..ea669d14c 100644 --- a/packages/grpc-js/src/stream-decoder.ts +++ b/packages/grpc-js/src/stream-decoder.ts @@ -30,6 +30,8 @@ export class StreamDecoder { private readPartialMessage: Buffer[] = []; private readMessageRemaining = 0; + constructor(private maxReadMessageLength: number) {} + write(data: Buffer): Buffer[] { let readHead = 0; let toRead: number; @@ -60,6 +62,9 @@ export class StreamDecoder { // readSizeRemaining >=0 here if (this.readSizeRemaining === 0) { this.readMessageSize = this.readPartialSize.readUInt32BE(0); + if (this.maxReadMessageLength !== -1 && this.readMessageSize > this.maxReadMessageLength) { + throw new Error(`Received message larger than max (${this.readMessageSize} vs ${this.maxReadMessageLength})`); + } this.readMessageRemaining = this.readMessageSize; if (this.readMessageRemaining > 0) { this.readState = ReadState.READING_MESSAGE; diff --git a/packages/grpc-js/src/subchannel-call.ts b/packages/grpc-js/src/subchannel-call.ts index 0ce7d72cb..bee00119f 100644 --- a/packages/grpc-js/src/subchannel-call.ts +++ b/packages/grpc-js/src/subchannel-call.ts @@ -18,7 +18,7 @@ import * as http2 from 'http2'; import * as os from 'os'; -import { Status } from './constants'; +import { DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH, Status } from './constants'; import { Metadata } from './metadata'; import { StreamDecoder } from './stream-decoder'; import * as logging from './logging'; @@ -116,7 +116,7 @@ function mapHttpStatusCode(code: number): StatusObject { } export class Http2SubchannelCall implements SubchannelCall { - private decoder = new StreamDecoder(); + private decoder: StreamDecoder; private isReadFilterPending = false; private isPushPending = false; @@ -147,6 +147,8 @@ export class Http2SubchannelCall implements SubchannelCall { private readonly transport: Transport, private readonly callId: number ) { + const maxReceiveMessageLength = transport.getOptions()['grpc.max_receive_message_length'] ?? DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH; + this.decoder = new StreamDecoder(maxReceiveMessageLength); http2Stream.on('response', (headers, flags) => { let headersString = ''; for (const header of Object.keys(headers)) { @@ -182,7 +184,13 @@ export class Http2SubchannelCall implements SubchannelCall { return; } this.trace('receive HTTP/2 data frame of length ' + data.length); - const messages = this.decoder.write(data); + let messages: Buffer[]; + try { + messages = this.decoder.write(data); + } catch (e) { + this.cancelWithStatus(Status.RESOURCE_EXHAUSTED, (e as Error).message); + return; + } for (const message of messages) { this.trace('parsed message of length ' + message.length); diff --git a/packages/grpc-js/src/transport.ts b/packages/grpc-js/src/transport.ts index 66a5d4556..934b62111 100644 --- a/packages/grpc-js/src/transport.ts +++ b/packages/grpc-js/src/transport.ts @@ -84,6 +84,7 @@ export interface TransportDisconnectListener { export interface Transport { getChannelzRef(): SocketRef; getPeerName(): string; + getOptions(): ChannelOptions; createCall( metadata: Metadata, host: string, @@ -147,7 +148,7 @@ class Http2Transport implements Transport { constructor( private session: http2.ClientHttp2Session, subchannelAddress: SubchannelAddress, - options: ChannelOptions, + private options: ChannelOptions, /** * Name of the remote server, if it is not the same as the subchannel * address, i.e. if connecting through an HTTP CONNECT proxy. @@ -617,6 +618,10 @@ class Http2Transport implements Transport { return this.subchannelAddressString; } + getOptions() { + return this.options; + } + shutdown() { this.session.close(); unregisterChannelzRef(this.channelzRef); diff --git a/packages/grpc-js/test/fixtures/test_service.proto b/packages/grpc-js/test/fixtures/test_service.proto index 64ce0d378..2a7a303f3 100644 --- a/packages/grpc-js/test/fixtures/test_service.proto +++ b/packages/grpc-js/test/fixtures/test_service.proto @@ -21,6 +21,7 @@ message Request { bool error = 1; string message = 2; int32 errorAfter = 3; + int32 responseLength = 4; } message Response { diff --git a/packages/grpc-js/test/test-server-errors.ts b/packages/grpc-js/test/test-server-errors.ts index 24ccfeef3..243e10918 100644 --- a/packages/grpc-js/test/test-server-errors.ts +++ b/packages/grpc-js/test/test-server-errors.ts @@ -33,6 +33,7 @@ import { } from '../src/server-call'; import { loadProtoFile } from './common'; +import { CompressionAlgorithms } from '../src/compression-algorithms'; const protoFile = join(__dirname, 'fixtures', 'test_service.proto'); const testServiceDef = loadProtoFile(protoFile); @@ -310,7 +311,7 @@ describe('Other conditions', () => { trailerMetadata ); } else { - cb(null, { count: 1 }, trailerMetadata); + cb(null, { count: 1, message: 'a'.repeat(req.responseLength) }, trailerMetadata); } }, @@ -320,6 +321,7 @@ describe('Other conditions', () => { ) { let count = 0; let errored = false; + let responseLength = 0; stream.on('data', (data: any) => { if (data.error) { @@ -327,13 +329,14 @@ describe('Other conditions', () => { errored = true; cb(new Error(message) as ServiceError, null, trailerMetadata); } else { + responseLength += data.responseLength; count++; } }); stream.on('end', () => { if (!errored) { - cb(null, { count }, trailerMetadata); + cb(null, { count, message: 'a'.repeat(responseLength) }, trailerMetadata); } }); }, @@ -349,7 +352,7 @@ describe('Other conditions', () => { }); } else { for (let i = 1; i <= 5; i++) { - stream.write({ count: i }); + stream.write({ count: i, message: 'a'.repeat(req.responseLength) }); if (req.errorAfter && req.errorAfter === i) { stream.emit('error', { code: grpc.status.UNKNOWN, @@ -376,7 +379,7 @@ describe('Other conditions', () => { err.metadata.add('count', '' + count); stream.emit('error', err); } else { - stream.write({ count }); + stream.write({ count, message: 'a'.repeat(data.responseLength) }); count++; } }); @@ -740,6 +743,44 @@ describe('Other conditions', () => { }); }); }); + + describe('Max message size', () => { + const largeMessage = 'a'.repeat(10_000_000); + it('Should be enforced on the server', done => { + client.unary({ message: largeMessage }, (error?: ServiceError) => { + assert(error); + assert.strictEqual(error.code, grpc.status.RESOURCE_EXHAUSTED); + done(); + }); + }); + it('Should be enforced on the client', done => { + client.unary({ responseLength: 10_000_000 }, (error?: ServiceError) => { + assert(error); + assert.strictEqual(error.code, grpc.status.RESOURCE_EXHAUSTED); + done(); + }); + }); + describe('Compressed messages', () => { + it('Should be enforced with gzip', done => { + const compressingClient = new testServiceClient(`localhost:${port}`, clientInsecureCreds, {'grpc.default_compression_algorithm': CompressionAlgorithms.gzip}); + compressingClient.unary({ message: largeMessage }, (error?: ServiceError) => { + assert(error); + assert.strictEqual(error.code, grpc.status.RESOURCE_EXHAUSTED); + assert.match(error.details, /Received message that decompresses to a size larger/); + done(); + }); + }); + it('Should be enforced with deflate', done => { + const compressingClient = new testServiceClient(`localhost:${port}`, clientInsecureCreds, {'grpc.default_compression_algorithm': CompressionAlgorithms.deflate}); + compressingClient.unary({ message: largeMessage }, (error?: ServiceError) => { + assert(error); + assert.strictEqual(error.code, grpc.status.RESOURCE_EXHAUSTED); + assert.match(error.details, /Received message that decompresses to a size larger/); + done(); + }); + }); + }); + }); }); function identity(arg: any): any { From 98cd87f7512c95cd48bf04c3225f0fa22b5dcb78 Mon Sep 17 00:00:00 2001 From: David Fiala Date: Thu, 6 Jun 2024 22:57:13 -0700 Subject: [PATCH 44/55] ensure that client keepalive timers are always cleared when they trigger. this is a necessary change to fit with having removed keepaliveDisabled boolean. manually inspected test logs for both server.ts and transport.ts to verify both types of keepalives are operating correctly. --- packages/grpc-js/src/transport.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/grpc-js/src/transport.ts b/packages/grpc-js/src/transport.ts index ab5438211..06509cb18 100644 --- a/packages/grpc-js/src/transport.ts +++ b/packages/grpc-js/src/transport.ts @@ -422,6 +422,7 @@ class Http2Transport implements Transport { 'Sending ping with timeout ' + this.keepaliveTimeoutMs + 'ms' ); this.keepaliveTimer = setTimeout(() => { + this.keepaliveTimer = null; this.keepaliveTrace('Ping timeout passed without response'); this.handleDisconnect(); }, this.keepaliveTimeoutMs); @@ -471,6 +472,7 @@ class Http2Transport implements Transport { 'Starting keepalive timer for ' + this.keepaliveTimeMs + 'ms' ); this.keepaliveTimer = setTimeout(() => { + this.keepaliveTimer = null; this.maybeSendPing(); }, this.keepaliveTimeMs); this.keepaliveTimer.unref?.(); From 7ecaa2d2dcaaa49467d41143169212caf55a40cd Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 7 Jun 2024 10:52:50 -0700 Subject: [PATCH 45/55] grpc-js: Bump to 1.10.9 --- packages/grpc-js/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index f8b070353..73b63bf7b 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.10.8", + "version": "1.10.9", "description": "gRPC Library for Node - pure JS implementation", "homepage": "https://grpc.io/", "repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js", From e7590295327b1bbd6dae812cf45f4c5c5b181985 Mon Sep 17 00:00:00 2001 From: James Watkins-Harvey Date: Fri, 10 May 2024 16:17:06 -0400 Subject: [PATCH 46/55] HTTP CONNECT: handle early server packets --- packages/grpc-js/src/http_proxy.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/grpc-js/src/http_proxy.ts b/packages/grpc-js/src/http_proxy.ts index 3e905c488..30eeb621e 100644 --- a/packages/grpc-js/src/http_proxy.ts +++ b/packages/grpc-js/src/http_proxy.ts @@ -233,6 +233,12 @@ export function getProxiedConnection( ' through proxy ' + proxyAddressString ); + // The HTTP client may have already read a few bytes of the proxied + // connection. If that's the case, put them back into the socket. + // See https://github.com/grpc/grpc-node/issues/2744. + if (head.length > 0) { + socket.unshift(head); + } if ('secureContext' in connectionOptions) { /* The proxy is connecting to a TLS server, so upgrade this socket * connection to a TLS connection. From 5ae551445452ccf1db1d4ed8f3890f6b0dfc0c35 Mon Sep 17 00:00:00 2001 From: Brendan Myers Date: Wed, 29 May 2024 19:15:30 +1000 Subject: [PATCH 47/55] fix: add decoding for url encoded user credentials --- packages/grpc-js/src/http_proxy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/src/http_proxy.ts b/packages/grpc-js/src/http_proxy.ts index 30eeb621e..6fabf5025 100644 --- a/packages/grpc-js/src/http_proxy.ts +++ b/packages/grpc-js/src/http_proxy.ts @@ -80,7 +80,7 @@ function getProxyInfo(): ProxyInfo { if (proxyUrl.username) { if (proxyUrl.password) { log(LogVerbosity.INFO, 'userinfo found in proxy URI'); - userCred = `${proxyUrl.username}:${proxyUrl.password}`; + userCred = decodeURIComponent(`${proxyUrl.username}:${proxyUrl.password}`); } else { userCred = proxyUrl.username; } From cbab4e51cdecbc1cff1d27c46d29ae915c4554fb Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 18 Jun 2024 15:42:59 -0700 Subject: [PATCH 48/55] grpc-js: Bump to 1.10.10 --- packages/grpc-js/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 73b63bf7b..774a0eafd 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.10.9", + "version": "1.10.10", "description": "gRPC Library for Node - pure JS implementation", "homepage": "https://grpc.io/", "repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js", From 42844cffd2d5f27eb7dbac7b5da1dd05b3de5a95 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 20 Jun 2024 13:15:12 -0700 Subject: [PATCH 49/55] grpc-js: Re-add client-side max send message size checking --- packages/grpc-js/src/compression-filter.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/src/compression-filter.ts b/packages/grpc-js/src/compression-filter.ts index f1600b36d..189749f03 100644 --- a/packages/grpc-js/src/compression-filter.ts +++ b/packages/grpc-js/src/compression-filter.ts @@ -21,7 +21,7 @@ import { WriteObject, WriteFlags } from './call-interface'; import { Channel } from './channel'; import { ChannelOptions } from './channel-options'; import { CompressionAlgorithms } from './compression-algorithms'; -import { DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH, LogVerbosity, Status } from './constants'; +import { DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH, DEFAULT_MAX_SEND_MESSAGE_LENGTH, LogVerbosity, Status } from './constants'; import { BaseFilter, Filter, FilterFactory } from './filter'; import * as logging from './logging'; import { Metadata, MetadataValue } from './metadata'; @@ -219,6 +219,7 @@ export class CompressionFilter extends BaseFilter implements Filter { private receiveCompression: CompressionHandler = new IdentityHandler(); private currentCompressionAlgorithm: CompressionAlgorithm = 'identity'; private maxReceiveMessageLength: number; + private maxSendMessageLength: number; constructor( channelOptions: ChannelOptions, @@ -228,7 +229,8 @@ export class CompressionFilter extends BaseFilter implements Filter { const compressionAlgorithmKey = channelOptions['grpc.default_compression_algorithm']; - this.maxReceiveMessageLength = channelOptions['grpc.max_receive_message_length'] ?? DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH + this.maxReceiveMessageLength = channelOptions['grpc.max_receive_message_length'] ?? DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH; + this.maxSendMessageLength = channelOptions['grpc.max_send_message_length'] ?? DEFAULT_MAX_SEND_MESSAGE_LENGTH; if (compressionAlgorithmKey !== undefined) { if (isCompressionAlgorithmKey(compressionAlgorithmKey)) { const clientSelectedEncoding = CompressionAlgorithms[ @@ -314,6 +316,12 @@ export class CompressionFilter extends BaseFilter implements Filter { * and the output is a framed and possibly compressed message. For this * reason, this filter should be at the bottom of the filter stack */ const resolvedMessage: WriteObject = await message; + if (this.maxSendMessageLength !== -1 && resolvedMessage.message.length > this.maxSendMessageLength) { + throw { + code: Status.RESOURCE_EXHAUSTED, + details: `Attempted to send message with a size larger than ${this.maxSendMessageLength}` + }; + } let compress: boolean; if (this.sendCompression instanceof IdentityHandler) { compress = false; From c1815e09e2ae44bfa00d1664433a2c9c80fed179 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 3 Jul 2024 15:22:03 -0700 Subject: [PATCH 50/55] grpc-js: Fix pick_first reconnecting without active calls --- packages/grpc-js/src/load-balancer-pick-first.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/src/load-balancer-pick-first.ts b/packages/grpc-js/src/load-balancer-pick-first.ts index f6c43b33d..e08853336 100644 --- a/packages/grpc-js/src/load-balancer-pick-first.ts +++ b/packages/grpc-js/src/load-balancer-pick-first.ts @@ -32,7 +32,7 @@ import { PickResultType, UnavailablePicker, } from './picker'; -import { Endpoint, SubchannelAddress } from './subchannel-address'; +import { Endpoint, SubchannelAddress, subchannelAddressToString } from './subchannel-address'; import * as logging from './logging'; import { LogVerbosity } from './constants'; import { @@ -348,7 +348,6 @@ export class PickFirstLoadBalancer implements LoadBalancer { if (newState !== ConnectivityState.READY) { this.removeCurrentPick(); this.calculateAndReportNewState(); - this.requestReresolution(); } return; } @@ -483,6 +482,13 @@ export class PickFirstLoadBalancer implements LoadBalancer { subchannel: this.channelControlHelper.createSubchannel(address, {}), hasReportedTransientFailure: false, })); + trace('connectToAddressList([' + addressList.map(address => subchannelAddressToString(address)) + '])'); + for (const { subchannel } of newChildrenList) { + if (subchannel.getConnectivityState() === ConnectivityState.READY) { + this.pickSubchannel(subchannel); + return; + } + } /* Ref each subchannel before resetting the list, to ensure that * subchannels shared between the list don't drop to 0 refs during the * transition. */ @@ -527,6 +533,7 @@ export class PickFirstLoadBalancer implements LoadBalancer { const rawAddressList = ([] as SubchannelAddress[]).concat( ...endpointList.map(endpoint => endpoint.addresses) ); + trace('updateAddressList([' + rawAddressList.map(address => subchannelAddressToString(address)) + '])'); if (rawAddressList.length === 0) { throw new Error('No addresses in endpoint list passed to pick_first'); } From e804ad65b652c90ba0c9223892ac48827879c97d Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 3 Jul 2024 15:37:40 -0700 Subject: [PATCH 51/55] grpc-js: Bump to 1.10.11 --- packages/grpc-js/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 774a0eafd..23af2f981 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.10.10", + "version": "1.10.11", "description": "gRPC Library for Node - pure JS implementation", "homepage": "https://grpc.io/", "repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js", From a5fac6f0565e147cdc1cb3376e9509ef4d503e2e Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 8 Jul 2024 15:08:30 -0700 Subject: [PATCH 52/55] grpc-js: pick-first: Fix short circuit READY subchannel handling --- packages/grpc-js/src/load-balancer-pick-first.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js/src/load-balancer-pick-first.ts b/packages/grpc-js/src/load-balancer-pick-first.ts index e08853336..e042e1161 100644 --- a/packages/grpc-js/src/load-balancer-pick-first.ts +++ b/packages/grpc-js/src/load-balancer-pick-first.ts @@ -485,6 +485,8 @@ export class PickFirstLoadBalancer implements LoadBalancer { trace('connectToAddressList([' + addressList.map(address => subchannelAddressToString(address)) + '])'); for (const { subchannel } of newChildrenList) { if (subchannel.getConnectivityState() === ConnectivityState.READY) { + this.channelControlHelper.addChannelzChild(subchannel.getChannelzRef()); + subchannel.addConnectivityStateListener(this.subchannelStateListener); this.pickSubchannel(subchannel); return; } @@ -500,10 +502,6 @@ export class PickFirstLoadBalancer implements LoadBalancer { this.children = newChildrenList; for (const { subchannel } of this.children) { subchannel.addConnectivityStateListener(this.subchannelStateListener); - if (subchannel.getConnectivityState() === ConnectivityState.READY) { - this.pickSubchannel(subchannel); - return; - } } for (const child of this.children) { if ( From 745a451e4c1d2d8583e92cbc86cc9e5eee0b3c95 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 9 Jul 2024 11:03:15 -0700 Subject: [PATCH 53/55] grpc-js: Increase state change deadline in server idle tests --- packages/grpc-js/test/test-idle-timer.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/grpc-js/test/test-idle-timer.ts b/packages/grpc-js/test/test-idle-timer.ts index 3f2a8ed20..ed6af2cf7 100644 --- a/packages/grpc-js/test/test-idle-timer.ts +++ b/packages/grpc-js/test/test-idle-timer.ts @@ -199,7 +199,7 @@ describe('Server idle timer', () => { grpc.connectivityState.READY ); client?.waitForClientState( - Date.now() + 600, + Date.now() + 1500, grpc.connectivityState.IDLE, done ); @@ -217,7 +217,7 @@ describe('Server idle timer', () => { ); client!.waitForClientState( - Date.now() + 600, + Date.now() + 1500, grpc.connectivityState.IDLE, err => { if (err) return done(err); @@ -248,7 +248,7 @@ describe('Server idle timer', () => { ); client!.waitForClientState( - Date.now() + 600, + Date.now() + 1500, grpc.connectivityState.IDLE, done ); From 395de4b333840fa28c7b54e726a017fee5c89c0d Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 9 Jul 2024 11:23:19 -0700 Subject: [PATCH 54/55] grpc-js: Refresh server idle timer if not enough time has passed --- packages/grpc-js/src/server.ts | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 33db41004..4683d44a1 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -1790,19 +1790,22 @@ export class Server { // for future refreshes if ( sessionInfo !== undefined && - sessionInfo.activeStreams === 0 && - Date.now() - sessionInfo.lastIdle >= ctx.sessionIdleTimeout + sessionInfo.activeStreams === 0 ) { - ctx.trace( - 'Session idle timeout triggered for ' + - socket?.remoteAddress + - ':' + - socket?.remotePort + - ' last idle at ' + - sessionInfo.lastIdle - ); + if (Date.now() - sessionInfo.lastIdle >= ctx.sessionIdleTimeout) { + ctx.trace( + 'Session idle timeout triggered for ' + + socket?.remoteAddress + + ':' + + socket?.remotePort + + ' last idle at ' + + sessionInfo.lastIdle + ); - ctx.closeSession(session); + ctx.closeSession(session); + } else { + sessionInfo.timeout.refresh(); + } } } From 810e9e6a40f586edb33f1fc4017495a000875839 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 9 Jul 2024 15:14:44 -0700 Subject: [PATCH 55/55] grpc-js: Ensure pending calls end after channel close --- packages/grpc-js/src/internal-channel.ts | 31 ++++++++++++++++++++++-- packages/grpc-js/test/test-client.ts | 30 +++++++++++++++++++++++ 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/src/internal-channel.ts b/packages/grpc-js/src/internal-channel.ts index e0cebd469..857f2a4eb 100644 --- a/packages/grpc-js/src/internal-channel.ts +++ b/packages/grpc-js/src/internal-channel.ts @@ -20,7 +20,7 @@ import { ChannelOptions } from './channel-options'; import { ResolvingLoadBalancer } from './resolving-load-balancer'; import { SubchannelPool, getSubchannelPool } from './subchannel-pool'; import { ChannelControlHelper } from './load-balancer'; -import { UnavailablePicker, Picker, QueuePicker } from './picker'; +import { UnavailablePicker, Picker, QueuePicker, PickArgs, PickResult, PickResultType } from './picker'; import { Metadata } from './metadata'; import { Status, LogVerbosity, Propagate } from './constants'; import { FilterStackFactory } from './filter-stack'; @@ -143,6 +143,22 @@ class ChannelSubchannelWrapper } } +class ShutdownPicker implements Picker { + pick(pickArgs: PickArgs): PickResult { + return { + pickResultType: PickResultType.DROP, + status: { + code: Status.UNAVAILABLE, + details: 'Channel closed before call started', + metadata: new Metadata() + }, + subchannel: null, + onCallStarted: null, + onCallEnded: null + } + } +} + export class InternalChannel { private readonly resolvingLoadBalancer: ResolvingLoadBalancer; private readonly subchannelPool: SubchannelPool; @@ -536,7 +552,9 @@ export class InternalChannel { } getConfig(method: string, metadata: Metadata): GetConfigResult { - this.resolvingLoadBalancer.exitIdle(); + if (this.connectivityState !== ConnectivityState.SHUTDOWN) { + this.resolvingLoadBalancer.exitIdle(); + } if (this.configSelector) { return { type: 'SUCCESS', @@ -745,6 +763,15 @@ export class InternalChannel { close() { this.resolvingLoadBalancer.destroy(); this.updateState(ConnectivityState.SHUTDOWN); + this.currentPicker = new ShutdownPicker(); + for (const call of this.configSelectionQueue) { + call.cancelWithStatus(Status.UNAVAILABLE, 'Channel closed before call started'); + } + this.configSelectionQueue = []; + for (const call of this.pickQueue) { + call.cancelWithStatus(Status.UNAVAILABLE, 'Channel closed before call started'); + } + this.pickQueue = []; clearInterval(this.callRefTimer); if (this.idleTimer) { clearTimeout(this.idleTimer); diff --git a/packages/grpc-js/test/test-client.ts b/packages/grpc-js/test/test-client.ts index 67b396015..bbb3f063f 100644 --- a/packages/grpc-js/test/test-client.ts +++ b/packages/grpc-js/test/test-client.ts @@ -97,6 +97,21 @@ describe('Client without a server', () => { } ); }); + it('close should force calls to end', done => { + client.makeUnaryRequest( + '/service/method', + x => x, + x => x, + Buffer.from([]), + new grpc.Metadata({waitForReady: true}), + (error, value) => { + assert(error); + assert.strictEqual(error?.code, grpc.status.UNAVAILABLE); + done(); + } + ); + client.close(); + }); }); describe('Client with a nonexistent target domain', () => { @@ -133,4 +148,19 @@ describe('Client with a nonexistent target domain', () => { } ); }); + it('close should force calls to end', done => { + client.makeUnaryRequest( + '/service/method', + x => x, + x => x, + Buffer.from([]), + new grpc.Metadata({waitForReady: true}), + (error, value) => { + assert(error); + assert.strictEqual(error?.code, grpc.status.UNAVAILABLE); + done(); + } + ); + client.close(); + }); });