From f3b6eb1c85b59022a3760f57a376ffd97c06edce Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 14 Apr 2021 14:00:16 -0700 Subject: [PATCH 001/450] grpc-js-xds: Update deps and generated code for xDS v3 --- packages/grpc-js-xds/deps/envoy-api | 2 +- packages/grpc-js-xds/deps/udpa | 2 +- packages/grpc-js-xds/package.json | 2 +- packages/grpc-js-xds/src/generated/ads.ts | 63 + packages/grpc-js-xds/src/generated/cluster.ts | 89 +- .../grpc-js-xds/src/generated/endpoint.ts | 49 +- .../envoy/api/v2/UpstreamConnectionOptions.ts | 17 - .../src/generated/envoy/api/v2/Vhds.ts | 17 - .../v2/auth/CertificateValidationContext.ts | 315 ----- .../envoy/api/v2/auth/CommonTlsContext.ts | 140 --- .../envoy/api/v2/auth/DownstreamTlsContext.ts | 101 -- .../envoy/api/v2/auth/GenericSecret.ts | 17 - .../envoy/api/v2/auth/PrivateKeyProvider.ts | 42 - .../envoy/api/v2/auth/SdsSecretConfig.ts | 23 - .../src/generated/envoy/api/v2/auth/Secret.ts | 36 - .../envoy/api/v2/auth/TlsCertificate.ts | 78 -- .../envoy/api/v2/auth/TlsParameters.ts | 171 --- .../envoy/api/v2/auth/TlsSessionTicketKeys.ts | 61 - .../envoy/api/v2/auth/UpstreamTlsContext.ts | 68 -- .../envoy/api/v2/core/BuildVersion.ts | 4 +- .../envoy/api/v2/core/GrpcProtocolOptions.ts | 17 - .../envoy/api/v2/core/RuntimeDouble.ts | 2 +- .../envoy/api/v2/core/SelfConfigSource.ts | 20 - .../v2/endpoint/EndpointLoadMetricStats.ts | 2 +- .../generated/envoy/api/v2/listener/Filter.ts | 34 - .../envoy/api/v2/listener/FilterChain.ts | 118 -- .../envoy/api/v2/route/HedgePolicy.ts | 66 -- .../api/v2/route/QueryParameterMatcher.ts | 86 -- .../generated/envoy/api/v2/route/RateLimit.ts | 341 ------ .../envoy/api/v2/route/RedirectAction.ts | 139 --- .../envoy/api/v2/route/RetryPolicy.ts | 218 ---- .../v2 => accesslog/v3}/AccessLog.ts | 37 +- .../config/accesslog/v3/AccessLogFilter.ts | 124 ++ .../v2 => accesslog/v3}/AndFilter.ts | 8 +- .../config/accesslog/v3/ComparisonFilter.ts | 48 + .../config/accesslog/v3/DurationFilter.ts | 23 + .../v2 => accesslog/v3}/ExtensionFilter.ts | 11 +- .../v2 => accesslog/v3}/GrpcStatusFilter.ts | 28 +- .../envoy/config/accesslog/v3/HeaderFilter.ts | 25 + .../config/accesslog/v3/MetadataFilter.ts | 48 + .../v3}/NotHealthCheckFilter.ts | 2 +- .../accesslog/v2 => accesslog/v3}/OrFilter.ts | 8 +- .../v2 => accesslog/v3}/ResponseFlagFilter.ts | 20 +- .../config/accesslog/v3/RuntimeFilter.ts | 73 ++ .../config/accesslog/v3/StatusCodeFilter.ts | 23 + .../v2 => accesslog/v3}/TraceableFilter.ts | 2 +- .../cluster/v3}/CircuitBreakers.ts | 50 +- .../{api/v2 => config/cluster/v3}/Cluster.ts | 1043 +++++++++++------ .../config/cluster/v3/ClusterCollection.ts | 19 + .../cluster => config/cluster/v3}/Filter.ts | 2 +- .../cluster/v3}/LoadBalancingPolicy.ts | 23 +- .../cluster/v3}/OutlierDetection.ts | 48 +- .../config/cluster/v3/TrackClusterStats.ts | 36 + .../cluster/v3}/UpstreamBindConfig.ts | 8 +- .../cluster/v3/UpstreamConnectionOptions.ts | 17 + .../generated/envoy/config/core/v3/Address.ts | 35 + .../core/v3}/AggregatedConfigSource.ts | 6 +- .../core/v3}/ApiConfigSource.ts | 44 +- .../v2/core => config/core/v3}/ApiVersion.ts | 4 +- .../envoy/config/core/v3/AsyncDataSource.ts | 34 + .../envoy/config/core/v3/BackoffStrategy.ts | 43 + .../envoy/config/core/v3/BindConfig.ts | 49 + .../envoy/config/core/v3/BuildVersion.ts | 36 + .../envoy/config/core/v3/CidrRange.ts | 33 + .../core => config/core/v3}/ConfigSource.ts | 53 +- .../envoy/config/core/v3/ControlPlane.ts | 26 + .../envoy/config/core/v3/DataSource.ts | 40 + .../config/core/v3/EnvoyInternalAddress.ts | 28 + .../core/v3}/EventServiceConfig.ts | 8 +- .../envoy/config/core/v3/Extension.ts | 75 ++ .../config/core/v3/ExtensionConfigSource.ts | 72 ++ .../config/core/v3/GrpcProtocolOptions.ts | 17 + .../v2/core => config/core/v3}/GrpcService.ts | 213 ++-- .../envoy/config/core/v3/HeaderMap.ts | 17 + .../envoy/config/core/v3/HeaderValue.ts | 38 + .../envoy/config/core/v3/HeaderValueOption.ts | 34 + .../v2/core => config/core/v3}/HealthCheck.ts | 258 ++-- .../core => config/core/v3}/HealthStatus.ts | 2 +- .../core/v3}/Http1ProtocolOptions.ts | 62 +- .../core/v3}/Http2ProtocolOptions.ts | 128 +- .../config/core/v3/Http3ProtocolOptions.ts | 22 + .../core/v3}/HttpProtocolOptions.ts | 26 +- .../generated/envoy/config/core/v3/HttpUri.ts | 79 ++ .../envoy/config/core/v3/KeepaliveSettings.ts | 40 + .../envoy/config/core/v3/Locality.ts | 56 + .../envoy/config/core/v3/Metadata.ts | 67 ++ .../generated/envoy/config/core/v3/Node.ts | 159 +++ .../generated/envoy/config/core/v3/Pipe.ts | 30 + .../config/core/v3/ProxyProtocolConfig.ts | 29 + .../core/v3}/RateLimitSettings.ts | 2 +- .../envoy/config/core/v3/RemoteDataSource.ts | 40 + .../envoy/config/core/v3/RequestMethod.ts | 17 + .../envoy/config/core/v3/RetryPolicy.ts | 38 + .../envoy/config/core/v3/RoutingPriority.ts | 15 + .../envoy/config/core/v3/RuntimeDouble.ts | 30 + .../config/core/v3/RuntimeFeatureFlag.ts | 35 + .../core/v3/RuntimeFractionalPercent.ts | 49 + .../envoy/config/core/v3/RuntimePercent.ts | 31 + .../envoy/config/core/v3/RuntimeUInt32.ts | 30 + .../envoy/config/core/v3/SelfConfigSource.ts | 31 + .../envoy/config/core/v3/SocketAddress.ts | 97 ++ .../envoy/config/core/v3/SocketOption.ts | 90 ++ .../core/v3/SubstitutionFormatString.ts | 197 ++++ .../envoy/config/core/v3/TcpKeepalive.ts | 43 + .../core/v3}/TcpProtocolOptions.ts | 2 +- .../envoy/config/core/v3/TrafficDirection.ts | 19 + .../envoy/config/core/v3/TransportSocket.ts | 43 + .../config/core/v3/TypedExtensionConfig.ts | 43 + .../core/v3}/UpstreamHttpProtocolOptions.ts | 2 +- .../envoy/config/core/v3/WatchedDirectory.ts | 24 + .../endpoint/v3}/ClusterLoadAssignment.ts | 74 +- .../envoy/config/endpoint/v3/ClusterStats.ts | 115 ++ .../endpoint/v3}/Endpoint.ts | 32 +- .../endpoint/v3/EndpointLoadMetricStats.ts | 35 + .../endpoint/v3}/LbEndpoint.ts | 24 +- .../endpoint/v3}/LocalityLbEndpoints.ts | 14 +- .../endpoint/v3/UpstreamEndpointStats.ts | 104 ++ .../endpoint/v3/UpstreamLocalityStats.ts | 104 ++ .../filter/accesslog/v2/AccessLogFilter.ts | 115 -- .../filter/accesslog/v2/ComparisonFilter.ts | 48 - .../filter/accesslog/v2/DurationFilter.ts | 23 - .../filter/accesslog/v2/HeaderFilter.ts | 25 - .../filter/accesslog/v2/RuntimeFilter.ts | 63 - .../filter/accesslog/v2/StatusCodeFilter.ts | 23 - .../http_connection_manager/v2/HttpFilter.ts | 34 - .../http_connection_manager/v2/ScopedRds.ts | 17 - .../v2/ScopedRouteConfigurationsList.ts | 17 - .../v3}/ActiveRawUdpListenerConfig.ts | 2 +- .../config/listener/{v2 => v3}/ApiListener.ts | 2 +- .../envoy/config/listener/v3/Filter.ts | 52 + .../envoy/config/listener/v3/FilterChain.ts | 170 +++ .../listener/v3}/FilterChainMatch.ts | 46 +- .../v2 => config/listener/v3}/Listener.ts | 231 ++-- .../config/listener/v3/ListenerCollection.ts | 19 + .../listener/v3}/ListenerFilter.ts | 19 +- .../v3}/ListenerFilterChainMatchPredicate.ts | 30 +- .../listener/v3}/UdpListenerConfig.ts | 9 +- .../route => config/route/v3}/CorsPolicy.ts | 86 +- .../v2/route => config/route/v3}/Decorator.ts | 2 +- .../route/v3}/DirectResponseAction.ts | 16 +- .../route => config/route/v3}/FilterAction.ts | 2 +- .../envoy/config/route/v3/FilterConfig.ts | 47 + .../route/v3}/HeaderMatcher.ts | 84 +- .../envoy/config/route/v3/HedgePolicy.ts | 76 ++ .../config/route/v3/InternalRedirectPolicy.ts | 72 ++ .../config/route/v3/QueryParameterMatcher.ts | 47 + .../envoy/config/route/v3/RateLimit.ts | 578 +++++++++ .../envoy/config/route/v3/RedirectAction.ts | 222 ++++ .../envoy/config/route/v3/RetryPolicy.ts | 392 +++++++ .../v2/route => config/route/v3}/Route.ts | 107 +- .../route => config/route/v3}/RouteAction.ts | 479 +++++--- .../route/v3}/RouteConfiguration.ts | 89 +- .../route => config/route/v3}/RouteMatch.ts | 128 +- .../route/v3}/ScopedRouteConfiguration.ts | 58 +- .../v2/route => config/route/v3}/Tracing.ts | 26 +- .../generated/envoy/config/route/v3/Vhds.ts | 17 + .../route/v3}/VirtualCluster.ts | 57 +- .../route => config/route/v3}/VirtualHost.ts | 107 +- .../route/v3}/WeightedCluster.ts | 97 +- .../envoy/config/trace/{v2 => v3}/Tracing.ts | 53 +- .../v3}/HttpConnectionManager.ts | 395 ++++--- .../http_connection_manager/v3/HttpFilter.ts | 66 ++ .../v3/LocalReplyConfig.ts | 106 ++ .../http_connection_manager/v3}/Rds.ts | 8 +- .../v3}/RequestIDExtension.ts | 2 +- .../v3/ResponseMapper.ts | 67 ++ .../http_connection_manager/v3/ScopedRds.ts | 17 + .../v3/ScopedRouteConfigurationsList.ts | 17 + .../v3}/ScopedRoutes.ts | 88 +- .../envoy/service/discovery/v3/AdsDummy.ts | 16 + .../v3/AggregatedDiscoveryService.ts | 52 + .../discovery/v3/DeltaDiscoveryRequest.ts | 206 ++++ .../discovery/v3/DeltaDiscoveryResponse.ts | 74 ++ .../service/discovery/v3/DiscoveryRequest.ts | 110 ++ .../service/discovery/v3/DiscoveryResponse.ts | 106 ++ .../envoy/service/discovery/v3/Resource.ts | 118 ++ .../load_stats/v3/LoadReportingService.ts | 108 ++ .../service/load_stats/v3/LoadStatsRequest.ts | 32 + .../load_stats/v3/LoadStatsResponse.ts | 71 ++ .../src/generated/envoy/type/Percent.ts | 2 +- .../envoy/type/matcher/ListStringMatcher.ts | 17 - .../envoy/type/matcher/v3/DoubleMatcher.ts | 35 + .../envoy/type/matcher/v3/ListMatcher.ts | 25 + .../type/matcher/v3/ListStringMatcher.ts | 17 + .../envoy/type/matcher/v3/MetadataMatcher.ts | 65 + .../{ => v3}/RegexMatchAndSubstitute.ts | 8 +- .../type/matcher/{ => v3}/RegexMatcher.ts | 32 +- .../type/matcher/{ => v3}/StringMatcher.ts | 66 +- .../envoy/type/matcher/v3/ValueMatcher.ts | 101 ++ .../envoy/type/metadata/v2/MetadataKind.ts | 98 -- .../type/metadata/{v2 => v3}/MetadataKey.ts | 14 +- .../envoy/type/metadata/v3/MetadataKind.ts | 98 ++ .../type/tracing/{v2 => v3}/CustomTag.ts | 54 +- .../envoy/type/{ => v3}/CodecClientType.ts | 2 +- .../envoy/type/{ => v3}/DoubleRange.ts | 6 +- .../envoy/type/v3/FractionalPercent.ts | 68 ++ .../envoy/type/{ => v3}/Int32Range.ts | 2 +- .../envoy/type/{ => v3}/Int64Range.ts | 2 +- .../src/generated/envoy/type/v3/Percent.ts | 16 + .../envoy/type/v3/SemanticVersion.ts | 24 + .../generated/google/api/CustomHttpPattern.ts | 30 - .../src/generated/google/api/Http.ts | 49 - .../src/generated/google/api/HttpRule.ts | 680 ----------- .../src/generated/google/protobuf/Any.ts | 6 +- .../generated/google/protobuf/DoubleValue.ts | 2 +- .../generated/google/protobuf/FieldOptions.ts | 3 + .../generated/google/protobuf/FloatValue.ts | 2 +- .../google/protobuf/MessageOptions.ts | 3 + .../google/protobuf/UninterpretedOption.ts | 2 +- .../src/generated/google/protobuf/Value.ts | 2 +- .../src/generated/http_connection_manager.ts | 123 +- .../grpc-js-xds/src/generated/listener.ts | 132 ++- packages/grpc-js-xds/src/generated/lrs.ts | 59 + packages/grpc-js-xds/src/generated/route.ts | 58 +- .../annotations/FieldSecurityAnnotation.ts | 32 + .../udpa/annotations/VersioningAnnotation.ts | 20 + .../src/generated/validate/DoubleRules.ts | 14 +- .../src/generated/validate/FloatRules.ts | 14 +- .../src/generated/xds/core/v3/Authority.ts | 16 + .../generated/xds/core/v3/CollectionEntry.ts | 90 ++ .../generated/xds/core/v3/ContextParams.ts | 26 + .../generated/xds/core/v3/ResourceLocator.ts | 220 ++++ 222 files changed, 9580 insertions(+), 5510 deletions(-) delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/UpstreamConnectionOptions.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/Vhds.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/auth/CertificateValidationContext.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/auth/CommonTlsContext.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/auth/DownstreamTlsContext.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/auth/GenericSecret.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/auth/PrivateKeyProvider.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/auth/SdsSecretConfig.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/auth/Secret.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/auth/TlsCertificate.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/auth/TlsParameters.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/auth/TlsSessionTicketKeys.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/auth/UpstreamTlsContext.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/GrpcProtocolOptions.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/SelfConfigSource.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/listener/Filter.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/listener/FilterChain.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/route/HedgePolicy.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/route/QueryParameterMatcher.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/route/RateLimit.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/route/RedirectAction.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/route/RetryPolicy.ts rename packages/grpc-js-xds/src/generated/envoy/config/{filter/accesslog/v2 => accesslog/v3}/AccessLog.ts (54%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AccessLogFilter.ts rename packages/grpc-js-xds/src/generated/envoy/config/{filter/accesslog/v2 => accesslog/v3}/AndFilter.ts (51%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/ComparisonFilter.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/DurationFilter.ts rename packages/grpc-js-xds/src/generated/envoy/config/{filter/accesslog/v2 => accesslog/v3}/ExtensionFilter.ts (64%) rename packages/grpc-js-xds/src/generated/envoy/config/{filter/accesslog/v2 => accesslog/v3}/GrpcStatusFilter.ts (51%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/HeaderFilter.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/MetadataFilter.ts rename packages/grpc-js-xds/src/generated/envoy/config/{filter/accesslog/v2 => accesslog/v3}/NotHealthCheckFilter.ts (81%) rename packages/grpc-js-xds/src/generated/envoy/config/{filter/accesslog/v2 => accesslog/v3}/OrFilter.ts (50%) rename packages/grpc-js-xds/src/generated/envoy/config/{filter/accesslog/v2 => accesslog/v3}/ResponseFlagFilter.ts (51%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/RuntimeFilter.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/StatusCodeFilter.ts rename packages/grpc-js-xds/src/generated/envoy/config/{filter/accesslog/v2 => accesslog/v3}/TraceableFilter.ts (81%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2/cluster => config/cluster/v3}/CircuitBreakers.ts (75%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2 => config/cluster/v3}/Cluster.ts (50%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/ClusterCollection.ts rename packages/grpc-js-xds/src/generated/envoy/{api/v2/cluster => config/cluster/v3}/Filter.ts (92%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2 => config/cluster/v3}/LoadBalancingPolicy.ts (80%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2/cluster => config/cluster/v3}/OutlierDetection.ts (85%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/TrackClusterStats.ts rename packages/grpc-js-xds/src/generated/envoy/{api/v2 => config/cluster/v3}/UpstreamBindConfig.ts (59%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/UpstreamConnectionOptions.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/Address.ts rename packages/grpc-js-xds/src/generated/envoy/{api/v2/core => config/core/v3}/AggregatedConfigSource.ts (57%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2/core => config/core/v3}/ApiConfigSource.ts (66%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2/core => config/core/v3}/ApiVersion.ts (69%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/AsyncDataSource.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/BackoffStrategy.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/BindConfig.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/BuildVersion.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/CidrRange.ts rename packages/grpc-js-xds/src/generated/envoy/{api/v2/core => config/core/v3}/ConfigSource.ts (70%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/ControlPlane.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/DataSource.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/EnvoyInternalAddress.ts rename packages/grpc-js-xds/src/generated/envoy/{api/v2/core => config/core/v3}/EventServiceConfig.ts (58%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/Extension.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/ExtensionConfigSource.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/GrpcProtocolOptions.ts rename packages/grpc-js-xds/src/generated/envoy/{api/v2/core => config/core/v3}/GrpcService.ts (59%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/HeaderMap.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/HeaderValue.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/HeaderValueOption.ts rename packages/grpc-js-xds/src/generated/envoy/{api/v2/core => config/core/v3}/HealthCheck.ts (67%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2/core => config/core/v3}/HealthStatus.ts (91%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2/core => config/core/v3}/Http1ProtocolOptions.ts (57%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2/core => config/core/v3}/Http2ProtocolOptions.ts (65%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http3ProtocolOptions.ts rename packages/grpc-js-xds/src/generated/envoy/{api/v2/core => config/core/v3}/HttpProtocolOptions.ts (75%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/HttpUri.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/KeepaliveSettings.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/Locality.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/Metadata.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/Node.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/Pipe.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/ProxyProtocolConfig.ts rename packages/grpc-js-xds/src/generated/envoy/{api/v2/core => config/core/v3}/RateLimitSettings.ts (94%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/RemoteDataSource.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/RequestMethod.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/RetryPolicy.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/RoutingPriority.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeDouble.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeFeatureFlag.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeFractionalPercent.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimePercent.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeUInt32.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/SelfConfigSource.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/SocketAddress.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/SocketOption.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/SubstitutionFormatString.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/TcpKeepalive.ts rename packages/grpc-js-xds/src/generated/envoy/{api/v2/core => config/core/v3}/TcpProtocolOptions.ts (70%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/TrafficDirection.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/TransportSocket.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/TypedExtensionConfig.ts rename packages/grpc-js-xds/src/generated/envoy/{api/v2/core => config/core/v3}/UpstreamHttpProtocolOptions.ts (95%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/WatchedDirectory.ts rename packages/grpc-js-xds/src/generated/envoy/{api/v2 => config/endpoint/v3}/ClusterLoadAssignment.ts (67%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterStats.ts rename packages/grpc-js-xds/src/generated/envoy/{api/v2/endpoint => config/endpoint/v3}/Endpoint.ts (69%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/EndpointLoadMetricStats.ts rename packages/grpc-js-xds/src/generated/envoy/{api/v2/endpoint => config/endpoint/v3}/LbEndpoint.ts (74%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2/endpoint => config/endpoint/v3}/LocalityLbEndpoints.ts (87%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/UpstreamEndpointStats.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/UpstreamLocalityStats.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/AccessLogFilter.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/ComparisonFilter.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/DurationFilter.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/HeaderFilter.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/RuntimeFilter.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/StatusCodeFilter.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/HttpFilter.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/ScopedRds.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/ScopedRouteConfigurationsList.ts rename packages/grpc-js-xds/src/generated/envoy/{api/v2/listener => config/listener/v3}/ActiveRawUdpListenerConfig.ts (56%) rename packages/grpc-js-xds/src/generated/envoy/config/listener/{v2 => v3}/ApiListener.ts (96%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/listener/v3/Filter.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/listener/v3/FilterChain.ts rename packages/grpc-js-xds/src/generated/envoy/{api/v2/listener => config/listener/v3}/FilterChainMatch.ts (81%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2 => config/listener/v3}/Listener.ts (66%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerCollection.ts rename packages/grpc-js-xds/src/generated/envoy/{api/v2/listener => config/listener/v3}/ListenerFilter.ts (58%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2/listener => config/listener/v3}/ListenerFilterChainMatchPredicate.ts (66%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2/listener => config/listener/v3}/UdpListenerConfig.ts (72%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2/route => config/route/v3}/CorsPolicy.ts (50%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2/route => config/route/v3}/Decorator.ts (94%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2/route => config/route/v3}/DirectResponseAction.ts (52%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2/route => config/route/v3}/FilterAction.ts (82%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/route/v3/FilterConfig.ts rename packages/grpc-js-xds/src/generated/envoy/{api/v2/route => config/route/v3}/HeaderMatcher.ts (69%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/route/v3/HedgePolicy.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/route/v3/InternalRedirectPolicy.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/route/v3/QueryParameterMatcher.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/route/v3/RateLimit.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/route/v3/RedirectAction.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/route/v3/RetryPolicy.ts rename packages/grpc-js-xds/src/generated/envoy/{api/v2/route => config/route/v3}/Route.ts (58%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2/route => config/route/v3}/RouteAction.ts (62%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2 => config/route/v3}/RouteConfiguration.ts (63%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2/route => config/route/v3}/RouteMatch.ts (67%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2 => config/route/v3}/ScopedRouteConfiguration.ts (59%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2/route => config/route/v3}/Tracing.ts (75%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/route/v3/Vhds.ts rename packages/grpc-js-xds/src/generated/envoy/{api/v2/route => config/route/v3}/VirtualCluster.ts (58%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2/route => config/route/v3}/VirtualHost.ts (71%) rename packages/grpc-js-xds/src/generated/envoy/{api/v2/route => config/route/v3}/WeightedCluster.ts (64%) rename packages/grpc-js-xds/src/generated/envoy/config/trace/{v2 => v3}/Tracing.ts (54%) rename packages/grpc-js-xds/src/generated/envoy/{config/filter/network/http_connection_manager/v2 => extensions/filters/network/http_connection_manager/v3}/HttpConnectionManager.ts (64%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpFilter.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/LocalReplyConfig.ts rename packages/grpc-js-xds/src/generated/envoy/{config/filter/network/http_connection_manager/v2 => extensions/filters/network/http_connection_manager/v3}/Rds.ts (63%) rename packages/grpc-js-xds/src/generated/envoy/{config/filter/network/http_connection_manager/v2 => extensions/filters/network/http_connection_manager/v3}/RequestIDExtension.ts (78%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ResponseMapper.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRds.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRouteConfigurationsList.ts rename packages/grpc-js-xds/src/generated/envoy/{config/filter/network/http_connection_manager/v2 => extensions/filters/network/http_connection_manager/v3}/ScopedRoutes.ts (57%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/AdsDummy.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/AggregatedDiscoveryService.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DeltaDiscoveryRequest.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DeltaDiscoveryResponse.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DiscoveryRequest.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DiscoveryResponse.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/Resource.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadReportingService.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadStatsRequest.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadStatsResponse.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/type/matcher/ListStringMatcher.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/DoubleMatcher.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/ListMatcher.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/ListStringMatcher.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/MetadataMatcher.ts rename packages/grpc-js-xds/src/generated/envoy/type/matcher/{ => v3}/RegexMatchAndSubstitute.ts (89%) rename packages/grpc-js-xds/src/generated/envoy/type/matcher/{ => v3}/RegexMatcher.ts (57%) rename packages/grpc-js-xds/src/generated/envoy/type/matcher/{ => v3}/StringMatcher.ts (58%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/ValueMatcher.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/type/metadata/v2/MetadataKind.ts rename packages/grpc-js-xds/src/generated/envoy/type/metadata/{v2 => v3}/MetadataKey.ts (85%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/type/metadata/v3/MetadataKind.ts rename packages/grpc-js-xds/src/generated/envoy/type/tracing/{v2 => v3}/CustomTag.ts (66%) rename packages/grpc-js-xds/src/generated/envoy/type/{ => v3}/CodecClientType.ts (84%) rename packages/grpc-js-xds/src/generated/envoy/type/{ => v3}/DoubleRange.ts (82%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/type/v3/FractionalPercent.ts rename packages/grpc-js-xds/src/generated/envoy/type/{ => v3}/Int32Range.ts (90%) rename packages/grpc-js-xds/src/generated/envoy/type/{ => v3}/Int64Range.ts (91%) create mode 100644 packages/grpc-js-xds/src/generated/envoy/type/v3/Percent.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/type/v3/SemanticVersion.ts delete mode 100644 packages/grpc-js-xds/src/generated/google/api/CustomHttpPattern.ts delete mode 100644 packages/grpc-js-xds/src/generated/google/api/Http.ts delete mode 100644 packages/grpc-js-xds/src/generated/google/api/HttpRule.ts create mode 100644 packages/grpc-js-xds/src/generated/udpa/annotations/FieldSecurityAnnotation.ts create mode 100644 packages/grpc-js-xds/src/generated/udpa/annotations/VersioningAnnotation.ts create mode 100644 packages/grpc-js-xds/src/generated/xds/core/v3/Authority.ts create mode 100644 packages/grpc-js-xds/src/generated/xds/core/v3/CollectionEntry.ts create mode 100644 packages/grpc-js-xds/src/generated/xds/core/v3/ContextParams.ts create mode 100644 packages/grpc-js-xds/src/generated/xds/core/v3/ResourceLocator.ts diff --git a/packages/grpc-js-xds/deps/envoy-api b/packages/grpc-js-xds/deps/envoy-api index 50cef8fca..18b54850c 160000 --- a/packages/grpc-js-xds/deps/envoy-api +++ b/packages/grpc-js-xds/deps/envoy-api @@ -1 +1 @@ -Subproject commit 50cef8fcab37ba59a61068934d08a3f4c28a681f +Subproject commit 18b54850c9b7ba29a4ab67cbd7ed7eab7b0bbdb2 diff --git a/packages/grpc-js-xds/deps/udpa b/packages/grpc-js-xds/deps/udpa index 3b31d022a..cc1b757b3 160000 --- a/packages/grpc-js-xds/deps/udpa +++ b/packages/grpc-js-xds/deps/udpa @@ -1 +1 @@ -Subproject commit 3b31d022a144b334eb2224838e4d6952ab5253aa +Subproject commit cc1b757b3eddccaaaf0743cbb107742bb7e3ee4f diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index 3f90c7e97..f69c8bf49 100644 --- a/packages/grpc-js-xds/package.json +++ b/packages/grpc-js-xds/package.json @@ -12,7 +12,7 @@ "prepare": "npm run compile", "pretest": "npm run compile", "posttest": "npm run check", - "generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --json --includeComments --includeDirs deps/envoy-api/ deps/udpa/ deps/googleapis/ deps/protoc-gen-validate/ -O src/generated/ --grpcLib @grpc/grpc-js envoy/service/discovery/v2/ads.proto envoy/service/load_stats/v2/lrs.proto envoy/api/v2/listener.proto envoy/api/v2/route.proto envoy/api/v2/cluster.proto envoy/api/v2/endpoint.proto envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto", + "generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs deps/envoy-api/ deps/udpa/ deps/googleapis/ deps/protoc-gen-validate/ -O src/generated/ --grpcLib @grpc/grpc-js envoy/service/discovery/v2/ads.proto envoy/service/load_stats/v2/lrs.proto 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", "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" }, "repository": { diff --git a/packages/grpc-js-xds/src/generated/ads.ts b/packages/grpc-js-xds/src/generated/ads.ts index 0eacd1e34..665374958 100644 --- a/packages/grpc-js-xds/src/generated/ads.ts +++ b/packages/grpc-js-xds/src/generated/ads.ts @@ -2,6 +2,7 @@ import type * as grpc from '@grpc/grpc-js'; import type { ServiceDefinition, EnumTypeDefinition, MessageTypeDefinition } from '@grpc/proto-loader'; import type { AggregatedDiscoveryServiceClient as _envoy_service_discovery_v2_AggregatedDiscoveryServiceClient } from './envoy/service/discovery/v2/AggregatedDiscoveryService'; +import type { AggregatedDiscoveryServiceClient as _envoy_service_discovery_v3_AggregatedDiscoveryServiceClient } from './envoy/service/discovery/v3/AggregatedDiscoveryService'; type SubtypeConstructor any, Subtype> = { new(...args: ConstructorParameters): Subtype; @@ -50,6 +51,45 @@ export interface ProtoGrpcType { } } } + config: { + core: { + v3: { + Address: MessageTypeDefinition + AsyncDataSource: MessageTypeDefinition + BackoffStrategy: MessageTypeDefinition + BindConfig: MessageTypeDefinition + BuildVersion: MessageTypeDefinition + CidrRange: MessageTypeDefinition + ControlPlane: MessageTypeDefinition + DataSource: MessageTypeDefinition + EnvoyInternalAddress: MessageTypeDefinition + Extension: MessageTypeDefinition + HeaderMap: MessageTypeDefinition + HeaderValue: MessageTypeDefinition + HeaderValueOption: MessageTypeDefinition + HttpUri: MessageTypeDefinition + Locality: MessageTypeDefinition + Metadata: MessageTypeDefinition + Node: MessageTypeDefinition + Pipe: MessageTypeDefinition + RemoteDataSource: MessageTypeDefinition + RequestMethod: EnumTypeDefinition + RetryPolicy: MessageTypeDefinition + RoutingPriority: EnumTypeDefinition + RuntimeDouble: MessageTypeDefinition + RuntimeFeatureFlag: MessageTypeDefinition + RuntimeFractionalPercent: MessageTypeDefinition + RuntimePercent: MessageTypeDefinition + RuntimeUInt32: MessageTypeDefinition + SocketAddress: MessageTypeDefinition + SocketOption: MessageTypeDefinition + TcpKeepalive: MessageTypeDefinition + TrafficDirection: EnumTypeDefinition + TransportSocket: MessageTypeDefinition + WatchedDirectory: MessageTypeDefinition + } + } + } service: { discovery: { v2: { @@ -64,12 +104,34 @@ export interface ProtoGrpcType { */ AggregatedDiscoveryService: SubtypeConstructor & { service: ServiceDefinition } } + v3: { + AdsDummy: MessageTypeDefinition + /** + * See https://github.com/lyft/envoy-api#apis for a description of the role of + * ADS and how it is intended to be used by a management server. ADS requests + * have the same structure as their singleton xDS counterparts, but can + * multiplex many resource types on a single stream. The type_url in the + * DiscoveryRequest/DiscoveryResponse provides sufficient information to recover + * the multiplexed singleton APIs at the Envoy instance and management server. + */ + AggregatedDiscoveryService: SubtypeConstructor & { service: ServiceDefinition } + DeltaDiscoveryRequest: MessageTypeDefinition + DeltaDiscoveryResponse: MessageTypeDefinition + DiscoveryRequest: MessageTypeDefinition + DiscoveryResponse: MessageTypeDefinition + Resource: MessageTypeDefinition + } } } type: { FractionalPercent: MessageTypeDefinition Percent: MessageTypeDefinition SemanticVersion: MessageTypeDefinition + v3: { + FractionalPercent: MessageTypeDefinition + Percent: MessageTypeDefinition + SemanticVersion: MessageTypeDefinition + } } } google: { @@ -122,6 +184,7 @@ export interface ProtoGrpcType { MigrateAnnotation: MessageTypeDefinition PackageVersionStatus: EnumTypeDefinition StatusAnnotation: MessageTypeDefinition + VersioningAnnotation: MessageTypeDefinition } } validate: { diff --git a/packages/grpc-js-xds/src/generated/cluster.ts b/packages/grpc-js-xds/src/generated/cluster.ts index b7005a3f0..5e4683580 100644 --- a/packages/grpc-js-xds/src/generated/cluster.ts +++ b/packages/grpc-js-xds/src/generated/cluster.ts @@ -10,32 +10,22 @@ export interface ProtoGrpcType { envoy: { annotations: { } - api: { - v2: { - Cluster: MessageTypeDefinition - ClusterLoadAssignment: MessageTypeDefinition - LoadBalancingPolicy: MessageTypeDefinition - UpstreamBindConfig: MessageTypeDefinition - UpstreamConnectionOptions: MessageTypeDefinition - auth: { - CertificateValidationContext: MessageTypeDefinition - CommonTlsContext: MessageTypeDefinition - DownstreamTlsContext: MessageTypeDefinition - GenericSecret: MessageTypeDefinition - PrivateKeyProvider: MessageTypeDefinition - SdsSecretConfig: MessageTypeDefinition - Secret: MessageTypeDefinition - TlsCertificate: MessageTypeDefinition - TlsParameters: MessageTypeDefinition - TlsSessionTicketKeys: MessageTypeDefinition - UpstreamTlsContext: MessageTypeDefinition - } - cluster: { + config: { + cluster: { + v3: { CircuitBreakers: MessageTypeDefinition + Cluster: MessageTypeDefinition + ClusterCollection: MessageTypeDefinition Filter: MessageTypeDefinition + LoadBalancingPolicy: MessageTypeDefinition OutlierDetection: MessageTypeDefinition + TrackClusterStats: MessageTypeDefinition + UpstreamBindConfig: MessageTypeDefinition + UpstreamConnectionOptions: MessageTypeDefinition } - core: { + } + core: { + v3: { Address: MessageTypeDefinition AggregatedConfigSource: MessageTypeDefinition ApiConfigSource: MessageTypeDefinition @@ -48,8 +38,10 @@ export interface ProtoGrpcType { ConfigSource: MessageTypeDefinition ControlPlane: MessageTypeDefinition DataSource: MessageTypeDefinition + EnvoyInternalAddress: MessageTypeDefinition EventServiceConfig: MessageTypeDefinition Extension: MessageTypeDefinition + ExtensionConfigSource: MessageTypeDefinition GrpcProtocolOptions: MessageTypeDefinition GrpcService: MessageTypeDefinition HeaderMap: MessageTypeDefinition @@ -59,8 +51,10 @@ export interface ProtoGrpcType { HealthStatus: EnumTypeDefinition Http1ProtocolOptions: MessageTypeDefinition Http2ProtocolOptions: MessageTypeDefinition + Http3ProtocolOptions: MessageTypeDefinition HttpProtocolOptions: MessageTypeDefinition HttpUri: MessageTypeDefinition + KeepaliveSettings: MessageTypeDefinition Locality: MessageTypeDefinition Metadata: MessageTypeDefinition Node: MessageTypeDefinition @@ -73,6 +67,7 @@ export interface ProtoGrpcType { RuntimeDouble: MessageTypeDefinition RuntimeFeatureFlag: MessageTypeDefinition RuntimeFractionalPercent: MessageTypeDefinition + RuntimePercent: MessageTypeDefinition RuntimeUInt32: MessageTypeDefinition SelfConfigSource: MessageTypeDefinition SocketAddress: MessageTypeDefinition @@ -81,9 +76,14 @@ export interface ProtoGrpcType { TcpProtocolOptions: MessageTypeDefinition TrafficDirection: EnumTypeDefinition TransportSocket: MessageTypeDefinition + TypedExtensionConfig: MessageTypeDefinition UpstreamHttpProtocolOptions: MessageTypeDefinition + WatchedDirectory: MessageTypeDefinition } - endpoint: { + } + endpoint: { + v3: { + ClusterLoadAssignment: MessageTypeDefinition Endpoint: MessageTypeDefinition LbEndpoint: MessageTypeDefinition LocalityLbEndpoints: MessageTypeDefinition @@ -91,27 +91,26 @@ export interface ProtoGrpcType { } } type: { - CodecClientType: EnumTypeDefinition - DoubleRange: MessageTypeDefinition - FractionalPercent: MessageTypeDefinition - Int32Range: MessageTypeDefinition - Int64Range: MessageTypeDefinition - Percent: MessageTypeDefinition - SemanticVersion: MessageTypeDefinition matcher: { - ListStringMatcher: MessageTypeDefinition - RegexMatchAndSubstitute: MessageTypeDefinition - RegexMatcher: MessageTypeDefinition - StringMatcher: MessageTypeDefinition + v3: { + ListStringMatcher: MessageTypeDefinition + RegexMatchAndSubstitute: MessageTypeDefinition + RegexMatcher: MessageTypeDefinition + StringMatcher: MessageTypeDefinition + } + } + v3: { + CodecClientType: EnumTypeDefinition + DoubleRange: MessageTypeDefinition + FractionalPercent: MessageTypeDefinition + Int32Range: MessageTypeDefinition + Int64Range: MessageTypeDefinition + Percent: MessageTypeDefinition + SemanticVersion: MessageTypeDefinition } } } google: { - api: { - CustomHttpPattern: MessageTypeDefinition - Http: MessageTypeDefinition - HttpRule: MessageTypeDefinition - } protobuf: { Any: MessageTypeDefinition BoolValue: MessageTypeDefinition @@ -155,10 +154,12 @@ export interface ProtoGrpcType { udpa: { annotations: { FieldMigrateAnnotation: MessageTypeDefinition + FieldSecurityAnnotation: MessageTypeDefinition FileMigrateAnnotation: MessageTypeDefinition MigrateAnnotation: MessageTypeDefinition PackageVersionStatus: EnumTypeDefinition StatusAnnotation: MessageTypeDefinition + VersioningAnnotation: MessageTypeDefinition } } validate: { @@ -187,5 +188,15 @@ export interface ProtoGrpcType { UInt32Rules: MessageTypeDefinition UInt64Rules: MessageTypeDefinition } + xds: { + core: { + v3: { + Authority: MessageTypeDefinition + CollectionEntry: MessageTypeDefinition + ContextParams: MessageTypeDefinition + ResourceLocator: MessageTypeDefinition + } + } + } } diff --git a/packages/grpc-js-xds/src/generated/endpoint.ts b/packages/grpc-js-xds/src/generated/endpoint.ts index 33d5872ef..dda6a78da 100644 --- a/packages/grpc-js-xds/src/generated/endpoint.ts +++ b/packages/grpc-js-xds/src/generated/endpoint.ts @@ -8,12 +8,9 @@ type SubtypeConstructor any, Subtype> export interface ProtoGrpcType { envoy: { - annotations: { - } - api: { - v2: { - ClusterLoadAssignment: MessageTypeDefinition - core: { + config: { + core: { + v3: { Address: MessageTypeDefinition AsyncDataSource: MessageTypeDefinition BackoffStrategy: MessageTypeDefinition @@ -22,6 +19,7 @@ export interface ProtoGrpcType { CidrRange: MessageTypeDefinition ControlPlane: MessageTypeDefinition DataSource: MessageTypeDefinition + EnvoyInternalAddress: MessageTypeDefinition EventServiceConfig: MessageTypeDefinition Extension: MessageTypeDefinition GrpcService: MessageTypeDefinition @@ -42,14 +40,19 @@ export interface ProtoGrpcType { RuntimeDouble: MessageTypeDefinition RuntimeFeatureFlag: MessageTypeDefinition RuntimeFractionalPercent: MessageTypeDefinition + RuntimePercent: MessageTypeDefinition RuntimeUInt32: MessageTypeDefinition SocketAddress: MessageTypeDefinition SocketOption: MessageTypeDefinition TcpKeepalive: MessageTypeDefinition TrafficDirection: EnumTypeDefinition TransportSocket: MessageTypeDefinition + WatchedDirectory: MessageTypeDefinition } - endpoint: { + } + endpoint: { + v3: { + ClusterLoadAssignment: MessageTypeDefinition Endpoint: MessageTypeDefinition LbEndpoint: MessageTypeDefinition LocalityLbEndpoints: MessageTypeDefinition @@ -57,27 +60,26 @@ export interface ProtoGrpcType { } } type: { - CodecClientType: EnumTypeDefinition - DoubleRange: MessageTypeDefinition - FractionalPercent: MessageTypeDefinition - Int32Range: MessageTypeDefinition - Int64Range: MessageTypeDefinition - Percent: MessageTypeDefinition - SemanticVersion: MessageTypeDefinition matcher: { - ListStringMatcher: MessageTypeDefinition - RegexMatchAndSubstitute: MessageTypeDefinition - RegexMatcher: MessageTypeDefinition - StringMatcher: MessageTypeDefinition + v3: { + ListStringMatcher: MessageTypeDefinition + RegexMatchAndSubstitute: MessageTypeDefinition + RegexMatcher: MessageTypeDefinition + StringMatcher: MessageTypeDefinition + } + } + v3: { + CodecClientType: EnumTypeDefinition + DoubleRange: MessageTypeDefinition + FractionalPercent: MessageTypeDefinition + Int32Range: MessageTypeDefinition + Int64Range: MessageTypeDefinition + Percent: MessageTypeDefinition + SemanticVersion: MessageTypeDefinition } } } google: { - api: { - CustomHttpPattern: MessageTypeDefinition - Http: MessageTypeDefinition - HttpRule: MessageTypeDefinition - } protobuf: { Any: MessageTypeDefinition BoolValue: MessageTypeDefinition @@ -125,6 +127,7 @@ export interface ProtoGrpcType { MigrateAnnotation: MessageTypeDefinition PackageVersionStatus: EnumTypeDefinition StatusAnnotation: MessageTypeDefinition + VersioningAnnotation: MessageTypeDefinition } } validate: { diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/UpstreamConnectionOptions.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/UpstreamConnectionOptions.ts deleted file mode 100644 index e46a2cd06..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/UpstreamConnectionOptions.ts +++ /dev/null @@ -1,17 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/cluster.proto - -import type { TcpKeepalive as _envoy_api_v2_core_TcpKeepalive, TcpKeepalive__Output as _envoy_api_v2_core_TcpKeepalive__Output } from '../../../envoy/api/v2/core/TcpKeepalive'; - -export interface UpstreamConnectionOptions { - /** - * If set then set SO_KEEPALIVE on the socket to enable TCP Keepalives. - */ - 'tcp_keepalive'?: (_envoy_api_v2_core_TcpKeepalive); -} - -export interface UpstreamConnectionOptions__Output { - /** - * If set then set SO_KEEPALIVE on the socket to enable TCP Keepalives. - */ - 'tcp_keepalive'?: (_envoy_api_v2_core_TcpKeepalive__Output); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/Vhds.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/Vhds.ts deleted file mode 100644 index f2ec45d2d..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/Vhds.ts +++ /dev/null @@ -1,17 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/route.proto - -import type { ConfigSource as _envoy_api_v2_core_ConfigSource, ConfigSource__Output as _envoy_api_v2_core_ConfigSource__Output } from '../../../envoy/api/v2/core/ConfigSource'; - -export interface Vhds { - /** - * Configuration source specifier for VHDS. - */ - 'config_source'?: (_envoy_api_v2_core_ConfigSource); -} - -export interface Vhds__Output { - /** - * Configuration source specifier for VHDS. - */ - 'config_source'?: (_envoy_api_v2_core_ConfigSource__Output); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/CertificateValidationContext.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/CertificateValidationContext.ts deleted file mode 100644 index 0272f3b5c..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/CertificateValidationContext.ts +++ /dev/null @@ -1,315 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/auth/common.proto - -import type { DataSource as _envoy_api_v2_core_DataSource, DataSource__Output as _envoy_api_v2_core_DataSource__Output } from '../../../../envoy/api/v2/core/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_StringMatcher, StringMatcher__Output as _envoy_type_matcher_StringMatcher__Output } from '../../../../envoy/type/matcher/StringMatcher'; - -// Original file: deps/envoy-api/envoy/api/v2/auth/common.proto - -/** - * Peer certificate verification mode. - */ -export enum _envoy_api_v2_auth_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: 11] - */ -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. - * - * See :ref:`the TLS overview ` for a list of common - * system CA locations. - */ - 'trusted_ca'?: (_envoy_api_v2_core_DataSource); - /** - * 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)[]; - /** - * An optional list of Subject Alternative Names. If specified, Envoy will verify that the - * Subject Alternative Name of the presented certificate matches one of the specified values. - * - * .. attention:: - * - * Subject Alternative Names are easily spoofable and verifying only them is insecure, - * therefore this option must be used together with :ref:`trusted_ca - * `. - */ - 'verify_subject_alt_name'?: (string)[]; - /** - * [#not-implemented-hide:] Must present a signed time-stamped OCSP response. - */ - 'require_ocsp_staple'?: (_google_protobuf_BoolValue); - /** - * [#not-implemented-hide:] Must present signed certificate time-stamp. - */ - 'require_signed_certificate_timestamp'?: (_google_protobuf_BoolValue); - /** - * 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. - */ - 'crl'?: (_envoy_api_v2_core_DataSource); - /** - * If specified, Envoy will not reject expired certificates. - */ - 'allow_expired_certificate'?: (boolean); - /** - * An optional list of Subject Alternative name matchers. Envoy will verify that the - * Subject Alternative Name of the presented certificate matches one of the specified matches. - * - * 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_StringMatcher)[]; - /** - * Certificate trust chain verification mode. - */ - 'trust_chain_verification'?: (_envoy_api_v2_auth_CertificateValidationContext_TrustChainVerification | keyof typeof _envoy_api_v2_auth_CertificateValidationContext_TrustChainVerification); -} - -/** - * [#next-free-field: 11] - */ -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. - * - * See :ref:`the TLS overview ` for a list of common - * system CA locations. - */ - 'trusted_ca'?: (_envoy_api_v2_core_DataSource__Output); - /** - * 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)[]; - /** - * An optional list of Subject Alternative Names. If specified, Envoy will verify that the - * Subject Alternative Name of the presented certificate matches one of the specified values. - * - * .. attention:: - * - * Subject Alternative Names are easily spoofable and verifying only them is insecure, - * therefore this option must be used together with :ref:`trusted_ca - * `. - */ - 'verify_subject_alt_name': (string)[]; - /** - * [#not-implemented-hide:] Must present a signed time-stamped OCSP response. - */ - 'require_ocsp_staple'?: (_google_protobuf_BoolValue__Output); - /** - * [#not-implemented-hide:] Must present signed certificate time-stamp. - */ - 'require_signed_certificate_timestamp'?: (_google_protobuf_BoolValue__Output); - /** - * 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. - */ - 'crl'?: (_envoy_api_v2_core_DataSource__Output); - /** - * If specified, Envoy will not reject expired certificates. - */ - 'allow_expired_certificate': (boolean); - /** - * An optional list of Subject Alternative name matchers. Envoy will verify that the - * Subject Alternative Name of the presented certificate matches one of the specified matches. - * - * 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_StringMatcher__Output)[]; - /** - * Certificate trust chain verification mode. - */ - 'trust_chain_verification': (keyof typeof _envoy_api_v2_auth_CertificateValidationContext_TrustChainVerification); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/CommonTlsContext.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/CommonTlsContext.ts deleted file mode 100644 index 784e3d2ce..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/CommonTlsContext.ts +++ /dev/null @@ -1,140 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/auth/tls.proto - -import type { TlsParameters as _envoy_api_v2_auth_TlsParameters, TlsParameters__Output as _envoy_api_v2_auth_TlsParameters__Output } from '../../../../envoy/api/v2/auth/TlsParameters'; -import type { TlsCertificate as _envoy_api_v2_auth_TlsCertificate, TlsCertificate__Output as _envoy_api_v2_auth_TlsCertificate__Output } from '../../../../envoy/api/v2/auth/TlsCertificate'; -import type { CertificateValidationContext as _envoy_api_v2_auth_CertificateValidationContext, CertificateValidationContext__Output as _envoy_api_v2_auth_CertificateValidationContext__Output } from '../../../../envoy/api/v2/auth/CertificateValidationContext'; -import type { SdsSecretConfig as _envoy_api_v2_auth_SdsSecretConfig, SdsSecretConfig__Output as _envoy_api_v2_auth_SdsSecretConfig__Output } from '../../../../envoy/api/v2/auth/SdsSecretConfig'; - -export interface _envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext { - /** - * How to validate peer certificates. - */ - 'default_validation_context'?: (_envoy_api_v2_auth_CertificateValidationContext); - /** - * Config for fetching validation context via SDS API. - */ - 'validation_context_sds_secret_config'?: (_envoy_api_v2_auth_SdsSecretConfig); -} - -export interface _envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext__Output { - /** - * How to validate peer certificates. - */ - 'default_validation_context'?: (_envoy_api_v2_auth_CertificateValidationContext__Output); - /** - * Config for fetching validation context via SDS API. - */ - 'validation_context_sds_secret_config'?: (_envoy_api_v2_auth_SdsSecretConfig__Output); -} - -/** - * TLS context shared by both client and server TLS contexts. - * [#next-free-field: 9] - */ -export interface CommonTlsContext { - /** - * TLS protocol versions, cipher suites etc. - */ - 'tls_params'?: (_envoy_api_v2_auth_TlsParameters); - /** - * :ref:`Multiple TLS certificates ` can be associated with the - * same context to allow both RSA and ECDSA certificates. - * - * Only a single TLS certificate is supported in client contexts. In server contexts, the first - * RSA certificate is used for clients that only support RSA and the first ECDSA certificate is - * used for clients that support ECDSA. - */ - 'tls_certificates'?: (_envoy_api_v2_auth_TlsCertificate)[]; - /** - * How to validate peer certificates. - */ - 'validation_context'?: (_envoy_api_v2_auth_CertificateValidationContext); - /** - * Supplies the list of ALPN protocols that the listener should expose. In - * practice this is likely to be set to one of two values (see the - * :ref:`codec_type - * ` - * parameter in the HTTP connection manager for more information): - * - * * "h2,http/1.1" If the listener is going to support both HTTP/2 and HTTP/1.1. - * * "http/1.1" If the listener is only going to support HTTP/1.1. - * - * There is no default for this parameter. If empty, Envoy will not expose ALPN. - */ - 'alpn_protocols'?: (string)[]; - /** - * Configs for fetching TLS certificates via SDS API. - */ - 'tls_certificate_sds_secret_configs'?: (_envoy_api_v2_auth_SdsSecretConfig)[]; - /** - * Config for fetching validation context via SDS API. - */ - 'validation_context_sds_secret_config'?: (_envoy_api_v2_auth_SdsSecretConfig); - /** - * Combined certificate validation context holds a default CertificateValidationContext - * and SDS config. When SDS server returns dynamic CertificateValidationContext, both dynamic - * and default CertificateValidationContext are merged into a new CertificateValidationContext - * for validation. This merge is done by Message::MergeFrom(), so dynamic - * CertificateValidationContext overwrites singular fields in default - * CertificateValidationContext, and concatenates repeated fields to default - * CertificateValidationContext, and logical OR is applied to boolean fields. - */ - 'combined_validation_context'?: (_envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext); - 'validation_context_type'?: "validation_context"|"validation_context_sds_secret_config"|"combined_validation_context"; -} - -/** - * TLS context shared by both client and server TLS contexts. - * [#next-free-field: 9] - */ -export interface CommonTlsContext__Output { - /** - * TLS protocol versions, cipher suites etc. - */ - 'tls_params'?: (_envoy_api_v2_auth_TlsParameters__Output); - /** - * :ref:`Multiple TLS certificates ` can be associated with the - * same context to allow both RSA and ECDSA certificates. - * - * Only a single TLS certificate is supported in client contexts. In server contexts, the first - * RSA certificate is used for clients that only support RSA and the first ECDSA certificate is - * used for clients that support ECDSA. - */ - 'tls_certificates': (_envoy_api_v2_auth_TlsCertificate__Output)[]; - /** - * How to validate peer certificates. - */ - 'validation_context'?: (_envoy_api_v2_auth_CertificateValidationContext__Output); - /** - * Supplies the list of ALPN protocols that the listener should expose. In - * practice this is likely to be set to one of two values (see the - * :ref:`codec_type - * ` - * parameter in the HTTP connection manager for more information): - * - * * "h2,http/1.1" If the listener is going to support both HTTP/2 and HTTP/1.1. - * * "http/1.1" If the listener is only going to support HTTP/1.1. - * - * There is no default for this parameter. If empty, Envoy will not expose ALPN. - */ - 'alpn_protocols': (string)[]; - /** - * Configs for fetching TLS certificates via SDS API. - */ - 'tls_certificate_sds_secret_configs': (_envoy_api_v2_auth_SdsSecretConfig__Output)[]; - /** - * Config for fetching validation context via SDS API. - */ - 'validation_context_sds_secret_config'?: (_envoy_api_v2_auth_SdsSecretConfig__Output); - /** - * Combined certificate validation context holds a default CertificateValidationContext - * and SDS config. When SDS server returns dynamic CertificateValidationContext, both dynamic - * and default CertificateValidationContext are merged into a new CertificateValidationContext - * for validation. This merge is done by Message::MergeFrom(), so dynamic - * CertificateValidationContext overwrites singular fields in default - * CertificateValidationContext, and concatenates repeated fields to default - * CertificateValidationContext, and logical OR is applied to boolean fields. - */ - 'combined_validation_context'?: (_envoy_api_v2_auth_CommonTlsContext_CombinedCertificateValidationContext__Output); - 'validation_context_type': "validation_context"|"validation_context_sds_secret_config"|"combined_validation_context"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/DownstreamTlsContext.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/DownstreamTlsContext.ts deleted file mode 100644 index ef9a6f9a4..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/DownstreamTlsContext.ts +++ /dev/null @@ -1,101 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/auth/tls.proto - -import type { CommonTlsContext as _envoy_api_v2_auth_CommonTlsContext, CommonTlsContext__Output as _envoy_api_v2_auth_CommonTlsContext__Output } from '../../../../envoy/api/v2/auth/CommonTlsContext'; -import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; -import type { TlsSessionTicketKeys as _envoy_api_v2_auth_TlsSessionTicketKeys, TlsSessionTicketKeys__Output as _envoy_api_v2_auth_TlsSessionTicketKeys__Output } from '../../../../envoy/api/v2/auth/TlsSessionTicketKeys'; -import type { SdsSecretConfig as _envoy_api_v2_auth_SdsSecretConfig, SdsSecretConfig__Output as _envoy_api_v2_auth_SdsSecretConfig__Output } from '../../../../envoy/api/v2/auth/SdsSecretConfig'; -import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; - -/** - * [#next-free-field: 8] - */ -export interface DownstreamTlsContext { - /** - * Common TLS context settings. - */ - 'common_tls_context'?: (_envoy_api_v2_auth_CommonTlsContext); - /** - * If specified, Envoy will reject connections without a valid client - * certificate. - */ - 'require_client_certificate'?: (_google_protobuf_BoolValue); - /** - * If specified, Envoy will reject connections without a valid and matching SNI. - * [#not-implemented-hide:] - */ - 'require_sni'?: (_google_protobuf_BoolValue); - /** - * TLS session ticket key settings. - */ - 'session_ticket_keys'?: (_envoy_api_v2_auth_TlsSessionTicketKeys); - /** - * Config for fetching TLS session ticket keys via SDS API. - */ - 'session_ticket_keys_sds_secret_config'?: (_envoy_api_v2_auth_SdsSecretConfig); - /** - * If specified, session_timeout will change maximum lifetime (in seconds) of TLS session - * Currently this value is used as a hint to `TLS session ticket lifetime (for TLSv1.2) - * ` - * only seconds could be specified (fractional seconds are going to be ignored). - */ - 'session_timeout'?: (_google_protobuf_Duration); - /** - * Config for controlling stateless TLS session resumption: setting this to true will cause the TLS - * server to not issue TLS session tickets for the purposes of stateless TLS session resumption. - * If set to false, the TLS server will issue TLS session tickets and encrypt/decrypt them using - * the keys specified through either :ref:`session_ticket_keys ` - * or :ref:`session_ticket_keys_sds_secret_config `. - * If this config is set to false and no keys are explicitly configured, the TLS server will issue - * TLS session tickets and encrypt/decrypt them using an internally-generated and managed key, with the - * implication that sessions cannot be resumed across hot restarts or on different hosts. - */ - 'disable_stateless_session_resumption'?: (boolean); - 'session_ticket_keys_type'?: "session_ticket_keys"|"session_ticket_keys_sds_secret_config"|"disable_stateless_session_resumption"; -} - -/** - * [#next-free-field: 8] - */ -export interface DownstreamTlsContext__Output { - /** - * Common TLS context settings. - */ - 'common_tls_context'?: (_envoy_api_v2_auth_CommonTlsContext__Output); - /** - * If specified, Envoy will reject connections without a valid client - * certificate. - */ - 'require_client_certificate'?: (_google_protobuf_BoolValue__Output); - /** - * If specified, Envoy will reject connections without a valid and matching SNI. - * [#not-implemented-hide:] - */ - 'require_sni'?: (_google_protobuf_BoolValue__Output); - /** - * TLS session ticket key settings. - */ - 'session_ticket_keys'?: (_envoy_api_v2_auth_TlsSessionTicketKeys__Output); - /** - * Config for fetching TLS session ticket keys via SDS API. - */ - 'session_ticket_keys_sds_secret_config'?: (_envoy_api_v2_auth_SdsSecretConfig__Output); - /** - * If specified, session_timeout will change maximum lifetime (in seconds) of TLS session - * Currently this value is used as a hint to `TLS session ticket lifetime (for TLSv1.2) - * ` - * only seconds could be specified (fractional seconds are going to be ignored). - */ - 'session_timeout'?: (_google_protobuf_Duration__Output); - /** - * Config for controlling stateless TLS session resumption: setting this to true will cause the TLS - * server to not issue TLS session tickets for the purposes of stateless TLS session resumption. - * If set to false, the TLS server will issue TLS session tickets and encrypt/decrypt them using - * the keys specified through either :ref:`session_ticket_keys ` - * or :ref:`session_ticket_keys_sds_secret_config `. - * If this config is set to false and no keys are explicitly configured, the TLS server will issue - * TLS session tickets and encrypt/decrypt them using an internally-generated and managed key, with the - * implication that sessions cannot be resumed across hot restarts or on different hosts. - */ - 'disable_stateless_session_resumption'?: (boolean); - 'session_ticket_keys_type': "session_ticket_keys"|"session_ticket_keys_sds_secret_config"|"disable_stateless_session_resumption"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/GenericSecret.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/GenericSecret.ts deleted file mode 100644 index d7b712525..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/GenericSecret.ts +++ /dev/null @@ -1,17 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/auth/secret.proto - -import type { DataSource as _envoy_api_v2_core_DataSource, DataSource__Output as _envoy_api_v2_core_DataSource__Output } from '../../../../envoy/api/v2/core/DataSource'; - -export interface GenericSecret { - /** - * Secret of generic type and is available to filters. - */ - 'secret'?: (_envoy_api_v2_core_DataSource); -} - -export interface GenericSecret__Output { - /** - * Secret of generic type and is available to filters. - */ - 'secret'?: (_envoy_api_v2_core_DataSource__Output); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/PrivateKeyProvider.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/PrivateKeyProvider.ts deleted file mode 100644 index 415448053..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/PrivateKeyProvider.ts +++ /dev/null @@ -1,42 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/auth/common.proto - -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; -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); - 'config'?: (_google_protobuf_Struct); - 'typed_config'?: (_google_protobuf_Any); - /** - * Private key method provider specific configuration. - */ - 'config_type'?: "config"|"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); - 'config'?: (_google_protobuf_Struct__Output); - 'typed_config'?: (_google_protobuf_Any__Output); - /** - * Private key method provider specific configuration. - */ - 'config_type': "config"|"typed_config"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/SdsSecretConfig.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/SdsSecretConfig.ts deleted file mode 100644 index 888059332..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/SdsSecretConfig.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/auth/secret.proto - -import type { ConfigSource as _envoy_api_v2_core_ConfigSource, ConfigSource__Output as _envoy_api_v2_core_ConfigSource__Output } from '../../../../envoy/api/v2/core/ConfigSource'; - -export interface SdsSecretConfig { - /** - * Name (FQDN, UUID, SPKI, SHA256, etc.) 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_api_v2_core_ConfigSource); -} - -export interface SdsSecretConfig__Output { - /** - * Name (FQDN, UUID, SPKI, SHA256, etc.) 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_api_v2_core_ConfigSource__Output); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/Secret.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/Secret.ts deleted file mode 100644 index 0768daed8..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/Secret.ts +++ /dev/null @@ -1,36 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/auth/secret.proto - -import type { TlsCertificate as _envoy_api_v2_auth_TlsCertificate, TlsCertificate__Output as _envoy_api_v2_auth_TlsCertificate__Output } from '../../../../envoy/api/v2/auth/TlsCertificate'; -import type { TlsSessionTicketKeys as _envoy_api_v2_auth_TlsSessionTicketKeys, TlsSessionTicketKeys__Output as _envoy_api_v2_auth_TlsSessionTicketKeys__Output } from '../../../../envoy/api/v2/auth/TlsSessionTicketKeys'; -import type { CertificateValidationContext as _envoy_api_v2_auth_CertificateValidationContext, CertificateValidationContext__Output as _envoy_api_v2_auth_CertificateValidationContext__Output } from '../../../../envoy/api/v2/auth/CertificateValidationContext'; -import type { GenericSecret as _envoy_api_v2_auth_GenericSecret, GenericSecret__Output as _envoy_api_v2_auth_GenericSecret__Output } from '../../../../envoy/api/v2/auth/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_api_v2_auth_TlsCertificate); - 'session_ticket_keys'?: (_envoy_api_v2_auth_TlsSessionTicketKeys); - 'validation_context'?: (_envoy_api_v2_auth_CertificateValidationContext); - 'generic_secret'?: (_envoy_api_v2_auth_GenericSecret); - '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_api_v2_auth_TlsCertificate__Output); - 'session_ticket_keys'?: (_envoy_api_v2_auth_TlsSessionTicketKeys__Output); - 'validation_context'?: (_envoy_api_v2_auth_CertificateValidationContext__Output); - 'generic_secret'?: (_envoy_api_v2_auth_GenericSecret__Output); - 'type': "tls_certificate"|"session_ticket_keys"|"validation_context"|"generic_secret"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/TlsCertificate.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/TlsCertificate.ts deleted file mode 100644 index dd7efcf21..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/TlsCertificate.ts +++ /dev/null @@ -1,78 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/auth/common.proto - -import type { DataSource as _envoy_api_v2_core_DataSource, DataSource__Output as _envoy_api_v2_core_DataSource__Output } from '../../../../envoy/api/v2/core/DataSource'; -import type { PrivateKeyProvider as _envoy_api_v2_auth_PrivateKeyProvider, PrivateKeyProvider__Output as _envoy_api_v2_auth_PrivateKeyProvider__Output } from '../../../../envoy/api/v2/auth/PrivateKeyProvider'; - -/** - * [#next-free-field: 7] - */ -export interface TlsCertificate { - /** - * The TLS certificate chain. - */ - 'certificate_chain'?: (_envoy_api_v2_core_DataSource); - /** - * The TLS private key. - */ - 'private_key'?: (_envoy_api_v2_core_DataSource); - /** - * 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_api_v2_core_DataSource); - /** - * [#not-implemented-hide:] - */ - 'ocsp_staple'?: (_envoy_api_v2_core_DataSource); - /** - * [#not-implemented-hide:] - */ - 'signed_certificate_timestamp'?: (_envoy_api_v2_core_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_api_v2_auth_PrivateKeyProvider); -} - -/** - * [#next-free-field: 7] - */ -export interface TlsCertificate__Output { - /** - * The TLS certificate chain. - */ - 'certificate_chain'?: (_envoy_api_v2_core_DataSource__Output); - /** - * The TLS private key. - */ - 'private_key'?: (_envoy_api_v2_core_DataSource__Output); - /** - * 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_api_v2_core_DataSource__Output); - /** - * [#not-implemented-hide:] - */ - 'ocsp_staple'?: (_envoy_api_v2_core_DataSource__Output); - /** - * [#not-implemented-hide:] - */ - 'signed_certificate_timestamp': (_envoy_api_v2_core_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_api_v2_auth_PrivateKeyProvider__Output); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/TlsParameters.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/TlsParameters.ts deleted file mode 100644 index 29fe8f4c8..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/TlsParameters.ts +++ /dev/null @@ -1,171 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/auth/common.proto - - -// Original file: deps/envoy-api/envoy/api/v2/auth/common.proto - -export enum _envoy_api_v2_auth_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_api_v2_auth_TlsParameters_TlsProtocol | keyof typeof _envoy_api_v2_auth_TlsParameters_TlsProtocol); - /** - * Maximum TLS protocol version. By default, it's ``TLSv1_3`` for servers in non-FIPS builds, and - * ``TLSv1_2`` for clients and for servers using :ref:`BoringSSL FIPS `. - */ - 'tls_maximum_protocol_version'?: (_envoy_api_v2_auth_TlsParameters_TlsProtocol | keyof typeof _envoy_api_v2_auth_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, the default list will be used. - * - * In non-FIPS builds, the default 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 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 - */ - '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_api_v2_auth_TlsParameters_TlsProtocol); - /** - * Maximum TLS protocol version. By default, it's ``TLSv1_3`` for servers in non-FIPS builds, and - * ``TLSv1_2`` for clients and for servers using :ref:`BoringSSL FIPS `. - */ - 'tls_maximum_protocol_version': (keyof typeof _envoy_api_v2_auth_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, the default list will be used. - * - * In non-FIPS builds, the default 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 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 - */ - '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/api/v2/auth/TlsSessionTicketKeys.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/TlsSessionTicketKeys.ts deleted file mode 100644 index d4bedd682..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/TlsSessionTicketKeys.ts +++ /dev/null @@ -1,61 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/auth/common.proto - -import type { DataSource as _envoy_api_v2_core_DataSource, DataSource__Output as _envoy_api_v2_core_DataSource__Output } from '../../../../envoy/api/v2/core/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_api_v2_core_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_api_v2_core_DataSource__Output)[]; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/UpstreamTlsContext.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/UpstreamTlsContext.ts deleted file mode 100644 index b9dc4414f..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/auth/UpstreamTlsContext.ts +++ /dev/null @@ -1,68 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/auth/tls.proto - -import type { CommonTlsContext as _envoy_api_v2_auth_CommonTlsContext, CommonTlsContext__Output as _envoy_api_v2_auth_CommonTlsContext__Output } from '../../../../envoy/api/v2/auth/CommonTlsContext'; -import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; - -export interface UpstreamTlsContext { - /** - * Common TLS context settings. - * - * .. attention:: - * - * Server certificate verification is not enabled by default. Configure - * :ref:`trusted_ca` to enable - * verification. - */ - 'common_tls_context'?: (_envoy_api_v2_auth_CommonTlsContext); - /** - * SNI string to use when creating TLS backend connections. - */ - 'sni'?: (string); - /** - * If true, server-initiated TLS renegotiation will be allowed. - * - * .. attention:: - * - * TLS renegotiation is considered insecure and shouldn't be used unless absolutely necessary. - */ - 'allow_renegotiation'?: (boolean); - /** - * Maximum number of session keys (Pre-Shared Keys for TLSv1.3+, Session IDs and Session Tickets - * for TLSv1.2 and older) to store for the purpose of session resumption. - * - * Defaults to 1, setting this to 0 disables session resumption. - */ - 'max_session_keys'?: (_google_protobuf_UInt32Value); -} - -export interface UpstreamTlsContext__Output { - /** - * Common TLS context settings. - * - * .. attention:: - * - * Server certificate verification is not enabled by default. Configure - * :ref:`trusted_ca` to enable - * verification. - */ - 'common_tls_context'?: (_envoy_api_v2_auth_CommonTlsContext__Output); - /** - * SNI string to use when creating TLS backend connections. - */ - 'sni': (string); - /** - * If true, server-initiated TLS renegotiation will be allowed. - * - * .. attention:: - * - * TLS renegotiation is considered insecure and shouldn't be used unless absolutely necessary. - */ - 'allow_renegotiation': (boolean); - /** - * Maximum number of session keys (Pre-Shared Keys for TLSv1.3+, Session IDs and Session Tickets - * for TLSv1.2 and older) to store for the purpose of session resumption. - * - * Defaults to 1, setting this to 0 disables session resumption. - */ - 'max_session_keys'?: (_google_protobuf_UInt32Value__Output); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BuildVersion.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BuildVersion.ts index 009506fa2..50a44a3b2 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BuildVersion.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BuildVersion.ts @@ -14,7 +14,7 @@ export interface BuildVersion { 'version'?: (_envoy_type_SemanticVersion); /** * Free-form build information. - * Envoy defines several well known keys in the source/common/common/version.h file + * Envoy defines several well known keys in the source/common/version/version.h file */ 'metadata'?: (_google_protobuf_Struct); } @@ -30,7 +30,7 @@ export interface BuildVersion__Output { 'version'?: (_envoy_type_SemanticVersion__Output); /** * Free-form build information. - * Envoy defines several well known keys in the source/common/common/version.h file + * Envoy defines several well known keys in the source/common/version/version.h file */ 'metadata'?: (_google_protobuf_Struct__Output); } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/GrpcProtocolOptions.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/GrpcProtocolOptions.ts deleted file mode 100644 index 66723801e..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/GrpcProtocolOptions.ts +++ /dev/null @@ -1,17 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/protocol.proto - -import type { Http2ProtocolOptions as _envoy_api_v2_core_Http2ProtocolOptions, Http2ProtocolOptions__Output as _envoy_api_v2_core_Http2ProtocolOptions__Output } from '../../../../envoy/api/v2/core/Http2ProtocolOptions'; - -/** - * [#not-implemented-hide:] - */ -export interface GrpcProtocolOptions { - 'http2_protocol_options'?: (_envoy_api_v2_core_Http2ProtocolOptions); -} - -/** - * [#not-implemented-hide:] - */ -export interface GrpcProtocolOptions__Output { - 'http2_protocol_options'?: (_envoy_api_v2_core_Http2ProtocolOptions__Output); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeDouble.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeDouble.ts index 8d9aba3e0..1ea2b8146 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeDouble.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeDouble.ts @@ -22,7 +22,7 @@ export interface RuntimeDouble__Output { /** * Default value if runtime value is not available. */ - 'default_value': (number | string); + 'default_value': (number); /** * Runtime key to get value for comparison. This value is used if defined. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/SelfConfigSource.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/SelfConfigSource.ts deleted file mode 100644 index 144cfdf5a..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/SelfConfigSource.ts +++ /dev/null @@ -1,20 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/config_source.proto - - -/** - * [#not-implemented-hide:] - * Self-referencing config source options. This is currently empty, but when - * set in :ref:`ConfigSource ` can be used to - * specify that other data can be obtained from the same server. - */ -export interface SelfConfigSource { -} - -/** - * [#not-implemented-hide:] - * Self-referencing config source options. This is currently empty, but when - * set in :ref:`ConfigSource ` can be used to - * specify that other data can be obtained from the same server. - */ -export interface SelfConfigSource__Output { -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/EndpointLoadMetricStats.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/EndpointLoadMetricStats.ts index 9ed8016b7..335b759b6 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/EndpointLoadMetricStats.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/EndpointLoadMetricStats.ts @@ -37,5 +37,5 @@ export interface EndpointLoadMetricStats__Output { * Sum of metric values across all calls that finished with this metric for * load_reporting_interval. */ - 'total_metric_value': (number | string); + 'total_metric_value': (number); } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/listener/Filter.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/listener/Filter.ts deleted file mode 100644 index 2c6e0d087..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/listener/Filter.ts +++ /dev/null @@ -1,34 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/listener/listener_components.proto - -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; -import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; - -export interface Filter { - /** - * The name of the filter to instantiate. The name must match a - * :ref:`supported filter `. - */ - 'name'?: (string); - 'config'?: (_google_protobuf_Struct); - 'typed_config'?: (_google_protobuf_Any); - /** - * Filter specific configuration which depends on the filter being - * instantiated. See the supported filters for further documentation. - */ - 'config_type'?: "config"|"typed_config"; -} - -export interface Filter__Output { - /** - * The name of the filter to instantiate. The name must match a - * :ref:`supported filter `. - */ - 'name': (string); - 'config'?: (_google_protobuf_Struct__Output); - 'typed_config'?: (_google_protobuf_Any__Output); - /** - * Filter specific configuration which depends on the filter being - * instantiated. See the supported filters for further documentation. - */ - 'config_type': "config"|"typed_config"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/listener/FilterChain.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/listener/FilterChain.ts deleted file mode 100644 index 1e98abe50..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/listener/FilterChain.ts +++ /dev/null @@ -1,118 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/listener/listener_components.proto - -import type { FilterChainMatch as _envoy_api_v2_listener_FilterChainMatch, FilterChainMatch__Output as _envoy_api_v2_listener_FilterChainMatch__Output } from '../../../../envoy/api/v2/listener/FilterChainMatch'; -import type { DownstreamTlsContext as _envoy_api_v2_auth_DownstreamTlsContext, DownstreamTlsContext__Output as _envoy_api_v2_auth_DownstreamTlsContext__Output } from '../../../../envoy/api/v2/auth/DownstreamTlsContext'; -import type { Filter as _envoy_api_v2_listener_Filter, Filter__Output as _envoy_api_v2_listener_Filter__Output } from '../../../../envoy/api/v2/listener/Filter'; -import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; -import type { Metadata as _envoy_api_v2_core_Metadata, Metadata__Output as _envoy_api_v2_core_Metadata__Output } from '../../../../envoy/api/v2/core/Metadata'; -import type { TransportSocket as _envoy_api_v2_core_TransportSocket, TransportSocket__Output as _envoy_api_v2_core_TransportSocket__Output } from '../../../../envoy/api/v2/core/TransportSocket'; - -/** - * A filter chain wraps a set of match criteria, an option TLS context, a set of filters, and - * various other parameters. - * [#next-free-field: 8] - */ -export interface FilterChain { - /** - * The criteria to use when matching a connection to this filter chain. - */ - 'filter_chain_match'?: (_envoy_api_v2_listener_FilterChainMatch); - /** - * The TLS context for this filter chain. - * - * .. attention:: - * - * **This field is deprecated**. Use `transport_socket` with name `tls` instead. If both are - * set, `transport_socket` takes priority. - */ - 'tls_context'?: (_envoy_api_v2_auth_DownstreamTlsContext); - /** - * A list of individual network filters that make up the filter chain for - * connections established with the listener. Order matters as the filters are - * processed sequentially as connection events happen. Note: If the filter - * list is empty, the connection will close by default. - */ - 'filters'?: (_envoy_api_v2_listener_Filter)[]; - /** - * Whether the listener should expect a PROXY protocol V1 header on new - * connections. If this option is enabled, the listener will assume that that - * remote address of the connection is the one specified in the header. Some - * load balancers including the AWS ELB support this option. If the option is - * absent or set to false, Envoy will use the physical peer address of the - * connection as the remote address. - */ - 'use_proxy_proto'?: (_google_protobuf_BoolValue); - /** - * [#not-implemented-hide:] filter chain metadata. - */ - 'metadata'?: (_envoy_api_v2_core_Metadata); - /** - * Optional custom transport socket implementation to use for downstream connections. - * To setup TLS, set a transport socket with name `tls` and - * :ref:`DownstreamTlsContext ` in the `typed_config`. - * If no transport socket configuration is specified, new connections - * will be set up with plaintext. - */ - 'transport_socket'?: (_envoy_api_v2_core_TransportSocket); - /** - * [#not-implemented-hide:] The unique name (or empty) by which this filter chain is known. If no - * name is provided, Envoy will allocate an internal UUID for the filter chain. If the filter - * chain is to be dynamically updated or removed via FCDS a unique name must be provided. - */ - 'name'?: (string); -} - -/** - * A filter chain wraps a set of match criteria, an option TLS context, a set of filters, and - * various other parameters. - * [#next-free-field: 8] - */ -export interface FilterChain__Output { - /** - * The criteria to use when matching a connection to this filter chain. - */ - 'filter_chain_match'?: (_envoy_api_v2_listener_FilterChainMatch__Output); - /** - * The TLS context for this filter chain. - * - * .. attention:: - * - * **This field is deprecated**. Use `transport_socket` with name `tls` instead. If both are - * set, `transport_socket` takes priority. - */ - 'tls_context'?: (_envoy_api_v2_auth_DownstreamTlsContext__Output); - /** - * A list of individual network filters that make up the filter chain for - * connections established with the listener. Order matters as the filters are - * processed sequentially as connection events happen. Note: If the filter - * list is empty, the connection will close by default. - */ - 'filters': (_envoy_api_v2_listener_Filter__Output)[]; - /** - * Whether the listener should expect a PROXY protocol V1 header on new - * connections. If this option is enabled, the listener will assume that that - * remote address of the connection is the one specified in the header. Some - * load balancers including the AWS ELB support this option. If the option is - * absent or set to false, Envoy will use the physical peer address of the - * connection as the remote address. - */ - 'use_proxy_proto'?: (_google_protobuf_BoolValue__Output); - /** - * [#not-implemented-hide:] filter chain metadata. - */ - 'metadata'?: (_envoy_api_v2_core_Metadata__Output); - /** - * Optional custom transport socket implementation to use for downstream connections. - * To setup TLS, set a transport socket with name `tls` and - * :ref:`DownstreamTlsContext ` in the `typed_config`. - * If no transport socket configuration is specified, new connections - * will be set up with plaintext. - */ - 'transport_socket'?: (_envoy_api_v2_core_TransportSocket__Output); - /** - * [#not-implemented-hide:] The unique name (or empty) by which this filter chain is known. If no - * name is provided, Envoy will allocate an internal UUID for the filter chain. If the filter - * chain is to be dynamically updated or removed via FCDS a unique name must be provided. - */ - 'name': (string); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/HedgePolicy.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/route/HedgePolicy.ts deleted file mode 100644 index 8134fc359..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/HedgePolicy.ts +++ /dev/null @@ -1,66 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto - -import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; -import type { FractionalPercent as _envoy_type_FractionalPercent, FractionalPercent__Output as _envoy_type_FractionalPercent__Output } from '../../../../envoy/type/FractionalPercent'; - -/** - * HTTP request hedging :ref:`architecture overview `. - */ -export interface HedgePolicy { - /** - * Specifies the number of initial requests that should be sent upstream. - * Must be at least 1. - * Defaults to 1. - * [#not-implemented-hide:] - */ - 'initial_requests'?: (_google_protobuf_UInt32Value); - /** - * Specifies a probability that an additional upstream request should be sent - * on top of what is specified by initial_requests. - * Defaults to 0. - * [#not-implemented-hide:] - */ - 'additional_request_chance'?: (_envoy_type_FractionalPercent); - /** - * Indicates that a hedged request should be sent when the per-try timeout - * is hit. This will only occur if the retry policy also indicates that a - * timed out request should be retried. - * Once a timed out request is retried due to per try timeout, the router - * filter will ensure that it is not retried again even if the returned - * response headers would otherwise be retried according the specified - * :ref:`RetryPolicy `. - * Defaults to false. - */ - 'hedge_on_per_try_timeout'?: (boolean); -} - -/** - * HTTP request hedging :ref:`architecture overview `. - */ -export interface HedgePolicy__Output { - /** - * Specifies the number of initial requests that should be sent upstream. - * Must be at least 1. - * Defaults to 1. - * [#not-implemented-hide:] - */ - 'initial_requests'?: (_google_protobuf_UInt32Value__Output); - /** - * Specifies a probability that an additional upstream request should be sent - * on top of what is specified by initial_requests. - * Defaults to 0. - * [#not-implemented-hide:] - */ - 'additional_request_chance'?: (_envoy_type_FractionalPercent__Output); - /** - * Indicates that a hedged request should be sent when the per-try timeout - * is hit. This will only occur if the retry policy also indicates that a - * timed out request should be retried. - * Once a timed out request is retried due to per try timeout, the router - * filter will ensure that it is not retried again even if the returned - * response headers would otherwise be retried according the specified - * :ref:`RetryPolicy `. - * Defaults to false. - */ - 'hedge_on_per_try_timeout': (boolean); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/QueryParameterMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/route/QueryParameterMatcher.ts deleted file mode 100644 index 68f4fbcaa..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/QueryParameterMatcher.ts +++ /dev/null @@ -1,86 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto - -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_StringMatcher, StringMatcher__Output as _envoy_type_matcher_StringMatcher__Output } from '../../../../envoy/type/matcher/StringMatcher'; - -/** - * Query parameter matching treats the query string of a request's :path header - * as an ampersand-separated list of keys and/or key=value elements. - * [#next-free-field: 7] - */ -export interface QueryParameterMatcher { - /** - * Specifies the name of a key that must be present in the requested - * *path*'s query string. - */ - 'name'?: (string); - /** - * Specifies the value of the key. If the value is absent, a request - * that contains the key in its query string will match, whether the - * key appears with a value (e.g., "?debug=true") or not (e.g., "?debug") - * - * ..attention:: - * This field is deprecated. Use an `exact` match inside the `string_match` field. - */ - 'value'?: (string); - /** - * Specifies whether the query parameter value is a regular expression. - * Defaults to false. The entire query parameter value (i.e., the part to - * the right of the equals sign in "key=value") must match the regex. - * E.g., the regex ``\d+$`` will match *123* but not *a123* or *123a*. - * - * ..attention:: - * This field is deprecated. Use a `safe_regex` match inside the `string_match` field. - */ - 'regex'?: (_google_protobuf_BoolValue); - /** - * Specifies whether a query parameter value should match against a string. - */ - 'string_match'?: (_envoy_type_matcher_StringMatcher); - /** - * Specifies whether a query parameter should be present. - */ - 'present_match'?: (boolean); - 'query_parameter_match_specifier'?: "string_match"|"present_match"; -} - -/** - * Query parameter matching treats the query string of a request's :path header - * as an ampersand-separated list of keys and/or key=value elements. - * [#next-free-field: 7] - */ -export interface QueryParameterMatcher__Output { - /** - * Specifies the name of a key that must be present in the requested - * *path*'s query string. - */ - 'name': (string); - /** - * Specifies the value of the key. If the value is absent, a request - * that contains the key in its query string will match, whether the - * key appears with a value (e.g., "?debug=true") or not (e.g., "?debug") - * - * ..attention:: - * This field is deprecated. Use an `exact` match inside the `string_match` field. - */ - 'value': (string); - /** - * Specifies whether the query parameter value is a regular expression. - * Defaults to false. The entire query parameter value (i.e., the part to - * the right of the equals sign in "key=value") must match the regex. - * E.g., the regex ``\d+$`` will match *123* but not *a123* or *123a*. - * - * ..attention:: - * This field is deprecated. Use a `safe_regex` match inside the `string_match` field. - */ - 'regex'?: (_google_protobuf_BoolValue__Output); - /** - * Specifies whether a query parameter value should match against a string. - */ - 'string_match'?: (_envoy_type_matcher_StringMatcher__Output); - /** - * Specifies whether a query parameter should be present. - */ - 'present_match'?: (boolean); - 'query_parameter_match_specifier': "string_match"|"present_match"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/RateLimit.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/route/RateLimit.ts deleted file mode 100644 index 998d94e53..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/RateLimit.ts +++ /dev/null @@ -1,341 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto - -import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; -import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; -import type { HeaderMatcher as _envoy_api_v2_route_HeaderMatcher, HeaderMatcher__Output as _envoy_api_v2_route_HeaderMatcher__Output } from '../../../../envoy/api/v2/route/HeaderMatcher'; - -/** - * [#next-free-field: 7] - */ -export interface _envoy_api_v2_route_RateLimit_Action { - /** - * Rate limit on source cluster. - */ - 'source_cluster'?: (_envoy_api_v2_route_RateLimit_Action_SourceCluster); - /** - * Rate limit on destination cluster. - */ - 'destination_cluster'?: (_envoy_api_v2_route_RateLimit_Action_DestinationCluster); - /** - * Rate limit on request headers. - */ - 'request_headers'?: (_envoy_api_v2_route_RateLimit_Action_RequestHeaders); - /** - * Rate limit on remote address. - */ - 'remote_address'?: (_envoy_api_v2_route_RateLimit_Action_RemoteAddress); - /** - * Rate limit on a generic key. - */ - 'generic_key'?: (_envoy_api_v2_route_RateLimit_Action_GenericKey); - /** - * Rate limit on the existence of request headers. - */ - 'header_value_match'?: (_envoy_api_v2_route_RateLimit_Action_HeaderValueMatch); - 'action_specifier'?: "source_cluster"|"destination_cluster"|"request_headers"|"remote_address"|"generic_key"|"header_value_match"; -} - -/** - * [#next-free-field: 7] - */ -export interface _envoy_api_v2_route_RateLimit_Action__Output { - /** - * Rate limit on source cluster. - */ - 'source_cluster'?: (_envoy_api_v2_route_RateLimit_Action_SourceCluster__Output); - /** - * Rate limit on destination cluster. - */ - 'destination_cluster'?: (_envoy_api_v2_route_RateLimit_Action_DestinationCluster__Output); - /** - * Rate limit on request headers. - */ - 'request_headers'?: (_envoy_api_v2_route_RateLimit_Action_RequestHeaders__Output); - /** - * Rate limit on remote address. - */ - 'remote_address'?: (_envoy_api_v2_route_RateLimit_Action_RemoteAddress__Output); - /** - * Rate limit on a generic key. - */ - 'generic_key'?: (_envoy_api_v2_route_RateLimit_Action_GenericKey__Output); - /** - * Rate limit on the existence of request headers. - */ - 'header_value_match'?: (_envoy_api_v2_route_RateLimit_Action_HeaderValueMatch__Output); - 'action_specifier': "source_cluster"|"destination_cluster"|"request_headers"|"remote_address"|"generic_key"|"header_value_match"; -} - -/** - * The following descriptor entry is appended to the descriptor: - * - * .. code-block:: cpp - * - * ("destination_cluster", "") - * - * Once a request matches against a route table rule, a routed cluster is determined by one of - * the following :ref:`route table configuration ` - * settings: - * - * * :ref:`cluster ` indicates the upstream cluster - * to route to. - * * :ref:`weighted_clusters ` - * chooses a cluster randomly from a set of clusters with attributed weight. - * * :ref:`cluster_header ` indicates which - * header in the request contains the target cluster. - */ -export interface _envoy_api_v2_route_RateLimit_Action_DestinationCluster { -} - -/** - * The following descriptor entry is appended to the descriptor: - * - * .. code-block:: cpp - * - * ("destination_cluster", "") - * - * Once a request matches against a route table rule, a routed cluster is determined by one of - * the following :ref:`route table configuration ` - * settings: - * - * * :ref:`cluster ` indicates the upstream cluster - * to route to. - * * :ref:`weighted_clusters ` - * chooses a cluster randomly from a set of clusters with attributed weight. - * * :ref:`cluster_header ` indicates which - * header in the request contains the target cluster. - */ -export interface _envoy_api_v2_route_RateLimit_Action_DestinationCluster__Output { -} - -/** - * The following descriptor entry is appended to the descriptor: - * - * .. code-block:: cpp - * - * ("generic_key", "") - */ -export interface _envoy_api_v2_route_RateLimit_Action_GenericKey { - /** - * The value to use in the descriptor entry. - */ - 'descriptor_value'?: (string); -} - -/** - * The following descriptor entry is appended to the descriptor: - * - * .. code-block:: cpp - * - * ("generic_key", "") - */ -export interface _envoy_api_v2_route_RateLimit_Action_GenericKey__Output { - /** - * The value to use in the descriptor entry. - */ - 'descriptor_value': (string); -} - -/** - * The following descriptor entry is appended to the descriptor: - * - * .. code-block:: cpp - * - * ("header_match", "") - */ -export interface _envoy_api_v2_route_RateLimit_Action_HeaderValueMatch { - /** - * The value to use in the descriptor entry. - */ - 'descriptor_value'?: (string); - /** - * If set to true, the action will append a descriptor entry when the - * request matches the headers. If set to false, the action will append a - * descriptor entry when the request does not match the headers. The - * default value is true. - */ - 'expect_match'?: (_google_protobuf_BoolValue); - /** - * Specifies a set of headers that the rate limit action should match - * on. The action will check the request’s headers against all the - * specified headers in the config. A match will happen if all the - * headers in the config are present in the request with the same values - * (or based on presence if the value field is not in the config). - */ - 'headers'?: (_envoy_api_v2_route_HeaderMatcher)[]; -} - -/** - * The following descriptor entry is appended to the descriptor: - * - * .. code-block:: cpp - * - * ("header_match", "") - */ -export interface _envoy_api_v2_route_RateLimit_Action_HeaderValueMatch__Output { - /** - * The value to use in the descriptor entry. - */ - 'descriptor_value': (string); - /** - * If set to true, the action will append a descriptor entry when the - * request matches the headers. If set to false, the action will append a - * descriptor entry when the request does not match the headers. The - * default value is true. - */ - 'expect_match'?: (_google_protobuf_BoolValue__Output); - /** - * Specifies a set of headers that the rate limit action should match - * on. The action will check the request’s headers against all the - * specified headers in the config. A match will happen if all the - * headers in the config are present in the request with the same values - * (or based on presence if the value field is not in the config). - */ - 'headers': (_envoy_api_v2_route_HeaderMatcher__Output)[]; -} - -/** - * The following descriptor entry is appended to the descriptor and is populated using the - * trusted address from :ref:`x-forwarded-for `: - * - * .. code-block:: cpp - * - * ("remote_address", "") - */ -export interface _envoy_api_v2_route_RateLimit_Action_RemoteAddress { -} - -/** - * The following descriptor entry is appended to the descriptor and is populated using the - * trusted address from :ref:`x-forwarded-for `: - * - * .. code-block:: cpp - * - * ("remote_address", "") - */ -export interface _envoy_api_v2_route_RateLimit_Action_RemoteAddress__Output { -} - -/** - * The following descriptor entry is appended when a header contains a key that matches the - * *header_name*: - * - * .. code-block:: cpp - * - * ("", "") - */ -export interface _envoy_api_v2_route_RateLimit_Action_RequestHeaders { - /** - * The header name to be queried from the request headers. The header’s - * value is used to populate the value of the descriptor entry for the - * descriptor_key. - */ - 'header_name'?: (string); - /** - * The key to use in the descriptor entry. - */ - 'descriptor_key'?: (string); -} - -/** - * The following descriptor entry is appended when a header contains a key that matches the - * *header_name*: - * - * .. code-block:: cpp - * - * ("", "") - */ -export interface _envoy_api_v2_route_RateLimit_Action_RequestHeaders__Output { - /** - * The header name to be queried from the request headers. The header’s - * value is used to populate the value of the descriptor entry for the - * descriptor_key. - */ - 'header_name': (string); - /** - * The key to use in the descriptor entry. - */ - 'descriptor_key': (string); -} - -/** - * The following descriptor entry is appended to the descriptor: - * - * .. code-block:: cpp - * - * ("source_cluster", "") - * - * is derived from the :option:`--service-cluster` option. - */ -export interface _envoy_api_v2_route_RateLimit_Action_SourceCluster { -} - -/** - * The following descriptor entry is appended to the descriptor: - * - * .. code-block:: cpp - * - * ("source_cluster", "") - * - * is derived from the :option:`--service-cluster` option. - */ -export interface _envoy_api_v2_route_RateLimit_Action_SourceCluster__Output { -} - -/** - * Global rate limiting :ref:`architecture overview `. - */ -export interface RateLimit { - /** - * Refers to the stage set in the filter. The rate limit configuration only - * applies to filters with the same stage number. The default stage number is - * 0. - * - * .. note:: - * - * The filter supports a range of 0 - 10 inclusively for stage numbers. - */ - 'stage'?: (_google_protobuf_UInt32Value); - /** - * The key to be set in runtime to disable this rate limit configuration. - */ - 'disable_key'?: (string); - /** - * A list of actions that are to be applied for this rate limit configuration. - * Order matters as the actions are processed sequentially and the descriptor - * is composed by appending descriptor entries in that sequence. If an action - * cannot append a descriptor entry, no descriptor is generated for the - * configuration. See :ref:`composing actions - * ` for additional documentation. - */ - 'actions'?: (_envoy_api_v2_route_RateLimit_Action)[]; -} - -/** - * Global rate limiting :ref:`architecture overview `. - */ -export interface RateLimit__Output { - /** - * Refers to the stage set in the filter. The rate limit configuration only - * applies to filters with the same stage number. The default stage number is - * 0. - * - * .. note:: - * - * The filter supports a range of 0 - 10 inclusively for stage numbers. - */ - 'stage'?: (_google_protobuf_UInt32Value__Output); - /** - * The key to be set in runtime to disable this rate limit configuration. - */ - 'disable_key': (string); - /** - * A list of actions that are to be applied for this rate limit configuration. - * Order matters as the actions are processed sequentially and the descriptor - * is composed by appending descriptor entries in that sequence. If an action - * cannot append a descriptor entry, no descriptor is generated for the - * configuration. See :ref:`composing actions - * ` for additional documentation. - */ - 'actions': (_envoy_api_v2_route_RateLimit_Action__Output)[]; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/RedirectAction.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/route/RedirectAction.ts deleted file mode 100644 index de7105a54..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/RedirectAction.ts +++ /dev/null @@ -1,139 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto - - -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto - -export enum _envoy_api_v2_route_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, -} - -/** - * [#next-free-field: 9] - */ -export interface RedirectAction { - /** - * The host portion of the URL will be swapped with this value. - */ - 'host_redirect'?: (string); - /** - * The path portion of the URL will be swapped with this value. - */ - 'path_redirect'?: (string); - /** - * The HTTP status code to use in the redirect response. The default response - * code is MOVED_PERMANENTLY (301). - */ - 'response_code'?: (_envoy_api_v2_route_RedirectAction_RedirectResponseCode | keyof typeof _envoy_api_v2_route_RedirectAction_RedirectResponseCode); - /** - * The scheme portion of the URL will be swapped with "https". - */ - 'https_redirect'?: (boolean); - /** - * Indicates that during redirection, the matched prefix (or path) - * should be swapped with this value. This option allows redirect URLs be dynamically created - * based on the request. - * - * .. attention:: - * - * Pay attention to the use of trailing slashes as mentioned in - * :ref:`RouteAction's prefix_rewrite `. - */ - 'prefix_rewrite'?: (string); - /** - * Indicates that during redirection, the query portion of the URL will - * be removed. Default value is false. - */ - 'strip_query'?: (boolean); - /** - * The scheme portion of the URL will be swapped with this value. - */ - 'scheme_redirect'?: (string); - /** - * The port value of the URL will be swapped with this value. - */ - 'port_redirect'?: (number); - /** - * When the scheme redirection take place, the following rules apply: - * 1. If the source URI scheme is `http` and the port is explicitly - * set to `:80`, the port will be removed after the redirection - * 2. If the source URI scheme is `https` and the port is explicitly - * set to `:443`, the port will be removed after the redirection - */ - 'scheme_rewrite_specifier'?: "https_redirect"|"scheme_redirect"; - 'path_rewrite_specifier'?: "path_redirect"|"prefix_rewrite"; -} - -/** - * [#next-free-field: 9] - */ -export interface RedirectAction__Output { - /** - * The host portion of the URL will be swapped with this value. - */ - 'host_redirect': (string); - /** - * The path portion of the URL will be swapped with this value. - */ - 'path_redirect'?: (string); - /** - * The HTTP status code to use in the redirect response. The default response - * code is MOVED_PERMANENTLY (301). - */ - 'response_code': (keyof typeof _envoy_api_v2_route_RedirectAction_RedirectResponseCode); - /** - * The scheme portion of the URL will be swapped with "https". - */ - 'https_redirect'?: (boolean); - /** - * Indicates that during redirection, the matched prefix (or path) - * should be swapped with this value. This option allows redirect URLs be dynamically created - * based on the request. - * - * .. attention:: - * - * Pay attention to the use of trailing slashes as mentioned in - * :ref:`RouteAction's prefix_rewrite `. - */ - 'prefix_rewrite'?: (string); - /** - * Indicates that during redirection, the query portion of the URL will - * be removed. Default value is false. - */ - 'strip_query': (boolean); - /** - * The scheme portion of the URL will be swapped with this value. - */ - 'scheme_redirect'?: (string); - /** - * The port value of the URL will be swapped with this value. - */ - 'port_redirect': (number); - /** - * When the scheme redirection take place, the following rules apply: - * 1. If the source URI scheme is `http` and the port is explicitly - * set to `:80`, the port will be removed after the redirection - * 2. If the source URI scheme is `https` and the port is explicitly - * set to `:443`, the port will be removed after the redirection - */ - 'scheme_rewrite_specifier': "https_redirect"|"scheme_redirect"; - 'path_rewrite_specifier': "path_redirect"|"prefix_rewrite"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/RetryPolicy.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/route/RetryPolicy.ts deleted file mode 100644 index 63b7deb5a..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/RetryPolicy.ts +++ /dev/null @@ -1,218 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto - -import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; -import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; -import type { HeaderMatcher as _envoy_api_v2_route_HeaderMatcher, HeaderMatcher__Output as _envoy_api_v2_route_HeaderMatcher__Output } from '../../../../envoy/api/v2/route/HeaderMatcher'; -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; -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'; - -export interface _envoy_api_v2_route_RetryPolicy_RetryBackOff { - /** - * Specifies the base interval between retries. This parameter is required and must be greater - * than zero. Values less than 1 ms are rounded up to 1 ms. - * See :ref:`config_http_filters_router_x-envoy-max-retries` for a discussion of Envoy's - * back-off algorithm. - */ - 'base_interval'?: (_google_protobuf_Duration); - /** - * Specifies the maximum interval between retries. This parameter is optional, but must be - * greater than or equal to the `base_interval` if set. The default is 10 times the - * `base_interval`. See :ref:`config_http_filters_router_x-envoy-max-retries` for a discussion - * of Envoy's back-off algorithm. - */ - 'max_interval'?: (_google_protobuf_Duration); -} - -export interface _envoy_api_v2_route_RetryPolicy_RetryBackOff__Output { - /** - * Specifies the base interval between retries. This parameter is required and must be greater - * than zero. Values less than 1 ms are rounded up to 1 ms. - * See :ref:`config_http_filters_router_x-envoy-max-retries` for a discussion of Envoy's - * back-off algorithm. - */ - 'base_interval'?: (_google_protobuf_Duration__Output); - /** - * Specifies the maximum interval between retries. This parameter is optional, but must be - * greater than or equal to the `base_interval` if set. The default is 10 times the - * `base_interval`. See :ref:`config_http_filters_router_x-envoy-max-retries` for a discussion - * of Envoy's back-off algorithm. - */ - 'max_interval'?: (_google_protobuf_Duration__Output); -} - -export interface _envoy_api_v2_route_RetryPolicy_RetryHostPredicate { - 'name'?: (string); - 'config'?: (_google_protobuf_Struct); - 'typed_config'?: (_google_protobuf_Any); - 'config_type'?: "config"|"typed_config"; -} - -export interface _envoy_api_v2_route_RetryPolicy_RetryHostPredicate__Output { - 'name': (string); - 'config'?: (_google_protobuf_Struct__Output); - 'typed_config'?: (_google_protobuf_Any__Output); - 'config_type': "config"|"typed_config"; -} - -export interface _envoy_api_v2_route_RetryPolicy_RetryPriority { - 'name'?: (string); - 'config'?: (_google_protobuf_Struct); - 'typed_config'?: (_google_protobuf_Any); - 'config_type'?: "config"|"typed_config"; -} - -export interface _envoy_api_v2_route_RetryPolicy_RetryPriority__Output { - 'name': (string); - 'config'?: (_google_protobuf_Struct__Output); - 'typed_config'?: (_google_protobuf_Any__Output); - 'config_type': "config"|"typed_config"; -} - -/** - * HTTP retry :ref:`architecture overview `. - * [#next-free-field: 11] - */ -export interface RetryPolicy { - /** - * Specifies the conditions under which retry takes place. These are the same - * conditions documented for :ref:`config_http_filters_router_x-envoy-retry-on` and - * :ref:`config_http_filters_router_x-envoy-retry-grpc-on`. - */ - 'retry_on'?: (string); - /** - * Specifies the allowed number of retries. This parameter is optional and - * defaults to 1. These are the same conditions documented for - * :ref:`config_http_filters_router_x-envoy-max-retries`. - */ - 'num_retries'?: (_google_protobuf_UInt32Value); - /** - * Specifies a non-zero upstream timeout per retry attempt. This parameter is optional. The - * same conditions documented for - * :ref:`config_http_filters_router_x-envoy-upstream-rq-per-try-timeout-ms` apply. - * - * .. note:: - * - * If left unspecified, Envoy will use the global - * :ref:`route timeout ` for the request. - * Consequently, when using a :ref:`5xx ` based - * retry policy, a request that times out will not be retried as the total timeout budget - * would have been exhausted. - */ - 'per_try_timeout'?: (_google_protobuf_Duration); - /** - * Specifies an implementation of a RetryPriority which is used to determine the - * distribution of load across priorities used for retries. Refer to - * :ref:`retry plugin configuration ` for more details. - */ - 'retry_priority'?: (_envoy_api_v2_route_RetryPolicy_RetryPriority); - /** - * Specifies a collection of RetryHostPredicates that will be consulted when selecting a host - * for retries. If any of the predicates reject the host, host selection will be reattempted. - * Refer to :ref:`retry plugin configuration ` for more - * details. - */ - 'retry_host_predicate'?: (_envoy_api_v2_route_RetryPolicy_RetryHostPredicate)[]; - /** - * The maximum number of times host selection will be reattempted before giving up, at which - * point the host that was last selected will be routed to. If unspecified, this will default to - * retrying once. - */ - 'host_selection_retry_max_attempts'?: (number | string | Long); - /** - * HTTP status codes that should trigger a retry in addition to those specified by retry_on. - */ - 'retriable_status_codes'?: (number)[]; - /** - * Specifies parameters that control retry back off. This parameter is optional, in which case the - * default base interval is 25 milliseconds or, if set, the current value of the - * `upstream.base_retry_backoff_ms` runtime parameter. The default maximum interval is 10 times - * the base interval. The documentation for :ref:`config_http_filters_router_x-envoy-max-retries` - * describes Envoy's back-off algorithm. - */ - 'retry_back_off'?: (_envoy_api_v2_route_RetryPolicy_RetryBackOff); - /** - * HTTP response headers that trigger a retry if present in the response. A retry will be - * triggered if any of the header matches match the upstream response headers. - * The field is only consulted if 'retriable-headers' retry policy is active. - */ - 'retriable_headers'?: (_envoy_api_v2_route_HeaderMatcher)[]; - /** - * HTTP headers which must be present in the request for retries to be attempted. - */ - 'retriable_request_headers'?: (_envoy_api_v2_route_HeaderMatcher)[]; -} - -/** - * HTTP retry :ref:`architecture overview `. - * [#next-free-field: 11] - */ -export interface RetryPolicy__Output { - /** - * Specifies the conditions under which retry takes place. These are the same - * conditions documented for :ref:`config_http_filters_router_x-envoy-retry-on` and - * :ref:`config_http_filters_router_x-envoy-retry-grpc-on`. - */ - 'retry_on': (string); - /** - * Specifies the allowed number of retries. This parameter is optional and - * defaults to 1. These are the same conditions documented for - * :ref:`config_http_filters_router_x-envoy-max-retries`. - */ - 'num_retries'?: (_google_protobuf_UInt32Value__Output); - /** - * Specifies a non-zero upstream timeout per retry attempt. This parameter is optional. The - * same conditions documented for - * :ref:`config_http_filters_router_x-envoy-upstream-rq-per-try-timeout-ms` apply. - * - * .. note:: - * - * If left unspecified, Envoy will use the global - * :ref:`route timeout ` for the request. - * Consequently, when using a :ref:`5xx ` based - * retry policy, a request that times out will not be retried as the total timeout budget - * would have been exhausted. - */ - 'per_try_timeout'?: (_google_protobuf_Duration__Output); - /** - * Specifies an implementation of a RetryPriority which is used to determine the - * distribution of load across priorities used for retries. Refer to - * :ref:`retry plugin configuration ` for more details. - */ - 'retry_priority'?: (_envoy_api_v2_route_RetryPolicy_RetryPriority__Output); - /** - * Specifies a collection of RetryHostPredicates that will be consulted when selecting a host - * for retries. If any of the predicates reject the host, host selection will be reattempted. - * Refer to :ref:`retry plugin configuration ` for more - * details. - */ - 'retry_host_predicate': (_envoy_api_v2_route_RetryPolicy_RetryHostPredicate__Output)[]; - /** - * The maximum number of times host selection will be reattempted before giving up, at which - * point the host that was last selected will be routed to. If unspecified, this will default to - * retrying once. - */ - 'host_selection_retry_max_attempts': (string); - /** - * HTTP status codes that should trigger a retry in addition to those specified by retry_on. - */ - 'retriable_status_codes': (number)[]; - /** - * Specifies parameters that control retry back off. This parameter is optional, in which case the - * default base interval is 25 milliseconds or, if set, the current value of the - * `upstream.base_retry_backoff_ms` runtime parameter. The default maximum interval is 10 times - * the base interval. The documentation for :ref:`config_http_filters_router_x-envoy-max-retries` - * describes Envoy's back-off algorithm. - */ - 'retry_back_off'?: (_envoy_api_v2_route_RetryPolicy_RetryBackOff__Output); - /** - * HTTP response headers that trigger a retry if present in the response. A retry will be - * triggered if any of the header matches match the upstream response headers. - * The field is only consulted if 'retriable-headers' retry policy is active. - */ - 'retriable_headers': (_envoy_api_v2_route_HeaderMatcher__Output)[]; - /** - * HTTP headers which must be present in the request for retries to be attempted. - */ - 'retriable_request_headers': (_envoy_api_v2_route_HeaderMatcher__Output)[]; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/AccessLog.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AccessLog.ts similarity index 54% rename from packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/AccessLog.ts rename to packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AccessLog.ts index 82e056a4b..413f569ce 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/AccessLog.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AccessLog.ts @@ -1,8 +1,7 @@ -// Original file: deps/envoy-api/envoy/config/filter/accesslog/v2/accesslog.proto +// Original file: deps/envoy-api/envoy/config/accesslog/v3/accesslog.proto -import type { AccessLogFilter as _envoy_config_filter_accesslog_v2_AccessLogFilter, AccessLogFilter__Output as _envoy_config_filter_accesslog_v2_AccessLogFilter__Output } from '../../../../../envoy/config/filter/accesslog/v2/AccessLogFilter'; -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../../google/protobuf/Struct'; -import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../../google/protobuf/Any'; +import type { AccessLogFilter as _envoy_config_accesslog_v3_AccessLogFilter, AccessLogFilter__Output as _envoy_config_accesslog_v3_AccessLogFilter__Output } from '../../../../envoy/config/accesslog/v3/AccessLogFilter'; +import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; export interface AccessLog { /** @@ -17,21 +16,20 @@ export interface AccessLog { /** * Filter which is used to determine if the access log needs to be written. */ - 'filter'?: (_envoy_config_filter_accesslog_v2_AccessLogFilter); - 'config'?: (_google_protobuf_Struct); + 'filter'?: (_envoy_config_accesslog_v3_AccessLogFilter); 'typed_config'?: (_google_protobuf_Any); /** - * Custom configuration that depends on the access log being instantiated. Built-in - * configurations include: + * Custom configuration that depends on the access log being instantiated. + * Built-in configurations include: * * #. "envoy.access_loggers.file": :ref:`FileAccessLog - * ` + * ` * #. "envoy.access_loggers.http_grpc": :ref:`HttpGrpcAccessLogConfig - * ` + * ` * #. "envoy.access_loggers.tcp_grpc": :ref:`TcpGrpcAccessLogConfig - * ` + * ` */ - 'config_type'?: "config"|"typed_config"; + 'config_type'?: "typed_config"; } export interface AccessLog__Output { @@ -47,19 +45,18 @@ export interface AccessLog__Output { /** * Filter which is used to determine if the access log needs to be written. */ - 'filter'?: (_envoy_config_filter_accesslog_v2_AccessLogFilter__Output); - 'config'?: (_google_protobuf_Struct__Output); + 'filter'?: (_envoy_config_accesslog_v3_AccessLogFilter__Output); 'typed_config'?: (_google_protobuf_Any__Output); /** - * Custom configuration that depends on the access log being instantiated. Built-in - * configurations include: + * Custom configuration that depends on the access log being instantiated. + * Built-in configurations include: * * #. "envoy.access_loggers.file": :ref:`FileAccessLog - * ` + * ` * #. "envoy.access_loggers.http_grpc": :ref:`HttpGrpcAccessLogConfig - * ` + * ` * #. "envoy.access_loggers.tcp_grpc": :ref:`TcpGrpcAccessLogConfig - * ` + * ` */ - 'config_type': "config"|"typed_config"; + 'config_type': "typed_config"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AccessLogFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AccessLogFilter.ts new file mode 100644 index 000000000..9470b6eaa --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AccessLogFilter.ts @@ -0,0 +1,124 @@ +// Original file: deps/envoy-api/envoy/config/accesslog/v3/accesslog.proto + +import type { StatusCodeFilter as _envoy_config_accesslog_v3_StatusCodeFilter, StatusCodeFilter__Output as _envoy_config_accesslog_v3_StatusCodeFilter__Output } from '../../../../envoy/config/accesslog/v3/StatusCodeFilter'; +import type { DurationFilter as _envoy_config_accesslog_v3_DurationFilter, DurationFilter__Output as _envoy_config_accesslog_v3_DurationFilter__Output } from '../../../../envoy/config/accesslog/v3/DurationFilter'; +import type { NotHealthCheckFilter as _envoy_config_accesslog_v3_NotHealthCheckFilter, NotHealthCheckFilter__Output as _envoy_config_accesslog_v3_NotHealthCheckFilter__Output } from '../../../../envoy/config/accesslog/v3/NotHealthCheckFilter'; +import type { TraceableFilter as _envoy_config_accesslog_v3_TraceableFilter, TraceableFilter__Output as _envoy_config_accesslog_v3_TraceableFilter__Output } from '../../../../envoy/config/accesslog/v3/TraceableFilter'; +import type { RuntimeFilter as _envoy_config_accesslog_v3_RuntimeFilter, RuntimeFilter__Output as _envoy_config_accesslog_v3_RuntimeFilter__Output } from '../../../../envoy/config/accesslog/v3/RuntimeFilter'; +import type { AndFilter as _envoy_config_accesslog_v3_AndFilter, AndFilter__Output as _envoy_config_accesslog_v3_AndFilter__Output } from '../../../../envoy/config/accesslog/v3/AndFilter'; +import type { OrFilter as _envoy_config_accesslog_v3_OrFilter, OrFilter__Output as _envoy_config_accesslog_v3_OrFilter__Output } from '../../../../envoy/config/accesslog/v3/OrFilter'; +import type { HeaderFilter as _envoy_config_accesslog_v3_HeaderFilter, HeaderFilter__Output as _envoy_config_accesslog_v3_HeaderFilter__Output } from '../../../../envoy/config/accesslog/v3/HeaderFilter'; +import type { ResponseFlagFilter as _envoy_config_accesslog_v3_ResponseFlagFilter, ResponseFlagFilter__Output as _envoy_config_accesslog_v3_ResponseFlagFilter__Output } from '../../../../envoy/config/accesslog/v3/ResponseFlagFilter'; +import type { GrpcStatusFilter as _envoy_config_accesslog_v3_GrpcStatusFilter, GrpcStatusFilter__Output as _envoy_config_accesslog_v3_GrpcStatusFilter__Output } from '../../../../envoy/config/accesslog/v3/GrpcStatusFilter'; +import type { ExtensionFilter as _envoy_config_accesslog_v3_ExtensionFilter, ExtensionFilter__Output as _envoy_config_accesslog_v3_ExtensionFilter__Output } from '../../../../envoy/config/accesslog/v3/ExtensionFilter'; +import type { MetadataFilter as _envoy_config_accesslog_v3_MetadataFilter, MetadataFilter__Output as _envoy_config_accesslog_v3_MetadataFilter__Output } from '../../../../envoy/config/accesslog/v3/MetadataFilter'; + +/** + * [#next-free-field: 13] + */ +export interface AccessLogFilter { + /** + * Status code filter. + */ + 'status_code_filter'?: (_envoy_config_accesslog_v3_StatusCodeFilter); + /** + * Duration filter. + */ + 'duration_filter'?: (_envoy_config_accesslog_v3_DurationFilter); + /** + * Not health check filter. + */ + 'not_health_check_filter'?: (_envoy_config_accesslog_v3_NotHealthCheckFilter); + /** + * Traceable filter. + */ + 'traceable_filter'?: (_envoy_config_accesslog_v3_TraceableFilter); + /** + * Runtime filter. + */ + 'runtime_filter'?: (_envoy_config_accesslog_v3_RuntimeFilter); + /** + * And filter. + */ + 'and_filter'?: (_envoy_config_accesslog_v3_AndFilter); + /** + * Or filter. + */ + 'or_filter'?: (_envoy_config_accesslog_v3_OrFilter); + /** + * Header filter. + */ + 'header_filter'?: (_envoy_config_accesslog_v3_HeaderFilter); + /** + * Response flag filter. + */ + 'response_flag_filter'?: (_envoy_config_accesslog_v3_ResponseFlagFilter); + /** + * gRPC status filter. + */ + 'grpc_status_filter'?: (_envoy_config_accesslog_v3_GrpcStatusFilter); + /** + * Extension filter. + */ + 'extension_filter'?: (_envoy_config_accesslog_v3_ExtensionFilter); + /** + * Metadata Filter + */ + 'metadata_filter'?: (_envoy_config_accesslog_v3_MetadataFilter); + 'filter_specifier'?: "status_code_filter"|"duration_filter"|"not_health_check_filter"|"traceable_filter"|"runtime_filter"|"and_filter"|"or_filter"|"header_filter"|"response_flag_filter"|"grpc_status_filter"|"extension_filter"|"metadata_filter"; +} + +/** + * [#next-free-field: 13] + */ +export interface AccessLogFilter__Output { + /** + * Status code filter. + */ + 'status_code_filter'?: (_envoy_config_accesslog_v3_StatusCodeFilter__Output); + /** + * Duration filter. + */ + 'duration_filter'?: (_envoy_config_accesslog_v3_DurationFilter__Output); + /** + * Not health check filter. + */ + 'not_health_check_filter'?: (_envoy_config_accesslog_v3_NotHealthCheckFilter__Output); + /** + * Traceable filter. + */ + 'traceable_filter'?: (_envoy_config_accesslog_v3_TraceableFilter__Output); + /** + * Runtime filter. + */ + 'runtime_filter'?: (_envoy_config_accesslog_v3_RuntimeFilter__Output); + /** + * And filter. + */ + 'and_filter'?: (_envoy_config_accesslog_v3_AndFilter__Output); + /** + * Or filter. + */ + 'or_filter'?: (_envoy_config_accesslog_v3_OrFilter__Output); + /** + * Header filter. + */ + 'header_filter'?: (_envoy_config_accesslog_v3_HeaderFilter__Output); + /** + * Response flag filter. + */ + 'response_flag_filter'?: (_envoy_config_accesslog_v3_ResponseFlagFilter__Output); + /** + * gRPC status filter. + */ + 'grpc_status_filter'?: (_envoy_config_accesslog_v3_GrpcStatusFilter__Output); + /** + * Extension filter. + */ + 'extension_filter'?: (_envoy_config_accesslog_v3_ExtensionFilter__Output); + /** + * Metadata Filter + */ + 'metadata_filter'?: (_envoy_config_accesslog_v3_MetadataFilter__Output); + 'filter_specifier': "status_code_filter"|"duration_filter"|"not_health_check_filter"|"traceable_filter"|"runtime_filter"|"and_filter"|"or_filter"|"header_filter"|"response_flag_filter"|"grpc_status_filter"|"extension_filter"|"metadata_filter"; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/AndFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AndFilter.ts similarity index 51% rename from packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/AndFilter.ts rename to packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AndFilter.ts index 7cf1cb98c..c3c2ac8b4 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/AndFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AndFilter.ts @@ -1,6 +1,6 @@ -// Original file: deps/envoy-api/envoy/config/filter/accesslog/v2/accesslog.proto +// Original file: deps/envoy-api/envoy/config/accesslog/v3/accesslog.proto -import type { AccessLogFilter as _envoy_config_filter_accesslog_v2_AccessLogFilter, AccessLogFilter__Output as _envoy_config_filter_accesslog_v2_AccessLogFilter__Output } from '../../../../../envoy/config/filter/accesslog/v2/AccessLogFilter'; +import type { AccessLogFilter as _envoy_config_accesslog_v3_AccessLogFilter, AccessLogFilter__Output as _envoy_config_accesslog_v3_AccessLogFilter__Output } from '../../../../envoy/config/accesslog/v3/AccessLogFilter'; /** * Performs a logical “and” operation on the result of each filter in filters. @@ -8,7 +8,7 @@ import type { AccessLogFilter as _envoy_config_filter_accesslog_v2_AccessLogFilt * filter returns false immediately. */ export interface AndFilter { - 'filters'?: (_envoy_config_filter_accesslog_v2_AccessLogFilter)[]; + 'filters'?: (_envoy_config_accesslog_v3_AccessLogFilter)[]; } /** @@ -17,5 +17,5 @@ export interface AndFilter { * filter returns false immediately. */ export interface AndFilter__Output { - 'filters': (_envoy_config_filter_accesslog_v2_AccessLogFilter__Output)[]; + 'filters': (_envoy_config_accesslog_v3_AccessLogFilter__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 new file mode 100644 index 000000000..118a47a75 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/ComparisonFilter.ts @@ -0,0 +1,48 @@ +// Original file: deps/envoy-api/envoy/config/accesslog/v3/accesslog.proto + +import type { RuntimeUInt32 as _envoy_config_core_v3_RuntimeUInt32, RuntimeUInt32__Output as _envoy_config_core_v3_RuntimeUInt32__Output } from '../../../../envoy/config/core/v3/RuntimeUInt32'; + +// Original file: deps/envoy-api/envoy/config/accesslog/v3/accesslog.proto + +export enum _envoy_config_accesslog_v3_ComparisonFilter_Op { + /** + * = + */ + EQ = 0, + /** + * >= + */ + GE = 1, + /** + * <= + */ + LE = 2, +} + +/** + * Filter on an integer comparison. + */ +export interface ComparisonFilter { + /** + * Comparison operator. + */ + 'op'?: (_envoy_config_accesslog_v3_ComparisonFilter_Op | keyof typeof _envoy_config_accesslog_v3_ComparisonFilter_Op); + /** + * Value to compare against. + */ + 'value'?: (_envoy_config_core_v3_RuntimeUInt32); +} + +/** + * Filter on an integer comparison. + */ +export interface ComparisonFilter__Output { + /** + * Comparison operator. + */ + 'op': (keyof typeof _envoy_config_accesslog_v3_ComparisonFilter_Op); + /** + * Value to compare against. + */ + 'value'?: (_envoy_config_core_v3_RuntimeUInt32__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/DurationFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/DurationFilter.ts new file mode 100644 index 000000000..03b0500e8 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/DurationFilter.ts @@ -0,0 +1,23 @@ +// Original file: deps/envoy-api/envoy/config/accesslog/v3/accesslog.proto + +import type { ComparisonFilter as _envoy_config_accesslog_v3_ComparisonFilter, ComparisonFilter__Output as _envoy_config_accesslog_v3_ComparisonFilter__Output } from '../../../../envoy/config/accesslog/v3/ComparisonFilter'; + +/** + * Filters on total request duration in milliseconds. + */ +export interface DurationFilter { + /** + * Comparison. + */ + 'comparison'?: (_envoy_config_accesslog_v3_ComparisonFilter); +} + +/** + * Filters on total request duration in milliseconds. + */ +export interface DurationFilter__Output { + /** + * Comparison. + */ + 'comparison'?: (_envoy_config_accesslog_v3_ComparisonFilter__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/ExtensionFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/ExtensionFilter.ts similarity index 64% rename from packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/ExtensionFilter.ts rename to packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/ExtensionFilter.ts index 184c76eb6..127618eef 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/ExtensionFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/ExtensionFilter.ts @@ -1,7 +1,6 @@ -// Original file: deps/envoy-api/envoy/config/filter/accesslog/v2/accesslog.proto +// Original file: deps/envoy-api/envoy/config/accesslog/v3/accesslog.proto -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../../google/protobuf/Struct'; -import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../../google/protobuf/Any'; +import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; /** * Extension filter is statically registered at runtime. @@ -12,12 +11,11 @@ export interface ExtensionFilter { * match a statically registered filter. */ 'name'?: (string); - 'config'?: (_google_protobuf_Struct); 'typed_config'?: (_google_protobuf_Any); /** * Custom configuration that depends on the filter being instantiated. */ - 'config_type'?: "config"|"typed_config"; + 'config_type'?: "typed_config"; } /** @@ -29,10 +27,9 @@ export interface ExtensionFilter__Output { * match a statically registered filter. */ 'name': (string); - 'config'?: (_google_protobuf_Struct__Output); 'typed_config'?: (_google_protobuf_Any__Output); /** * Custom configuration that depends on the filter being instantiated. */ - 'config_type': "config"|"typed_config"; + 'config_type': "typed_config"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/GrpcStatusFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/GrpcStatusFilter.ts similarity index 51% rename from packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/GrpcStatusFilter.ts rename to packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/GrpcStatusFilter.ts index 8e8b0981e..f7ccc8052 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/GrpcStatusFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/GrpcStatusFilter.ts @@ -1,9 +1,9 @@ -// Original file: deps/envoy-api/envoy/config/filter/accesslog/v2/accesslog.proto +// Original file: deps/envoy-api/envoy/config/accesslog/v3/accesslog.proto -// Original file: deps/envoy-api/envoy/config/filter/accesslog/v2/accesslog.proto +// Original file: deps/envoy-api/envoy/config/accesslog/v3/accesslog.proto -export enum _envoy_config_filter_accesslog_v2_GrpcStatusFilter_Status { +export enum _envoy_config_accesslog_v3_GrpcStatusFilter_Status { OK = 0, CANCELED = 1, UNKNOWN = 2, @@ -24,33 +24,35 @@ export enum _envoy_config_filter_accesslog_v2_GrpcStatusFilter_Status { } /** - * Filters gRPC requests based on their response status. If a gRPC status is not provided, the - * filter will infer the status from the HTTP status code. + * Filters gRPC requests based on their response status. If a gRPC status is not + * provided, the filter will infer the status from the HTTP status code. */ export interface GrpcStatusFilter { /** * Logs only responses that have any one of the gRPC statuses in this field. */ - 'statuses'?: (_envoy_config_filter_accesslog_v2_GrpcStatusFilter_Status | keyof typeof _envoy_config_filter_accesslog_v2_GrpcStatusFilter_Status)[]; + 'statuses'?: (_envoy_config_accesslog_v3_GrpcStatusFilter_Status | keyof typeof _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 allow all other responses. + * 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 + * allow all other responses. */ 'exclude'?: (boolean); } /** - * Filters gRPC requests based on their response status. If a gRPC status is not provided, the - * filter will infer the status from the HTTP status code. + * Filters gRPC requests based on their response status. If a gRPC status is not + * provided, the filter will infer the status from the HTTP status code. */ export interface GrpcStatusFilter__Output { /** * Logs only responses that have any one of the gRPC statuses in this field. */ - 'statuses': (keyof typeof _envoy_config_filter_accesslog_v2_GrpcStatusFilter_Status)[]; + 'statuses': (keyof typeof _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 allow all other responses. + * 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 + * allow all other responses. */ 'exclude': (boolean); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/HeaderFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/HeaderFilter.ts new file mode 100644 index 000000000..9cda884b3 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/HeaderFilter.ts @@ -0,0 +1,25 @@ +// Original file: deps/envoy-api/envoy/config/accesslog/v3/accesslog.proto + +import type { HeaderMatcher as _envoy_config_route_v3_HeaderMatcher, HeaderMatcher__Output as _envoy_config_route_v3_HeaderMatcher__Output } from '../../../../envoy/config/route/v3/HeaderMatcher'; + +/** + * Filters requests based on the presence or value of a request header. + */ +export interface HeaderFilter { + /** + * Only requests with a header which matches the specified HeaderMatcher will + * pass the filter check. + */ + 'header'?: (_envoy_config_route_v3_HeaderMatcher); +} + +/** + * Filters requests based on the presence or value of a request header. + */ +export interface HeaderFilter__Output { + /** + * Only requests with a header which matches the specified HeaderMatcher will + * pass the filter check. + */ + 'header'?: (_envoy_config_route_v3_HeaderMatcher__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/MetadataFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/MetadataFilter.ts new file mode 100644 index 000000000..7fdd1d447 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/MetadataFilter.ts @@ -0,0 +1,48 @@ +// Original file: deps/envoy-api/envoy/config/accesslog/v3/accesslog.proto + +import type { MetadataMatcher as _envoy_type_matcher_v3_MetadataMatcher, MetadataMatcher__Output as _envoy_type_matcher_v3_MetadataMatcher__Output } from '../../../../envoy/type/matcher/v3/MetadataMatcher'; +import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; + +/** + * Filters based on matching dynamic metadata. + * If the matcher path and key correspond to an existing key in dynamic + * metadata, the request is logged only if the matcher value is equal to the + * metadata value. If the matcher path and key *do not* correspond to an + * existing key in dynamic metadata, the request is logged only if + * match_if_key_not_found is "true" or unset. + */ +export interface MetadataFilter { + /** + * Matcher to check metadata for specified value. For example, to match on the + * access_log_hint metadata, set the filter to "envoy.common" and the path to + * "access_log_hint", and the value to "true". + */ + 'matcher'?: (_envoy_type_matcher_v3_MetadataMatcher); + /** + * Default result if the key does not exist in dynamic metadata: if unset or + * true, then log; if false, then don't log. + */ + 'match_if_key_not_found'?: (_google_protobuf_BoolValue); +} + +/** + * Filters based on matching dynamic metadata. + * If the matcher path and key correspond to an existing key in dynamic + * metadata, the request is logged only if the matcher value is equal to the + * metadata value. If the matcher path and key *do not* correspond to an + * existing key in dynamic metadata, the request is logged only if + * match_if_key_not_found is "true" or unset. + */ +export interface MetadataFilter__Output { + /** + * Matcher to check metadata for specified value. For example, to match on the + * access_log_hint metadata, set the filter to "envoy.common" and the path to + * "access_log_hint", and the value to "true". + */ + 'matcher'?: (_envoy_type_matcher_v3_MetadataMatcher__Output); + /** + * Default result if the key does not exist in dynamic metadata: if unset or + * true, then log; if false, then don't log. + */ + 'match_if_key_not_found'?: (_google_protobuf_BoolValue__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/NotHealthCheckFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/NotHealthCheckFilter.ts similarity index 81% rename from packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/NotHealthCheckFilter.ts rename to packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/NotHealthCheckFilter.ts index 3de68f081..40728fc34 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/NotHealthCheckFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/NotHealthCheckFilter.ts @@ -1,4 +1,4 @@ -// Original file: deps/envoy-api/envoy/config/filter/accesslog/v2/accesslog.proto +// Original file: deps/envoy-api/envoy/config/accesslog/v3/accesslog.proto /** diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/OrFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/OrFilter.ts similarity index 50% rename from packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/OrFilter.ts rename to packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/OrFilter.ts index 859c1218c..1756d3ad5 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/OrFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/OrFilter.ts @@ -1,6 +1,6 @@ -// Original file: deps/envoy-api/envoy/config/filter/accesslog/v2/accesslog.proto +// Original file: deps/envoy-api/envoy/config/accesslog/v3/accesslog.proto -import type { AccessLogFilter as _envoy_config_filter_accesslog_v2_AccessLogFilter, AccessLogFilter__Output as _envoy_config_filter_accesslog_v2_AccessLogFilter__Output } from '../../../../../envoy/config/filter/accesslog/v2/AccessLogFilter'; +import type { AccessLogFilter as _envoy_config_accesslog_v3_AccessLogFilter, AccessLogFilter__Output as _envoy_config_accesslog_v3_AccessLogFilter__Output } from '../../../../envoy/config/accesslog/v3/AccessLogFilter'; /** * Performs a logical “or” operation on the result of each individual filter. @@ -8,7 +8,7 @@ import type { AccessLogFilter as _envoy_config_filter_accesslog_v2_AccessLogFilt * filter returns true immediately. */ export interface OrFilter { - 'filters'?: (_envoy_config_filter_accesslog_v2_AccessLogFilter)[]; + 'filters'?: (_envoy_config_accesslog_v3_AccessLogFilter)[]; } /** @@ -17,5 +17,5 @@ export interface OrFilter { * filter returns true immediately. */ export interface OrFilter__Output { - 'filters': (_envoy_config_filter_accesslog_v2_AccessLogFilter__Output)[]; + 'filters': (_envoy_config_accesslog_v3_AccessLogFilter__Output)[]; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/ResponseFlagFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/ResponseFlagFilter.ts similarity index 51% rename from packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/ResponseFlagFilter.ts rename to packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/ResponseFlagFilter.ts index 280fbb26a..c45a63054 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/ResponseFlagFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/ResponseFlagFilter.ts @@ -1,16 +1,17 @@ -// Original file: deps/envoy-api/envoy/config/filter/accesslog/v2/accesslog.proto +// Original file: deps/envoy-api/envoy/config/accesslog/v3/accesslog.proto /** * Filters requests that received responses with an Envoy response flag set. * A list of the response flags can be found - * in the access log formatter :ref:`documentation`. + * in the access log formatter + * :ref:`documentation`. */ export interface ResponseFlagFilter { /** - * Only responses with the any of the flags listed in this field will be logged. - * This field is optional. If it is not specified, then any response flag will pass - * the filter check. + * Only responses with the any of the flags listed in this field will be + * logged. This field is optional. If it is not specified, then any response + * flag will pass the filter check. */ 'flags'?: (string)[]; } @@ -18,13 +19,14 @@ export interface ResponseFlagFilter { /** * Filters requests that received responses with an Envoy response flag set. * A list of the response flags can be found - * in the access log formatter :ref:`documentation`. + * in the access log formatter + * :ref:`documentation`. */ export interface ResponseFlagFilter__Output { /** - * Only responses with the any of the flags listed in this field will be logged. - * This field is optional. If it is not specified, then any response flag will pass - * the filter check. + * Only responses with the any of the flags listed in this field will be + * logged. This field is optional. If it is not specified, then any response + * flag will pass the filter check. */ 'flags': (string)[]; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/RuntimeFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/RuntimeFilter.ts new file mode 100644 index 000000000..9388f49ec --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/RuntimeFilter.ts @@ -0,0 +1,73 @@ +// Original file: deps/envoy-api/envoy/config/accesslog/v3/accesslog.proto + +import type { FractionalPercent as _envoy_type_v3_FractionalPercent, FractionalPercent__Output as _envoy_type_v3_FractionalPercent__Output } from '../../../../envoy/type/v3/FractionalPercent'; + +/** + * Filters for random sampling of requests. + */ +export interface RuntimeFilter { + /** + * Runtime key to get an optional overridden numerator for use in the + * *percent_sampled* field. If found in runtime, this value will replace the + * default numerator. + */ + 'runtime_key'?: (string); + /** + * The default sampling percentage. If not specified, defaults to 0% with + * denominator of 100. + */ + 'percent_sampled'?: (_envoy_type_v3_FractionalPercent); + /** + * By default, sampling pivots on the header + * :ref:`x-request-id` being + * present. If :ref:`x-request-id` + * is present, the filter will consistently sample across multiple hosts based + * on the runtime key value and the value extracted from + * :ref:`x-request-id`. If it is + * missing, or *use_independent_randomness* is set to true, the filter will + * randomly sample based on the runtime key value alone. + * *use_independent_randomness* can be used for logging kill switches within + * complex nested :ref:`AndFilter + * ` and :ref:`OrFilter + * ` blocks that are easier to + * reason about from a probability perspective (i.e., setting to true will + * cause the filter to behave like an independent random variable when + * composed within logical operator filters). + */ + 'use_independent_randomness'?: (boolean); +} + +/** + * Filters for random sampling of requests. + */ +export interface RuntimeFilter__Output { + /** + * Runtime key to get an optional overridden numerator for use in the + * *percent_sampled* field. If found in runtime, this value will replace the + * default numerator. + */ + 'runtime_key': (string); + /** + * The default sampling percentage. If not specified, defaults to 0% with + * denominator of 100. + */ + 'percent_sampled'?: (_envoy_type_v3_FractionalPercent__Output); + /** + * By default, sampling pivots on the header + * :ref:`x-request-id` being + * present. If :ref:`x-request-id` + * is present, the filter will consistently sample across multiple hosts based + * on the runtime key value and the value extracted from + * :ref:`x-request-id`. If it is + * missing, or *use_independent_randomness* is set to true, the filter will + * randomly sample based on the runtime key value alone. + * *use_independent_randomness* can be used for logging kill switches within + * complex nested :ref:`AndFilter + * ` and :ref:`OrFilter + * ` blocks that are easier to + * reason about from a probability perspective (i.e., setting to true will + * cause the filter to behave like an independent random variable when + * composed within logical operator filters). + */ + 'use_independent_randomness': (boolean); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/StatusCodeFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/StatusCodeFilter.ts new file mode 100644 index 000000000..313ed86ca --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/StatusCodeFilter.ts @@ -0,0 +1,23 @@ +// Original file: deps/envoy-api/envoy/config/accesslog/v3/accesslog.proto + +import type { ComparisonFilter as _envoy_config_accesslog_v3_ComparisonFilter, ComparisonFilter__Output as _envoy_config_accesslog_v3_ComparisonFilter__Output } from '../../../../envoy/config/accesslog/v3/ComparisonFilter'; + +/** + * Filters on HTTP response/status code. + */ +export interface StatusCodeFilter { + /** + * Comparison. + */ + 'comparison'?: (_envoy_config_accesslog_v3_ComparisonFilter); +} + +/** + * Filters on HTTP response/status code. + */ +export interface StatusCodeFilter__Output { + /** + * Comparison. + */ + 'comparison'?: (_envoy_config_accesslog_v3_ComparisonFilter__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/TraceableFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/TraceableFilter.ts similarity index 81% rename from packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/TraceableFilter.ts rename to packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/TraceableFilter.ts index 8de24656a..c2b3a646b 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/TraceableFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/TraceableFilter.ts @@ -1,4 +1,4 @@ -// Original file: deps/envoy-api/envoy/config/filter/accesslog/v2/accesslog.proto +// Original file: deps/envoy-api/envoy/config/accesslog/v3/accesslog.proto /** diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/cluster/CircuitBreakers.ts b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/CircuitBreakers.ts similarity index 75% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/cluster/CircuitBreakers.ts rename to packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/CircuitBreakers.ts index edf946590..c4f4add69 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/cluster/CircuitBreakers.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/CircuitBreakers.ts @@ -1,10 +1,10 @@ -// Original file: deps/envoy-api/envoy/api/v2/cluster/circuit_breaker.proto +// Original file: deps/envoy-api/envoy/config/cluster/v3/circuit_breaker.proto -import type { RoutingPriority as _envoy_api_v2_core_RoutingPriority } from '../../../../envoy/api/v2/core/RoutingPriority'; +import type { RoutingPriority as _envoy_config_core_v3_RoutingPriority } 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_Percent, Percent__Output as _envoy_type_Percent__Output } from '../../../../envoy/type/Percent'; +import type { Percent as _envoy_type_v3_Percent, Percent__Output as _envoy_type_v3_Percent__Output } from '../../../../envoy/type/v3/Percent'; -export interface _envoy_api_v2_cluster_CircuitBreakers_Thresholds_RetryBudget { +export interface _envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget { /** * Specifies the limit on concurrent retries as a percentage of the sum of active requests and * active pending requests. For example, if there are 100 active requests and the @@ -12,7 +12,7 @@ export interface _envoy_api_v2_cluster_CircuitBreakers_Thresholds_RetryBudget { * * This parameter is optional. Defaults to 20%. */ - 'budget_percent'?: (_envoy_type_Percent); + 'budget_percent'?: (_envoy_type_v3_Percent); /** * Specifies the minimum retry concurrency allowed for the retry budget. The limit on the * number of active retries may never go below this number. @@ -22,7 +22,7 @@ export interface _envoy_api_v2_cluster_CircuitBreakers_Thresholds_RetryBudget { 'min_retry_concurrency'?: (_google_protobuf_UInt32Value); } -export interface _envoy_api_v2_cluster_CircuitBreakers_Thresholds_RetryBudget__Output { +export interface _envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget__Output { /** * Specifies the limit on concurrent retries as a percentage of the sum of active requests and * active pending requests. For example, if there are 100 active requests and the @@ -30,7 +30,7 @@ export interface _envoy_api_v2_cluster_CircuitBreakers_Thresholds_RetryBudget__O * * This parameter is optional. Defaults to 20%. */ - 'budget_percent'?: (_envoy_type_Percent__Output); + 'budget_percent'?: (_envoy_type_v3_Percent__Output); /** * Specifies the minimum retry concurrency allowed for the retry budget. The limit on the * number of active retries may never go below this number. @@ -42,15 +42,15 @@ export interface _envoy_api_v2_cluster_CircuitBreakers_Thresholds_RetryBudget__O /** * A Thresholds defines CircuitBreaker settings for a - * :ref:`RoutingPriority`. + * :ref:`RoutingPriority`. * [#next-free-field: 9] */ -export interface _envoy_api_v2_cluster_CircuitBreakers_Thresholds { +export interface _envoy_config_cluster_v3_CircuitBreakers_Thresholds { /** - * The :ref:`RoutingPriority` + * The :ref:`RoutingPriority` * the specified CircuitBreaker settings apply to. */ - 'priority'?: (_envoy_api_v2_core_RoutingPriority | keyof typeof _envoy_api_v2_core_RoutingPriority); + 'priority'?: (_envoy_config_core_v3_RoutingPriority | keyof typeof _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. @@ -80,7 +80,7 @@ export interface _envoy_api_v2_cluster_CircuitBreakers_Thresholds { * If this field is set, the retry budget will override any configured retry circuit * breaker. */ - 'retry_budget'?: (_envoy_api_v2_cluster_CircuitBreakers_Thresholds_RetryBudget); + 'retry_budget'?: (_envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget); /** * If track_remaining is true, then stats will be published that expose * the number of resources remaining until the circuit breakers open. If @@ -104,15 +104,15 @@ export interface _envoy_api_v2_cluster_CircuitBreakers_Thresholds { /** * A Thresholds defines CircuitBreaker settings for a - * :ref:`RoutingPriority`. + * :ref:`RoutingPriority`. * [#next-free-field: 9] */ -export interface _envoy_api_v2_cluster_CircuitBreakers_Thresholds__Output { +export interface _envoy_config_cluster_v3_CircuitBreakers_Thresholds__Output { /** - * The :ref:`RoutingPriority` + * The :ref:`RoutingPriority` * the specified CircuitBreaker settings apply to. */ - 'priority': (keyof typeof _envoy_api_v2_core_RoutingPriority); + 'priority': (keyof typeof _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. @@ -142,7 +142,7 @@ export interface _envoy_api_v2_cluster_CircuitBreakers_Thresholds__Output { * If this field is set, the retry budget will override any configured retry circuit * breaker. */ - 'retry_budget'?: (_envoy_api_v2_cluster_CircuitBreakers_Thresholds_RetryBudget__Output); + 'retry_budget'?: (_envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget__Output); /** * If track_remaining is true, then stats will be published that expose * the number of resources remaining until the circuit breakers open. If @@ -170,13 +170,13 @@ export interface _envoy_api_v2_cluster_CircuitBreakers_Thresholds__Output { */ export interface CircuitBreakers { /** - * If multiple :ref:`Thresholds` - * are defined with the same :ref:`RoutingPriority`, + * If multiple :ref:`Thresholds` + * are defined with the same :ref:`RoutingPriority`, * the first one in the list is used. If no Thresholds is defined for a given - * :ref:`RoutingPriority`, the default values + * :ref:`RoutingPriority`, the default values * are used. */ - 'thresholds'?: (_envoy_api_v2_cluster_CircuitBreakers_Thresholds)[]; + 'thresholds'?: (_envoy_config_cluster_v3_CircuitBreakers_Thresholds)[]; } /** @@ -185,11 +185,11 @@ export interface CircuitBreakers { */ export interface CircuitBreakers__Output { /** - * If multiple :ref:`Thresholds` - * are defined with the same :ref:`RoutingPriority`, + * If multiple :ref:`Thresholds` + * are defined with the same :ref:`RoutingPriority`, * the first one in the list is used. If no Thresholds is defined for a given - * :ref:`RoutingPriority`, the default values + * :ref:`RoutingPriority`, the default values * are used. */ - 'thresholds': (_envoy_api_v2_cluster_CircuitBreakers_Thresholds__Output)[]; + 'thresholds': (_envoy_config_cluster_v3_CircuitBreakers_Thresholds__Output)[]; } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/Cluster.ts b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/Cluster.ts similarity index 50% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/Cluster.ts rename to packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/Cluster.ts index f077d2edc..fa76fba89 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/Cluster.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/Cluster.ts @@ -1,36 +1,39 @@ -// Original file: deps/envoy-api/envoy/api/v2/cluster.proto +// Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto -import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../google/protobuf/Duration'; -import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../google/protobuf/UInt32Value'; -import type { Address as _envoy_api_v2_core_Address, Address__Output as _envoy_api_v2_core_Address__Output } from '../../../envoy/api/v2/core/Address'; -import type { HealthCheck as _envoy_api_v2_core_HealthCheck, HealthCheck__Output as _envoy_api_v2_core_HealthCheck__Output } from '../../../envoy/api/v2/core/HealthCheck'; -import type { CircuitBreakers as _envoy_api_v2_cluster_CircuitBreakers, CircuitBreakers__Output as _envoy_api_v2_cluster_CircuitBreakers__Output } from '../../../envoy/api/v2/cluster/CircuitBreakers'; -import type { UpstreamTlsContext as _envoy_api_v2_auth_UpstreamTlsContext, UpstreamTlsContext__Output as _envoy_api_v2_auth_UpstreamTlsContext__Output } from '../../../envoy/api/v2/auth/UpstreamTlsContext'; -import type { Http1ProtocolOptions as _envoy_api_v2_core_Http1ProtocolOptions, Http1ProtocolOptions__Output as _envoy_api_v2_core_Http1ProtocolOptions__Output } from '../../../envoy/api/v2/core/Http1ProtocolOptions'; -import type { Http2ProtocolOptions as _envoy_api_v2_core_Http2ProtocolOptions, Http2ProtocolOptions__Output as _envoy_api_v2_core_Http2ProtocolOptions__Output } from '../../../envoy/api/v2/core/Http2ProtocolOptions'; -import type { OutlierDetection as _envoy_api_v2_cluster_OutlierDetection, OutlierDetection__Output as _envoy_api_v2_cluster_OutlierDetection__Output } from '../../../envoy/api/v2/cluster/OutlierDetection'; -import type { BindConfig as _envoy_api_v2_core_BindConfig, BindConfig__Output as _envoy_api_v2_core_BindConfig__Output } from '../../../envoy/api/v2/core/BindConfig'; -import type { TransportSocket as _envoy_api_v2_core_TransportSocket, TransportSocket__Output as _envoy_api_v2_core_TransportSocket__Output } from '../../../envoy/api/v2/core/TransportSocket'; -import type { Metadata as _envoy_api_v2_core_Metadata, Metadata__Output as _envoy_api_v2_core_Metadata__Output } from '../../../envoy/api/v2/core/Metadata'; -import type { HttpProtocolOptions as _envoy_api_v2_core_HttpProtocolOptions, HttpProtocolOptions__Output as _envoy_api_v2_core_HttpProtocolOptions__Output } from '../../../envoy/api/v2/core/HttpProtocolOptions'; -import type { UpstreamConnectionOptions as _envoy_api_v2_UpstreamConnectionOptions, UpstreamConnectionOptions__Output as _envoy_api_v2_UpstreamConnectionOptions__Output } from '../../../envoy/api/v2/UpstreamConnectionOptions'; -import type { ClusterLoadAssignment as _envoy_api_v2_ClusterLoadAssignment, ClusterLoadAssignment__Output as _envoy_api_v2_ClusterLoadAssignment__Output } from '../../../envoy/api/v2/ClusterLoadAssignment'; -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../google/protobuf/Struct'; -import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any'; -import type { Filter as _envoy_api_v2_cluster_Filter, Filter__Output as _envoy_api_v2_cluster_Filter__Output } from '../../../envoy/api/v2/cluster/Filter'; -import type { LoadBalancingPolicy as _envoy_api_v2_LoadBalancingPolicy, LoadBalancingPolicy__Output as _envoy_api_v2_LoadBalancingPolicy__Output } from '../../../envoy/api/v2/LoadBalancingPolicy'; -import type { ConfigSource as _envoy_api_v2_core_ConfigSource, ConfigSource__Output as _envoy_api_v2_core_ConfigSource__Output } from '../../../envoy/api/v2/core/ConfigSource'; -import type { UpstreamHttpProtocolOptions as _envoy_api_v2_core_UpstreamHttpProtocolOptions, UpstreamHttpProtocolOptions__Output as _envoy_api_v2_core_UpstreamHttpProtocolOptions__Output } from '../../../envoy/api/v2/core/UpstreamHttpProtocolOptions'; -import type { UInt64Value as _google_protobuf_UInt64Value, UInt64Value__Output as _google_protobuf_UInt64Value__Output } from '../../../google/protobuf/UInt64Value'; -import type { Percent as _envoy_type_Percent, Percent__Output as _envoy_type_Percent__Output } from '../../../envoy/type/Percent'; +import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; +import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; +import type { HealthCheck as _envoy_config_core_v3_HealthCheck, HealthCheck__Output as _envoy_config_core_v3_HealthCheck__Output } from '../../../../envoy/config/core/v3/HealthCheck'; +import type { CircuitBreakers as _envoy_config_cluster_v3_CircuitBreakers, CircuitBreakers__Output as _envoy_config_cluster_v3_CircuitBreakers__Output } from '../../../../envoy/config/cluster/v3/CircuitBreakers'; +import type { Http1ProtocolOptions as _envoy_config_core_v3_Http1ProtocolOptions, Http1ProtocolOptions__Output as _envoy_config_core_v3_Http1ProtocolOptions__Output } from '../../../../envoy/config/core/v3/Http1ProtocolOptions'; +import type { Http2ProtocolOptions as _envoy_config_core_v3_Http2ProtocolOptions, Http2ProtocolOptions__Output as _envoy_config_core_v3_Http2ProtocolOptions__Output } from '../../../../envoy/config/core/v3/Http2ProtocolOptions'; +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 { OutlierDetection as _envoy_config_cluster_v3_OutlierDetection, OutlierDetection__Output as _envoy_config_cluster_v3_OutlierDetection__Output } from '../../../../envoy/config/cluster/v3/OutlierDetection'; +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 { TransportSocket as _envoy_config_core_v3_TransportSocket, TransportSocket__Output as _envoy_config_core_v3_TransportSocket__Output } from '../../../../envoy/config/core/v3/TransportSocket'; +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 { HttpProtocolOptions as _envoy_config_core_v3_HttpProtocolOptions, HttpProtocolOptions__Output as _envoy_config_core_v3_HttpProtocolOptions__Output } from '../../../../envoy/config/core/v3/HttpProtocolOptions'; +import type { UpstreamConnectionOptions as _envoy_config_cluster_v3_UpstreamConnectionOptions, UpstreamConnectionOptions__Output as _envoy_config_cluster_v3_UpstreamConnectionOptions__Output } from '../../../../envoy/config/cluster/v3/UpstreamConnectionOptions'; +import type { ClusterLoadAssignment as _envoy_config_endpoint_v3_ClusterLoadAssignment, ClusterLoadAssignment__Output as _envoy_config_endpoint_v3_ClusterLoadAssignment__Output } from '../../../../envoy/config/endpoint/v3/ClusterLoadAssignment'; +import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; +import type { Filter as _envoy_config_cluster_v3_Filter, Filter__Output as _envoy_config_cluster_v3_Filter__Output } from '../../../../envoy/config/cluster/v3/Filter'; +import type { LoadBalancingPolicy as _envoy_config_cluster_v3_LoadBalancingPolicy, LoadBalancingPolicy__Output as _envoy_config_cluster_v3_LoadBalancingPolicy__Output } from '../../../../envoy/config/cluster/v3/LoadBalancingPolicy'; +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 { UpstreamHttpProtocolOptions as _envoy_config_core_v3_UpstreamHttpProtocolOptions, UpstreamHttpProtocolOptions__Output as _envoy_config_core_v3_UpstreamHttpProtocolOptions__Output } from '../../../../envoy/config/core/v3/UpstreamHttpProtocolOptions'; +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 { TrackClusterStats as _envoy_config_cluster_v3_TrackClusterStats, TrackClusterStats__Output as _envoy_config_cluster_v3_TrackClusterStats__Output } from '../../../../envoy/config/cluster/v3/TrackClusterStats'; +import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; +import type { RuntimeDouble as _envoy_config_core_v3_RuntimeDouble, RuntimeDouble__Output as _envoy_config_core_v3_RuntimeDouble__Output } from '../../../../envoy/config/core/v3/RuntimeDouble'; +import type { UInt64Value as _google_protobuf_UInt64Value, UInt64Value__Output as _google_protobuf_UInt64Value__Output } from '../../../../google/protobuf/UInt64Value'; +import type { Percent as _envoy_type_v3_Percent, Percent__Output as _envoy_type_v3_Percent__Output } from '../../../../envoy/type/v3/Percent'; +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/api/v2/cluster.proto +// Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto -export enum _envoy_api_v2_Cluster_ClusterProtocolSelection { +export enum _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 + * If :ref:`http2_protocol_options ` are * present, HTTP2 will be used, otherwise HTTP1.1 will be used. */ USE_CONFIGURED_PROTOCOL = 0, @@ -44,7 +47,7 @@ export enum _envoy_api_v2_Cluster_ClusterProtocolSelection { * Common configuration for all load balancer implementations. * [#next-free-field: 8] */ -export interface _envoy_api_v2_Cluster_CommonLbConfig { +export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig { /** * Configures the :ref:`healthy panic threshold `. * If not specified, the default is 50%. @@ -53,9 +56,9 @@ export interface _envoy_api_v2_Cluster_CommonLbConfig { * .. note:: * The specified percent will be truncated to the nearest 1%. */ - 'healthy_panic_threshold'?: (_envoy_type_Percent); - 'zone_aware_lb_config'?: (_envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig); - 'locality_weighted_lb_config'?: (_envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig); + 'healthy_panic_threshold'?: (_envoy_type_v3_Percent); + 'zone_aware_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig); + 'locality_weighted_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig); /** * If set, all health check/weight/metadata updates that happen within this duration will be * merged and delivered in one shot when the duration expires. The start of the duration is when @@ -74,25 +77,9 @@ export interface _envoy_api_v2_Cluster_CommonLbConfig { */ 'update_merge_window'?: (_google_protobuf_Duration); /** - * If set to true, Envoy will not consider new hosts when computing load balancing weights until - * they have been health checked for the first time. This will have no effect unless - * active health checking is also configured. - * - * Ignoring a host means that for any load balancing calculations that adjust weights based - * on the ratio of eligible hosts and total hosts (priority spillover, locality weighting and - * panic mode) Envoy will exclude these hosts in the denominator. - * - * For example, with hosts in two priorities P0 and P1, where P0 looks like - * {healthy, unhealthy (new), unhealthy (new)} - * and where P1 looks like - * {healthy, healthy} - * all traffic will still hit P0, as 1 / (3 - 2) = 1. - * - * Enabling this will allow scaling up the number of hosts for a given cluster without entering - * panic mode or triggering priority spillover, assuming the hosts pass the first health check. - * - * If panic mode is triggered, new hosts are still eligible for traffic; they simply do not - * contribute to the calculation when deciding whether panic mode is enabled or not. + * If set to true, Envoy will :ref:`exclude ` new hosts + * when computing load balancing weights until they have been health checked for the first time. + * This will have no effect unless active health checking is also configured. */ 'ignore_new_hosts_until_first_hc'?: (boolean); /** @@ -103,7 +90,7 @@ export interface _envoy_api_v2_Cluster_CommonLbConfig { /** * Common Configuration for all consistent hashing load balancers (MaglevLb, RingHashLb, etc.) */ - 'consistent_hashing_lb_config'?: (_envoy_api_v2_Cluster_CommonLbConfig_ConsistentHashingLbConfig); + 'consistent_hashing_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig); 'locality_config_specifier'?: "zone_aware_lb_config"|"locality_weighted_lb_config"; } @@ -111,7 +98,7 @@ export interface _envoy_api_v2_Cluster_CommonLbConfig { * Common configuration for all load balancer implementations. * [#next-free-field: 8] */ -export interface _envoy_api_v2_Cluster_CommonLbConfig__Output { +export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig__Output { /** * Configures the :ref:`healthy panic threshold `. * If not specified, the default is 50%. @@ -120,9 +107,9 @@ export interface _envoy_api_v2_Cluster_CommonLbConfig__Output { * .. note:: * The specified percent will be truncated to the nearest 1%. */ - 'healthy_panic_threshold'?: (_envoy_type_Percent__Output); - 'zone_aware_lb_config'?: (_envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig__Output); - 'locality_weighted_lb_config'?: (_envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig__Output); + 'healthy_panic_threshold'?: (_envoy_type_v3_Percent__Output); + 'zone_aware_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig__Output); + 'locality_weighted_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig__Output); /** * If set, all health check/weight/metadata updates that happen within this duration will be * merged and delivered in one shot when the duration expires. The start of the duration is when @@ -141,25 +128,9 @@ export interface _envoy_api_v2_Cluster_CommonLbConfig__Output { */ 'update_merge_window'?: (_google_protobuf_Duration__Output); /** - * If set to true, Envoy will not consider new hosts when computing load balancing weights until - * they have been health checked for the first time. This will have no effect unless - * active health checking is also configured. - * - * Ignoring a host means that for any load balancing calculations that adjust weights based - * on the ratio of eligible hosts and total hosts (priority spillover, locality weighting and - * panic mode) Envoy will exclude these hosts in the denominator. - * - * For example, with hosts in two priorities P0 and P1, where P0 looks like - * {healthy, unhealthy (new), unhealthy (new)} - * and where P1 looks like - * {healthy, healthy} - * all traffic will still hit P0, as 1 / (3 - 2) = 1. - * - * Enabling this will allow scaling up the number of hosts for a given cluster without entering - * panic mode or triggering priority spillover, assuming the hosts pass the first health check. - * - * If panic mode is triggered, new hosts are still eligible for traffic; they simply do not - * contribute to the calculation when deciding whether panic mode is enabled or not. + * If set to true, Envoy will :ref:`exclude ` new hosts + * when computing load balancing weights until they have been health checked for the first time. + * This will have no effect unless active health checking is also configured. */ 'ignore_new_hosts_until_first_hc': (boolean); /** @@ -170,36 +141,78 @@ export interface _envoy_api_v2_Cluster_CommonLbConfig__Output { /** * Common Configuration for all consistent hashing load balancers (MaglevLb, RingHashLb, etc.) */ - 'consistent_hashing_lb_config'?: (_envoy_api_v2_Cluster_CommonLbConfig_ConsistentHashingLbConfig__Output); + 'consistent_hashing_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig__Output); 'locality_config_specifier': "zone_aware_lb_config"|"locality_weighted_lb_config"; } /** * Common Configuration for all consistent hashing load balancers (MaglevLb, RingHashLb, etc.) */ -export interface _envoy_api_v2_Cluster_CommonLbConfig_ConsistentHashingLbConfig { +export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig { /** * If set to `true`, the cluster will use hostname instead of the resolved * address as the key to consistently hash to an upstream host. Only valid for StrictDNS clusters with hostnames which resolve to a single IP address. */ 'use_hostname_for_hashing'?: (boolean); + /** + * Configures percentage of average cluster load to bound per upstream host. For example, with a value of 150 + * no upstream host will get a load more than 1.5 times the average load of all the hosts in the cluster. + * If not specified, the load is not bounded for any upstream host. Typical value for this parameter is between 120 and 200. + * Minimum is 100. + * + * Applies to both Ring Hash and Maglev load balancers. + * + * This is implemented based on the method described in the paper https://arxiv.org/abs/1608.01350. For the specified + * `hash_balance_factor`, requests to any upstream host are capped at `hash_balance_factor/100` times the average number of requests + * across the cluster. When a request arrives for an upstream host that is currently serving at its max capacity, linear probing + * is used to identify an eligible host. Further, the linear probe is implemented using a random jump in hosts ring/table to identify + * the eligible host (this technique is as described in the paper https://arxiv.org/abs/1908.08762 - the random jump avoids the + * cascading overflow effect when choosing the next host in the ring/table). + * + * If weights are specified on the hosts, they are respected. + * + * This is an O(N) algorithm, unlike other load balancers. Using a lower `hash_balance_factor` results in more hosts + * being probed, so use a higher value if you require better performance. + */ + 'hash_balance_factor'?: (_google_protobuf_UInt32Value); } /** * Common Configuration for all consistent hashing load balancers (MaglevLb, RingHashLb, etc.) */ -export interface _envoy_api_v2_Cluster_CommonLbConfig_ConsistentHashingLbConfig__Output { +export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig__Output { /** * If set to `true`, the cluster will use hostname instead of the resolved * address as the key to consistently hash to an upstream host. Only valid for StrictDNS clusters with hostnames which resolve to a single IP address. */ 'use_hostname_for_hashing': (boolean); + /** + * Configures percentage of average cluster load to bound per upstream host. For example, with a value of 150 + * no upstream host will get a load more than 1.5 times the average load of all the hosts in the cluster. + * If not specified, the load is not bounded for any upstream host. Typical value for this parameter is between 120 and 200. + * Minimum is 100. + * + * Applies to both Ring Hash and Maglev load balancers. + * + * This is implemented based on the method described in the paper https://arxiv.org/abs/1608.01350. For the specified + * `hash_balance_factor`, requests to any upstream host are capped at `hash_balance_factor/100` times the average number of requests + * across the cluster. When a request arrives for an upstream host that is currently serving at its max capacity, linear probing + * is used to identify an eligible host. Further, the linear probe is implemented using a random jump in hosts ring/table to identify + * the eligible host (this technique is as described in the paper https://arxiv.org/abs/1908.08762 - the random jump avoids the + * cascading overflow effect when choosing the next host in the ring/table). + * + * If weights are specified on the hosts, they are respected. + * + * This is an O(N) algorithm, unlike other load balancers. Using a lower `hash_balance_factor` results in more hosts + * being probed, so use a higher value if you require better performance. + */ + 'hash_balance_factor'?: (_google_protobuf_UInt32Value__Output); } /** * Extended cluster type. */ -export interface _envoy_api_v2_Cluster_CustomClusterType { +export interface _envoy_config_cluster_v3_Cluster_CustomClusterType { /** * The type of the cluster to instantiate. The name must match a supported cluster type. */ @@ -214,7 +227,7 @@ export interface _envoy_api_v2_Cluster_CustomClusterType { /** * Extended cluster type. */ -export interface _envoy_api_v2_Cluster_CustomClusterType__Output { +export interface _envoy_config_cluster_v3_Cluster_CustomClusterType__Output { /** * The type of the cluster to instantiate. The name must match a supported cluster type. */ @@ -226,13 +239,13 @@ export interface _envoy_api_v2_Cluster_CustomClusterType__Output { 'typed_config'?: (_google_protobuf_Any__Output); } -// Original file: deps/envoy-api/envoy/api/v2/cluster.proto +// Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto /** * Refer to :ref:`service discovery type ` * for an explanation on each type. */ -export enum _envoy_api_v2_Cluster_DiscoveryType { +export enum _envoy_config_cluster_v3_Cluster_DiscoveryType { /** * Refer to the :ref:`static discovery type` * for an explanation. @@ -263,7 +276,7 @@ export enum _envoy_api_v2_Cluster_DiscoveryType { ORIGINAL_DST = 4, } -// Original file: deps/envoy-api/envoy/api/v2/cluster.proto +// Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto /** * When V4_ONLY is selected, the DNS resolver will only perform a lookup for @@ -272,12 +285,12 @@ export enum _envoy_api_v2_Cluster_DiscoveryType { * 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. * For cluster types other than - * :ref:`STRICT_DNS` and - * :ref:`LOGICAL_DNS`, + * :ref:`STRICT_DNS` and + * :ref:`LOGICAL_DNS`, * this setting is * ignored. */ -export enum _envoy_api_v2_Cluster_DnsLookupFamily { +export enum _envoy_config_cluster_v3_Cluster_DnsLookupFamily { AUTO = 0, V4_ONLY = 1, V6_ONLY = 2, @@ -286,15 +299,15 @@ export enum _envoy_api_v2_Cluster_DnsLookupFamily { /** * Only valid when discovery type is EDS. */ -export interface _envoy_api_v2_Cluster_EdsClusterConfig { +export interface _envoy_config_cluster_v3_Cluster_EdsClusterConfig { /** * Configuration for the source of EDS updates for this Cluster. */ - 'eds_config'?: (_envoy_api_v2_core_ConfigSource); + 'eds_config'?: (_envoy_config_core_v3_ConfigSource); /** * Optional alternative to cluster name to present to EDS. This does not * have the same restrictions as cluster name, i.e. it may be arbitrary - * length. + * length. This may be a xdstp:// URL. */ 'service_name'?: (string); } @@ -302,25 +315,25 @@ export interface _envoy_api_v2_Cluster_EdsClusterConfig { /** * Only valid when discovery type is EDS. */ -export interface _envoy_api_v2_Cluster_EdsClusterConfig__Output { +export interface _envoy_config_cluster_v3_Cluster_EdsClusterConfig__Output { /** * Configuration for the source of EDS updates for this Cluster. */ - 'eds_config'?: (_envoy_api_v2_core_ConfigSource__Output); + 'eds_config'?: (_envoy_config_core_v3_ConfigSource__Output); /** * Optional alternative to cluster name to present to EDS. This does not * have the same restrictions as cluster name, i.e. it may be arbitrary - * length. + * length. This may be a xdstp:// URL. */ 'service_name': (string); } -// Original file: deps/envoy-api/envoy/api/v2/cluster.proto +// Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto /** * The hash function used to hash hosts onto the ketama ring. */ -export enum _envoy_api_v2_Cluster_RingHashLbConfig_HashFunction { +export enum _envoy_config_cluster_v3_Cluster_RingHashLbConfig_HashFunction { /** * Use `xxHash `_, this is the default hash function. */ @@ -333,13 +346,13 @@ export enum _envoy_api_v2_Cluster_RingHashLbConfig_HashFunction { MURMUR_HASH_2 = 1, } -// Original file: deps/envoy-api/envoy/api/v2/cluster.proto +// Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto /** * Refer to :ref:`load balancer type ` architecture * overview section for information on each type. */ -export enum _envoy_api_v2_Cluster_LbPolicy { +export enum _envoy_config_cluster_v3_Cluster_LbPolicy { /** * Refer to the :ref:`round robin load balancing * policy` @@ -364,16 +377,6 @@ export enum _envoy_api_v2_Cluster_LbPolicy { * for an explanation. */ RANDOM = 3, - /** - * Refer to the :ref:`original destination load balancing - * policy` - * for an explanation. - * - * .. attention:: - * - * **This load balancing policy is deprecated**. Use CLUSTER_PROVIDED instead. - */ - ORIGINAL_DST_LB = 4, /** * Refer to the :ref:`Maglev load balancing policy` * for an explanation. @@ -387,7 +390,7 @@ export enum _envoy_api_v2_Cluster_LbPolicy { CLUSTER_PROVIDED = 6, /** * [#not-implemented-hide:] Use the new :ref:`load_balancing_policy - * ` field to determine the LB policy. + * ` field to determine the LB policy. * [#next-major-version: In the v3 API, we should consider deprecating the lb_policy field * and instead using the new load_balancing_policy field as the one and only mechanism for * configuring this.] @@ -400,22 +403,22 @@ export enum _envoy_api_v2_Cluster_LbPolicy { * endpoint metadata and selected by route and weighted cluster metadata. * [#next-free-field: 8] */ -export interface _envoy_api_v2_Cluster_LbSubsetConfig { +export interface _envoy_config_cluster_v3_Cluster_LbSubsetConfig { /** * The behavior used when no endpoint subset matches the selected route's * metadata. The value defaults to - * :ref:`NO_FALLBACK`. + * :ref:`NO_FALLBACK`. */ - 'fallback_policy'?: (_envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy | keyof typeof _envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy); + 'fallback_policy'?: (_envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy | keyof typeof _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy); /** * Specifies the default subset of endpoints used during fallback if * fallback_policy is - * :ref:`DEFAULT_SUBSET`. + * :ref:`DEFAULT_SUBSET`. * Each field in default_subset is * compared to the matching LbEndpoint.Metadata under the *envoy.lb* * namespace. It is valid for no hosts to match, in which case the behavior * is the same as a fallback_policy of - * :ref:`NO_FALLBACK`. + * :ref:`NO_FALLBACK`. */ 'default_subset'?: (_google_protobuf_Struct); /** @@ -434,7 +437,7 @@ export interface _envoy_api_v2_Cluster_LbSubsetConfig { * weighted cluster contains the same keys and values as the subset's * metadata. The same host may appear in multiple subsets. */ - 'subset_selectors'?: (_envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector)[]; + 'subset_selectors'?: (_envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector)[]; /** * If true, routing to subsets will take into account the localities and locality weights of the * endpoints when making the routing decision. @@ -477,22 +480,22 @@ export interface _envoy_api_v2_Cluster_LbSubsetConfig { * endpoint metadata and selected by route and weighted cluster metadata. * [#next-free-field: 8] */ -export interface _envoy_api_v2_Cluster_LbSubsetConfig__Output { +export interface _envoy_config_cluster_v3_Cluster_LbSubsetConfig__Output { /** * The behavior used when no endpoint subset matches the selected route's * metadata. The value defaults to - * :ref:`NO_FALLBACK`. + * :ref:`NO_FALLBACK`. */ - 'fallback_policy': (keyof typeof _envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy); + 'fallback_policy': (keyof typeof _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy); /** * Specifies the default subset of endpoints used during fallback if * fallback_policy is - * :ref:`DEFAULT_SUBSET`. + * :ref:`DEFAULT_SUBSET`. * Each field in default_subset is * compared to the matching LbEndpoint.Metadata under the *envoy.lb* * namespace. It is valid for no hosts to match, in which case the behavior * is the same as a fallback_policy of - * :ref:`NO_FALLBACK`. + * :ref:`NO_FALLBACK`. */ 'default_subset'?: (_google_protobuf_Struct__Output); /** @@ -511,7 +514,7 @@ export interface _envoy_api_v2_Cluster_LbSubsetConfig__Output { * weighted cluster contains the same keys and values as the subset's * metadata. The same host may appear in multiple subsets. */ - 'subset_selectors': (_envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector__Output)[]; + 'subset_selectors': (_envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector__Output)[]; /** * If true, routing to subsets will take into account the localities and locality weights of the * endpoints when making the routing decision. @@ -549,7 +552,7 @@ export interface _envoy_api_v2_Cluster_LbSubsetConfig__Output { 'list_as_any': (boolean); } -// Original file: deps/envoy-api/envoy/api/v2/cluster.proto +// Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto /** * If NO_FALLBACK is selected, a result @@ -558,7 +561,7 @@ export interface _envoy_api_v2_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_api_v2_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy { +export enum _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy { NO_FALLBACK = 0, ANY_ENDPOINT = 1, DEFAULT_SUBSET = 2, @@ -567,25 +570,40 @@ export enum _envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy { /** * Specifications for subsets. */ -export interface _envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector { +export interface _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector { /** * List of keys to match with the weighted cluster metadata. */ 'keys'?: (string)[]; + /** + * Selects a mode of operation in which each subset has only one host. This mode uses the same rules for + * choosing a host, but updating hosts is faster, especially for large numbers of hosts. + * + * If a match is found to a host, that host will be used regardless of priority levels, unless the host is unhealthy. + * + * Currently, this mode is only supported if `subset_selectors` has only one entry, and `keys` contains + * only one entry. + * + * When this mode is enabled, configurations that contain more than one host with the same metadata value for the single key in `keys` + * will use only one of the hosts with the given key; no requests will be routed to the others. The cluster gauge + * :ref:`lb_subsets_single_host_per_subset_duplicate` indicates how many duplicates are + * present in the current configuration. + */ + 'single_host_per_subset'?: (boolean); /** * The behavior used when no endpoint subset matches the selected route's * metadata. */ - 'fallback_policy'?: (_envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy | keyof typeof _envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy); + 'fallback_policy'?: (_envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy | keyof typeof _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy); /** * Subset of - * :ref:`keys` used by - * :ref:`KEYS_SUBSET` + * :ref:`keys` used by + * :ref:`KEYS_SUBSET` * fallback policy. * It has to be a non empty list if KEYS_SUBSET fallback policy is selected. * For any other fallback policy the parameter is not used and should not be set. * Only values also present in - * :ref:`keys` are allowed, but + * :ref:`keys` are allowed, but * `fallback_keys_subset` cannot be equal to `keys`. */ 'fallback_keys_subset'?: (string)[]; @@ -594,36 +612,51 @@ export interface _envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector { /** * Specifications for subsets. */ -export interface _envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector__Output { +export interface _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector__Output { /** * List of keys to match with the weighted cluster metadata. */ 'keys': (string)[]; + /** + * Selects a mode of operation in which each subset has only one host. This mode uses the same rules for + * choosing a host, but updating hosts is faster, especially for large numbers of hosts. + * + * If a match is found to a host, that host will be used regardless of priority levels, unless the host is unhealthy. + * + * Currently, this mode is only supported if `subset_selectors` has only one entry, and `keys` contains + * only one entry. + * + * When this mode is enabled, configurations that contain more than one host with the same metadata value for the single key in `keys` + * will use only one of the hosts with the given key; no requests will be routed to the others. The cluster gauge + * :ref:`lb_subsets_single_host_per_subset_duplicate` indicates how many duplicates are + * present in the current configuration. + */ + 'single_host_per_subset': (boolean); /** * The behavior used when no endpoint subset matches the selected route's * metadata. */ - 'fallback_policy': (keyof typeof _envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy); + 'fallback_policy': (keyof typeof _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy); /** * Subset of - * :ref:`keys` used by - * :ref:`KEYS_SUBSET` + * :ref:`keys` used by + * :ref:`KEYS_SUBSET` * fallback policy. * It has to be a non empty list if KEYS_SUBSET fallback policy is selected. * For any other fallback policy the parameter is not used and should not be set. * Only values also present in - * :ref:`keys` are allowed, but + * :ref:`keys` are allowed, but * `fallback_keys_subset` cannot be equal to `keys`. */ 'fallback_keys_subset': (string)[]; } -// Original file: deps/envoy-api/envoy/api/v2/cluster.proto +// Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto /** * Allows to override top level fallback policy per selector. */ -export enum _envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy { +export enum _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy { /** * If NOT_DEFINED top level config fallback policy is used instead. */ @@ -645,7 +678,7 @@ export enum _envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelect /** * If KEYS_SUBSET is selected, subset selector matching is performed again with metadata * keys reduced to - * :ref:`fallback_keys_subset`. + * :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. */ @@ -655,37 +688,117 @@ export enum _envoy_api_v2_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelect /** * Specific configuration for the LeastRequest load balancing policy. */ -export interface _envoy_api_v2_Cluster_LeastRequestLbConfig { +export interface _envoy_config_cluster_v3_Cluster_LeastRequestLbConfig { /** * The number of random healthy hosts from which the host with the fewest active requests will * be chosen. Defaults to 2 so that we perform two-choice selection if the field is not set. */ 'choice_count'?: (_google_protobuf_UInt32Value); + /** + * The following formula is used to calculate the dynamic weights when hosts have different load + * balancing weights: + * + * `weight = load_balancing_weight / (active_requests + 1)^active_request_bias` + * + * The larger the active request bias is, the more aggressively active requests will lower the + * effective weight when all host weights are not equal. + * + * `active_request_bias` must be greater than or equal to 0.0. + * + * When `active_request_bias == 0.0` the Least Request Load Balancer doesn't consider the number + * of active requests at the time it picks a host and behaves like the Round Robin Load + * Balancer. + * + * When `active_request_bias > 0.0` the Least Request Load Balancer scales the load balancing + * weight by the number of active requests at the time it does a pick. + * + * The value is cached for performance reasons and refreshed whenever one of the Load Balancer's + * host sets changes, e.g., whenever there is a host membership update or a host load balancing + * weight change. + * + * .. note:: + * This setting only takes effect if all host weights are not equal. + */ + 'active_request_bias'?: (_envoy_config_core_v3_RuntimeDouble); } /** * Specific configuration for the LeastRequest load balancing policy. */ -export interface _envoy_api_v2_Cluster_LeastRequestLbConfig__Output { +export interface _envoy_config_cluster_v3_Cluster_LeastRequestLbConfig__Output { /** * The number of random healthy hosts from which the host with the fewest active requests will * be chosen. Defaults to 2 so that we perform two-choice selection if the field is not set. */ 'choice_count'?: (_google_protobuf_UInt32Value__Output); + /** + * The following formula is used to calculate the dynamic weights when hosts have different load + * balancing weights: + * + * `weight = load_balancing_weight / (active_requests + 1)^active_request_bias` + * + * The larger the active request bias is, the more aggressively active requests will lower the + * effective weight when all host weights are not equal. + * + * `active_request_bias` must be greater than or equal to 0.0. + * + * When `active_request_bias == 0.0` the Least Request Load Balancer doesn't consider the number + * of active requests at the time it picks a host and behaves like the Round Robin Load + * Balancer. + * + * When `active_request_bias > 0.0` the Least Request Load Balancer scales the load balancing + * weight by the number of active requests at the time it does a pick. + * + * The value is cached for performance reasons and refreshed whenever one of the Load Balancer's + * host sets changes, e.g., whenever there is a host membership update or a host load balancing + * weight change. + * + * .. note:: + * This setting only takes effect if all host weights are not equal. + */ + 'active_request_bias'?: (_envoy_config_core_v3_RuntimeDouble__Output); } /** * Configuration for :ref:`locality weighted load balancing * ` */ -export interface _envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig { +export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig { } /** * Configuration for :ref:`locality weighted load balancing * ` */ -export interface _envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig__Output { +export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig__Output { +} + +/** + * Specific configuration for the :ref:`Maglev` + * load balancing policy. + */ +export interface _envoy_config_cluster_v3_Cluster_MaglevLbConfig { + /** + * The table size for Maglev hashing. The Maglev aims for ‘minimal disruption’ rather than an absolute guarantee. + * Minimal disruption means that when the set of upstreams changes, a connection will likely be sent to the same + * upstream as it was before. Increasing the table size reduces the amount of disruption. + * The table size must be prime number. If it is not specified, the default is 65537. + */ + 'table_size'?: (_google_protobuf_UInt64Value); +} + +/** + * Specific configuration for the :ref:`Maglev` + * load balancing policy. + */ +export interface _envoy_config_cluster_v3_Cluster_MaglevLbConfig__Output { + /** + * The table size for Maglev hashing. The Maglev aims for ‘minimal disruption’ rather than an absolute guarantee. + * Minimal disruption means that when the set of upstreams changes, a connection will likely be sent to the same + * upstream as it was before. Increasing the table size reduces the amount of disruption. + * The table size must be prime number. If it is not specified, the default is 65537. + */ + 'table_size'?: (_google_protobuf_UInt64Value__Output); } /** @@ -693,7 +806,7 @@ export interface _envoy_api_v2_Cluster_CommonLbConfig_LocalityWeightedLbConfig__ * :ref:`Original Destination ` * load balancing policy. */ -export interface _envoy_api_v2_Cluster_OriginalDstLbConfig { +export interface _envoy_config_cluster_v3_Cluster_OriginalDstLbConfig { /** * When true, :ref:`x-envoy-original-dst-host * ` can be used to override destination @@ -704,6 +817,10 @@ export interface _envoy_api_v2_Cluster_OriginalDstLbConfig { * This header isn't sanitized by default, so enabling this feature allows HTTP clients to * route traffic to arbitrary hosts and/or ports, which may have serious security * consequences. + * + * .. note:: + * + * If the header appears multiple times only the first value is used. */ 'use_http_header'?: (boolean); } @@ -713,7 +830,7 @@ export interface _envoy_api_v2_Cluster_OriginalDstLbConfig { * :ref:`Original Destination ` * load balancing policy. */ -export interface _envoy_api_v2_Cluster_OriginalDstLbConfig__Output { +export interface _envoy_config_cluster_v3_Cluster_OriginalDstLbConfig__Output { /** * When true, :ref:`x-envoy-original-dst-host * ` can be used to override destination @@ -724,38 +841,152 @@ export interface _envoy_api_v2_Cluster_OriginalDstLbConfig__Output { * This header isn't sanitized by default, so enabling this feature allows HTTP clients to * route traffic to arbitrary hosts and/or ports, which may have serious security * consequences. + * + * .. note:: + * + * If the header appears multiple times only the first value is used. */ 'use_http_header': (boolean); } -export interface _envoy_api_v2_Cluster_RefreshRate { +export interface _envoy_config_cluster_v3_Cluster_PreconnectPolicy { + /** + * Indicates how many streams (rounded up) can be anticipated per-upstream for each + * incoming stream. This is useful for high-QPS or latency-sensitive services. Preconnecting + * will only be done if the upstream is healthy and the cluster has traffic. + * + * For example if this is 2, for an incoming HTTP/1.1 stream, 2 connections will be + * established, one for the new incoming stream, and one for a presumed follow-up stream. For + * HTTP/2, only one connection would be established by default as one connection can + * serve both the original and presumed follow-up stream. + * + * In steady state for non-multiplexed connections a value of 1.5 would mean if there were 100 + * active streams, there would be 100 connections in use, and 50 connections preconnected. + * This might be a useful value for something like short lived single-use connections, + * for example proxying HTTP/1.1 if keep-alive were false and each stream resulted in connection + * termination. It would likely be overkill for long lived connections, such as TCP proxying SMTP + * or regular HTTP/1.1 with keep-alive. For long lived traffic, a value of 1.05 would be more + * reasonable, where for every 100 connections, 5 preconnected connections would be in the queue + * in case of unexpected disconnects where the connection could not be reused. + * + * If this value is not set, or set explicitly to one, Envoy will fetch as many connections + * as needed to serve streams in flight. This means in steady state if a connection is torn down, + * a subsequent streams will pay an upstream-rtt latency penalty waiting for a new connection. + * + * This is limited somewhat arbitrarily to 3 because preconnecting too aggressively can + * harm latency more than the preconnecting helps. + */ + 'per_upstream_preconnect_ratio'?: (_google_protobuf_DoubleValue); + /** + * Indicates how many many streams (rounded up) can be anticipated across a cluster for each + * stream, useful for low QPS services. This is currently supported for a subset of + * deterministic non-hash-based load-balancing algorithms (weighted round robin, random). + * Unlike *per_upstream_preconnect_ratio* this preconnects across the upstream instances in a + * cluster, doing best effort predictions of what upstream would be picked next and + * pre-establishing a connection. + * + * Preconnecting will be limited to one preconnect per configured upstream in the cluster and will + * only be done if there are healthy upstreams and the cluster has traffic. + * + * For example if preconnecting is set to 2 for a round robin HTTP/2 cluster, on the first + * incoming stream, 2 connections will be preconnected - one to the first upstream for this + * cluster, one to the second on the assumption there will be a follow-up stream. + * + * If this value is not set, or set explicitly to one, Envoy will fetch as many connections + * as needed to serve streams in flight, so during warm up and in steady state if a connection + * is closed (and per_upstream_preconnect_ratio is not set), there will be a latency hit for + * connection establishment. + * + * If both this and preconnect_ratio are set, Envoy will make sure both predicted needs are met, + * basically preconnecting max(predictive-preconnect, per-upstream-preconnect), for each + * upstream. + */ + 'predictive_preconnect_ratio'?: (_google_protobuf_DoubleValue); +} + +export interface _envoy_config_cluster_v3_Cluster_PreconnectPolicy__Output { + /** + * Indicates how many streams (rounded up) can be anticipated per-upstream for each + * incoming stream. This is useful for high-QPS or latency-sensitive services. Preconnecting + * will only be done if the upstream is healthy and the cluster has traffic. + * + * For example if this is 2, for an incoming HTTP/1.1 stream, 2 connections will be + * established, one for the new incoming stream, and one for a presumed follow-up stream. For + * HTTP/2, only one connection would be established by default as one connection can + * serve both the original and presumed follow-up stream. + * + * In steady state for non-multiplexed connections a value of 1.5 would mean if there were 100 + * active streams, there would be 100 connections in use, and 50 connections preconnected. + * This might be a useful value for something like short lived single-use connections, + * for example proxying HTTP/1.1 if keep-alive were false and each stream resulted in connection + * termination. It would likely be overkill for long lived connections, such as TCP proxying SMTP + * or regular HTTP/1.1 with keep-alive. For long lived traffic, a value of 1.05 would be more + * reasonable, where for every 100 connections, 5 preconnected connections would be in the queue + * in case of unexpected disconnects where the connection could not be reused. + * + * If this value is not set, or set explicitly to one, Envoy will fetch as many connections + * as needed to serve streams in flight. This means in steady state if a connection is torn down, + * a subsequent streams will pay an upstream-rtt latency penalty waiting for a new connection. + * + * This is limited somewhat arbitrarily to 3 because preconnecting too aggressively can + * harm latency more than the preconnecting helps. + */ + 'per_upstream_preconnect_ratio'?: (_google_protobuf_DoubleValue__Output); + /** + * Indicates how many many streams (rounded up) can be anticipated across a cluster for each + * stream, useful for low QPS services. This is currently supported for a subset of + * deterministic non-hash-based load-balancing algorithms (weighted round robin, random). + * Unlike *per_upstream_preconnect_ratio* this preconnects across the upstream instances in a + * cluster, doing best effort predictions of what upstream would be picked next and + * pre-establishing a connection. + * + * Preconnecting will be limited to one preconnect per configured upstream in the cluster and will + * only be done if there are healthy upstreams and the cluster has traffic. + * + * For example if preconnecting is set to 2 for a round robin HTTP/2 cluster, on the first + * incoming stream, 2 connections will be preconnected - one to the first upstream for this + * cluster, one to the second on the assumption there will be a follow-up stream. + * + * If this value is not set, or set explicitly to one, Envoy will fetch as many connections + * as needed to serve streams in flight, so during warm up and in steady state if a connection + * is closed (and per_upstream_preconnect_ratio is not set), there will be a latency hit for + * connection establishment. + * + * If both this and preconnect_ratio are set, Envoy will make sure both predicted needs are met, + * basically preconnecting max(predictive-preconnect, per-upstream-preconnect), for each + * upstream. + */ + 'predictive_preconnect_ratio'?: (_google_protobuf_DoubleValue__Output); +} + +export interface _envoy_config_cluster_v3_Cluster_RefreshRate { /** * Specifies the base interval between refreshes. This parameter is required and must be greater * than zero and less than - * :ref:`max_interval `. + * :ref:`max_interval `. */ 'base_interval'?: (_google_protobuf_Duration); /** * Specifies the maximum interval between refreshes. This parameter is optional, but must be * greater than or equal to the - * :ref:`base_interval ` if set. The default - * is 10 times the :ref:`base_interval `. + * :ref:`base_interval ` if set. The default + * is 10 times the :ref:`base_interval `. */ 'max_interval'?: (_google_protobuf_Duration); } -export interface _envoy_api_v2_Cluster_RefreshRate__Output { +export interface _envoy_config_cluster_v3_Cluster_RefreshRate__Output { /** * Specifies the base interval between refreshes. This parameter is required and must be greater * than zero and less than - * :ref:`max_interval `. + * :ref:`max_interval `. */ 'base_interval'?: (_google_protobuf_Duration__Output); /** * Specifies the maximum interval between refreshes. This parameter is optional, but must be * greater than or equal to the - * :ref:`base_interval ` if set. The default - * is 10 times the :ref:`base_interval `. + * :ref:`base_interval ` if set. The default + * is 10 times the :ref:`base_interval `. */ 'max_interval'?: (_google_protobuf_Duration__Output); } @@ -764,23 +995,23 @@ export interface _envoy_api_v2_Cluster_RefreshRate__Output { * Specific configuration for the :ref:`RingHash` * load balancing policy. */ -export interface _envoy_api_v2_Cluster_RingHashLbConfig { +export interface _envoy_config_cluster_v3_Cluster_RingHashLbConfig { /** * 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 * to 1024 entries, and limited to 8M entries. See also - * :ref:`maximum_ring_size`. + * :ref:`maximum_ring_size`. */ 'minimum_ring_size'?: (_google_protobuf_UInt64Value); /** * The hash function used to hash hosts onto the ketama ring. The value defaults to - * :ref:`XX_HASH`. + * :ref:`XX_HASH`. */ - 'hash_function'?: (_envoy_api_v2_Cluster_RingHashLbConfig_HashFunction | keyof typeof _envoy_api_v2_Cluster_RingHashLbConfig_HashFunction); + 'hash_function'?: (_envoy_config_cluster_v3_Cluster_RingHashLbConfig_HashFunction | keyof typeof _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 - * :ref:`minimum_ring_size`. + * :ref:`minimum_ring_size`. */ 'maximum_ring_size'?: (_google_protobuf_UInt64Value); } @@ -789,23 +1020,23 @@ export interface _envoy_api_v2_Cluster_RingHashLbConfig { * Specific configuration for the :ref:`RingHash` * load balancing policy. */ -export interface _envoy_api_v2_Cluster_RingHashLbConfig__Output { +export interface _envoy_config_cluster_v3_Cluster_RingHashLbConfig__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 * to 1024 entries, and limited to 8M entries. See also - * :ref:`maximum_ring_size`. + * :ref:`maximum_ring_size`. */ 'minimum_ring_size'?: (_google_protobuf_UInt64Value__Output); /** * The hash function used to hash hosts onto the ketama ring. The value defaults to - * :ref:`XX_HASH`. + * :ref:`XX_HASH`. */ - 'hash_function': (keyof typeof _envoy_api_v2_Cluster_RingHashLbConfig_HashFunction); + 'hash_function': (keyof typeof _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 - * :ref:`minimum_ring_size`. + * :ref:`minimum_ring_size`. */ 'maximum_ring_size'?: (_google_protobuf_UInt64Value__Output); } @@ -814,7 +1045,7 @@ export interface _envoy_api_v2_Cluster_RingHashLbConfig__Output { * TransportSocketMatch specifies what transport socket config will be used * when the match conditions are satisfied. */ -export interface _envoy_api_v2_Cluster_TransportSocketMatch { +export interface _envoy_config_cluster_v3_Cluster_TransportSocketMatch { /** * The name of the match, used in stats generation. */ @@ -830,14 +1061,14 @@ export interface _envoy_api_v2_Cluster_TransportSocketMatch { /** * The configuration of the transport socket. */ - 'transport_socket'?: (_envoy_api_v2_core_TransportSocket); + 'transport_socket'?: (_envoy_config_core_v3_TransportSocket); } /** * TransportSocketMatch specifies what transport socket config will be used * when the match conditions are satisfied. */ -export interface _envoy_api_v2_Cluster_TransportSocketMatch__Output { +export interface _envoy_config_cluster_v3_Cluster_TransportSocketMatch__Output { /** * The name of the match, used in stats generation. */ @@ -853,21 +1084,21 @@ export interface _envoy_api_v2_Cluster_TransportSocketMatch__Output { /** * The configuration of the transport socket. */ - 'transport_socket'?: (_envoy_api_v2_core_TransportSocket__Output); + 'transport_socket'?: (_envoy_config_core_v3_TransportSocket__Output); } /** * Configuration for :ref:`zone aware routing * `. */ -export interface _envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig { +export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig { /** * Configures percentage of requests that will be considered for zone aware routing * if zone aware routing is configured. If not specified, the default is 100%. * * :ref:`runtime values `. * * :ref:`Zone aware routing support `. */ - 'routing_enabled'?: (_envoy_type_Percent); + 'routing_enabled'?: (_envoy_type_v3_Percent); /** * Configures minimum upstream cluster size required for zone aware routing * If upstream cluster size is less than specified, zone aware routing is not performed @@ -889,14 +1120,14 @@ export interface _envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig { * Configuration for :ref:`zone aware routing * `. */ -export interface _envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig__Output { +export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig__Output { /** * Configures percentage of requests that will be considered for zone aware routing * if zone aware routing is configured. If not specified, the default is 100%. * * :ref:`runtime values `. * * :ref:`Zone aware routing support `. */ - 'routing_enabled'?: (_envoy_type_Percent__Output); + 'routing_enabled'?: (_envoy_type_v3_Percent__Output); /** * Configures minimum upstream cluster size required for zone aware routing * If upstream cluster size is less than specified, zone aware routing is not performed @@ -916,14 +1147,14 @@ export interface _envoy_api_v2_Cluster_CommonLbConfig_ZoneAwareLbConfig__Output /** * Configuration for a single upstream cluster. - * [#next-free-field: 48] + * [#next-free-field: 53] */ export interface Cluster { /** * Supplies the name of the cluster which must be unique across all clusters. * The cluster name is used when emitting * :ref:`statistics ` if :ref:`alt_stat_name - * ` is not provided. + * ` is not provided. * Any ``:`` in the cluster name will be converted to ``_`` when emitting statistics. */ 'name'?: (string); @@ -931,11 +1162,11 @@ export interface Cluster { * The :ref:`service discovery type ` * to use for resolving the cluster. */ - 'type'?: (_envoy_api_v2_Cluster_DiscoveryType | keyof typeof _envoy_api_v2_Cluster_DiscoveryType); + 'type'?: (_envoy_config_cluster_v3_Cluster_DiscoveryType | keyof typeof _envoy_config_cluster_v3_Cluster_DiscoveryType); /** * Configuration to use for EDS updates for the Cluster. */ - 'eds_cluster_config'?: (_envoy_api_v2_Cluster_EdsClusterConfig); + 'eds_cluster_config'?: (_envoy_config_cluster_v3_Cluster_EdsClusterConfig); /** * The timeout for new network connections to hosts in the cluster. */ @@ -948,28 +1179,16 @@ export interface Cluster { /** * The :ref:`load balancer type ` to use * when picking a host in the cluster. + * [#comment:TODO: Remove enum constraint :ref:`LOAD_BALANCING_POLICY_CONFIG` when implemented.] */ - 'lb_policy'?: (_envoy_api_v2_Cluster_LbPolicy | keyof typeof _envoy_api_v2_Cluster_LbPolicy); - /** - * If the service discovery type is - * :ref:`STATIC`, - * :ref:`STRICT_DNS` - * or :ref:`LOGICAL_DNS`, - * then hosts is required. - * - * .. attention:: - * - * **This field is deprecated**. Set the - * :ref:`load_assignment` field instead. - */ - 'hosts'?: (_envoy_api_v2_core_Address)[]; + 'lb_policy'?: (_envoy_config_cluster_v3_Cluster_LbPolicy | keyof typeof _envoy_config_cluster_v3_Cluster_LbPolicy); /** * Optional :ref:`active health checking ` * configuration for the cluster. If no * configuration is specified no health checking will be done and all cluster * members will be considered healthy at all times. */ - 'health_checks'?: (_envoy_api_v2_core_HealthCheck)[]; + 'health_checks'?: (_envoy_config_core_v3_HealthCheck)[]; /** * Optional maximum requests for a single upstream connection. This parameter * is respected by both the HTTP/1.1 and HTTP/2 connection pool @@ -980,20 +1199,18 @@ export interface Cluster { /** * Optional :ref:`circuit breaking ` for the cluster. */ - 'circuit_breakers'?: (_envoy_api_v2_cluster_CircuitBreakers); - /** - * The TLS configuration for connections to the upstream cluster. - * - * .. attention:: - * - * **This field is deprecated**. Use `transport_socket` with name `tls` instead. If both are - * set, `transport_socket` takes priority. - */ - 'tls_context'?: (_envoy_api_v2_auth_UpstreamTlsContext); + 'circuit_breakers'?: (_envoy_config_cluster_v3_CircuitBreakers); /** * Additional options when handling HTTP1 requests. + * This has been deprecated in favor of http_protocol_options fields in the in the + * :ref:`http_protocol_options ` message. + * http_protocol_options can be set via the cluster's + * :ref:`extension_protocol_options`. + * See ref:`upstream_http_protocol_options + * ` + * for example usage. */ - 'http_protocol_options'?: (_envoy_api_v2_core_Http1ProtocolOptions); + 'http_protocol_options'?: (_envoy_config_core_v3_Http1ProtocolOptions); /** * Even if default HTTP2 protocol options are desired, this field must be * set so that Envoy will assume that the upstream supports HTTP/2 when @@ -1001,48 +1218,58 @@ export interface Cluster { * supports prior knowledge for upstream connections. Even if TLS is used * with ALPN, `http2_protocol_options` must be specified. As an aside this allows HTTP/2 * connections to happen over plain text. + * This has been deprecated in favor of http2_protocol_options fields in the in the + * :ref:`http_protocol_options ` + * message. http2_protocol_options can be set via the cluster's + * :ref:`extension_protocol_options`. + * See ref:`upstream_http_protocol_options + * ` + * for example usage. */ - 'http2_protocol_options'?: (_envoy_api_v2_core_Http2ProtocolOptions); + 'http2_protocol_options'?: (_envoy_config_core_v3_Http2ProtocolOptions); /** * If the DNS refresh rate is specified and the cluster type is either - * :ref:`STRICT_DNS`, - * or :ref:`LOGICAL_DNS`, + * :ref:`STRICT_DNS`, + * or :ref:`LOGICAL_DNS`, * this value is used as the cluster’s DNS refresh * rate. The value configured must be at least 1ms. If this setting is not specified, the * value defaults to 5000ms. For cluster types other than - * :ref:`STRICT_DNS` - * and :ref:`LOGICAL_DNS` + * :ref:`STRICT_DNS` + * and :ref:`LOGICAL_DNS` * this setting is ignored. */ 'dns_refresh_rate'?: (_google_protobuf_Duration); /** * The DNS IP address resolution policy. If this setting is not specified, the * value defaults to - * :ref:`AUTO`. + * :ref:`AUTO`. */ - 'dns_lookup_family'?: (_envoy_api_v2_Cluster_DnsLookupFamily | keyof typeof _envoy_api_v2_Cluster_DnsLookupFamily); + 'dns_lookup_family'?: (_envoy_config_cluster_v3_Cluster_DnsLookupFamily | keyof typeof _envoy_config_cluster_v3_Cluster_DnsLookupFamily); /** * If DNS resolvers are specified and the cluster type is either - * :ref:`STRICT_DNS`, - * or :ref:`LOGICAL_DNS`, + * :ref:`STRICT_DNS`, + * or :ref:`LOGICAL_DNS`, * this value is used to specify the cluster’s dns resolvers. * If this setting is not specified, the value defaults to the default * resolver, which uses /etc/resolv.conf for configuration. For cluster types * other than - * :ref:`STRICT_DNS` - * and :ref:`LOGICAL_DNS` + * :ref:`STRICT_DNS` + * and :ref:`LOGICAL_DNS` * this setting is ignored. + * Setting this value causes failure if the + * ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during + * server startup. Apple's API only allows overriding DNS resolvers via system settings. */ - 'dns_resolvers'?: (_envoy_api_v2_core_Address)[]; + 'dns_resolvers'?: (_envoy_config_core_v3_Address)[]; /** * If specified, outlier detection will be enabled for this upstream cluster. * Each of the configuration values can be overridden via * :ref:`runtime values `. */ - 'outlier_detection'?: (_envoy_api_v2_cluster_OutlierDetection); + 'outlier_detection'?: (_envoy_config_cluster_v3_OutlierDetection); /** * The interval for removing stale hosts from a cluster type - * :ref:`ORIGINAL_DST`. + * :ref:`ORIGINAL_DST`. * Hosts are considered stale if they have not been used * as upstream destinations during this interval. New hosts are added * to original destination clusters on demand as new connections are @@ -1052,7 +1279,7 @@ export interface Cluster { * them remain open, saving the latency that would otherwise be spent * on opening new connections. If this setting is not specified, the * value defaults to 5000ms. For cluster types other than - * :ref:`ORIGINAL_DST` + * :ref:`ORIGINAL_DST` * this setting is ignored. */ 'cleanup_interval'?: (_google_protobuf_Duration); @@ -1061,23 +1288,23 @@ export interface Cluster { * This overrides any bind_config specified in the bootstrap proto. * If the address and port are empty, no bind will be performed. */ - 'upstream_bind_config'?: (_envoy_api_v2_core_BindConfig); + 'upstream_bind_config'?: (_envoy_config_core_v3_BindConfig); /** * Configuration for load balancing subsetting. */ - 'lb_subset_config'?: (_envoy_api_v2_Cluster_LbSubsetConfig); + 'lb_subset_config'?: (_envoy_config_cluster_v3_Cluster_LbSubsetConfig); /** * Optional configuration for the Ring Hash load balancing policy. */ - 'ring_hash_lb_config'?: (_envoy_api_v2_Cluster_RingHashLbConfig); + 'ring_hash_lb_config'?: (_envoy_config_cluster_v3_Cluster_RingHashLbConfig); /** * Optional custom transport socket implementation to use for upstream connections. * To setup TLS, set a transport socket with name `tls` and - * :ref:`UpstreamTlsContexts ` in the `typed_config`. + * :ref:`UpstreamTlsContexts ` in the `typed_config`. * If no transport socket configuration is specified, new connections * will be set up with plaintext. */ - 'transport_socket'?: (_envoy_api_v2_core_TransportSocket); + 'transport_socket'?: (_envoy_config_core_v3_TransportSocket); /** * The Metadata field can be used to provide additional information about the * cluster. It can be used for stats, logging, and varying filter behavior. @@ -1085,15 +1312,20 @@ export interface Cluster { * will need the information. For instance, if the metadata is intended for * the Router filter, the filter name should be specified as *envoy.filters.http.router*. */ - 'metadata'?: (_envoy_api_v2_core_Metadata); + 'metadata'?: (_envoy_config_core_v3_Metadata); /** * Determines how Envoy selects the protocol used to speak to upstream hosts. + * This has been deprecated in favor of setting explicit protocol selection + * in the :ref:`http_protocol_options + * ` message. + * http_protocol_options can be set via the cluster's + * :ref:`extension_protocol_options`. */ - 'protocol_selection'?: (_envoy_api_v2_Cluster_ClusterProtocolSelection | keyof typeof _envoy_api_v2_Cluster_ClusterProtocolSelection); + 'protocol_selection'?: (_envoy_config_cluster_v3_Cluster_ClusterProtocolSelection | keyof typeof _envoy_config_cluster_v3_Cluster_ClusterProtocolSelection); /** * Common configuration for all load balancer implementations. */ - 'common_lb_config'?: (_envoy_api_v2_Cluster_CommonLbConfig); + 'common_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig); /** * An optional alternative to the cluster name to be used while emitting stats. * Any ``:`` in the name will be converted to ``_`` when emitting statistics. This should not be @@ -1104,12 +1336,20 @@ export interface Cluster { /** * Additional options when handling HTTP requests upstream. These options will be applicable to * both HTTP1 and HTTP2 requests. + * This has been deprecated in favor of + * :ref:`common_http_protocol_options ` + * in the :ref:`http_protocol_options ` message. + * common_http_protocol_options can be set via the cluster's + * :ref:`extension_protocol_options`. + * See ref:`upstream_http_protocol_options + * ` + * for example usage. */ - 'common_http_protocol_options'?: (_envoy_api_v2_core_HttpProtocolOptions); + 'common_http_protocol_options'?: (_envoy_config_core_v3_HttpProtocolOptions); /** * Optional options for upstream connections. */ - 'upstream_connection_options'?: (_envoy_api_v2_UpstreamConnectionOptions); + 'upstream_connection_options'?: (_envoy_config_cluster_v3_UpstreamConnectionOptions); /** * If an upstream host becomes unhealthy (as determined by the configured health checks * or outlier detection), immediately close all connections to the failed host. @@ -1131,46 +1371,40 @@ export interface Cluster { * from service discovery. This means that if active health checking is used, Envoy will *not* * wait for the endpoint to go unhealthy before removing it. */ - 'drain_connections_on_host_removal'?: (boolean); + 'ignore_health_on_host_removal'?: (boolean); /** * Setting this is required for specifying members of - * :ref:`STATIC`, - * :ref:`STRICT_DNS` - * or :ref:`LOGICAL_DNS` clusters. + * :ref:`STATIC`, + * :ref:`STRICT_DNS` + * or :ref:`LOGICAL_DNS` clusters. * This field supersedes the *hosts* field in the v2 API. * * .. attention:: * * Setting this allows non-EDS cluster types to contain embedded EDS equivalent - * :ref:`endpoint assignments`. + * :ref:`endpoint assignments`. */ - 'load_assignment'?: (_envoy_api_v2_ClusterLoadAssignment); + 'load_assignment'?: (_envoy_config_endpoint_v3_ClusterLoadAssignment); /** * Optional configuration for the Original Destination load balancing policy. */ - 'original_dst_lb_config'?: (_envoy_api_v2_Cluster_OriginalDstLbConfig); - /** - * The extension_protocol_options field is used to provide extension-specific protocol options - * for upstream connections. The key should match the extension filter name, such as - * "envoy.filters.network.thrift_proxy". See the extension's documentation for details on - * specific options. - */ - 'extension_protocol_options'?: ({[key: string]: _google_protobuf_Struct}); + 'original_dst_lb_config'?: (_envoy_config_cluster_v3_Cluster_OriginalDstLbConfig); /** * The extension_protocol_options field is used to provide extension-specific protocol options * for upstream connections. The key should match the extension filter name, such as * "envoy.filters.network.thrift_proxy". See the extension's documentation for details on * specific options. + * [#next-major-version: make this a list of typed extensions.] */ 'typed_extension_protocol_options'?: ({[key: string]: _google_protobuf_Any}); /** * Optional configuration for the LeastRequest load balancing policy. */ - 'least_request_lb_config'?: (_envoy_api_v2_Cluster_LeastRequestLbConfig); + 'least_request_lb_config'?: (_envoy_config_cluster_v3_Cluster_LeastRequestLbConfig); /** * The custom cluster type. */ - 'cluster_type'?: (_envoy_api_v2_Cluster_CustomClusterType); + 'cluster_type'?: (_envoy_config_cluster_v3_Cluster_CustomClusterType); /** * Optional configuration for setting cluster's DNS refresh rate. If the value is set to true, * cluster's DNS refresh rate will be set to resource record's TTL which comes from DNS @@ -1182,13 +1416,13 @@ export interface Cluster { * The chain will be applied to all outgoing connections that Envoy makes to the upstream * servers of this cluster. */ - 'filters'?: (_envoy_api_v2_cluster_Filter)[]; + 'filters'?: (_envoy_config_cluster_v3_Filter)[]; /** * [#not-implemented-hide:] New mechanism for LB policy configuration. Used only if the - * :ref:`lb_policy` field has the value - * :ref:`LOAD_BALANCING_POLICY_CONFIG`. + * :ref:`lb_policy` field has the value + * :ref:`LOAD_BALANCING_POLICY_CONFIG`. */ - 'load_balancing_policy'?: (_envoy_api_v2_LoadBalancingPolicy); + 'load_balancing_policy'?: (_envoy_config_cluster_v3_LoadBalancingPolicy); /** * [#not-implemented-hide:] * If present, tells the client where to send load reports via LRS. If not present, the @@ -1205,13 +1439,13 @@ export interface Cluster { * maybe by allowing LRS to go on the ADS stream, or maybe by moving some of the negotiation * from the LRS stream here.] */ - 'lrs_server'?: (_envoy_api_v2_core_ConfigSource); + 'lrs_server'?: (_envoy_config_core_v3_ConfigSource); /** * Configuration to use different transport sockets for different endpoints. * The entry of *envoy.transport_socket_match* in the - * :ref:`LbEndpoint.Metadata ` + * :ref:`LbEndpoint.Metadata ` * is used to match against the transport sockets as they appear in the list. The first - * :ref:`match ` is used. + * :ref:`match ` is used. * For example, with the following match * * .. code-block:: yaml @@ -1231,7 +1465,7 @@ export interface Cluster { * Connections to the endpoints whose metadata value under *envoy.transport_socket_match* * having "acceptMTLS"/"true" key/value pair use the "enableMTLS" socket configuration. * - * If a :ref:`socket match ` with empty match + * If a :ref:`socket match ` with empty match * criteria is provided, that always match any endpoint. For example, the "defaultToPlaintext" * socket match in case above. * @@ -1251,61 +1485,119 @@ export interface Cluster { * *TransportSocketMatch* in this field. Other client Envoys receive CDS without * *transport_socket_match* set, and still send plain text traffic to the same cluster. * + * This field can be used to specify custom transport socket configurations for health + * checks by adding matching key/value pairs in a health check's + * :ref:`transport socket match criteria ` field. + * * [#comment:TODO(incfly): add a detailed architecture doc on intended usage.] */ - 'transport_socket_matches'?: (_envoy_api_v2_Cluster_TransportSocketMatch)[]; + 'transport_socket_matches'?: (_envoy_config_cluster_v3_Cluster_TransportSocketMatch)[]; /** * If the DNS failure refresh rate is specified and the cluster type is either - * :ref:`STRICT_DNS`, - * or :ref:`LOGICAL_DNS`, + * :ref:`STRICT_DNS`, + * or :ref:`LOGICAL_DNS`, * this is used as the cluster’s DNS refresh rate when requests are failing. If this setting is * not specified, the failure refresh rate defaults to the DNS refresh rate. For cluster types - * other than :ref:`STRICT_DNS` and - * :ref:`LOGICAL_DNS` this setting is + * other than :ref:`STRICT_DNS` and + * :ref:`LOGICAL_DNS` this setting is * ignored. */ - 'dns_failure_refresh_rate'?: (_envoy_api_v2_Cluster_RefreshRate); + 'dns_failure_refresh_rate'?: (_envoy_config_cluster_v3_Cluster_RefreshRate); /** * [#next-major-version: Reconcile DNS options in a single message.] * Always use TCP queries instead of UDP queries for DNS lookups. + * 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. */ 'use_tcp_for_dns_lookups'?: (boolean); /** * HTTP protocol options that are applied only to upstream HTTP connections. * These options apply to all HTTP versions. + * This has been deprecated in favor of + * :ref:`upstream_http_protocol_options ` + * in the :ref:`http_protocol_options ` message. + * upstream_http_protocol_options can be set via the cluster's + * :ref:`extension_protocol_options`. + * See ref:`upstream_http_protocol_options + * ` + * for example usage. */ - 'upstream_http_protocol_options'?: (_envoy_api_v2_core_UpstreamHttpProtocolOptions); + 'upstream_http_protocol_options'?: (_envoy_config_core_v3_UpstreamHttpProtocolOptions); /** * If track_timeout_budgets is true, the :ref:`timeout budget histograms * ` will be published for each * request. These show what percentage of a request's per try and global timeout was used. A value * of 0 would indicate that none of the timeout was used or that the timeout was infinite. A value * of 100 would indicate that the request took the entirety of the timeout given to it. + * + * .. attention:: + * + * This field has been deprecated in favor of `timeout_budgets`, part of + * :ref:`track_cluster_stats `. */ 'track_timeout_budgets'?: (boolean); + /** + * Optional customization and configuration of upstream connection pool, and upstream type. + * + * Currently this field only applies for HTTP traffic but is designed for eventual use for custom + * TCP upstreams. + * + * For HTTP traffic, Envoy will generally take downstream HTTP and send it upstream as upstream + * HTTP, using the http connection pool and the codec from `http2_protocol_options` + * + * For routes where CONNECT termination is configured, Envoy will take downstream CONNECT + * requests and forward the CONNECT payload upstream over raw TCP using the tcp connection pool. + * + * The default pool used is the generic connection pool which creates the HTTP upstream for most + * HTTP requests, and the TCP upstream if CONNECT termination is configured. + * + * If users desire custom connection pool or upstream behavior, for example terminating + * CONNECT only if a custom filter indicates it is appropriate, the custom factories + * can be registered and configured here. + */ + 'upstream_config'?: (_envoy_config_core_v3_TypedExtensionConfig); + /** + * Configuration to track optional cluster stats. + */ + 'track_cluster_stats'?: (_envoy_config_cluster_v3_TrackClusterStats); + /** + * Preconnect configuration for this cluster. + */ + 'preconnect_policy'?: (_envoy_config_cluster_v3_Cluster_PreconnectPolicy); + /** + * If `connection_pool_per_downstream_connection` is true, the cluster will use a separate + * connection pool for every downstream connection + */ + 'connection_pool_per_downstream_connection'?: (boolean); + /** + * Optional configuration for the Maglev load balancing policy. + */ + 'maglev_lb_config'?: (_envoy_config_cluster_v3_Cluster_MaglevLbConfig); 'cluster_discovery_type'?: "type"|"cluster_type"; /** * Optional configuration for the load balancing algorithm selected by * LbPolicy. Currently only - * :ref:`RING_HASH` and - * :ref:`LEAST_REQUEST` + * :ref:`RING_HASH`, + * :ref:`MAGLEV` and + * :ref:`LEAST_REQUEST` * has additional configuration options. - * Specifying ring_hash_lb_config or least_request_lb_config without setting the corresponding + * Specifying ring_hash_lb_config or maglev_lb_config or least_request_lb_config without setting the corresponding * LbPolicy will generate an error at runtime. */ - 'lb_config'?: "ring_hash_lb_config"|"original_dst_lb_config"|"least_request_lb_config"; + 'lb_config'?: "ring_hash_lb_config"|"maglev_lb_config"|"original_dst_lb_config"|"least_request_lb_config"; } /** * Configuration for a single upstream cluster. - * [#next-free-field: 48] + * [#next-free-field: 53] */ export interface Cluster__Output { /** * Supplies the name of the cluster which must be unique across all clusters. * The cluster name is used when emitting * :ref:`statistics ` if :ref:`alt_stat_name - * ` is not provided. + * ` is not provided. * Any ``:`` in the cluster name will be converted to ``_`` when emitting statistics. */ 'name': (string); @@ -1313,11 +1605,11 @@ export interface Cluster__Output { * The :ref:`service discovery type ` * to use for resolving the cluster. */ - 'type'?: (keyof typeof _envoy_api_v2_Cluster_DiscoveryType); + 'type'?: (keyof typeof _envoy_config_cluster_v3_Cluster_DiscoveryType); /** * Configuration to use for EDS updates for the Cluster. */ - 'eds_cluster_config'?: (_envoy_api_v2_Cluster_EdsClusterConfig__Output); + 'eds_cluster_config'?: (_envoy_config_cluster_v3_Cluster_EdsClusterConfig__Output); /** * The timeout for new network connections to hosts in the cluster. */ @@ -1330,28 +1622,16 @@ export interface Cluster__Output { /** * The :ref:`load balancer type ` to use * when picking a host in the cluster. + * [#comment:TODO: Remove enum constraint :ref:`LOAD_BALANCING_POLICY_CONFIG` when implemented.] */ - 'lb_policy': (keyof typeof _envoy_api_v2_Cluster_LbPolicy); - /** - * If the service discovery type is - * :ref:`STATIC`, - * :ref:`STRICT_DNS` - * or :ref:`LOGICAL_DNS`, - * then hosts is required. - * - * .. attention:: - * - * **This field is deprecated**. Set the - * :ref:`load_assignment` field instead. - */ - 'hosts': (_envoy_api_v2_core_Address__Output)[]; + 'lb_policy': (keyof typeof _envoy_config_cluster_v3_Cluster_LbPolicy); /** * Optional :ref:`active health checking ` * configuration for the cluster. If no * configuration is specified no health checking will be done and all cluster * members will be considered healthy at all times. */ - 'health_checks': (_envoy_api_v2_core_HealthCheck__Output)[]; + 'health_checks': (_envoy_config_core_v3_HealthCheck__Output)[]; /** * Optional maximum requests for a single upstream connection. This parameter * is respected by both the HTTP/1.1 and HTTP/2 connection pool @@ -1362,20 +1642,18 @@ export interface Cluster__Output { /** * Optional :ref:`circuit breaking ` for the cluster. */ - 'circuit_breakers'?: (_envoy_api_v2_cluster_CircuitBreakers__Output); - /** - * The TLS configuration for connections to the upstream cluster. - * - * .. attention:: - * - * **This field is deprecated**. Use `transport_socket` with name `tls` instead. If both are - * set, `transport_socket` takes priority. - */ - 'tls_context'?: (_envoy_api_v2_auth_UpstreamTlsContext__Output); + 'circuit_breakers'?: (_envoy_config_cluster_v3_CircuitBreakers__Output); /** * Additional options when handling HTTP1 requests. + * This has been deprecated in favor of http_protocol_options fields in the in the + * :ref:`http_protocol_options ` message. + * http_protocol_options can be set via the cluster's + * :ref:`extension_protocol_options`. + * See ref:`upstream_http_protocol_options + * ` + * for example usage. */ - 'http_protocol_options'?: (_envoy_api_v2_core_Http1ProtocolOptions__Output); + 'http_protocol_options'?: (_envoy_config_core_v3_Http1ProtocolOptions__Output); /** * Even if default HTTP2 protocol options are desired, this field must be * set so that Envoy will assume that the upstream supports HTTP/2 when @@ -1383,48 +1661,58 @@ export interface Cluster__Output { * supports prior knowledge for upstream connections. Even if TLS is used * with ALPN, `http2_protocol_options` must be specified. As an aside this allows HTTP/2 * connections to happen over plain text. + * This has been deprecated in favor of http2_protocol_options fields in the in the + * :ref:`http_protocol_options ` + * message. http2_protocol_options can be set via the cluster's + * :ref:`extension_protocol_options`. + * See ref:`upstream_http_protocol_options + * ` + * for example usage. */ - 'http2_protocol_options'?: (_envoy_api_v2_core_Http2ProtocolOptions__Output); + 'http2_protocol_options'?: (_envoy_config_core_v3_Http2ProtocolOptions__Output); /** * If the DNS refresh rate is specified and the cluster type is either - * :ref:`STRICT_DNS`, - * or :ref:`LOGICAL_DNS`, + * :ref:`STRICT_DNS`, + * or :ref:`LOGICAL_DNS`, * this value is used as the cluster’s DNS refresh * rate. The value configured must be at least 1ms. If this setting is not specified, the * value defaults to 5000ms. For cluster types other than - * :ref:`STRICT_DNS` - * and :ref:`LOGICAL_DNS` + * :ref:`STRICT_DNS` + * and :ref:`LOGICAL_DNS` * this setting is ignored. */ 'dns_refresh_rate'?: (_google_protobuf_Duration__Output); /** * The DNS IP address resolution policy. If this setting is not specified, the * value defaults to - * :ref:`AUTO`. + * :ref:`AUTO`. */ - 'dns_lookup_family': (keyof typeof _envoy_api_v2_Cluster_DnsLookupFamily); + 'dns_lookup_family': (keyof typeof _envoy_config_cluster_v3_Cluster_DnsLookupFamily); /** * If DNS resolvers are specified and the cluster type is either - * :ref:`STRICT_DNS`, - * or :ref:`LOGICAL_DNS`, + * :ref:`STRICT_DNS`, + * or :ref:`LOGICAL_DNS`, * this value is used to specify the cluster’s dns resolvers. * If this setting is not specified, the value defaults to the default * resolver, which uses /etc/resolv.conf for configuration. For cluster types * other than - * :ref:`STRICT_DNS` - * and :ref:`LOGICAL_DNS` + * :ref:`STRICT_DNS` + * and :ref:`LOGICAL_DNS` * this setting is ignored. + * Setting this value causes failure if the + * ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during + * server startup. Apple's API only allows overriding DNS resolvers via system settings. */ - 'dns_resolvers': (_envoy_api_v2_core_Address__Output)[]; + 'dns_resolvers': (_envoy_config_core_v3_Address__Output)[]; /** * If specified, outlier detection will be enabled for this upstream cluster. * Each of the configuration values can be overridden via * :ref:`runtime values `. */ - 'outlier_detection'?: (_envoy_api_v2_cluster_OutlierDetection__Output); + 'outlier_detection'?: (_envoy_config_cluster_v3_OutlierDetection__Output); /** * The interval for removing stale hosts from a cluster type - * :ref:`ORIGINAL_DST`. + * :ref:`ORIGINAL_DST`. * Hosts are considered stale if they have not been used * as upstream destinations during this interval. New hosts are added * to original destination clusters on demand as new connections are @@ -1434,7 +1722,7 @@ export interface Cluster__Output { * them remain open, saving the latency that would otherwise be spent * on opening new connections. If this setting is not specified, the * value defaults to 5000ms. For cluster types other than - * :ref:`ORIGINAL_DST` + * :ref:`ORIGINAL_DST` * this setting is ignored. */ 'cleanup_interval'?: (_google_protobuf_Duration__Output); @@ -1443,23 +1731,23 @@ export interface Cluster__Output { * This overrides any bind_config specified in the bootstrap proto. * If the address and port are empty, no bind will be performed. */ - 'upstream_bind_config'?: (_envoy_api_v2_core_BindConfig__Output); + 'upstream_bind_config'?: (_envoy_config_core_v3_BindConfig__Output); /** * Configuration for load balancing subsetting. */ - 'lb_subset_config'?: (_envoy_api_v2_Cluster_LbSubsetConfig__Output); + 'lb_subset_config'?: (_envoy_config_cluster_v3_Cluster_LbSubsetConfig__Output); /** * Optional configuration for the Ring Hash load balancing policy. */ - 'ring_hash_lb_config'?: (_envoy_api_v2_Cluster_RingHashLbConfig__Output); + 'ring_hash_lb_config'?: (_envoy_config_cluster_v3_Cluster_RingHashLbConfig__Output); /** * Optional custom transport socket implementation to use for upstream connections. * To setup TLS, set a transport socket with name `tls` and - * :ref:`UpstreamTlsContexts ` in the `typed_config`. + * :ref:`UpstreamTlsContexts ` in the `typed_config`. * If no transport socket configuration is specified, new connections * will be set up with plaintext. */ - 'transport_socket'?: (_envoy_api_v2_core_TransportSocket__Output); + 'transport_socket'?: (_envoy_config_core_v3_TransportSocket__Output); /** * The Metadata field can be used to provide additional information about the * cluster. It can be used for stats, logging, and varying filter behavior. @@ -1467,15 +1755,20 @@ export interface Cluster__Output { * will need the information. For instance, if the metadata is intended for * the Router filter, the filter name should be specified as *envoy.filters.http.router*. */ - 'metadata'?: (_envoy_api_v2_core_Metadata__Output); + 'metadata'?: (_envoy_config_core_v3_Metadata__Output); /** * Determines how Envoy selects the protocol used to speak to upstream hosts. + * This has been deprecated in favor of setting explicit protocol selection + * in the :ref:`http_protocol_options + * ` message. + * http_protocol_options can be set via the cluster's + * :ref:`extension_protocol_options`. */ - 'protocol_selection': (keyof typeof _envoy_api_v2_Cluster_ClusterProtocolSelection); + 'protocol_selection': (keyof typeof _envoy_config_cluster_v3_Cluster_ClusterProtocolSelection); /** * Common configuration for all load balancer implementations. */ - 'common_lb_config'?: (_envoy_api_v2_Cluster_CommonLbConfig__Output); + 'common_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig__Output); /** * An optional alternative to the cluster name to be used while emitting stats. * Any ``:`` in the name will be converted to ``_`` when emitting statistics. This should not be @@ -1486,12 +1779,20 @@ export interface Cluster__Output { /** * Additional options when handling HTTP requests upstream. These options will be applicable to * both HTTP1 and HTTP2 requests. + * This has been deprecated in favor of + * :ref:`common_http_protocol_options ` + * in the :ref:`http_protocol_options ` message. + * common_http_protocol_options can be set via the cluster's + * :ref:`extension_protocol_options`. + * See ref:`upstream_http_protocol_options + * ` + * for example usage. */ - 'common_http_protocol_options'?: (_envoy_api_v2_core_HttpProtocolOptions__Output); + 'common_http_protocol_options'?: (_envoy_config_core_v3_HttpProtocolOptions__Output); /** * Optional options for upstream connections. */ - 'upstream_connection_options'?: (_envoy_api_v2_UpstreamConnectionOptions__Output); + 'upstream_connection_options'?: (_envoy_config_cluster_v3_UpstreamConnectionOptions__Output); /** * If an upstream host becomes unhealthy (as determined by the configured health checks * or outlier detection), immediately close all connections to the failed host. @@ -1513,46 +1814,40 @@ export interface Cluster__Output { * from service discovery. This means that if active health checking is used, Envoy will *not* * wait for the endpoint to go unhealthy before removing it. */ - 'drain_connections_on_host_removal': (boolean); + 'ignore_health_on_host_removal': (boolean); /** * Setting this is required for specifying members of - * :ref:`STATIC`, - * :ref:`STRICT_DNS` - * or :ref:`LOGICAL_DNS` clusters. + * :ref:`STATIC`, + * :ref:`STRICT_DNS` + * or :ref:`LOGICAL_DNS` clusters. * This field supersedes the *hosts* field in the v2 API. * * .. attention:: * * Setting this allows non-EDS cluster types to contain embedded EDS equivalent - * :ref:`endpoint assignments`. + * :ref:`endpoint assignments`. */ - 'load_assignment'?: (_envoy_api_v2_ClusterLoadAssignment__Output); + 'load_assignment'?: (_envoy_config_endpoint_v3_ClusterLoadAssignment__Output); /** * Optional configuration for the Original Destination load balancing policy. */ - 'original_dst_lb_config'?: (_envoy_api_v2_Cluster_OriginalDstLbConfig__Output); - /** - * The extension_protocol_options field is used to provide extension-specific protocol options - * for upstream connections. The key should match the extension filter name, such as - * "envoy.filters.network.thrift_proxy". See the extension's documentation for details on - * specific options. - */ - 'extension_protocol_options'?: ({[key: string]: _google_protobuf_Struct__Output}); + 'original_dst_lb_config'?: (_envoy_config_cluster_v3_Cluster_OriginalDstLbConfig__Output); /** * The extension_protocol_options field is used to provide extension-specific protocol options * for upstream connections. The key should match the extension filter name, such as * "envoy.filters.network.thrift_proxy". See the extension's documentation for details on * specific options. + * [#next-major-version: make this a list of typed extensions.] */ 'typed_extension_protocol_options'?: ({[key: string]: _google_protobuf_Any__Output}); /** * Optional configuration for the LeastRequest load balancing policy. */ - 'least_request_lb_config'?: (_envoy_api_v2_Cluster_LeastRequestLbConfig__Output); + 'least_request_lb_config'?: (_envoy_config_cluster_v3_Cluster_LeastRequestLbConfig__Output); /** * The custom cluster type. */ - 'cluster_type'?: (_envoy_api_v2_Cluster_CustomClusterType__Output); + 'cluster_type'?: (_envoy_config_cluster_v3_Cluster_CustomClusterType__Output); /** * Optional configuration for setting cluster's DNS refresh rate. If the value is set to true, * cluster's DNS refresh rate will be set to resource record's TTL which comes from DNS @@ -1564,13 +1859,13 @@ export interface Cluster__Output { * The chain will be applied to all outgoing connections that Envoy makes to the upstream * servers of this cluster. */ - 'filters': (_envoy_api_v2_cluster_Filter__Output)[]; + 'filters': (_envoy_config_cluster_v3_Filter__Output)[]; /** * [#not-implemented-hide:] New mechanism for LB policy configuration. Used only if the - * :ref:`lb_policy` field has the value - * :ref:`LOAD_BALANCING_POLICY_CONFIG`. + * :ref:`lb_policy` field has the value + * :ref:`LOAD_BALANCING_POLICY_CONFIG`. */ - 'load_balancing_policy'?: (_envoy_api_v2_LoadBalancingPolicy__Output); + 'load_balancing_policy'?: (_envoy_config_cluster_v3_LoadBalancingPolicy__Output); /** * [#not-implemented-hide:] * If present, tells the client where to send load reports via LRS. If not present, the @@ -1587,13 +1882,13 @@ export interface Cluster__Output { * maybe by allowing LRS to go on the ADS stream, or maybe by moving some of the negotiation * from the LRS stream here.] */ - 'lrs_server'?: (_envoy_api_v2_core_ConfigSource__Output); + 'lrs_server'?: (_envoy_config_core_v3_ConfigSource__Output); /** * Configuration to use different transport sockets for different endpoints. * The entry of *envoy.transport_socket_match* in the - * :ref:`LbEndpoint.Metadata ` + * :ref:`LbEndpoint.Metadata ` * is used to match against the transport sockets as they appear in the list. The first - * :ref:`match ` is used. + * :ref:`match ` is used. * For example, with the following match * * .. code-block:: yaml @@ -1613,7 +1908,7 @@ export interface Cluster__Output { * Connections to the endpoints whose metadata value under *envoy.transport_socket_match* * having "acceptMTLS"/"true" key/value pair use the "enableMTLS" socket configuration. * - * If a :ref:`socket match ` with empty match + * If a :ref:`socket match ` with empty match * criteria is provided, that always match any endpoint. For example, the "defaultToPlaintext" * socket match in case above. * @@ -1633,47 +1928,105 @@ export interface Cluster__Output { * *TransportSocketMatch* in this field. Other client Envoys receive CDS without * *transport_socket_match* set, and still send plain text traffic to the same cluster. * + * This field can be used to specify custom transport socket configurations for health + * checks by adding matching key/value pairs in a health check's + * :ref:`transport socket match criteria ` field. + * * [#comment:TODO(incfly): add a detailed architecture doc on intended usage.] */ - 'transport_socket_matches': (_envoy_api_v2_Cluster_TransportSocketMatch__Output)[]; + 'transport_socket_matches': (_envoy_config_cluster_v3_Cluster_TransportSocketMatch__Output)[]; /** * If the DNS failure refresh rate is specified and the cluster type is either - * :ref:`STRICT_DNS`, - * or :ref:`LOGICAL_DNS`, + * :ref:`STRICT_DNS`, + * or :ref:`LOGICAL_DNS`, * this is used as the cluster’s DNS refresh rate when requests are failing. If this setting is * not specified, the failure refresh rate defaults to the DNS refresh rate. For cluster types - * other than :ref:`STRICT_DNS` and - * :ref:`LOGICAL_DNS` this setting is + * other than :ref:`STRICT_DNS` and + * :ref:`LOGICAL_DNS` this setting is * ignored. */ - 'dns_failure_refresh_rate'?: (_envoy_api_v2_Cluster_RefreshRate__Output); + 'dns_failure_refresh_rate'?: (_envoy_config_cluster_v3_Cluster_RefreshRate__Output); /** * [#next-major-version: Reconcile DNS options in a single message.] * Always use TCP queries instead of UDP queries for DNS lookups. + * 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. */ 'use_tcp_for_dns_lookups': (boolean); /** * HTTP protocol options that are applied only to upstream HTTP connections. * These options apply to all HTTP versions. + * This has been deprecated in favor of + * :ref:`upstream_http_protocol_options ` + * in the :ref:`http_protocol_options ` message. + * upstream_http_protocol_options can be set via the cluster's + * :ref:`extension_protocol_options`. + * See ref:`upstream_http_protocol_options + * ` + * for example usage. */ - 'upstream_http_protocol_options'?: (_envoy_api_v2_core_UpstreamHttpProtocolOptions__Output); + 'upstream_http_protocol_options'?: (_envoy_config_core_v3_UpstreamHttpProtocolOptions__Output); /** * If track_timeout_budgets is true, the :ref:`timeout budget histograms * ` will be published for each * request. These show what percentage of a request's per try and global timeout was used. A value * of 0 would indicate that none of the timeout was used or that the timeout was infinite. A value * of 100 would indicate that the request took the entirety of the timeout given to it. + * + * .. attention:: + * + * This field has been deprecated in favor of `timeout_budgets`, part of + * :ref:`track_cluster_stats `. */ 'track_timeout_budgets': (boolean); + /** + * Optional customization and configuration of upstream connection pool, and upstream type. + * + * Currently this field only applies for HTTP traffic but is designed for eventual use for custom + * TCP upstreams. + * + * For HTTP traffic, Envoy will generally take downstream HTTP and send it upstream as upstream + * HTTP, using the http connection pool and the codec from `http2_protocol_options` + * + * For routes where CONNECT termination is configured, Envoy will take downstream CONNECT + * requests and forward the CONNECT payload upstream over raw TCP using the tcp connection pool. + * + * The default pool used is the generic connection pool which creates the HTTP upstream for most + * HTTP requests, and the TCP upstream if CONNECT termination is configured. + * + * If users desire custom connection pool or upstream behavior, for example terminating + * CONNECT only if a custom filter indicates it is appropriate, the custom factories + * can be registered and configured here. + */ + 'upstream_config'?: (_envoy_config_core_v3_TypedExtensionConfig__Output); + /** + * Configuration to track optional cluster stats. + */ + 'track_cluster_stats'?: (_envoy_config_cluster_v3_TrackClusterStats__Output); + /** + * Preconnect configuration for this cluster. + */ + 'preconnect_policy'?: (_envoy_config_cluster_v3_Cluster_PreconnectPolicy__Output); + /** + * If `connection_pool_per_downstream_connection` is true, the cluster will use a separate + * connection pool for every downstream connection + */ + 'connection_pool_per_downstream_connection': (boolean); + /** + * Optional configuration for the Maglev load balancing policy. + */ + 'maglev_lb_config'?: (_envoy_config_cluster_v3_Cluster_MaglevLbConfig__Output); 'cluster_discovery_type': "type"|"cluster_type"; /** * Optional configuration for the load balancing algorithm selected by * LbPolicy. Currently only - * :ref:`RING_HASH` and - * :ref:`LEAST_REQUEST` + * :ref:`RING_HASH`, + * :ref:`MAGLEV` and + * :ref:`LEAST_REQUEST` * has additional configuration options. - * Specifying ring_hash_lb_config or least_request_lb_config without setting the corresponding + * Specifying ring_hash_lb_config or maglev_lb_config or least_request_lb_config without setting the corresponding * LbPolicy will generate an error at runtime. */ - 'lb_config': "ring_hash_lb_config"|"original_dst_lb_config"|"least_request_lb_config"; + 'lb_config': "ring_hash_lb_config"|"maglev_lb_config"|"original_dst_lb_config"|"least_request_lb_config"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/ClusterCollection.ts b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/ClusterCollection.ts new file mode 100644 index 000000000..aab9c6281 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/ClusterCollection.ts @@ -0,0 +1,19 @@ +// Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto + +import type { CollectionEntry as _xds_core_v3_CollectionEntry, CollectionEntry__Output as _xds_core_v3_CollectionEntry__Output } from '../../../../xds/core/v3/CollectionEntry'; + +/** + * Cluster list collections. Entries are *Cluster* resources or references. + * [#not-implemented-hide:] + */ +export interface ClusterCollection { + 'entries'?: (_xds_core_v3_CollectionEntry); +} + +/** + * Cluster list collections. Entries are *Cluster* resources or references. + * [#not-implemented-hide:] + */ +export interface ClusterCollection__Output { + 'entries'?: (_xds_core_v3_CollectionEntry__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/cluster/Filter.ts b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/Filter.ts similarity index 92% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/cluster/Filter.ts rename to packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/Filter.ts index 5608fadf2..53feedb98 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/cluster/Filter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/Filter.ts @@ -1,4 +1,4 @@ -// Original file: deps/envoy-api/envoy/api/v2/cluster/filter.proto +// Original file: deps/envoy-api/envoy/config/cluster/v3/filter.proto import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/LoadBalancingPolicy.ts b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/LoadBalancingPolicy.ts similarity index 80% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/LoadBalancingPolicy.ts rename to packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/LoadBalancingPolicy.ts index f79112a1c..29e343218 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/LoadBalancingPolicy.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/LoadBalancingPolicy.ts @@ -1,31 +1,20 @@ -// Original file: deps/envoy-api/envoy/api/v2/cluster.proto +// Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../google/protobuf/Struct'; -import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any'; +import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; -export interface _envoy_api_v2_LoadBalancingPolicy_Policy { +export interface _envoy_config_cluster_v3_LoadBalancingPolicy_Policy { /** * Required. The name of the LB policy. */ 'name'?: (string); - /** - * Optional config for the LB policy. - * No more than one of these two fields may be populated. - */ - 'config'?: (_google_protobuf_Struct); 'typed_config'?: (_google_protobuf_Any); } -export interface _envoy_api_v2_LoadBalancingPolicy_Policy__Output { +export interface _envoy_config_cluster_v3_LoadBalancingPolicy_Policy__Output { /** * Required. The name of the LB policy. */ 'name': (string); - /** - * Optional config for the LB policy. - * No more than one of these two fields may be populated. - */ - 'config'?: (_google_protobuf_Struct__Output); 'typed_config'?: (_google_protobuf_Any__Output); } @@ -56,7 +45,7 @@ export interface LoadBalancingPolicy { * supports. This provides a mechanism for starting to use new LB policies that are not yet * supported by all clients. */ - 'policies'?: (_envoy_api_v2_LoadBalancingPolicy_Policy)[]; + 'policies'?: (_envoy_config_cluster_v3_LoadBalancingPolicy_Policy)[]; } /** @@ -86,5 +75,5 @@ export interface LoadBalancingPolicy__Output { * supports. This provides a mechanism for starting to use new LB policies that are not yet * supported by all clients. */ - 'policies': (_envoy_api_v2_LoadBalancingPolicy_Policy__Output)[]; + 'policies': (_envoy_config_cluster_v3_LoadBalancingPolicy_Policy__Output)[]; } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/cluster/OutlierDetection.ts b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/OutlierDetection.ts similarity index 85% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/cluster/OutlierDetection.ts rename to packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/OutlierDetection.ts index 53c1b4609..f37001691 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/cluster/OutlierDetection.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/OutlierDetection.ts @@ -1,4 +1,4 @@ -// Original file: deps/envoy-api/envoy/api/v2/cluster/outlier_detection.proto +// Original file: deps/envoy-api/envoy/config/cluster/v3/outlier_detection.proto import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; @@ -6,7 +6,7 @@ import type { Duration as _google_protobuf_Duration, Duration__Output as _google /** * See the :ref:`architecture overview ` for * more information on outlier detection. - * [#next-free-field: 21] + * [#next-free-field: 22] */ export interface OutlierDetection { /** @@ -23,7 +23,8 @@ export interface OutlierDetection { 'interval'?: (_google_protobuf_Duration); /** * The base time that a host is ejected for. The real time is equal to the - * base time multiplied by the number of times the host has been ejected. + * base time multiplied by the number of times the host has been ejected and is + * capped by :ref:`max_ejection_time`. * Defaults to 30000ms or 30s. */ 'base_ejection_time'?: (_google_protobuf_Duration); @@ -83,17 +84,17 @@ export interface OutlierDetection { /** * Determines whether to distinguish local origin failures from external errors. If set to true * the following configuration parameters are taken into account: - * :ref:`consecutive_local_origin_failure`, - * :ref:`enforcing_consecutive_local_origin_failure` + * :ref:`consecutive_local_origin_failure`, + * :ref:`enforcing_consecutive_local_origin_failure` * and - * :ref:`enforcing_local_origin_success_rate`. + * :ref:`enforcing_local_origin_success_rate`. * Defaults to false. */ 'split_external_local_origin_errors'?: (boolean); /** * The number of consecutive locally originated failures before ejection * occurs. Defaults to 5. Parameter takes effect only when - * :ref:`split_external_local_origin_errors` + * :ref:`split_external_local_origin_errors` * is set to true. */ 'consecutive_local_origin_failure'?: (_google_protobuf_UInt32Value); @@ -102,7 +103,7 @@ export interface OutlierDetection { * is detected through consecutive locally originated failures. This setting can be * used to disable ejection or to ramp it up slowly. Defaults to 100. * Parameter takes effect only when - * :ref:`split_external_local_origin_errors` + * :ref:`split_external_local_origin_errors` * is set to true. */ 'enforcing_consecutive_local_origin_failure'?: (_google_protobuf_UInt32Value); @@ -111,7 +112,7 @@ export interface OutlierDetection { * is detected through success rate statistics for locally originated errors. * This setting can be used to disable ejection or to ramp it up slowly. Defaults to 100. * Parameter takes effect only when - * :ref:`split_external_local_origin_errors` + * :ref:`split_external_local_origin_errors` * is set to true. */ 'enforcing_local_origin_success_rate'?: (_google_protobuf_UInt32Value); @@ -149,12 +150,18 @@ export interface OutlierDetection { * this host. Defaults to 50. */ 'failure_percentage_request_volume'?: (_google_protobuf_UInt32Value); + /** + * The maximum time that a host is ejected for. See :ref:`base_ejection_time` + * for more information. + * Defaults to 300000ms or 300s. + */ + 'max_ejection_time'?: (_google_protobuf_Duration); } /** * See the :ref:`architecture overview ` for * more information on outlier detection. - * [#next-free-field: 21] + * [#next-free-field: 22] */ export interface OutlierDetection__Output { /** @@ -171,7 +178,8 @@ export interface OutlierDetection__Output { 'interval'?: (_google_protobuf_Duration__Output); /** * The base time that a host is ejected for. The real time is equal to the - * base time multiplied by the number of times the host has been ejected. + * base time multiplied by the number of times the host has been ejected and is + * capped by :ref:`max_ejection_time`. * Defaults to 30000ms or 30s. */ 'base_ejection_time'?: (_google_protobuf_Duration__Output); @@ -231,17 +239,17 @@ export interface OutlierDetection__Output { /** * Determines whether to distinguish local origin failures from external errors. If set to true * the following configuration parameters are taken into account: - * :ref:`consecutive_local_origin_failure`, - * :ref:`enforcing_consecutive_local_origin_failure` + * :ref:`consecutive_local_origin_failure`, + * :ref:`enforcing_consecutive_local_origin_failure` * and - * :ref:`enforcing_local_origin_success_rate`. + * :ref:`enforcing_local_origin_success_rate`. * Defaults to false. */ 'split_external_local_origin_errors': (boolean); /** * The number of consecutive locally originated failures before ejection * occurs. Defaults to 5. Parameter takes effect only when - * :ref:`split_external_local_origin_errors` + * :ref:`split_external_local_origin_errors` * is set to true. */ 'consecutive_local_origin_failure'?: (_google_protobuf_UInt32Value__Output); @@ -250,7 +258,7 @@ export interface OutlierDetection__Output { * is detected through consecutive locally originated failures. This setting can be * used to disable ejection or to ramp it up slowly. Defaults to 100. * Parameter takes effect only when - * :ref:`split_external_local_origin_errors` + * :ref:`split_external_local_origin_errors` * is set to true. */ 'enforcing_consecutive_local_origin_failure'?: (_google_protobuf_UInt32Value__Output); @@ -259,7 +267,7 @@ export interface OutlierDetection__Output { * is detected through success rate statistics for locally originated errors. * This setting can be used to disable ejection or to ramp it up slowly. Defaults to 100. * Parameter takes effect only when - * :ref:`split_external_local_origin_errors` + * :ref:`split_external_local_origin_errors` * is set to true. */ 'enforcing_local_origin_success_rate'?: (_google_protobuf_UInt32Value__Output); @@ -297,4 +305,10 @@ export interface OutlierDetection__Output { * this host. Defaults to 50. */ 'failure_percentage_request_volume'?: (_google_protobuf_UInt32Value__Output); + /** + * The maximum time that a host is ejected for. See :ref:`base_ejection_time` + * for more information. + * Defaults to 300000ms or 300s. + */ + 'max_ejection_time'?: (_google_protobuf_Duration__Output); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/TrackClusterStats.ts b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/TrackClusterStats.ts new file mode 100644 index 000000000..a65d1fd8d --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/TrackClusterStats.ts @@ -0,0 +1,36 @@ +// Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto + + +export interface TrackClusterStats { + /** + * If timeout_budgets is true, the :ref:`timeout budget histograms + * ` will be published for each + * request. These show what percentage of a request's per try and global timeout was used. A value + * of 0 would indicate that none of the timeout was used or that the timeout was infinite. A value + * of 100 would indicate that the request took the entirety of the timeout given to it. + */ + 'timeout_budgets'?: (boolean); + /** + * If request_response_sizes is true, then the :ref:`histograms + * ` tracking header and body sizes + * of requests and responses will be published. + */ + 'request_response_sizes'?: (boolean); +} + +export interface TrackClusterStats__Output { + /** + * If timeout_budgets is true, the :ref:`timeout budget histograms + * ` will be published for each + * request. These show what percentage of a request's per try and global timeout was used. A value + * of 0 would indicate that none of the timeout was used or that the timeout was infinite. A value + * of 100 would indicate that the request took the entirety of the timeout given to it. + */ + 'timeout_budgets': (boolean); + /** + * If request_response_sizes is true, then the :ref:`histograms + * ` tracking header and body sizes + * of requests and responses will be published. + */ + 'request_response_sizes': (boolean); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/UpstreamBindConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/UpstreamBindConfig.ts similarity index 59% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/UpstreamBindConfig.ts rename to packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/UpstreamBindConfig.ts index 966ccca85..0f95c0816 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/UpstreamBindConfig.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/UpstreamBindConfig.ts @@ -1,6 +1,6 @@ -// Original file: deps/envoy-api/envoy/api/v2/cluster.proto +// Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto -import type { Address as _envoy_api_v2_core_Address, Address__Output as _envoy_api_v2_core_Address__Output } from '../../../envoy/api/v2/core/Address'; +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 @@ -10,7 +10,7 @@ export interface UpstreamBindConfig { /** * The address Envoy should bind to when establishing upstream connections. */ - 'source_address'?: (_envoy_api_v2_core_Address); + 'source_address'?: (_envoy_config_core_v3_Address); } /** @@ -21,5 +21,5 @@ export interface UpstreamBindConfig__Output { /** * The address Envoy should bind to when establishing upstream connections. */ - 'source_address'?: (_envoy_api_v2_core_Address__Output); + 'source_address'?: (_envoy_config_core_v3_Address__Output); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/UpstreamConnectionOptions.ts b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/UpstreamConnectionOptions.ts new file mode 100644 index 000000000..2e7f23894 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/UpstreamConnectionOptions.ts @@ -0,0 +1,17 @@ +// Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto + +import type { TcpKeepalive as _envoy_config_core_v3_TcpKeepalive, TcpKeepalive__Output as _envoy_config_core_v3_TcpKeepalive__Output } from '../../../../envoy/config/core/v3/TcpKeepalive'; + +export interface UpstreamConnectionOptions { + /** + * If set then set SO_KEEPALIVE on the socket to enable TCP Keepalives. + */ + 'tcp_keepalive'?: (_envoy_config_core_v3_TcpKeepalive); +} + +export interface UpstreamConnectionOptions__Output { + /** + * If set then set SO_KEEPALIVE on the socket to enable TCP Keepalives. + */ + 'tcp_keepalive'?: (_envoy_config_core_v3_TcpKeepalive__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Address.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Address.ts new file mode 100644 index 000000000..4d5881baf --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Address.ts @@ -0,0 +1,35 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/address.proto + +import type { SocketAddress as _envoy_config_core_v3_SocketAddress, SocketAddress__Output as _envoy_config_core_v3_SocketAddress__Output } from '../../../../envoy/config/core/v3/SocketAddress'; +import type { Pipe as _envoy_config_core_v3_Pipe, Pipe__Output as _envoy_config_core_v3_Pipe__Output } from '../../../../envoy/config/core/v3/Pipe'; +import type { EnvoyInternalAddress as _envoy_config_core_v3_EnvoyInternalAddress, EnvoyInternalAddress__Output as _envoy_config_core_v3_EnvoyInternalAddress__Output } from '../../../../envoy/config/core/v3/EnvoyInternalAddress'; + +/** + * Addresses specify either a logical or physical address and port, which are + * used to tell Envoy where to bind/listen, connect to upstream and find + * management servers. + */ +export interface Address { + 'socket_address'?: (_envoy_config_core_v3_SocketAddress); + 'pipe'?: (_envoy_config_core_v3_Pipe); + /** + * [#not-implemented-hide:] + */ + 'envoy_internal_address'?: (_envoy_config_core_v3_EnvoyInternalAddress); + 'address'?: "socket_address"|"pipe"|"envoy_internal_address"; +} + +/** + * Addresses specify either a logical or physical address and port, which are + * used to tell Envoy where to bind/listen, connect to upstream and find + * management servers. + */ +export interface Address__Output { + 'socket_address'?: (_envoy_config_core_v3_SocketAddress__Output); + 'pipe'?: (_envoy_config_core_v3_Pipe__Output); + /** + * [#not-implemented-hide:] + */ + 'envoy_internal_address'?: (_envoy_config_core_v3_EnvoyInternalAddress__Output); + 'address': "socket_address"|"pipe"|"envoy_internal_address"; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/AggregatedConfigSource.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/AggregatedConfigSource.ts similarity index 57% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/core/AggregatedConfigSource.ts rename to packages/grpc-js-xds/src/generated/envoy/config/core/v3/AggregatedConfigSource.ts index 6837dd0db..824ef93c8 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/AggregatedConfigSource.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/AggregatedConfigSource.ts @@ -1,9 +1,9 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/config_source.proto +// Original file: deps/envoy-api/envoy/config/core/v3/config_source.proto /** * Aggregated Discovery Service (ADS) options. This is currently empty, but when - * set in :ref:`ConfigSource ` can be used to + * set in :ref:`ConfigSource ` can be used to * specify that ADS is to be used. */ export interface AggregatedConfigSource { @@ -11,7 +11,7 @@ export interface AggregatedConfigSource { /** * Aggregated Discovery Service (ADS) options. This is currently empty, but when - * set in :ref:`ConfigSource ` can be used to + * set in :ref:`ConfigSource ` can be used to * specify that ADS is to be used. */ export interface AggregatedConfigSource__Output { diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/ApiConfigSource.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ApiConfigSource.ts similarity index 66% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/core/ApiConfigSource.ts rename to packages/grpc-js-xds/src/generated/envoy/config/core/v3/ApiConfigSource.ts index a99924d9b..99afe9a26 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/ApiConfigSource.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ApiConfigSource.ts @@ -1,21 +1,21 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/config_source.proto +// Original file: deps/envoy-api/envoy/config/core/v3/config_source.proto import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; -import type { GrpcService as _envoy_api_v2_core_GrpcService, GrpcService__Output as _envoy_api_v2_core_GrpcService__Output } from '../../../../envoy/api/v2/core/GrpcService'; -import type { RateLimitSettings as _envoy_api_v2_core_RateLimitSettings, RateLimitSettings__Output as _envoy_api_v2_core_RateLimitSettings__Output } from '../../../../envoy/api/v2/core/RateLimitSettings'; -import type { ApiVersion as _envoy_api_v2_core_ApiVersion } from '../../../../envoy/api/v2/core/ApiVersion'; +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'; -// Original file: deps/envoy-api/envoy/api/v2/core/config_source.proto +// Original file: deps/envoy-api/envoy/config/core/v3/config_source.proto /** * APIs may be fetched via either REST or gRPC. */ -export enum _envoy_api_v2_core_ApiConfigSource_ApiType { +export enum _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. */ - UNSUPPORTED_REST_LEGACY = 0, + DEPRECATED_AND_UNAVAILABLE_DO_NOT_USE = 0, /** * REST-JSON v2 API. The `canonical JSON encoding * `_ for @@ -23,7 +23,7 @@ export enum _envoy_api_v2_core_ApiConfigSource_ApiType { */ REST = 1, /** - * gRPC v2 API. + * SotW gRPC service. */ GRPC = 2, /** @@ -32,6 +32,18 @@ export enum _envoy_api_v2_core_ApiConfigSource_ApiType { * 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, } /** @@ -43,7 +55,7 @@ export interface ApiConfigSource { /** * API type (gRPC, REST, delta gRPC) */ - 'api_type'?: (_envoy_api_v2_core_ApiConfigSource_ApiType | keyof typeof _envoy_api_v2_core_ApiConfigSource_ApiType); + 'api_type'?: (_envoy_config_core_v3_ApiConfigSource_ApiType | keyof typeof _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 @@ -63,7 +75,7 @@ export interface ApiConfigSource { * Multiple gRPC services be provided for GRPC. If > 1 cluster is defined, * services will be cycled through if any kind of failure occurs. */ - 'grpc_services'?: (_envoy_api_v2_core_GrpcService)[]; + 'grpc_services'?: (_envoy_config_core_v3_GrpcService)[]; /** * For REST APIs, the request timeout. If not set, a default value of 1s will be used. */ @@ -72,7 +84,7 @@ export interface ApiConfigSource { * For GRPC APIs, the rate limit settings. If present, discovery requests made by Envoy will be * rate limited. */ - 'rate_limit_settings'?: (_envoy_api_v2_core_RateLimitSettings); + 'rate_limit_settings'?: (_envoy_config_core_v3_RateLimitSettings); /** * Skip the node identifier in subsequent discovery requests for streaming gRPC config types. */ @@ -81,7 +93,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_api_v2_core_ApiVersion | keyof typeof _envoy_api_v2_core_ApiVersion); + 'transport_api_version'?: (_envoy_config_core_v3_ApiVersion | keyof typeof _envoy_config_core_v3_ApiVersion); } /** @@ -93,7 +105,7 @@ export interface ApiConfigSource__Output { /** * API type (gRPC, REST, delta gRPC) */ - 'api_type': (keyof typeof _envoy_api_v2_core_ApiConfigSource_ApiType); + 'api_type': (keyof typeof _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 @@ -113,7 +125,7 @@ export interface ApiConfigSource__Output { * Multiple gRPC services be provided for GRPC. If > 1 cluster is defined, * services will be cycled through if any kind of failure occurs. */ - 'grpc_services': (_envoy_api_v2_core_GrpcService__Output)[]; + 'grpc_services': (_envoy_config_core_v3_GrpcService__Output)[]; /** * For REST APIs, the request timeout. If not set, a default value of 1s will be used. */ @@ -122,7 +134,7 @@ export interface ApiConfigSource__Output { * For GRPC APIs, the rate limit settings. If present, discovery requests made by Envoy will be * rate limited. */ - 'rate_limit_settings'?: (_envoy_api_v2_core_RateLimitSettings__Output); + 'rate_limit_settings'?: (_envoy_config_core_v3_RateLimitSettings__Output); /** * Skip the node identifier in subsequent discovery requests for streaming gRPC config types. */ @@ -131,5 +143,5 @@ 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_api_v2_core_ApiVersion); + 'transport_api_version': (keyof typeof _envoy_config_core_v3_ApiVersion); } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/ApiVersion.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ApiVersion.ts similarity index 69% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/core/ApiVersion.ts rename to packages/grpc-js-xds/src/generated/envoy/config/core/v3/ApiVersion.ts index 7f03a5995..b46f6ec43 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/ApiVersion.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ApiVersion.ts @@ -1,7 +1,7 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/config_source.proto +// Original file: deps/envoy-api/envoy/config/core/v3/config_source.proto /** - * xDS API version. This is used to describe both resource and transport + * 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 { diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/AsyncDataSource.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/AsyncDataSource.ts new file mode 100644 index 000000000..476ea851f --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/AsyncDataSource.ts @@ -0,0 +1,34 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.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 { RemoteDataSource as _envoy_config_core_v3_RemoteDataSource, RemoteDataSource__Output as _envoy_config_core_v3_RemoteDataSource__Output } from '../../../../envoy/config/core/v3/RemoteDataSource'; + +/** + * Async data source which support async data fetch. + */ +export interface AsyncDataSource { + /** + * Local async data source. + */ + 'local'?: (_envoy_config_core_v3_DataSource); + /** + * Remote async data source. + */ + 'remote'?: (_envoy_config_core_v3_RemoteDataSource); + 'specifier'?: "local"|"remote"; +} + +/** + * Async data source which support async data fetch. + */ +export interface AsyncDataSource__Output { + /** + * Local async data source. + */ + 'local'?: (_envoy_config_core_v3_DataSource__Output); + /** + * Remote async data source. + */ + 'remote'?: (_envoy_config_core_v3_RemoteDataSource__Output); + 'specifier': "local"|"remote"; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BackoffStrategy.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BackoffStrategy.ts new file mode 100644 index 000000000..9878375d6 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BackoffStrategy.ts @@ -0,0 +1,43 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/backoff.proto + +import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; + +/** + * Configuration defining a jittered exponential back off strategy. + */ +export interface BackoffStrategy { + /** + * The base interval to be used for the next back off computation. It should + * be greater than zero and less than or equal to :ref:`max_interval + * `. + */ + 'base_interval'?: (_google_protobuf_Duration); + /** + * Specifies the maximum interval between retries. This parameter is optional, + * but must be greater than or equal to the :ref:`base_interval + * ` if set. The default + * is 10 times the :ref:`base_interval + * `. + */ + 'max_interval'?: (_google_protobuf_Duration); +} + +/** + * Configuration defining a jittered exponential back off strategy. + */ +export interface BackoffStrategy__Output { + /** + * The base interval to be used for the next back off computation. It should + * be greater than zero and less than or equal to :ref:`max_interval + * `. + */ + 'base_interval'?: (_google_protobuf_Duration__Output); + /** + * Specifies the maximum interval between retries. This parameter is optional, + * but must be greater than or equal to the :ref:`base_interval + * ` if set. The default + * is 10 times the :ref:`base_interval + * `. + */ + 'max_interval'?: (_google_protobuf_Duration__Output); +} 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 new file mode 100644 index 000000000..eb2bc7626 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BindConfig.ts @@ -0,0 +1,49 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/address.proto + +import type { SocketAddress as _envoy_config_core_v3_SocketAddress, SocketAddress__Output as _envoy_config_core_v3_SocketAddress__Output } from '../../../../envoy/config/core/v3/SocketAddress'; +import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; +import type { SocketOption as _envoy_config_core_v3_SocketOption, SocketOption__Output as _envoy_config_core_v3_SocketOption__Output } from '../../../../envoy/config/core/v3/SocketOption'; + +export interface BindConfig { + /** + * The address to bind to when creating a socket. + */ + 'source_address'?: (_envoy_config_core_v3_SocketAddress); + /** + * Whether to set the *IP_FREEBIND* option when creating the socket. When this + * flag is set to true, allows the :ref:`source_address + * ` to be an IP address + * that is not configured on the system running Envoy. When this flag is set + * to false, the option *IP_FREEBIND* is disabled on the socket. When this + * flag is not set (default), the socket is not modified, i.e. the option is + * neither enabled nor disabled. + */ + 'freebind'?: (_google_protobuf_BoolValue); + /** + * Additional socket options that may not be present in Envoy source code or + * precompiled binaries. + */ + 'socket_options'?: (_envoy_config_core_v3_SocketOption)[]; +} + +export interface BindConfig__Output { + /** + * The address to bind to when creating a socket. + */ + 'source_address'?: (_envoy_config_core_v3_SocketAddress__Output); + /** + * Whether to set the *IP_FREEBIND* option when creating the socket. When this + * flag is set to true, allows the :ref:`source_address + * ` to be an IP address + * that is not configured on the system running Envoy. When this flag is set + * to false, the option *IP_FREEBIND* is disabled on the socket. When this + * flag is not set (default), the socket is not modified, i.e. the option is + * neither enabled nor disabled. + */ + 'freebind'?: (_google_protobuf_BoolValue__Output); + /** + * Additional socket options that may not be present in Envoy source code or + * precompiled binaries. + */ + 'socket_options': (_envoy_config_core_v3_SocketOption__Output)[]; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BuildVersion.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BuildVersion.ts new file mode 100644 index 000000000..a3a33e4a3 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BuildVersion.ts @@ -0,0 +1,36 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + +import type { SemanticVersion as _envoy_type_v3_SemanticVersion, SemanticVersion__Output as _envoy_type_v3_SemanticVersion__Output } from '../../../../envoy/type/v3/SemanticVersion'; +import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; + +/** + * BuildVersion combines SemVer version of extension with free-form build information + * (i.e. 'alpha', 'private-build') as a set of strings. + */ +export interface BuildVersion { + /** + * SemVer version of extension. + */ + 'version'?: (_envoy_type_v3_SemanticVersion); + /** + * Free-form build information. + * Envoy defines several well known keys in the source/common/version/version.h file + */ + 'metadata'?: (_google_protobuf_Struct); +} + +/** + * BuildVersion combines SemVer version of extension with free-form build information + * (i.e. 'alpha', 'private-build') as a set of strings. + */ +export interface BuildVersion__Output { + /** + * SemVer version of extension. + */ + 'version'?: (_envoy_type_v3_SemanticVersion__Output); + /** + * Free-form build information. + * Envoy defines several well known keys in the source/common/version/version.h file + */ + 'metadata'?: (_google_protobuf_Struct__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/CidrRange.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/CidrRange.ts new file mode 100644 index 000000000..c4a01b0da --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/CidrRange.ts @@ -0,0 +1,33 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/address.proto + +import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; + +/** + * CidrRange specifies an IP Address and a prefix length to construct + * the subnet mask for a `CIDR `_ range. + */ +export interface CidrRange { + /** + * IPv4 or IPv6 address, e.g. ``192.0.0.0`` or ``2001:db8::``. + */ + 'address_prefix'?: (string); + /** + * Length of prefix, e.g. 0, 32. + */ + 'prefix_len'?: (_google_protobuf_UInt32Value); +} + +/** + * CidrRange specifies an IP Address and a prefix length to construct + * the subnet mask for a `CIDR `_ range. + */ +export interface CidrRange__Output { + /** + * IPv4 or IPv6 address, e.g. ``192.0.0.0`` or ``2001:db8::``. + */ + 'address_prefix': (string); + /** + * Length of prefix, e.g. 0, 32. + */ + 'prefix_len'?: (_google_protobuf_UInt32Value__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/ConfigSource.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ConfigSource.ts similarity index 70% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/core/ConfigSource.ts rename to packages/grpc-js-xds/src/generated/envoy/config/core/v3/ConfigSource.ts index 766af6148..9462f4844 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/ConfigSource.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ConfigSource.ts @@ -1,24 +1,25 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/config_source.proto +// Original file: deps/envoy-api/envoy/config/core/v3/config_source.proto -import type { ApiConfigSource as _envoy_api_v2_core_ApiConfigSource, ApiConfigSource__Output as _envoy_api_v2_core_ApiConfigSource__Output } from '../../../../envoy/api/v2/core/ApiConfigSource'; -import type { AggregatedConfigSource as _envoy_api_v2_core_AggregatedConfigSource, AggregatedConfigSource__Output as _envoy_api_v2_core_AggregatedConfigSource__Output } from '../../../../envoy/api/v2/core/AggregatedConfigSource'; +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 { 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_api_v2_core_SelfConfigSource, SelfConfigSource__Output as _envoy_api_v2_core_SelfConfigSource__Output } from '../../../../envoy/api/v2/core/SelfConfigSource'; -import type { ApiVersion as _envoy_api_v2_core_ApiVersion } from '../../../../envoy/api/v2/core/ApiVersion'; +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 { Authority as _xds_core_v3_Authority, Authority__Output as _xds_core_v3_Authority__Output } from '../../../../xds/core/v3/Authority'; /** * Configuration for :ref:`listeners `, :ref:`clusters * `, :ref:`routes - * `, :ref:`endpoints + * `, :ref:`endpoints * ` etc. may either be sourced from the * filesystem or from an xDS API source. Filesystem configs are watched with * inotify for updates. - * [#next-free-field: 7] + * [#next-free-field: 8] */ export interface ConfigSource { /** * Path on the filesystem to source and watch for configuration updates. - * When sourcing configuration for :ref:`secret `, + * When sourcing configuration for :ref:`secret `, * the certificate and key files are also watched for updates. * * .. note:: @@ -35,12 +36,12 @@ export interface ConfigSource { /** * API configuration source. */ - 'api_config_source'?: (_envoy_api_v2_core_ApiConfigSource); + 'api_config_source'?: (_envoy_config_core_v3_ApiConfigSource); /** * When set, ADS will be used to fetch resources. The ADS API configuration * source in the bootstrap configuration is used. */ - 'ads'?: (_envoy_api_v2_core_AggregatedConfigSource); + 'ads'?: (_envoy_config_core_v3_AggregatedConfigSource); /** * When this timeout is specified, Envoy will wait no longer than the specified time for first * config response on this xDS subscription during the :ref:`initialization process @@ -64,29 +65,36 @@ export interface ConfigSource { * this field can implicitly mean to use the same stream in the case where the ConfigSource * is provided via ADS and the specified data can also be obtained via ADS.] */ - 'self'?: (_envoy_api_v2_core_SelfConfigSource); + 'self'?: (_envoy_config_core_v3_SelfConfigSource); /** * API version for xDS resources. This implies the type URLs that the client * will request for resources and the resource type that the client will in * turn expect to be delivered. */ - 'resource_api_version'?: (_envoy_api_v2_core_ApiVersion | keyof typeof _envoy_api_v2_core_ApiVersion); + 'resource_api_version'?: (_envoy_config_core_v3_ApiVersion | keyof typeof _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 + * association between authority name and configuration source. + * [#not-implemented-hide:] + */ + 'authorities'?: (_xds_core_v3_Authority)[]; 'config_source_specifier'?: "path"|"api_config_source"|"ads"|"self"; } /** * Configuration for :ref:`listeners `, :ref:`clusters * `, :ref:`routes - * `, :ref:`endpoints + * `, :ref:`endpoints * ` etc. may either be sourced from the * filesystem or from an xDS API source. Filesystem configs are watched with * inotify for updates. - * [#next-free-field: 7] + * [#next-free-field: 8] */ export interface ConfigSource__Output { /** * Path on the filesystem to source and watch for configuration updates. - * When sourcing configuration for :ref:`secret `, + * When sourcing configuration for :ref:`secret `, * the certificate and key files are also watched for updates. * * .. note:: @@ -103,12 +111,12 @@ export interface ConfigSource__Output { /** * API configuration source. */ - 'api_config_source'?: (_envoy_api_v2_core_ApiConfigSource__Output); + 'api_config_source'?: (_envoy_config_core_v3_ApiConfigSource__Output); /** * When set, ADS will be used to fetch resources. The ADS API configuration * source in the bootstrap configuration is used. */ - 'ads'?: (_envoy_api_v2_core_AggregatedConfigSource__Output); + 'ads'?: (_envoy_config_core_v3_AggregatedConfigSource__Output); /** * When this timeout is specified, Envoy will wait no longer than the specified time for first * config response on this xDS subscription during the :ref:`initialization process @@ -132,12 +140,19 @@ export interface ConfigSource__Output { * this field can implicitly mean to use the same stream in the case where the ConfigSource * is provided via ADS and the specified data can also be obtained via ADS.] */ - 'self'?: (_envoy_api_v2_core_SelfConfigSource__Output); + 'self'?: (_envoy_config_core_v3_SelfConfigSource__Output); /** * API version for xDS resources. This implies the type URLs that the client * will request for resources and the resource type that the client will in * turn expect to be delivered. */ - 'resource_api_version': (keyof typeof _envoy_api_v2_core_ApiVersion); + 'resource_api_version': (keyof typeof _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 + * association between authority name and configuration source. + * [#not-implemented-hide:] + */ + 'authorities': (_xds_core_v3_Authority__Output)[]; 'config_source_specifier': "path"|"api_config_source"|"ads"|"self"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ControlPlane.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ControlPlane.ts new file mode 100644 index 000000000..dc55f8042 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ControlPlane.ts @@ -0,0 +1,26 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + + +/** + * Identifies a specific ControlPlane instance that Envoy is connected to. + */ +export interface ControlPlane { + /** + * An opaque control plane identifier that uniquely identifies an instance + * of control plane. This can be used to identify which control plane instance, + * the Envoy is connected to. + */ + 'identifier'?: (string); +} + +/** + * Identifies a specific ControlPlane instance that Envoy is connected to. + */ +export interface ControlPlane__Output { + /** + * An opaque control plane identifier that uniquely identifies an instance + * of control plane. This can be used to identify which control plane instance, + * the Envoy is connected to. + */ + 'identifier': (string); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/DataSource.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/DataSource.ts new file mode 100644 index 000000000..cc29e084f --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/DataSource.ts @@ -0,0 +1,40 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + + +/** + * Data source consisting of either a file or an inline value. + */ +export interface DataSource { + /** + * Local filesystem data source. + */ + 'filename'?: (string); + /** + * Bytes inlined in the configuration. + */ + 'inline_bytes'?: (Buffer | Uint8Array | string); + /** + * String inlined in the configuration. + */ + 'inline_string'?: (string); + 'specifier'?: "filename"|"inline_bytes"|"inline_string"; +} + +/** + * Data source consisting of either a file or an inline value. + */ +export interface DataSource__Output { + /** + * Local filesystem data source. + */ + 'filename'?: (string); + /** + * Bytes inlined in the configuration. + */ + 'inline_bytes'?: (Buffer); + /** + * String inlined in the configuration. + */ + 'inline_string'?: (string); + 'specifier': "filename"|"inline_bytes"|"inline_string"; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/EnvoyInternalAddress.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/EnvoyInternalAddress.ts new file mode 100644 index 000000000..dfe6a52b4 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/EnvoyInternalAddress.ts @@ -0,0 +1,28 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/address.proto + + +/** + * [#not-implemented-hide:] The address represents an envoy internal listener. + * TODO(lambdai): Make this address available for listener and endpoint. + * TODO(asraa): When address available, remove workaround from test/server/server_fuzz_test.cc:30. + */ +export interface EnvoyInternalAddress { + /** + * [#not-implemented-hide:] The :ref:`listener name ` of the destination internal listener. + */ + 'server_listener_name'?: (string); + 'address_name_specifier'?: "server_listener_name"; +} + +/** + * [#not-implemented-hide:] The address represents an envoy internal listener. + * TODO(lambdai): Make this address available for listener and endpoint. + * TODO(asraa): When address available, remove workaround from test/server/server_fuzz_test.cc:30. + */ +export interface EnvoyInternalAddress__Output { + /** + * [#not-implemented-hide:] The :ref:`listener name ` of the destination internal listener. + */ + 'server_listener_name'?: (string); + 'address_name_specifier': "server_listener_name"; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/EventServiceConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/EventServiceConfig.ts similarity index 58% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/core/EventServiceConfig.ts rename to packages/grpc-js-xds/src/generated/envoy/config/core/v3/EventServiceConfig.ts index d0637578c..72aedc6ab 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/EventServiceConfig.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/EventServiceConfig.ts @@ -1,6 +1,6 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/event_service_config.proto +// Original file: deps/envoy-api/envoy/config/core/v3/event_service_config.proto -import type { GrpcService as _envoy_api_v2_core_GrpcService, GrpcService__Output as _envoy_api_v2_core_GrpcService__Output } from '../../../../envoy/api/v2/core/GrpcService'; +import type { GrpcService as _envoy_config_core_v3_GrpcService, GrpcService__Output as _envoy_config_core_v3_GrpcService__Output } from '../../../../envoy/config/core/v3/GrpcService'; /** * [#not-implemented-hide:] @@ -10,7 +10,7 @@ export interface EventServiceConfig { /** * Specifies the gRPC service that hosts the event reporting service. */ - 'grpc_service'?: (_envoy_api_v2_core_GrpcService); + 'grpc_service'?: (_envoy_config_core_v3_GrpcService); 'config_source_specifier'?: "grpc_service"; } @@ -22,6 +22,6 @@ export interface EventServiceConfig__Output { /** * Specifies the gRPC service that hosts the event reporting service. */ - 'grpc_service'?: (_envoy_api_v2_core_GrpcService__Output); + 'grpc_service'?: (_envoy_config_core_v3_GrpcService__Output); 'config_source_specifier': "grpc_service"; } 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 new file mode 100644 index 000000000..0c7e0abd3 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Extension.ts @@ -0,0 +1,75 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + +import type { BuildVersion as _envoy_config_core_v3_BuildVersion, BuildVersion__Output as _envoy_config_core_v3_BuildVersion__Output } from '../../../../envoy/config/core/v3/BuildVersion'; + +/** + * Version and identification for an Envoy extension. + * [#next-free-field: 6] + */ +export interface Extension { + /** + * This is the name of the Envoy filter as specified in the Envoy + * configuration, e.g. envoy.filters.http.router, com.acme.widget. + */ + 'name'?: (string); + /** + * Category of the extension. + * Extension category names use reverse DNS notation. For instance "envoy.filters.listener" + * for Envoy's built-in listener filters or "com.acme.filters.http" for HTTP filters from + * acme.com vendor. + * [#comment:TODO(yanavlasov): Link to the doc with existing envoy category names.] + */ + 'category'?: (string); + /** + * [#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.] + */ + 'type_descriptor'?: (string); + /** + * The version is a property of the extension and maintained independently + * of other extensions and the Envoy API. + * This field is not set when extension did not provide version information. + */ + 'version'?: (_envoy_config_core_v3_BuildVersion); + /** + * Indicates that the extension is present but was disabled via dynamic configuration. + */ + 'disabled'?: (boolean); +} + +/** + * Version and identification for an Envoy extension. + * [#next-free-field: 6] + */ +export interface Extension__Output { + /** + * This is the name of the Envoy filter as specified in the Envoy + * configuration, e.g. envoy.filters.http.router, com.acme.widget. + */ + 'name': (string); + /** + * Category of the extension. + * Extension category names use reverse DNS notation. For instance "envoy.filters.listener" + * for Envoy's built-in listener filters or "com.acme.filters.http" for HTTP filters from + * acme.com vendor. + * [#comment:TODO(yanavlasov): Link to the doc with existing envoy category names.] + */ + 'category': (string); + /** + * [#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.] + */ + 'type_descriptor': (string); + /** + * The version is a property of the extension and maintained independently + * of other extensions and the Envoy API. + * This field is not set when extension did not provide version information. + */ + 'version'?: (_envoy_config_core_v3_BuildVersion__Output); + /** + * Indicates that the extension is present but was disabled via dynamic configuration. + */ + 'disabled': (boolean); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ExtensionConfigSource.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ExtensionConfigSource.ts new file mode 100644 index 000000000..085324b6d --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ExtensionConfigSource.ts @@ -0,0 +1,72 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/extension.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'; +import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; + +/** + * Configuration source specifier for a late-bound extension configuration. The + * parent resource is warmed until all the initial extension configurations are + * received, unless the flag to apply the default configuration is set. + * Subsequent extension updates are atomic on a per-worker basis. Once an + * extension configuration is applied to a request or a connection, it remains + * constant for the duration of processing. If the initial delivery of the + * extension configuration fails, due to a timeout for example, the optional + * default configuration is applied. Without a default configuration, the + * extension is disabled, until an extension configuration is received. The + * behavior of a disabled extension depends on the context. For example, a + * filter chain with a disabled extension filter rejects all incoming streams. + */ +export interface ExtensionConfigSource { + 'config_source'?: (_envoy_config_core_v3_ConfigSource); + /** + * Optional default configuration to use as the initial configuration if + * there is a failure to receive the initial extension configuration or if + * `apply_default_config_without_warming` flag is set. + */ + 'default_config'?: (_google_protobuf_Any); + /** + * Use the default config as the initial configuration without warming and + * waiting for the first discovery response. Requires the default configuration + * to be supplied. + */ + 'apply_default_config_without_warming'?: (boolean); + /** + * A set of permitted extension type URLs. Extension configuration updates are rejected + * if they do not match any type URL in the set. + */ + 'type_urls'?: (string)[]; +} + +/** + * Configuration source specifier for a late-bound extension configuration. The + * parent resource is warmed until all the initial extension configurations are + * received, unless the flag to apply the default configuration is set. + * Subsequent extension updates are atomic on a per-worker basis. Once an + * extension configuration is applied to a request or a connection, it remains + * constant for the duration of processing. If the initial delivery of the + * extension configuration fails, due to a timeout for example, the optional + * default configuration is applied. Without a default configuration, the + * extension is disabled, until an extension configuration is received. The + * behavior of a disabled extension depends on the context. For example, a + * filter chain with a disabled extension filter rejects all incoming streams. + */ +export interface ExtensionConfigSource__Output { + 'config_source'?: (_envoy_config_core_v3_ConfigSource__Output); + /** + * Optional default configuration to use as the initial configuration if + * there is a failure to receive the initial extension configuration or if + * `apply_default_config_without_warming` flag is set. + */ + 'default_config'?: (_google_protobuf_Any__Output); + /** + * Use the default config as the initial configuration without warming and + * waiting for the first discovery response. Requires the default configuration + * to be supplied. + */ + 'apply_default_config_without_warming': (boolean); + /** + * A set of permitted extension type URLs. Extension configuration updates are rejected + * if they do not match any type URL in the set. + */ + 'type_urls': (string)[]; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/GrpcProtocolOptions.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/GrpcProtocolOptions.ts new file mode 100644 index 000000000..b0486cc37 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/GrpcProtocolOptions.ts @@ -0,0 +1,17 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/protocol.proto + +import type { Http2ProtocolOptions as _envoy_config_core_v3_Http2ProtocolOptions, Http2ProtocolOptions__Output as _envoy_config_core_v3_Http2ProtocolOptions__Output } from '../../../../envoy/config/core/v3/Http2ProtocolOptions'; + +/** + * [#not-implemented-hide:] + */ +export interface GrpcProtocolOptions { + 'http2_protocol_options'?: (_envoy_config_core_v3_Http2ProtocolOptions); +} + +/** + * [#not-implemented-hide:] + */ +export interface GrpcProtocolOptions__Output { + 'http2_protocol_options'?: (_envoy_config_core_v3_Http2ProtocolOptions__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/GrpcService.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/GrpcService.ts similarity index 59% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/core/GrpcService.ts rename to packages/grpc-js-xds/src/generated/envoy/config/core/v3/GrpcService.ts index 3bc894b57..24249309b 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/GrpcService.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/GrpcService.ts @@ -1,9 +1,10 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/grpc_service.proto +// Original file: deps/envoy-api/envoy/config/core/v3/grpc_service.proto import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; -import type { HeaderValue as _envoy_api_v2_core_HeaderValue, HeaderValue__Output as _envoy_api_v2_core_HeaderValue__Output } from '../../../../envoy/api/v2/core/HeaderValue'; +import type { HeaderValue as _envoy_config_core_v3_HeaderValue, HeaderValue__Output as _envoy_config_core_v3_HeaderValue__Output } from '../../../../envoy/config/core/v3/HeaderValue'; import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; -import type { DataSource as _envoy_api_v2_core_DataSource, DataSource__Output as _envoy_api_v2_core_DataSource__Output } from '../../../../envoy/api/v2/core/DataSource'; +import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; +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 { Empty as _google_protobuf_Empty, Empty__Output as _google_protobuf_Empty__Output } from '../../../../google/protobuf/Empty'; 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'; @@ -11,7 +12,7 @@ import type { Long } from '@grpc/proto-loader'; /** * [#next-free-field: 8] */ -export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials { +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials { /** * Access token credentials. * https://grpc.io/grpc/cpp/namespacegrpc.html#ad3a80da696ffdaea943f0f858d7a360d. @@ -31,31 +32,31 @@ export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials { * Service Account JWT Access credentials. * https://grpc.io/grpc/cpp/namespacegrpc.html#a92a9f959d6102461f66ee973d8e9d3aa. */ - 'service_account_jwt_access'?: (_envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials); + 'service_account_jwt_access'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials); /** * Google IAM credentials. * https://grpc.io/grpc/cpp/namespacegrpc.html#a9fc1fc101b41e680d47028166e76f9d0. */ - 'google_iam'?: (_envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials); + 'google_iam'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials); /** * Custom authenticator credentials. * https://grpc.io/grpc/cpp/namespacegrpc.html#a823c6a4b19ffc71fb33e90154ee2ad07. * https://grpc.io/docs/guides/auth.html#extending-grpc-to-support-other-authentication-mechanisms. */ - 'from_plugin'?: (_envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin); + 'from_plugin'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin); /** * Custom security token service which implements OAuth 2.0 token exchange. * https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-16 * See https://github.com/grpc/grpc/pull/19587. */ - 'sts_service'?: (_envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_StsService); + 'sts_service'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService); 'credential_specifier'?: "access_token"|"google_compute_engine"|"google_refresh_token"|"service_account_jwt_access"|"google_iam"|"from_plugin"|"sts_service"; } /** * [#next-free-field: 8] */ -export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials__Output { +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials__Output { /** * Access token credentials. * https://grpc.io/grpc/cpp/namespacegrpc.html#ad3a80da696ffdaea943f0f858d7a360d. @@ -75,38 +76,58 @@ export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials__Outp * Service Account JWT Access credentials. * https://grpc.io/grpc/cpp/namespacegrpc.html#a92a9f959d6102461f66ee973d8e9d3aa. */ - 'service_account_jwt_access'?: (_envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials__Output); + 'service_account_jwt_access'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials__Output); /** * Google IAM credentials. * https://grpc.io/grpc/cpp/namespacegrpc.html#a9fc1fc101b41e680d47028166e76f9d0. */ - 'google_iam'?: (_envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials__Output); + 'google_iam'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials__Output); /** * Custom authenticator credentials. * https://grpc.io/grpc/cpp/namespacegrpc.html#a823c6a4b19ffc71fb33e90154ee2ad07. * https://grpc.io/docs/guides/auth.html#extending-grpc-to-support-other-authentication-mechanisms. */ - 'from_plugin'?: (_envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin__Output); + 'from_plugin'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin__Output); /** * Custom security token service which implements OAuth 2.0 token exchange. * https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-16 * See https://github.com/grpc/grpc/pull/19587. */ - 'sts_service'?: (_envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_StsService__Output); + 'sts_service'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService__Output); 'credential_specifier': "access_token"|"google_compute_engine"|"google_refresh_token"|"service_account_jwt_access"|"google_iam"|"from_plugin"|"sts_service"; } +/** + * Channel arguments. + */ +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs { + /** + * See grpc_types.h GRPC_ARG #defines for keys that work here. + */ + 'args'?: ({[key: string]: _envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value}); +} + +/** + * Channel arguments. + */ +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs__Output { + /** + * See grpc_types.h GRPC_ARG #defines for keys that work here. + */ + 'args'?: ({[key: string]: _envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value__Output}); +} + /** * See https://grpc.io/docs/guides/auth.html#credential-types to understand Channel and Call * credential types. */ -export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials { - 'ssl_credentials'?: (_envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials); +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials { + 'ssl_credentials'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials); /** * https://grpc.io/grpc/cpp/namespacegrpc.html#a6beb3ac70ff94bd2ebbd89b8f21d1f61 */ 'google_default'?: (_google_protobuf_Empty); - 'local_credentials'?: (_envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials); + 'local_credentials'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials); 'credential_specifier'?: "ssl_credentials"|"google_default"|"local_credentials"; } @@ -114,50 +135,60 @@ export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials { * See https://grpc.io/docs/guides/auth.html#credential-types to understand Channel and Call * credential types. */ -export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials__Output { - 'ssl_credentials'?: (_envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials__Output); +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials__Output { + 'ssl_credentials'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials__Output); /** * https://grpc.io/grpc/cpp/namespacegrpc.html#a6beb3ac70ff94bd2ebbd89b8f21d1f61 */ 'google_default'?: (_google_protobuf_Empty__Output); - 'local_credentials'?: (_envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials__Output); + 'local_credentials'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials__Output); 'credential_specifier': "ssl_credentials"|"google_default"|"local_credentials"; } -export interface _envoy_api_v2_core_GrpcService_EnvoyGrpc { +export interface _envoy_config_core_v3_GrpcService_EnvoyGrpc { /** * The name of the upstream gRPC cluster. SSL credentials will be supplied - * in the :ref:`Cluster ` :ref:`transport_socket - * `. + * in the :ref:`Cluster ` :ref:`transport_socket + * `. */ 'cluster_name'?: (string); + /** + * The `:authority` header in the grpc request. If this field is not set, the authority header value will be `cluster_name`. + * Note that this authority does not override the SNI. The SNI is provided by the transport socket of the cluster. + */ + 'authority'?: (string); } -export interface _envoy_api_v2_core_GrpcService_EnvoyGrpc__Output { +export interface _envoy_config_core_v3_GrpcService_EnvoyGrpc__Output { /** * The name of the upstream gRPC cluster. SSL credentials will be supplied - * in the :ref:`Cluster ` :ref:`transport_socket - * `. + * in the :ref:`Cluster ` :ref:`transport_socket + * `. */ 'cluster_name': (string); + /** + * The `:authority` header in the grpc request. If this field is not set, the authority header value will be `cluster_name`. + * Note that this authority does not override the SNI. The SNI is provided by the transport socket of the cluster. + */ + 'authority': (string); } /** - * [#next-free-field: 7] + * [#next-free-field: 9] */ -export interface _envoy_api_v2_core_GrpcService_GoogleGrpc { +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc { /** * The target URI when using the `Google C++ gRPC client * `_. SSL credentials will be supplied in - * :ref:`channel_credentials `. + * :ref:`channel_credentials `. */ 'target_uri'?: (string); - 'channel_credentials'?: (_envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials); + 'channel_credentials'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials); /** * A set of call credentials that can be composed with `channel credentials * `_. */ - 'call_credentials'?: (_envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials)[]; + 'call_credentials'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials)[]; /** * The human readable prefix to use when emitting statistics for the gRPC * service. @@ -181,24 +212,33 @@ export interface _envoy_api_v2_core_GrpcService_GoogleGrpc { * gRPC library. */ 'config'?: (_google_protobuf_Struct); + /** + * How many bytes each stream can buffer internally. + * If not set an implementation defined default is applied (1MiB). + */ + 'per_stream_buffer_limit_bytes'?: (_google_protobuf_UInt32Value); + /** + * Custom channels args. + */ + 'channel_args'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs); } /** - * [#next-free-field: 7] + * [#next-free-field: 9] */ -export interface _envoy_api_v2_core_GrpcService_GoogleGrpc__Output { +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc__Output { /** * The target URI when using the `Google C++ gRPC client * `_. SSL credentials will be supplied in - * :ref:`channel_credentials `. + * :ref:`channel_credentials `. */ 'target_uri': (string); - 'channel_credentials'?: (_envoy_api_v2_core_GrpcService_GoogleGrpc_ChannelCredentials__Output); + 'channel_credentials'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials__Output); /** * A set of call credentials that can be composed with `channel credentials * `_. */ - 'call_credentials': (_envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials__Output)[]; + 'call_credentials': (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials__Output)[]; /** * The human readable prefix to use when emitting statistics for the gRPC * service. @@ -222,14 +262,23 @@ export interface _envoy_api_v2_core_GrpcService_GoogleGrpc__Output { * gRPC library. */ 'config'?: (_google_protobuf_Struct__Output); + /** + * How many bytes each stream can buffer internally. + * If not set an implementation defined default is applied (1MiB). + */ + 'per_stream_buffer_limit_bytes'?: (_google_protobuf_UInt32Value__Output); + /** + * Custom channels args. + */ + 'channel_args'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs__Output); } -export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials { +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials { 'authorization_token'?: (string); 'authority_selector'?: (string); } -export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials__Output { +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials__Output { 'authorization_token': (string); 'authority_selector': (string); } @@ -238,36 +287,34 @@ export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_Googl * Local channel credentials. Only UDS is supported for now. * See https://github.com/grpc/grpc/pull/15909. */ -export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials { +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials { } /** * Local channel credentials. Only UDS is supported for now. * See https://github.com/grpc/grpc/pull/15909. */ -export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_GoogleLocalCredentials__Output { +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials__Output { } -export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin { +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin { 'name'?: (string); - 'config'?: (_google_protobuf_Struct); 'typed_config'?: (_google_protobuf_Any); - 'config_type'?: "config"|"typed_config"; + 'config_type'?: "typed_config"; } -export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin__Output { +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin__Output { 'name': (string); - 'config'?: (_google_protobuf_Struct__Output); 'typed_config'?: (_google_protobuf_Any__Output); - 'config_type': "config"|"typed_config"; + 'config_type': "typed_config"; } -export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials { +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials { 'json_key'?: (string); 'token_lifetime_seconds'?: (number | string | Long); } -export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials__Output { +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials__Output { 'json_key': (string); 'token_lifetime_seconds': (string); } @@ -275,37 +322,37 @@ export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_Servi /** * See https://grpc.io/grpc/cpp/structgrpc_1_1_ssl_credentials_options.html. */ -export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials { +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials { /** * PEM encoded server root certificates. */ - 'root_certs'?: (_envoy_api_v2_core_DataSource); + 'root_certs'?: (_envoy_config_core_v3_DataSource); /** * PEM encoded client private key. */ - 'private_key'?: (_envoy_api_v2_core_DataSource); + 'private_key'?: (_envoy_config_core_v3_DataSource); /** * PEM encoded client certificate chain. */ - 'cert_chain'?: (_envoy_api_v2_core_DataSource); + 'cert_chain'?: (_envoy_config_core_v3_DataSource); } /** * See https://grpc.io/grpc/cpp/structgrpc_1_1_ssl_credentials_options.html. */ -export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials__Output { +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials__Output { /** * PEM encoded server root certificates. */ - 'root_certs'?: (_envoy_api_v2_core_DataSource__Output); + 'root_certs'?: (_envoy_config_core_v3_DataSource__Output); /** * PEM encoded client private key. */ - 'private_key'?: (_envoy_api_v2_core_DataSource__Output); + 'private_key'?: (_envoy_config_core_v3_DataSource__Output); /** * PEM encoded client certificate chain. */ - 'cert_chain'?: (_envoy_api_v2_core_DataSource__Output); + 'cert_chain'?: (_envoy_config_core_v3_DataSource__Output); } /** @@ -315,7 +362,7 @@ export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_SslCredentials__Outpu * https://github.com/grpc/grpc/pull/19587. * [#next-free-field: 10] */ -export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_StsService { +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService { /** * URI of the token exchange service that handles token exchange requests. * [#comment:TODO(asraa): Add URI validation when implemented. Tracked by @@ -369,7 +416,7 @@ export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_StsSe * https://github.com/grpc/grpc/pull/19587. * [#next-free-field: 10] */ -export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_StsService__Output { +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService__Output { /** * URI of the token exchange service that handles token exchange requests. * [#comment:TODO(asraa): Add URI validation when implemented. Tracked by @@ -416,9 +463,29 @@ export interface _envoy_api_v2_core_GrpcService_GoogleGrpc_CallCredentials_StsSe 'actor_token_type': (string); } +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value { + 'string_value'?: (string); + 'int_value'?: (number | string | Long); + /** + * Pointer values are not supported, since they don't make any sense when + * delivered via the API. + */ + 'value_specifier'?: "string_value"|"int_value"; +} + +export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value__Output { + 'string_value'?: (string); + 'int_value'?: (string); + /** + * Pointer values are not supported, since they don't make any sense when + * delivered via the API. + */ + 'value_specifier': "string_value"|"int_value"; +} + /** * gRPC service configuration. This is used by :ref:`ApiConfigSource - * ` and filter configurations. + * ` and filter configurations. * [#next-free-field: 6] */ export interface GrpcService { @@ -427,30 +494,32 @@ export interface GrpcService { * See the :ref:`gRPC services overview ` * documentation for discussion on gRPC client selection. */ - 'envoy_grpc'?: (_envoy_api_v2_core_GrpcService_EnvoyGrpc); + 'envoy_grpc'?: (_envoy_config_core_v3_GrpcService_EnvoyGrpc); /** * `Google C++ gRPC client `_ * See the :ref:`gRPC services overview ` * documentation for discussion on gRPC client selection. */ - 'google_grpc'?: (_envoy_api_v2_core_GrpcService_GoogleGrpc); + 'google_grpc'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc); /** * The timeout for the gRPC request. This is the timeout for a specific * request. */ 'timeout'?: (_google_protobuf_Duration); /** - * Additional metadata to include in streams initiated to the GrpcService. - * This can be used for scenarios in which additional ad hoc authorization - * headers (e.g. ``x-foo-bar: baz-key``) are to be injected. + * Additional metadata to include in streams initiated to the GrpcService. This can be used for + * scenarios in which additional ad hoc authorization headers (e.g. ``x-foo-bar: baz-key``) are to + * be injected. For more information, including details on header value syntax, see the + * documentation on :ref:`custom request headers + * `. */ - 'initial_metadata'?: (_envoy_api_v2_core_HeaderValue)[]; + 'initial_metadata'?: (_envoy_config_core_v3_HeaderValue)[]; 'target_specifier'?: "envoy_grpc"|"google_grpc"; } /** * gRPC service configuration. This is used by :ref:`ApiConfigSource - * ` and filter configurations. + * ` and filter configurations. * [#next-free-field: 6] */ export interface GrpcService__Output { @@ -459,23 +528,25 @@ export interface GrpcService__Output { * See the :ref:`gRPC services overview ` * documentation for discussion on gRPC client selection. */ - 'envoy_grpc'?: (_envoy_api_v2_core_GrpcService_EnvoyGrpc__Output); + 'envoy_grpc'?: (_envoy_config_core_v3_GrpcService_EnvoyGrpc__Output); /** * `Google C++ gRPC client `_ * See the :ref:`gRPC services overview ` * documentation for discussion on gRPC client selection. */ - 'google_grpc'?: (_envoy_api_v2_core_GrpcService_GoogleGrpc__Output); + 'google_grpc'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc__Output); /** * The timeout for the gRPC request. This is the timeout for a specific * request. */ 'timeout'?: (_google_protobuf_Duration__Output); /** - * Additional metadata to include in streams initiated to the GrpcService. - * This can be used for scenarios in which additional ad hoc authorization - * headers (e.g. ``x-foo-bar: baz-key``) are to be injected. + * Additional metadata to include in streams initiated to the GrpcService. This can be used for + * scenarios in which additional ad hoc authorization headers (e.g. ``x-foo-bar: baz-key``) are to + * be injected. For more information, including details on header value syntax, see the + * documentation on :ref:`custom request headers + * `. */ - 'initial_metadata': (_envoy_api_v2_core_HeaderValue__Output)[]; + 'initial_metadata': (_envoy_config_core_v3_HeaderValue__Output)[]; 'target_specifier': "envoy_grpc"|"google_grpc"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HeaderMap.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HeaderMap.ts new file mode 100644 index 000000000..3ee496152 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HeaderMap.ts @@ -0,0 +1,17 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + +import type { HeaderValue as _envoy_config_core_v3_HeaderValue, HeaderValue__Output as _envoy_config_core_v3_HeaderValue__Output } from '../../../../envoy/config/core/v3/HeaderValue'; + +/** + * Wrapper for a set of headers. + */ +export interface HeaderMap { + 'headers'?: (_envoy_config_core_v3_HeaderValue)[]; +} + +/** + * Wrapper for a set of headers. + */ +export interface HeaderMap__Output { + 'headers': (_envoy_config_core_v3_HeaderValue__Output)[]; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HeaderValue.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HeaderValue.ts new file mode 100644 index 000000000..a9fb6c07a --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HeaderValue.ts @@ -0,0 +1,38 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + + +/** + * Header name/value pair. + */ +export interface HeaderValue { + /** + * Header name. + */ + 'key'?: (string); + /** + * Header value. + * + * The same :ref:`format specifier ` as used for + * :ref:`HTTP access logging ` applies here, however + * unknown header values are replaced with the empty string instead of `-`. + */ + 'value'?: (string); +} + +/** + * Header name/value pair. + */ +export interface HeaderValue__Output { + /** + * Header name. + */ + 'key': (string); + /** + * Header value. + * + * The same :ref:`format specifier ` as used for + * :ref:`HTTP access logging ` applies here, however + * unknown header values are replaced with the empty string instead of `-`. + */ + 'value': (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 new file mode 100644 index 000000000..4a0fe7120 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HeaderValueOption.ts @@ -0,0 +1,34 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + +import type { HeaderValue as _envoy_config_core_v3_HeaderValue, HeaderValue__Output as _envoy_config_core_v3_HeaderValue__Output } from '../../../../envoy/config/core/v3/HeaderValue'; +import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; + +/** + * Header name/value pair plus option to control append behavior. + */ +export interface HeaderValueOption { + /** + * Header name/value pair that this option applies to. + */ + 'header'?: (_envoy_config_core_v3_HeaderValue); + /** + * Should the value be appended? If true (default), the value is appended to + * existing values. Otherwise it replaces any existing values. + */ + 'append'?: (_google_protobuf_BoolValue); +} + +/** + * Header name/value pair plus option to control append behavior. + */ +export interface HeaderValueOption__Output { + /** + * Header name/value pair that this option applies to. + */ + 'header'?: (_envoy_config_core_v3_HeaderValue__Output); + /** + * Should the value be appended? If true (default), the value is appended to + * existing values. Otherwise it replaces any existing values. + */ + 'append'?: (_google_protobuf_BoolValue__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HealthCheck.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HealthCheck.ts similarity index 67% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/core/HealthCheck.ts rename to packages/grpc-js-xds/src/generated/envoy/config/core/v3/HealthCheck.ts index 0b45042f3..3a7320a08 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HealthCheck.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HealthCheck.ts @@ -1,49 +1,47 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/health_check.proto +// Original file: deps/envoy-api/envoy/config/core/v3/health_check.proto import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; -import type { EventServiceConfig as _envoy_api_v2_core_EventServiceConfig, EventServiceConfig__Output as _envoy_api_v2_core_EventServiceConfig__Output } from '../../../../envoy/api/v2/core/EventServiceConfig'; -import type { HeaderValueOption as _envoy_api_v2_core_HeaderValueOption, HeaderValueOption__Output as _envoy_api_v2_core_HeaderValueOption__Output } from '../../../../envoy/api/v2/core/HeaderValueOption'; -import type { Int64Range as _envoy_type_Int64Range, Int64Range__Output as _envoy_type_Int64Range__Output } from '../../../../envoy/type/Int64Range'; -import type { CodecClientType as _envoy_type_CodecClientType } from '../../../../envoy/type/CodecClientType'; -import type { StringMatcher as _envoy_type_matcher_StringMatcher, StringMatcher__Output as _envoy_type_matcher_StringMatcher__Output } from '../../../../envoy/type/matcher/StringMatcher'; +import type { EventServiceConfig as _envoy_config_core_v3_EventServiceConfig, EventServiceConfig__Output as _envoy_config_core_v3_EventServiceConfig__Output } from '../../../../envoy/config/core/v3/EventServiceConfig'; import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; +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 { StringMatcher as _envoy_type_matcher_v3_StringMatcher, StringMatcher__Output as _envoy_type_matcher_v3_StringMatcher__Output } from '../../../../envoy/type/matcher/v3/StringMatcher'; 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. */ -export interface _envoy_api_v2_core_HealthCheck_CustomHealthCheck { +export interface _envoy_config_core_v3_HealthCheck_CustomHealthCheck { /** * The registered name of the custom health checker. */ 'name'?: (string); - 'config'?: (_google_protobuf_Struct); 'typed_config'?: (_google_protobuf_Any); /** * A custom health checker specific configuration which depends on the custom health checker * being instantiated. See :api:`envoy/config/health_checker` for reference. */ - 'config_type'?: "config"|"typed_config"; + 'config_type'?: "typed_config"; } /** * Custom health check. */ -export interface _envoy_api_v2_core_HealthCheck_CustomHealthCheck__Output { +export interface _envoy_config_core_v3_HealthCheck_CustomHealthCheck__Output { /** * The registered name of the custom health checker. */ 'name': (string); - 'config'?: (_google_protobuf_Struct__Output); 'typed_config'?: (_google_protobuf_Any__Output); /** * A custom health checker specific configuration which depends on the custom health checker * being instantiated. See :api:`envoy/config/health_checker` for reference. */ - 'config_type': "config"|"typed_config"; + 'config_type': "typed_config"; } /** @@ -52,7 +50,7 @@ export interface _envoy_api_v2_core_HealthCheck_CustomHealthCheck__Output { * healthcheck. See `gRPC doc `_ * for details. */ -export interface _envoy_api_v2_core_HealthCheck_GrpcHealthCheck { +export interface _envoy_config_core_v3_HealthCheck_GrpcHealthCheck { /** * An optional service name parameter which will be sent to gRPC service in * `grpc.health.v1.HealthCheckRequest @@ -65,7 +63,7 @@ export interface _envoy_api_v2_core_HealthCheck_GrpcHealthCheck { * The value of the :authority header in the gRPC health check request. If * left empty (default value), the name of the cluster this health check is associated * with will be used. The authority header can be customized for a specific endpoint by setting - * the :ref:`hostname ` field. + * the :ref:`hostname ` field. */ 'authority'?: (string); } @@ -76,7 +74,7 @@ export interface _envoy_api_v2_core_HealthCheck_GrpcHealthCheck { * healthcheck. See `gRPC doc `_ * for details. */ -export interface _envoy_api_v2_core_HealthCheck_GrpcHealthCheck__Output { +export interface _envoy_config_core_v3_HealthCheck_GrpcHealthCheck__Output { /** * An optional service name parameter which will be sent to gRPC service in * `grpc.health.v1.HealthCheckRequest @@ -89,7 +87,7 @@ export interface _envoy_api_v2_core_HealthCheck_GrpcHealthCheck__Output { * The value of the :authority header in the gRPC health check request. If * left empty (default value), the name of the cluster this health check is associated * with will be used. The authority header can be customized for a specific endpoint by setting - * the :ref:`hostname ` field. + * the :ref:`hostname ` field. */ 'authority': (string); } @@ -97,12 +95,12 @@ export interface _envoy_api_v2_core_HealthCheck_GrpcHealthCheck__Output { /** * [#next-free-field: 12] */ -export interface _envoy_api_v2_core_HealthCheck_HttpHealthCheck { +export interface _envoy_config_core_v3_HealthCheck_HttpHealthCheck { /** * The value of the host header in the HTTP health check request. If * left empty (default value), the name of the cluster this health check is associated * with will be used. The host header can be customized for a specific endpoint by setting the - * :ref:`hostname ` field. + * :ref:`hostname ` field. */ 'host'?: (string); /** @@ -113,69 +111,52 @@ export interface _envoy_api_v2_core_HealthCheck_HttpHealthCheck { /** * [#not-implemented-hide:] HTTP specific payload. */ - 'send'?: (_envoy_api_v2_core_HealthCheck_Payload); + 'send'?: (_envoy_config_core_v3_HealthCheck_Payload); /** * [#not-implemented-hide:] HTTP specific response. */ - 'receive'?: (_envoy_api_v2_core_HealthCheck_Payload); - /** - * An optional service name parameter which is used to validate the identity of - * the health checked cluster. See the :ref:`architecture overview - * ` for more information. - * - * .. attention:: - * - * This field has been deprecated in favor of `service_name_matcher` for better flexibility - * over matching with service-cluster name. - */ - 'service_name'?: (string); + 'receive'?: (_envoy_config_core_v3_HealthCheck_Payload); /** * Specifies a list of HTTP headers that should be added to each request that is sent to the * health checked cluster. For more information, including details on header value syntax, see * the documentation on :ref:`custom request headers * `. */ - 'request_headers_to_add'?: (_envoy_api_v2_core_HeaderValueOption)[]; + 'request_headers_to_add'?: (_envoy_config_core_v3_HeaderValueOption)[]; /** * Specifies a list of HTTP headers that should be removed from each request that is sent to the * health checked cluster. */ 'request_headers_to_remove'?: (string)[]; - /** - * If set, health checks will be made using http/2. - * Deprecated, use :ref:`codec_client_type - * ` instead. - */ - 'use_http2'?: (boolean); /** * Specifies a list of HTTP response statuses considered healthy. If provided, replaces default * 200-only policy - 200 must be included explicitly as needed. Ranges follow half-open - * semantics of :ref:`Int64Range `. The start and end of each + * semantics of :ref:`Int64Range `. The start and end of each * range are required. Only statuses in the range [100, 600) are allowed. */ - 'expected_statuses'?: (_envoy_type_Int64Range)[]; + 'expected_statuses'?: (_envoy_type_v3_Int64Range)[]; /** * Use specified application protocol for health checks. */ - 'codec_client_type'?: (_envoy_type_CodecClientType | keyof typeof _envoy_type_CodecClientType); + 'codec_client_type'?: (_envoy_type_v3_CodecClientType | keyof typeof _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 - * `. See the :ref:`architecture overview + * `. See the :ref:`architecture overview * ` for more information. */ - 'service_name_matcher'?: (_envoy_type_matcher_StringMatcher); + 'service_name_matcher'?: (_envoy_type_matcher_v3_StringMatcher); } /** * [#next-free-field: 12] */ -export interface _envoy_api_v2_core_HealthCheck_HttpHealthCheck__Output { +export interface _envoy_config_core_v3_HealthCheck_HttpHealthCheck__Output { /** * The value of the host header in the HTTP health check request. If * left empty (default value), the name of the cluster this health check is associated * with will be used. The host header can be customized for a specific endpoint by setting the - * :ref:`hostname ` field. + * :ref:`hostname ` field. */ 'host': (string); /** @@ -186,64 +167,47 @@ export interface _envoy_api_v2_core_HealthCheck_HttpHealthCheck__Output { /** * [#not-implemented-hide:] HTTP specific payload. */ - 'send'?: (_envoy_api_v2_core_HealthCheck_Payload__Output); + 'send'?: (_envoy_config_core_v3_HealthCheck_Payload__Output); /** * [#not-implemented-hide:] HTTP specific response. */ - 'receive'?: (_envoy_api_v2_core_HealthCheck_Payload__Output); - /** - * An optional service name parameter which is used to validate the identity of - * the health checked cluster. See the :ref:`architecture overview - * ` for more information. - * - * .. attention:: - * - * This field has been deprecated in favor of `service_name_matcher` for better flexibility - * over matching with service-cluster name. - */ - 'service_name': (string); + 'receive'?: (_envoy_config_core_v3_HealthCheck_Payload__Output); /** * Specifies a list of HTTP headers that should be added to each request that is sent to the * health checked cluster. For more information, including details on header value syntax, see * the documentation on :ref:`custom request headers * `. */ - 'request_headers_to_add': (_envoy_api_v2_core_HeaderValueOption__Output)[]; + 'request_headers_to_add': (_envoy_config_core_v3_HeaderValueOption__Output)[]; /** * Specifies a list of HTTP headers that should be removed from each request that is sent to the * health checked cluster. */ 'request_headers_to_remove': (string)[]; - /** - * If set, health checks will be made using http/2. - * Deprecated, use :ref:`codec_client_type - * ` instead. - */ - 'use_http2': (boolean); /** * Specifies a list of HTTP response statuses considered healthy. If provided, replaces default * 200-only policy - 200 must be included explicitly as needed. Ranges follow half-open - * semantics of :ref:`Int64Range `. The start and end of each + * semantics of :ref:`Int64Range `. The start and end of each * range are required. Only statuses in the range [100, 600) are allowed. */ - 'expected_statuses': (_envoy_type_Int64Range__Output)[]; + 'expected_statuses': (_envoy_type_v3_Int64Range__Output)[]; /** * Use specified application protocol for health checks. */ - 'codec_client_type': (keyof typeof _envoy_type_CodecClientType); + 'codec_client_type': (keyof typeof _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 - * `. See the :ref:`architecture overview + * `. See the :ref:`architecture overview * ` for more information. */ - 'service_name_matcher'?: (_envoy_type_matcher_StringMatcher__Output); + 'service_name_matcher'?: (_envoy_type_matcher_v3_StringMatcher__Output); } /** * Describes the encoding of the payload bytes in the payload. */ -export interface _envoy_api_v2_core_HealthCheck_Payload { +export interface _envoy_config_core_v3_HealthCheck_Payload { /** * Hex encoded payload. E.g., "000000FF". */ @@ -258,7 +222,7 @@ export interface _envoy_api_v2_core_HealthCheck_Payload { /** * Describes the encoding of the payload bytes in the payload. */ -export interface _envoy_api_v2_core_HealthCheck_Payload__Output { +export interface _envoy_config_core_v3_HealthCheck_Payload__Output { /** * Hex encoded payload. E.g., "000000FF". */ @@ -270,7 +234,7 @@ export interface _envoy_api_v2_core_HealthCheck_Payload__Output { 'payload': "text"|"binary"; } -export interface _envoy_api_v2_core_HealthCheck_RedisHealthCheck { +export interface _envoy_config_core_v3_HealthCheck_RedisHealthCheck { /** * If set, optionally perform ``EXISTS `` instead of ``PING``. A return value * from Redis of 0 (does not exist) is considered a passing healthcheck. A return value other @@ -280,7 +244,7 @@ export interface _envoy_api_v2_core_HealthCheck_RedisHealthCheck { 'key'?: (string); } -export interface _envoy_api_v2_core_HealthCheck_RedisHealthCheck__Output { +export interface _envoy_config_core_v3_HealthCheck_RedisHealthCheck__Output { /** * If set, optionally perform ``EXISTS `` instead of ``PING``. A return value * from Redis of 0 (does not exist) is considered a passing healthcheck. A return value other @@ -290,30 +254,30 @@ export interface _envoy_api_v2_core_HealthCheck_RedisHealthCheck__Output { 'key': (string); } -export interface _envoy_api_v2_core_HealthCheck_TcpHealthCheck { +export interface _envoy_config_core_v3_HealthCheck_TcpHealthCheck { /** * Empty payloads imply a connect-only health check. */ - 'send'?: (_envoy_api_v2_core_HealthCheck_Payload); + 'send'?: (_envoy_config_core_v3_HealthCheck_Payload); /** * When checking the response, “fuzzy” matching is performed such that each * binary block must be found, and in the order specified, but not * necessarily contiguous. */ - 'receive'?: (_envoy_api_v2_core_HealthCheck_Payload)[]; + 'receive'?: (_envoy_config_core_v3_HealthCheck_Payload)[]; } -export interface _envoy_api_v2_core_HealthCheck_TcpHealthCheck__Output { +export interface _envoy_config_core_v3_HealthCheck_TcpHealthCheck__Output { /** * Empty payloads imply a connect-only health check. */ - 'send'?: (_envoy_api_v2_core_HealthCheck_Payload__Output); + 'send'?: (_envoy_config_core_v3_HealthCheck_Payload__Output); /** * When checking the response, “fuzzy” matching is performed such that each * binary block must be found, and in the order specified, but not * necessarily contiguous. */ - 'receive': (_envoy_api_v2_core_HealthCheck_Payload__Output)[]; + 'receive': (_envoy_config_core_v3_HealthCheck_Payload__Output)[]; } /** @@ -322,11 +286,11 @@ export interface _envoy_api_v2_core_HealthCheck_TcpHealthCheck__Output { * * This allows overriding the cluster TLS settings, just for health check connections. */ -export interface _envoy_api_v2_core_HealthCheck_TlsOptions { +export interface _envoy_config_core_v3_HealthCheck_TlsOptions { /** * Specifies the ALPN protocols for health check connections. This is useful if the * corresponding upstream is using ALPN-based :ref:`FilterChainMatch - * ` along with different protocols for health checks + * ` along with different protocols for health checks * versus data connections. If empty, no ALPN protocols will be set on health check connections. */ 'alpn_protocols'?: (string)[]; @@ -338,18 +302,18 @@ export interface _envoy_api_v2_core_HealthCheck_TlsOptions { * * This allows overriding the cluster TLS settings, just for health check connections. */ -export interface _envoy_api_v2_core_HealthCheck_TlsOptions__Output { +export interface _envoy_config_core_v3_HealthCheck_TlsOptions__Output { /** * Specifies the ALPN protocols for health check connections. This is useful if the * corresponding upstream is using ALPN-based :ref:`FilterChainMatch - * ` along with different protocols for health checks + * ` along with different protocols for health checks * versus data connections. If empty, no ALPN protocols will be set on health check connections. */ 'alpn_protocols': (string)[]; } /** - * [#next-free-field: 23] + * [#next-free-field: 25] */ export interface HealthCheck { /** @@ -389,15 +353,15 @@ export interface HealthCheck { /** * HTTP health check. */ - 'http_health_check'?: (_envoy_api_v2_core_HealthCheck_HttpHealthCheck); + 'http_health_check'?: (_envoy_config_core_v3_HealthCheck_HttpHealthCheck); /** * TCP health check. */ - 'tcp_health_check'?: (_envoy_api_v2_core_HealthCheck_TcpHealthCheck); + 'tcp_health_check'?: (_envoy_config_core_v3_HealthCheck_TcpHealthCheck); /** * gRPC health check. */ - 'grpc_health_check'?: (_envoy_api_v2_core_HealthCheck_GrpcHealthCheck); + 'grpc_health_check'?: (_envoy_config_core_v3_HealthCheck_GrpcHealthCheck); /** * The "no traffic interval" is a special health check interval that is used when a cluster has * never had traffic routed to it. This lower interval allows cluster information to be kept up to @@ -412,7 +376,7 @@ export interface HealthCheck { /** * Custom health check. */ - 'custom_health_check'?: (_envoy_api_v2_core_HealthCheck_CustomHealthCheck); + 'custom_health_check'?: (_envoy_config_core_v3_HealthCheck_CustomHealthCheck); /** * The "unhealthy interval" is a health check interval that is used for hosts that are marked as * unhealthy. As soon as the host is marked as healthy, Envoy will shift back to using the @@ -467,18 +431,67 @@ export interface HealthCheck { /** * This allows overriding the cluster TLS settings, just for health check connections. */ - 'tls_options'?: (_envoy_api_v2_core_HealthCheck_TlsOptions); + 'tls_options'?: (_envoy_config_core_v3_HealthCheck_TlsOptions); /** * [#not-implemented-hide:] * The gRPC service for the health check event service. * If empty, health check events won't be sent to a remote endpoint. */ - 'event_service'?: (_envoy_api_v2_core_EventServiceConfig); + 'event_service'?: (_envoy_config_core_v3_EventServiceConfig); + /** + * Optional key/value pairs that will be used to match a transport socket from those specified in the cluster's + * :ref:`tranport socket matches `. + * For example, the following match criteria + * + * .. code-block:: yaml + * + * transport_socket_match_criteria: + * useMTLS: true + * + * Will match the following :ref:`cluster socket match ` + * + * .. code-block:: yaml + * + * transport_socket_matches: + * - name: "useMTLS" + * match: + * useMTLS: true + * transport_socket: + * name: envoy.transport_sockets.tls + * config: { ... } # tls socket configuration + * + * If this field is set, then for health checks it will supersede an entry of *envoy.transport_socket* in the + * :ref:`LbEndpoint.Metadata `. + * This allows using different transport socket capabilities for health checking versus proxying to the + * endpoint. + * + * If the key/values pairs specified do not match any + * :ref:`transport socket matches `, + * the cluster's :ref:`transport socket ` + * will be used for health check socket configuration. + */ + 'transport_socket_match_criteria'?: (_google_protobuf_Struct); + /** + * The "no traffic healthy interval" is a special health check interval that + * is used for hosts that are currently passing active health checking + * (including new hosts) when the cluster has received no traffic. + * + * This is useful for when we want to send frequent health checks with + * `no_traffic_interval` but then revert to lower frequency `no_traffic_healthy_interval` once + * a host in the cluster is marked as healthy. + * + * Once a cluster has been used for traffic routing, Envoy will shift back to using the + * standard health check interval that is defined. + * + * If no_traffic_healthy_interval is not set, it will default to the + * no traffic interval and send that interval regardless of health state. + */ + 'no_traffic_healthy_interval'?: (_google_protobuf_Duration); 'health_checker'?: "http_health_check"|"tcp_health_check"|"grpc_health_check"|"custom_health_check"; } /** - * [#next-free-field: 23] + * [#next-free-field: 25] */ export interface HealthCheck__Output { /** @@ -518,15 +531,15 @@ export interface HealthCheck__Output { /** * HTTP health check. */ - 'http_health_check'?: (_envoy_api_v2_core_HealthCheck_HttpHealthCheck__Output); + 'http_health_check'?: (_envoy_config_core_v3_HealthCheck_HttpHealthCheck__Output); /** * TCP health check. */ - 'tcp_health_check'?: (_envoy_api_v2_core_HealthCheck_TcpHealthCheck__Output); + 'tcp_health_check'?: (_envoy_config_core_v3_HealthCheck_TcpHealthCheck__Output); /** * gRPC health check. */ - 'grpc_health_check'?: (_envoy_api_v2_core_HealthCheck_GrpcHealthCheck__Output); + 'grpc_health_check'?: (_envoy_config_core_v3_HealthCheck_GrpcHealthCheck__Output); /** * The "no traffic interval" is a special health check interval that is used when a cluster has * never had traffic routed to it. This lower interval allows cluster information to be kept up to @@ -541,7 +554,7 @@ export interface HealthCheck__Output { /** * Custom health check. */ - 'custom_health_check'?: (_envoy_api_v2_core_HealthCheck_CustomHealthCheck__Output); + 'custom_health_check'?: (_envoy_config_core_v3_HealthCheck_CustomHealthCheck__Output); /** * The "unhealthy interval" is a health check interval that is used for hosts that are marked as * unhealthy. As soon as the host is marked as healthy, Envoy will shift back to using the @@ -596,12 +609,61 @@ export interface HealthCheck__Output { /** * This allows overriding the cluster TLS settings, just for health check connections. */ - 'tls_options'?: (_envoy_api_v2_core_HealthCheck_TlsOptions__Output); + 'tls_options'?: (_envoy_config_core_v3_HealthCheck_TlsOptions__Output); /** * [#not-implemented-hide:] * The gRPC service for the health check event service. * If empty, health check events won't be sent to a remote endpoint. */ - 'event_service'?: (_envoy_api_v2_core_EventServiceConfig__Output); + 'event_service'?: (_envoy_config_core_v3_EventServiceConfig__Output); + /** + * Optional key/value pairs that will be used to match a transport socket from those specified in the cluster's + * :ref:`tranport socket matches `. + * For example, the following match criteria + * + * .. code-block:: yaml + * + * transport_socket_match_criteria: + * useMTLS: true + * + * Will match the following :ref:`cluster socket match ` + * + * .. code-block:: yaml + * + * transport_socket_matches: + * - name: "useMTLS" + * match: + * useMTLS: true + * transport_socket: + * name: envoy.transport_sockets.tls + * config: { ... } # tls socket configuration + * + * If this field is set, then for health checks it will supersede an entry of *envoy.transport_socket* in the + * :ref:`LbEndpoint.Metadata `. + * This allows using different transport socket capabilities for health checking versus proxying to the + * endpoint. + * + * If the key/values pairs specified do not match any + * :ref:`transport socket matches `, + * the cluster's :ref:`transport socket ` + * will be used for health check socket configuration. + */ + 'transport_socket_match_criteria'?: (_google_protobuf_Struct__Output); + /** + * The "no traffic healthy interval" is a special health check interval that + * is used for hosts that are currently passing active health checking + * (including new hosts) when the cluster has received no traffic. + * + * This is useful for when we want to send frequent health checks with + * `no_traffic_interval` but then revert to lower frequency `no_traffic_healthy_interval` once + * a host in the cluster is marked as healthy. + * + * Once a cluster has been used for traffic routing, Envoy will shift back to using the + * standard health check interval that is defined. + * + * If no_traffic_healthy_interval is not set, it will default to the + * no traffic interval and send that interval regardless of health state. + */ + 'no_traffic_healthy_interval'?: (_google_protobuf_Duration__Output); 'health_checker': "http_health_check"|"tcp_health_check"|"grpc_health_check"|"custom_health_check"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HealthStatus.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HealthStatus.ts similarity index 91% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/core/HealthStatus.ts rename to packages/grpc-js-xds/src/generated/envoy/config/core/v3/HealthStatus.ts index e1d572fa4..6ecbca272 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HealthStatus.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HealthStatus.ts @@ -1,4 +1,4 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/health_check.proto +// Original file: deps/envoy-api/envoy/config/core/v3/health_check.proto /** * Endpoint health status. diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Http1ProtocolOptions.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http1ProtocolOptions.ts similarity index 57% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/core/Http1ProtocolOptions.ts rename to packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http1ProtocolOptions.ts index b9bb0ce54..982f58b0e 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Http1ProtocolOptions.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http1ProtocolOptions.ts @@ -1,8 +1,8 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/protocol.proto +// Original file: deps/envoy-api/envoy/config/core/v3/protocol.proto import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; -export interface _envoy_api_v2_core_Http1ProtocolOptions_HeaderKeyFormat { +export interface _envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat { /** * Formats the header by proper casing words: the first character and any character following * a special character will be capitalized if it's an alpha character. For example, @@ -10,11 +10,11 @@ export interface _envoy_api_v2_core_Http1ProtocolOptions_HeaderKeyFormat { * Note that while this results in most headers following conventional casing, certain headers * are not covered. For example, the "TE" header will be formatted as "Te". */ - 'proper_case_words'?: (_envoy_api_v2_core_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords); + 'proper_case_words'?: (_envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords); 'header_format'?: "proper_case_words"; } -export interface _envoy_api_v2_core_Http1ProtocolOptions_HeaderKeyFormat__Output { +export interface _envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat__Output { /** * Formats the header by proper casing words: the first character and any character following * a special character will be capitalized if it's an alpha character. For example, @@ -22,18 +22,18 @@ export interface _envoy_api_v2_core_Http1ProtocolOptions_HeaderKeyFormat__Output * Note that while this results in most headers following conventional casing, certain headers * are not covered. For example, the "TE" header will be formatted as "Te". */ - 'proper_case_words'?: (_envoy_api_v2_core_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords__Output); + 'proper_case_words'?: (_envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords__Output); 'header_format': "proper_case_words"; } -export interface _envoy_api_v2_core_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords { +export interface _envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords { } -export interface _envoy_api_v2_core_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords__Output { +export interface _envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords__Output { } /** - * [#next-free-field: 6] + * [#next-free-field: 8] */ export interface Http1ProtocolOptions { /** @@ -60,7 +60,7 @@ export interface Http1ProtocolOptions { * Describes how the keys for response headers should be formatted. By default, all header keys * are lower cased. */ - 'header_key_format'?: (_envoy_api_v2_core_Http1ProtocolOptions_HeaderKeyFormat); + 'header_key_format'?: (_envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat); /** * Enables trailers for HTTP/1. By default the HTTP/1 codec drops proxied trailers. * @@ -73,10 +73,30 @@ export interface Http1ProtocolOptions { * - The content length header is not present. */ 'enable_trailers'?: (boolean); + /** + * Allows Envoy to process requests/responses with both `Content-Length` and `Transfer-Encoding` + * headers set. By default such messages are rejected, but if option is enabled - Envoy will + * remove Content-Length header and process message. + * See `RFC7230, sec. 3.3.3 ` for details. + * + * .. attention:: + * Enabling this option might lead to request smuggling vulnerability, especially if traffic + * is proxied via multiple layers of proxies. + */ + 'allow_chunked_length'?: (boolean); + /** + * Allows invalid HTTP messaging. When this option is false, then Envoy will terminate + * HTTP/1.1 connections upon receiving an invalid HTTP message. However, + * when this option is true, then Envoy will leave the HTTP/1.1 connection + * open where possible. + * If set, this overrides any HCM :ref:`stream_error_on_invalid_http_messaging + * `. + */ + 'override_stream_error_on_invalid_http_message'?: (_google_protobuf_BoolValue); } /** - * [#next-free-field: 6] + * [#next-free-field: 8] */ export interface Http1ProtocolOptions__Output { /** @@ -103,7 +123,7 @@ export interface Http1ProtocolOptions__Output { * Describes how the keys for response headers should be formatted. By default, all header keys * are lower cased. */ - 'header_key_format'?: (_envoy_api_v2_core_Http1ProtocolOptions_HeaderKeyFormat__Output); + 'header_key_format'?: (_envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat__Output); /** * Enables trailers for HTTP/1. By default the HTTP/1 codec drops proxied trailers. * @@ -116,4 +136,24 @@ export interface Http1ProtocolOptions__Output { * - The content length header is not present. */ 'enable_trailers': (boolean); + /** + * Allows Envoy to process requests/responses with both `Content-Length` and `Transfer-Encoding` + * headers set. By default such messages are rejected, but if option is enabled - Envoy will + * remove Content-Length header and process message. + * See `RFC7230, sec. 3.3.3 ` for details. + * + * .. attention:: + * Enabling this option might lead to request smuggling vulnerability, especially if traffic + * is proxied via multiple layers of proxies. + */ + 'allow_chunked_length': (boolean); + /** + * Allows invalid HTTP messaging. When this option is false, then Envoy will terminate + * HTTP/1.1 connections upon receiving an invalid HTTP message. However, + * when this option is true, then Envoy will leave the HTTP/1.1 connection + * open where possible. + * If set, this overrides any HCM :ref:`stream_error_on_invalid_http_messaging + * `. + */ + 'override_stream_error_on_invalid_http_message'?: (_google_protobuf_BoolValue__Output); } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Http2ProtocolOptions.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http2ProtocolOptions.ts similarity index 65% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/core/Http2ProtocolOptions.ts rename to packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http2ProtocolOptions.ts index 893f61a15..e379d44be 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Http2ProtocolOptions.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http2ProtocolOptions.ts @@ -1,12 +1,14 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/protocol.proto +// Original file: deps/envoy-api/envoy/config/core/v3/protocol.proto import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; +import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; +import type { KeepaliveSettings as _envoy_config_core_v3_KeepaliveSettings, KeepaliveSettings__Output as _envoy_config_core_v3_KeepaliveSettings__Output } from '../../../../envoy/config/core/v3/KeepaliveSettings'; /** * Defines a parameter to be sent in the SETTINGS frame. * See `RFC7540, sec. 6.5.1 `_ for details. */ -export interface _envoy_api_v2_core_Http2ProtocolOptions_SettingsParameter { +export interface _envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter { /** * The 16 bit parameter identifier. */ @@ -21,7 +23,7 @@ export interface _envoy_api_v2_core_Http2ProtocolOptions_SettingsParameter { * Defines a parameter to be sent in the SETTINGS frame. * See `RFC7540, sec. 6.5.1 `_ for details. */ -export interface _envoy_api_v2_core_Http2ProtocolOptions_SettingsParameter__Output { +export interface _envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter__Output { /** * The 16 bit parameter identifier. */ @@ -33,7 +35,7 @@ export interface _envoy_api_v2_core_Http2ProtocolOptions_SettingsParameter__Outp } /** - * [#next-free-field: 14] + * [#next-free-field: 16] */ export interface Http2ProtocolOptions { /** @@ -81,7 +83,7 @@ export interface Http2ProtocolOptions { * Still under implementation. DO NOT USE. * * Allows metadata. See [metadata - * docs](https://github.com/envoyproxy/envoy/blob/master/source/docs/h2_metadata.md) for more + * docs](https://github.com/envoyproxy/envoy/blob/main/source/docs/h2_metadata.md) for more * information. */ 'allow_metadata'?: (boolean); @@ -90,7 +92,8 @@ export interface Http2ProtocolOptions { * be written into the socket). Exceeding this limit triggers flood mitigation and connection is * terminated. The ``http2.outbound_flood`` stat tracks the number of terminated connections due * to flood mitigation. The default limit is 10000. - * [#comment:TODO: implement same limits for upstream outbound frames as well.] + * NOTE: flood and abuse mitigation for upstream connections is presently enabled by the + * `envoy.reloadable_features.upstream_http2_flood_checks` flag. */ 'max_outbound_frames'?: (_google_protobuf_UInt32Value); /** @@ -99,7 +102,8 @@ export interface Http2ProtocolOptions { * this limit triggers flood mitigation and connection is terminated. The * ``http2.outbound_control_flood`` stat tracks the number of terminated connections due to flood * mitigation. The default limit is 1000. - * [#comment:TODO: implement same limits for upstream outbound frames as well.] + * NOTE: flood and abuse mitigation for upstream connections is presently enabled by the + * `envoy.reloadable_features.upstream_http2_flood_checks` flag. */ 'max_outbound_control_frames'?: (_google_protobuf_UInt32Value); /** @@ -109,7 +113,8 @@ export interface Http2ProtocolOptions { * stat tracks the number of connections terminated due to flood mitigation. * Setting this to 0 will terminate connection upon receiving first frame with an empty payload * and no end stream flag. The default limit is 1. - * [#comment:TODO: implement same limits for upstream inbound frames as well.] + * NOTE: flood and abuse mitigation for upstream connections is presently enabled by the + * `envoy.reloadable_features.upstream_http2_flood_checks` flag. */ 'max_consecutive_inbound_frames_with_empty_payload'?: (_google_protobuf_UInt32Value); /** @@ -117,11 +122,15 @@ export interface Http2ProtocolOptions { * of PRIORITY frames received over the lifetime of connection exceeds the value calculated * using this formula:: * - * max_inbound_priority_frames_per_stream * (1 + inbound_streams) + * max_inbound_priority_frames_per_stream * (1 + opened_streams) * - * the connection is terminated. The ``http2.inbound_priority_frames_flood`` stat tracks + * the connection is terminated. For downstream connections the `opened_streams` is incremented when + * Envoy receives complete response headers from the upstream server. For upstream connection the + * `opened_streams` is incremented when Envoy send the HEADERS frame for a new stream. The + * ``http2.inbound_priority_frames_flood`` stat tracks * the number of connections terminated due to flood mitigation. The default limit is 100. - * [#comment:TODO: implement same limits for upstream inbound frames as well.] + * NOTE: flood and abuse mitigation for upstream connections is presently enabled by the + * `envoy.reloadable_features.upstream_http2_flood_checks` flag. */ 'max_inbound_priority_frames_per_stream'?: (_google_protobuf_UInt32Value); /** @@ -129,14 +138,18 @@ export interface Http2ProtocolOptions { * of WINDOW_UPDATE frames received over the lifetime of connection exceeds the value calculated * using this formula:: * - * 1 + 2 * (inbound_streams + + * 5 + 2 * (opened_streams + * max_inbound_window_update_frames_per_data_frame_sent * outbound_data_frames) * - * the connection is terminated. The ``http2.inbound_priority_frames_flood`` stat tracks - * the number of connections terminated due to flood mitigation. The default limit is 10. + * the connection is terminated. For downstream connections the `opened_streams` is incremented when + * Envoy receives complete response headers from the upstream server. For upstream connections the + * `opened_streams` is incremented when Envoy sends the HEADERS frame for a new stream. The + * ``http2.inbound_priority_frames_flood`` stat tracks the number of connections terminated due to + * flood mitigation. The default max_inbound_window_update_frames_per_data_frame_sent value is 10. * Setting this to 1 should be enough to support HTTP/2 implementations with basic flow control, * but more complex implementations that try to estimate available bandwidth require at least 2. - * [#comment:TODO: implement same limits for upstream inbound frames as well.] + * NOTE: flood and abuse mitigation for upstream connections is presently enabled by the + * `envoy.reloadable_features.upstream_http2_flood_checks` flag. */ 'max_inbound_window_update_frames_per_data_frame_sent'?: (_google_protobuf_UInt32Value); /** @@ -144,6 +157,13 @@ export interface Http2ProtocolOptions { * the whole HTTP/2 connection is terminated upon receiving invalid HEADERS frame. However, * when this option is enabled, only the offending stream is terminated. * + * This is overridden by HCM :ref:`stream_error_on_invalid_http_messaging + * ` + * iff present. + * + * This is deprecated in favor of :ref:`override_stream_error_on_invalid_http_message + * ` + * * See `RFC7540, sec. 8.1 `_ for details. */ 'stream_error_on_invalid_http_messaging'?: (boolean); @@ -175,11 +195,27 @@ export interface Http2ProtocolOptions { * `_ for * standardized identifiers. */ - 'custom_settings_parameters'?: (_envoy_api_v2_core_Http2ProtocolOptions_SettingsParameter)[]; + 'custom_settings_parameters'?: (_envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter)[]; + /** + * Allows invalid HTTP messaging and headers. When this option is disabled (default), then + * the whole HTTP/2 connection is terminated upon receiving invalid HEADERS frame. However, + * when this option is enabled, only the offending stream is terminated. + * + * This overrides any HCM :ref:`stream_error_on_invalid_http_messaging + * ` + * + * See `RFC7540, sec. 8.1 `_ for details. + */ + 'override_stream_error_on_invalid_http_message'?: (_google_protobuf_BoolValue); + /** + * Send HTTP/2 PING frames to verify that the connection is still healthy. If the remote peer + * does not respond within the configured timeout, the connection will be aborted. + */ + 'connection_keepalive'?: (_envoy_config_core_v3_KeepaliveSettings); } /** - * [#next-free-field: 14] + * [#next-free-field: 16] */ export interface Http2ProtocolOptions__Output { /** @@ -227,7 +263,7 @@ export interface Http2ProtocolOptions__Output { * Still under implementation. DO NOT USE. * * Allows metadata. See [metadata - * docs](https://github.com/envoyproxy/envoy/blob/master/source/docs/h2_metadata.md) for more + * docs](https://github.com/envoyproxy/envoy/blob/main/source/docs/h2_metadata.md) for more * information. */ 'allow_metadata': (boolean); @@ -236,7 +272,8 @@ export interface Http2ProtocolOptions__Output { * be written into the socket). Exceeding this limit triggers flood mitigation and connection is * terminated. The ``http2.outbound_flood`` stat tracks the number of terminated connections due * to flood mitigation. The default limit is 10000. - * [#comment:TODO: implement same limits for upstream outbound frames as well.] + * NOTE: flood and abuse mitigation for upstream connections is presently enabled by the + * `envoy.reloadable_features.upstream_http2_flood_checks` flag. */ 'max_outbound_frames'?: (_google_protobuf_UInt32Value__Output); /** @@ -245,7 +282,8 @@ export interface Http2ProtocolOptions__Output { * this limit triggers flood mitigation and connection is terminated. The * ``http2.outbound_control_flood`` stat tracks the number of terminated connections due to flood * mitigation. The default limit is 1000. - * [#comment:TODO: implement same limits for upstream outbound frames as well.] + * NOTE: flood and abuse mitigation for upstream connections is presently enabled by the + * `envoy.reloadable_features.upstream_http2_flood_checks` flag. */ 'max_outbound_control_frames'?: (_google_protobuf_UInt32Value__Output); /** @@ -255,7 +293,8 @@ export interface Http2ProtocolOptions__Output { * stat tracks the number of connections terminated due to flood mitigation. * Setting this to 0 will terminate connection upon receiving first frame with an empty payload * and no end stream flag. The default limit is 1. - * [#comment:TODO: implement same limits for upstream inbound frames as well.] + * NOTE: flood and abuse mitigation for upstream connections is presently enabled by the + * `envoy.reloadable_features.upstream_http2_flood_checks` flag. */ 'max_consecutive_inbound_frames_with_empty_payload'?: (_google_protobuf_UInt32Value__Output); /** @@ -263,11 +302,15 @@ export interface Http2ProtocolOptions__Output { * of PRIORITY frames received over the lifetime of connection exceeds the value calculated * using this formula:: * - * max_inbound_priority_frames_per_stream * (1 + inbound_streams) + * max_inbound_priority_frames_per_stream * (1 + opened_streams) * - * the connection is terminated. The ``http2.inbound_priority_frames_flood`` stat tracks + * the connection is terminated. For downstream connections the `opened_streams` is incremented when + * Envoy receives complete response headers from the upstream server. For upstream connection the + * `opened_streams` is incremented when Envoy send the HEADERS frame for a new stream. The + * ``http2.inbound_priority_frames_flood`` stat tracks * the number of connections terminated due to flood mitigation. The default limit is 100. - * [#comment:TODO: implement same limits for upstream inbound frames as well.] + * NOTE: flood and abuse mitigation for upstream connections is presently enabled by the + * `envoy.reloadable_features.upstream_http2_flood_checks` flag. */ 'max_inbound_priority_frames_per_stream'?: (_google_protobuf_UInt32Value__Output); /** @@ -275,14 +318,18 @@ export interface Http2ProtocolOptions__Output { * of WINDOW_UPDATE frames received over the lifetime of connection exceeds the value calculated * using this formula:: * - * 1 + 2 * (inbound_streams + + * 5 + 2 * (opened_streams + * max_inbound_window_update_frames_per_data_frame_sent * outbound_data_frames) * - * the connection is terminated. The ``http2.inbound_priority_frames_flood`` stat tracks - * the number of connections terminated due to flood mitigation. The default limit is 10. + * the connection is terminated. For downstream connections the `opened_streams` is incremented when + * Envoy receives complete response headers from the upstream server. For upstream connections the + * `opened_streams` is incremented when Envoy sends the HEADERS frame for a new stream. The + * ``http2.inbound_priority_frames_flood`` stat tracks the number of connections terminated due to + * flood mitigation. The default max_inbound_window_update_frames_per_data_frame_sent value is 10. * Setting this to 1 should be enough to support HTTP/2 implementations with basic flow control, * but more complex implementations that try to estimate available bandwidth require at least 2. - * [#comment:TODO: implement same limits for upstream inbound frames as well.] + * NOTE: flood and abuse mitigation for upstream connections is presently enabled by the + * `envoy.reloadable_features.upstream_http2_flood_checks` flag. */ 'max_inbound_window_update_frames_per_data_frame_sent'?: (_google_protobuf_UInt32Value__Output); /** @@ -290,6 +337,13 @@ export interface Http2ProtocolOptions__Output { * the whole HTTP/2 connection is terminated upon receiving invalid HEADERS frame. However, * when this option is enabled, only the offending stream is terminated. * + * This is overridden by HCM :ref:`stream_error_on_invalid_http_messaging + * ` + * iff present. + * + * This is deprecated in favor of :ref:`override_stream_error_on_invalid_http_message + * ` + * * See `RFC7540, sec. 8.1 `_ for details. */ 'stream_error_on_invalid_http_messaging': (boolean); @@ -321,5 +375,21 @@ export interface Http2ProtocolOptions__Output { * `_ for * standardized identifiers. */ - 'custom_settings_parameters': (_envoy_api_v2_core_Http2ProtocolOptions_SettingsParameter__Output)[]; + 'custom_settings_parameters': (_envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter__Output)[]; + /** + * Allows invalid HTTP messaging and headers. When this option is disabled (default), then + * the whole HTTP/2 connection is terminated upon receiving invalid HEADERS frame. However, + * when this option is enabled, only the offending stream is terminated. + * + * This overrides any HCM :ref:`stream_error_on_invalid_http_messaging + * ` + * + * See `RFC7540, sec. 8.1 `_ for details. + */ + 'override_stream_error_on_invalid_http_message'?: (_google_protobuf_BoolValue__Output); + /** + * Send HTTP/2 PING frames to verify that the connection is still healthy. If the remote peer + * does not respond within the configured timeout, the connection will be aborted. + */ + 'connection_keepalive'?: (_envoy_config_core_v3_KeepaliveSettings__Output); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http3ProtocolOptions.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http3ProtocolOptions.ts new file mode 100644 index 000000000..320285d87 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http3ProtocolOptions.ts @@ -0,0 +1,22 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/protocol.proto + + +/** + * [#not-implemented-hide:] + * + * A message which allows using HTTP/3 as an upstream protocol. + * + * Eventually this will include configuration for tuning HTTP/3. + */ +export interface Http3ProtocolOptions { +} + +/** + * [#not-implemented-hide:] + * + * A message which allows using HTTP/3 as an upstream protocol. + * + * Eventually this will include configuration for tuning HTTP/3. + */ +export interface Http3ProtocolOptions__Output { +} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HttpProtocolOptions.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HttpProtocolOptions.ts similarity index 75% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/core/HttpProtocolOptions.ts rename to packages/grpc-js-xds/src/generated/envoy/config/core/v3/HttpProtocolOptions.ts index 219fdb0c7..4a5efeebd 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HttpProtocolOptions.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HttpProtocolOptions.ts @@ -1,9 +1,9 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/protocol.proto +// Original file: deps/envoy-api/envoy/config/core/v3/protocol.proto import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; -// Original file: deps/envoy-api/envoy/api/v2/core/protocol.proto +// Original file: deps/envoy-api/envoy/config/core/v3/protocol.proto /** * Action to take when Envoy receives client request with header names containing underscore @@ -12,7 +12,7 @@ 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_api_v2_core_HttpProtocolOptions_HeadersWithUnderscoresAction { +export enum _envoy_config_core_v3_HttpProtocolOptions_HeadersWithUnderscoresAction { /** * Allow headers with underscores. This is the default behavior. */ @@ -41,13 +41,17 @@ export interface HttpProtocolOptions { * idle timeout is reached the connection will be closed. If the connection is an HTTP/2 * downstream connection a drain sequence will occur prior to closing the connection, see * :ref:`drain_timeout - * `. + * `. * Note that request based timeouts mean that HTTP/2 PINGs will not keep the connection alive. * If not specified, this defaults to 1 hour. To disable idle timeouts explicitly set this to 0. * * .. warning:: * Disabling this timeout has a highly likelihood of yielding connection leaks due to lost TCP * FIN packets, etc. + * + * If the :ref:`overload action ` "envoy.overload_actions.reduce_timeouts" + * is configured, this timeout is scaled for downstream connections according to the value for + * :ref:`HTTP_DOWNSTREAM_CONNECTION_IDLE `. */ 'idle_timeout'?: (_google_protobuf_Duration); /** @@ -61,7 +65,7 @@ export interface HttpProtocolOptions { * was established. If not set, there is no max duration. When max_connection_duration is reached * the connection will be closed. Drain sequence will occur prior to closing the connection if * if's applicable. See :ref:`drain_timeout - * `. + * `. * Note: not implemented for upstream connections. */ 'max_connection_duration'?: (_google_protobuf_Duration); @@ -75,7 +79,7 @@ export interface HttpProtocolOptions { * If this setting is not specified, the value defaults to ALLOW. * Note: upstream responses are not affected by this setting. */ - 'headers_with_underscores_action'?: (_envoy_api_v2_core_HttpProtocolOptions_HeadersWithUnderscoresAction | keyof typeof _envoy_api_v2_core_HttpProtocolOptions_HeadersWithUnderscoresAction); + 'headers_with_underscores_action'?: (_envoy_config_core_v3_HttpProtocolOptions_HeadersWithUnderscoresAction | keyof typeof _envoy_config_core_v3_HttpProtocolOptions_HeadersWithUnderscoresAction); } /** @@ -88,13 +92,17 @@ export interface HttpProtocolOptions__Output { * idle timeout is reached the connection will be closed. If the connection is an HTTP/2 * downstream connection a drain sequence will occur prior to closing the connection, see * :ref:`drain_timeout - * `. + * `. * Note that request based timeouts mean that HTTP/2 PINGs will not keep the connection alive. * If not specified, this defaults to 1 hour. To disable idle timeouts explicitly set this to 0. * * .. warning:: * Disabling this timeout has a highly likelihood of yielding connection leaks due to lost TCP * FIN packets, etc. + * + * If the :ref:`overload action ` "envoy.overload_actions.reduce_timeouts" + * is configured, this timeout is scaled for downstream connections according to the value for + * :ref:`HTTP_DOWNSTREAM_CONNECTION_IDLE `. */ 'idle_timeout'?: (_google_protobuf_Duration__Output); /** @@ -108,7 +116,7 @@ export interface HttpProtocolOptions__Output { * was established. If not set, there is no max duration. When max_connection_duration is reached * the connection will be closed. Drain sequence will occur prior to closing the connection if * if's applicable. See :ref:`drain_timeout - * `. + * `. * Note: not implemented for upstream connections. */ 'max_connection_duration'?: (_google_protobuf_Duration__Output); @@ -122,5 +130,5 @@ export interface HttpProtocolOptions__Output { * If this setting is not specified, the value defaults to ALLOW. * Note: upstream responses are not affected by this setting. */ - 'headers_with_underscores_action': (keyof typeof _envoy_api_v2_core_HttpProtocolOptions_HeadersWithUnderscoresAction); + 'headers_with_underscores_action': (keyof typeof _envoy_config_core_v3_HttpProtocolOptions_HeadersWithUnderscoresAction); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HttpUri.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HttpUri.ts new file mode 100644 index 000000000..5da6ed4c0 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HttpUri.ts @@ -0,0 +1,79 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/http_uri.proto + +import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; + +/** + * Envoy external URI descriptor + */ +export interface HttpUri { + /** + * The HTTP server URI. It should be a full FQDN with protocol, host and path. + * + * Example: + * + * .. code-block:: yaml + * + * uri: https://www.googleapis.com/oauth2/v1/certs + */ + 'uri'?: (string); + /** + * A cluster is created in the Envoy "cluster_manager" config + * section. This field specifies the cluster name. + * + * Example: + * + * .. code-block:: yaml + * + * cluster: jwks_cluster + */ + 'cluster'?: (string); + /** + * Sets the maximum duration in milliseconds that a response can take to arrive upon request. + */ + 'timeout'?: (_google_protobuf_Duration); + /** + * Specify how `uri` is to be fetched. Today, this requires an explicit + * cluster, but in the future we may support dynamic cluster creation or + * inline DNS resolution. See `issue + * `_. + */ + 'http_upstream_type'?: "cluster"; +} + +/** + * Envoy external URI descriptor + */ +export interface HttpUri__Output { + /** + * The HTTP server URI. It should be a full FQDN with protocol, host and path. + * + * Example: + * + * .. code-block:: yaml + * + * uri: https://www.googleapis.com/oauth2/v1/certs + */ + 'uri': (string); + /** + * A cluster is created in the Envoy "cluster_manager" config + * section. This field specifies the cluster name. + * + * Example: + * + * .. code-block:: yaml + * + * cluster: jwks_cluster + */ + 'cluster'?: (string); + /** + * Sets the maximum duration in milliseconds that a response can take to arrive upon request. + */ + 'timeout'?: (_google_protobuf_Duration__Output); + /** + * Specify how `uri` is to be fetched. Today, this requires an explicit + * cluster, but in the future we may support dynamic cluster creation or + * inline DNS resolution. See `issue + * `_. + */ + 'http_upstream_type': "cluster"; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/KeepaliveSettings.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/KeepaliveSettings.ts new file mode 100644 index 000000000..cb2e14c58 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/KeepaliveSettings.ts @@ -0,0 +1,40 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/protocol.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 KeepaliveSettings { + /** + * Send HTTP/2 PING frames at this period, in order to test that the connection is still alive. + */ + 'interval'?: (_google_protobuf_Duration); + /** + * How long to wait for a response to a keepalive PING. If a response is not received within this + * time period, the connection will be aborted. + */ + 'timeout'?: (_google_protobuf_Duration); + /** + * A random jitter amount as a percentage of interval that will be added to each interval. + * A value of zero means there will be no jitter. + * The default value is 15%. + */ + 'interval_jitter'?: (_envoy_type_v3_Percent); +} + +export interface KeepaliveSettings__Output { + /** + * Send HTTP/2 PING frames at this period, in order to test that the connection is still alive. + */ + 'interval'?: (_google_protobuf_Duration__Output); + /** + * How long to wait for a response to a keepalive PING. If a response is not received within this + * time period, the connection will be aborted. + */ + 'timeout'?: (_google_protobuf_Duration__Output); + /** + * A random jitter amount as a percentage of interval that will be added to each interval. + * A value of zero means there will be no jitter. + * The default value is 15%. + */ + 'interval_jitter'?: (_envoy_type_v3_Percent__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Locality.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Locality.ts new file mode 100644 index 000000000..2b4b42a75 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Locality.ts @@ -0,0 +1,56 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + + +/** + * Identifies location of where either Envoy runs or where upstream hosts run. + */ +export interface Locality { + /** + * Region this :ref:`zone ` belongs to. + */ + 'region'?: (string); + /** + * Defines the local service zone where Envoy is running. Though optional, it + * should be set if discovery service routing is used and the discovery + * service exposes :ref:`zone data `, + * either in this message or via :option:`--service-zone`. The meaning of zone + * is context dependent, e.g. `Availability Zone (AZ) + * `_ + * on AWS, `Zone `_ on + * GCP, etc. + */ + 'zone'?: (string); + /** + * When used for locality of upstream hosts, this field further splits zone + * into smaller chunks of sub-zones so they can be load balanced + * independently. + */ + 'sub_zone'?: (string); +} + +/** + * Identifies location of where either Envoy runs or where upstream hosts run. + */ +export interface Locality__Output { + /** + * Region this :ref:`zone ` belongs to. + */ + 'region': (string); + /** + * Defines the local service zone where Envoy is running. Though optional, it + * should be set if discovery service routing is used and the discovery + * service exposes :ref:`zone data `, + * either in this message or via :option:`--service-zone`. The meaning of zone + * is context dependent, e.g. `Availability Zone (AZ) + * `_ + * on AWS, `Zone `_ on + * GCP, etc. + */ + 'zone': (string); + /** + * When used for locality of upstream hosts, this field further splits zone + * into smaller chunks of sub-zones so they can be load balanced + * independently. + */ + 'sub_zone': (string); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Metadata.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Metadata.ts new file mode 100644 index 000000000..6d7181f18 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Metadata.ts @@ -0,0 +1,67 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + +import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; + +/** + * Metadata provides additional inputs to filters based on matched listeners, + * filter chains, routes and endpoints. It is structured as a map, usually from + * filter name (in reverse DNS format) to metadata specific to the filter. Metadata + * key-values for a filter are merged as connection and request handling occurs, + * with later values for the same key overriding earlier values. + * + * An example use of metadata is providing additional values to + * http_connection_manager in the envoy.http_connection_manager.access_log + * namespace. + * + * Another example use of metadata is to per service config info in cluster metadata, which may get + * consumed by multiple filters. + * + * For load balancing, Metadata provides a means to subset cluster endpoints. + * Endpoints have a Metadata object associated and routes contain a Metadata + * object to match against. There are some well defined metadata used today for + * this purpose: + * + * * ``{"envoy.lb": {"canary": }}`` This indicates the canary status of an + * endpoint and is also used during header processing + * (x-envoy-upstream-canary) and for stats purposes. + * [#next-major-version: move to type/metadata/v2] + */ +export interface Metadata { + /** + * Key is the reverse DNS filter name, e.g. com.acme.widget. The envoy.* + * namespace is reserved for Envoy's built-in filters. + */ + 'filter_metadata'?: ({[key: string]: _google_protobuf_Struct}); +} + +/** + * Metadata provides additional inputs to filters based on matched listeners, + * filter chains, routes and endpoints. It is structured as a map, usually from + * filter name (in reverse DNS format) to metadata specific to the filter. Metadata + * key-values for a filter are merged as connection and request handling occurs, + * with later values for the same key overriding earlier values. + * + * An example use of metadata is providing additional values to + * http_connection_manager in the envoy.http_connection_manager.access_log + * namespace. + * + * Another example use of metadata is to per service config info in cluster metadata, which may get + * consumed by multiple filters. + * + * For load balancing, Metadata provides a means to subset cluster endpoints. + * Endpoints have a Metadata object associated and routes contain a Metadata + * object to match against. There are some well defined metadata used today for + * this purpose: + * + * * ``{"envoy.lb": {"canary": }}`` This indicates the canary status of an + * endpoint and is also used during header processing + * (x-envoy-upstream-canary) and for stats purposes. + * [#next-major-version: move to type/metadata/v2] + */ +export interface Metadata__Output { + /** + * Key is the reverse DNS filter name, e.g. com.acme.widget. The envoy.* + * namespace is reserved for Envoy's built-in filters. + */ + 'filter_metadata'?: ({[key: string]: _google_protobuf_Struct__Output}); +} 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 new file mode 100644 index 000000000..717263976 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Node.ts @@ -0,0 +1,159 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + +import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; +import type { Locality as _envoy_config_core_v3_Locality, Locality__Output as _envoy_config_core_v3_Locality__Output } from '../../../../envoy/config/core/v3/Locality'; +import type { BuildVersion as _envoy_config_core_v3_BuildVersion, BuildVersion__Output as _envoy_config_core_v3_BuildVersion__Output } from '../../../../envoy/config/core/v3/BuildVersion'; +import type { Extension as _envoy_config_core_v3_Extension, Extension__Output as _envoy_config_core_v3_Extension__Output } from '../../../../envoy/config/core/v3/Extension'; +import type { Address as _envoy_config_core_v3_Address, Address__Output as _envoy_config_core_v3_Address__Output } from '../../../../envoy/config/core/v3/Address'; + +/** + * Identifies a specific Envoy instance. The node identifier is presented to the + * management server, which may use this identifier to distinguish per Envoy + * configuration for serving. + * [#next-free-field: 12] + */ +export interface Node { + /** + * An opaque node identifier for the Envoy node. This also provides the local + * service node name. It should be set if any of the following features are + * used: :ref:`statsd `, :ref:`CDS + * `, and :ref:`HTTP tracing + * `, either in this message or via + * :option:`--service-node`. + */ + 'id'?: (string); + /** + * Defines the local service cluster name where Envoy is running. Though + * optional, it should be set if any of the following features are used: + * :ref:`statsd `, :ref:`health check cluster + * verification + * `, + * :ref:`runtime override directory `, + * :ref:`user agent addition + * `, + * :ref:`HTTP global rate limiting `, + * :ref:`CDS `, and :ref:`HTTP tracing + * `, either in this message or via + * :option:`--service-cluster`. + */ + 'cluster'?: (string); + /** + * Opaque metadata extending the node identifier. Envoy will pass this + * directly to the management server. + */ + 'metadata'?: (_google_protobuf_Struct); + /** + * Locality specifying where the Envoy instance is running. + */ + 'locality'?: (_envoy_config_core_v3_Locality); + /** + * Free-form string that identifies the entity requesting config. + * E.g. "envoy" or "grpc" + */ + 'user_agent_name'?: (string); + /** + * Free-form string that identifies the version of the entity requesting config. + * E.g. "1.12.2" or "abcd1234", or "SpecialEnvoyBuild" + */ + 'user_agent_version'?: (string); + /** + * Structured version of the entity requesting config. + */ + 'user_agent_build_version'?: (_envoy_config_core_v3_BuildVersion); + /** + * List of extensions and their versions supported by the node. + */ + 'extensions'?: (_envoy_config_core_v3_Extension)[]; + /** + * Client feature support list. These are well known features described + * in the Envoy API repository for a given major version of an API. Client features + * use reverse DNS naming scheme, for example `com.acme.feature`. + * See :ref:`the list of features ` that xDS client may + * support. + */ + 'client_features'?: (string)[]; + /** + * Known listening ports on the node as a generic hint to the management server + * 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. + */ + 'listening_addresses'?: (_envoy_config_core_v3_Address)[]; + 'user_agent_version_type'?: "user_agent_version"|"user_agent_build_version"; +} + +/** + * Identifies a specific Envoy instance. The node identifier is presented to the + * management server, which may use this identifier to distinguish per Envoy + * configuration for serving. + * [#next-free-field: 12] + */ +export interface Node__Output { + /** + * An opaque node identifier for the Envoy node. This also provides the local + * service node name. It should be set if any of the following features are + * used: :ref:`statsd `, :ref:`CDS + * `, and :ref:`HTTP tracing + * `, either in this message or via + * :option:`--service-node`. + */ + 'id': (string); + /** + * Defines the local service cluster name where Envoy is running. Though + * optional, it should be set if any of the following features are used: + * :ref:`statsd `, :ref:`health check cluster + * verification + * `, + * :ref:`runtime override directory `, + * :ref:`user agent addition + * `, + * :ref:`HTTP global rate limiting `, + * :ref:`CDS `, and :ref:`HTTP tracing + * `, either in this message or via + * :option:`--service-cluster`. + */ + 'cluster': (string); + /** + * Opaque metadata extending the node identifier. Envoy will pass this + * directly to the management server. + */ + 'metadata'?: (_google_protobuf_Struct__Output); + /** + * Locality specifying where the Envoy instance is running. + */ + 'locality'?: (_envoy_config_core_v3_Locality__Output); + /** + * Free-form string that identifies the entity requesting config. + * E.g. "envoy" or "grpc" + */ + 'user_agent_name': (string); + /** + * Free-form string that identifies the version of the entity requesting config. + * E.g. "1.12.2" or "abcd1234", or "SpecialEnvoyBuild" + */ + 'user_agent_version'?: (string); + /** + * Structured version of the entity requesting config. + */ + 'user_agent_build_version'?: (_envoy_config_core_v3_BuildVersion__Output); + /** + * List of extensions and their versions supported by the node. + */ + 'extensions': (_envoy_config_core_v3_Extension__Output)[]; + /** + * Client feature support list. These are well known features described + * in the Envoy API repository for a given major version of an API. Client features + * use reverse DNS naming scheme, for example `com.acme.feature`. + * See :ref:`the list of features ` that xDS client may + * support. + */ + 'client_features': (string)[]; + /** + * Known listening ports on the node as a generic hint to the management server + * 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. + */ + 'listening_addresses': (_envoy_config_core_v3_Address__Output)[]; + 'user_agent_version_type': "user_agent_version"|"user_agent_build_version"; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Pipe.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Pipe.ts new file mode 100644 index 000000000..3d8fdb1c8 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Pipe.ts @@ -0,0 +1,30 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/address.proto + + +export interface Pipe { + /** + * Unix Domain Socket path. On Linux, paths starting with '@' will use the + * abstract namespace. The starting '@' is replaced by a null byte by Envoy. + * Paths starting with '@' will result in an error in environments other than + * Linux. + */ + 'path'?: (string); + /** + * The mode for the Pipe. Not applicable for abstract sockets. + */ + 'mode'?: (number); +} + +export interface Pipe__Output { + /** + * Unix Domain Socket path. On Linux, paths starting with '@' will use the + * abstract namespace. The starting '@' is replaced by a null byte by Envoy. + * Paths starting with '@' will result in an error in environments other than + * Linux. + */ + 'path': (string); + /** + * The mode for the Pipe. Not applicable for abstract sockets. + */ + 'mode': (number); +} 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 new file mode 100644 index 000000000..a28de2dbe --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ProxyProtocolConfig.ts @@ -0,0 +1,29 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/proxy_protocol.proto + + +// Original file: deps/envoy-api/envoy/config/core/v3/proxy_protocol.proto + +export enum _envoy_config_core_v3_ProxyProtocolConfig_Version { + /** + * PROXY protocol version 1. Human readable format. + */ + V1 = 0, + /** + * PROXY protocol version 2. Binary format. + */ + V2 = 1, +} + +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); +} + +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); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RateLimitSettings.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RateLimitSettings.ts similarity index 94% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/core/RateLimitSettings.ts rename to packages/grpc-js-xds/src/generated/envoy/config/core/v3/RateLimitSettings.ts index 222c86eb4..8f4093fd4 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RateLimitSettings.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RateLimitSettings.ts @@ -1,4 +1,4 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/config_source.proto +// Original file: deps/envoy-api/envoy/config/core/v3/config_source.proto import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; import type { DoubleValue as _google_protobuf_DoubleValue, DoubleValue__Output as _google_protobuf_DoubleValue__Output } from '../../../../google/protobuf/DoubleValue'; diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RemoteDataSource.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RemoteDataSource.ts new file mode 100644 index 000000000..99634015f --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RemoteDataSource.ts @@ -0,0 +1,40 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + +import type { HttpUri as _envoy_config_core_v3_HttpUri, HttpUri__Output as _envoy_config_core_v3_HttpUri__Output } from '../../../../envoy/config/core/v3/HttpUri'; +import type { RetryPolicy as _envoy_config_core_v3_RetryPolicy, RetryPolicy__Output as _envoy_config_core_v3_RetryPolicy__Output } from '../../../../envoy/config/core/v3/RetryPolicy'; + +/** + * The message specifies how to fetch data from remote and how to verify it. + */ +export interface RemoteDataSource { + /** + * The HTTP URI to fetch the remote data. + */ + 'http_uri'?: (_envoy_config_core_v3_HttpUri); + /** + * SHA256 string for verifying data. + */ + 'sha256'?: (string); + /** + * Retry policy for fetching remote data. + */ + 'retry_policy'?: (_envoy_config_core_v3_RetryPolicy); +} + +/** + * The message specifies how to fetch data from remote and how to verify it. + */ +export interface RemoteDataSource__Output { + /** + * The HTTP URI to fetch the remote data. + */ + 'http_uri'?: (_envoy_config_core_v3_HttpUri__Output); + /** + * SHA256 string for verifying data. + */ + 'sha256': (string); + /** + * Retry policy for fetching remote data. + */ + 'retry_policy'?: (_envoy_config_core_v3_RetryPolicy__Output); +} 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 new file mode 100644 index 000000000..9be1aa6d1 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RequestMethod.ts @@ -0,0 +1,17 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + +/** + * 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, +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RetryPolicy.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RetryPolicy.ts new file mode 100644 index 000000000..6d0d9927b --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RetryPolicy.ts @@ -0,0 +1,38 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + +import type { BackoffStrategy as _envoy_config_core_v3_BackoffStrategy, BackoffStrategy__Output as _envoy_config_core_v3_BackoffStrategy__Output } from '../../../../envoy/config/core/v3/BackoffStrategy'; +import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; + +/** + * The message specifies the retry policy of remote data source when fetching fails. + */ +export interface RetryPolicy { + /** + * Specifies parameters that control :ref:`retry backoff strategy `. + * This parameter is optional, in which case the default base interval is 1000 milliseconds. The + * default maximum interval is 10 times the base interval. + */ + 'retry_back_off'?: (_envoy_config_core_v3_BackoffStrategy); + /** + * Specifies the allowed number of retries. This parameter is optional and + * defaults to 1. + */ + 'num_retries'?: (_google_protobuf_UInt32Value); +} + +/** + * The message specifies the retry policy of remote data source when fetching fails. + */ +export interface RetryPolicy__Output { + /** + * Specifies parameters that control :ref:`retry backoff strategy `. + * This parameter is optional, in which case the default base interval is 1000 milliseconds. The + * default maximum interval is 10 times the base interval. + */ + 'retry_back_off'?: (_envoy_config_core_v3_BackoffStrategy__Output); + /** + * Specifies the allowed number of retries. This parameter is optional and + * defaults to 1. + */ + 'num_retries'?: (_google_protobuf_UInt32Value__Output); +} 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 new file mode 100644 index 000000000..917d8a3df --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RoutingPriority.ts @@ -0,0 +1,15 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + +/** + * 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 enum RoutingPriority { + DEFAULT = 0, + HIGH = 1, +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeDouble.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeDouble.ts new file mode 100644 index 000000000..a0f849ab5 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeDouble.ts @@ -0,0 +1,30 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + + +/** + * Runtime derived double with a default when not specified. + */ +export interface RuntimeDouble { + /** + * Default value if runtime value is not available. + */ + 'default_value'?: (number | string); + /** + * Runtime key to get value for comparison. This value is used if defined. + */ + 'runtime_key'?: (string); +} + +/** + * Runtime derived double with a default when not specified. + */ +export interface RuntimeDouble__Output { + /** + * Default value if runtime value is not available. + */ + 'default_value': (number); + /** + * Runtime key to get value for comparison. This value is used if defined. + */ + 'runtime_key': (string); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeFeatureFlag.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeFeatureFlag.ts new file mode 100644 index 000000000..413a4f931 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeFeatureFlag.ts @@ -0,0 +1,35 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + +import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; + +/** + * Runtime derived bool with a default when not specified. + */ +export interface RuntimeFeatureFlag { + /** + * Default value if runtime value is not available. + */ + 'default_value'?: (_google_protobuf_BoolValue); + /** + * Runtime key to get value for comparison. This value is used if defined. The boolean value must + * be represented via its + * `canonical JSON encoding `_. + */ + 'runtime_key'?: (string); +} + +/** + * Runtime derived bool with a default when not specified. + */ +export interface RuntimeFeatureFlag__Output { + /** + * Default value if runtime value is not available. + */ + 'default_value'?: (_google_protobuf_BoolValue__Output); + /** + * Runtime key to get value for comparison. This value is used if defined. The boolean value must + * be represented via its + * `canonical JSON encoding `_. + */ + 'runtime_key': (string); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeFractionalPercent.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeFractionalPercent.ts new file mode 100644 index 000000000..5610f7bdd --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeFractionalPercent.ts @@ -0,0 +1,49 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + +import type { FractionalPercent as _envoy_type_v3_FractionalPercent, FractionalPercent__Output as _envoy_type_v3_FractionalPercent__Output } from '../../../../envoy/type/v3/FractionalPercent'; + +/** + * Runtime derived FractionalPercent with defaults for when the numerator or denominator is not + * specified via a runtime key. + * + * .. note:: + * + * Parsing of the runtime key's data is implemented such that it may be represented as a + * :ref:`FractionalPercent ` proto represented as JSON/YAML + * and may also be represented as an integer with the assumption that the value is an integral + * percentage out of 100. For instance, a runtime key lookup returning the value "42" would parse + * as a `FractionalPercent` whose numerator is 42 and denominator is HUNDRED. + */ +export interface RuntimeFractionalPercent { + /** + * Default value if the runtime value's for the numerator/denominator keys are not available. + */ + 'default_value'?: (_envoy_type_v3_FractionalPercent); + /** + * Runtime key for a YAML representation of a FractionalPercent. + */ + 'runtime_key'?: (string); +} + +/** + * Runtime derived FractionalPercent with defaults for when the numerator or denominator is not + * specified via a runtime key. + * + * .. note:: + * + * Parsing of the runtime key's data is implemented such that it may be represented as a + * :ref:`FractionalPercent ` proto represented as JSON/YAML + * and may also be represented as an integer with the assumption that the value is an integral + * percentage out of 100. For instance, a runtime key lookup returning the value "42" would parse + * as a `FractionalPercent` whose numerator is 42 and denominator is HUNDRED. + */ +export interface RuntimeFractionalPercent__Output { + /** + * Default value if the runtime value's for the numerator/denominator keys are not available. + */ + 'default_value'?: (_envoy_type_v3_FractionalPercent__Output); + /** + * Runtime key for a YAML representation of a FractionalPercent. + */ + 'runtime_key': (string); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimePercent.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimePercent.ts new file mode 100644 index 000000000..b317b5aa2 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimePercent.ts @@ -0,0 +1,31 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + +import type { Percent as _envoy_type_v3_Percent, Percent__Output as _envoy_type_v3_Percent__Output } from '../../../../envoy/type/v3/Percent'; + +/** + * Runtime derived percentage with a default when not specified. + */ +export interface RuntimePercent { + /** + * Default value if runtime value is not available. + */ + 'default_value'?: (_envoy_type_v3_Percent); + /** + * Runtime key to get value for comparison. This value is used if defined. + */ + 'runtime_key'?: (string); +} + +/** + * Runtime derived percentage with a default when not specified. + */ +export interface RuntimePercent__Output { + /** + * Default value if runtime value is not available. + */ + 'default_value'?: (_envoy_type_v3_Percent__Output); + /** + * Runtime key to get value for comparison. This value is used if defined. + */ + 'runtime_key': (string); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeUInt32.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeUInt32.ts new file mode 100644 index 000000000..6cc9eead6 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeUInt32.ts @@ -0,0 +1,30 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + + +/** + * Runtime derived uint32 with a default when not specified. + */ +export interface RuntimeUInt32 { + /** + * Default value if runtime value is not available. + */ + 'default_value'?: (number); + /** + * Runtime key to get value for comparison. This value is used if defined. + */ + 'runtime_key'?: (string); +} + +/** + * Runtime derived uint32 with a default when not specified. + */ +export interface RuntimeUInt32__Output { + /** + * Default value if runtime value is not available. + */ + 'default_value': (number); + /** + * Runtime key to get value for comparison. This value is used if defined. + */ + 'runtime_key': (string); +} 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 new file mode 100644 index 000000000..e387adca2 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SelfConfigSource.ts @@ -0,0 +1,31 @@ +// 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'; + +/** + * [#not-implemented-hide:] + * Self-referencing config source options. This is currently empty, but when + * set in :ref:`ConfigSource ` can be used to + * specify that other data can be obtained from the same server. + */ +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); +} + +/** + * [#not-implemented-hide:] + * Self-referencing config source options. This is currently empty, but when + * set in :ref:`ConfigSource ` can be used to + * specify that other data can be obtained from the same server. + */ +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); +} 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 new file mode 100644 index 000000000..e3f342d16 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SocketAddress.ts @@ -0,0 +1,97 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/address.proto + + +// Original file: deps/envoy-api/envoy/config/core/v3/address.proto + +export enum _envoy_config_core_v3_SocketAddress_Protocol { + TCP = 0, + UDP = 1, +} + +/** + * [#next-free-field: 7] + */ +export interface SocketAddress { + 'protocol'?: (_envoy_config_core_v3_SocketAddress_Protocol | keyof typeof _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 ``::`` + * to bind to any address. [#comment:TODO(zuercher) reinstate when implemented: + * It is possible to distinguish a Listener address via the prefix/suffix matching + * in :ref:`FilterChainMatch `.] When used + * within an upstream :ref:`BindConfig `, the address + * controls the source address of outbound connections. For :ref:`clusters + * `, the cluster type determines whether the + * address must be an IP (*STATIC* or *EDS* clusters) or a hostname resolved by DNS + * (*STRICT_DNS* or *LOGICAL_DNS* clusters). Address resolution can be customized + * via :ref:`resolver_name `. + */ + 'address'?: (string); + 'port_value'?: (number); + /** + * This is only valid if :ref:`resolver_name + * ` is specified below and the + * named resolver is capable of named port resolution. + */ + 'named_port'?: (string); + /** + * The name of the custom resolver. This must have been registered with Envoy. If + * this is empty, a context dependent default applies. If the address is a concrete + * IP address, no resolution will occur. If address is a hostname this + * should be set for resolution other than DNS. Specifying a custom resolver with + * *STRICT_DNS* or *LOGICAL_DNS* will generate an error at runtime. + */ + 'resolver_name'?: (string); + /** + * When binding to an IPv6 address above, this enables `IPv4 compatibility + * `_. Binding to ``::`` will + * allow both IPv4 and IPv6 connections, with peer IPv4 addresses mapped into + * IPv6 space as ``::FFFF:``. + */ + 'ipv4_compat'?: (boolean); + 'port_specifier'?: "port_value"|"named_port"; +} + +/** + * [#next-free-field: 7] + */ +export interface SocketAddress__Output { + 'protocol': (keyof typeof _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 ``::`` + * to bind to any address. [#comment:TODO(zuercher) reinstate when implemented: + * It is possible to distinguish a Listener address via the prefix/suffix matching + * in :ref:`FilterChainMatch `.] When used + * within an upstream :ref:`BindConfig `, the address + * controls the source address of outbound connections. For :ref:`clusters + * `, the cluster type determines whether the + * address must be an IP (*STATIC* or *EDS* clusters) or a hostname resolved by DNS + * (*STRICT_DNS* or *LOGICAL_DNS* clusters). Address resolution can be customized + * via :ref:`resolver_name `. + */ + 'address': (string); + 'port_value'?: (number); + /** + * This is only valid if :ref:`resolver_name + * ` is specified below and the + * named resolver is capable of named port resolution. + */ + 'named_port'?: (string); + /** + * The name of the custom resolver. This must have been registered with Envoy. If + * this is empty, a context dependent default applies. If the address is a concrete + * IP address, no resolution will occur. If address is a hostname this + * should be set for resolution other than DNS. Specifying a custom resolver with + * *STRICT_DNS* or *LOGICAL_DNS* will generate an error at runtime. + */ + 'resolver_name': (string); + /** + * When binding to an IPv6 address above, this enables `IPv4 compatibility + * `_. Binding to ``::`` will + * allow both IPv4 and IPv6 connections, with peer IPv4 addresses mapped into + * IPv6 space as ``::FFFF:``. + */ + 'ipv4_compat': (boolean); + 'port_specifier': "port_value"|"named_port"; +} 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 new file mode 100644 index 000000000..56f13c339 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SocketOption.ts @@ -0,0 +1,90 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/socket_option.proto + +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 { + /** + * 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, +} + +/** + * Generic socket option message. This would be used to set socket options that + * might not exist in upstream kernels or precompiled Envoy binaries. + * [#next-free-field: 7] + */ +export interface SocketOption { + /** + * An optional name to give this socket option for debugging, etc. + * Uniqueness is not required and no special meaning is assumed. + */ + 'description'?: (string); + /** + * Corresponding to the level value passed to setsockopt, such as IPPROTO_TCP + */ + 'level'?: (number | string | Long); + /** + * The numeric name as passed to setsockopt + */ + 'name'?: (number | string | Long); + /** + * Because many sockopts take an int value. + */ + 'int_value'?: (number | string | Long); + /** + * Otherwise it's a byte buffer. + */ + 'buf_value'?: (Buffer | Uint8Array | string); + /** + * 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); + 'value'?: "int_value"|"buf_value"; +} + +/** + * Generic socket option message. This would be used to set socket options that + * might not exist in upstream kernels or precompiled Envoy binaries. + * [#next-free-field: 7] + */ +export interface SocketOption__Output { + /** + * An optional name to give this socket option for debugging, etc. + * Uniqueness is not required and no special meaning is assumed. + */ + 'description': (string); + /** + * Corresponding to the level value passed to setsockopt, such as IPPROTO_TCP + */ + 'level': (string); + /** + * The numeric name as passed to setsockopt + */ + 'name': (string); + /** + * Because many sockopts take an int value. + */ + 'int_value'?: (string); + /** + * Otherwise it's a byte buffer. + */ + 'buf_value'?: (Buffer); + /** + * 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); + '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 new file mode 100644 index 000000000..41bd5e539 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SubstitutionFormatString.ts @@ -0,0 +1,197 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/substitution_format_string.proto + +import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; +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 { TypedExtensionConfig as _envoy_config_core_v3_TypedExtensionConfig, TypedExtensionConfig__Output as _envoy_config_core_v3_TypedExtensionConfig__Output } from '../../../../envoy/config/core/v3/TypedExtensionConfig'; + +/** + * Configuration to use multiple :ref:`command operators ` + * to generate a new string in either plain text or JSON format. + * [#next-free-field: 7] + */ +export interface SubstitutionFormatString { + /** + * Specify a format with command operators to form a text string. + * Its details is described in :ref:`format string`. + * + * For example, setting ``text_format`` like below, + * + * .. validated-code-block:: yaml + * :type-name: envoy.config.core.v3.SubstitutionFormatString + * + * text_format: "%LOCAL_REPLY_BODY%:%RESPONSE_CODE%:path=%REQ(:path)%\n" + * + * generates plain text similar to: + * + * .. code-block:: text + * + * 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. + */ + 'text_format'?: (string); + /** + * Specify a format with command operators to form a JSON string. + * Its details is described in :ref:`format dictionary`. + * Values are rendered as strings, numbers, or boolean values as appropriate. + * Nested JSON objects may be produced by some command operators (e.g. FILTER_STATE or DYNAMIC_METADATA). + * See the documentation for a specific command operator for details. + * + * .. validated-code-block:: yaml + * :type-name: envoy.config.core.v3.SubstitutionFormatString + * + * json_format: + * status: "%RESPONSE_CODE%" + * message: "%LOCAL_REPLY_BODY%" + * + * The following JSON object would be created: + * + * .. code-block:: json + * + * { + * "status": 500, + * "message": "My error message" + * } + */ + 'json_format'?: (_google_protobuf_Struct); + /** + * If set to true, when command operators are evaluated to null, + * + * * for ``text_format``, the output of the empty operator is changed from ``-`` to an + * empty string, so that empty values are omitted entirely. + * * for ``json_format`` the keys with null values are omitted in the output structure. + */ + 'omit_empty_values'?: (boolean); + /** + * Specify a *content_type* field. + * If this field is not set then ``text/plain`` is used for *text_format* and + * ``application/json`` is used for *json_format*. + * + * .. validated-code-block:: yaml + * :type-name: envoy.config.core.v3.SubstitutionFormatString + * + * content_type: "text/html; charset=UTF-8" + */ + 'content_type'?: (string); + /** + * Specify a format with command operators to form a text string. + * Its details is described in :ref:`format string`. + * + * For example, setting ``text_format`` like below, + * + * .. validated-code-block:: yaml + * :type-name: envoy.config.core.v3.SubstitutionFormatString + * + * text_format_source: + * inline_string: "%LOCAL_REPLY_BODY%:%RESPONSE_CODE%:path=%REQ(:path)%\n" + * + * generates plain text similar to: + * + * .. code-block:: text + * + * upstream connect error:503:path=/foo + */ + 'text_format_source'?: (_envoy_config_core_v3_DataSource); + /** + * Specifies a collection of Formatter plugins that can be called from the access log configuration. + * See the formatters extensions documentation for details. + */ + 'formatters'?: (_envoy_config_core_v3_TypedExtensionConfig)[]; + 'format'?: "text_format"|"json_format"|"text_format_source"; +} + +/** + * Configuration to use multiple :ref:`command operators ` + * to generate a new string in either plain text or JSON format. + * [#next-free-field: 7] + */ +export interface SubstitutionFormatString__Output { + /** + * Specify a format with command operators to form a text string. + * Its details is described in :ref:`format string`. + * + * For example, setting ``text_format`` like below, + * + * .. validated-code-block:: yaml + * :type-name: envoy.config.core.v3.SubstitutionFormatString + * + * text_format: "%LOCAL_REPLY_BODY%:%RESPONSE_CODE%:path=%REQ(:path)%\n" + * + * generates plain text similar to: + * + * .. code-block:: text + * + * 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. + */ + 'text_format'?: (string); + /** + * Specify a format with command operators to form a JSON string. + * Its details is described in :ref:`format dictionary`. + * Values are rendered as strings, numbers, or boolean values as appropriate. + * Nested JSON objects may be produced by some command operators (e.g. FILTER_STATE or DYNAMIC_METADATA). + * See the documentation for a specific command operator for details. + * + * .. validated-code-block:: yaml + * :type-name: envoy.config.core.v3.SubstitutionFormatString + * + * json_format: + * status: "%RESPONSE_CODE%" + * message: "%LOCAL_REPLY_BODY%" + * + * The following JSON object would be created: + * + * .. code-block:: json + * + * { + * "status": 500, + * "message": "My error message" + * } + */ + 'json_format'?: (_google_protobuf_Struct__Output); + /** + * If set to true, when command operators are evaluated to null, + * + * * for ``text_format``, the output of the empty operator is changed from ``-`` to an + * empty string, so that empty values are omitted entirely. + * * for ``json_format`` the keys with null values are omitted in the output structure. + */ + 'omit_empty_values': (boolean); + /** + * Specify a *content_type* field. + * If this field is not set then ``text/plain`` is used for *text_format* and + * ``application/json`` is used for *json_format*. + * + * .. validated-code-block:: yaml + * :type-name: envoy.config.core.v3.SubstitutionFormatString + * + * content_type: "text/html; charset=UTF-8" + */ + 'content_type': (string); + /** + * Specify a format with command operators to form a text string. + * Its details is described in :ref:`format string`. + * + * For example, setting ``text_format`` like below, + * + * .. validated-code-block:: yaml + * :type-name: envoy.config.core.v3.SubstitutionFormatString + * + * text_format_source: + * inline_string: "%LOCAL_REPLY_BODY%:%RESPONSE_CODE%:path=%REQ(:path)%\n" + * + * generates plain text similar to: + * + * .. code-block:: text + * + * upstream connect error:503:path=/foo + */ + 'text_format_source'?: (_envoy_config_core_v3_DataSource__Output); + /** + * Specifies a collection of Formatter plugins that can be called from the access log configuration. + * See the formatters extensions documentation for details. + */ + 'formatters': (_envoy_config_core_v3_TypedExtensionConfig__Output)[]; + 'format': "text_format"|"json_format"|"text_format_source"; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TcpKeepalive.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TcpKeepalive.ts new file mode 100644 index 000000000..a1bac359e --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TcpKeepalive.ts @@ -0,0 +1,43 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/address.proto + +import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; + +export interface TcpKeepalive { + /** + * Maximum number of keepalive probes to send without response before deciding + * the connection is dead. Default is to use the OS level configuration (unless + * overridden, Linux defaults to 9.) + */ + 'keepalive_probes'?: (_google_protobuf_UInt32Value); + /** + * The number of seconds a connection needs to be idle before keep-alive probes + * start being sent. Default is to use the OS level configuration (unless + * overridden, Linux defaults to 7200s (i.e., 2 hours.) + */ + 'keepalive_time'?: (_google_protobuf_UInt32Value); + /** + * The number of seconds between keep-alive probes. Default is to use the OS + * level configuration (unless overridden, Linux defaults to 75s.) + */ + 'keepalive_interval'?: (_google_protobuf_UInt32Value); +} + +export interface TcpKeepalive__Output { + /** + * Maximum number of keepalive probes to send without response before deciding + * the connection is dead. Default is to use the OS level configuration (unless + * overridden, Linux defaults to 9.) + */ + 'keepalive_probes'?: (_google_protobuf_UInt32Value__Output); + /** + * The number of seconds a connection needs to be idle before keep-alive probes + * start being sent. Default is to use the OS level configuration (unless + * overridden, Linux defaults to 7200s (i.e., 2 hours.) + */ + 'keepalive_time'?: (_google_protobuf_UInt32Value__Output); + /** + * The number of seconds between keep-alive probes. Default is to use the OS + * level configuration (unless overridden, Linux defaults to 75s.) + */ + 'keepalive_interval'?: (_google_protobuf_UInt32Value__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/TcpProtocolOptions.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TcpProtocolOptions.ts similarity index 70% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/core/TcpProtocolOptions.ts rename to packages/grpc-js-xds/src/generated/envoy/config/core/v3/TcpProtocolOptions.ts index bb7afc1d1..28239f63e 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/TcpProtocolOptions.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TcpProtocolOptions.ts @@ -1,4 +1,4 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/protocol.proto +// Original file: deps/envoy-api/envoy/config/core/v3/protocol.proto /** 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 new file mode 100644 index 000000000..b68323b09 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TrafficDirection.ts @@ -0,0 +1,19 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + +/** + * Identifies the direction of the traffic relative to the local Envoy. + */ +export enum 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, +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TransportSocket.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TransportSocket.ts new file mode 100644 index 000000000..b14402783 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TransportSocket.ts @@ -0,0 +1,43 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + +import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; + +/** + * Configuration for transport socket in :ref:`listeners ` and + * :ref:`clusters `. If the configuration is + * empty, a default transport socket implementation and configuration will be + * chosen based on the platform and existence of tls_context. + */ +export interface TransportSocket { + /** + * The name of the transport socket to instantiate. The name must match a supported transport + * socket implementation. + */ + 'name'?: (string); + 'typed_config'?: (_google_protobuf_Any); + /** + * Implementation specific configuration which depends on the implementation being instantiated. + * See the supported transport socket implementations for further documentation. + */ + 'config_type'?: "typed_config"; +} + +/** + * Configuration for transport socket in :ref:`listeners ` and + * :ref:`clusters `. If the configuration is + * empty, a default transport socket implementation and configuration will be + * chosen based on the platform and existence of tls_context. + */ +export interface TransportSocket__Output { + /** + * The name of the transport socket to instantiate. The name must match a supported transport + * socket implementation. + */ + 'name': (string); + 'typed_config'?: (_google_protobuf_Any__Output); + /** + * Implementation specific configuration which depends on the implementation being instantiated. + * See the supported transport socket implementations for further documentation. + */ + 'config_type': "typed_config"; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TypedExtensionConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TypedExtensionConfig.ts new file mode 100644 index 000000000..788826a1b --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TypedExtensionConfig.ts @@ -0,0 +1,43 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/extension.proto + +import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; + +/** + * Message type for extension configuration. + * [#next-major-version: revisit all existing typed_config that doesn't use this wrapper.]. + */ +export interface TypedExtensionConfig { + /** + * The name of an extension. This is not used to select the extension, instead + * it serves the role of an opaque identifier. + */ + 'name'?: (string); + /** + * The typed config for the extension. The type URL will be used to identify + * the extension. In the case that the type URL is *udpa.type.v1.TypedStruct*, + * the inner type URL of *TypedStruct* will be utilized. See the + * :ref:`extension configuration overview + * ` for further details. + */ + 'typed_config'?: (_google_protobuf_Any); +} + +/** + * Message type for extension configuration. + * [#next-major-version: revisit all existing typed_config that doesn't use this wrapper.]. + */ +export interface TypedExtensionConfig__Output { + /** + * The name of an extension. This is not used to select the extension, instead + * it serves the role of an opaque identifier. + */ + 'name': (string); + /** + * The typed config for the extension. The type URL will be used to identify + * the extension. In the case that the type URL is *udpa.type.v1.TypedStruct*, + * the inner type URL of *TypedStruct* will be utilized. See the + * :ref:`extension configuration overview + * ` for further details. + */ + 'typed_config'?: (_google_protobuf_Any__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/UpstreamHttpProtocolOptions.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/UpstreamHttpProtocolOptions.ts similarity index 95% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/core/UpstreamHttpProtocolOptions.ts rename to packages/grpc-js-xds/src/generated/envoy/config/core/v3/UpstreamHttpProtocolOptions.ts index 9c55560e8..b765ec5a7 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/UpstreamHttpProtocolOptions.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/UpstreamHttpProtocolOptions.ts @@ -1,4 +1,4 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/protocol.proto +// Original file: deps/envoy-api/envoy/config/core/v3/protocol.proto export interface UpstreamHttpProtocolOptions { diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/WatchedDirectory.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/WatchedDirectory.ts new file mode 100644 index 000000000..d6f0d124b --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/WatchedDirectory.ts @@ -0,0 +1,24 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + + +/** + * A directory that is watched for changes, e.g. by inotify on Linux. Move/rename + * events inside this directory trigger the watch. + */ +export interface WatchedDirectory { + /** + * Directory path to watch. + */ + 'path'?: (string); +} + +/** + * A directory that is watched for changes, e.g. by inotify on Linux. Move/rename + * events inside this directory trigger the watch. + */ +export interface WatchedDirectory__Output { + /** + * Directory path to watch. + */ + 'path': (string); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/ClusterLoadAssignment.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterLoadAssignment.ts similarity index 67% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/ClusterLoadAssignment.ts rename to packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterLoadAssignment.ts index 14598bec1..a092f0dde 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/ClusterLoadAssignment.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterLoadAssignment.ts @@ -1,15 +1,15 @@ -// Original file: deps/envoy-api/envoy/api/v2/endpoint.proto +// Original file: deps/envoy-api/envoy/config/endpoint/v3/endpoint.proto -import type { LocalityLbEndpoints as _envoy_api_v2_endpoint_LocalityLbEndpoints, LocalityLbEndpoints__Output as _envoy_api_v2_endpoint_LocalityLbEndpoints__Output } from '../../../envoy/api/v2/endpoint/LocalityLbEndpoints'; -import type { Endpoint as _envoy_api_v2_endpoint_Endpoint, Endpoint__Output as _envoy_api_v2_endpoint_Endpoint__Output } from '../../../envoy/api/v2/endpoint/Endpoint'; -import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../google/protobuf/UInt32Value'; -import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../google/protobuf/Duration'; -import type { FractionalPercent as _envoy_type_FractionalPercent, FractionalPercent__Output as _envoy_type_FractionalPercent__Output } from '../../../envoy/type/FractionalPercent'; +import type { LocalityLbEndpoints as _envoy_config_endpoint_v3_LocalityLbEndpoints, LocalityLbEndpoints__Output as _envoy_config_endpoint_v3_LocalityLbEndpoints__Output } from '../../../../envoy/config/endpoint/v3/LocalityLbEndpoints'; +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 { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; +import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; +import type { FractionalPercent as _envoy_type_v3_FractionalPercent, FractionalPercent__Output as _envoy_type_v3_FractionalPercent__Output } from '../../../../envoy/type/v3/FractionalPercent'; /** * [#not-implemented-hide:] */ -export interface _envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload { +export interface _envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload { /** * Identifier for the policy specifying the drop. */ @@ -17,13 +17,13 @@ export interface _envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload { /** * Percentage of traffic that should be dropped for the category. */ - 'drop_percentage'?: (_envoy_type_FractionalPercent); + 'drop_percentage'?: (_envoy_type_v3_FractionalPercent); } /** * [#not-implemented-hide:] */ -export interface _envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload__Output { +export interface _envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload__Output { /** * Identifier for the policy specifying the drop. */ @@ -31,14 +31,14 @@ export interface _envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload__Output /** * Percentage of traffic that should be dropped for the category. */ - 'drop_percentage'?: (_envoy_type_FractionalPercent__Output); + 'drop_percentage'?: (_envoy_type_v3_FractionalPercent__Output); } /** * Load balancing policy settings. * [#next-free-field: 6] */ -export interface _envoy_api_v2_ClusterLoadAssignment_Policy { +export interface _envoy_config_endpoint_v3_ClusterLoadAssignment_Policy { /** * Action to trim the overall incoming traffic to protect the upstream * hosts. This action allows protection in case the hosts are unable to @@ -61,11 +61,11 @@ export interface _envoy_api_v2_ClusterLoadAssignment_Policy { * actual_outgoing_load = 20% // remaining after applying all categories. * [#not-implemented-hide:] */ - 'drop_overloads'?: (_envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload)[]; + 'drop_overloads'?: (_envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload)[]; /** * Priority levels and localities are considered overprovisioned with this * factor (in percentage). This means that we don't consider a priority - * level or locality unhealthy until the percentage of healthy hosts + * level or locality unhealthy until the fraction of healthy hosts * multiplied by the overprovisioning factor drops below 100. * With the default value 140(1.4), Envoy doesn't consider a priority level * or a locality unhealthy until their percentage of healthy hosts drops @@ -86,24 +86,13 @@ export interface _envoy_api_v2_ClusterLoadAssignment_Policy { * Defaults to 0 which means endpoints never go stale. */ 'endpoint_stale_after'?: (_google_protobuf_Duration); - /** - * The flag to disable overprovisioning. If it is set to true, - * :ref:`overprovisioning factor - * ` will be ignored - * and Envoy will not perform graceful failover between priority levels or - * localities as endpoints become unhealthy. Otherwise Envoy will perform - * graceful failover as :ref:`overprovisioning factor - * ` suggests. - * [#not-implemented-hide:] - */ - 'disable_overprovisioning'?: (boolean); } /** * Load balancing policy settings. * [#next-free-field: 6] */ -export interface _envoy_api_v2_ClusterLoadAssignment_Policy__Output { +export interface _envoy_config_endpoint_v3_ClusterLoadAssignment_Policy__Output { /** * Action to trim the overall incoming traffic to protect the upstream * hosts. This action allows protection in case the hosts are unable to @@ -126,11 +115,11 @@ export interface _envoy_api_v2_ClusterLoadAssignment_Policy__Output { * actual_outgoing_load = 20% // remaining after applying all categories. * [#not-implemented-hide:] */ - 'drop_overloads': (_envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload__Output)[]; + 'drop_overloads': (_envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOverload__Output)[]; /** * Priority levels and localities are considered overprovisioned with this * factor (in percentage). This means that we don't consider a priority - * level or locality unhealthy until the percentage of healthy hosts + * level or locality unhealthy until the fraction of healthy hosts * multiplied by the overprovisioning factor drops below 100. * With the default value 140(1.4), Envoy doesn't consider a priority level * or a locality unhealthy until their percentage of healthy hosts drops @@ -151,17 +140,6 @@ export interface _envoy_api_v2_ClusterLoadAssignment_Policy__Output { * Defaults to 0 which means endpoints never go stale. */ 'endpoint_stale_after'?: (_google_protobuf_Duration__Output); - /** - * The flag to disable overprovisioning. If it is set to true, - * :ref:`overprovisioning factor - * ` will be ignored - * and Envoy will not perform graceful failover between priority levels or - * localities as endpoints become unhealthy. Otherwise Envoy will perform - * graceful failover as :ref:`overprovisioning factor - * ` suggests. - * [#not-implemented-hide:] - */ - 'disable_overprovisioning': (boolean); } /** @@ -179,24 +157,24 @@ export interface _envoy_api_v2_ClusterLoadAssignment_Policy__Output { export interface ClusterLoadAssignment { /** * Name of the cluster. This will be the :ref:`service_name - * ` value if specified + * ` value if specified * in the cluster :ref:`EdsClusterConfig - * `. + * `. */ 'cluster_name'?: (string); /** * List of endpoints to load balance to. */ - 'endpoints'?: (_envoy_api_v2_endpoint_LocalityLbEndpoints)[]; + 'endpoints'?: (_envoy_config_endpoint_v3_LocalityLbEndpoints)[]; /** * Load balancing policy settings. */ - 'policy'?: (_envoy_api_v2_ClusterLoadAssignment_Policy); + 'policy'?: (_envoy_config_endpoint_v3_ClusterLoadAssignment_Policy); /** * Map of named endpoints that can be referenced in LocalityLbEndpoints. * [#not-implemented-hide:] */ - 'named_endpoints'?: ({[key: string]: _envoy_api_v2_endpoint_Endpoint}); + 'named_endpoints'?: ({[key: string]: _envoy_config_endpoint_v3_Endpoint}); } /** @@ -214,22 +192,22 @@ export interface ClusterLoadAssignment { export interface ClusterLoadAssignment__Output { /** * Name of the cluster. This will be the :ref:`service_name - * ` value if specified + * ` value if specified * in the cluster :ref:`EdsClusterConfig - * `. + * `. */ 'cluster_name': (string); /** * List of endpoints to load balance to. */ - 'endpoints': (_envoy_api_v2_endpoint_LocalityLbEndpoints__Output)[]; + 'endpoints': (_envoy_config_endpoint_v3_LocalityLbEndpoints__Output)[]; /** * Load balancing policy settings. */ - 'policy'?: (_envoy_api_v2_ClusterLoadAssignment_Policy__Output); + 'policy'?: (_envoy_config_endpoint_v3_ClusterLoadAssignment_Policy__Output); /** * Map of named endpoints that can be referenced in LocalityLbEndpoints. * [#not-implemented-hide:] */ - 'named_endpoints'?: ({[key: string]: _envoy_api_v2_endpoint_Endpoint__Output}); + 'named_endpoints'?: ({[key: string]: _envoy_config_endpoint_v3_Endpoint__Output}); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterStats.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterStats.ts new file mode 100644 index 000000000..4d15bee14 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterStats.ts @@ -0,0 +1,115 @@ +// Original file: deps/envoy-api/envoy/config/endpoint/v3/load_report.proto + +import type { UpstreamLocalityStats as _envoy_config_endpoint_v3_UpstreamLocalityStats, UpstreamLocalityStats__Output as _envoy_config_endpoint_v3_UpstreamLocalityStats__Output } from '../../../../envoy/config/endpoint/v3/UpstreamLocalityStats'; +import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; +import type { Long } from '@grpc/proto-loader'; + +export interface _envoy_config_endpoint_v3_ClusterStats_DroppedRequests { + /** + * Identifier for the policy specifying the drop. + */ + 'category'?: (string); + /** + * Total number of deliberately dropped requests for the category. + */ + 'dropped_count'?: (number | string | Long); +} + +export interface _envoy_config_endpoint_v3_ClusterStats_DroppedRequests__Output { + /** + * Identifier for the policy specifying the drop. + */ + 'category': (string); + /** + * Total number of deliberately dropped requests for the category. + */ + 'dropped_count': (string); +} + +/** + * Per cluster load stats. Envoy reports these stats a management server in a + * :ref:`LoadStatsRequest` + * Next ID: 7 + * [#next-free-field: 7] + */ +export interface ClusterStats { + /** + * The name of the cluster. + */ + 'cluster_name'?: (string); + /** + * Need at least one. + */ + 'upstream_locality_stats'?: (_envoy_config_endpoint_v3_UpstreamLocalityStats)[]; + /** + * Cluster-level stats such as total_successful_requests may be computed by + * summing upstream_locality_stats. In addition, below there are additional + * cluster-wide stats. + * + * The total number of dropped requests. This covers requests + * deliberately dropped by the drop_overload policy and circuit breaking. + */ + 'total_dropped_requests'?: (number | string | Long); + /** + * Period over which the actual load report occurred. This will be guaranteed to include every + * request reported. Due to system load and delays between the *LoadStatsRequest* sent from Envoy + * and the *LoadStatsResponse* message sent from the management server, this may be longer than + * the requested load reporting interval in the *LoadStatsResponse*. + */ + 'load_report_interval'?: (_google_protobuf_Duration); + /** + * Information about deliberately dropped requests for each category specified + * in the DropOverload policy. + */ + 'dropped_requests'?: (_envoy_config_endpoint_v3_ClusterStats_DroppedRequests)[]; + /** + * The eds_cluster_config service_name of the cluster. + * It's possible that two clusters send the same service_name to EDS, + * in that case, the management server is supposed to do aggregation on the load reports. + */ + 'cluster_service_name'?: (string); +} + +/** + * Per cluster load stats. Envoy reports these stats a management server in a + * :ref:`LoadStatsRequest` + * Next ID: 7 + * [#next-free-field: 7] + */ +export interface ClusterStats__Output { + /** + * The name of the cluster. + */ + 'cluster_name': (string); + /** + * Need at least one. + */ + 'upstream_locality_stats': (_envoy_config_endpoint_v3_UpstreamLocalityStats__Output)[]; + /** + * Cluster-level stats such as total_successful_requests may be computed by + * summing upstream_locality_stats. In addition, below there are additional + * cluster-wide stats. + * + * The total number of dropped requests. This covers requests + * deliberately dropped by the drop_overload policy and circuit breaking. + */ + 'total_dropped_requests': (string); + /** + * Period over which the actual load report occurred. This will be guaranteed to include every + * request reported. Due to system load and delays between the *LoadStatsRequest* sent from Envoy + * and the *LoadStatsResponse* message sent from the management server, this may be longer than + * the requested load reporting interval in the *LoadStatsResponse*. + */ + 'load_report_interval'?: (_google_protobuf_Duration__Output); + /** + * Information about deliberately dropped requests for each category specified + * in the DropOverload policy. + */ + 'dropped_requests': (_envoy_config_endpoint_v3_ClusterStats_DroppedRequests__Output)[]; + /** + * The eds_cluster_config service_name of the cluster. + * It's possible that two clusters send the same service_name to EDS, + * in that case, the management server is supposed to do aggregation on the load reports. + */ + 'cluster_service_name': (string); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/Endpoint.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/Endpoint.ts similarity index 69% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/Endpoint.ts rename to packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/Endpoint.ts index 68bef75e1..7e1a7b346 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/Endpoint.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/Endpoint.ts @@ -1,11 +1,11 @@ -// Original file: deps/envoy-api/envoy/api/v2/endpoint/endpoint_components.proto +// Original file: deps/envoy-api/envoy/config/endpoint/v3/endpoint_components.proto -import type { Address as _envoy_api_v2_core_Address, Address__Output as _envoy_api_v2_core_Address__Output } from '../../../../envoy/api/v2/core/Address'; +import type { Address as _envoy_config_core_v3_Address, Address__Output as _envoy_config_core_v3_Address__Output } from '../../../../envoy/config/core/v3/Address'; /** * The optional health check configuration. */ -export interface _envoy_api_v2_endpoint_Endpoint_HealthCheckConfig { +export interface _envoy_config_endpoint_v3_Endpoint_HealthCheckConfig { /** * Optional alternative health check port value. * @@ -17,8 +17,8 @@ export interface _envoy_api_v2_endpoint_Endpoint_HealthCheckConfig { 'port_value'?: (number); /** * By default, the host header for L7 health checks is controlled by cluster level configuration - * (see: :ref:`host ` and - * :ref:`authority `). Setting this + * (see: :ref:`host ` and + * :ref:`authority `). Setting this * to a non-empty value allows overriding the cluster level configuration for a specific * endpoint. */ @@ -28,7 +28,7 @@ export interface _envoy_api_v2_endpoint_Endpoint_HealthCheckConfig { /** * The optional health check configuration. */ -export interface _envoy_api_v2_endpoint_Endpoint_HealthCheckConfig__Output { +export interface _envoy_config_endpoint_v3_Endpoint_HealthCheckConfig__Output { /** * Optional alternative health check port value. * @@ -40,8 +40,8 @@ export interface _envoy_api_v2_endpoint_Endpoint_HealthCheckConfig__Output { 'port_value': (number); /** * By default, the host header for L7 health checks is controlled by cluster level configuration - * (see: :ref:`host ` and - * :ref:`authority `). Setting this + * (see: :ref:`host ` and + * :ref:`authority `). Setting this * to a non-empty value allows overriding the cluster level configuration for a specific * endpoint. */ @@ -59,11 +59,11 @@ export interface Endpoint { * * The form of host address depends on the given cluster type. For STATIC or EDS, * it is expected to be a direct IP address (or something resolvable by the - * specified :ref:`resolver ` + * specified :ref:`resolver ` * in the Address). For LOGICAL or STRICT DNS, it is expected to be hostname, * and will be resolved via DNS. */ - 'address'?: (_envoy_api_v2_core_Address); + 'address'?: (_envoy_config_core_v3_Address); /** * The optional health check configuration is used as configuration for the * health checker to contact the health checked host. @@ -73,12 +73,12 @@ export interface Endpoint { * This takes into effect only for upstream clusters with * :ref:`active health checking ` enabled. */ - 'health_check_config'?: (_envoy_api_v2_endpoint_Endpoint_HealthCheckConfig); + 'health_check_config'?: (_envoy_config_endpoint_v3_Endpoint_HealthCheckConfig); /** * The hostname associated with this endpoint. This hostname is not used for routing or address * resolution. If provided, it will be associated with the endpoint, and can be used for features * that require a hostname, like - * :ref:`auto_host_rewrite `. + * :ref:`auto_host_rewrite `. */ 'hostname'?: (string); } @@ -94,11 +94,11 @@ export interface Endpoint__Output { * * The form of host address depends on the given cluster type. For STATIC or EDS, * it is expected to be a direct IP address (or something resolvable by the - * specified :ref:`resolver ` + * specified :ref:`resolver ` * in the Address). For LOGICAL or STRICT DNS, it is expected to be hostname, * and will be resolved via DNS. */ - 'address'?: (_envoy_api_v2_core_Address__Output); + 'address'?: (_envoy_config_core_v3_Address__Output); /** * The optional health check configuration is used as configuration for the * health checker to contact the health checked host. @@ -108,12 +108,12 @@ export interface Endpoint__Output { * This takes into effect only for upstream clusters with * :ref:`active health checking ` enabled. */ - 'health_check_config'?: (_envoy_api_v2_endpoint_Endpoint_HealthCheckConfig__Output); + 'health_check_config'?: (_envoy_config_endpoint_v3_Endpoint_HealthCheckConfig__Output); /** * The hostname associated with this endpoint. This hostname is not used for routing or address * resolution. If provided, it will be associated with the endpoint, and can be used for features * that require a hostname, like - * :ref:`auto_host_rewrite `. + * :ref:`auto_host_rewrite `. */ 'hostname': (string); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/EndpointLoadMetricStats.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/EndpointLoadMetricStats.ts new file mode 100644 index 000000000..50f63f4ca --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/EndpointLoadMetricStats.ts @@ -0,0 +1,35 @@ +// Original file: deps/envoy-api/envoy/config/endpoint/v3/load_report.proto + +import type { Long } from '@grpc/proto-loader'; + +export interface EndpointLoadMetricStats { + /** + * Name of the metric; may be empty. + */ + 'metric_name'?: (string); + /** + * Number of calls that finished and included this metric. + */ + 'num_requests_finished_with_metric'?: (number | string | Long); + /** + * Sum of metric values across all calls that finished with this metric for + * load_reporting_interval. + */ + 'total_metric_value'?: (number | string); +} + +export interface EndpointLoadMetricStats__Output { + /** + * Name of the metric; may be empty. + */ + 'metric_name': (string); + /** + * Number of calls that finished and included this metric. + */ + 'num_requests_finished_with_metric': (string); + /** + * Sum of metric values across all calls that finished with this metric for + * load_reporting_interval. + */ + 'total_metric_value': (number); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/LbEndpoint.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LbEndpoint.ts similarity index 74% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/LbEndpoint.ts rename to packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LbEndpoint.ts index 1f8be9305..449dd8aa3 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/LbEndpoint.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LbEndpoint.ts @@ -1,8 +1,8 @@ -// Original file: deps/envoy-api/envoy/api/v2/endpoint/endpoint_components.proto +// Original file: deps/envoy-api/envoy/config/endpoint/v3/endpoint_components.proto -import type { Endpoint as _envoy_api_v2_endpoint_Endpoint, Endpoint__Output as _envoy_api_v2_endpoint_Endpoint__Output } from '../../../../envoy/api/v2/endpoint/Endpoint'; -import type { HealthStatus as _envoy_api_v2_core_HealthStatus } from '../../../../envoy/api/v2/core/HealthStatus'; -import type { Metadata as _envoy_api_v2_core_Metadata, Metadata__Output as _envoy_api_v2_core_Metadata__Output } from '../../../../envoy/api/v2/core/Metadata'; +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 { 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'; /** @@ -10,21 +10,21 @@ import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output a * [#next-free-field: 6] */ export interface LbEndpoint { - 'endpoint'?: (_envoy_api_v2_endpoint_Endpoint); + 'endpoint'?: (_envoy_config_endpoint_v3_Endpoint); /** * Optional health status when known and supplied by EDS server. */ - 'health_status'?: (_envoy_api_v2_core_HealthStatus | keyof typeof _envoy_api_v2_core_HealthStatus); + 'health_status'?: (_envoy_config_core_v3_HealthStatus | keyof typeof _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 * name should be specified as *envoy.lb*. An example boolean key-value pair * is *canary*, providing the optional canary status of the upstream host. * This may be matched against in a route's - * :ref:`RouteAction ` metadata_match field + * :ref:`RouteAction ` metadata_match field * to subset the endpoints considered in cluster load balancing. */ - 'metadata'?: (_envoy_api_v2_core_Metadata); + 'metadata'?: (_envoy_config_core_v3_Metadata); /** * The optional load balancing weight of the upstream host; at least 1. * Envoy uses the load balancing weight in some of the built in load @@ -52,21 +52,21 @@ export interface LbEndpoint { * [#next-free-field: 6] */ export interface LbEndpoint__Output { - 'endpoint'?: (_envoy_api_v2_endpoint_Endpoint__Output); + 'endpoint'?: (_envoy_config_endpoint_v3_Endpoint__Output); /** * Optional health status when known and supplied by EDS server. */ - 'health_status': (keyof typeof _envoy_api_v2_core_HealthStatus); + 'health_status': (keyof typeof _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 * name should be specified as *envoy.lb*. An example boolean key-value pair * is *canary*, providing the optional canary status of the upstream host. * This may be matched against in a route's - * :ref:`RouteAction ` metadata_match field + * :ref:`RouteAction ` metadata_match field * to subset the endpoints considered in cluster load balancing. */ - 'metadata'?: (_envoy_api_v2_core_Metadata__Output); + 'metadata'?: (_envoy_config_core_v3_Metadata__Output); /** * The optional load balancing weight of the upstream host; at least 1. * Envoy uses the load balancing weight in some of the built in load diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/LocalityLbEndpoints.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LocalityLbEndpoints.ts similarity index 87% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/LocalityLbEndpoints.ts rename to packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LocalityLbEndpoints.ts index 557d97072..9924d2466 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/LocalityLbEndpoints.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LocalityLbEndpoints.ts @@ -1,7 +1,7 @@ -// Original file: deps/envoy-api/envoy/api/v2/endpoint/endpoint_components.proto +// Original file: deps/envoy-api/envoy/config/endpoint/v3/endpoint_components.proto -import type { Locality as _envoy_api_v2_core_Locality, Locality__Output as _envoy_api_v2_core_Locality__Output } from '../../../../envoy/api/v2/core/Locality'; -import type { LbEndpoint as _envoy_api_v2_endpoint_LbEndpoint, LbEndpoint__Output as _envoy_api_v2_endpoint_LbEndpoint__Output } from '../../../../envoy/api/v2/endpoint/LbEndpoint'; +import type { Locality as _envoy_config_core_v3_Locality, Locality__Output as _envoy_config_core_v3_Locality__Output } from '../../../../envoy/config/core/v3/Locality'; +import type { LbEndpoint as _envoy_config_endpoint_v3_LbEndpoint, LbEndpoint__Output as _envoy_config_endpoint_v3_LbEndpoint__Output } from '../../../../envoy/config/endpoint/v3/LbEndpoint'; import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; /** @@ -15,11 +15,11 @@ export interface LocalityLbEndpoints { /** * Identifies location of where the upstream hosts run. */ - 'locality'?: (_envoy_api_v2_core_Locality); + 'locality'?: (_envoy_config_core_v3_Locality); /** * The group of endpoints belonging to the locality specified. */ - 'lb_endpoints'?: (_envoy_api_v2_endpoint_LbEndpoint)[]; + 'lb_endpoints'?: (_envoy_config_endpoint_v3_LbEndpoint)[]; /** * Optional: Per priority/region/zone/sub_zone weight; at least 1. The load * balancing weight for a locality is divided by the sum of the weights of all @@ -68,11 +68,11 @@ export interface LocalityLbEndpoints__Output { /** * Identifies location of where the upstream hosts run. */ - 'locality'?: (_envoy_api_v2_core_Locality__Output); + 'locality'?: (_envoy_config_core_v3_Locality__Output); /** * The group of endpoints belonging to the locality specified. */ - 'lb_endpoints': (_envoy_api_v2_endpoint_LbEndpoint__Output)[]; + 'lb_endpoints': (_envoy_config_endpoint_v3_LbEndpoint__Output)[]; /** * Optional: Per priority/region/zone/sub_zone weight; at least 1. The load * balancing weight for a locality is divided by the sum of the weights of all diff --git a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/UpstreamEndpointStats.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/UpstreamEndpointStats.ts new file mode 100644 index 000000000..8fe66d6c4 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/UpstreamEndpointStats.ts @@ -0,0 +1,104 @@ +// Original file: deps/envoy-api/envoy/config/endpoint/v3/load_report.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 { EndpointLoadMetricStats as _envoy_config_endpoint_v3_EndpointLoadMetricStats, EndpointLoadMetricStats__Output as _envoy_config_endpoint_v3_EndpointLoadMetricStats__Output } from '../../../../envoy/config/endpoint/v3/EndpointLoadMetricStats'; +import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; +import type { Long } from '@grpc/proto-loader'; + +/** + * [#next-free-field: 8] + */ +export interface UpstreamEndpointStats { + /** + * Upstream host address. + */ + 'address'?: (_envoy_config_core_v3_Address); + /** + * The total number of requests successfully completed by the endpoints in the + * locality. These include non-5xx responses for HTTP, where errors + * originate at the client and the endpoint responded successfully. For gRPC, + * the grpc-status values are those not covered by total_error_requests below. + */ + 'total_successful_requests'?: (number | string | Long); + /** + * The total number of unfinished requests for this endpoint. + */ + 'total_requests_in_progress'?: (number | string | Long); + /** + * The total number of requests that failed due to errors at the endpoint. + * For HTTP these are responses with 5xx status codes and for gRPC the + * grpc-status values: + * + * - DeadlineExceeded + * - Unimplemented + * - Internal + * - Unavailable + * - Unknown + * - DataLoss + */ + 'total_error_requests'?: (number | string | Long); + /** + * Stats for multi-dimensional load balancing. + */ + 'load_metric_stats'?: (_envoy_config_endpoint_v3_EndpointLoadMetricStats)[]; + /** + * Opaque and implementation dependent metadata of the + * endpoint. Envoy will pass this directly to the management server. + */ + 'metadata'?: (_google_protobuf_Struct); + /** + * The total number of requests that were issued to this endpoint + * since the last report. A single TCP connection, HTTP or gRPC + * request or stream is counted as one request. + */ + 'total_issued_requests'?: (number | string | Long); +} + +/** + * [#next-free-field: 8] + */ +export interface UpstreamEndpointStats__Output { + /** + * Upstream host address. + */ + 'address'?: (_envoy_config_core_v3_Address__Output); + /** + * The total number of requests successfully completed by the endpoints in the + * locality. These include non-5xx responses for HTTP, where errors + * originate at the client and the endpoint responded successfully. For gRPC, + * the grpc-status values are those not covered by total_error_requests below. + */ + 'total_successful_requests': (string); + /** + * The total number of unfinished requests for this endpoint. + */ + 'total_requests_in_progress': (string); + /** + * The total number of requests that failed due to errors at the endpoint. + * For HTTP these are responses with 5xx status codes and for gRPC the + * grpc-status values: + * + * - DeadlineExceeded + * - Unimplemented + * - Internal + * - Unavailable + * - Unknown + * - DataLoss + */ + 'total_error_requests': (string); + /** + * Stats for multi-dimensional load balancing. + */ + 'load_metric_stats': (_envoy_config_endpoint_v3_EndpointLoadMetricStats__Output)[]; + /** + * Opaque and implementation dependent metadata of the + * endpoint. Envoy will pass this directly to the management server. + */ + 'metadata'?: (_google_protobuf_Struct__Output); + /** + * The total number of requests that were issued to this endpoint + * since the last report. A single TCP connection, HTTP or gRPC + * request or stream is counted as one request. + */ + 'total_issued_requests': (string); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/UpstreamLocalityStats.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/UpstreamLocalityStats.ts new file mode 100644 index 000000000..3eb8cc4eb --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/UpstreamLocalityStats.ts @@ -0,0 +1,104 @@ +// Original file: deps/envoy-api/envoy/config/endpoint/v3/load_report.proto + +import type { Locality as _envoy_config_core_v3_Locality, Locality__Output as _envoy_config_core_v3_Locality__Output } from '../../../../envoy/config/core/v3/Locality'; +import type { EndpointLoadMetricStats as _envoy_config_endpoint_v3_EndpointLoadMetricStats, EndpointLoadMetricStats__Output as _envoy_config_endpoint_v3_EndpointLoadMetricStats__Output } from '../../../../envoy/config/endpoint/v3/EndpointLoadMetricStats'; +import type { UpstreamEndpointStats as _envoy_config_endpoint_v3_UpstreamEndpointStats, UpstreamEndpointStats__Output as _envoy_config_endpoint_v3_UpstreamEndpointStats__Output } from '../../../../envoy/config/endpoint/v3/UpstreamEndpointStats'; +import type { Long } from '@grpc/proto-loader'; + +/** + * These are stats Envoy reports to the management server at a frequency defined by + * :ref:`LoadStatsResponse.load_reporting_interval`. + * Stats per upstream region/zone and optionally per subzone. + * [#next-free-field: 9] + */ +export interface UpstreamLocalityStats { + /** + * Name of zone, region and optionally endpoint group these metrics were + * collected from. Zone and region names could be empty if unknown. + */ + 'locality'?: (_envoy_config_core_v3_Locality); + /** + * The total number of requests successfully completed by the endpoints in the + * locality. + */ + 'total_successful_requests'?: (number | string | Long); + /** + * The total number of unfinished requests + */ + 'total_requests_in_progress'?: (number | string | Long); + /** + * The total number of requests that failed due to errors at the endpoint, + * aggregated over all endpoints in the locality. + */ + 'total_error_requests'?: (number | string | Long); + /** + * Stats for multi-dimensional load balancing. + */ + 'load_metric_stats'?: (_envoy_config_endpoint_v3_EndpointLoadMetricStats)[]; + /** + * [#not-implemented-hide:] The priority of the endpoint group these metrics + * were collected from. + */ + 'priority'?: (number); + /** + * Endpoint granularity stats information for this locality. This information + * is populated if the Server requests it by setting + * :ref:`LoadStatsResponse.report_endpoint_granularity`. + */ + 'upstream_endpoint_stats'?: (_envoy_config_endpoint_v3_UpstreamEndpointStats)[]; + /** + * The total number of requests that were issued by this Envoy since + * the last report. This information is aggregated over all the + * upstream endpoints in the locality. + */ + 'total_issued_requests'?: (number | string | Long); +} + +/** + * These are stats Envoy reports to the management server at a frequency defined by + * :ref:`LoadStatsResponse.load_reporting_interval`. + * Stats per upstream region/zone and optionally per subzone. + * [#next-free-field: 9] + */ +export interface UpstreamLocalityStats__Output { + /** + * Name of zone, region and optionally endpoint group these metrics were + * collected from. Zone and region names could be empty if unknown. + */ + 'locality'?: (_envoy_config_core_v3_Locality__Output); + /** + * The total number of requests successfully completed by the endpoints in the + * locality. + */ + 'total_successful_requests': (string); + /** + * The total number of unfinished requests + */ + 'total_requests_in_progress': (string); + /** + * The total number of requests that failed due to errors at the endpoint, + * aggregated over all endpoints in the locality. + */ + 'total_error_requests': (string); + /** + * Stats for multi-dimensional load balancing. + */ + 'load_metric_stats': (_envoy_config_endpoint_v3_EndpointLoadMetricStats__Output)[]; + /** + * [#not-implemented-hide:] The priority of the endpoint group these metrics + * were collected from. + */ + 'priority': (number); + /** + * Endpoint granularity stats information for this locality. This information + * is populated if the Server requests it by setting + * :ref:`LoadStatsResponse.report_endpoint_granularity`. + */ + 'upstream_endpoint_stats': (_envoy_config_endpoint_v3_UpstreamEndpointStats__Output)[]; + /** + * The total number of requests that were issued by this Envoy since + * the last report. This information is aggregated over all the + * upstream endpoints in the locality. + */ + 'total_issued_requests': (string); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/AccessLogFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/AccessLogFilter.ts deleted file mode 100644 index d75c9676c..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/AccessLogFilter.ts +++ /dev/null @@ -1,115 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/filter/accesslog/v2/accesslog.proto - -import type { StatusCodeFilter as _envoy_config_filter_accesslog_v2_StatusCodeFilter, StatusCodeFilter__Output as _envoy_config_filter_accesslog_v2_StatusCodeFilter__Output } from '../../../../../envoy/config/filter/accesslog/v2/StatusCodeFilter'; -import type { DurationFilter as _envoy_config_filter_accesslog_v2_DurationFilter, DurationFilter__Output as _envoy_config_filter_accesslog_v2_DurationFilter__Output } from '../../../../../envoy/config/filter/accesslog/v2/DurationFilter'; -import type { NotHealthCheckFilter as _envoy_config_filter_accesslog_v2_NotHealthCheckFilter, NotHealthCheckFilter__Output as _envoy_config_filter_accesslog_v2_NotHealthCheckFilter__Output } from '../../../../../envoy/config/filter/accesslog/v2/NotHealthCheckFilter'; -import type { TraceableFilter as _envoy_config_filter_accesslog_v2_TraceableFilter, TraceableFilter__Output as _envoy_config_filter_accesslog_v2_TraceableFilter__Output } from '../../../../../envoy/config/filter/accesslog/v2/TraceableFilter'; -import type { RuntimeFilter as _envoy_config_filter_accesslog_v2_RuntimeFilter, RuntimeFilter__Output as _envoy_config_filter_accesslog_v2_RuntimeFilter__Output } from '../../../../../envoy/config/filter/accesslog/v2/RuntimeFilter'; -import type { AndFilter as _envoy_config_filter_accesslog_v2_AndFilter, AndFilter__Output as _envoy_config_filter_accesslog_v2_AndFilter__Output } from '../../../../../envoy/config/filter/accesslog/v2/AndFilter'; -import type { OrFilter as _envoy_config_filter_accesslog_v2_OrFilter, OrFilter__Output as _envoy_config_filter_accesslog_v2_OrFilter__Output } from '../../../../../envoy/config/filter/accesslog/v2/OrFilter'; -import type { HeaderFilter as _envoy_config_filter_accesslog_v2_HeaderFilter, HeaderFilter__Output as _envoy_config_filter_accesslog_v2_HeaderFilter__Output } from '../../../../../envoy/config/filter/accesslog/v2/HeaderFilter'; -import type { ResponseFlagFilter as _envoy_config_filter_accesslog_v2_ResponseFlagFilter, ResponseFlagFilter__Output as _envoy_config_filter_accesslog_v2_ResponseFlagFilter__Output } from '../../../../../envoy/config/filter/accesslog/v2/ResponseFlagFilter'; -import type { GrpcStatusFilter as _envoy_config_filter_accesslog_v2_GrpcStatusFilter, GrpcStatusFilter__Output as _envoy_config_filter_accesslog_v2_GrpcStatusFilter__Output } from '../../../../../envoy/config/filter/accesslog/v2/GrpcStatusFilter'; -import type { ExtensionFilter as _envoy_config_filter_accesslog_v2_ExtensionFilter, ExtensionFilter__Output as _envoy_config_filter_accesslog_v2_ExtensionFilter__Output } from '../../../../../envoy/config/filter/accesslog/v2/ExtensionFilter'; - -/** - * [#next-free-field: 12] - */ -export interface AccessLogFilter { - /** - * Status code filter. - */ - 'status_code_filter'?: (_envoy_config_filter_accesslog_v2_StatusCodeFilter); - /** - * Duration filter. - */ - 'duration_filter'?: (_envoy_config_filter_accesslog_v2_DurationFilter); - /** - * Not health check filter. - */ - 'not_health_check_filter'?: (_envoy_config_filter_accesslog_v2_NotHealthCheckFilter); - /** - * Traceable filter. - */ - 'traceable_filter'?: (_envoy_config_filter_accesslog_v2_TraceableFilter); - /** - * Runtime filter. - */ - 'runtime_filter'?: (_envoy_config_filter_accesslog_v2_RuntimeFilter); - /** - * And filter. - */ - 'and_filter'?: (_envoy_config_filter_accesslog_v2_AndFilter); - /** - * Or filter. - */ - 'or_filter'?: (_envoy_config_filter_accesslog_v2_OrFilter); - /** - * Header filter. - */ - 'header_filter'?: (_envoy_config_filter_accesslog_v2_HeaderFilter); - /** - * Response flag filter. - */ - 'response_flag_filter'?: (_envoy_config_filter_accesslog_v2_ResponseFlagFilter); - /** - * gRPC status filter. - */ - 'grpc_status_filter'?: (_envoy_config_filter_accesslog_v2_GrpcStatusFilter); - /** - * Extension filter. - */ - 'extension_filter'?: (_envoy_config_filter_accesslog_v2_ExtensionFilter); - 'filter_specifier'?: "status_code_filter"|"duration_filter"|"not_health_check_filter"|"traceable_filter"|"runtime_filter"|"and_filter"|"or_filter"|"header_filter"|"response_flag_filter"|"grpc_status_filter"|"extension_filter"; -} - -/** - * [#next-free-field: 12] - */ -export interface AccessLogFilter__Output { - /** - * Status code filter. - */ - 'status_code_filter'?: (_envoy_config_filter_accesslog_v2_StatusCodeFilter__Output); - /** - * Duration filter. - */ - 'duration_filter'?: (_envoy_config_filter_accesslog_v2_DurationFilter__Output); - /** - * Not health check filter. - */ - 'not_health_check_filter'?: (_envoy_config_filter_accesslog_v2_NotHealthCheckFilter__Output); - /** - * Traceable filter. - */ - 'traceable_filter'?: (_envoy_config_filter_accesslog_v2_TraceableFilter__Output); - /** - * Runtime filter. - */ - 'runtime_filter'?: (_envoy_config_filter_accesslog_v2_RuntimeFilter__Output); - /** - * And filter. - */ - 'and_filter'?: (_envoy_config_filter_accesslog_v2_AndFilter__Output); - /** - * Or filter. - */ - 'or_filter'?: (_envoy_config_filter_accesslog_v2_OrFilter__Output); - /** - * Header filter. - */ - 'header_filter'?: (_envoy_config_filter_accesslog_v2_HeaderFilter__Output); - /** - * Response flag filter. - */ - 'response_flag_filter'?: (_envoy_config_filter_accesslog_v2_ResponseFlagFilter__Output); - /** - * gRPC status filter. - */ - 'grpc_status_filter'?: (_envoy_config_filter_accesslog_v2_GrpcStatusFilter__Output); - /** - * Extension filter. - */ - 'extension_filter'?: (_envoy_config_filter_accesslog_v2_ExtensionFilter__Output); - 'filter_specifier': "status_code_filter"|"duration_filter"|"not_health_check_filter"|"traceable_filter"|"runtime_filter"|"and_filter"|"or_filter"|"header_filter"|"response_flag_filter"|"grpc_status_filter"|"extension_filter"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/ComparisonFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/ComparisonFilter.ts deleted file mode 100644 index 8989ba603..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/ComparisonFilter.ts +++ /dev/null @@ -1,48 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/filter/accesslog/v2/accesslog.proto - -import type { RuntimeUInt32 as _envoy_api_v2_core_RuntimeUInt32, RuntimeUInt32__Output as _envoy_api_v2_core_RuntimeUInt32__Output } from '../../../../../envoy/api/v2/core/RuntimeUInt32'; - -// Original file: deps/envoy-api/envoy/config/filter/accesslog/v2/accesslog.proto - -export enum _envoy_config_filter_accesslog_v2_ComparisonFilter_Op { - /** - * = - */ - EQ = 0, - /** - * >= - */ - GE = 1, - /** - * <= - */ - LE = 2, -} - -/** - * Filter on an integer comparison. - */ -export interface ComparisonFilter { - /** - * Comparison operator. - */ - 'op'?: (_envoy_config_filter_accesslog_v2_ComparisonFilter_Op | keyof typeof _envoy_config_filter_accesslog_v2_ComparisonFilter_Op); - /** - * Value to compare against. - */ - 'value'?: (_envoy_api_v2_core_RuntimeUInt32); -} - -/** - * Filter on an integer comparison. - */ -export interface ComparisonFilter__Output { - /** - * Comparison operator. - */ - 'op': (keyof typeof _envoy_config_filter_accesslog_v2_ComparisonFilter_Op); - /** - * Value to compare against. - */ - 'value'?: (_envoy_api_v2_core_RuntimeUInt32__Output); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/DurationFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/DurationFilter.ts deleted file mode 100644 index 52a37cd95..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/DurationFilter.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/filter/accesslog/v2/accesslog.proto - -import type { ComparisonFilter as _envoy_config_filter_accesslog_v2_ComparisonFilter, ComparisonFilter__Output as _envoy_config_filter_accesslog_v2_ComparisonFilter__Output } from '../../../../../envoy/config/filter/accesslog/v2/ComparisonFilter'; - -/** - * Filters on total request duration in milliseconds. - */ -export interface DurationFilter { - /** - * Comparison. - */ - 'comparison'?: (_envoy_config_filter_accesslog_v2_ComparisonFilter); -} - -/** - * Filters on total request duration in milliseconds. - */ -export interface DurationFilter__Output { - /** - * Comparison. - */ - 'comparison'?: (_envoy_config_filter_accesslog_v2_ComparisonFilter__Output); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/HeaderFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/HeaderFilter.ts deleted file mode 100644 index d40610617..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/HeaderFilter.ts +++ /dev/null @@ -1,25 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/filter/accesslog/v2/accesslog.proto - -import type { HeaderMatcher as _envoy_api_v2_route_HeaderMatcher, HeaderMatcher__Output as _envoy_api_v2_route_HeaderMatcher__Output } from '../../../../../envoy/api/v2/route/HeaderMatcher'; - -/** - * Filters requests based on the presence or value of a request header. - */ -export interface HeaderFilter { - /** - * Only requests with a header which matches the specified HeaderMatcher will pass the filter - * check. - */ - 'header'?: (_envoy_api_v2_route_HeaderMatcher); -} - -/** - * Filters requests based on the presence or value of a request header. - */ -export interface HeaderFilter__Output { - /** - * Only requests with a header which matches the specified HeaderMatcher will pass the filter - * check. - */ - 'header'?: (_envoy_api_v2_route_HeaderMatcher__Output); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/RuntimeFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/RuntimeFilter.ts deleted file mode 100644 index 100ce050b..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/RuntimeFilter.ts +++ /dev/null @@ -1,63 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/filter/accesslog/v2/accesslog.proto - -import type { FractionalPercent as _envoy_type_FractionalPercent, FractionalPercent__Output as _envoy_type_FractionalPercent__Output } from '../../../../../envoy/type/FractionalPercent'; - -/** - * Filters for random sampling of requests. - */ -export interface RuntimeFilter { - /** - * Runtime key to get an optional overridden numerator for use in the *percent_sampled* field. - * If found in runtime, this value will replace the default numerator. - */ - 'runtime_key'?: (string); - /** - * The default sampling percentage. If not specified, defaults to 0% with denominator of 100. - */ - 'percent_sampled'?: (_envoy_type_FractionalPercent); - /** - * By default, sampling pivots on the header - * :ref:`x-request-id` being present. If - * :ref:`x-request-id` is present, the filter will - * consistently sample across multiple hosts based on the runtime key value and the value - * extracted from :ref:`x-request-id`. If it is - * missing, or *use_independent_randomness* is set to true, the filter will randomly sample based - * on the runtime key value alone. *use_independent_randomness* can be used for logging kill - * switches within complex nested :ref:`AndFilter - * ` and :ref:`OrFilter - * ` blocks that are easier to reason about - * from a probability perspective (i.e., setting to true will cause the filter to behave like - * an independent random variable when composed within logical operator filters). - */ - 'use_independent_randomness'?: (boolean); -} - -/** - * Filters for random sampling of requests. - */ -export interface RuntimeFilter__Output { - /** - * Runtime key to get an optional overridden numerator for use in the *percent_sampled* field. - * If found in runtime, this value will replace the default numerator. - */ - 'runtime_key': (string); - /** - * The default sampling percentage. If not specified, defaults to 0% with denominator of 100. - */ - 'percent_sampled'?: (_envoy_type_FractionalPercent__Output); - /** - * By default, sampling pivots on the header - * :ref:`x-request-id` being present. If - * :ref:`x-request-id` is present, the filter will - * consistently sample across multiple hosts based on the runtime key value and the value - * extracted from :ref:`x-request-id`. If it is - * missing, or *use_independent_randomness* is set to true, the filter will randomly sample based - * on the runtime key value alone. *use_independent_randomness* can be used for logging kill - * switches within complex nested :ref:`AndFilter - * ` and :ref:`OrFilter - * ` blocks that are easier to reason about - * from a probability perspective (i.e., setting to true will cause the filter to behave like - * an independent random variable when composed within logical operator filters). - */ - 'use_independent_randomness': (boolean); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/StatusCodeFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/StatusCodeFilter.ts deleted file mode 100644 index d60a80a14..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/accesslog/v2/StatusCodeFilter.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/filter/accesslog/v2/accesslog.proto - -import type { ComparisonFilter as _envoy_config_filter_accesslog_v2_ComparisonFilter, ComparisonFilter__Output as _envoy_config_filter_accesslog_v2_ComparisonFilter__Output } from '../../../../../envoy/config/filter/accesslog/v2/ComparisonFilter'; - -/** - * Filters on HTTP response/status code. - */ -export interface StatusCodeFilter { - /** - * Comparison. - */ - 'comparison'?: (_envoy_config_filter_accesslog_v2_ComparisonFilter); -} - -/** - * Filters on HTTP response/status code. - */ -export interface StatusCodeFilter__Output { - /** - * Comparison. - */ - 'comparison'?: (_envoy_config_filter_accesslog_v2_ComparisonFilter__Output); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/HttpFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/HttpFilter.ts deleted file mode 100644 index 84e4292fc..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/HttpFilter.ts +++ /dev/null @@ -1,34 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto - -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../../../google/protobuf/Struct'; -import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../../../google/protobuf/Any'; - -export interface HttpFilter { - /** - * The name of the filter to instantiate. The name must match a - * :ref:`supported filter `. - */ - 'name'?: (string); - 'config'?: (_google_protobuf_Struct); - 'typed_config'?: (_google_protobuf_Any); - /** - * Filter specific configuration which depends on the filter being instantiated. See the supported - * filters for further documentation. - */ - 'config_type'?: "config"|"typed_config"; -} - -export interface HttpFilter__Output { - /** - * The name of the filter to instantiate. The name must match a - * :ref:`supported filter `. - */ - 'name': (string); - 'config'?: (_google_protobuf_Struct__Output); - 'typed_config'?: (_google_protobuf_Any__Output); - /** - * Filter specific configuration which depends on the filter being instantiated. See the supported - * filters for further documentation. - */ - 'config_type': "config"|"typed_config"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/ScopedRds.ts b/packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/ScopedRds.ts deleted file mode 100644 index b3d89dffb..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/ScopedRds.ts +++ /dev/null @@ -1,17 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto - -import type { ConfigSource as _envoy_api_v2_core_ConfigSource, ConfigSource__Output as _envoy_api_v2_core_ConfigSource__Output } from '../../../../../../envoy/api/v2/core/ConfigSource'; - -export interface ScopedRds { - /** - * Configuration source specifier for scoped RDS. - */ - 'scoped_rds_config_source'?: (_envoy_api_v2_core_ConfigSource); -} - -export interface ScopedRds__Output { - /** - * Configuration source specifier for scoped RDS. - */ - 'scoped_rds_config_source'?: (_envoy_api_v2_core_ConfigSource__Output); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/ScopedRouteConfigurationsList.ts b/packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/ScopedRouteConfigurationsList.ts deleted file mode 100644 index a57f1725e..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/ScopedRouteConfigurationsList.ts +++ /dev/null @@ -1,17 +0,0 @@ -// Original file: deps/envoy-api/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto - -import type { ScopedRouteConfiguration as _envoy_api_v2_ScopedRouteConfiguration, ScopedRouteConfiguration__Output as _envoy_api_v2_ScopedRouteConfiguration__Output } from '../../../../../../envoy/api/v2/ScopedRouteConfiguration'; - -/** - * This message is used to work around the limitations with 'oneof' and repeated fields. - */ -export interface ScopedRouteConfigurationsList { - 'scoped_route_configurations'?: (_envoy_api_v2_ScopedRouteConfiguration)[]; -} - -/** - * This message is used to work around the limitations with 'oneof' and repeated fields. - */ -export interface ScopedRouteConfigurationsList__Output { - 'scoped_route_configurations': (_envoy_api_v2_ScopedRouteConfiguration__Output)[]; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/listener/ActiveRawUdpListenerConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ActiveRawUdpListenerConfig.ts similarity index 56% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/listener/ActiveRawUdpListenerConfig.ts rename to packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ActiveRawUdpListenerConfig.ts index 7bb47c26c..3cc895aa9 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/listener/ActiveRawUdpListenerConfig.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ActiveRawUdpListenerConfig.ts @@ -1,4 +1,4 @@ -// Original file: deps/envoy-api/envoy/api/v2/listener/udp_listener_config.proto +// Original file: deps/envoy-api/envoy/config/listener/v3/udp_listener_config.proto export interface ActiveRawUdpListenerConfig { diff --git a/packages/grpc-js-xds/src/generated/envoy/config/listener/v2/ApiListener.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ApiListener.ts similarity index 96% rename from packages/grpc-js-xds/src/generated/envoy/config/listener/v2/ApiListener.ts rename to packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ApiListener.ts index f683d3e82..508236641 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/listener/v2/ApiListener.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ApiListener.ts @@ -1,4 +1,4 @@ -// Original file: deps/envoy-api/envoy/config/listener/v2/api_listener.proto +// Original file: deps/envoy-api/envoy/config/listener/v3/api_listener.proto import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; diff --git a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/Filter.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/Filter.ts new file mode 100644 index 000000000..a3d26c904 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/Filter.ts @@ -0,0 +1,52 @@ +// Original file: deps/envoy-api/envoy/config/listener/v3/listener_components.proto + +import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; +import type { ExtensionConfigSource as _envoy_config_core_v3_ExtensionConfigSource, ExtensionConfigSource__Output as _envoy_config_core_v3_ExtensionConfigSource__Output } from '../../../../envoy/config/core/v3/ExtensionConfigSource'; + +/** + * [#next-free-field: 6] + */ +export interface Filter { + /** + * The name of the filter to instantiate. The name must match a + * :ref:`supported filter `. + */ + 'name'?: (string); + /** + * Filter specific configuration which depends on the filter being + * instantiated. See the supported filters for further documentation. + */ + 'typed_config'?: (_google_protobuf_Any); + /** + * Configuration source specifier for an extension configuration discovery + * service. In case of a failure and without the default configuration, the + * listener closes the connections. + * [#not-implemented-hide:] + */ + 'config_discovery'?: (_envoy_config_core_v3_ExtensionConfigSource); + 'config_type'?: "typed_config"|"config_discovery"; +} + +/** + * [#next-free-field: 6] + */ +export interface Filter__Output { + /** + * The name of the filter to instantiate. The name must match a + * :ref:`supported filter `. + */ + 'name': (string); + /** + * Filter specific configuration which depends on the filter being + * instantiated. See the supported filters for further documentation. + */ + 'typed_config'?: (_google_protobuf_Any__Output); + /** + * Configuration source specifier for an extension configuration discovery + * service. In case of a failure and without the default configuration, the + * listener closes the connections. + * [#not-implemented-hide:] + */ + 'config_discovery'?: (_envoy_config_core_v3_ExtensionConfigSource__Output); + 'config_type': "typed_config"|"config_discovery"; +} 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 new file mode 100644 index 000000000..e7f0adb7c --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/FilterChain.ts @@ -0,0 +1,170 @@ +// Original file: deps/envoy-api/envoy/config/listener/v3/listener_components.proto + +import type { FilterChainMatch as _envoy_config_listener_v3_FilterChainMatch, FilterChainMatch__Output as _envoy_config_listener_v3_FilterChainMatch__Output } from '../../../../envoy/config/listener/v3/FilterChainMatch'; +import type { Filter as _envoy_config_listener_v3_Filter, Filter__Output as _envoy_config_listener_v3_Filter__Output } from '../../../../envoy/config/listener/v3/Filter'; +import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; +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 { TransportSocket as _envoy_config_core_v3_TransportSocket, TransportSocket__Output as _envoy_config_core_v3_TransportSocket__Output } from '../../../../envoy/config/core/v3/TransportSocket'; +import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; + +/** + * The configuration for on-demand filter chain. If this field is not empty in FilterChain message, + * a filter chain will be built on-demand. + * On-demand filter chains help speedup the warming up of listeners since the building and initialization of + * an on-demand filter chain will be postponed to the arrival of new connection requests that require this filter chain. + * Filter chains that are not often used can be set as on-demand. + */ +export interface _envoy_config_listener_v3_FilterChain_OnDemandConfiguration { + /** + * The timeout to wait for filter chain placeholders to complete rebuilding. + * 1. If this field is set to 0, timeout is disabled. + * 2. If not specified, a default timeout of 15s is used. + * Rebuilding will wait until dependencies are ready, have failed, or this timeout is reached. + * Upon failure or timeout, all connections related to this filter chain will be closed. + * Rebuilding will start again on the next new connection. + */ + 'rebuild_timeout'?: (_google_protobuf_Duration); +} + +/** + * The configuration for on-demand filter chain. If this field is not empty in FilterChain message, + * a filter chain will be built on-demand. + * On-demand filter chains help speedup the warming up of listeners since the building and initialization of + * an on-demand filter chain will be postponed to the arrival of new connection requests that require this filter chain. + * Filter chains that are not often used can be set as on-demand. + */ +export interface _envoy_config_listener_v3_FilterChain_OnDemandConfiguration__Output { + /** + * The timeout to wait for filter chain placeholders to complete rebuilding. + * 1. If this field is set to 0, timeout is disabled. + * 2. If not specified, a default timeout of 15s is used. + * Rebuilding will wait until dependencies are ready, have failed, or this timeout is reached. + * Upon failure or timeout, all connections related to this filter chain will be closed. + * Rebuilding will start again on the next new connection. + */ + 'rebuild_timeout'?: (_google_protobuf_Duration__Output); +} + +/** + * A filter chain wraps a set of match criteria, an option TLS context, a set of filters, and + * various other parameters. + * [#next-free-field: 10] + */ +export interface FilterChain { + /** + * The criteria to use when matching a connection to this filter chain. + */ + 'filter_chain_match'?: (_envoy_config_listener_v3_FilterChainMatch); + /** + * A list of individual network filters that make up the filter chain for + * connections established with the listener. Order matters as the filters are + * processed sequentially as connection events happen. Note: If the filter + * list is empty, the connection will close by default. + */ + 'filters'?: (_envoy_config_listener_v3_Filter)[]; + /** + * Whether the listener should expect a PROXY protocol V1 header on new + * connections. If this option is enabled, the listener will assume that that + * remote address of the connection is the one specified in the header. Some + * load balancers including the AWS ELB support this option. If the option is + * absent or set to false, Envoy will use the physical peer address of the + * connection as the remote address. + * + * This field is deprecated. Add a + * :ref:`PROXY protocol listener filter ` + * explicitly instead. + */ + 'use_proxy_proto'?: (_google_protobuf_BoolValue); + /** + * [#not-implemented-hide:] filter chain metadata. + */ + 'metadata'?: (_envoy_config_core_v3_Metadata); + /** + * Optional custom transport socket implementation to use for downstream connections. + * To setup TLS, set a transport socket with name `tls` and + * :ref:`DownstreamTlsContext ` in the `typed_config`. + * If no transport socket configuration is specified, new connections + * will be set up with plaintext. + */ + 'transport_socket'?: (_envoy_config_core_v3_TransportSocket); + /** + * [#not-implemented-hide:] The unique name (or empty) by which this filter chain is known. If no + * name is provided, Envoy will allocate an internal UUID for the filter chain. If the filter + * chain is to be dynamically updated or removed via FCDS a unique name must be provided. + */ + 'name'?: (string); + /** + * [#not-implemented-hide:] The configuration to specify whether the filter chain will be built on-demand. + * If this field is not empty, the filter chain will be built on-demand. + * Otherwise, the filter chain will be built normally and block listener warming. + */ + 'on_demand_configuration'?: (_envoy_config_listener_v3_FilterChain_OnDemandConfiguration); + /** + * If present and nonzero, the amount of time to allow incoming connections to complete any + * transport socket negotiations. If this expires before the transport reports connection + * establishment, the connection is summarily closed. + */ + 'transport_socket_connect_timeout'?: (_google_protobuf_Duration); +} + +/** + * A filter chain wraps a set of match criteria, an option TLS context, a set of filters, and + * various other parameters. + * [#next-free-field: 10] + */ +export interface FilterChain__Output { + /** + * The criteria to use when matching a connection to this filter chain. + */ + 'filter_chain_match'?: (_envoy_config_listener_v3_FilterChainMatch__Output); + /** + * A list of individual network filters that make up the filter chain for + * connections established with the listener. Order matters as the filters are + * processed sequentially as connection events happen. Note: If the filter + * list is empty, the connection will close by default. + */ + 'filters': (_envoy_config_listener_v3_Filter__Output)[]; + /** + * Whether the listener should expect a PROXY protocol V1 header on new + * connections. If this option is enabled, the listener will assume that that + * remote address of the connection is the one specified in the header. Some + * load balancers including the AWS ELB support this option. If the option is + * absent or set to false, Envoy will use the physical peer address of the + * connection as the remote address. + * + * This field is deprecated. Add a + * :ref:`PROXY protocol listener filter ` + * explicitly instead. + */ + 'use_proxy_proto'?: (_google_protobuf_BoolValue__Output); + /** + * [#not-implemented-hide:] filter chain metadata. + */ + 'metadata'?: (_envoy_config_core_v3_Metadata__Output); + /** + * Optional custom transport socket implementation to use for downstream connections. + * To setup TLS, set a transport socket with name `tls` and + * :ref:`DownstreamTlsContext ` in the `typed_config`. + * If no transport socket configuration is specified, new connections + * will be set up with plaintext. + */ + 'transport_socket'?: (_envoy_config_core_v3_TransportSocket__Output); + /** + * [#not-implemented-hide:] The unique name (or empty) by which this filter chain is known. If no + * name is provided, Envoy will allocate an internal UUID for the filter chain. If the filter + * chain is to be dynamically updated or removed via FCDS a unique name must be provided. + */ + 'name': (string); + /** + * [#not-implemented-hide:] The configuration to specify whether the filter chain will be built on-demand. + * If this field is not empty, the filter chain will be built on-demand. + * Otherwise, the filter chain will be built normally and block listener warming. + */ + 'on_demand_configuration'?: (_envoy_config_listener_v3_FilterChain_OnDemandConfiguration__Output); + /** + * If present and nonzero, the amount of time to allow incoming connections to complete any + * transport socket negotiations. If this expires before the transport reports connection + * establishment, the connection is summarily closed. + */ + 'transport_socket_connect_timeout'?: (_google_protobuf_Duration__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/listener/FilterChainMatch.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/FilterChainMatch.ts similarity index 81% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/listener/FilterChainMatch.ts rename to packages/grpc-js-xds/src/generated/envoy/config/listener/v3/FilterChainMatch.ts index 881a5a961..1170232ae 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/listener/FilterChainMatch.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/FilterChainMatch.ts @@ -1,11 +1,11 @@ -// Original file: deps/envoy-api/envoy/api/v2/listener/listener_components.proto +// Original file: deps/envoy-api/envoy/config/listener/v3/listener_components.proto -import type { CidrRange as _envoy_api_v2_core_CidrRange, CidrRange__Output as _envoy_api_v2_core_CidrRange__Output } from '../../../../envoy/api/v2/core/CidrRange'; +import type { CidrRange as _envoy_config_core_v3_CidrRange, CidrRange__Output as _envoy_config_core_v3_CidrRange__Output } from '../../../../envoy/config/core/v3/CidrRange'; import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; -// Original file: deps/envoy-api/envoy/api/v2/listener/listener_components.proto +// Original file: deps/envoy-api/envoy/config/listener/v3/listener_components.proto -export enum _envoy_api_v2_listener_FilterChainMatch_ConnectionSourceType { +export enum _envoy_config_listener_v3_FilterChainMatch_ConnectionSourceType { /** * Any connection source matches. */ @@ -13,7 +13,7 @@ export enum _envoy_api_v2_listener_FilterChainMatch_ConnectionSourceType { /** * Match a connection originating from the same host. */ - LOCAL = 1, + SAME_IP_OR_LOOPBACK = 1, /** * Match a connection originating from a different host. */ @@ -45,6 +45,18 @@ export enum _envoy_api_v2_listener_FilterChainMatch_ConnectionSourceType { * ``www.example.com``, then ``*.example.com``, then ``*.com``, then any filter * chain without ``server_names`` requirements). * + * A different way to reason about the filter chain matches: + * Suppose there exists N filter chains. Prune the filter chain set using the above 8 steps. + * In each step, filter chains which most specifically matches the attributes continue to the next step. + * The listener guarantees at most 1 filter chain is left after all of the steps. + * + * Example: + * + * For destination port, filter chains specifying the destination port of incoming traffic are the + * most specific match. If none of the filter chains specifies the exact destination port, the filter + * chains which do not specify ports are the most specific match. Filter chains specifying the + * wrong port can never be the most specific match. + * * [#comment: Implemented rules are kept in the preference order, with deprecated fields * listed at the end, because that's how we want to list them in the docs. * @@ -56,7 +68,7 @@ export interface FilterChainMatch { * If non-empty, an IP address and prefix length to match addresses when the * listener is bound to 0.0.0.0/:: or when use_original_dst is specified. */ - 'prefix_ranges'?: (_envoy_api_v2_core_CidrRange)[]; + 'prefix_ranges'?: (_envoy_config_core_v3_CidrRange)[]; /** * If non-empty, an IP address and suffix length to match addresses when the * listener is bound to 0.0.0.0/:: or when use_original_dst is specified. @@ -73,7 +85,7 @@ export interface FilterChainMatch { * parameter is not specified or the list is empty, the source IP address is * ignored. */ - 'source_prefix_ranges'?: (_envoy_api_v2_core_CidrRange)[]; + 'source_prefix_ranges'?: (_envoy_config_core_v3_CidrRange)[]; /** * The criteria is satisfied if the source port of the downstream connection * is contained in at least one of the specified ports. If the parameter is @@ -138,7 +150,7 @@ export interface FilterChainMatch { /** * Specifies the connection source IP match type. Can be any, local or external network. */ - 'source_type'?: (_envoy_api_v2_listener_FilterChainMatch_ConnectionSourceType | keyof typeof _envoy_api_v2_listener_FilterChainMatch_ConnectionSourceType); + 'source_type'?: (_envoy_config_listener_v3_FilterChainMatch_ConnectionSourceType | keyof typeof _envoy_config_listener_v3_FilterChainMatch_ConnectionSourceType); } /** @@ -166,6 +178,18 @@ export interface FilterChainMatch { * ``www.example.com``, then ``*.example.com``, then ``*.com``, then any filter * chain without ``server_names`` requirements). * + * A different way to reason about the filter chain matches: + * Suppose there exists N filter chains. Prune the filter chain set using the above 8 steps. + * In each step, filter chains which most specifically matches the attributes continue to the next step. + * The listener guarantees at most 1 filter chain is left after all of the steps. + * + * Example: + * + * For destination port, filter chains specifying the destination port of incoming traffic are the + * most specific match. If none of the filter chains specifies the exact destination port, the filter + * chains which do not specify ports are the most specific match. Filter chains specifying the + * wrong port can never be the most specific match. + * * [#comment: Implemented rules are kept in the preference order, with deprecated fields * listed at the end, because that's how we want to list them in the docs. * @@ -177,7 +201,7 @@ export interface FilterChainMatch__Output { * If non-empty, an IP address and prefix length to match addresses when the * listener is bound to 0.0.0.0/:: or when use_original_dst is specified. */ - 'prefix_ranges': (_envoy_api_v2_core_CidrRange__Output)[]; + 'prefix_ranges': (_envoy_config_core_v3_CidrRange__Output)[]; /** * If non-empty, an IP address and suffix length to match addresses when the * listener is bound to 0.0.0.0/:: or when use_original_dst is specified. @@ -194,7 +218,7 @@ export interface FilterChainMatch__Output { * parameter is not specified or the list is empty, the source IP address is * ignored. */ - 'source_prefix_ranges': (_envoy_api_v2_core_CidrRange__Output)[]; + 'source_prefix_ranges': (_envoy_config_core_v3_CidrRange__Output)[]; /** * The criteria is satisfied if the source port of the downstream connection * is contained in at least one of the specified ports. If the parameter is @@ -259,5 +283,5 @@ export interface FilterChainMatch__Output { /** * Specifies the connection source IP match type. Can be any, local or external network. */ - 'source_type': (keyof typeof _envoy_api_v2_listener_FilterChainMatch_ConnectionSourceType); + 'source_type': (keyof typeof _envoy_config_listener_v3_FilterChainMatch_ConnectionSourceType); } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/Listener.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/Listener.ts similarity index 66% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/Listener.ts rename to packages/grpc-js-xds/src/generated/envoy/config/listener/v3/Listener.ts index 8aed6564d..ebcac4381 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/Listener.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/Listener.ts @@ -1,55 +1,52 @@ -// Original file: deps/envoy-api/envoy/api/v2/listener.proto +// Original file: deps/envoy-api/envoy/config/listener/v3/listener.proto -import type { Address as _envoy_api_v2_core_Address, Address__Output as _envoy_api_v2_core_Address__Output } from '../../../envoy/api/v2/core/Address'; -import type { FilterChain as _envoy_api_v2_listener_FilterChain, FilterChain__Output as _envoy_api_v2_listener_FilterChain__Output } from '../../../envoy/api/v2/listener/FilterChain'; -import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../google/protobuf/BoolValue'; -import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../google/protobuf/UInt32Value'; -import type { Metadata as _envoy_api_v2_core_Metadata, Metadata__Output as _envoy_api_v2_core_Metadata__Output } from '../../../envoy/api/v2/core/Metadata'; -import type { ListenerFilter as _envoy_api_v2_listener_ListenerFilter, ListenerFilter__Output as _envoy_api_v2_listener_ListenerFilter__Output } from '../../../envoy/api/v2/listener/ListenerFilter'; -import type { SocketOption as _envoy_api_v2_core_SocketOption, SocketOption__Output as _envoy_api_v2_core_SocketOption__Output } from '../../../envoy/api/v2/core/SocketOption'; -import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../google/protobuf/Duration'; -import type { TrafficDirection as _envoy_api_v2_core_TrafficDirection } from '../../../envoy/api/v2/core/TrafficDirection'; -import type { UdpListenerConfig as _envoy_api_v2_listener_UdpListenerConfig, UdpListenerConfig__Output as _envoy_api_v2_listener_UdpListenerConfig__Output } from '../../../envoy/api/v2/listener/UdpListenerConfig'; -import type { ApiListener as _envoy_config_listener_v2_ApiListener, ApiListener__Output as _envoy_config_listener_v2_ApiListener__Output } from '../../../envoy/config/listener/v2/ApiListener'; -import type { AccessLog as _envoy_config_filter_accesslog_v2_AccessLog, AccessLog__Output as _envoy_config_filter_accesslog_v2_AccessLog__Output } from '../../../envoy/config/filter/accesslog/v2/AccessLog'; +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 { FilterChain as _envoy_config_listener_v3_FilterChain, FilterChain__Output as _envoy_config_listener_v3_FilterChain__Output } from '../../../../envoy/config/listener/v3/FilterChain'; +import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; +import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; +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 { 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 { 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'; +import type { TypedExtensionConfig as _envoy_config_core_v3_TypedExtensionConfig, TypedExtensionConfig__Output as _envoy_config_core_v3_TypedExtensionConfig__Output } from '../../../../envoy/config/core/v3/TypedExtensionConfig'; /** * Configuration for listener connection balancing. */ -export interface _envoy_api_v2_Listener_ConnectionBalanceConfig { +export interface _envoy_config_listener_v3_Listener_ConnectionBalanceConfig { /** * If specified, the listener will use the exact connection balancer. */ - 'exact_balance'?: (_envoy_api_v2_Listener_ConnectionBalanceConfig_ExactBalance); + 'exact_balance'?: (_envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalance); 'balance_type'?: "exact_balance"; } /** * Configuration for listener connection balancing. */ -export interface _envoy_api_v2_Listener_ConnectionBalanceConfig__Output { +export interface _envoy_config_listener_v3_Listener_ConnectionBalanceConfig__Output { /** * If specified, the listener will use the exact connection balancer. */ - 'exact_balance'?: (_envoy_api_v2_Listener_ConnectionBalanceConfig_ExactBalance__Output); + 'exact_balance'?: (_envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalance__Output); 'balance_type': "exact_balance"; } /** * [#not-implemented-hide:] */ -export interface _envoy_api_v2_Listener_DeprecatedV1 { +export interface _envoy_config_listener_v3_Listener_DeprecatedV1 { /** * Whether the listener should bind to the port. A listener that doesn't * bind can only receive connections redirected from other listeners that * set use_original_dst parameter to true. Default is true. * - * This is deprecated in v2, all Listeners will bind to their port. An - * additional filter chain must be created for every original destination - * port this listener may redirect to in v2, with the original port - * specified in the FilterChainMatch destination_port field. - * - * [#comment:TODO(PiotrSikora): Remove this once verified that we no longer need it.] + * This is deprecated. Use :ref:`Listener.bind_to_port + * ` */ 'bind_to_port'?: (_google_protobuf_BoolValue); } @@ -57,25 +54,21 @@ export interface _envoy_api_v2_Listener_DeprecatedV1 { /** * [#not-implemented-hide:] */ -export interface _envoy_api_v2_Listener_DeprecatedV1__Output { +export interface _envoy_config_listener_v3_Listener_DeprecatedV1__Output { /** * Whether the listener should bind to the port. A listener that doesn't * bind can only receive connections redirected from other listeners that * set use_original_dst parameter to true. Default is true. * - * This is deprecated in v2, all Listeners will bind to their port. An - * additional filter chain must be created for every original destination - * port this listener may redirect to in v2, with the original port - * specified in the FilterChainMatch destination_port field. - * - * [#comment:TODO(PiotrSikora): Remove this once verified that we no longer need it.] + * This is deprecated. Use :ref:`Listener.bind_to_port + * ` */ 'bind_to_port'?: (_google_protobuf_BoolValue__Output); } -// Original file: deps/envoy-api/envoy/api/v2/listener.proto +// Original file: deps/envoy-api/envoy/config/listener/v3/listener.proto -export enum _envoy_api_v2_Listener_DrainType { +export enum _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. @@ -97,7 +90,7 @@ export enum _envoy_api_v2_Listener_DrainType { * sacrifices accept throughput for accuracy and should be used when there are a small number of * connections that rarely cycle (e.g., service mesh gRPC egress). */ -export interface _envoy_api_v2_Listener_ConnectionBalanceConfig_ExactBalance { +export interface _envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalance { } /** @@ -108,11 +101,11 @@ export interface _envoy_api_v2_Listener_ConnectionBalanceConfig_ExactBalance { * sacrifices accept throughput for accuracy and should be used when there are a small number of * connections that rarely cycle (e.g., service mesh gRPC egress). */ -export interface _envoy_api_v2_Listener_ConnectionBalanceConfig_ExactBalance__Output { +export interface _envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalance__Output { } /** - * [#next-free-field: 23] + * [#next-free-field: 27] */ export interface Listener { /** @@ -126,33 +119,23 @@ export interface Listener { * that is governed by the bind rules of the OS. E.g., multiple listeners can listen on port 0 on * Linux as the actual port will be allocated by the OS. */ - 'address'?: (_envoy_api_v2_core_Address); + 'address'?: (_envoy_config_core_v3_Address); /** * A list of filter chains to consider for this listener. The - * :ref:`FilterChain ` with the most specific - * :ref:`FilterChainMatch ` criteria is used on a + * :ref:`FilterChain ` with the most specific + * :ref:`FilterChainMatch ` criteria is used on a * connection. * * Example using SNI for filter chain selection can be found in the * :ref:`FAQ entry `. */ - 'filter_chains'?: (_envoy_api_v2_listener_FilterChain)[]; + 'filter_chains'?: (_envoy_config_listener_v3_FilterChain)[]; /** * If a connection is redirected using *iptables*, the port on which the proxy * receives it might be different from the original destination address. When this flag is set to * true, the listener hands off redirected connections to the listener associated with the * original destination address. If there is no listener associated with the original destination * address, the connection is handled by the listener that receives it. Defaults to false. - * - * .. attention:: - * - * This field is deprecated. Use :ref:`an original_dst ` - * :ref:`listener filter ` instead. - * - * Note that hand off to another listener is *NOT* performed without this flag. Once - * :ref:`FilterChainMatch ` is implemented this flag - * will be removed, as filter chain matching can be used to select a filter chain based on the - * restored destination address. */ 'use_original_dst'?: (_google_protobuf_BoolValue); /** @@ -163,34 +146,34 @@ export interface Listener { /** * Listener metadata. */ - 'metadata'?: (_envoy_api_v2_core_Metadata); + 'metadata'?: (_envoy_config_core_v3_Metadata); /** * [#not-implemented-hide:] */ - 'deprecated_v1'?: (_envoy_api_v2_Listener_DeprecatedV1); + 'deprecated_v1'?: (_envoy_config_listener_v3_Listener_DeprecatedV1); /** * The type of draining to perform at a listener-wide level. */ - 'drain_type'?: (_envoy_api_v2_Listener_DrainType | keyof typeof _envoy_api_v2_Listener_DrainType); + 'drain_type'?: (_envoy_config_listener_v3_Listener_DrainType | keyof typeof _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 - * :ref:`filter_chains `. Order matters as the + * :ref:`filter_chains `. Order matters as the * filters are processed sequentially right after a socket has been accepted by the listener, and * before a connection is created. * UDP Listener filters can be specified when the protocol in the listener socket address in - * :ref:`protocol ` is :ref:`UDP - * `. + * :ref:`protocol ` is :ref:`UDP + * `. * UDP listeners currently support a single filter. */ - 'listener_filters'?: (_envoy_api_v2_listener_ListenerFilter)[]; + 'listener_filters'?: (_envoy_config_listener_v3_ListenerFilter)[]; /** * Whether the listener should be set as a transparent socket. * When this flag is set to true, connections can be redirected to the listener using an * *iptables* *TPROXY* target, in which case the original source and destination addresses and * ports are preserved on accepted connections. This flag should be used in combination with * :ref:`an original_dst ` :ref:`listener filter - * ` to mark the connections' local addresses as + * ` to mark the connections' local addresses as * "restored." This can be used to hand off each redirected connection to another listener * associated with the connection's destination address. Direct connections to the socket without * using *TPROXY* cannot be distinguished from connections redirected using *TPROXY* and are @@ -231,7 +214,7 @@ export interface Listener { * Additional socket options that may not be present in Envoy source code or * precompiled binaries. */ - 'socket_options'?: (_envoy_api_v2_core_SocketOption)[]; + 'socket_options'?: (_envoy_config_core_v3_SocketOption)[]; /** * The timeout to wait for all listener filters to complete operation. If the timeout is reached, * the accepted socket is closed without a connection being created unless @@ -242,7 +225,7 @@ export interface Listener { /** * Specifies the intended direction of the traffic relative to the local Envoy. */ - 'traffic_direction'?: (_envoy_api_v2_core_TrafficDirection | keyof typeof _envoy_api_v2_core_TrafficDirection); + 'traffic_direction'?: (_envoy_config_core_v3_TrafficDirection | keyof typeof _envoy_config_core_v3_TrafficDirection); /** * Whether a connection should be created when listener filters timeout. Default is false. * @@ -255,17 +238,17 @@ export interface Listener { 'continue_on_listener_filters_timeout'?: (boolean); /** * If the protocol in the listener socket address in :ref:`protocol - * ` is :ref:`UDP - * `, this field specifies the actual udp + * ` is :ref:`UDP + * `, this field specifies the actual udp * listener to create, i.e. :ref:`udp_listener_name - * ` = "raw_udp_listener" for + * ` = "raw_udp_listener" for * creating a packet-oriented UDP listener. If not present, treat it as "raw_udp_listener". */ - 'udp_listener_config'?: (_envoy_api_v2_listener_UdpListenerConfig); + 'udp_listener_config'?: (_envoy_config_listener_v3_UdpListenerConfig); /** * Used to represent an API listener, which is used in non-proxy clients. The type of API * exposed to the non-proxy application depends on the type of API listener. - * When this field is set, no other field except for :ref:`name` + * When this field is set, no other field except for :ref:`name` * should be set. * * .. note:: @@ -280,13 +263,13 @@ export interface Listener { * socket listener and the various types of API listener. That way, a given Listener message * can structurally only contain the fields of the relevant type.] */ - 'api_listener'?: (_envoy_config_listener_v2_ApiListener); + 'api_listener'?: (_envoy_config_listener_v3_ApiListener); /** * The listener's connection balancer configuration, currently only applicable to TCP listeners. * If no configuration is specified, Envoy will not attempt to balance active connections between * worker threads. */ - 'connection_balance_config'?: (_envoy_api_v2_Listener_ConnectionBalanceConfig); + 'connection_balance_config'?: (_envoy_config_listener_v3_Listener_ConnectionBalanceConfig); /** * When this flag is set to true, listeners set the *SO_REUSEPORT* socket option and * create one socket for each worker thread. This makes inbound connections @@ -304,11 +287,39 @@ export interface Listener { * Configuration for :ref:`access logs ` * emitted by this listener. */ - 'access_log'?: (_envoy_config_filter_accesslog_v2_AccessLog)[]; + 'access_log'?: (_envoy_config_accesslog_v3_AccessLog)[]; + /** + * If the protocol in the listener socket address in :ref:`protocol + * ` is :ref:`UDP + * `, this field specifies the actual udp + * writer to create, i.e. :ref:`name ` + * = "udp_default_writer" for creating a udp writer with writing in passthrough mode, + * = "udp_gso_batch_writer" for creating a udp writer with writing in batch mode. + * If not present, treat it as "udp_default_writer". + * [#not-implemented-hide:] + */ + 'udp_writer_config'?: (_envoy_config_core_v3_TypedExtensionConfig); + /** + * The maximum length a tcp listener's pending connections queue can grow to. If no value is + * provided net.core.somaxconn will be used on Linux and 128 otherwise. + */ + 'tcp_backlog_size'?: (_google_protobuf_UInt32Value); + /** + * The default filter chain if none of the filter chain matches. If no default filter chain is supplied, + * the connection will be closed. The filter chain match is ignored in this field. + */ + 'default_filter_chain'?: (_envoy_config_listener_v3_FilterChain); + /** + * Whether the listener should bind to the port. A listener that doesn't + * bind can only receive connections redirected from other listeners that set + * :ref:`use_original_dst ` + * to true. Default is true. + */ + 'bind_to_port'?: (_google_protobuf_BoolValue); } /** - * [#next-free-field: 23] + * [#next-free-field: 27] */ export interface Listener__Output { /** @@ -322,33 +333,23 @@ export interface Listener__Output { * that is governed by the bind rules of the OS. E.g., multiple listeners can listen on port 0 on * Linux as the actual port will be allocated by the OS. */ - 'address'?: (_envoy_api_v2_core_Address__Output); + 'address'?: (_envoy_config_core_v3_Address__Output); /** * A list of filter chains to consider for this listener. The - * :ref:`FilterChain ` with the most specific - * :ref:`FilterChainMatch ` criteria is used on a + * :ref:`FilterChain ` with the most specific + * :ref:`FilterChainMatch ` criteria is used on a * connection. * * Example using SNI for filter chain selection can be found in the * :ref:`FAQ entry `. */ - 'filter_chains': (_envoy_api_v2_listener_FilterChain__Output)[]; + 'filter_chains': (_envoy_config_listener_v3_FilterChain__Output)[]; /** * If a connection is redirected using *iptables*, the port on which the proxy * receives it might be different from the original destination address. When this flag is set to * true, the listener hands off redirected connections to the listener associated with the * original destination address. If there is no listener associated with the original destination * address, the connection is handled by the listener that receives it. Defaults to false. - * - * .. attention:: - * - * This field is deprecated. Use :ref:`an original_dst ` - * :ref:`listener filter ` instead. - * - * Note that hand off to another listener is *NOT* performed without this flag. Once - * :ref:`FilterChainMatch ` is implemented this flag - * will be removed, as filter chain matching can be used to select a filter chain based on the - * restored destination address. */ 'use_original_dst'?: (_google_protobuf_BoolValue__Output); /** @@ -359,34 +360,34 @@ export interface Listener__Output { /** * Listener metadata. */ - 'metadata'?: (_envoy_api_v2_core_Metadata__Output); + 'metadata'?: (_envoy_config_core_v3_Metadata__Output); /** * [#not-implemented-hide:] */ - 'deprecated_v1'?: (_envoy_api_v2_Listener_DeprecatedV1__Output); + 'deprecated_v1'?: (_envoy_config_listener_v3_Listener_DeprecatedV1__Output); /** * The type of draining to perform at a listener-wide level. */ - 'drain_type': (keyof typeof _envoy_api_v2_Listener_DrainType); + 'drain_type': (keyof typeof _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 - * :ref:`filter_chains `. Order matters as the + * :ref:`filter_chains `. Order matters as the * filters are processed sequentially right after a socket has been accepted by the listener, and * before a connection is created. * UDP Listener filters can be specified when the protocol in the listener socket address in - * :ref:`protocol ` is :ref:`UDP - * `. + * :ref:`protocol ` is :ref:`UDP + * `. * UDP listeners currently support a single filter. */ - 'listener_filters': (_envoy_api_v2_listener_ListenerFilter__Output)[]; + 'listener_filters': (_envoy_config_listener_v3_ListenerFilter__Output)[]; /** * Whether the listener should be set as a transparent socket. * When this flag is set to true, connections can be redirected to the listener using an * *iptables* *TPROXY* target, in which case the original source and destination addresses and * ports are preserved on accepted connections. This flag should be used in combination with * :ref:`an original_dst ` :ref:`listener filter - * ` to mark the connections' local addresses as + * ` to mark the connections' local addresses as * "restored." This can be used to hand off each redirected connection to another listener * associated with the connection's destination address. Direct connections to the socket without * using *TPROXY* cannot be distinguished from connections redirected using *TPROXY* and are @@ -427,7 +428,7 @@ export interface Listener__Output { * Additional socket options that may not be present in Envoy source code or * precompiled binaries. */ - 'socket_options': (_envoy_api_v2_core_SocketOption__Output)[]; + 'socket_options': (_envoy_config_core_v3_SocketOption__Output)[]; /** * The timeout to wait for all listener filters to complete operation. If the timeout is reached, * the accepted socket is closed without a connection being created unless @@ -438,7 +439,7 @@ export interface Listener__Output { /** * Specifies the intended direction of the traffic relative to the local Envoy. */ - 'traffic_direction': (keyof typeof _envoy_api_v2_core_TrafficDirection); + 'traffic_direction': (keyof typeof _envoy_config_core_v3_TrafficDirection); /** * Whether a connection should be created when listener filters timeout. Default is false. * @@ -451,17 +452,17 @@ export interface Listener__Output { 'continue_on_listener_filters_timeout': (boolean); /** * If the protocol in the listener socket address in :ref:`protocol - * ` is :ref:`UDP - * `, this field specifies the actual udp + * ` is :ref:`UDP + * `, this field specifies the actual udp * listener to create, i.e. :ref:`udp_listener_name - * ` = "raw_udp_listener" for + * ` = "raw_udp_listener" for * creating a packet-oriented UDP listener. If not present, treat it as "raw_udp_listener". */ - 'udp_listener_config'?: (_envoy_api_v2_listener_UdpListenerConfig__Output); + 'udp_listener_config'?: (_envoy_config_listener_v3_UdpListenerConfig__Output); /** * Used to represent an API listener, which is used in non-proxy clients. The type of API * exposed to the non-proxy application depends on the type of API listener. - * When this field is set, no other field except for :ref:`name` + * When this field is set, no other field except for :ref:`name` * should be set. * * .. note:: @@ -476,13 +477,13 @@ export interface Listener__Output { * socket listener and the various types of API listener. That way, a given Listener message * can structurally only contain the fields of the relevant type.] */ - 'api_listener'?: (_envoy_config_listener_v2_ApiListener__Output); + 'api_listener'?: (_envoy_config_listener_v3_ApiListener__Output); /** * The listener's connection balancer configuration, currently only applicable to TCP listeners. * If no configuration is specified, Envoy will not attempt to balance active connections between * worker threads. */ - 'connection_balance_config'?: (_envoy_api_v2_Listener_ConnectionBalanceConfig__Output); + 'connection_balance_config'?: (_envoy_config_listener_v3_Listener_ConnectionBalanceConfig__Output); /** * When this flag is set to true, listeners set the *SO_REUSEPORT* socket option and * create one socket for each worker thread. This makes inbound connections @@ -500,5 +501,33 @@ export interface Listener__Output { * Configuration for :ref:`access logs ` * emitted by this listener. */ - 'access_log': (_envoy_config_filter_accesslog_v2_AccessLog__Output)[]; + 'access_log': (_envoy_config_accesslog_v3_AccessLog__Output)[]; + /** + * If the protocol in the listener socket address in :ref:`protocol + * ` is :ref:`UDP + * `, this field specifies the actual udp + * writer to create, i.e. :ref:`name ` + * = "udp_default_writer" for creating a udp writer with writing in passthrough mode, + * = "udp_gso_batch_writer" for creating a udp writer with writing in batch mode. + * If not present, treat it as "udp_default_writer". + * [#not-implemented-hide:] + */ + 'udp_writer_config'?: (_envoy_config_core_v3_TypedExtensionConfig__Output); + /** + * The maximum length a tcp listener's pending connections queue can grow to. If no value is + * provided net.core.somaxconn will be used on Linux and 128 otherwise. + */ + 'tcp_backlog_size'?: (_google_protobuf_UInt32Value__Output); + /** + * The default filter chain if none of the filter chain matches. If no default filter chain is supplied, + * the connection will be closed. The filter chain match is ignored in this field. + */ + 'default_filter_chain'?: (_envoy_config_listener_v3_FilterChain__Output); + /** + * Whether the listener should bind to the port. A listener that doesn't + * bind can only receive connections redirected from other listeners that set + * :ref:`use_original_dst ` + * to true. Default is true. + */ + 'bind_to_port'?: (_google_protobuf_BoolValue__Output); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerCollection.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerCollection.ts new file mode 100644 index 000000000..590ca8ed3 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerCollection.ts @@ -0,0 +1,19 @@ +// Original file: deps/envoy-api/envoy/config/listener/v3/listener.proto + +import type { CollectionEntry as _xds_core_v3_CollectionEntry, CollectionEntry__Output as _xds_core_v3_CollectionEntry__Output } from '../../../../xds/core/v3/CollectionEntry'; + +/** + * Listener list collections. Entries are *Listener* resources or references. + * [#not-implemented-hide:] + */ +export interface ListenerCollection { + 'entries'?: (_xds_core_v3_CollectionEntry)[]; +} + +/** + * Listener list collections. Entries are *Listener* resources or references. + * [#not-implemented-hide:] + */ +export interface ListenerCollection__Output { + 'entries': (_xds_core_v3_CollectionEntry__Output)[]; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/listener/ListenerFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilter.ts similarity index 58% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/listener/ListenerFilter.ts rename to packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilter.ts index 080d922b1..e8a827618 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/listener/ListenerFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilter.ts @@ -1,8 +1,7 @@ -// Original file: deps/envoy-api/envoy/api/v2/listener/listener_components.proto +// Original file: deps/envoy-api/envoy/config/listener/v3/listener_components.proto -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; -import type { ListenerFilterChainMatchPredicate as _envoy_api_v2_listener_ListenerFilterChainMatchPredicate, ListenerFilterChainMatchPredicate__Output as _envoy_api_v2_listener_ListenerFilterChainMatchPredicate__Output } from '../../../../envoy/api/v2/listener/ListenerFilterChainMatchPredicate'; +import type { ListenerFilterChainMatchPredicate as _envoy_config_listener_v3_ListenerFilterChainMatchPredicate, ListenerFilterChainMatchPredicate__Output as _envoy_config_listener_v3_ListenerFilterChainMatchPredicate__Output } from '../../../../envoy/config/listener/v3/ListenerFilterChainMatchPredicate'; export interface ListenerFilter { /** @@ -10,19 +9,18 @@ export interface ListenerFilter { * :ref:`supported filter `. */ 'name'?: (string); - 'config'?: (_google_protobuf_Struct); 'typed_config'?: (_google_protobuf_Any); /** * Optional match predicate used to disable the filter. The filter is enabled when this field is empty. - * See :ref:`ListenerFilterChainMatchPredicate ` + * See :ref:`ListenerFilterChainMatchPredicate ` * for further examples. */ - 'filter_disabled'?: (_envoy_api_v2_listener_ListenerFilterChainMatchPredicate); + 'filter_disabled'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate); /** * Filter specific configuration which depends on the filter being instantiated. * See the supported filters for further documentation. */ - 'config_type'?: "config"|"typed_config"; + 'config_type'?: "typed_config"; } export interface ListenerFilter__Output { @@ -31,17 +29,16 @@ export interface ListenerFilter__Output { * :ref:`supported filter `. */ 'name': (string); - 'config'?: (_google_protobuf_Struct__Output); 'typed_config'?: (_google_protobuf_Any__Output); /** * Optional match predicate used to disable the filter. The filter is enabled when this field is empty. - * See :ref:`ListenerFilterChainMatchPredicate ` + * See :ref:`ListenerFilterChainMatchPredicate ` * for further examples. */ - 'filter_disabled'?: (_envoy_api_v2_listener_ListenerFilterChainMatchPredicate__Output); + 'filter_disabled'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate__Output); /** * Filter specific configuration which depends on the filter being instantiated. * See the supported filters for further documentation. */ - 'config_type': "config"|"typed_config"; + 'config_type': "typed_config"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/listener/ListenerFilterChainMatchPredicate.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilterChainMatchPredicate.ts similarity index 66% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/listener/ListenerFilterChainMatchPredicate.ts rename to packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilterChainMatchPredicate.ts index ac3ddfd2a..e0d9ccc3e 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/listener/ListenerFilterChainMatchPredicate.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilterChainMatchPredicate.ts @@ -1,26 +1,26 @@ -// Original file: deps/envoy-api/envoy/api/v2/listener/listener_components.proto +// Original file: deps/envoy-api/envoy/config/listener/v3/listener_components.proto -import type { ListenerFilterChainMatchPredicate as _envoy_api_v2_listener_ListenerFilterChainMatchPredicate, ListenerFilterChainMatchPredicate__Output as _envoy_api_v2_listener_ListenerFilterChainMatchPredicate__Output } from '../../../../envoy/api/v2/listener/ListenerFilterChainMatchPredicate'; -import type { Int32Range as _envoy_type_Int32Range, Int32Range__Output as _envoy_type_Int32Range__Output } from '../../../../envoy/type/Int32Range'; +import type { ListenerFilterChainMatchPredicate as _envoy_config_listener_v3_ListenerFilterChainMatchPredicate, ListenerFilterChainMatchPredicate__Output as _envoy_config_listener_v3_ListenerFilterChainMatchPredicate__Output } from '../../../../envoy/config/listener/v3/ListenerFilterChainMatchPredicate'; +import type { Int32Range as _envoy_type_v3_Int32Range, Int32Range__Output as _envoy_type_v3_Int32Range__Output } from '../../../../envoy/type/v3/Int32Range'; /** * A set of match configurations used for logical operations. */ -export interface _envoy_api_v2_listener_ListenerFilterChainMatchPredicate_MatchSet { +export interface _envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet { /** * The list of rules that make up the set. */ - 'rules'?: (_envoy_api_v2_listener_ListenerFilterChainMatchPredicate)[]; + 'rules'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate)[]; } /** * A set of match configurations used for logical operations. */ -export interface _envoy_api_v2_listener_ListenerFilterChainMatchPredicate_MatchSet__Output { +export interface _envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet__Output { /** * The list of rules that make up the set. */ - 'rules': (_envoy_api_v2_listener_ListenerFilterChainMatchPredicate__Output)[]; + 'rules': (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate__Output)[]; } /** @@ -57,16 +57,16 @@ export interface ListenerFilterChainMatchPredicate { * A set that describes a logical OR. If any member of the set matches, the match configuration * matches. */ - 'or_match'?: (_envoy_api_v2_listener_ListenerFilterChainMatchPredicate_MatchSet); + 'or_match'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet); /** * A set that describes a logical AND. If all members of the set match, the match configuration * matches. */ - 'and_match'?: (_envoy_api_v2_listener_ListenerFilterChainMatchPredicate_MatchSet); + 'and_match'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet); /** * A negation match. The match configuration will match if the negated match condition matches. */ - 'not_match'?: (_envoy_api_v2_listener_ListenerFilterChainMatchPredicate); + 'not_match'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate); /** * The match configuration will always match. */ @@ -75,7 +75,7 @@ export interface ListenerFilterChainMatchPredicate { * Match destination port. Particularly, the match evaluation must use the recovered local port if * the owning listener filter is after :ref:`an original_dst listener filter `. */ - 'destination_port_range'?: (_envoy_type_Int32Range); + 'destination_port_range'?: (_envoy_type_v3_Int32Range); 'rule'?: "or_match"|"and_match"|"not_match"|"any_match"|"destination_port_range"; } @@ -113,16 +113,16 @@ export interface ListenerFilterChainMatchPredicate__Output { * A set that describes a logical OR. If any member of the set matches, the match configuration * matches. */ - 'or_match'?: (_envoy_api_v2_listener_ListenerFilterChainMatchPredicate_MatchSet__Output); + 'or_match'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet__Output); /** * A set that describes a logical AND. If all members of the set match, the match configuration * matches. */ - 'and_match'?: (_envoy_api_v2_listener_ListenerFilterChainMatchPredicate_MatchSet__Output); + 'and_match'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet__Output); /** * A negation match. The match configuration will match if the negated match condition matches. */ - 'not_match'?: (_envoy_api_v2_listener_ListenerFilterChainMatchPredicate__Output); + 'not_match'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate__Output); /** * The match configuration will always match. */ @@ -131,6 +131,6 @@ export interface ListenerFilterChainMatchPredicate__Output { * Match destination port. Particularly, the match evaluation must use the recovered local port if * the owning listener filter is after :ref:`an original_dst listener filter `. */ - 'destination_port_range'?: (_envoy_type_Int32Range__Output); + 'destination_port_range'?: (_envoy_type_v3_Int32Range__Output); 'rule': "or_match"|"and_match"|"not_match"|"any_match"|"destination_port_range"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/listener/UdpListenerConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/UdpListenerConfig.ts similarity index 72% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/listener/UdpListenerConfig.ts rename to packages/grpc-js-xds/src/generated/envoy/config/listener/v3/UdpListenerConfig.ts index 2299c5719..c7475c42b 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/listener/UdpListenerConfig.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/UdpListenerConfig.ts @@ -1,6 +1,5 @@ -// Original file: deps/envoy-api/envoy/api/v2/listener/udp_listener_config.proto +// Original file: deps/envoy-api/envoy/config/listener/v3/udp_listener_config.proto -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; export interface UdpListenerConfig { @@ -10,13 +9,12 @@ export interface UdpListenerConfig { * If not specified, treat as "raw_udp_listener". */ 'udp_listener_name'?: (string); - 'config'?: (_google_protobuf_Struct); 'typed_config'?: (_google_protobuf_Any); /** * Used to create a specific listener factory. To some factory, e.g. * "raw_udp_listener", config is not needed. */ - 'config_type'?: "config"|"typed_config"; + 'config_type'?: "typed_config"; } export interface UdpListenerConfig__Output { @@ -26,11 +24,10 @@ export interface UdpListenerConfig__Output { * If not specified, treat as "raw_udp_listener". */ 'udp_listener_name': (string); - 'config'?: (_google_protobuf_Struct__Output); 'typed_config'?: (_google_protobuf_Any__Output); /** * Used to create a specific listener factory. To some factory, e.g. * "raw_udp_listener", config is not needed. */ - 'config_type': "config"|"typed_config"; + 'config_type': "typed_config"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/CorsPolicy.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/CorsPolicy.ts similarity index 50% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/route/CorsPolicy.ts rename to packages/grpc-js-xds/src/generated/envoy/config/route/v3/CorsPolicy.ts index 7b76b9d85..c292a199a 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/CorsPolicy.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/CorsPolicy.ts @@ -1,22 +1,13 @@ -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; -import type { RuntimeFractionalPercent as _envoy_api_v2_core_RuntimeFractionalPercent, RuntimeFractionalPercent__Output as _envoy_api_v2_core_RuntimeFractionalPercent__Output } from '../../../../envoy/api/v2/core/RuntimeFractionalPercent'; -import type { StringMatcher as _envoy_type_matcher_StringMatcher, StringMatcher__Output as _envoy_type_matcher_StringMatcher__Output } from '../../../../envoy/type/matcher/StringMatcher'; +import type { RuntimeFractionalPercent as _envoy_config_core_v3_RuntimeFractionalPercent, RuntimeFractionalPercent__Output as _envoy_config_core_v3_RuntimeFractionalPercent__Output } from '../../../../envoy/config/core/v3/RuntimeFractionalPercent'; +import type { StringMatcher as _envoy_type_matcher_v3_StringMatcher, StringMatcher__Output as _envoy_type_matcher_v3_StringMatcher__Output } from '../../../../envoy/type/matcher/v3/StringMatcher'; /** * [#next-free-field: 12] */ export interface CorsPolicy { - /** - * Specifies the origins that will be allowed to do CORS requests. - * - * An origin is allowed if either allow_origin or allow_origin_regex match. - * - * .. attention:: - * This field has been deprecated in favor of `allow_origin_string_match`. - */ - 'allow_origin'?: (string)[]; /** * Specifies the content for the *access-control-allow-methods* header. */ @@ -37,35 +28,16 @@ export interface CorsPolicy { * Specifies whether the resource allows credentials. */ 'allow_credentials'?: (_google_protobuf_BoolValue); - /** - * Specifies if the CORS filter is enabled. Defaults to true. Only effective on route. - * - * .. attention:: - * - * **This field is deprecated**. Set the - * :ref:`filter_enabled` field instead. - */ - 'enabled'?: (_google_protobuf_BoolValue); - /** - * Specifies regex patterns that match allowed origins. - * - * An origin is allowed if either allow_origin or allow_origin_regex match. - * - * .. attention:: - * This field has been deprecated in favor of `allow_origin_string_match` as it is not safe for - * use with untrusted input in all cases. - */ - 'allow_origin_regex'?: (string)[]; /** * Specifies the % of requests for which the CORS filter is enabled. * * If neither ``enabled``, ``filter_enabled``, nor ``shadow_enabled`` are specified, the CORS * filter will be enabled for 100% of the requests. * - * If :ref:`runtime_key ` is + * If :ref:`runtime_key ` is * specified, Envoy will lookup the runtime key to get the percentage of requests to filter. */ - 'filter_enabled'?: (_envoy_api_v2_core_RuntimeFractionalPercent); + 'filter_enabled'?: (_envoy_config_core_v3_RuntimeFractionalPercent); /** * Specifies the % of requests for which the CORS policies will be evaluated and tracked, but not * enforced. @@ -73,32 +45,23 @@ export interface CorsPolicy { * This field is intended to be used when ``filter_enabled`` and ``enabled`` are off. One of those * fields have to explicitly disable the filter in order for this setting to take effect. * - * If :ref:`runtime_key ` is specified, + * If :ref:`runtime_key ` is specified, * Envoy will lookup the runtime key to get the percentage of requests for which it will evaluate * and track the request's *Origin* to determine if it's valid but will not enforce any policies. */ - 'shadow_enabled'?: (_envoy_api_v2_core_RuntimeFractionalPercent); + 'shadow_enabled'?: (_envoy_config_core_v3_RuntimeFractionalPercent); /** * Specifies string patterns that match allowed origins. An origin is allowed if any of the * string matchers match. */ - 'allow_origin_string_match'?: (_envoy_type_matcher_StringMatcher)[]; - 'enabled_specifier'?: "enabled"|"filter_enabled"; + 'allow_origin_string_match'?: (_envoy_type_matcher_v3_StringMatcher)[]; + 'enabled_specifier'?: "filter_enabled"; } /** * [#next-free-field: 12] */ export interface CorsPolicy__Output { - /** - * Specifies the origins that will be allowed to do CORS requests. - * - * An origin is allowed if either allow_origin or allow_origin_regex match. - * - * .. attention:: - * This field has been deprecated in favor of `allow_origin_string_match`. - */ - 'allow_origin': (string)[]; /** * Specifies the content for the *access-control-allow-methods* header. */ @@ -119,35 +82,16 @@ export interface CorsPolicy__Output { * Specifies whether the resource allows credentials. */ 'allow_credentials'?: (_google_protobuf_BoolValue__Output); - /** - * Specifies if the CORS filter is enabled. Defaults to true. Only effective on route. - * - * .. attention:: - * - * **This field is deprecated**. Set the - * :ref:`filter_enabled` field instead. - */ - 'enabled'?: (_google_protobuf_BoolValue__Output); - /** - * Specifies regex patterns that match allowed origins. - * - * An origin is allowed if either allow_origin or allow_origin_regex match. - * - * .. attention:: - * This field has been deprecated in favor of `allow_origin_string_match` as it is not safe for - * use with untrusted input in all cases. - */ - 'allow_origin_regex': (string)[]; /** * Specifies the % of requests for which the CORS filter is enabled. * * If neither ``enabled``, ``filter_enabled``, nor ``shadow_enabled`` are specified, the CORS * filter will be enabled for 100% of the requests. * - * If :ref:`runtime_key ` is + * If :ref:`runtime_key ` is * specified, Envoy will lookup the runtime key to get the percentage of requests to filter. */ - 'filter_enabled'?: (_envoy_api_v2_core_RuntimeFractionalPercent__Output); + 'filter_enabled'?: (_envoy_config_core_v3_RuntimeFractionalPercent__Output); /** * Specifies the % of requests for which the CORS policies will be evaluated and tracked, but not * enforced. @@ -155,15 +99,15 @@ export interface CorsPolicy__Output { * This field is intended to be used when ``filter_enabled`` and ``enabled`` are off. One of those * fields have to explicitly disable the filter in order for this setting to take effect. * - * If :ref:`runtime_key ` is specified, + * If :ref:`runtime_key ` is specified, * Envoy will lookup the runtime key to get the percentage of requests for which it will evaluate * and track the request's *Origin* to determine if it's valid but will not enforce any policies. */ - 'shadow_enabled'?: (_envoy_api_v2_core_RuntimeFractionalPercent__Output); + 'shadow_enabled'?: (_envoy_config_core_v3_RuntimeFractionalPercent__Output); /** * Specifies string patterns that match allowed origins. An origin is allowed if any of the * string matchers match. */ - 'allow_origin_string_match': (_envoy_type_matcher_StringMatcher__Output)[]; - 'enabled_specifier': "enabled"|"filter_enabled"; + 'allow_origin_string_match': (_envoy_type_matcher_v3_StringMatcher__Output)[]; + 'enabled_specifier': "filter_enabled"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/Decorator.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Decorator.ts similarity index 94% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/route/Decorator.ts rename to packages/grpc-js-xds/src/generated/envoy/config/route/v3/Decorator.ts index 68c91327d..00e37d98f 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/Decorator.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Decorator.ts @@ -1,4 +1,4 @@ -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/DirectResponseAction.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/DirectResponseAction.ts similarity index 52% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/route/DirectResponseAction.ts rename to packages/grpc-js-xds/src/generated/envoy/config/route/v3/DirectResponseAction.ts index 83777f9e3..9088fe712 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/DirectResponseAction.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/DirectResponseAction.ts @@ -1,6 +1,6 @@ -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto -import type { DataSource as _envoy_api_v2_core_DataSource, DataSource__Output as _envoy_api_v2_core_DataSource__Output } from '../../../../envoy/api/v2/core/DataSource'; +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 DirectResponseAction { /** @@ -14,10 +14,10 @@ export interface DirectResponseAction { * .. note:: * * Headers can be specified using *response_headers_to_add* in the enclosing - * :ref:`envoy_api_msg_route.Route`, :ref:`envoy_api_msg_RouteConfiguration` or - * :ref:`envoy_api_msg_route.VirtualHost`. + * :ref:`envoy_api_msg_config.route.v3.Route`, :ref:`envoy_api_msg_config.route.v3.RouteConfiguration` or + * :ref:`envoy_api_msg_config.route.v3.VirtualHost`. */ - 'body'?: (_envoy_api_v2_core_DataSource); + 'body'?: (_envoy_config_core_v3_DataSource); } export interface DirectResponseAction__Output { @@ -32,8 +32,8 @@ export interface DirectResponseAction__Output { * .. note:: * * Headers can be specified using *response_headers_to_add* in the enclosing - * :ref:`envoy_api_msg_route.Route`, :ref:`envoy_api_msg_RouteConfiguration` or - * :ref:`envoy_api_msg_route.VirtualHost`. + * :ref:`envoy_api_msg_config.route.v3.Route`, :ref:`envoy_api_msg_config.route.v3.RouteConfiguration` or + * :ref:`envoy_api_msg_config.route.v3.VirtualHost`. */ - 'body'?: (_envoy_api_v2_core_DataSource__Output); + 'body'?: (_envoy_config_core_v3_DataSource__Output); } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/FilterAction.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/FilterAction.ts similarity index 82% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/route/FilterAction.ts rename to packages/grpc-js-xds/src/generated/envoy/config/route/v3/FilterAction.ts index a41f3f417..78221b2c7 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/FilterAction.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/FilterAction.ts @@ -1,4 +1,4 @@ -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/FilterConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/FilterConfig.ts new file mode 100644 index 000000000..ff5976e0b --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/FilterConfig.ts @@ -0,0 +1,47 @@ +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto + +import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; + +/** + * A simple wrapper for an HTTP filter config. This is intended to be used as a wrapper for the + * map value in + * :ref:`VirtualHost.typed_per_filter_config`, + * :ref:`Route.typed_per_filter_config`, + * or :ref:`WeightedCluster.ClusterWeight.typed_per_filter_config` + * to add additional flags to the filter. + * [#not-implemented-hide:] + */ +export interface FilterConfig { + /** + * The filter config. + */ + 'config'?: (_google_protobuf_Any); + /** + * If true, the filter is optional, meaning that if the client does + * not support the specified filter, it may ignore the map entry rather + * than rejecting the config. + */ + 'is_optional'?: (boolean); +} + +/** + * A simple wrapper for an HTTP filter config. This is intended to be used as a wrapper for the + * map value in + * :ref:`VirtualHost.typed_per_filter_config`, + * :ref:`Route.typed_per_filter_config`, + * or :ref:`WeightedCluster.ClusterWeight.typed_per_filter_config` + * to add additional flags to the filter. + * [#not-implemented-hide:] + */ +export interface FilterConfig__Output { + /** + * The filter config. + */ + 'config'?: (_google_protobuf_Any__Output); + /** + * If true, the filter is optional, meaning that if the client does + * not support the specified filter, it may ignore the map entry rather + * than rejecting the config. + */ + 'is_optional': (boolean); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/HeaderMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/HeaderMatcher.ts similarity index 69% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/route/HeaderMatcher.ts rename to packages/grpc-js-xds/src/generated/envoy/config/route/v3/HeaderMatcher.ts index 347849901..8d20c5c63 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/HeaderMatcher.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/HeaderMatcher.ts @@ -1,7 +1,7 @@ -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto -import type { Int64Range as _envoy_type_Int64Range, Int64Range__Output as _envoy_type_Int64Range__Output } from '../../../../envoy/type/Int64Range'; -import type { RegexMatcher as _envoy_type_matcher_RegexMatcher, RegexMatcher__Output as _envoy_type_matcher_RegexMatcher__Output } from '../../../../envoy/type/matcher/RegexMatcher'; +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 { Long } from '@grpc/proto-loader'; /** @@ -24,12 +24,12 @@ import type { Long } from '@grpc/proto-loader'; * * .. attention:: * In the absence of any header match specifier, match will default to :ref:`present_match - * `. i.e, a request that has the :ref:`name - * ` header will match, regardless of the header's + * `. i.e, a request that has the :ref:`name + * ` header will match, regardless of the header's * value. * * [#next-major-version: HeaderMatcher should be refactored to use StringMatcher.] - * [#next-free-field: 12] + * [#next-free-field: 13] */ export interface HeaderMatcher { /** @@ -40,23 +40,6 @@ export interface HeaderMatcher { * If specified, header match will be performed based on the value of the header. */ 'exact_match'?: (string); - /** - * If specified, this regex string is a regular expression rule which implies the entire request - * header value must match the regex. The rule will not match if only a subsequence of the - * request header value matches the regex. The regex grammar used in the value field is defined - * `here `_. - * - * Examples: - * - * * The regex ``\d{3}`` matches the value *123* - * * The regex ``\d{3}`` does not match the value *1234* - * * The regex ``\d{3}`` does not match the value *123.456* - * - * .. attention:: - * This field has been deprecated in favor of `safe_regex_match` as it is not safe for use - * with untrusted input in all cases. - */ - 'regex_match'?: (string); /** * If specified, header match will be performed based on range. * The rule will match if the request header value is within this range. @@ -70,7 +53,7 @@ export interface HeaderMatcher { * * For range [-10,0), route will match for header value -1, but not for 0, "somestring", 10.9, * "-1somestring" */ - 'range_match'?: (_envoy_type_Int64Range); + 'range_match'?: (_envoy_type_v3_Int64Range); /** * If specified, header match will be performed based on whether the header is in the * request. @@ -108,11 +91,21 @@ 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. */ - 'safe_regex_match'?: (_envoy_type_matcher_RegexMatcher); + 'safe_regex_match'?: (_envoy_type_matcher_v3_RegexMatcher); + /** + * If specified, header match will be performed based on whether the header value contains + * the given value or not. + * Note: empty contains match is not allowed, please use present_match instead. + * + * Examples: + * + * * The value *abcd* matches the value *xyzabcdpqr*, but not for *xyzbcdpqr*. + */ + 'contains_match'?: (string); /** * Specifies how the header match will be performed to route the request. */ - 'header_match_specifier'?: "exact_match"|"regex_match"|"safe_regex_match"|"range_match"|"present_match"|"prefix_match"|"suffix_match"; + 'header_match_specifier'?: "exact_match"|"safe_regex_match"|"range_match"|"present_match"|"prefix_match"|"suffix_match"|"contains_match"; } /** @@ -135,12 +128,12 @@ export interface HeaderMatcher { * * .. attention:: * In the absence of any header match specifier, match will default to :ref:`present_match - * `. i.e, a request that has the :ref:`name - * ` header will match, regardless of the header's + * `. i.e, a request that has the :ref:`name + * ` header will match, regardless of the header's * value. * * [#next-major-version: HeaderMatcher should be refactored to use StringMatcher.] - * [#next-free-field: 12] + * [#next-free-field: 13] */ export interface HeaderMatcher__Output { /** @@ -151,23 +144,6 @@ export interface HeaderMatcher__Output { * If specified, header match will be performed based on the value of the header. */ 'exact_match'?: (string); - /** - * If specified, this regex string is a regular expression rule which implies the entire request - * header value must match the regex. The rule will not match if only a subsequence of the - * request header value matches the regex. The regex grammar used in the value field is defined - * `here `_. - * - * Examples: - * - * * The regex ``\d{3}`` matches the value *123* - * * The regex ``\d{3}`` does not match the value *1234* - * * The regex ``\d{3}`` does not match the value *123.456* - * - * .. attention:: - * This field has been deprecated in favor of `safe_regex_match` as it is not safe for use - * with untrusted input in all cases. - */ - 'regex_match'?: (string); /** * If specified, header match will be performed based on range. * The rule will match if the request header value is within this range. @@ -181,7 +157,7 @@ export interface HeaderMatcher__Output { * * For range [-10,0), route will match for header value -1, but not for 0, "somestring", 10.9, * "-1somestring" */ - 'range_match'?: (_envoy_type_Int64Range__Output); + 'range_match'?: (_envoy_type_v3_Int64Range__Output); /** * If specified, header match will be performed based on whether the header is in the * request. @@ -219,9 +195,19 @@ 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. */ - 'safe_regex_match'?: (_envoy_type_matcher_RegexMatcher__Output); + 'safe_regex_match'?: (_envoy_type_matcher_v3_RegexMatcher__Output); + /** + * If specified, header match will be performed based on whether the header value contains + * the given value or not. + * Note: empty contains match is not allowed, please use present_match instead. + * + * Examples: + * + * * The value *abcd* matches the value *xyzabcdpqr*, but not for *xyzbcdpqr*. + */ + 'contains_match'?: (string); /** * Specifies how the header match will be performed to route the request. */ - 'header_match_specifier': "exact_match"|"regex_match"|"safe_regex_match"|"range_match"|"present_match"|"prefix_match"|"suffix_match"; + 'header_match_specifier': "exact_match"|"safe_regex_match"|"range_match"|"present_match"|"prefix_match"|"suffix_match"|"contains_match"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/HedgePolicy.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/HedgePolicy.ts new file mode 100644 index 000000000..344d825e7 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/HedgePolicy.ts @@ -0,0 +1,76 @@ +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto + +import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; +import type { FractionalPercent as _envoy_type_v3_FractionalPercent, FractionalPercent__Output as _envoy_type_v3_FractionalPercent__Output } from '../../../../envoy/type/v3/FractionalPercent'; + +/** + * HTTP request hedging :ref:`architecture overview `. + */ +export interface HedgePolicy { + /** + * Specifies the number of initial requests that should be sent upstream. + * Must be at least 1. + * Defaults to 1. + * [#not-implemented-hide:] + */ + 'initial_requests'?: (_google_protobuf_UInt32Value); + /** + * Specifies a probability that an additional upstream request should be sent + * on top of what is specified by initial_requests. + * Defaults to 0. + * [#not-implemented-hide:] + */ + 'additional_request_chance'?: (_envoy_type_v3_FractionalPercent); + /** + * Indicates that a hedged request should be sent when the per-try timeout is hit. + * This means that a retry will be issued without resetting the original request, leaving multiple upstream requests in flight. + * The first request to complete successfully will be the one returned to the caller. + * + * * At any time, a successful response (i.e. not triggering any of the retry-on conditions) would be returned to the client. + * * Before per-try timeout, an error response (per retry-on conditions) would be retried immediately or returned ot the client + * if there are no more retries left. + * * After per-try timeout, an error response would be discarded, as a retry in the form of a hedged request is already in progress. + * + * Note: For this to have effect, you must have a :ref:`RetryPolicy ` that retries at least + * one error code and specifies a maximum number of retries. + * + * Defaults to false. + */ + 'hedge_on_per_try_timeout'?: (boolean); +} + +/** + * HTTP request hedging :ref:`architecture overview `. + */ +export interface HedgePolicy__Output { + /** + * Specifies the number of initial requests that should be sent upstream. + * Must be at least 1. + * Defaults to 1. + * [#not-implemented-hide:] + */ + 'initial_requests'?: (_google_protobuf_UInt32Value__Output); + /** + * Specifies a probability that an additional upstream request should be sent + * on top of what is specified by initial_requests. + * Defaults to 0. + * [#not-implemented-hide:] + */ + 'additional_request_chance'?: (_envoy_type_v3_FractionalPercent__Output); + /** + * Indicates that a hedged request should be sent when the per-try timeout is hit. + * This means that a retry will be issued without resetting the original request, leaving multiple upstream requests in flight. + * The first request to complete successfully will be the one returned to the caller. + * + * * At any time, a successful response (i.e. not triggering any of the retry-on conditions) would be returned to the client. + * * Before per-try timeout, an error response (per retry-on conditions) would be retried immediately or returned ot the client + * if there are no more retries left. + * * After per-try timeout, an error response would be discarded, as a retry in the form of a hedged request is already in progress. + * + * Note: For this to have effect, you must have a :ref:`RetryPolicy ` that retries at least + * one error code and specifies a maximum number of retries. + * + * Defaults to false. + */ + 'hedge_on_per_try_timeout': (boolean); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/InternalRedirectPolicy.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/InternalRedirectPolicy.ts new file mode 100644 index 000000000..73a2bb32e --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/InternalRedirectPolicy.ts @@ -0,0 +1,72 @@ +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto + +import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; +import type { TypedExtensionConfig as _envoy_config_core_v3_TypedExtensionConfig, TypedExtensionConfig__Output as _envoy_config_core_v3_TypedExtensionConfig__Output } from '../../../../envoy/config/core/v3/TypedExtensionConfig'; + +/** + * HTTP Internal Redirect :ref:`architecture overview `. + */ +export interface InternalRedirectPolicy { + /** + * An internal redirect is not handled, unless the number of previous internal redirects that a + * downstream request has encountered is lower than this value. + * In the case where a downstream request is bounced among multiple routes by internal redirect, + * the first route that hits this threshold, or does not set :ref:`internal_redirect_policy + * ` + * will pass the redirect back to downstream. + * + * If not specified, at most one redirect will be followed. + */ + 'max_internal_redirects'?: (_google_protobuf_UInt32Value); + /** + * Defines what upstream response codes are allowed to trigger internal redirect. If unspecified, + * only 302 will be treated as internal redirect. + * Only 301, 302, 303, 307 and 308 are valid values. Any other codes will be ignored. + */ + 'redirect_response_codes'?: (number)[]; + /** + * Specifies a list of predicates that are queried when an upstream response is deemed + * to trigger an internal redirect by all other criteria. Any predicate in the list can reject + * the redirect, causing the response to be proxied to downstream. + */ + 'predicates'?: (_envoy_config_core_v3_TypedExtensionConfig)[]; + /** + * Allow internal redirect to follow a target URI with a different scheme than the value of + * x-forwarded-proto. The default is false. + */ + 'allow_cross_scheme_redirect'?: (boolean); +} + +/** + * HTTP Internal Redirect :ref:`architecture overview `. + */ +export interface InternalRedirectPolicy__Output { + /** + * An internal redirect is not handled, unless the number of previous internal redirects that a + * downstream request has encountered is lower than this value. + * In the case where a downstream request is bounced among multiple routes by internal redirect, + * the first route that hits this threshold, or does not set :ref:`internal_redirect_policy + * ` + * will pass the redirect back to downstream. + * + * If not specified, at most one redirect will be followed. + */ + 'max_internal_redirects'?: (_google_protobuf_UInt32Value__Output); + /** + * Defines what upstream response codes are allowed to trigger internal redirect. If unspecified, + * only 302 will be treated as internal redirect. + * Only 301, 302, 303, 307 and 308 are valid values. Any other codes will be ignored. + */ + 'redirect_response_codes': (number)[]; + /** + * Specifies a list of predicates that are queried when an upstream response is deemed + * to trigger an internal redirect by all other criteria. Any predicate in the list can reject + * the redirect, causing the response to be proxied to downstream. + */ + 'predicates': (_envoy_config_core_v3_TypedExtensionConfig__Output)[]; + /** + * Allow internal redirect to follow a target URI with a different scheme than the value of + * x-forwarded-proto. The default is false. + */ + 'allow_cross_scheme_redirect': (boolean); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/QueryParameterMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/QueryParameterMatcher.ts new file mode 100644 index 000000000..c88fa8ff7 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/QueryParameterMatcher.ts @@ -0,0 +1,47 @@ +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.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'; + +/** + * Query parameter matching treats the query string of a request's :path header + * as an ampersand-separated list of keys and/or key=value elements. + * [#next-free-field: 7] + */ +export interface QueryParameterMatcher { + /** + * Specifies the name of a key that must be present in the requested + * *path*'s query string. + */ + 'name'?: (string); + /** + * Specifies whether a query parameter value should match against a string. + */ + 'string_match'?: (_envoy_type_matcher_v3_StringMatcher); + /** + * Specifies whether a query parameter should be present. + */ + 'present_match'?: (boolean); + 'query_parameter_match_specifier'?: "string_match"|"present_match"; +} + +/** + * Query parameter matching treats the query string of a request's :path header + * as an ampersand-separated list of keys and/or key=value elements. + * [#next-free-field: 7] + */ +export interface QueryParameterMatcher__Output { + /** + * Specifies the name of a key that must be present in the requested + * *path*'s query string. + */ + 'name': (string); + /** + * Specifies whether a query parameter value should match against a string. + */ + 'string_match'?: (_envoy_type_matcher_v3_StringMatcher__Output); + /** + * Specifies whether a query parameter should be present. + */ + 'present_match'?: (boolean); + 'query_parameter_match_specifier': "string_match"|"present_match"; +} 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 new file mode 100644 index 000000000..33d93af7d --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RateLimit.ts @@ -0,0 +1,578 @@ +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto + +import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; +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 { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; +import type { HeaderMatcher as _envoy_config_route_v3_HeaderMatcher, HeaderMatcher__Output as _envoy_config_route_v3_HeaderMatcher__Output } from '../../../../envoy/config/route/v3/HeaderMatcher'; +import type { MetadataKey as _envoy_type_metadata_v3_MetadataKey, MetadataKey__Output as _envoy_type_metadata_v3_MetadataKey__Output } from '../../../../envoy/type/metadata/v3/MetadataKey'; + +/** + * [#next-free-field: 10] + */ +export interface _envoy_config_route_v3_RateLimit_Action { + /** + * Rate limit on source cluster. + */ + 'source_cluster'?: (_envoy_config_route_v3_RateLimit_Action_SourceCluster); + /** + * Rate limit on destination cluster. + */ + 'destination_cluster'?: (_envoy_config_route_v3_RateLimit_Action_DestinationCluster); + /** + * Rate limit on request headers. + */ + 'request_headers'?: (_envoy_config_route_v3_RateLimit_Action_RequestHeaders); + /** + * Rate limit on remote address. + */ + 'remote_address'?: (_envoy_config_route_v3_RateLimit_Action_RemoteAddress); + /** + * Rate limit on a generic key. + */ + 'generic_key'?: (_envoy_config_route_v3_RateLimit_Action_GenericKey); + /** + * Rate limit on the existence of request headers. + */ + 'header_value_match'?: (_envoy_config_route_v3_RateLimit_Action_HeaderValueMatch); + /** + * Rate limit on dynamic metadata. + * + * .. attention:: + * This field has been deprecated in favor of the :ref:`metadata ` field + */ + 'dynamic_metadata'?: (_envoy_config_route_v3_RateLimit_Action_DynamicMetaData); + /** + * Rate limit on metadata. + */ + 'metadata'?: (_envoy_config_route_v3_RateLimit_Action_MetaData); + /** + * Rate limit descriptor extension. See the rate limit descriptor extensions documentation. + */ + 'extension'?: (_envoy_config_core_v3_TypedExtensionConfig); + 'action_specifier'?: "source_cluster"|"destination_cluster"|"request_headers"|"remote_address"|"generic_key"|"header_value_match"|"dynamic_metadata"|"metadata"|"extension"; +} + +/** + * [#next-free-field: 10] + */ +export interface _envoy_config_route_v3_RateLimit_Action__Output { + /** + * Rate limit on source cluster. + */ + 'source_cluster'?: (_envoy_config_route_v3_RateLimit_Action_SourceCluster__Output); + /** + * Rate limit on destination cluster. + */ + 'destination_cluster'?: (_envoy_config_route_v3_RateLimit_Action_DestinationCluster__Output); + /** + * Rate limit on request headers. + */ + 'request_headers'?: (_envoy_config_route_v3_RateLimit_Action_RequestHeaders__Output); + /** + * Rate limit on remote address. + */ + 'remote_address'?: (_envoy_config_route_v3_RateLimit_Action_RemoteAddress__Output); + /** + * Rate limit on a generic key. + */ + 'generic_key'?: (_envoy_config_route_v3_RateLimit_Action_GenericKey__Output); + /** + * Rate limit on the existence of request headers. + */ + 'header_value_match'?: (_envoy_config_route_v3_RateLimit_Action_HeaderValueMatch__Output); + /** + * Rate limit on dynamic metadata. + * + * .. attention:: + * This field has been deprecated in favor of the :ref:`metadata ` field + */ + 'dynamic_metadata'?: (_envoy_config_route_v3_RateLimit_Action_DynamicMetaData__Output); + /** + * Rate limit on metadata. + */ + 'metadata'?: (_envoy_config_route_v3_RateLimit_Action_MetaData__Output); + /** + * Rate limit descriptor extension. See the rate limit descriptor extensions documentation. + */ + 'extension'?: (_envoy_config_core_v3_TypedExtensionConfig__Output); + 'action_specifier': "source_cluster"|"destination_cluster"|"request_headers"|"remote_address"|"generic_key"|"header_value_match"|"dynamic_metadata"|"metadata"|"extension"; +} + +/** + * The following descriptor entry is appended to the descriptor: + * + * .. code-block:: cpp + * + * ("destination_cluster", "") + * + * Once a request matches against a route table rule, a routed cluster is determined by one of + * the following :ref:`route table configuration ` + * settings: + * + * * :ref:`cluster ` indicates the upstream cluster + * to route to. + * * :ref:`weighted_clusters ` + * chooses a cluster randomly from a set of clusters with attributed weight. + * * :ref:`cluster_header ` indicates which + * header in the request contains the target cluster. + */ +export interface _envoy_config_route_v3_RateLimit_Action_DestinationCluster { +} + +/** + * The following descriptor entry is appended to the descriptor: + * + * .. code-block:: cpp + * + * ("destination_cluster", "") + * + * Once a request matches against a route table rule, a routed cluster is determined by one of + * the following :ref:`route table configuration ` + * settings: + * + * * :ref:`cluster ` indicates the upstream cluster + * to route to. + * * :ref:`weighted_clusters ` + * chooses a cluster randomly from a set of clusters with attributed weight. + * * :ref:`cluster_header ` indicates which + * header in the request contains the target cluster. + */ +export interface _envoy_config_route_v3_RateLimit_Action_DestinationCluster__Output { +} + +/** + * The following descriptor entry is appended when the + * :ref:`dynamic metadata ` contains a key value: + * + * .. code-block:: cpp + * + * ("", "") + * + * .. attention:: + * This action has been deprecated in favor of the :ref:`metadata ` action + */ +export interface _envoy_config_route_v3_RateLimit_Action_DynamicMetaData { + /** + * The key to use in the descriptor entry. + */ + 'descriptor_key'?: (string); + /** + * Metadata struct that defines the key and path to retrieve the string value. A match will + * only happen if the value in the dynamic metadata is of type string. + */ + 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey); + /** + * An optional value to use if *metadata_key* is empty. If not set and + * no value is present under the metadata_key then no descriptor is generated. + */ + 'default_value'?: (string); +} + +/** + * The following descriptor entry is appended when the + * :ref:`dynamic metadata ` contains a key value: + * + * .. code-block:: cpp + * + * ("", "") + * + * .. attention:: + * This action has been deprecated in favor of the :ref:`metadata ` action + */ +export interface _envoy_config_route_v3_RateLimit_Action_DynamicMetaData__Output { + /** + * The key to use in the descriptor entry. + */ + 'descriptor_key': (string); + /** + * Metadata struct that defines the key and path to retrieve the string value. A match will + * only happen if the value in the dynamic metadata is of type string. + */ + 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey__Output); + /** + * An optional value to use if *metadata_key* is empty. If not set and + * no value is present under the metadata_key then no descriptor is generated. + */ + 'default_value': (string); +} + +/** + * Fetches the override from the dynamic metadata. + */ +export interface _envoy_config_route_v3_RateLimit_Override_DynamicMetadata { + /** + * Metadata struct that defines the key and path to retrieve the struct value. + * The value must be a struct containing an integer "requests_per_unit" property + * and a "unit" property with a value parseable to :ref:`RateLimitUnit + * enum ` + */ + 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey); +} + +/** + * Fetches the override from the dynamic metadata. + */ +export interface _envoy_config_route_v3_RateLimit_Override_DynamicMetadata__Output { + /** + * Metadata struct that defines the key and path to retrieve the struct value. + * The value must be a struct containing an integer "requests_per_unit" property + * and a "unit" property with a value parseable to :ref:`RateLimitUnit + * enum ` + */ + 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey__Output); +} + +/** + * The following descriptor entry is appended to the descriptor: + * + * .. code-block:: cpp + * + * ("generic_key", "") + */ +export interface _envoy_config_route_v3_RateLimit_Action_GenericKey { + /** + * The value to use in the descriptor entry. + */ + 'descriptor_value'?: (string); + /** + * An optional key to use in the descriptor entry. If not set it defaults + * to 'generic_key' as the descriptor key. + */ + 'descriptor_key'?: (string); +} + +/** + * The following descriptor entry is appended to the descriptor: + * + * .. code-block:: cpp + * + * ("generic_key", "") + */ +export interface _envoy_config_route_v3_RateLimit_Action_GenericKey__Output { + /** + * The value to use in the descriptor entry. + */ + 'descriptor_value': (string); + /** + * An optional key to use in the descriptor entry. If not set it defaults + * to 'generic_key' as the descriptor key. + */ + 'descriptor_key': (string); +} + +/** + * The following descriptor entry is appended to the descriptor: + * + * .. code-block:: cpp + * + * ("header_match", "") + */ +export interface _envoy_config_route_v3_RateLimit_Action_HeaderValueMatch { + /** + * The value to use in the descriptor entry. + */ + 'descriptor_value'?: (string); + /** + * If set to true, the action will append a descriptor entry when the + * request matches the headers. If set to false, the action will append a + * descriptor entry when the request does not match the headers. The + * default value is true. + */ + 'expect_match'?: (_google_protobuf_BoolValue); + /** + * Specifies a set of headers that the rate limit action should match + * on. The action will check the request’s headers against all the + * specified headers in the config. A match will happen if all the + * headers in the config are present in the request with the same values + * (or based on presence if the value field is not in the config). + */ + 'headers'?: (_envoy_config_route_v3_HeaderMatcher)[]; +} + +/** + * The following descriptor entry is appended to the descriptor: + * + * .. code-block:: cpp + * + * ("header_match", "") + */ +export interface _envoy_config_route_v3_RateLimit_Action_HeaderValueMatch__Output { + /** + * The value to use in the descriptor entry. + */ + 'descriptor_value': (string); + /** + * If set to true, the action will append a descriptor entry when the + * request matches the headers. If set to false, the action will append a + * descriptor entry when the request does not match the headers. The + * default value is true. + */ + 'expect_match'?: (_google_protobuf_BoolValue__Output); + /** + * Specifies a set of headers that the rate limit action should match + * on. The action will check the request’s headers against all the + * specified headers in the config. A match will happen if all the + * headers in the config are present in the request with the same values + * (or based on presence if the value field is not in the config). + */ + 'headers': (_envoy_config_route_v3_HeaderMatcher__Output)[]; +} + +/** + * The following descriptor entry is appended when the metadata contains a key value: + * + * .. code-block:: cpp + * + * ("", "") + */ +export interface _envoy_config_route_v3_RateLimit_Action_MetaData { + /** + * The key to use in the descriptor entry. + */ + 'descriptor_key'?: (string); + /** + * Metadata struct that defines the key and path to retrieve the string value. A match will + * only happen if the value in the metadata is of type string. + */ + 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey); + /** + * An optional value to use if *metadata_key* is empty. If not set and + * no value is present under the metadata_key then no descriptor is generated. + */ + 'default_value'?: (string); + /** + * Source of metadata + */ + 'source'?: (_envoy_config_route_v3_RateLimit_Action_MetaData_Source | keyof typeof _envoy_config_route_v3_RateLimit_Action_MetaData_Source); +} + +/** + * The following descriptor entry is appended when the metadata contains a key value: + * + * .. code-block:: cpp + * + * ("", "") + */ +export interface _envoy_config_route_v3_RateLimit_Action_MetaData__Output { + /** + * The key to use in the descriptor entry. + */ + 'descriptor_key': (string); + /** + * Metadata struct that defines the key and path to retrieve the string value. A match will + * only happen if the value in the metadata is of type string. + */ + 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey__Output); + /** + * An optional value to use if *metadata_key* is empty. If not set and + * no value is present under the metadata_key then no descriptor is generated. + */ + 'default_value': (string); + /** + * Source of metadata + */ + 'source': (keyof typeof _envoy_config_route_v3_RateLimit_Action_MetaData_Source); +} + +export interface _envoy_config_route_v3_RateLimit_Override { + /** + * Limit override from dynamic metadata. + */ + 'dynamic_metadata'?: (_envoy_config_route_v3_RateLimit_Override_DynamicMetadata); + 'override_specifier'?: "dynamic_metadata"; +} + +export interface _envoy_config_route_v3_RateLimit_Override__Output { + /** + * Limit override from dynamic metadata. + */ + 'dynamic_metadata'?: (_envoy_config_route_v3_RateLimit_Override_DynamicMetadata__Output); + 'override_specifier': "dynamic_metadata"; +} + +/** + * The following descriptor entry is appended to the descriptor and is populated using the + * trusted address from :ref:`x-forwarded-for `: + * + * .. code-block:: cpp + * + * ("remote_address", "") + */ +export interface _envoy_config_route_v3_RateLimit_Action_RemoteAddress { +} + +/** + * The following descriptor entry is appended to the descriptor and is populated using the + * trusted address from :ref:`x-forwarded-for `: + * + * .. code-block:: cpp + * + * ("remote_address", "") + */ +export interface _envoy_config_route_v3_RateLimit_Action_RemoteAddress__Output { +} + +/** + * The following descriptor entry is appended when a header contains a key that matches the + * *header_name*: + * + * .. code-block:: cpp + * + * ("", "") + */ +export interface _envoy_config_route_v3_RateLimit_Action_RequestHeaders { + /** + * The header name to be queried from the request headers. The header’s + * value is used to populate the value of the descriptor entry for the + * descriptor_key. + */ + 'header_name'?: (string); + /** + * The key to use in the descriptor entry. + */ + 'descriptor_key'?: (string); + /** + * If set to true, Envoy skips the descriptor while calling rate limiting service + * when header is not present in the request. By default it skips calling the + * rate limiting service if this header is not present in the request. + */ + 'skip_if_absent'?: (boolean); +} + +/** + * The following descriptor entry is appended when a header contains a key that matches the + * *header_name*: + * + * .. code-block:: cpp + * + * ("", "") + */ +export interface _envoy_config_route_v3_RateLimit_Action_RequestHeaders__Output { + /** + * The header name to be queried from the request headers. The header’s + * value is used to populate the value of the descriptor entry for the + * descriptor_key. + */ + 'header_name': (string); + /** + * The key to use in the descriptor entry. + */ + 'descriptor_key': (string); + /** + * If set to true, Envoy skips the descriptor while calling rate limiting service + * when header is not present in the request. By default it skips calling the + * rate limiting service if this header is not present in the request. + */ + 'skip_if_absent': (boolean); +} + +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto + +export enum _envoy_config_route_v3_RateLimit_Action_MetaData_Source { + /** + * Query :ref:`dynamic metadata ` + */ + DYNAMIC = 0, + /** + * Query :ref:`route entry metadata ` + */ + ROUTE_ENTRY = 1, +} + +/** + * The following descriptor entry is appended to the descriptor: + * + * .. code-block:: cpp + * + * ("source_cluster", "") + * + * is derived from the :option:`--service-cluster` option. + */ +export interface _envoy_config_route_v3_RateLimit_Action_SourceCluster { +} + +/** + * The following descriptor entry is appended to the descriptor: + * + * .. code-block:: cpp + * + * ("source_cluster", "") + * + * is derived from the :option:`--service-cluster` option. + */ +export interface _envoy_config_route_v3_RateLimit_Action_SourceCluster__Output { +} + +/** + * Global rate limiting :ref:`architecture overview `. + * Also applies to Local rate limiting :ref:`using descriptors `. + */ +export interface RateLimit { + /** + * Refers to the stage set in the filter. The rate limit configuration only + * applies to filters with the same stage number. The default stage number is + * 0. + * + * .. note:: + * + * The filter supports a range of 0 - 10 inclusively for stage numbers. + */ + 'stage'?: (_google_protobuf_UInt32Value); + /** + * The key to be set in runtime to disable this rate limit configuration. + */ + 'disable_key'?: (string); + /** + * A list of actions that are to be applied for this rate limit configuration. + * Order matters as the actions are processed sequentially and the descriptor + * is composed by appending descriptor entries in that sequence. If an action + * cannot append a descriptor entry, no descriptor is generated for the + * configuration. See :ref:`composing actions + * ` for additional documentation. + */ + 'actions'?: (_envoy_config_route_v3_RateLimit_Action)[]; + /** + * An optional limit override to be appended to the descriptor produced by this + * rate limit configuration. If the override value is invalid or cannot be resolved + * from metadata, no override is provided. See :ref:`rate limit override + * ` for more information. + */ + 'limit'?: (_envoy_config_route_v3_RateLimit_Override); +} + +/** + * Global rate limiting :ref:`architecture overview `. + * Also applies to Local rate limiting :ref:`using descriptors `. + */ +export interface RateLimit__Output { + /** + * Refers to the stage set in the filter. The rate limit configuration only + * applies to filters with the same stage number. The default stage number is + * 0. + * + * .. note:: + * + * The filter supports a range of 0 - 10 inclusively for stage numbers. + */ + 'stage'?: (_google_protobuf_UInt32Value__Output); + /** + * The key to be set in runtime to disable this rate limit configuration. + */ + 'disable_key': (string); + /** + * A list of actions that are to be applied for this rate limit configuration. + * Order matters as the actions are processed sequentially and the descriptor + * is composed by appending descriptor entries in that sequence. If an action + * cannot append a descriptor entry, no descriptor is generated for the + * configuration. See :ref:`composing actions + * ` for additional documentation. + */ + 'actions': (_envoy_config_route_v3_RateLimit_Action__Output)[]; + /** + * An optional limit override to be appended to the descriptor produced by this + * rate limit configuration. If the override value is invalid or cannot be resolved + * from metadata, no override is provided. See :ref:`rate limit override + * ` for more information. + */ + 'limit'?: (_envoy_config_route_v3_RateLimit_Override__Output); +} 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 new file mode 100644 index 000000000..baea6bc4e --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RedirectAction.ts @@ -0,0 +1,222 @@ +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto + +import type { RegexMatchAndSubstitute as _envoy_type_matcher_v3_RegexMatchAndSubstitute, RegexMatchAndSubstitute__Output as _envoy_type_matcher_v3_RegexMatchAndSubstitute__Output } from '../../../../envoy/type/matcher/v3/RegexMatchAndSubstitute'; + +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto + +export enum _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, +} + +/** + * [#next-free-field: 10] + */ +export interface RedirectAction { + /** + * The host portion of the URL will be swapped with this value. + */ + 'host_redirect'?: (string); + /** + * The path portion of the URL will be swapped with this value. + * Please note that query string in path_redirect will override the + * request's query string and will not be stripped. + * + * For example, let's say we have the following routes: + * + * - match: { path: "/old-path-1" } + * redirect: { path_redirect: "/new-path-1" } + * - match: { path: "/old-path-2" } + * redirect: { path_redirect: "/new-path-2", strip-query: "true" } + * - match: { path: "/old-path-3" } + * redirect: { path_redirect: "/new-path-3?foo=1", strip_query: "true" } + * + * 1. if request uri is "/old-path-1?bar=1", users will be redirected to "/new-path-1?bar=1" + * 2. if request uri is "/old-path-2?bar=1", users will be redirected to "/new-path-2" + * 3. if request uri is "/old-path-3?bar=1", users will be redirected to "/new-path-3?foo=1" + */ + 'path_redirect'?: (string); + /** + * 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); + /** + * The scheme portion of the URL will be swapped with "https". + */ + 'https_redirect'?: (boolean); + /** + * Indicates that during redirection, the matched prefix (or path) + * should be swapped with this value. This option allows redirect URLs be dynamically created + * based on the request. + * + * .. attention:: + * + * Pay attention to the use of trailing slashes as mentioned in + * :ref:`RouteAction's prefix_rewrite `. + */ + 'prefix_rewrite'?: (string); + /** + * Indicates that during redirection, the query portion of the URL will + * be removed. Default value is false. + */ + 'strip_query'?: (boolean); + /** + * The scheme portion of the URL will be swapped with this value. + */ + 'scheme_redirect'?: (string); + /** + * The port value of the URL will be swapped with this value. + */ + 'port_redirect'?: (number); + /** + * Indicates that during redirect, portions of the path that match the + * pattern should be rewritten, even allowing the substitution of capture + * groups from the pattern into the new path as specified by the rewrite + * substitution string. This is useful to allow application paths to be + * rewritten in a way that is aware of segments with variable content like + * identifiers. + * + * Examples using Google's `RE2 `_ engine: + * + * * The path pattern ``^/service/([^/]+)(/.*)$`` paired with a substitution + * string of ``\2/instance/\1`` would transform ``/service/foo/v1/api`` + * into ``/v1/api/instance/foo``. + * + * * The pattern ``one`` paired with a substitution string of ``two`` would + * transform ``/xxx/one/yyy/one/zzz`` into ``/xxx/two/yyy/two/zzz``. + * + * * The pattern ``^(.*?)one(.*)$`` paired with a substitution string of + * ``\1two\2`` would replace only the first occurrence of ``one``, + * transforming path ``/xxx/one/yyy/one/zzz`` into ``/xxx/two/yyy/one/zzz``. + * + * * The pattern ``(?i)/xxx/`` paired with a substitution string of ``/yyy/`` + * would do a case-insensitive match and transform path ``/aaa/XxX/bbb`` to + * ``/aaa/yyy/bbb``. + */ + 'regex_rewrite'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute); + /** + * When the scheme redirection take place, the following rules apply: + * 1. If the source URI scheme is `http` and the port is explicitly + * set to `:80`, the port will be removed after the redirection + * 2. If the source URI scheme is `https` and the port is explicitly + * set to `:443`, the port will be removed after the redirection + */ + 'scheme_rewrite_specifier'?: "https_redirect"|"scheme_redirect"; + 'path_rewrite_specifier'?: "path_redirect"|"prefix_rewrite"|"regex_rewrite"; +} + +/** + * [#next-free-field: 10] + */ +export interface RedirectAction__Output { + /** + * The host portion of the URL will be swapped with this value. + */ + 'host_redirect': (string); + /** + * The path portion of the URL will be swapped with this value. + * Please note that query string in path_redirect will override the + * request's query string and will not be stripped. + * + * For example, let's say we have the following routes: + * + * - match: { path: "/old-path-1" } + * redirect: { path_redirect: "/new-path-1" } + * - match: { path: "/old-path-2" } + * redirect: { path_redirect: "/new-path-2", strip-query: "true" } + * - match: { path: "/old-path-3" } + * redirect: { path_redirect: "/new-path-3?foo=1", strip_query: "true" } + * + * 1. if request uri is "/old-path-1?bar=1", users will be redirected to "/new-path-1?bar=1" + * 2. if request uri is "/old-path-2?bar=1", users will be redirected to "/new-path-2" + * 3. if request uri is "/old-path-3?bar=1", users will be redirected to "/new-path-3?foo=1" + */ + 'path_redirect'?: (string); + /** + * 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); + /** + * The scheme portion of the URL will be swapped with "https". + */ + 'https_redirect'?: (boolean); + /** + * Indicates that during redirection, the matched prefix (or path) + * should be swapped with this value. This option allows redirect URLs be dynamically created + * based on the request. + * + * .. attention:: + * + * Pay attention to the use of trailing slashes as mentioned in + * :ref:`RouteAction's prefix_rewrite `. + */ + 'prefix_rewrite'?: (string); + /** + * Indicates that during redirection, the query portion of the URL will + * be removed. Default value is false. + */ + 'strip_query': (boolean); + /** + * The scheme portion of the URL will be swapped with this value. + */ + 'scheme_redirect'?: (string); + /** + * The port value of the URL will be swapped with this value. + */ + 'port_redirect': (number); + /** + * Indicates that during redirect, portions of the path that match the + * pattern should be rewritten, even allowing the substitution of capture + * groups from the pattern into the new path as specified by the rewrite + * substitution string. This is useful to allow application paths to be + * rewritten in a way that is aware of segments with variable content like + * identifiers. + * + * Examples using Google's `RE2 `_ engine: + * + * * The path pattern ``^/service/([^/]+)(/.*)$`` paired with a substitution + * string of ``\2/instance/\1`` would transform ``/service/foo/v1/api`` + * into ``/v1/api/instance/foo``. + * + * * The pattern ``one`` paired with a substitution string of ``two`` would + * transform ``/xxx/one/yyy/one/zzz`` into ``/xxx/two/yyy/two/zzz``. + * + * * The pattern ``^(.*?)one(.*)$`` paired with a substitution string of + * ``\1two\2`` would replace only the first occurrence of ``one``, + * transforming path ``/xxx/one/yyy/one/zzz`` into ``/xxx/two/yyy/one/zzz``. + * + * * The pattern ``(?i)/xxx/`` paired with a substitution string of ``/yyy/`` + * would do a case-insensitive match and transform path ``/aaa/XxX/bbb`` to + * ``/aaa/yyy/bbb``. + */ + 'regex_rewrite'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute__Output); + /** + * When the scheme redirection take place, the following rules apply: + * 1. If the source URI scheme is `http` and the port is explicitly + * set to `:80`, the port will be removed after the redirection + * 2. If the source URI scheme is `https` and the port is explicitly + * set to `:443`, the port will be removed after the redirection + */ + 'scheme_rewrite_specifier': "https_redirect"|"scheme_redirect"; + 'path_rewrite_specifier': "path_redirect"|"prefix_rewrite"|"regex_rewrite"; +} 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 new file mode 100644 index 000000000..52f391dd9 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RetryPolicy.ts @@ -0,0 +1,392 @@ +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto + +import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; +import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; +import type { HeaderMatcher as _envoy_config_route_v3_HeaderMatcher, HeaderMatcher__Output as _envoy_config_route_v3_HeaderMatcher__Output } from '../../../../envoy/config/route/v3/HeaderMatcher'; +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'; + +/** + * A retry back-off strategy that applies when the upstream server rate limits + * the request. + * + * Given this configuration: + * + * .. code-block:: yaml + * + * rate_limited_retry_back_off: + * reset_headers: + * - name: Retry-After + * format: SECONDS + * - name: X-RateLimit-Reset + * format: UNIX_TIMESTAMP + * max_interval: "300s" + * + * The following algorithm will apply: + * + * 1. If the response contains the header ``Retry-After`` its value must be on + * the form ``120`` (an integer that represents the number of seconds to + * wait before retrying). If so, this value is used as the back-off interval. + * 2. Otherwise, if the response contains the header ``X-RateLimit-Reset`` its + * value must be on the form ``1595320702`` (an integer that represents the + * point in time at which to retry, as a Unix timestamp in seconds). If so, + * the current time is subtracted from this value and the result is used as + * the back-off interval. + * 3. Otherwise, Envoy will use the default + * :ref:`exponential back-off ` + * strategy. + * + * No matter which format is used, if the resulting back-off interval exceeds + * ``max_interval`` it is discarded and the next header in ``reset_headers`` + * is tried. If a request timeout is configured for the route it will further + * limit how long the request will be allowed to run. + * + * To prevent many clients retrying at the same point in time jitter is added + * to the back-off interval, so the resulting interval is decided by taking: + * ``random(interval, interval * 1.5)``. + * + * .. attention:: + * + * Configuring ``rate_limited_retry_back_off`` will not by itself cause a request + * to be retried. You will still need to configure the right retry policy to match + * the responses from the upstream server. + */ +export interface _envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff { + /** + * Specifies the reset headers (like ``Retry-After`` or ``X-RateLimit-Reset``) + * to match against the response. Headers are tried in order, and matched case + * insensitive. The first header to be parsed successfully is used. If no headers + * match the default exponential back-off is used instead. + */ + 'reset_headers'?: (_envoy_config_route_v3_RetryPolicy_ResetHeader)[]; + /** + * Specifies the maximum back off interval that Envoy will allow. If a reset + * header contains an interval longer than this then it will be discarded and + * the next header will be tried. Defaults to 300 seconds. + */ + 'max_interval'?: (_google_protobuf_Duration); +} + +/** + * A retry back-off strategy that applies when the upstream server rate limits + * the request. + * + * Given this configuration: + * + * .. code-block:: yaml + * + * rate_limited_retry_back_off: + * reset_headers: + * - name: Retry-After + * format: SECONDS + * - name: X-RateLimit-Reset + * format: UNIX_TIMESTAMP + * max_interval: "300s" + * + * The following algorithm will apply: + * + * 1. If the response contains the header ``Retry-After`` its value must be on + * the form ``120`` (an integer that represents the number of seconds to + * wait before retrying). If so, this value is used as the back-off interval. + * 2. Otherwise, if the response contains the header ``X-RateLimit-Reset`` its + * value must be on the form ``1595320702`` (an integer that represents the + * point in time at which to retry, as a Unix timestamp in seconds). If so, + * the current time is subtracted from this value and the result is used as + * the back-off interval. + * 3. Otherwise, Envoy will use the default + * :ref:`exponential back-off ` + * strategy. + * + * No matter which format is used, if the resulting back-off interval exceeds + * ``max_interval`` it is discarded and the next header in ``reset_headers`` + * is tried. If a request timeout is configured for the route it will further + * limit how long the request will be allowed to run. + * + * To prevent many clients retrying at the same point in time jitter is added + * to the back-off interval, so the resulting interval is decided by taking: + * ``random(interval, interval * 1.5)``. + * + * .. attention:: + * + * Configuring ``rate_limited_retry_back_off`` will not by itself cause a request + * to be retried. You will still need to configure the right retry policy to match + * the responses from the upstream server. + */ +export interface _envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff__Output { + /** + * Specifies the reset headers (like ``Retry-After`` or ``X-RateLimit-Reset``) + * to match against the response. Headers are tried in order, and matched case + * insensitive. The first header to be parsed successfully is used. If no headers + * match the default exponential back-off is used instead. + */ + 'reset_headers': (_envoy_config_route_v3_RetryPolicy_ResetHeader__Output)[]; + /** + * Specifies the maximum back off interval that Envoy will allow. If a reset + * header contains an interval longer than this then it will be discarded and + * the next header will be tried. Defaults to 300 seconds. + */ + 'max_interval'?: (_google_protobuf_Duration__Output); +} + +export interface _envoy_config_route_v3_RetryPolicy_ResetHeader { + /** + * The name of the reset header. + * + * .. note:: + * + * If the header appears multiple times only the first value is used. + */ + 'name'?: (string); + /** + * The format of the reset header. + */ + 'format'?: (_envoy_config_route_v3_RetryPolicy_ResetHeaderFormat | keyof typeof _envoy_config_route_v3_RetryPolicy_ResetHeaderFormat); +} + +export interface _envoy_config_route_v3_RetryPolicy_ResetHeader__Output { + /** + * The name of the reset header. + * + * .. note:: + * + * If the header appears multiple times only the first value is used. + */ + 'name': (string); + /** + * The format of the reset header. + */ + 'format': (keyof typeof _envoy_config_route_v3_RetryPolicy_ResetHeaderFormat); +} + +// 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 interface _envoy_config_route_v3_RetryPolicy_RetryBackOff { + /** + * Specifies the base interval between retries. This parameter is required and must be greater + * than zero. Values less than 1 ms are rounded up to 1 ms. + * See :ref:`config_http_filters_router_x-envoy-max-retries` for a discussion of Envoy's + * back-off algorithm. + */ + 'base_interval'?: (_google_protobuf_Duration); + /** + * Specifies the maximum interval between retries. This parameter is optional, but must be + * greater than or equal to the `base_interval` if set. The default is 10 times the + * `base_interval`. See :ref:`config_http_filters_router_x-envoy-max-retries` for a discussion + * of Envoy's back-off algorithm. + */ + 'max_interval'?: (_google_protobuf_Duration); +} + +export interface _envoy_config_route_v3_RetryPolicy_RetryBackOff__Output { + /** + * Specifies the base interval between retries. This parameter is required and must be greater + * than zero. Values less than 1 ms are rounded up to 1 ms. + * See :ref:`config_http_filters_router_x-envoy-max-retries` for a discussion of Envoy's + * back-off algorithm. + */ + 'base_interval'?: (_google_protobuf_Duration__Output); + /** + * Specifies the maximum interval between retries. This parameter is optional, but must be + * greater than or equal to the `base_interval` if set. The default is 10 times the + * `base_interval`. See :ref:`config_http_filters_router_x-envoy-max-retries` for a discussion + * of Envoy's back-off algorithm. + */ + 'max_interval'?: (_google_protobuf_Duration__Output); +} + +export interface _envoy_config_route_v3_RetryPolicy_RetryHostPredicate { + 'name'?: (string); + 'typed_config'?: (_google_protobuf_Any); + 'config_type'?: "typed_config"; +} + +export interface _envoy_config_route_v3_RetryPolicy_RetryHostPredicate__Output { + 'name': (string); + 'typed_config'?: (_google_protobuf_Any__Output); + 'config_type': "typed_config"; +} + +export interface _envoy_config_route_v3_RetryPolicy_RetryPriority { + 'name'?: (string); + 'typed_config'?: (_google_protobuf_Any); + 'config_type'?: "typed_config"; +} + +export interface _envoy_config_route_v3_RetryPolicy_RetryPriority__Output { + 'name': (string); + 'typed_config'?: (_google_protobuf_Any__Output); + 'config_type': "typed_config"; +} + +/** + * HTTP retry :ref:`architecture overview `. + * [#next-free-field: 12] + */ +export interface RetryPolicy { + /** + * Specifies the conditions under which retry takes place. These are the same + * conditions documented for :ref:`config_http_filters_router_x-envoy-retry-on` and + * :ref:`config_http_filters_router_x-envoy-retry-grpc-on`. + */ + 'retry_on'?: (string); + /** + * Specifies the allowed number of retries. This parameter is optional and + * defaults to 1. These are the same conditions documented for + * :ref:`config_http_filters_router_x-envoy-max-retries`. + */ + 'num_retries'?: (_google_protobuf_UInt32Value); + /** + * Specifies a non-zero upstream timeout per retry attempt. This parameter is optional. The + * same conditions documented for + * :ref:`config_http_filters_router_x-envoy-upstream-rq-per-try-timeout-ms` apply. + * + * .. note:: + * + * If left unspecified, Envoy will use the global + * :ref:`route timeout ` for the request. + * Consequently, when using a :ref:`5xx ` based + * retry policy, a request that times out will not be retried as the total timeout budget + * would have been exhausted. + */ + 'per_try_timeout'?: (_google_protobuf_Duration); + /** + * Specifies an implementation of a RetryPriority which is used to determine the + * distribution of load across priorities used for retries. Refer to + * :ref:`retry plugin configuration ` for more details. + */ + 'retry_priority'?: (_envoy_config_route_v3_RetryPolicy_RetryPriority); + /** + * Specifies a collection of RetryHostPredicates that will be consulted when selecting a host + * for retries. If any of the predicates reject the host, host selection will be reattempted. + * Refer to :ref:`retry plugin configuration ` for more + * details. + */ + 'retry_host_predicate'?: (_envoy_config_route_v3_RetryPolicy_RetryHostPredicate)[]; + /** + * The maximum number of times host selection will be reattempted before giving up, at which + * point the host that was last selected will be routed to. If unspecified, this will default to + * retrying once. + */ + 'host_selection_retry_max_attempts'?: (number | string | Long); + /** + * HTTP status codes that should trigger a retry in addition to those specified by retry_on. + */ + 'retriable_status_codes'?: (number)[]; + /** + * Specifies parameters that control exponential retry back off. This parameter is optional, in which case the + * default base interval is 25 milliseconds or, if set, the current value of the + * `upstream.base_retry_backoff_ms` runtime parameter. The default maximum interval is 10 times + * the base interval. The documentation for :ref:`config_http_filters_router_x-envoy-max-retries` + * describes Envoy's back-off algorithm. + */ + 'retry_back_off'?: (_envoy_config_route_v3_RetryPolicy_RetryBackOff); + /** + * HTTP response headers that trigger a retry if present in the response. A retry will be + * triggered if any of the header matches match the upstream response headers. + * The field is only consulted if 'retriable-headers' retry policy is active. + */ + 'retriable_headers'?: (_envoy_config_route_v3_HeaderMatcher)[]; + /** + * HTTP headers which must be present in the request for retries to be attempted. + */ + 'retriable_request_headers'?: (_envoy_config_route_v3_HeaderMatcher)[]; + /** + * Specifies parameters that control a retry back-off strategy that is used + * when the request is rate limited by the upstream server. The server may + * return a response header like ``Retry-After`` or ``X-RateLimit-Reset`` to + * provide feedback to the client on how long to wait before retrying. If + * configured, this back-off strategy will be used instead of the + * default exponential back off strategy (configured using `retry_back_off`) + * whenever a response includes the matching headers. + */ + 'rate_limited_retry_back_off'?: (_envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff); +} + +/** + * HTTP retry :ref:`architecture overview `. + * [#next-free-field: 12] + */ +export interface RetryPolicy__Output { + /** + * Specifies the conditions under which retry takes place. These are the same + * conditions documented for :ref:`config_http_filters_router_x-envoy-retry-on` and + * :ref:`config_http_filters_router_x-envoy-retry-grpc-on`. + */ + 'retry_on': (string); + /** + * Specifies the allowed number of retries. This parameter is optional and + * defaults to 1. These are the same conditions documented for + * :ref:`config_http_filters_router_x-envoy-max-retries`. + */ + 'num_retries'?: (_google_protobuf_UInt32Value__Output); + /** + * Specifies a non-zero upstream timeout per retry attempt. This parameter is optional. The + * same conditions documented for + * :ref:`config_http_filters_router_x-envoy-upstream-rq-per-try-timeout-ms` apply. + * + * .. note:: + * + * If left unspecified, Envoy will use the global + * :ref:`route timeout ` for the request. + * Consequently, when using a :ref:`5xx ` based + * retry policy, a request that times out will not be retried as the total timeout budget + * would have been exhausted. + */ + 'per_try_timeout'?: (_google_protobuf_Duration__Output); + /** + * Specifies an implementation of a RetryPriority which is used to determine the + * distribution of load across priorities used for retries. Refer to + * :ref:`retry plugin configuration ` for more details. + */ + 'retry_priority'?: (_envoy_config_route_v3_RetryPolicy_RetryPriority__Output); + /** + * Specifies a collection of RetryHostPredicates that will be consulted when selecting a host + * for retries. If any of the predicates reject the host, host selection will be reattempted. + * Refer to :ref:`retry plugin configuration ` for more + * details. + */ + 'retry_host_predicate': (_envoy_config_route_v3_RetryPolicy_RetryHostPredicate__Output)[]; + /** + * The maximum number of times host selection will be reattempted before giving up, at which + * point the host that was last selected will be routed to. If unspecified, this will default to + * retrying once. + */ + 'host_selection_retry_max_attempts': (string); + /** + * HTTP status codes that should trigger a retry in addition to those specified by retry_on. + */ + 'retriable_status_codes': (number)[]; + /** + * Specifies parameters that control exponential retry back off. This parameter is optional, in which case the + * default base interval is 25 milliseconds or, if set, the current value of the + * `upstream.base_retry_backoff_ms` runtime parameter. The default maximum interval is 10 times + * the base interval. The documentation for :ref:`config_http_filters_router_x-envoy-max-retries` + * describes Envoy's back-off algorithm. + */ + 'retry_back_off'?: (_envoy_config_route_v3_RetryPolicy_RetryBackOff__Output); + /** + * HTTP response headers that trigger a retry if present in the response. A retry will be + * triggered if any of the header matches match the upstream response headers. + * The field is only consulted if 'retriable-headers' retry policy is active. + */ + 'retriable_headers': (_envoy_config_route_v3_HeaderMatcher__Output)[]; + /** + * HTTP headers which must be present in the request for retries to be attempted. + */ + 'retriable_request_headers': (_envoy_config_route_v3_HeaderMatcher__Output)[]; + /** + * Specifies parameters that control a retry back-off strategy that is used + * when the request is rate limited by the upstream server. The server may + * return a response header like ``Retry-After`` or ``X-RateLimit-Reset`` to + * provide feedback to the client on how long to wait before retrying. If + * configured, this back-off strategy will be used instead of the + * default exponential back off strategy (configured using `retry_back_off`) + * whenever a response includes the matching headers. + */ + 'rate_limited_retry_back_off'?: (_envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/Route.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Route.ts similarity index 58% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/route/Route.ts rename to packages/grpc-js-xds/src/generated/envoy/config/route/v3/Route.ts index 86cb4ac3d..ea00564f8 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/Route.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Route.ts @@ -1,17 +1,16 @@ -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto -import type { RouteMatch as _envoy_api_v2_route_RouteMatch, RouteMatch__Output as _envoy_api_v2_route_RouteMatch__Output } from '../../../../envoy/api/v2/route/RouteMatch'; -import type { RouteAction as _envoy_api_v2_route_RouteAction, RouteAction__Output as _envoy_api_v2_route_RouteAction__Output } from '../../../../envoy/api/v2/route/RouteAction'; -import type { RedirectAction as _envoy_api_v2_route_RedirectAction, RedirectAction__Output as _envoy_api_v2_route_RedirectAction__Output } from '../../../../envoy/api/v2/route/RedirectAction'; -import type { Metadata as _envoy_api_v2_core_Metadata, Metadata__Output as _envoy_api_v2_core_Metadata__Output } from '../../../../envoy/api/v2/core/Metadata'; -import type { Decorator as _envoy_api_v2_route_Decorator, Decorator__Output as _envoy_api_v2_route_Decorator__Output } from '../../../../envoy/api/v2/route/Decorator'; -import type { DirectResponseAction as _envoy_api_v2_route_DirectResponseAction, DirectResponseAction__Output as _envoy_api_v2_route_DirectResponseAction__Output } from '../../../../envoy/api/v2/route/DirectResponseAction'; -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; -import type { HeaderValueOption as _envoy_api_v2_core_HeaderValueOption, HeaderValueOption__Output as _envoy_api_v2_core_HeaderValueOption__Output } from '../../../../envoy/api/v2/core/HeaderValueOption'; +import type { RouteMatch as _envoy_config_route_v3_RouteMatch, RouteMatch__Output as _envoy_config_route_v3_RouteMatch__Output } from '../../../../envoy/config/route/v3/RouteMatch'; +import type { RouteAction as _envoy_config_route_v3_RouteAction, RouteAction__Output as _envoy_config_route_v3_RouteAction__Output } from '../../../../envoy/config/route/v3/RouteAction'; +import type { RedirectAction as _envoy_config_route_v3_RedirectAction, RedirectAction__Output as _envoy_config_route_v3_RedirectAction__Output } from '../../../../envoy/config/route/v3/RedirectAction'; +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 { Decorator as _envoy_config_route_v3_Decorator, Decorator__Output as _envoy_config_route_v3_Decorator__Output } from '../../../../envoy/config/route/v3/Decorator'; +import type { DirectResponseAction as _envoy_config_route_v3_DirectResponseAction, DirectResponseAction__Output as _envoy_config_route_v3_DirectResponseAction__Output } from '../../../../envoy/config/route/v3/DirectResponseAction'; +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 { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; -import type { Tracing as _envoy_api_v2_route_Tracing, Tracing__Output as _envoy_api_v2_route_Tracing__Output } from '../../../../envoy/api/v2/route/Tracing'; +import type { Tracing as _envoy_config_route_v3_Tracing, Tracing__Output as _envoy_config_route_v3_Tracing__Output } from '../../../../envoy/config/route/v3/Tracing'; import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; -import type { FilterAction as _envoy_api_v2_route_FilterAction, FilterAction__Output as _envoy_api_v2_route_FilterAction__Output } from '../../../../envoy/api/v2/route/FilterAction'; +import type { FilterAction as _envoy_config_route_v3_FilterAction, FilterAction__Output as _envoy_config_route_v3_FilterAction__Output } from '../../../../envoy/config/route/v3/FilterAction'; /** * A route is both a specification of how to match a request as well as an indication of what to do @@ -20,22 +19,22 @@ import type { FilterAction as _envoy_api_v2_route_FilterAction, FilterAction__Ou * .. attention:: * * Envoy supports routing on HTTP method via :ref:`header matching - * `. + * `. * [#next-free-field: 18] */ export interface Route { /** * Route matching parameters. */ - 'match'?: (_envoy_api_v2_route_RouteMatch); + 'match'?: (_envoy_config_route_v3_RouteMatch); /** * Route request to some upstream cluster. */ - 'route'?: (_envoy_api_v2_route_RouteAction); + 'route'?: (_envoy_config_route_v3_RouteAction); /** * Return a redirect. */ - 'redirect'?: (_envoy_api_v2_route_RedirectAction); + 'redirect'?: (_envoy_config_route_v3_RedirectAction); /** * The Metadata field can be used to provide additional information * about the route. It can be used for configuration, stats, and logging. @@ -43,41 +42,33 @@ export interface Route { * For instance, if the metadata is intended for the Router filter, * the filter name should be specified as *envoy.filters.http.router*. */ - 'metadata'?: (_envoy_api_v2_core_Metadata); + 'metadata'?: (_envoy_config_core_v3_Metadata); /** * Decorator for the matched route. */ - 'decorator'?: (_envoy_api_v2_route_Decorator); + 'decorator'?: (_envoy_config_route_v3_Decorator); /** * Return an arbitrary HTTP response directly, without proxying. */ - 'direct_response'?: (_envoy_api_v2_route_DirectResponseAction); - /** - * The per_filter_config field can be used to provide route-specific - * configurations for filters. The key should match the filter name, such as - * *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter - * specific; see the :ref:`HTTP filter documentation ` for - * if and how it is utilized. - */ - 'per_filter_config'?: ({[key: string]: _google_protobuf_Struct}); + 'direct_response'?: (_envoy_config_route_v3_DirectResponseAction); /** * Specifies a set of headers that will be added to requests matching this * route. Headers specified at this level are applied before headers from the - * enclosing :ref:`envoy_api_msg_route.VirtualHost` and - * :ref:`envoy_api_msg_RouteConfiguration`. For more information, including details on + * enclosing :ref:`envoy_api_msg_config.route.v3.VirtualHost` and + * :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including details on * header value syntax, see the documentation on :ref:`custom request headers * `. */ - 'request_headers_to_add'?: (_envoy_api_v2_core_HeaderValueOption)[]; + 'request_headers_to_add'?: (_envoy_config_core_v3_HeaderValueOption)[]; /** * Specifies a set of headers that will be added to responses to requests * matching this route. Headers specified at this level are applied before - * headers from the enclosing :ref:`envoy_api_msg_route.VirtualHost` and - * :ref:`envoy_api_msg_RouteConfiguration`. For more information, including + * headers from the enclosing :ref:`envoy_api_msg_config.route.v3.VirtualHost` and + * :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including * details on header value syntax, see the documentation on * :ref:`custom request headers `. */ - 'response_headers_to_add'?: (_envoy_api_v2_core_HeaderValueOption)[]; + 'response_headers_to_add'?: (_envoy_config_core_v3_HeaderValueOption)[]; /** * Specifies a list of HTTP headers that should be removed from each response * to requests matching this route. @@ -94,6 +85,9 @@ export interface Route { * *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter * specific; see the :ref:`HTTP filter documentation ` for * if and how it is utilized. + * [#comment: An entry's value may be wrapped in a + * :ref:`FilterConfig` + * message to specify additional options.] */ 'typed_per_filter_config'?: ({[key: string]: _google_protobuf_Any}); /** @@ -104,7 +98,7 @@ export interface Route { * Presence of the object defines whether the connection manager's tracing configuration * is overridden by this route specific instance. */ - 'tracing'?: (_envoy_api_v2_route_Tracing); + 'tracing'?: (_envoy_config_route_v3_Tracing); /** * The maximum bytes which will be buffered for retries and shadowing. * If set, the bytes actually buffered will be the minimum value of this and the @@ -115,8 +109,10 @@ export interface Route { * [#not-implemented-hide:] * If true, a filter will define the action (e.g., it could dynamically generate the * RouteAction). + * [#comment: TODO(samflattery): Remove cleanup in route_fuzz_test.cc when + * implemented] */ - 'filter_action'?: (_envoy_api_v2_route_FilterAction); + 'filter_action'?: (_envoy_config_route_v3_FilterAction); 'action'?: "route"|"redirect"|"direct_response"|"filter_action"; } @@ -127,22 +123,22 @@ export interface Route { * .. attention:: * * Envoy supports routing on HTTP method via :ref:`header matching - * `. + * `. * [#next-free-field: 18] */ export interface Route__Output { /** * Route matching parameters. */ - 'match'?: (_envoy_api_v2_route_RouteMatch__Output); + 'match'?: (_envoy_config_route_v3_RouteMatch__Output); /** * Route request to some upstream cluster. */ - 'route'?: (_envoy_api_v2_route_RouteAction__Output); + 'route'?: (_envoy_config_route_v3_RouteAction__Output); /** * Return a redirect. */ - 'redirect'?: (_envoy_api_v2_route_RedirectAction__Output); + 'redirect'?: (_envoy_config_route_v3_RedirectAction__Output); /** * The Metadata field can be used to provide additional information * about the route. It can be used for configuration, stats, and logging. @@ -150,41 +146,33 @@ export interface Route__Output { * For instance, if the metadata is intended for the Router filter, * the filter name should be specified as *envoy.filters.http.router*. */ - 'metadata'?: (_envoy_api_v2_core_Metadata__Output); + 'metadata'?: (_envoy_config_core_v3_Metadata__Output); /** * Decorator for the matched route. */ - 'decorator'?: (_envoy_api_v2_route_Decorator__Output); + 'decorator'?: (_envoy_config_route_v3_Decorator__Output); /** * Return an arbitrary HTTP response directly, without proxying. */ - 'direct_response'?: (_envoy_api_v2_route_DirectResponseAction__Output); - /** - * The per_filter_config field can be used to provide route-specific - * configurations for filters. The key should match the filter name, such as - * *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter - * specific; see the :ref:`HTTP filter documentation ` for - * if and how it is utilized. - */ - 'per_filter_config'?: ({[key: string]: _google_protobuf_Struct__Output}); + 'direct_response'?: (_envoy_config_route_v3_DirectResponseAction__Output); /** * Specifies a set of headers that will be added to requests matching this * route. Headers specified at this level are applied before headers from the - * enclosing :ref:`envoy_api_msg_route.VirtualHost` and - * :ref:`envoy_api_msg_RouteConfiguration`. For more information, including details on + * enclosing :ref:`envoy_api_msg_config.route.v3.VirtualHost` and + * :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including details on * header value syntax, see the documentation on :ref:`custom request headers * `. */ - 'request_headers_to_add': (_envoy_api_v2_core_HeaderValueOption__Output)[]; + 'request_headers_to_add': (_envoy_config_core_v3_HeaderValueOption__Output)[]; /** * Specifies a set of headers that will be added to responses to requests * matching this route. Headers specified at this level are applied before - * headers from the enclosing :ref:`envoy_api_msg_route.VirtualHost` and - * :ref:`envoy_api_msg_RouteConfiguration`. For more information, including + * headers from the enclosing :ref:`envoy_api_msg_config.route.v3.VirtualHost` and + * :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including * details on header value syntax, see the documentation on * :ref:`custom request headers `. */ - 'response_headers_to_add': (_envoy_api_v2_core_HeaderValueOption__Output)[]; + 'response_headers_to_add': (_envoy_config_core_v3_HeaderValueOption__Output)[]; /** * Specifies a list of HTTP headers that should be removed from each response * to requests matching this route. @@ -201,6 +189,9 @@ export interface Route__Output { * *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter * specific; see the :ref:`HTTP filter documentation ` for * if and how it is utilized. + * [#comment: An entry's value may be wrapped in a + * :ref:`FilterConfig` + * message to specify additional options.] */ 'typed_per_filter_config'?: ({[key: string]: _google_protobuf_Any__Output}); /** @@ -211,7 +202,7 @@ export interface Route__Output { * Presence of the object defines whether the connection manager's tracing configuration * is overridden by this route specific instance. */ - 'tracing'?: (_envoy_api_v2_route_Tracing__Output); + 'tracing'?: (_envoy_config_route_v3_Tracing__Output); /** * The maximum bytes which will be buffered for retries and shadowing. * If set, the bytes actually buffered will be the minimum value of this and the @@ -222,7 +213,9 @@ export interface Route__Output { * [#not-implemented-hide:] * If true, a filter will define the action (e.g., it could dynamically generate the * RouteAction). + * [#comment: TODO(samflattery): Remove cleanup in route_fuzz_test.cc when + * implemented] */ - 'filter_action'?: (_envoy_api_v2_route_FilterAction__Output); + 'filter_action'?: (_envoy_config_route_v3_FilterAction__Output); 'action': "route"|"redirect"|"direct_response"|"filter_action"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/RouteAction.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteAction.ts similarity index 62% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/route/RouteAction.ts rename to packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteAction.ts index 5f07bae9b..797d6eda6 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/RouteAction.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteAction.ts @@ -1,22 +1,24 @@ -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto -import type { WeightedCluster as _envoy_api_v2_route_WeightedCluster, WeightedCluster__Output as _envoy_api_v2_route_WeightedCluster__Output } from '../../../../envoy/api/v2/route/WeightedCluster'; -import type { Metadata as _envoy_api_v2_core_Metadata, Metadata__Output as _envoy_api_v2_core_Metadata__Output } from '../../../../envoy/api/v2/core/Metadata'; +import type { WeightedCluster as _envoy_config_route_v3_WeightedCluster, WeightedCluster__Output as _envoy_config_route_v3_WeightedCluster__Output } from '../../../../envoy/config/route/v3/WeightedCluster'; +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 { 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_api_v2_route_RetryPolicy, RetryPolicy__Output as _envoy_api_v2_route_RetryPolicy__Output } from '../../../../envoy/api/v2/route/RetryPolicy'; -import type { RoutingPriority as _envoy_api_v2_core_RoutingPriority } from '../../../../envoy/api/v2/core/RoutingPriority'; -import type { RateLimit as _envoy_api_v2_route_RateLimit, RateLimit__Output as _envoy_api_v2_route_RateLimit__Output } from '../../../../envoy/api/v2/route/RateLimit'; -import type { CorsPolicy as _envoy_api_v2_route_CorsPolicy, CorsPolicy__Output as _envoy_api_v2_route_CorsPolicy__Output } from '../../../../envoy/api/v2/route/CorsPolicy'; -import type { HedgePolicy as _envoy_api_v2_route_HedgePolicy, HedgePolicy__Output as _envoy_api_v2_route_HedgePolicy__Output } from '../../../../envoy/api/v2/route/HedgePolicy'; +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 { 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'; import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; -import type { RegexMatchAndSubstitute as _envoy_type_matcher_RegexMatchAndSubstitute, RegexMatchAndSubstitute__Output as _envoy_type_matcher_RegexMatchAndSubstitute__Output } from '../../../../envoy/type/matcher/RegexMatchAndSubstitute'; +import type { RegexMatchAndSubstitute as _envoy_type_matcher_v3_RegexMatchAndSubstitute, RegexMatchAndSubstitute__Output as _envoy_type_matcher_v3_RegexMatchAndSubstitute__Output } from '../../../../envoy/type/matcher/v3/RegexMatchAndSubstitute'; import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; -import type { RuntimeFractionalPercent as _envoy_api_v2_core_RuntimeFractionalPercent, RuntimeFractionalPercent__Output as _envoy_api_v2_core_RuntimeFractionalPercent__Output } from '../../../../envoy/api/v2/core/RuntimeFractionalPercent'; +import type { InternalRedirectPolicy as _envoy_config_route_v3_InternalRedirectPolicy, InternalRedirectPolicy__Output as _envoy_config_route_v3_InternalRedirectPolicy__Output } from '../../../../envoy/config/route/v3/InternalRedirectPolicy'; +import type { RuntimeFractionalPercent as _envoy_config_core_v3_RuntimeFractionalPercent, RuntimeFractionalPercent__Output as _envoy_config_core_v3_RuntimeFractionalPercent__Output } from '../../../../envoy/config/core/v3/RuntimeFractionalPercent'; +import type { ProxyProtocolConfig as _envoy_config_core_v3_ProxyProtocolConfig, ProxyProtocolConfig__Output as _envoy_config_core_v3_ProxyProtocolConfig__Output } from '../../../../envoy/config/core/v3/ProxyProtocolConfig'; -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto -export enum _envoy_api_v2_route_RouteAction_ClusterNotFoundResponseCode { +export enum _envoy_config_route_v3_RouteAction_ClusterNotFoundResponseCode { /** * HTTP status code - 503 Service Unavailable. */ @@ -27,14 +29,44 @@ export enum _envoy_api_v2_route_RouteAction_ClusterNotFoundResponseCode { NOT_FOUND = 1, } -export interface _envoy_api_v2_route_RouteAction_HashPolicy_ConnectionProperties { +/** + * Configuration for sending data upstream as a raw data payload. This is used for + * CONNECT or POST requests, when forwarding request payload as raw TCP. + */ +export interface _envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig { + /** + * If present, the proxy protocol header will be prepended to the CONNECT payload sent upstream. + */ + 'proxy_protocol_config'?: (_envoy_config_core_v3_ProxyProtocolConfig); + /** + * If set, the route will also allow forwarding POST payload as raw TCP. + */ + 'allow_post'?: (boolean); +} + +/** + * Configuration for sending data upstream as a raw data payload. This is used for + * CONNECT or POST requests, when forwarding request payload as raw TCP. + */ +export interface _envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig__Output { + /** + * If present, the proxy protocol header will be prepended to the CONNECT payload sent upstream. + */ + 'proxy_protocol_config'?: (_envoy_config_core_v3_ProxyProtocolConfig__Output); + /** + * If set, the route will also allow forwarding POST payload as raw TCP. + */ + 'allow_post': (boolean); +} + +export interface _envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties { /** * Hash on source IP address. */ 'source_ip'?: (boolean); } -export interface _envoy_api_v2_route_RouteAction_HashPolicy_ConnectionProperties__Output { +export interface _envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties__Output { /** * Hash on source IP address. */ @@ -57,7 +89,7 @@ export interface _envoy_api_v2_route_RouteAction_HashPolicy_ConnectionProperties * streams on the same connection will independently receive the same * cookie, even if they arrive at the Envoy simultaneously. */ -export interface _envoy_api_v2_route_RouteAction_HashPolicy_Cookie { +export interface _envoy_config_route_v3_RouteAction_HashPolicy_Cookie { /** * The name of the cookie that will be used to obtain the hash key. If the * cookie is not present and ttl below is not set, no hash will be @@ -93,7 +125,7 @@ export interface _envoy_api_v2_route_RouteAction_HashPolicy_Cookie { * streams on the same connection will independently receive the same * cookie, even if they arrive at the Envoy simultaneously. */ -export interface _envoy_api_v2_route_RouteAction_HashPolicy_Cookie__Output { +export interface _envoy_config_route_v3_RouteAction_HashPolicy_Cookie__Output { /** * The name of the cookie that will be used to obtain the hash key. If the * cookie is not present and ttl below is not set, no hash will be @@ -113,7 +145,7 @@ export interface _envoy_api_v2_route_RouteAction_HashPolicy_Cookie__Output { 'path': (string); } -export interface _envoy_api_v2_route_RouteAction_HashPolicy_FilterState { +export interface _envoy_config_route_v3_RouteAction_HashPolicy_FilterState { /** * The name of the Object in the per-request filterState, which is an * Envoy::Http::Hashable object. If there is no data associated with the key, @@ -122,7 +154,7 @@ export interface _envoy_api_v2_route_RouteAction_HashPolicy_FilterState { 'key'?: (string); } -export interface _envoy_api_v2_route_RouteAction_HashPolicy_FilterState__Output { +export interface _envoy_config_route_v3_RouteAction_HashPolicy_FilterState__Output { /** * The name of the Object in the per-request filterState, which is an * Envoy::Http::Hashable object. If there is no data associated with the key, @@ -136,27 +168,27 @@ export interface _envoy_api_v2_route_RouteAction_HashPolicy_FilterState__Output * `. * [#next-free-field: 7] */ -export interface _envoy_api_v2_route_RouteAction_HashPolicy { +export interface _envoy_config_route_v3_RouteAction_HashPolicy { /** * Header hash policy. */ - 'header'?: (_envoy_api_v2_route_RouteAction_HashPolicy_Header); + 'header'?: (_envoy_config_route_v3_RouteAction_HashPolicy_Header); /** * Cookie hash policy. */ - 'cookie'?: (_envoy_api_v2_route_RouteAction_HashPolicy_Cookie); + 'cookie'?: (_envoy_config_route_v3_RouteAction_HashPolicy_Cookie); /** * Connection properties hash policy. */ - 'connection_properties'?: (_envoy_api_v2_route_RouteAction_HashPolicy_ConnectionProperties); + 'connection_properties'?: (_envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties); /** * Query parameter hash policy. */ - 'query_parameter'?: (_envoy_api_v2_route_RouteAction_HashPolicy_QueryParameter); + 'query_parameter'?: (_envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter); /** * Filter state hash policy. */ - 'filter_state'?: (_envoy_api_v2_route_RouteAction_HashPolicy_FilterState); + 'filter_state'?: (_envoy_config_route_v3_RouteAction_HashPolicy_FilterState); /** * The flag that short-circuits the hash computing. This field provides a * 'fallback' style of configuration: "if a terminal policy doesn't work, @@ -187,27 +219,27 @@ export interface _envoy_api_v2_route_RouteAction_HashPolicy { * `. * [#next-free-field: 7] */ -export interface _envoy_api_v2_route_RouteAction_HashPolicy__Output { +export interface _envoy_config_route_v3_RouteAction_HashPolicy__Output { /** * Header hash policy. */ - 'header'?: (_envoy_api_v2_route_RouteAction_HashPolicy_Header__Output); + 'header'?: (_envoy_config_route_v3_RouteAction_HashPolicy_Header__Output); /** * Cookie hash policy. */ - 'cookie'?: (_envoy_api_v2_route_RouteAction_HashPolicy_Cookie__Output); + 'cookie'?: (_envoy_config_route_v3_RouteAction_HashPolicy_Cookie__Output); /** * Connection properties hash policy. */ - 'connection_properties'?: (_envoy_api_v2_route_RouteAction_HashPolicy_ConnectionProperties__Output); + 'connection_properties'?: (_envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties__Output); /** * Query parameter hash policy. */ - 'query_parameter'?: (_envoy_api_v2_route_RouteAction_HashPolicy_QueryParameter__Output); + 'query_parameter'?: (_envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter__Output); /** * Filter state hash policy. */ - 'filter_state'?: (_envoy_api_v2_route_RouteAction_HashPolicy_FilterState__Output); + 'filter_state'?: (_envoy_config_route_v3_RouteAction_HashPolicy_FilterState__Output); /** * The flag that short-circuits the hash computing. This field provides a * 'fallback' style of configuration: "if a terminal policy doesn't work, @@ -233,33 +265,104 @@ export interface _envoy_api_v2_route_RouteAction_HashPolicy__Output { 'policy_specifier': "header"|"cookie"|"connection_properties"|"query_parameter"|"filter_state"; } -export interface _envoy_api_v2_route_RouteAction_HashPolicy_Header { +export interface _envoy_config_route_v3_RouteAction_HashPolicy_Header { /** * The name of the request header that will be used to obtain the hash * key. If the request header is not present, no hash will be produced. */ 'header_name'?: (string); + /** + * If specified, the request header value will be rewritten and used + * to produce the hash key. + */ + 'regex_rewrite'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute); } -export interface _envoy_api_v2_route_RouteAction_HashPolicy_Header__Output { +export interface _envoy_config_route_v3_RouteAction_HashPolicy_Header__Output { /** * The name of the request header that will be used to obtain the hash * key. If the request header is not present, no hash will be produced. */ 'header_name': (string); + /** + * If specified, the request header value will be rewritten and used + * to produce the hash key. + */ + 'regex_rewrite'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute__Output); } -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto /** * Configures :ref:`internal redirect ` behavior. + * [#next-major-version: remove this definition - it's defined in the InternalRedirectPolicy message.] */ -export enum _envoy_api_v2_route_RouteAction_InternalRedirectAction { +export enum _envoy_config_route_v3_RouteAction_InternalRedirectAction { PASS_THROUGH_INTERNAL_REDIRECT = 0, HANDLE_INTERNAL_REDIRECT = 1, } -export interface _envoy_api_v2_route_RouteAction_HashPolicy_QueryParameter { +export interface _envoy_config_route_v3_RouteAction_MaxStreamDuration { + /** + * Specifies the maximum duration allowed for streams on the route. If not specified, the value + * from the :ref:`max_stream_duration + * ` field in + * :ref:`HttpConnectionManager.common_http_protocol_options + * ` + * is used. If this field is set explicitly to zero, any + * HttpConnectionManager max_stream_duration timeout will be disabled for + * this route. + */ + 'max_stream_duration'?: (_google_protobuf_Duration); + /** + * If present, and the request contains a `grpc-timeout header + * `_, use that value as the + * *max_stream_duration*, but limit the applied timeout to the maximum value specified here. + * If set to 0, the `grpc-timeout` header is used without modification. + */ + 'grpc_timeout_header_max'?: (_google_protobuf_Duration); + /** + * If present, Envoy will adjust the timeout provided by the `grpc-timeout` header by + * subtracting the provided duration from the header. This is useful for allowing Envoy to set + * its global timeout to be less than that of the deadline imposed by the calling client, which + * makes it more likely that Envoy will handle the timeout instead of having the call canceled + * by the client. If, after applying the offset, the resulting timeout is zero or negative, + * the stream will timeout immediately. + */ + 'grpc_timeout_header_offset'?: (_google_protobuf_Duration); +} + +export interface _envoy_config_route_v3_RouteAction_MaxStreamDuration__Output { + /** + * Specifies the maximum duration allowed for streams on the route. If not specified, the value + * from the :ref:`max_stream_duration + * ` field in + * :ref:`HttpConnectionManager.common_http_protocol_options + * ` + * is used. If this field is set explicitly to zero, any + * HttpConnectionManager max_stream_duration timeout will be disabled for + * this route. + */ + 'max_stream_duration'?: (_google_protobuf_Duration__Output); + /** + * If present, and the request contains a `grpc-timeout header + * `_, use that value as the + * *max_stream_duration*, but limit the applied timeout to the maximum value specified here. + * If set to 0, the `grpc-timeout` header is used without modification. + */ + 'grpc_timeout_header_max'?: (_google_protobuf_Duration__Output); + /** + * If present, Envoy will adjust the timeout provided by the `grpc-timeout` header by + * subtracting the provided duration from the header. This is useful for allowing Envoy to set + * its global timeout to be less than that of the deadline imposed by the calling client, which + * makes it more likely that Envoy will handle the timeout instead of having the call canceled + * by the client. If, after applying the offset, the resulting timeout is zero or negative, + * the stream will timeout immediately. + */ + 'grpc_timeout_header_offset'?: (_google_protobuf_Duration__Output); +} + +export interface _envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter { /** * The name of the URL query parameter that will be used to obtain the hash * key. If the parameter is not present, no hash will be produced. Query @@ -268,7 +371,7 @@ export interface _envoy_api_v2_route_RouteAction_HashPolicy_QueryParameter { 'name'?: (string); } -export interface _envoy_api_v2_route_RouteAction_HashPolicy_QueryParameter__Output { +export interface _envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter__Output { /** * The name of the URL query parameter that will be used to obtain the hash * key. If the parameter is not present, no hash will be produced. Query @@ -290,30 +393,12 @@ export interface _envoy_api_v2_route_RouteAction_HashPolicy_QueryParameter__Outp * * Shadowing will not be triggered if the primary cluster does not exist. */ -export interface _envoy_api_v2_route_RouteAction_RequestMirrorPolicy { +export interface _envoy_config_route_v3_RouteAction_RequestMirrorPolicy { /** * Specifies the cluster that requests will be mirrored to. The cluster must * exist in the cluster manager configuration. */ 'cluster'?: (string); - /** - * If not specified, all requests to the target cluster will be mirrored. If - * specified, Envoy will lookup the runtime key to get the % of requests to - * mirror. Valid values are from 0 to 10000, allowing for increments of - * 0.01% of requests to be mirrored. If the runtime key is specified in the - * configuration but not present in runtime, 0 is the default and thus 0% of - * requests will be mirrored. - * - * .. attention:: - * - * **This field is deprecated**. Set the - * :ref:`runtime_fraction - * ` - * field instead. Mirroring occurs if both this and - * ` - * are not set. - */ - 'runtime_key'?: (string); /** * If not specified, all requests to the target cluster will be mirrored. * @@ -324,7 +409,7 @@ export interface _envoy_api_v2_route_RouteAction_RequestMirrorPolicy { * number is <= the value of the numerator N, or if the key is not present, the default * value, the request will be mirrored. */ - 'runtime_fraction'?: (_envoy_api_v2_core_RuntimeFractionalPercent); + 'runtime_fraction'?: (_envoy_config_core_v3_RuntimeFractionalPercent); /** * Determines if the trace span should be sampled. Defaults to true. */ @@ -344,30 +429,12 @@ export interface _envoy_api_v2_route_RouteAction_RequestMirrorPolicy { * * Shadowing will not be triggered if the primary cluster does not exist. */ -export interface _envoy_api_v2_route_RouteAction_RequestMirrorPolicy__Output { +export interface _envoy_config_route_v3_RouteAction_RequestMirrorPolicy__Output { /** * Specifies the cluster that requests will be mirrored to. The cluster must * exist in the cluster manager configuration. */ 'cluster': (string); - /** - * If not specified, all requests to the target cluster will be mirrored. If - * specified, Envoy will lookup the runtime key to get the % of requests to - * mirror. Valid values are from 0 to 10000, allowing for increments of - * 0.01% of requests to be mirrored. If the runtime key is specified in the - * configuration but not present in runtime, 0 is the default and thus 0% of - * requests will be mirrored. - * - * .. attention:: - * - * **This field is deprecated**. Set the - * :ref:`runtime_fraction - * ` - * field instead. Mirroring occurs if both this and - * ` - * are not set. - */ - 'runtime_key': (string); /** * If not specified, all requests to the target cluster will be mirrored. * @@ -378,7 +445,7 @@ export interface _envoy_api_v2_route_RouteAction_RequestMirrorPolicy__Output { * number is <= the value of the numerator N, or if the key is not present, the default * value, the request will be mirrored. */ - 'runtime_fraction'?: (_envoy_api_v2_core_RuntimeFractionalPercent__Output); + 'runtime_fraction'?: (_envoy_config_core_v3_RuntimeFractionalPercent__Output); /** * Determines if the trace span should be sampled. Defaults to true. */ @@ -390,10 +457,10 @@ export interface _envoy_api_v2_route_RouteAction_RequestMirrorPolicy__Output { * This overrides any enabled/disabled upgrade filter chain specified in the * HttpConnectionManager * :ref:`upgrade_configs - * ` + * ` * but does not affect any custom filter chain specified there. */ -export interface _envoy_api_v2_route_RouteAction_UpgradeConfig { +export interface _envoy_config_route_v3_RouteAction_UpgradeConfig { /** * The case-insensitive name of this upgrade, e.g. "websocket". * For each upgrade type present in upgrade_configs, requests with @@ -404,6 +471,13 @@ export interface _envoy_api_v2_route_RouteAction_UpgradeConfig { * Determines if upgrades are available on this route. Defaults to true. */ 'enabled'?: (_google_protobuf_BoolValue); + /** + * Configuration for sending data upstream as a raw data payload. This is used for + * CONNECT requests, when forwarding CONNECT payload as raw TCP. + * Note that CONNECT support is currently considered alpha in Envoy. + * [#comment:TODO(htuch): Replace the above comment with an alpha tag. + */ + 'connect_config'?: (_envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig); } /** @@ -411,10 +485,10 @@ export interface _envoy_api_v2_route_RouteAction_UpgradeConfig { * This overrides any enabled/disabled upgrade filter chain specified in the * HttpConnectionManager * :ref:`upgrade_configs - * ` + * ` * but does not affect any custom filter chain specified there. */ -export interface _envoy_api_v2_route_RouteAction_UpgradeConfig__Output { +export interface _envoy_config_route_v3_RouteAction_UpgradeConfig__Output { /** * The case-insensitive name of this upgrade, e.g. "websocket". * For each upgrade type present in upgrade_configs, requests with @@ -425,10 +499,17 @@ export interface _envoy_api_v2_route_RouteAction_UpgradeConfig__Output { * Determines if upgrades are available on this route. Defaults to true. */ 'enabled'?: (_google_protobuf_BoolValue__Output); + /** + * Configuration for sending data upstream as a raw data payload. This is used for + * CONNECT requests, when forwarding CONNECT payload as raw TCP. + * Note that CONNECT support is currently considered alpha in Envoy. + * [#comment:TODO(htuch): Replace the above comment with an alpha tag. + */ + 'connect_config'?: (_envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig__Output); } /** - * [#next-free-field: 34] + * [#next-free-field: 37] */ export interface RouteAction { /** @@ -446,6 +527,10 @@ export interface RouteAction { * * Internally, Envoy always uses the HTTP/2 *:authority* header to represent the HTTP/1 * *Host* header. Thus, if attempting to match on *Host*, match on *:authority* instead. + * + * .. note:: + * + * If the header appears multiple times only the first value is used. */ 'cluster_header'?: (string); /** @@ -455,15 +540,15 @@ export interface RouteAction { * :ref:`traffic splitting ` * for additional documentation. */ - 'weighted_clusters'?: (_envoy_api_v2_route_WeightedCluster); + 'weighted_clusters'?: (_envoy_config_route_v3_WeightedCluster); /** * Optional endpoint metadata match criteria used by the subset load balancer. Only endpoints * in the upstream cluster with metadata matching what's set in this field will be considered * for load balancing. If using :ref:`weighted_clusters - * `, metadata will be merged, with values + * `, metadata will be merged, with values * provided there taking precedence. The filter name should be specified as *envoy.lb*. */ - 'metadata_match'?: (_envoy_api_v2_core_Metadata); + 'metadata_match'?: (_envoy_config_core_v3_Metadata); /** * Indicates that during forwarding, the matched prefix (or path) should be * swapped with this value. This option allows application URLs to be rooted @@ -472,16 +557,16 @@ export interface RouteAction { * ` header. * * Only one of *prefix_rewrite* or - * :ref:`regex_rewrite ` + * :ref:`regex_rewrite ` * may be specified. * * .. attention:: * * Pay careful attention to the use of trailing slashes in the - * :ref:`route's match ` prefix value. + * :ref:`route's match ` prefix value. * Stripping a prefix from a path requires multiple Routes to handle all cases. For example, * rewriting * /prefix* to * /* and * /prefix/etc* to * /etc* cannot be done in a single - * :ref:`Route `, as shown by the below config entries: + * :ref:`Route `, as shown by the below config entries: * * .. code-block:: yaml * @@ -502,7 +587,7 @@ export interface RouteAction { * Indicates that during forwarding, the host header will be swapped with * this value. */ - 'host_rewrite'?: (string); + 'host_rewrite_literal'?: (string); /** * Indicates that during forwarding, the host header will be swapped with * the hostname of the upstream host chosen by the cluster manager. This @@ -530,29 +615,23 @@ export interface RouteAction { * it'll take precedence over the virtual host level retry policy entirely * (e.g.: policies are not merged, most internal one becomes the enforced policy). */ - 'retry_policy'?: (_envoy_api_v2_route_RetryPolicy); - /** - * Indicates that the route has a request mirroring policy. - * - * .. attention:: - * This field has been deprecated in favor of `request_mirror_policies` which supports one or - * more mirroring policies. - */ - 'request_mirror_policy'?: (_envoy_api_v2_route_RouteAction_RequestMirrorPolicy); + 'retry_policy'?: (_envoy_config_route_v3_RetryPolicy); /** * Optionally specifies the :ref:`routing priority `. */ - 'priority'?: (_envoy_api_v2_core_RoutingPriority | keyof typeof _envoy_api_v2_core_RoutingPriority); + 'priority'?: (_envoy_config_core_v3_RoutingPriority | keyof typeof _envoy_config_core_v3_RoutingPriority); /** * Specifies a set of rate limit configurations that could be applied to the * route. */ - 'rate_limits'?: (_envoy_api_v2_route_RateLimit)[]; + 'rate_limits'?: (_envoy_config_route_v3_RateLimit)[]; /** * Specifies if the rate limit filter should include the virtual host rate * limits. By default, if the route configured rate limits, the virtual host - * :ref:`rate_limits ` are not applied to the + * :ref:`rate_limits ` are not applied to the * request. + * + * This field is deprecated. Please use :ref:`vh_rate_limits ` */ 'include_vh_rate_limits'?: (_google_protobuf_BoolValue); /** @@ -569,25 +648,26 @@ export interface RouteAction { * there is already a hash generated, the hash is returned immediately, * ignoring the rest of the hash policy list. */ - 'hash_policy'?: (_envoy_api_v2_route_RouteAction_HashPolicy)[]; + 'hash_policy'?: (_envoy_config_route_v3_RouteAction_HashPolicy)[]; /** * Indicates that the route has a CORS policy. */ - 'cors'?: (_envoy_api_v2_route_CorsPolicy); + 'cors'?: (_envoy_config_route_v3_CorsPolicy); /** * 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_api_v2_route_RouteAction_ClusterNotFoundResponseCode | keyof typeof _envoy_api_v2_route_RouteAction_ClusterNotFoundResponseCode); + 'cluster_not_found_response_code'?: (_envoy_config_route_v3_RouteAction_ClusterNotFoundResponseCode | keyof typeof _envoy_config_route_v3_RouteAction_ClusterNotFoundResponseCode); /** + * Deprecated by :ref:`grpc_timeout_header_max ` * If present, and the request is a gRPC request, use the * `grpc-timeout header `_, * or its default value (infinity) instead of - * :ref:`timeout `, but limit the applied timeout + * :ref:`timeout `, but limit the applied timeout * to the maximum value specified here. If configured as 0, the maximum allowed timeout for * gRPC requests is infinity. If not configured at all, the `grpc-timeout` header is not used * and gRPC requests time out like any other requests using - * :ref:`timeout ` or its default. + * :ref:`timeout ` or its default. * This can be used to prevent unexpected upstream request timeouts due to potentially long * time gaps between gRPC request and response in gRPC streaming mode. * @@ -604,14 +684,14 @@ export interface RouteAction { /** * Specifies the idle timeout for the route. If not specified, there is no per-route idle timeout, * although the connection manager wide :ref:`stream_idle_timeout - * ` + * ` * will still apply. A value of 0 will completely disable the route's idle timeout, even if a * connection manager stream idle timeout is configured. * * The idle timeout is distinct to :ref:`timeout - * `, which provides an upper bound + * `, which provides an upper bound * on the upstream response time; :ref:`idle_timeout - * ` instead bounds the amount + * ` instead bounds the amount * of time the request's stream may be idle. * * After header decoding, the idle timeout will apply on downstream and @@ -620,17 +700,22 @@ export interface RouteAction { * fires, the stream is terminated with a 408 Request Timeout error code if no * upstream response header has been received, otherwise a stream reset * occurs. + * + * If the :ref:`overload action ` "envoy.overload_actions.reduce_timeouts" + * is configured, this timeout is scaled according to the value for + * :ref:`HTTP_DOWNSTREAM_STREAM_IDLE `. */ 'idle_timeout'?: (_google_protobuf_Duration); - 'upgrade_configs'?: (_envoy_api_v2_route_RouteAction_UpgradeConfig)[]; - 'internal_redirect_action'?: (_envoy_api_v2_route_RouteAction_InternalRedirectAction | keyof typeof _envoy_api_v2_route_RouteAction_InternalRedirectAction); + '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); /** * 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 * (e.g.: policies are not merged, most internal one becomes the enforced policy). */ - 'hedge_policy'?: (_envoy_api_v2_route_HedgePolicy); + 'hedge_policy'?: (_envoy_config_route_v3_HedgePolicy); /** + * Deprecated by :ref:`grpc_timeout_header_offset `. * If present, Envoy will adjust the timeout provided by the `grpc-timeout` header by subtracting * the provided duration from the header. This is useful in allowing Envoy to set its global * timeout to be less than that of the deadline imposed by the calling client, which makes it more @@ -649,24 +734,28 @@ export interface RouteAction { * * Pay attention to the potential security implications of using this option. Provided header * must come from trusted source. + * + * .. note:: + * + * If the header appears multiple times only the first value is used. */ - 'auto_host_rewrite_header'?: (string); + 'host_rewrite_header'?: (string); /** * Indicates that the route has request mirroring policies. */ - 'request_mirror_policies'?: (_envoy_api_v2_route_RouteAction_RequestMirrorPolicy)[]; + 'request_mirror_policies'?: (_envoy_config_route_v3_RouteAction_RequestMirrorPolicy)[]; /** * An internal redirect is handled, iff the number of previous internal redirects that a * downstream request has encountered is lower than this value, and - * :ref:`internal_redirect_action ` + * :ref:`internal_redirect_action ` * is set to :ref:`HANDLE_INTERNAL_REDIRECT - * ` + * ` * In the case where a downstream request is bounced among multiple routes by internal redirect, * the first route that hits this threshold, or has - * :ref:`internal_redirect_action ` + * :ref:`internal_redirect_action ` * set to * :ref:`PASS_THROUGH_INTERNAL_REDIRECT - * ` + * ` * will pass the redirect back to downstream. * * If not specified, at most one redirect will be followed. @@ -682,7 +771,7 @@ export interface RouteAction { * before the rewrite into the :ref:`x-envoy-original-path * ` header. * - * Only one of :ref:`prefix_rewrite ` + * Only one of :ref:`prefix_rewrite ` * or *regex_rewrite* may be specified. * * Examples using Google's `RE2 `_ engine: @@ -702,21 +791,50 @@ export interface RouteAction { * would do a case-insensitive match and transform path ``/aaa/XxX/bbb`` to * ``/aaa/yyy/bbb``. */ - 'regex_rewrite'?: (_envoy_type_matcher_RegexMatchAndSubstitute); + 'regex_rewrite'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute); /** * [#not-implemented-hide:] * Specifies the configuration for retry policy extension. Note that if this is set, it'll take * precedence over the virtual host level retry policy entirely (e.g.: policies are not merged, - * most internal one becomes the enforced policy). :ref:`Retry policy ` + * most internal one becomes the enforced policy). :ref:`Retry policy ` * should not be set if this field is used. */ 'retry_policy_typed_config'?: (_google_protobuf_Any); + /** + * If present, Envoy will try to follow an upstream redirect response instead of proxying the + * response back to the downstream. An upstream redirect response is defined + * by :ref:`redirect_response_codes + * `. + */ + 'internal_redirect_policy'?: (_envoy_config_route_v3_InternalRedirectPolicy); + /** + * Indicates that during forwarding, the host header will be swapped with + * the result of the regex substitution executed on path value with query and fragment removed. + * This is useful for transitioning variable content between path segment and subdomain. + * + * For example with the following config: + * + * .. code-block:: yaml + * + * host_rewrite_path_regex: + * pattern: + * google_re2: {} + * regex: "^/(.+)/.+$" + * substitution: \1 + * + * Would rewrite the host header to `envoyproxy.io` given the path `/envoyproxy.io/some/path`. + */ + 'host_rewrite_path_regex'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute); + /** + * Specifies the maximum stream duration for this route. + */ + 'max_stream_duration'?: (_envoy_config_route_v3_RouteAction_MaxStreamDuration); 'cluster_specifier'?: "cluster"|"cluster_header"|"weighted_clusters"; - 'host_rewrite_specifier'?: "host_rewrite"|"auto_host_rewrite"|"auto_host_rewrite_header"; + 'host_rewrite_specifier'?: "host_rewrite_literal"|"auto_host_rewrite"|"host_rewrite_header"|"host_rewrite_path_regex"; } /** - * [#next-free-field: 34] + * [#next-free-field: 37] */ export interface RouteAction__Output { /** @@ -734,6 +852,10 @@ export interface RouteAction__Output { * * Internally, Envoy always uses the HTTP/2 *:authority* header to represent the HTTP/1 * *Host* header. Thus, if attempting to match on *Host*, match on *:authority* instead. + * + * .. note:: + * + * If the header appears multiple times only the first value is used. */ 'cluster_header'?: (string); /** @@ -743,15 +865,15 @@ export interface RouteAction__Output { * :ref:`traffic splitting ` * for additional documentation. */ - 'weighted_clusters'?: (_envoy_api_v2_route_WeightedCluster__Output); + 'weighted_clusters'?: (_envoy_config_route_v3_WeightedCluster__Output); /** * Optional endpoint metadata match criteria used by the subset load balancer. Only endpoints * in the upstream cluster with metadata matching what's set in this field will be considered * for load balancing. If using :ref:`weighted_clusters - * `, metadata will be merged, with values + * `, metadata will be merged, with values * provided there taking precedence. The filter name should be specified as *envoy.lb*. */ - 'metadata_match'?: (_envoy_api_v2_core_Metadata__Output); + 'metadata_match'?: (_envoy_config_core_v3_Metadata__Output); /** * Indicates that during forwarding, the matched prefix (or path) should be * swapped with this value. This option allows application URLs to be rooted @@ -760,16 +882,16 @@ export interface RouteAction__Output { * ` header. * * Only one of *prefix_rewrite* or - * :ref:`regex_rewrite ` + * :ref:`regex_rewrite ` * may be specified. * * .. attention:: * * Pay careful attention to the use of trailing slashes in the - * :ref:`route's match ` prefix value. + * :ref:`route's match ` prefix value. * Stripping a prefix from a path requires multiple Routes to handle all cases. For example, * rewriting * /prefix* to * /* and * /prefix/etc* to * /etc* cannot be done in a single - * :ref:`Route `, as shown by the below config entries: + * :ref:`Route `, as shown by the below config entries: * * .. code-block:: yaml * @@ -790,7 +912,7 @@ export interface RouteAction__Output { * Indicates that during forwarding, the host header will be swapped with * this value. */ - 'host_rewrite'?: (string); + 'host_rewrite_literal'?: (string); /** * Indicates that during forwarding, the host header will be swapped with * the hostname of the upstream host chosen by the cluster manager. This @@ -818,29 +940,23 @@ export interface RouteAction__Output { * it'll take precedence over the virtual host level retry policy entirely * (e.g.: policies are not merged, most internal one becomes the enforced policy). */ - 'retry_policy'?: (_envoy_api_v2_route_RetryPolicy__Output); - /** - * Indicates that the route has a request mirroring policy. - * - * .. attention:: - * This field has been deprecated in favor of `request_mirror_policies` which supports one or - * more mirroring policies. - */ - 'request_mirror_policy'?: (_envoy_api_v2_route_RouteAction_RequestMirrorPolicy__Output); + 'retry_policy'?: (_envoy_config_route_v3_RetryPolicy__Output); /** * Optionally specifies the :ref:`routing priority `. */ - 'priority': (keyof typeof _envoy_api_v2_core_RoutingPriority); + 'priority': (keyof typeof _envoy_config_core_v3_RoutingPriority); /** * Specifies a set of rate limit configurations that could be applied to the * route. */ - 'rate_limits': (_envoy_api_v2_route_RateLimit__Output)[]; + 'rate_limits': (_envoy_config_route_v3_RateLimit__Output)[]; /** * Specifies if the rate limit filter should include the virtual host rate * limits. By default, if the route configured rate limits, the virtual host - * :ref:`rate_limits ` are not applied to the + * :ref:`rate_limits ` are not applied to the * request. + * + * This field is deprecated. Please use :ref:`vh_rate_limits ` */ 'include_vh_rate_limits'?: (_google_protobuf_BoolValue__Output); /** @@ -857,25 +973,26 @@ export interface RouteAction__Output { * there is already a hash generated, the hash is returned immediately, * ignoring the rest of the hash policy list. */ - 'hash_policy': (_envoy_api_v2_route_RouteAction_HashPolicy__Output)[]; + 'hash_policy': (_envoy_config_route_v3_RouteAction_HashPolicy__Output)[]; /** * Indicates that the route has a CORS policy. */ - 'cors'?: (_envoy_api_v2_route_CorsPolicy__Output); + 'cors'?: (_envoy_config_route_v3_CorsPolicy__Output); /** * 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_api_v2_route_RouteAction_ClusterNotFoundResponseCode); + 'cluster_not_found_response_code': (keyof typeof _envoy_config_route_v3_RouteAction_ClusterNotFoundResponseCode); /** + * Deprecated by :ref:`grpc_timeout_header_max ` * If present, and the request is a gRPC request, use the * `grpc-timeout header `_, * or its default value (infinity) instead of - * :ref:`timeout `, but limit the applied timeout + * :ref:`timeout `, but limit the applied timeout * to the maximum value specified here. If configured as 0, the maximum allowed timeout for * gRPC requests is infinity. If not configured at all, the `grpc-timeout` header is not used * and gRPC requests time out like any other requests using - * :ref:`timeout ` or its default. + * :ref:`timeout ` or its default. * This can be used to prevent unexpected upstream request timeouts due to potentially long * time gaps between gRPC request and response in gRPC streaming mode. * @@ -892,14 +1009,14 @@ export interface RouteAction__Output { /** * Specifies the idle timeout for the route. If not specified, there is no per-route idle timeout, * although the connection manager wide :ref:`stream_idle_timeout - * ` + * ` * will still apply. A value of 0 will completely disable the route's idle timeout, even if a * connection manager stream idle timeout is configured. * * The idle timeout is distinct to :ref:`timeout - * `, which provides an upper bound + * `, which provides an upper bound * on the upstream response time; :ref:`idle_timeout - * ` instead bounds the amount + * ` instead bounds the amount * of time the request's stream may be idle. * * After header decoding, the idle timeout will apply on downstream and @@ -908,17 +1025,22 @@ export interface RouteAction__Output { * fires, the stream is terminated with a 408 Request Timeout error code if no * upstream response header has been received, otherwise a stream reset * occurs. + * + * If the :ref:`overload action ` "envoy.overload_actions.reduce_timeouts" + * is configured, this timeout is scaled according to the value for + * :ref:`HTTP_DOWNSTREAM_STREAM_IDLE `. */ 'idle_timeout'?: (_google_protobuf_Duration__Output); - 'upgrade_configs': (_envoy_api_v2_route_RouteAction_UpgradeConfig__Output)[]; - 'internal_redirect_action': (keyof typeof _envoy_api_v2_route_RouteAction_InternalRedirectAction); + 'upgrade_configs': (_envoy_config_route_v3_RouteAction_UpgradeConfig__Output)[]; + 'internal_redirect_action': (keyof typeof _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 * (e.g.: policies are not merged, most internal one becomes the enforced policy). */ - 'hedge_policy'?: (_envoy_api_v2_route_HedgePolicy__Output); + 'hedge_policy'?: (_envoy_config_route_v3_HedgePolicy__Output); /** + * Deprecated by :ref:`grpc_timeout_header_offset `. * If present, Envoy will adjust the timeout provided by the `grpc-timeout` header by subtracting * the provided duration from the header. This is useful in allowing Envoy to set its global * timeout to be less than that of the deadline imposed by the calling client, which makes it more @@ -937,24 +1059,28 @@ export interface RouteAction__Output { * * Pay attention to the potential security implications of using this option. Provided header * must come from trusted source. + * + * .. note:: + * + * If the header appears multiple times only the first value is used. */ - 'auto_host_rewrite_header'?: (string); + 'host_rewrite_header'?: (string); /** * Indicates that the route has request mirroring policies. */ - 'request_mirror_policies': (_envoy_api_v2_route_RouteAction_RequestMirrorPolicy__Output)[]; + 'request_mirror_policies': (_envoy_config_route_v3_RouteAction_RequestMirrorPolicy__Output)[]; /** * An internal redirect is handled, iff the number of previous internal redirects that a * downstream request has encountered is lower than this value, and - * :ref:`internal_redirect_action ` + * :ref:`internal_redirect_action ` * is set to :ref:`HANDLE_INTERNAL_REDIRECT - * ` + * ` * In the case where a downstream request is bounced among multiple routes by internal redirect, * the first route that hits this threshold, or has - * :ref:`internal_redirect_action ` + * :ref:`internal_redirect_action ` * set to * :ref:`PASS_THROUGH_INTERNAL_REDIRECT - * ` + * ` * will pass the redirect back to downstream. * * If not specified, at most one redirect will be followed. @@ -970,7 +1096,7 @@ export interface RouteAction__Output { * before the rewrite into the :ref:`x-envoy-original-path * ` header. * - * Only one of :ref:`prefix_rewrite ` + * Only one of :ref:`prefix_rewrite ` * or *regex_rewrite* may be specified. * * Examples using Google's `RE2 `_ engine: @@ -990,15 +1116,44 @@ export interface RouteAction__Output { * would do a case-insensitive match and transform path ``/aaa/XxX/bbb`` to * ``/aaa/yyy/bbb``. */ - 'regex_rewrite'?: (_envoy_type_matcher_RegexMatchAndSubstitute__Output); + 'regex_rewrite'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute__Output); /** * [#not-implemented-hide:] * Specifies the configuration for retry policy extension. Note that if this is set, it'll take * precedence over the virtual host level retry policy entirely (e.g.: policies are not merged, - * most internal one becomes the enforced policy). :ref:`Retry policy ` + * most internal one becomes the enforced policy). :ref:`Retry policy ` * should not be set if this field is used. */ 'retry_policy_typed_config'?: (_google_protobuf_Any__Output); + /** + * If present, Envoy will try to follow an upstream redirect response instead of proxying the + * response back to the downstream. An upstream redirect response is defined + * by :ref:`redirect_response_codes + * `. + */ + 'internal_redirect_policy'?: (_envoy_config_route_v3_InternalRedirectPolicy__Output); + /** + * Indicates that during forwarding, the host header will be swapped with + * the result of the regex substitution executed on path value with query and fragment removed. + * This is useful for transitioning variable content between path segment and subdomain. + * + * For example with the following config: + * + * .. code-block:: yaml + * + * host_rewrite_path_regex: + * pattern: + * google_re2: {} + * regex: "^/(.+)/.+$" + * substitution: \1 + * + * Would rewrite the host header to `envoyproxy.io` given the path `/envoyproxy.io/some/path`. + */ + 'host_rewrite_path_regex'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute__Output); + /** + * Specifies the maximum stream duration for this route. + */ + 'max_stream_duration'?: (_envoy_config_route_v3_RouteAction_MaxStreamDuration__Output); 'cluster_specifier': "cluster"|"cluster_header"|"weighted_clusters"; - 'host_rewrite_specifier': "host_rewrite"|"auto_host_rewrite"|"auto_host_rewrite_header"; + 'host_rewrite_specifier': "host_rewrite_literal"|"auto_host_rewrite"|"host_rewrite_header"|"host_rewrite_path_regex"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/RouteConfiguration.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteConfiguration.ts similarity index 63% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/RouteConfiguration.ts rename to packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteConfiguration.ts index de0634c24..e9ad30257 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/RouteConfiguration.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteConfiguration.ts @@ -1,25 +1,26 @@ -// Original file: deps/envoy-api/envoy/api/v2/route.proto +// Original file: deps/envoy-api/envoy/config/route/v3/route.proto -import type { VirtualHost as _envoy_api_v2_route_VirtualHost, VirtualHost__Output as _envoy_api_v2_route_VirtualHost__Output } from '../../../envoy/api/v2/route/VirtualHost'; -import type { HeaderValueOption as _envoy_api_v2_core_HeaderValueOption, HeaderValueOption__Output as _envoy_api_v2_core_HeaderValueOption__Output } from '../../../envoy/api/v2/core/HeaderValueOption'; -import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../google/protobuf/BoolValue'; -import type { Vhds as _envoy_api_v2_Vhds, Vhds__Output as _envoy_api_v2_Vhds__Output } from '../../../envoy/api/v2/Vhds'; +import type { VirtualHost as _envoy_config_route_v3_VirtualHost, VirtualHost__Output as _envoy_config_route_v3_VirtualHost__Output } from '../../../../envoy/config/route/v3/VirtualHost'; +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 { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; +import type { Vhds as _envoy_config_route_v3_Vhds, Vhds__Output as _envoy_config_route_v3_Vhds__Output } from '../../../../envoy/config/route/v3/Vhds'; +import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; /** - * [#next-free-field: 11] + * [#next-free-field: 12] */ export interface RouteConfiguration { /** * The name of the route configuration. For example, it might match * :ref:`route_config_name - * ` in - * :ref:`envoy_api_msg_config.filter.network.http_connection_manager.v2.Rds`. + * ` in + * :ref:`envoy_api_msg_extensions.filters.network.http_connection_manager.v3.Rds`. */ 'name'?: (string); /** * An array of virtual hosts that make up the route table. */ - 'virtual_hosts'?: (_envoy_api_v2_route_VirtualHost)[]; + 'virtual_hosts'?: (_envoy_config_route_v3_VirtualHost)[]; /** * Optionally specifies a list of HTTP headers that the connection manager * will consider to be internal only. If they are found on external requests they will be cleaned @@ -30,12 +31,12 @@ export interface RouteConfiguration { /** * Specifies a list of HTTP headers that should be added to each response that * the connection manager encodes. Headers specified at this level are applied - * after headers from any enclosed :ref:`envoy_api_msg_route.VirtualHost` or - * :ref:`envoy_api_msg_route.RouteAction`. For more information, including details on + * after headers from any enclosed :ref:`envoy_api_msg_config.route.v3.VirtualHost` or + * :ref:`envoy_api_msg_config.route.v3.RouteAction`. For more information, including details on * header value syntax, see the documentation on :ref:`custom request headers * `. */ - 'response_headers_to_add'?: (_envoy_api_v2_core_HeaderValueOption)[]; + 'response_headers_to_add'?: (_envoy_config_core_v3_HeaderValueOption)[]; /** * Specifies a list of HTTP headers that should be removed from each response * that the connection manager encodes. @@ -44,12 +45,12 @@ export interface RouteConfiguration { /** * Specifies a list of HTTP headers that should be added to each request * routed by the HTTP connection manager. Headers specified at this level are - * applied after headers from any enclosed :ref:`envoy_api_msg_route.VirtualHost` or - * :ref:`envoy_api_msg_route.RouteAction`. For more information, including details on + * applied after headers from any enclosed :ref:`envoy_api_msg_config.route.v3.VirtualHost` or + * :ref:`envoy_api_msg_config.route.v3.RouteAction`. For more information, including details on * header value syntax, see the documentation on :ref:`custom request headers * `. */ - 'request_headers_to_add'?: (_envoy_api_v2_core_HeaderValueOption)[]; + 'request_headers_to_add'?: (_envoy_config_core_v3_HeaderValueOption)[]; /** * An optional boolean that specifies whether the clusters that the route * table refers to will be validated by the cluster manager. If set to true @@ -58,10 +59,10 @@ export interface RouteConfiguration { * route table will load and the router filter will return a 404 if the route * is selected at runtime. This setting defaults to true if the route table * is statically defined via the :ref:`route_config - * ` + * ` * option. This setting default to false if the route table is loaded dynamically via the * :ref:`rds - * ` + * ` * option. Users may wish to override the default behavior in certain cases (for example when * using CDS with a static route table). */ @@ -79,7 +80,7 @@ export interface RouteConfiguration { * generate a routing table for a given RouteConfiguration, with *vhds* derived configuration * taking precedence. */ - 'vhds'?: (_envoy_api_v2_Vhds); + 'vhds'?: (_envoy_config_route_v3_Vhds); /** * By default, headers that should be added/removed are evaluated from most to least specific: * @@ -93,23 +94,36 @@ export interface RouteConfiguration { * [#next-major-version: In the v3 API, this will default to true.] */ 'most_specific_header_mutations_wins'?: (boolean); + /** + * The maximum bytes of the response :ref:`direct response body + * ` size. If not specified the default + * is 4096. + * + * .. warning:: + * + * Envoy currently holds the content of :ref:`direct response body + * ` in memory. Be careful setting + * this to be larger than the default 4KB, since the allocated memory for direct response body + * is not subject to data plane buffering controls. + */ + 'max_direct_response_body_size_bytes'?: (_google_protobuf_UInt32Value); } /** - * [#next-free-field: 11] + * [#next-free-field: 12] */ export interface RouteConfiguration__Output { /** * The name of the route configuration. For example, it might match * :ref:`route_config_name - * ` in - * :ref:`envoy_api_msg_config.filter.network.http_connection_manager.v2.Rds`. + * ` in + * :ref:`envoy_api_msg_extensions.filters.network.http_connection_manager.v3.Rds`. */ 'name': (string); /** * An array of virtual hosts that make up the route table. */ - 'virtual_hosts': (_envoy_api_v2_route_VirtualHost__Output)[]; + 'virtual_hosts': (_envoy_config_route_v3_VirtualHost__Output)[]; /** * Optionally specifies a list of HTTP headers that the connection manager * will consider to be internal only. If they are found on external requests they will be cleaned @@ -120,12 +134,12 @@ export interface RouteConfiguration__Output { /** * Specifies a list of HTTP headers that should be added to each response that * the connection manager encodes. Headers specified at this level are applied - * after headers from any enclosed :ref:`envoy_api_msg_route.VirtualHost` or - * :ref:`envoy_api_msg_route.RouteAction`. For more information, including details on + * after headers from any enclosed :ref:`envoy_api_msg_config.route.v3.VirtualHost` or + * :ref:`envoy_api_msg_config.route.v3.RouteAction`. For more information, including details on * header value syntax, see the documentation on :ref:`custom request headers * `. */ - 'response_headers_to_add': (_envoy_api_v2_core_HeaderValueOption__Output)[]; + 'response_headers_to_add': (_envoy_config_core_v3_HeaderValueOption__Output)[]; /** * Specifies a list of HTTP headers that should be removed from each response * that the connection manager encodes. @@ -134,12 +148,12 @@ export interface RouteConfiguration__Output { /** * Specifies a list of HTTP headers that should be added to each request * routed by the HTTP connection manager. Headers specified at this level are - * applied after headers from any enclosed :ref:`envoy_api_msg_route.VirtualHost` or - * :ref:`envoy_api_msg_route.RouteAction`. For more information, including details on + * applied after headers from any enclosed :ref:`envoy_api_msg_config.route.v3.VirtualHost` or + * :ref:`envoy_api_msg_config.route.v3.RouteAction`. For more information, including details on * header value syntax, see the documentation on :ref:`custom request headers * `. */ - 'request_headers_to_add': (_envoy_api_v2_core_HeaderValueOption__Output)[]; + 'request_headers_to_add': (_envoy_config_core_v3_HeaderValueOption__Output)[]; /** * An optional boolean that specifies whether the clusters that the route * table refers to will be validated by the cluster manager. If set to true @@ -148,10 +162,10 @@ export interface RouteConfiguration__Output { * route table will load and the router filter will return a 404 if the route * is selected at runtime. This setting defaults to true if the route table * is statically defined via the :ref:`route_config - * ` + * ` * option. This setting default to false if the route table is loaded dynamically via the * :ref:`rds - * ` + * ` * option. Users may wish to override the default behavior in certain cases (for example when * using CDS with a static route table). */ @@ -169,7 +183,7 @@ export interface RouteConfiguration__Output { * generate a routing table for a given RouteConfiguration, with *vhds* derived configuration * taking precedence. */ - 'vhds'?: (_envoy_api_v2_Vhds__Output); + 'vhds'?: (_envoy_config_route_v3_Vhds__Output); /** * By default, headers that should be added/removed are evaluated from most to least specific: * @@ -183,4 +197,17 @@ export interface RouteConfiguration__Output { * [#next-major-version: In the v3 API, this will default to true.] */ 'most_specific_header_mutations_wins': (boolean); + /** + * The maximum bytes of the response :ref:`direct response body + * ` size. If not specified the default + * is 4096. + * + * .. warning:: + * + * Envoy currently holds the content of :ref:`direct response body + * ` in memory. Be careful setting + * this to be larger than the default 4KB, since the allocated memory for direct response body + * is not subject to data plane buffering controls. + */ + 'max_direct_response_body_size_bytes'?: (_google_protobuf_UInt32Value__Output); } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/RouteMatch.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteMatch.ts similarity index 67% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/route/RouteMatch.ts rename to packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteMatch.ts index b055c0506..d941bcfd1 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/RouteMatch.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteMatch.ts @@ -1,18 +1,30 @@ -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; -import type { HeaderMatcher as _envoy_api_v2_route_HeaderMatcher, HeaderMatcher__Output as _envoy_api_v2_route_HeaderMatcher__Output } from '../../../../envoy/api/v2/route/HeaderMatcher'; -import type { QueryParameterMatcher as _envoy_api_v2_route_QueryParameterMatcher, QueryParameterMatcher__Output as _envoy_api_v2_route_QueryParameterMatcher__Output } from '../../../../envoy/api/v2/route/QueryParameterMatcher'; -import type { RuntimeFractionalPercent as _envoy_api_v2_core_RuntimeFractionalPercent, RuntimeFractionalPercent__Output as _envoy_api_v2_core_RuntimeFractionalPercent__Output } from '../../../../envoy/api/v2/core/RuntimeFractionalPercent'; -import type { RegexMatcher as _envoy_type_matcher_RegexMatcher, RegexMatcher__Output as _envoy_type_matcher_RegexMatcher__Output } from '../../../../envoy/type/matcher/RegexMatcher'; +import type { HeaderMatcher as _envoy_config_route_v3_HeaderMatcher, HeaderMatcher__Output as _envoy_config_route_v3_HeaderMatcher__Output } from '../../../../envoy/config/route/v3/HeaderMatcher'; +import type { QueryParameterMatcher as _envoy_config_route_v3_QueryParameterMatcher, QueryParameterMatcher__Output as _envoy_config_route_v3_QueryParameterMatcher__Output } from '../../../../envoy/config/route/v3/QueryParameterMatcher'; +import type { RuntimeFractionalPercent as _envoy_config_core_v3_RuntimeFractionalPercent, RuntimeFractionalPercent__Output as _envoy_config_core_v3_RuntimeFractionalPercent__Output } from '../../../../envoy/config/core/v3/RuntimeFractionalPercent'; +import type { RegexMatcher as _envoy_type_matcher_v3_RegexMatcher, RegexMatcher__Output as _envoy_type_matcher_v3_RegexMatcher__Output } from '../../../../envoy/type/matcher/v3/RegexMatcher'; -export interface _envoy_api_v2_route_RouteMatch_GrpcRouteMatchOptions { +/** + * An extensible message for matching CONNECT requests. + */ +export interface _envoy_config_route_v3_RouteMatch_ConnectMatcher { +} + +/** + * An extensible message for matching CONNECT requests. + */ +export interface _envoy_config_route_v3_RouteMatch_ConnectMatcher__Output { +} + +export interface _envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions { } -export interface _envoy_api_v2_route_RouteMatch_GrpcRouteMatchOptions__Output { +export interface _envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions__Output { } -export interface _envoy_api_v2_route_RouteMatch_TlsContextMatchOptions { +export interface _envoy_config_route_v3_RouteMatch_TlsContextMatchOptions { /** * If specified, the route will match against whether or not a certificate is presented. * If not specified, certificate presentation status (true or false) will not be considered when route matching. @@ -25,7 +37,7 @@ export interface _envoy_api_v2_route_RouteMatch_TlsContextMatchOptions { 'validated'?: (_google_protobuf_BoolValue); } -export interface _envoy_api_v2_route_RouteMatch_TlsContextMatchOptions__Output { +export interface _envoy_config_route_v3_RouteMatch_TlsContextMatchOptions__Output { /** * If specified, the route will match against whether or not a certificate is presented. * If not specified, certificate presentation status (true or false) will not be considered when route matching. @@ -39,7 +51,7 @@ export interface _envoy_api_v2_route_RouteMatch_TlsContextMatchOptions__Output { } /** - * [#next-free-field: 12] + * [#next-free-field: 13] */ export interface RouteMatch { /** @@ -53,26 +65,7 @@ export interface RouteMatch { */ 'path'?: (string); /** - * If specified, the route is a regular expression rule meaning that the - * regex must match the *:path* header once the query string is removed. The entire path - * (without the query string) must match the regex. The rule will not match if only a - * subsequence of the *:path* header matches the regex. The regex grammar is defined `here - * `_. - * - * Examples: - * - * * The regex ``/b[io]t`` matches the path * /bit* - * * The regex ``/b[io]t`` matches the path * /bot* - * * The regex ``/b[io]t`` does not match the path * /bite* - * * The regex ``/b[io]t`` does not match the path * /bit/bot* - * - * .. attention:: - * This field has been deprecated in favor of `safe_regex` as it is not safe for use with - * untrusted input in all cases. - */ - 'regex'?: (string); - /** - * Indicates that prefix/path matching should be case insensitive. The default + * Indicates that prefix/path matching should be case sensitive. The default * is true. */ 'case_sensitive'?: (_google_protobuf_BoolValue); @@ -83,7 +76,7 @@ export interface RouteMatch { * the request with the same values (or based on presence if the value field * is not in the config). */ - 'headers'?: (_envoy_api_v2_route_HeaderMatcher)[]; + 'headers'?: (_envoy_config_route_v3_HeaderMatcher)[]; /** * Specifies a set of URL query parameters on which the route should * match. The router will check the query string from the *path* header @@ -91,13 +84,13 @@ export interface RouteMatch { * query parameters is nonzero, they all must match the *path* header's * query string for a match to occur. */ - 'query_parameters'?: (_envoy_api_v2_route_QueryParameterMatcher)[]; + 'query_parameters'?: (_envoy_config_route_v3_QueryParameterMatcher)[]; /** * If specified, only gRPC requests will be matched. The router will check * that the content-type header has a application/grpc or one of the various * application/grpc+ values. */ - 'grpc'?: (_envoy_api_v2_route_RouteMatch_GrpcRouteMatchOptions); + 'grpc'?: (_envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions); /** * Indicates that the route should additionally match on a runtime key. Every time the route * is considered for a match, it must also fall under the percentage of matches indicated by @@ -116,7 +109,7 @@ export interface RouteMatch { * instance, a runtime key lookup returning the value "42" would parse as a FractionalPercent * whose numerator is 42 and denominator is HUNDRED. This preserves legacy semantics. */ - 'runtime_fraction'?: (_envoy_api_v2_core_RuntimeFractionalPercent); + 'runtime_fraction'?: (_envoy_config_core_v3_RuntimeFractionalPercent); /** * If specified, the route is a regular expression rule meaning that the * regex must match the *:path* header once the query string is removed. The entire path @@ -131,19 +124,31 @@ export interface RouteMatch { * on :path, etc. The issue with that is it is unclear how to generically deal with query string * stripping. This needs more thought.] */ - 'safe_regex'?: (_envoy_type_matcher_RegexMatcher); + 'safe_regex'?: (_envoy_type_matcher_v3_RegexMatcher); /** * If specified, the client tls context will be matched against the defined * match options. * * [#next-major-version: unify with RBAC] */ - 'tls_context'?: (_envoy_api_v2_route_RouteMatch_TlsContextMatchOptions); - 'path_specifier'?: "prefix"|"path"|"regex"|"safe_regex"; + 'tls_context'?: (_envoy_config_route_v3_RouteMatch_TlsContextMatchOptions); + /** + * If this is used as the matcher, the matcher will only match CONNECT requests. + * Note that this will not match HTTP/2 upgrade-style CONNECT requests + * (WebSocket and the like) as they are normalized in Envoy as HTTP/1.1 style + * upgrades. + * This is the only way to match CONNECT requests for HTTP/1.1. For HTTP/2, + * where Extended CONNECT requests may have a path, the path matchers will work if + * there is a path present. + * Note that CONNECT support is currently considered alpha in Envoy. + * [#comment:TODO(htuch): Replace the above comment with an alpha tag. + */ + 'connect_matcher'?: (_envoy_config_route_v3_RouteMatch_ConnectMatcher); + 'path_specifier'?: "prefix"|"path"|"safe_regex"|"connect_matcher"; } /** - * [#next-free-field: 12] + * [#next-free-field: 13] */ export interface RouteMatch__Output { /** @@ -157,26 +162,7 @@ export interface RouteMatch__Output { */ 'path'?: (string); /** - * If specified, the route is a regular expression rule meaning that the - * regex must match the *:path* header once the query string is removed. The entire path - * (without the query string) must match the regex. The rule will not match if only a - * subsequence of the *:path* header matches the regex. The regex grammar is defined `here - * `_. - * - * Examples: - * - * * The regex ``/b[io]t`` matches the path * /bit* - * * The regex ``/b[io]t`` matches the path * /bot* - * * The regex ``/b[io]t`` does not match the path * /bite* - * * The regex ``/b[io]t`` does not match the path * /bit/bot* - * - * .. attention:: - * This field has been deprecated in favor of `safe_regex` as it is not safe for use with - * untrusted input in all cases. - */ - 'regex'?: (string); - /** - * Indicates that prefix/path matching should be case insensitive. The default + * Indicates that prefix/path matching should be case sensitive. The default * is true. */ 'case_sensitive'?: (_google_protobuf_BoolValue__Output); @@ -187,7 +173,7 @@ export interface RouteMatch__Output { * the request with the same values (or based on presence if the value field * is not in the config). */ - 'headers': (_envoy_api_v2_route_HeaderMatcher__Output)[]; + 'headers': (_envoy_config_route_v3_HeaderMatcher__Output)[]; /** * Specifies a set of URL query parameters on which the route should * match. The router will check the query string from the *path* header @@ -195,13 +181,13 @@ export interface RouteMatch__Output { * query parameters is nonzero, they all must match the *path* header's * query string for a match to occur. */ - 'query_parameters': (_envoy_api_v2_route_QueryParameterMatcher__Output)[]; + 'query_parameters': (_envoy_config_route_v3_QueryParameterMatcher__Output)[]; /** * If specified, only gRPC requests will be matched. The router will check * that the content-type header has a application/grpc or one of the various * application/grpc+ values. */ - 'grpc'?: (_envoy_api_v2_route_RouteMatch_GrpcRouteMatchOptions__Output); + 'grpc'?: (_envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions__Output); /** * Indicates that the route should additionally match on a runtime key. Every time the route * is considered for a match, it must also fall under the percentage of matches indicated by @@ -220,7 +206,7 @@ export interface RouteMatch__Output { * instance, a runtime key lookup returning the value "42" would parse as a FractionalPercent * whose numerator is 42 and denominator is HUNDRED. This preserves legacy semantics. */ - 'runtime_fraction'?: (_envoy_api_v2_core_RuntimeFractionalPercent__Output); + 'runtime_fraction'?: (_envoy_config_core_v3_RuntimeFractionalPercent__Output); /** * If specified, the route is a regular expression rule meaning that the * regex must match the *:path* header once the query string is removed. The entire path @@ -235,13 +221,25 @@ export interface RouteMatch__Output { * on :path, etc. The issue with that is it is unclear how to generically deal with query string * stripping. This needs more thought.] */ - 'safe_regex'?: (_envoy_type_matcher_RegexMatcher__Output); + 'safe_regex'?: (_envoy_type_matcher_v3_RegexMatcher__Output); /** * If specified, the client tls context will be matched against the defined * match options. * * [#next-major-version: unify with RBAC] */ - 'tls_context'?: (_envoy_api_v2_route_RouteMatch_TlsContextMatchOptions__Output); - 'path_specifier': "prefix"|"path"|"regex"|"safe_regex"; + 'tls_context'?: (_envoy_config_route_v3_RouteMatch_TlsContextMatchOptions__Output); + /** + * If this is used as the matcher, the matcher will only match CONNECT requests. + * Note that this will not match HTTP/2 upgrade-style CONNECT requests + * (WebSocket and the like) as they are normalized in Envoy as HTTP/1.1 style + * upgrades. + * This is the only way to match CONNECT requests for HTTP/1.1. For HTTP/2, + * where Extended CONNECT requests may have a path, the path matchers will work if + * there is a path present. + * Note that CONNECT support is currently considered alpha in Envoy. + * [#comment:TODO(htuch): Replace the above comment with an alpha tag. + */ + 'connect_matcher'?: (_envoy_config_route_v3_RouteMatch_ConnectMatcher__Output); + 'path_specifier': "prefix"|"path"|"safe_regex"|"connect_matcher"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/ScopedRouteConfiguration.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/ScopedRouteConfiguration.ts similarity index 59% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/ScopedRouteConfiguration.ts rename to packages/grpc-js-xds/src/generated/envoy/config/route/v3/ScopedRouteConfiguration.ts index 02810bf02..afbb9886b 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/ScopedRouteConfiguration.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/ScopedRouteConfiguration.ts @@ -1,7 +1,7 @@ -// Original file: deps/envoy-api/envoy/api/v2/scoped_route.proto +// Original file: deps/envoy-api/envoy/config/route/v3/scoped_route.proto -export interface _envoy_api_v2_ScopedRouteConfiguration_Key_Fragment { +export interface _envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment { /** * A string to match against. */ @@ -9,7 +9,7 @@ export interface _envoy_api_v2_ScopedRouteConfiguration_Key_Fragment { 'type'?: "string_key"; } -export interface _envoy_api_v2_ScopedRouteConfiguration_Key_Fragment__Output { +export interface _envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment__Output { /** * A string to match against. */ @@ -19,45 +19,45 @@ export interface _envoy_api_v2_ScopedRouteConfiguration_Key_Fragment__Output { /** * Specifies a key which is matched against the output of the - * :ref:`scope_key_builder` + * :ref:`scope_key_builder` * specified in the HttpConnectionManager. The matching is done per HTTP * request and is dependent on the order of the fragments contained in the * Key. */ -export interface _envoy_api_v2_ScopedRouteConfiguration_Key { +export interface _envoy_config_route_v3_ScopedRouteConfiguration_Key { /** * The ordered set of fragments to match against. The order must match the * fragments in the corresponding - * :ref:`scope_key_builder`. + * :ref:`scope_key_builder`. */ - 'fragments'?: (_envoy_api_v2_ScopedRouteConfiguration_Key_Fragment)[]; + 'fragments'?: (_envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment)[]; } /** * Specifies a key which is matched against the output of the - * :ref:`scope_key_builder` + * :ref:`scope_key_builder` * specified in the HttpConnectionManager. The matching is done per HTTP * request and is dependent on the order of the fragments contained in the * Key. */ -export interface _envoy_api_v2_ScopedRouteConfiguration_Key__Output { +export interface _envoy_config_route_v3_ScopedRouteConfiguration_Key__Output { /** * The ordered set of fragments to match against. The order must match the * fragments in the corresponding - * :ref:`scope_key_builder`. + * :ref:`scope_key_builder`. */ - 'fragments': (_envoy_api_v2_ScopedRouteConfiguration_Key_Fragment__Output)[]; + 'fragments': (_envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment__Output)[]; } /** * Specifies a routing scope, which associates a - * :ref:`Key` to a - * :ref:`envoy_api_msg_RouteConfiguration` (identified by its resource name). + * :ref:`Key` to a + * :ref:`envoy_api_msg_config.route.v3.RouteConfiguration` (identified by its resource name). * * The HTTP connection manager builds up a table consisting of these Key to * RouteConfiguration mappings, and looks up the RouteConfiguration to use per * request according to the algorithm specified in the - * :ref:`scope_key_builder` + * :ref:`scope_key_builder` * assigned to the HttpConnectionManager. * * For example, with the following configurations (in YAML): @@ -79,7 +79,7 @@ export interface _envoy_api_v2_ScopedRouteConfiguration_Key__Output { * key: vip * * ScopedRouteConfiguration resources (specified statically via - * :ref:`scoped_route_configurations_list` + * :ref:`scoped_route_configurations_list` * or obtained dynamically via SRDS): * * .. code:: @@ -115,26 +115,30 @@ export interface ScopedRouteConfiguration { */ 'name'?: (string); /** - * The resource name to use for a :ref:`envoy_api_msg_DiscoveryRequest` to an - * RDS server to fetch the :ref:`envoy_api_msg_RouteConfiguration` associated + * The resource name to use for a :ref:`envoy_api_msg_service.discovery.v3.DiscoveryRequest` to an + * RDS server to fetch the :ref:`envoy_api_msg_config.route.v3.RouteConfiguration` associated * with this scope. */ 'route_configuration_name'?: (string); /** * The key to match against. */ - 'key'?: (_envoy_api_v2_ScopedRouteConfiguration_Key); + 'key'?: (_envoy_config_route_v3_ScopedRouteConfiguration_Key); + /** + * Whether the RouteConfiguration should be loaded on demand. + */ + 'on_demand'?: (boolean); } /** * Specifies a routing scope, which associates a - * :ref:`Key` to a - * :ref:`envoy_api_msg_RouteConfiguration` (identified by its resource name). + * :ref:`Key` to a + * :ref:`envoy_api_msg_config.route.v3.RouteConfiguration` (identified by its resource name). * * The HTTP connection manager builds up a table consisting of these Key to * RouteConfiguration mappings, and looks up the RouteConfiguration to use per * request according to the algorithm specified in the - * :ref:`scope_key_builder` + * :ref:`scope_key_builder` * assigned to the HttpConnectionManager. * * For example, with the following configurations (in YAML): @@ -156,7 +160,7 @@ export interface ScopedRouteConfiguration { * key: vip * * ScopedRouteConfiguration resources (specified statically via - * :ref:`scoped_route_configurations_list` + * :ref:`scoped_route_configurations_list` * or obtained dynamically via SRDS): * * .. code:: @@ -192,13 +196,17 @@ export interface ScopedRouteConfiguration__Output { */ 'name': (string); /** - * The resource name to use for a :ref:`envoy_api_msg_DiscoveryRequest` to an - * RDS server to fetch the :ref:`envoy_api_msg_RouteConfiguration` associated + * The resource name to use for a :ref:`envoy_api_msg_service.discovery.v3.DiscoveryRequest` to an + * RDS server to fetch the :ref:`envoy_api_msg_config.route.v3.RouteConfiguration` associated * with this scope. */ 'route_configuration_name': (string); /** * The key to match against. */ - 'key'?: (_envoy_api_v2_ScopedRouteConfiguration_Key__Output); + 'key'?: (_envoy_config_route_v3_ScopedRouteConfiguration_Key__Output); + /** + * Whether the RouteConfiguration should be loaded on demand. + */ + 'on_demand': (boolean); } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/Tracing.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Tracing.ts similarity index 75% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/route/Tracing.ts rename to packages/grpc-js-xds/src/generated/envoy/config/route/v3/Tracing.ts index 18b063339..5be619a5f 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/Tracing.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Tracing.ts @@ -1,7 +1,7 @@ -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto -import type { FractionalPercent as _envoy_type_FractionalPercent, FractionalPercent__Output as _envoy_type_FractionalPercent__Output } from '../../../../envoy/type/FractionalPercent'; -import type { CustomTag as _envoy_type_tracing_v2_CustomTag, CustomTag__Output as _envoy_type_tracing_v2_CustomTag__Output } from '../../../../envoy/type/tracing/v2/CustomTag'; +import type { FractionalPercent as _envoy_type_v3_FractionalPercent, FractionalPercent__Output as _envoy_type_v3_FractionalPercent__Output } from '../../../../envoy/type/v3/FractionalPercent'; +import type { CustomTag as _envoy_type_tracing_v3_CustomTag, CustomTag__Output as _envoy_type_tracing_v3_CustomTag__Output } from '../../../../envoy/type/tracing/v3/CustomTag'; export interface Tracing { /** @@ -12,7 +12,7 @@ export interface Tracing { * `. * Default: 100% */ - 'client_sampling'?: (_envoy_type_FractionalPercent); + 'client_sampling'?: (_envoy_type_v3_FractionalPercent); /** * Target percentage of requests managed by this HTTP connection manager that will be randomly * selected for trace generation, if not requested by the client or not forced. This field is @@ -20,7 +20,7 @@ export interface Tracing { * :ref:`HTTP Connection Manager `. * Default: 100% */ - 'random_sampling'?: (_envoy_type_FractionalPercent); + 'random_sampling'?: (_envoy_type_v3_FractionalPercent); /** * Target percentage of requests managed by this HTTP connection manager that will be traced * after all other sampling checks have been applied (client-directed, force tracing, random @@ -31,16 +31,16 @@ export interface Tracing { * :ref:`HTTP Connection Manager `. * Default: 100% */ - 'overall_sampling'?: (_envoy_type_FractionalPercent); + 'overall_sampling'?: (_envoy_type_v3_FractionalPercent); /** * A list of custom tags with unique tag name to create tags for the active span. * It will take effect after merging with the :ref:`corresponding configuration - * ` + * ` * configured in the HTTP connection manager. If two tags with the same name are configured * each in the HTTP connection manager and the route level, the one configured here takes * priority. */ - 'custom_tags'?: (_envoy_type_tracing_v2_CustomTag)[]; + 'custom_tags'?: (_envoy_type_tracing_v3_CustomTag)[]; } export interface Tracing__Output { @@ -52,7 +52,7 @@ export interface Tracing__Output { * `. * Default: 100% */ - 'client_sampling'?: (_envoy_type_FractionalPercent__Output); + 'client_sampling'?: (_envoy_type_v3_FractionalPercent__Output); /** * Target percentage of requests managed by this HTTP connection manager that will be randomly * selected for trace generation, if not requested by the client or not forced. This field is @@ -60,7 +60,7 @@ export interface Tracing__Output { * :ref:`HTTP Connection Manager `. * Default: 100% */ - 'random_sampling'?: (_envoy_type_FractionalPercent__Output); + 'random_sampling'?: (_envoy_type_v3_FractionalPercent__Output); /** * Target percentage of requests managed by this HTTP connection manager that will be traced * after all other sampling checks have been applied (client-directed, force tracing, random @@ -71,14 +71,14 @@ export interface Tracing__Output { * :ref:`HTTP Connection Manager `. * Default: 100% */ - 'overall_sampling'?: (_envoy_type_FractionalPercent__Output); + 'overall_sampling'?: (_envoy_type_v3_FractionalPercent__Output); /** * A list of custom tags with unique tag name to create tags for the active span. * It will take effect after merging with the :ref:`corresponding configuration - * ` + * ` * configured in the HTTP connection manager. If two tags with the same name are configured * each in the HTTP connection manager and the route level, the one configured here takes * priority. */ - 'custom_tags': (_envoy_type_tracing_v2_CustomTag__Output)[]; + 'custom_tags': (_envoy_type_tracing_v3_CustomTag__Output)[]; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Vhds.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Vhds.ts new file mode 100644 index 000000000..2868685b2 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Vhds.ts @@ -0,0 +1,17 @@ +// Original file: deps/envoy-api/envoy/config/route/v3/route.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 Vhds { + /** + * Configuration source specifier for VHDS. + */ + 'config_source'?: (_envoy_config_core_v3_ConfigSource); +} + +export interface Vhds__Output { + /** + * Configuration source specifier for VHDS. + */ + 'config_source'?: (_envoy_config_core_v3_ConfigSource__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/VirtualCluster.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/VirtualCluster.ts similarity index 58% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/route/VirtualCluster.ts rename to packages/grpc-js-xds/src/generated/envoy/config/route/v3/VirtualCluster.ts index f072710ce..7674da733 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/VirtualCluster.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/VirtualCluster.ts @@ -1,7 +1,6 @@ -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto -import type { RequestMethod as _envoy_api_v2_core_RequestMethod } from '../../../../envoy/api/v2/core/RequestMethod'; -import type { HeaderMatcher as _envoy_api_v2_route_HeaderMatcher, HeaderMatcher__Output as _envoy_api_v2_route_HeaderMatcher__Output } from '../../../../envoy/api/v2/route/HeaderMatcher'; +import type { HeaderMatcher as _envoy_config_route_v3_HeaderMatcher, HeaderMatcher__Output as _envoy_config_route_v3_HeaderMatcher__Output } from '../../../../envoy/config/route/v3/HeaderMatcher'; /** * A virtual cluster is a way of specifying a regex matching rule against @@ -23,42 +22,18 @@ import type { HeaderMatcher as _envoy_api_v2_route_HeaderMatcher, HeaderMatcher_ * statistics output are not free. */ export interface VirtualCluster { - /** - * Specifies a regex pattern to use for matching requests. The entire path of the request - * must match the regex. The regex grammar used is defined `here - * `_. - * - * Examples: - * - * * The regex ``/rides/\d+`` matches the path * /rides/0* - * * The regex ``/rides/\d+`` matches the path * /rides/123* - * * The regex ``/rides/\d+`` does not match the path * /rides/123/456* - * - * .. attention:: - * This field has been deprecated in favor of `headers` as it is not safe for use with - * untrusted input in all cases. - */ - 'pattern'?: (string); /** * Specifies the name of the virtual cluster. The virtual cluster name as well * as the virtual host name are used when emitting statistics. The statistics are emitted by the * router filter and are documented :ref:`here `. */ 'name'?: (string); - /** - * Optionally specifies the HTTP method to match on. For example GET, PUT, - * etc. - * - * .. attention:: - * This field has been deprecated in favor of `headers`. - */ - 'method'?: (_envoy_api_v2_core_RequestMethod | keyof typeof _envoy_api_v2_core_RequestMethod); /** * Specifies a list of header matchers to use for matching requests. Each specified header must * match. The pseudo-headers `:path` and `:method` can be used to match the request path and * method, respectively. */ - 'headers'?: (_envoy_api_v2_route_HeaderMatcher)[]; + 'headers'?: (_envoy_config_route_v3_HeaderMatcher)[]; } /** @@ -81,40 +56,16 @@ export interface VirtualCluster { * statistics output are not free. */ export interface VirtualCluster__Output { - /** - * Specifies a regex pattern to use for matching requests. The entire path of the request - * must match the regex. The regex grammar used is defined `here - * `_. - * - * Examples: - * - * * The regex ``/rides/\d+`` matches the path * /rides/0* - * * The regex ``/rides/\d+`` matches the path * /rides/123* - * * The regex ``/rides/\d+`` does not match the path * /rides/123/456* - * - * .. attention:: - * This field has been deprecated in favor of `headers` as it is not safe for use with - * untrusted input in all cases. - */ - 'pattern': (string); /** * Specifies the name of the virtual cluster. The virtual cluster name as well * as the virtual host name are used when emitting statistics. The statistics are emitted by the * router filter and are documented :ref:`here `. */ 'name': (string); - /** - * Optionally specifies the HTTP method to match on. For example GET, PUT, - * etc. - * - * .. attention:: - * This field has been deprecated in favor of `headers`. - */ - 'method': (keyof typeof _envoy_api_v2_core_RequestMethod); /** * Specifies a list of header matchers to use for matching requests. Each specified header must * match. The pseudo-headers `:path` and `:method` can be used to match the request path and * method, respectively. */ - 'headers': (_envoy_api_v2_route_HeaderMatcher__Output)[]; + 'headers': (_envoy_config_route_v3_HeaderMatcher__Output)[]; } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/VirtualHost.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/VirtualHost.ts similarity index 71% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/route/VirtualHost.ts rename to packages/grpc-js-xds/src/generated/envoy/config/route/v3/VirtualHost.ts index ad806e949..86088ded6 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/VirtualHost.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/VirtualHost.ts @@ -1,19 +1,18 @@ -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto -import type { Route as _envoy_api_v2_route_Route, Route__Output as _envoy_api_v2_route_Route__Output } from '../../../../envoy/api/v2/route/Route'; -import type { VirtualCluster as _envoy_api_v2_route_VirtualCluster, VirtualCluster__Output as _envoy_api_v2_route_VirtualCluster__Output } from '../../../../envoy/api/v2/route/VirtualCluster'; -import type { RateLimit as _envoy_api_v2_route_RateLimit, RateLimit__Output as _envoy_api_v2_route_RateLimit__Output } from '../../../../envoy/api/v2/route/RateLimit'; -import type { HeaderValueOption as _envoy_api_v2_core_HeaderValueOption, HeaderValueOption__Output as _envoy_api_v2_core_HeaderValueOption__Output } from '../../../../envoy/api/v2/core/HeaderValueOption'; -import type { CorsPolicy as _envoy_api_v2_route_CorsPolicy, CorsPolicy__Output as _envoy_api_v2_route_CorsPolicy__Output } from '../../../../envoy/api/v2/route/CorsPolicy'; -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; +import type { Route as _envoy_config_route_v3_Route, Route__Output as _envoy_config_route_v3_Route__Output } from '../../../../envoy/config/route/v3/Route'; +import type { VirtualCluster as _envoy_config_route_v3_VirtualCluster, VirtualCluster__Output as _envoy_config_route_v3_VirtualCluster__Output } from '../../../../envoy/config/route/v3/VirtualCluster'; +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 { HeaderValueOption as _envoy_config_core_v3_HeaderValueOption, HeaderValueOption__Output as _envoy_config_core_v3_HeaderValueOption__Output } from '../../../../envoy/config/core/v3/HeaderValueOption'; +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 { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; -import type { RetryPolicy as _envoy_api_v2_route_RetryPolicy, RetryPolicy__Output as _envoy_api_v2_route_RetryPolicy__Output } from '../../../../envoy/api/v2/route/RetryPolicy'; -import type { HedgePolicy as _envoy_api_v2_route_HedgePolicy, HedgePolicy__Output as _envoy_api_v2_route_HedgePolicy__Output } from '../../../../envoy/api/v2/route/HedgePolicy'; +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 { HedgePolicy as _envoy_config_route_v3_HedgePolicy, HedgePolicy__Output as _envoy_config_route_v3_HedgePolicy__Output } from '../../../../envoy/config/route/v3/HedgePolicy'; import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto -export enum _envoy_api_v2_route_VirtualHost_TlsRequirementType { +export enum _envoy_config_route_v3_VirtualHost_TlsRequirementType { /** * No TLS requirement for the virtual host. */ @@ -69,57 +68,49 @@ export interface VirtualHost { * The list of routes that will be matched, in order, for incoming requests. * The first route that matches will be used. */ - 'routes'?: (_envoy_api_v2_route_Route)[]; + 'routes'?: (_envoy_config_route_v3_Route)[]; /** * 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_api_v2_route_VirtualHost_TlsRequirementType | keyof typeof _envoy_api_v2_route_VirtualHost_TlsRequirementType); + 'require_tls'?: (_envoy_config_route_v3_VirtualHost_TlsRequirementType | keyof typeof _envoy_config_route_v3_VirtualHost_TlsRequirementType); /** * A list of virtual clusters defined for this virtual host. Virtual clusters * are used for additional statistics gathering. */ - 'virtual_clusters'?: (_envoy_api_v2_route_VirtualCluster)[]; + 'virtual_clusters'?: (_envoy_config_route_v3_VirtualCluster)[]; /** * Specifies a set of rate limit configurations that will be applied to the * virtual host. */ - 'rate_limits'?: (_envoy_api_v2_route_RateLimit)[]; + 'rate_limits'?: (_envoy_config_route_v3_RateLimit)[]; /** * Specifies a list of HTTP headers that should be added to each request * handled by this virtual host. Headers specified at this level are applied - * after headers from enclosed :ref:`envoy_api_msg_route.Route` and before headers from the - * enclosing :ref:`envoy_api_msg_RouteConfiguration`. For more information, including + * after headers from enclosed :ref:`envoy_api_msg_config.route.v3.Route` and before headers from the + * enclosing :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including * details on header value syntax, see the documentation on :ref:`custom request headers * `. */ - 'request_headers_to_add'?: (_envoy_api_v2_core_HeaderValueOption)[]; + 'request_headers_to_add'?: (_envoy_config_core_v3_HeaderValueOption)[]; /** * Indicates that the virtual host has a CORS policy. */ - 'cors'?: (_envoy_api_v2_route_CorsPolicy); + 'cors'?: (_envoy_config_route_v3_CorsPolicy); /** * Specifies a list of HTTP headers that should be added to each response * handled by this virtual host. Headers specified at this level are applied - * after headers from enclosed :ref:`envoy_api_msg_route.Route` and before headers from the - * enclosing :ref:`envoy_api_msg_RouteConfiguration`. For more information, including + * after headers from enclosed :ref:`envoy_api_msg_config.route.v3.Route` and before headers from the + * enclosing :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including * details on header value syntax, see the documentation on :ref:`custom request headers * `. */ - 'response_headers_to_add'?: (_envoy_api_v2_core_HeaderValueOption)[]; + 'response_headers_to_add'?: (_envoy_config_core_v3_HeaderValueOption)[]; /** * Specifies a list of HTTP headers that should be removed from each response * handled by this virtual host. */ 'response_headers_to_remove'?: (string)[]; - /** - * The per_filter_config field can be used to provide virtual host-specific - * configurations for filters. The key should match the filter name, such as - * *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter - * specific; see the :ref:`HTTP filter documentation ` - * for if and how it is utilized. - */ - 'per_filter_config'?: ({[key: string]: _google_protobuf_Struct}); /** * Specifies a list of HTTP headers that should be removed from each request * handled by this virtual host. @@ -133,7 +124,7 @@ export interface VirtualHost { * will see the attempt count as perceived by the second Envoy. Defaults to false. * This header is unaffected by the * :ref:`suppress_envoy_headers - * ` flag. + * ` flag. * * [#next-major-version: rename to include_attempt_count_in_request.] */ @@ -144,6 +135,9 @@ export interface VirtualHost { * *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter * specific; see the :ref:`HTTP filter documentation ` * for if and how it is utilized. + * [#comment: An entry's value may be wrapped in a + * :ref:`FilterConfig` + * message to specify additional options.] */ 'typed_per_filter_config'?: ({[key: string]: _google_protobuf_Any}); /** @@ -151,13 +145,13 @@ export interface VirtualHost { * route level entry will take precedence over this config and it'll be treated * independently (e.g.: values are not inherited). */ - 'retry_policy'?: (_envoy_api_v2_route_RetryPolicy); + 'retry_policy'?: (_envoy_config_route_v3_RetryPolicy); /** * Indicates the hedge policy for all routes in this virtual host. Note that setting a * route level entry will take precedence over this config and it'll be treated * independently (e.g.: values are not inherited). */ - 'hedge_policy'?: (_envoy_api_v2_route_HedgePolicy); + 'hedge_policy'?: (_envoy_config_route_v3_HedgePolicy); /** * The maximum bytes which will be buffered for retries and shadowing. * If set and a route-specific limit is not set, the bytes actually buffered will be the minimum @@ -172,14 +166,14 @@ export interface VirtualHost { * will see the attempt count as perceived by the Envoy closest upstream from itself. Defaults to false. * This header is unaffected by the * :ref:`suppress_envoy_headers - * ` flag. + * ` flag. */ 'include_attempt_count_in_response'?: (boolean); /** * [#not-implemented-hide:] * Specifies the configuration for retry policy extension. Note that setting a route level entry * will take precedence over this config and it'll be treated independently (e.g.: values are not - * inherited). :ref:`Retry policy ` should not be + * inherited). :ref:`Retry policy ` should not be * set if this field is used. */ 'retry_policy_typed_config'?: (_google_protobuf_Any); @@ -224,57 +218,49 @@ export interface VirtualHost__Output { * The list of routes that will be matched, in order, for incoming requests. * The first route that matches will be used. */ - 'routes': (_envoy_api_v2_route_Route__Output)[]; + 'routes': (_envoy_config_route_v3_Route__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_api_v2_route_VirtualHost_TlsRequirementType); + 'require_tls': (keyof typeof _envoy_config_route_v3_VirtualHost_TlsRequirementType); /** * A list of virtual clusters defined for this virtual host. Virtual clusters * are used for additional statistics gathering. */ - 'virtual_clusters': (_envoy_api_v2_route_VirtualCluster__Output)[]; + 'virtual_clusters': (_envoy_config_route_v3_VirtualCluster__Output)[]; /** * Specifies a set of rate limit configurations that will be applied to the * virtual host. */ - 'rate_limits': (_envoy_api_v2_route_RateLimit__Output)[]; + 'rate_limits': (_envoy_config_route_v3_RateLimit__Output)[]; /** * Specifies a list of HTTP headers that should be added to each request * handled by this virtual host. Headers specified at this level are applied - * after headers from enclosed :ref:`envoy_api_msg_route.Route` and before headers from the - * enclosing :ref:`envoy_api_msg_RouteConfiguration`. For more information, including + * after headers from enclosed :ref:`envoy_api_msg_config.route.v3.Route` and before headers from the + * enclosing :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including * details on header value syntax, see the documentation on :ref:`custom request headers * `. */ - 'request_headers_to_add': (_envoy_api_v2_core_HeaderValueOption__Output)[]; + 'request_headers_to_add': (_envoy_config_core_v3_HeaderValueOption__Output)[]; /** * Indicates that the virtual host has a CORS policy. */ - 'cors'?: (_envoy_api_v2_route_CorsPolicy__Output); + 'cors'?: (_envoy_config_route_v3_CorsPolicy__Output); /** * Specifies a list of HTTP headers that should be added to each response * handled by this virtual host. Headers specified at this level are applied - * after headers from enclosed :ref:`envoy_api_msg_route.Route` and before headers from the - * enclosing :ref:`envoy_api_msg_RouteConfiguration`. For more information, including + * after headers from enclosed :ref:`envoy_api_msg_config.route.v3.Route` and before headers from the + * enclosing :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including * details on header value syntax, see the documentation on :ref:`custom request headers * `. */ - 'response_headers_to_add': (_envoy_api_v2_core_HeaderValueOption__Output)[]; + 'response_headers_to_add': (_envoy_config_core_v3_HeaderValueOption__Output)[]; /** * Specifies a list of HTTP headers that should be removed from each response * handled by this virtual host. */ 'response_headers_to_remove': (string)[]; - /** - * The per_filter_config field can be used to provide virtual host-specific - * configurations for filters. The key should match the filter name, such as - * *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter - * specific; see the :ref:`HTTP filter documentation ` - * for if and how it is utilized. - */ - 'per_filter_config'?: ({[key: string]: _google_protobuf_Struct__Output}); /** * Specifies a list of HTTP headers that should be removed from each request * handled by this virtual host. @@ -288,7 +274,7 @@ export interface VirtualHost__Output { * will see the attempt count as perceived by the second Envoy. Defaults to false. * This header is unaffected by the * :ref:`suppress_envoy_headers - * ` flag. + * ` flag. * * [#next-major-version: rename to include_attempt_count_in_request.] */ @@ -299,6 +285,9 @@ export interface VirtualHost__Output { * *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter * specific; see the :ref:`HTTP filter documentation ` * for if and how it is utilized. + * [#comment: An entry's value may be wrapped in a + * :ref:`FilterConfig` + * message to specify additional options.] */ 'typed_per_filter_config'?: ({[key: string]: _google_protobuf_Any__Output}); /** @@ -306,13 +295,13 @@ export interface VirtualHost__Output { * route level entry will take precedence over this config and it'll be treated * independently (e.g.: values are not inherited). */ - 'retry_policy'?: (_envoy_api_v2_route_RetryPolicy__Output); + 'retry_policy'?: (_envoy_config_route_v3_RetryPolicy__Output); /** * Indicates the hedge policy for all routes in this virtual host. Note that setting a * route level entry will take precedence over this config and it'll be treated * independently (e.g.: values are not inherited). */ - 'hedge_policy'?: (_envoy_api_v2_route_HedgePolicy__Output); + 'hedge_policy'?: (_envoy_config_route_v3_HedgePolicy__Output); /** * The maximum bytes which will be buffered for retries and shadowing. * If set and a route-specific limit is not set, the bytes actually buffered will be the minimum @@ -327,14 +316,14 @@ export interface VirtualHost__Output { * will see the attempt count as perceived by the Envoy closest upstream from itself. Defaults to false. * This header is unaffected by the * :ref:`suppress_envoy_headers - * ` flag. + * ` flag. */ 'include_attempt_count_in_response': (boolean); /** * [#not-implemented-hide:] * Specifies the configuration for retry policy extension. Note that setting a route level entry * will take precedence over this config and it'll be treated independently (e.g.: values are not - * inherited). :ref:`Retry policy ` should not be + * inherited). :ref:`Retry policy ` should not be * set if this field is used. */ 'retry_policy_typed_config'?: (_google_protobuf_Any__Output); diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/WeightedCluster.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/WeightedCluster.ts similarity index 64% rename from packages/grpc-js-xds/src/generated/envoy/api/v2/route/WeightedCluster.ts rename to packages/grpc-js-xds/src/generated/envoy/config/route/v3/WeightedCluster.ts index 5b283404b..7974508ea 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/route/WeightedCluster.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/WeightedCluster.ts @@ -1,15 +1,14 @@ -// Original file: deps/envoy-api/envoy/api/v2/route/route_components.proto +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; -import type { Metadata as _envoy_api_v2_core_Metadata, Metadata__Output as _envoy_api_v2_core_Metadata__Output } from '../../../../envoy/api/v2/core/Metadata'; -import type { HeaderValueOption as _envoy_api_v2_core_HeaderValueOption, HeaderValueOption__Output as _envoy_api_v2_core_HeaderValueOption__Output } from '../../../../envoy/api/v2/core/HeaderValueOption'; -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; +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 { HeaderValueOption as _envoy_config_core_v3_HeaderValueOption, HeaderValueOption__Output as _envoy_config_core_v3_HeaderValueOption__Output } from '../../../../envoy/config/core/v3/HeaderValueOption'; import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; /** * [#next-free-field: 11] */ -export interface _envoy_api_v2_route_WeightedCluster_ClusterWeight { +export interface _envoy_config_route_v3_WeightedCluster_ClusterWeight { /** * Name of the upstream cluster. The cluster must exist in the * :ref:`cluster manager configuration `. @@ -17,7 +16,7 @@ export interface _envoy_api_v2_route_WeightedCluster_ClusterWeight { 'name'?: (string); /** * An integer between 0 and :ref:`total_weight - * `. When a request matches the route, + * `. When a request matches the route, * the choice of an upstream cluster is determined by its weight. The sum of weights across all * entries in the clusters array must add up to the total_weight, which defaults to 100. */ @@ -26,38 +25,38 @@ export interface _envoy_api_v2_route_WeightedCluster_ClusterWeight { * Optional endpoint metadata match criteria used by the subset load balancer. Only endpoints in * the upstream cluster with metadata matching what is set in this field will be considered for * load balancing. Note that this will be merged with what's provided in - * :ref:`RouteAction.metadata_match `, with + * :ref:`RouteAction.metadata_match `, with * values here taking precedence. The filter name should be specified as *envoy.lb*. */ - 'metadata_match'?: (_envoy_api_v2_core_Metadata); + 'metadata_match'?: (_envoy_config_core_v3_Metadata); /** * Specifies a list of headers to be added to requests when this cluster is selected - * through the enclosing :ref:`envoy_api_msg_route.RouteAction`. + * through the enclosing :ref:`envoy_api_msg_config.route.v3.RouteAction`. * Headers specified at this level are applied before headers from the enclosing - * :ref:`envoy_api_msg_route.Route`, :ref:`envoy_api_msg_route.VirtualHost`, and - * :ref:`envoy_api_msg_RouteConfiguration`. For more information, including details on + * :ref:`envoy_api_msg_config.route.v3.Route`, :ref:`envoy_api_msg_config.route.v3.VirtualHost`, and + * :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including details on * header value syntax, see the documentation on :ref:`custom request headers * `. */ - 'request_headers_to_add'?: (_envoy_api_v2_core_HeaderValueOption)[]; + 'request_headers_to_add'?: (_envoy_config_core_v3_HeaderValueOption)[]; /** * Specifies a list of HTTP headers that should be removed from each request when - * this cluster is selected through the enclosing :ref:`envoy_api_msg_route.RouteAction`. + * this cluster is selected through the enclosing :ref:`envoy_api_msg_config.route.v3.RouteAction`. */ 'request_headers_to_remove'?: (string)[]; /** * Specifies a list of headers to be added to responses when this cluster is selected - * through the enclosing :ref:`envoy_api_msg_route.RouteAction`. + * through the enclosing :ref:`envoy_api_msg_config.route.v3.RouteAction`. * Headers specified at this level are applied before headers from the enclosing - * :ref:`envoy_api_msg_route.Route`, :ref:`envoy_api_msg_route.VirtualHost`, and - * :ref:`envoy_api_msg_RouteConfiguration`. For more information, including details on + * :ref:`envoy_api_msg_config.route.v3.Route`, :ref:`envoy_api_msg_config.route.v3.VirtualHost`, and + * :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including details on * header value syntax, see the documentation on :ref:`custom request headers * `. */ - 'response_headers_to_add'?: (_envoy_api_v2_core_HeaderValueOption)[]; + 'response_headers_to_add'?: (_envoy_config_core_v3_HeaderValueOption)[]; /** * Specifies a list of headers to be removed from responses when this cluster is selected - * through the enclosing :ref:`envoy_api_msg_route.RouteAction`. + * through the enclosing :ref:`envoy_api_msg_config.route.v3.RouteAction`. */ 'response_headers_to_remove'?: (string)[]; /** @@ -66,14 +65,9 @@ export interface _envoy_api_v2_route_WeightedCluster_ClusterWeight { * *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter * specific; see the :ref:`HTTP filter documentation ` * for if and how it is utilized. - */ - 'per_filter_config'?: ({[key: string]: _google_protobuf_Struct}); - /** - * The per_filter_config field can be used to provide weighted cluster-specific - * configurations for filters. The key should match the filter name, such as - * *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter - * specific; see the :ref:`HTTP filter documentation ` - * for if and how it is utilized. + * [#comment: An entry's value may be wrapped in a + * :ref:`FilterConfig` + * message to specify additional options.] */ 'typed_per_filter_config'?: ({[key: string]: _google_protobuf_Any}); } @@ -81,7 +75,7 @@ export interface _envoy_api_v2_route_WeightedCluster_ClusterWeight { /** * [#next-free-field: 11] */ -export interface _envoy_api_v2_route_WeightedCluster_ClusterWeight__Output { +export interface _envoy_config_route_v3_WeightedCluster_ClusterWeight__Output { /** * Name of the upstream cluster. The cluster must exist in the * :ref:`cluster manager configuration `. @@ -89,7 +83,7 @@ export interface _envoy_api_v2_route_WeightedCluster_ClusterWeight__Output { 'name': (string); /** * An integer between 0 and :ref:`total_weight - * `. When a request matches the route, + * `. When a request matches the route, * the choice of an upstream cluster is determined by its weight. The sum of weights across all * entries in the clusters array must add up to the total_weight, which defaults to 100. */ @@ -98,38 +92,38 @@ export interface _envoy_api_v2_route_WeightedCluster_ClusterWeight__Output { * Optional endpoint metadata match criteria used by the subset load balancer. Only endpoints in * the upstream cluster with metadata matching what is set in this field will be considered for * load balancing. Note that this will be merged with what's provided in - * :ref:`RouteAction.metadata_match `, with + * :ref:`RouteAction.metadata_match `, with * values here taking precedence. The filter name should be specified as *envoy.lb*. */ - 'metadata_match'?: (_envoy_api_v2_core_Metadata__Output); + 'metadata_match'?: (_envoy_config_core_v3_Metadata__Output); /** * Specifies a list of headers to be added to requests when this cluster is selected - * through the enclosing :ref:`envoy_api_msg_route.RouteAction`. + * through the enclosing :ref:`envoy_api_msg_config.route.v3.RouteAction`. * Headers specified at this level are applied before headers from the enclosing - * :ref:`envoy_api_msg_route.Route`, :ref:`envoy_api_msg_route.VirtualHost`, and - * :ref:`envoy_api_msg_RouteConfiguration`. For more information, including details on + * :ref:`envoy_api_msg_config.route.v3.Route`, :ref:`envoy_api_msg_config.route.v3.VirtualHost`, and + * :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including details on * header value syntax, see the documentation on :ref:`custom request headers * `. */ - 'request_headers_to_add': (_envoy_api_v2_core_HeaderValueOption__Output)[]; + 'request_headers_to_add': (_envoy_config_core_v3_HeaderValueOption__Output)[]; /** * Specifies a list of HTTP headers that should be removed from each request when - * this cluster is selected through the enclosing :ref:`envoy_api_msg_route.RouteAction`. + * this cluster is selected through the enclosing :ref:`envoy_api_msg_config.route.v3.RouteAction`. */ 'request_headers_to_remove': (string)[]; /** * Specifies a list of headers to be added to responses when this cluster is selected - * through the enclosing :ref:`envoy_api_msg_route.RouteAction`. + * through the enclosing :ref:`envoy_api_msg_config.route.v3.RouteAction`. * Headers specified at this level are applied before headers from the enclosing - * :ref:`envoy_api_msg_route.Route`, :ref:`envoy_api_msg_route.VirtualHost`, and - * :ref:`envoy_api_msg_RouteConfiguration`. For more information, including details on + * :ref:`envoy_api_msg_config.route.v3.Route`, :ref:`envoy_api_msg_config.route.v3.VirtualHost`, and + * :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including details on * header value syntax, see the documentation on :ref:`custom request headers * `. */ - 'response_headers_to_add': (_envoy_api_v2_core_HeaderValueOption__Output)[]; + 'response_headers_to_add': (_envoy_config_core_v3_HeaderValueOption__Output)[]; /** * Specifies a list of headers to be removed from responses when this cluster is selected - * through the enclosing :ref:`envoy_api_msg_route.RouteAction`. + * through the enclosing :ref:`envoy_api_msg_config.route.v3.RouteAction`. */ 'response_headers_to_remove': (string)[]; /** @@ -138,22 +132,17 @@ export interface _envoy_api_v2_route_WeightedCluster_ClusterWeight__Output { * *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter * specific; see the :ref:`HTTP filter documentation ` * for if and how it is utilized. - */ - 'per_filter_config'?: ({[key: string]: _google_protobuf_Struct__Output}); - /** - * The per_filter_config field can be used to provide weighted cluster-specific - * configurations for filters. The key should match the filter name, such as - * *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter - * specific; see the :ref:`HTTP filter documentation ` - * for if and how it is utilized. + * [#comment: An entry's value may be wrapped in a + * :ref:`FilterConfig` + * message to specify additional options.] */ 'typed_per_filter_config'?: ({[key: string]: _google_protobuf_Any__Output}); } /** - * Compared to the :ref:`cluster ` field that specifies a + * Compared to the :ref:`cluster ` field that specifies a * single upstream cluster as the target of a request, the :ref:`weighted_clusters - * ` option allows for specification of + * ` option allows for specification of * multiple upstream clusters along with weights that indicate the percentage of * traffic to be forwarded to each cluster. The router selects an upstream cluster based on the * weights. @@ -162,7 +151,7 @@ export interface WeightedCluster { /** * Specifies one or more upstream clusters associated with the route. */ - 'clusters'?: (_envoy_api_v2_route_WeightedCluster_ClusterWeight)[]; + 'clusters'?: (_envoy_config_route_v3_WeightedCluster_ClusterWeight)[]; /** * Specifies the runtime key prefix that should be used to construct the * runtime keys associated with each cluster. When the *runtime_key_prefix* is @@ -182,9 +171,9 @@ export interface WeightedCluster { } /** - * Compared to the :ref:`cluster ` field that specifies a + * Compared to the :ref:`cluster ` field that specifies a * single upstream cluster as the target of a request, the :ref:`weighted_clusters - * ` option allows for specification of + * ` option allows for specification of * multiple upstream clusters along with weights that indicate the percentage of * traffic to be forwarded to each cluster. The router selects an upstream cluster based on the * weights. @@ -193,7 +182,7 @@ export interface WeightedCluster__Output { /** * Specifies one or more upstream clusters associated with the route. */ - 'clusters': (_envoy_api_v2_route_WeightedCluster_ClusterWeight__Output)[]; + 'clusters': (_envoy_config_route_v3_WeightedCluster_ClusterWeight__Output)[]; /** * Specifies the runtime key prefix that should be used to construct the * runtime keys associated with each cluster. When the *runtime_key_prefix* is diff --git a/packages/grpc-js-xds/src/generated/envoy/config/trace/v2/Tracing.ts b/packages/grpc-js-xds/src/generated/envoy/config/trace/v3/Tracing.ts similarity index 54% rename from packages/grpc-js-xds/src/generated/envoy/config/trace/v2/Tracing.ts rename to packages/grpc-js-xds/src/generated/envoy/config/trace/v3/Tracing.ts index 629e3f1cc..36dfade51 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/trace/v2/Tracing.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/trace/v3/Tracing.ts @@ -1,17 +1,16 @@ -// Original file: deps/envoy-api/envoy/config/trace/v2/http_tracer.proto +// Original file: deps/envoy-api/envoy/config/trace/v3/http_tracer.proto -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; /** * Configuration for an HTTP tracer provider used by Envoy. * * The configuration is defined by the - * :ref:`HttpConnectionManager.Tracing ` - * :ref:`provider ` + * :ref:`HttpConnectionManager.Tracing ` + * :ref:`provider ` * field. */ -export interface _envoy_config_trace_v2_Tracing_Http { +export interface _envoy_config_trace_v3_Tracing_Http { /** * The name of the HTTP trace driver to instantiate. The name must match a * supported HTTP trace driver. Built-in trace drivers: @@ -24,31 +23,30 @@ export interface _envoy_config_trace_v2_Tracing_Http { * - *envoy.tracers.xray* */ 'name'?: (string); - 'config'?: (_google_protobuf_Struct); 'typed_config'?: (_google_protobuf_Any); /** * Trace driver specific configuration which depends on the driver being instantiated. * See the trace drivers for examples: * - * - :ref:`LightstepConfig ` - * - :ref:`ZipkinConfig ` - * - :ref:`DynamicOtConfig ` - * - :ref:`DatadogConfig ` - * - :ref:`OpenCensusConfig ` - * - :ref:`AWS X-Ray ` + * - :ref:`LightstepConfig ` + * - :ref:`ZipkinConfig ` + * - :ref:`DynamicOtConfig ` + * - :ref:`DatadogConfig ` + * - :ref:`OpenCensusConfig ` + * - :ref:`AWS X-Ray ` */ - 'config_type'?: "config"|"typed_config"; + 'config_type'?: "typed_config"; } /** * Configuration for an HTTP tracer provider used by Envoy. * * The configuration is defined by the - * :ref:`HttpConnectionManager.Tracing ` - * :ref:`provider ` + * :ref:`HttpConnectionManager.Tracing ` + * :ref:`provider ` * field. */ -export interface _envoy_config_trace_v2_Tracing_Http__Output { +export interface _envoy_config_trace_v3_Tracing_Http__Output { /** * The name of the HTTP trace driver to instantiate. The name must match a * supported HTTP trace driver. Built-in trace drivers: @@ -61,20 +59,19 @@ export interface _envoy_config_trace_v2_Tracing_Http__Output { * - *envoy.tracers.xray* */ 'name': (string); - 'config'?: (_google_protobuf_Struct__Output); 'typed_config'?: (_google_protobuf_Any__Output); /** * Trace driver specific configuration which depends on the driver being instantiated. * See the trace drivers for examples: * - * - :ref:`LightstepConfig ` - * - :ref:`ZipkinConfig ` - * - :ref:`DynamicOtConfig ` - * - :ref:`DatadogConfig ` - * - :ref:`OpenCensusConfig ` - * - :ref:`AWS X-Ray ` + * - :ref:`LightstepConfig ` + * - :ref:`ZipkinConfig ` + * - :ref:`DynamicOtConfig ` + * - :ref:`DatadogConfig ` + * - :ref:`OpenCensusConfig ` + * - :ref:`AWS X-Ray ` */ - 'config_type': "config"|"typed_config"; + 'config_type': "typed_config"; } /** @@ -86,13 +83,13 @@ export interface _envoy_config_trace_v2_Tracing_Http__Output { * .. attention:: * * Use of this message type has been deprecated in favor of direct use of - * :ref:`Tracing.Http `. + * :ref:`Tracing.Http `. */ export interface Tracing { /** * Provides configuration for the HTTP tracer. */ - 'http'?: (_envoy_config_trace_v2_Tracing_Http); + 'http'?: (_envoy_config_trace_v3_Tracing_Http); } /** @@ -104,11 +101,11 @@ export interface Tracing { * .. attention:: * * Use of this message type has been deprecated in favor of direct use of - * :ref:`Tracing.Http `. + * :ref:`Tracing.Http `. */ export interface Tracing__Output { /** * Provides configuration for the HTTP tracer. */ - 'http'?: (_envoy_config_trace_v2_Tracing_Http__Output); + 'http'?: (_envoy_config_trace_v3_Tracing_Http__Output); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/HttpConnectionManager.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpConnectionManager.ts similarity index 64% rename from packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/HttpConnectionManager.ts rename to packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpConnectionManager.ts index 1838f89a7..b68e812ef 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/HttpConnectionManager.ts +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpConnectionManager.ts @@ -1,24 +1,25 @@ -// Original file: deps/envoy-api/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto +// Original file: deps/envoy-api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto -import type { Rds as _envoy_config_filter_network_http_connection_manager_v2_Rds, Rds__Output as _envoy_config_filter_network_http_connection_manager_v2_Rds__Output } from '../../../../../../envoy/config/filter/network/http_connection_manager/v2/Rds'; -import type { RouteConfiguration as _envoy_api_v2_RouteConfiguration, RouteConfiguration__Output as _envoy_api_v2_RouteConfiguration__Output } from '../../../../../../envoy/api/v2/RouteConfiguration'; -import type { HttpFilter as _envoy_config_filter_network_http_connection_manager_v2_HttpFilter, HttpFilter__Output as _envoy_config_filter_network_http_connection_manager_v2_HttpFilter__Output } from '../../../../../../envoy/config/filter/network/http_connection_manager/v2/HttpFilter'; +import type { Rds as _envoy_extensions_filters_network_http_connection_manager_v3_Rds, Rds__Output as _envoy_extensions_filters_network_http_connection_manager_v3_Rds__Output } from '../../../../../../envoy/extensions/filters/network/http_connection_manager/v3/Rds'; +import type { RouteConfiguration as _envoy_config_route_v3_RouteConfiguration, RouteConfiguration__Output as _envoy_config_route_v3_RouteConfiguration__Output } from '../../../../../../envoy/config/route/v3/RouteConfiguration'; +import type { HttpFilter as _envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter, HttpFilter__Output as _envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter__Output } from '../../../../../../envoy/extensions/filters/network/http_connection_manager/v3/HttpFilter'; import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../../../google/protobuf/BoolValue'; -import type { Http1ProtocolOptions as _envoy_api_v2_core_Http1ProtocolOptions, Http1ProtocolOptions__Output as _envoy_api_v2_core_Http1ProtocolOptions__Output } from '../../../../../../envoy/api/v2/core/Http1ProtocolOptions'; -import type { Http2ProtocolOptions as _envoy_api_v2_core_Http2ProtocolOptions, Http2ProtocolOptions__Output as _envoy_api_v2_core_Http2ProtocolOptions__Output } from '../../../../../../envoy/api/v2/core/Http2ProtocolOptions'; +import type { Http1ProtocolOptions as _envoy_config_core_v3_Http1ProtocolOptions, Http1ProtocolOptions__Output as _envoy_config_core_v3_Http1ProtocolOptions__Output } from '../../../../../../envoy/config/core/v3/Http1ProtocolOptions'; +import type { Http2ProtocolOptions as _envoy_config_core_v3_Http2ProtocolOptions, Http2ProtocolOptions__Output as _envoy_config_core_v3_Http2ProtocolOptions__Output } from '../../../../../../envoy/config/core/v3/Http2ProtocolOptions'; import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../../../google/protobuf/Duration'; -import type { AccessLog as _envoy_config_filter_accesslog_v2_AccessLog, AccessLog__Output as _envoy_config_filter_accesslog_v2_AccessLog__Output } from '../../../../../../envoy/config/filter/accesslog/v2/AccessLog'; +import type { AccessLog as _envoy_config_accesslog_v3_AccessLog, AccessLog__Output as _envoy_config_accesslog_v3_AccessLog__Output } from '../../../../../../envoy/config/accesslog/v3/AccessLog'; import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../../../google/protobuf/UInt32Value'; -import type { ScopedRoutes as _envoy_config_filter_network_http_connection_manager_v2_ScopedRoutes, ScopedRoutes__Output as _envoy_config_filter_network_http_connection_manager_v2_ScopedRoutes__Output } from '../../../../../../envoy/config/filter/network/http_connection_manager/v2/ScopedRoutes'; -import type { HttpProtocolOptions as _envoy_api_v2_core_HttpProtocolOptions, HttpProtocolOptions__Output as _envoy_api_v2_core_HttpProtocolOptions__Output } from '../../../../../../envoy/api/v2/core/HttpProtocolOptions'; -import type { RequestIDExtension as _envoy_config_filter_network_http_connection_manager_v2_RequestIDExtension, RequestIDExtension__Output as _envoy_config_filter_network_http_connection_manager_v2_RequestIDExtension__Output } from '../../../../../../envoy/config/filter/network/http_connection_manager/v2/RequestIDExtension'; -import type { Percent as _envoy_type_Percent, Percent__Output as _envoy_type_Percent__Output } from '../../../../../../envoy/type/Percent'; -import type { CustomTag as _envoy_type_tracing_v2_CustomTag, CustomTag__Output as _envoy_type_tracing_v2_CustomTag__Output } from '../../../../../../envoy/type/tracing/v2/CustomTag'; -import type { _envoy_config_trace_v2_Tracing_Http, _envoy_config_trace_v2_Tracing_Http__Output } from '../../../../../../envoy/config/trace/v2/Tracing'; +import type { ScopedRoutes as _envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes, ScopedRoutes__Output as _envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes__Output } from '../../../../../../envoy/extensions/filters/network/http_connection_manager/v3/ScopedRoutes'; +import type { HttpProtocolOptions as _envoy_config_core_v3_HttpProtocolOptions, HttpProtocolOptions__Output as _envoy_config_core_v3_HttpProtocolOptions__Output } from '../../../../../../envoy/config/core/v3/HttpProtocolOptions'; +import type { RequestIDExtension as _envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension, RequestIDExtension__Output as _envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension__Output } from '../../../../../../envoy/extensions/filters/network/http_connection_manager/v3/RequestIDExtension'; +import type { LocalReplyConfig as _envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig, LocalReplyConfig__Output as _envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig__Output } from '../../../../../../envoy/extensions/filters/network/http_connection_manager/v3/LocalReplyConfig'; +import type { Percent as _envoy_type_v3_Percent, Percent__Output as _envoy_type_v3_Percent__Output } from '../../../../../../envoy/type/v3/Percent'; +import type { CustomTag as _envoy_type_tracing_v3_CustomTag, CustomTag__Output as _envoy_type_tracing_v3_CustomTag__Output } from '../../../../../../envoy/type/tracing/v3/CustomTag'; +import type { _envoy_config_trace_v3_Tracing_Http, _envoy_config_trace_v3_Tracing_Http__Output } from '../../../../../../envoy/config/trace/v3/Tracing'; -// Original file: deps/envoy-api/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto +// Original file: deps/envoy-api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto -export enum _envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_CodecType { +export enum _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 @@ -45,13 +46,13 @@ export enum _envoy_config_filter_network_http_connection_manager_v2_HttpConnecti HTTP3 = 3, } -// Original file: deps/envoy-api/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto +// Original file: deps/envoy-api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto /** * How to handle the :ref:`config_http_conn_man_headers_x-forwarded-client-cert` (XFCC) HTTP * header. */ -export enum _envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_ForwardClientCertDetails { +export enum _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. */ @@ -78,23 +79,23 @@ export enum _envoy_config_filter_network_http_connection_manager_v2_HttpConnecti ALWAYS_FORWARD_ONLY = 4, } -export interface _envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_InternalAddressConfig { +export interface _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig { /** * Whether unix socket addresses should be considered internal. */ 'unix_sockets'?: (boolean); } -export interface _envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_InternalAddressConfig__Output { +export interface _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig__Output { /** * Whether unix socket addresses should be considered internal. */ 'unix_sockets': (boolean); } -// Original file: deps/envoy-api/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto +// Original file: deps/envoy-api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto -export enum _envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_Tracing_OperationName { +export enum _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing_OperationName { /** * The HTTP listener is used for ingress/incoming requests. */ @@ -105,9 +106,9 @@ export enum _envoy_config_filter_network_http_connection_manager_v2_HttpConnecti EGRESS = 1, } -// Original file: deps/envoy-api/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto +// Original file: deps/envoy-api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto -export enum _envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_ServerHeaderTransformation { +export enum _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ServerHeaderTransformation { /** * Overwrite any Server header with the contents of server_name. */ @@ -127,7 +128,7 @@ export enum _envoy_config_filter_network_http_connection_manager_v2_HttpConnecti /** * [#next-free-field: 7] */ -export interface _envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_SetCurrentClientCertDetails { +export interface _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails { /** * Whether to forward the subject of the client cert. Defaults to false. */ @@ -160,7 +161,7 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_HttpCon /** * [#next-free-field: 7] */ -export interface _envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_SetCurrentClientCertDetails__Output { +export interface _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails__Output { /** * Whether to forward the subject of the client cert. Defaults to false. */ @@ -193,26 +194,7 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_HttpCon /** * [#next-free-field: 10] */ -export interface _envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_Tracing { - /** - * The span name will be derived from this field. If - * :ref:`traffic_direction ` is - * specified on the parent listener, then it is used instead of this field. - * - * .. attention:: - * This field has been deprecated in favor of `traffic_direction`. - */ - 'operation_name'?: (_envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_Tracing_OperationName | keyof typeof _envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_Tracing_OperationName); - /** - * A list of header names used to create tags for the active span. The header name is used to - * populate the tag name, and the header value is used to populate the tag value. The tag is - * created if the specified header name is present in the request's headers. - * - * .. attention:: - * This field has been deprecated in favor of :ref:`custom_tags - * `. - */ - 'request_headers_for_tags'?: (string)[]; +export interface _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing { /** * Target percentage of requests managed by this HTTP connection manager that will be force * traced if the :ref:`x-client-trace-id ` @@ -221,7 +203,7 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_HttpCon * `. * Default: 100% */ - 'client_sampling'?: (_envoy_type_Percent); + 'client_sampling'?: (_envoy_type_v3_Percent); /** * Target percentage of requests managed by this HTTP connection manager that will be randomly * selected for trace generation, if not requested by the client or not forced. This field is @@ -229,7 +211,7 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_HttpCon * :ref:`HTTP Connection Manager `. * Default: 100% */ - 'random_sampling'?: (_envoy_type_Percent); + 'random_sampling'?: (_envoy_type_v3_Percent); /** * Target percentage of requests managed by this HTTP connection manager that will be traced * after all other sampling checks have been applied (client-directed, force tracing, random @@ -240,7 +222,7 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_HttpCon * :ref:`HTTP Connection Manager `. * Default: 100% */ - 'overall_sampling'?: (_envoy_type_Percent); + 'overall_sampling'?: (_envoy_type_v3_Percent); /** * Whether to annotate spans with additional data. If true, spans will include logs for stream * events. @@ -255,7 +237,7 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_HttpCon /** * A list of custom tags with unique tag name to create tags for the active span. */ - 'custom_tags'?: (_envoy_type_tracing_v2_CustomTag)[]; + 'custom_tags'?: (_envoy_type_tracing_v3_CustomTag)[]; /** * Configuration for an external tracing provider. * If not specified, no tracing will be performed. @@ -268,32 +250,13 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_HttpCon * Such a constraint is inherent to OpenCensus itself. It cannot be overcome without changes * on OpenCensus side. */ - 'provider'?: (_envoy_config_trace_v2_Tracing_Http); + 'provider'?: (_envoy_config_trace_v3_Tracing_Http); } /** * [#next-free-field: 10] */ -export interface _envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_Tracing__Output { - /** - * The span name will be derived from this field. If - * :ref:`traffic_direction ` is - * specified on the parent listener, then it is used instead of this field. - * - * .. attention:: - * This field has been deprecated in favor of `traffic_direction`. - */ - 'operation_name': (keyof typeof _envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_Tracing_OperationName); - /** - * A list of header names used to create tags for the active span. The header name is used to - * populate the tag name, and the header value is used to populate the tag value. The tag is - * created if the specified header name is present in the request's headers. - * - * .. attention:: - * This field has been deprecated in favor of :ref:`custom_tags - * `. - */ - 'request_headers_for_tags': (string)[]; +export interface _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing__Output { /** * Target percentage of requests managed by this HTTP connection manager that will be force * traced if the :ref:`x-client-trace-id ` @@ -302,7 +265,7 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_HttpCon * `. * Default: 100% */ - 'client_sampling'?: (_envoy_type_Percent__Output); + 'client_sampling'?: (_envoy_type_v3_Percent__Output); /** * Target percentage of requests managed by this HTTP connection manager that will be randomly * selected for trace generation, if not requested by the client or not forced. This field is @@ -310,7 +273,7 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_HttpCon * :ref:`HTTP Connection Manager `. * Default: 100% */ - 'random_sampling'?: (_envoy_type_Percent__Output); + 'random_sampling'?: (_envoy_type_v3_Percent__Output); /** * Target percentage of requests managed by this HTTP connection manager that will be traced * after all other sampling checks have been applied (client-directed, force tracing, random @@ -321,7 +284,7 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_HttpCon * :ref:`HTTP Connection Manager `. * Default: 100% */ - 'overall_sampling'?: (_envoy_type_Percent__Output); + 'overall_sampling'?: (_envoy_type_v3_Percent__Output); /** * Whether to annotate spans with additional data. If true, spans will include logs for stream * events. @@ -336,7 +299,7 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_HttpCon /** * A list of custom tags with unique tag name to create tags for the active span. */ - 'custom_tags': (_envoy_type_tracing_v2_CustomTag__Output)[]; + 'custom_tags': (_envoy_type_tracing_v3_CustomTag__Output)[]; /** * Configuration for an external tracing provider. * If not specified, no tracing will be performed. @@ -349,7 +312,7 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_HttpCon * Such a constraint is inherent to OpenCensus itself. It cannot be overcome without changes * on OpenCensus side. */ - 'provider'?: (_envoy_config_trace_v2_Tracing_Http__Output); + 'provider'?: (_envoy_config_trace_v3_Tracing_Http__Output); } /** @@ -366,7 +329,7 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_HttpCon * The current implementation of upgrade headers does not work with HTTP/2 * upstreams. */ -export interface _envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_UpgradeConfig { +export interface _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig { /** * The case-insensitive name of this upgrade, e.g. "websocket". * For each upgrade type present in upgrade_configs, requests with @@ -379,11 +342,11 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_HttpCon * this type of upgrade. If no filters are present, the filter chain for * HTTP connections will be used for this upgrade type. */ - 'filters'?: (_envoy_config_filter_network_http_connection_manager_v2_HttpFilter)[]; + 'filters'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter)[]; /** * Determines if upgrades are enabled or disabled by default. Defaults to true. * This can be overridden on a per-route basis with :ref:`cluster - * ` as documented in the + * ` as documented in the * :ref:`upgrade documentation `. */ 'enabled'?: (_google_protobuf_BoolValue); @@ -403,7 +366,7 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_HttpCon * The current implementation of upgrade headers does not work with HTTP/2 * upstreams. */ -export interface _envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_UpgradeConfig__Output { +export interface _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig__Output { /** * The case-insensitive name of this upgrade, e.g. "websocket". * For each upgrade type present in upgrade_configs, requests with @@ -416,24 +379,24 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_HttpCon * this type of upgrade. If no filters are present, the filter chain for * HTTP connections will be used for this upgrade type. */ - 'filters': (_envoy_config_filter_network_http_connection_manager_v2_HttpFilter__Output)[]; + 'filters': (_envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter__Output)[]; /** * Determines if upgrades are enabled or disabled by default. Defaults to true. * This can be overridden on a per-route basis with :ref:`cluster - * ` as documented in the + * ` as documented in the * :ref:`upgrade documentation `. */ 'enabled'?: (_google_protobuf_BoolValue__Output); } /** - * [#next-free-field: 37] + * [#next-free-field: 43] */ export interface HttpConnectionManager { /** * Supplies the type of codec that the connection manager should use. */ - 'codec_type'?: (_envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_CodecType | keyof typeof _envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_CodecType); + 'codec_type'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_CodecType | keyof typeof _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 @@ -443,17 +406,17 @@ export interface HttpConnectionManager { /** * The connection manager’s route table will be dynamically loaded via the RDS API. */ - 'rds'?: (_envoy_config_filter_network_http_connection_manager_v2_Rds); + 'rds'?: (_envoy_extensions_filters_network_http_connection_manager_v3_Rds); /** * The route table for the connection manager is static and is specified in this property. */ - 'route_config'?: (_envoy_api_v2_RouteConfiguration); + 'route_config'?: (_envoy_config_route_v3_RouteConfiguration); /** * A list of individual HTTP filters that make up the filter chain for * requests made to the connection manager. :ref:`Order matters ` * as the filters are processed sequentially as request events happen. */ - 'http_filters'?: (_envoy_config_filter_network_http_connection_manager_v2_HttpFilter)[]; + 'http_filters'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter)[]; /** * Whether the connection manager manipulates the :ref:`config_http_conn_man_headers_user-agent` * and :ref:`config_http_conn_man_headers_downstream-service-cluster` headers. See the linked @@ -463,33 +426,22 @@ export interface HttpConnectionManager { /** * Presence of the object defines whether the connection manager * emits :ref:`tracing ` data to the :ref:`configured tracing provider - * `. + * `. */ - 'tracing'?: (_envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_Tracing); + 'tracing'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing); /** * Additional HTTP/1 settings that are passed to the HTTP/1 codec. */ - 'http_protocol_options'?: (_envoy_api_v2_core_Http1ProtocolOptions); + 'http_protocol_options'?: (_envoy_config_core_v3_Http1ProtocolOptions); /** * Additional HTTP/2 settings that are passed directly to the HTTP/2 codec. */ - 'http2_protocol_options'?: (_envoy_api_v2_core_Http2ProtocolOptions); + 'http2_protocol_options'?: (_envoy_config_core_v3_Http2ProtocolOptions); /** * An optional override that the connection manager will write to the server * header in responses. If not set, the default is *envoy*. */ 'server_name'?: (string); - /** - * The idle timeout for connections managed by the connection manager. The - * idle timeout is defined as the period in which there are no active - * requests. If not set, there is no idle timeout. When the idle timeout is - * reached the connection will be closed. If the connection is an HTTP/2 - * connection a drain sequence will occur prior to closing the connection. - * This field is deprecated. Use :ref:`idle_timeout - * ` - * instead. - */ - 'idle_timeout'?: (_google_protobuf_Duration); /** * The time that Envoy will wait between sending an HTTP/2 “shutdown * notification” (GOAWAY frame with max stream ID) and a final GOAWAY frame. @@ -506,7 +458,7 @@ export interface HttpConnectionManager { * Configuration for :ref:`HTTP access logs ` * emitted by the connection manager. */ - 'access_log'?: (_envoy_config_filter_accesslog_v2_AccessLog)[]; + 'access_log'?: (_envoy_config_accesslog_v3_AccessLog)[]; /** * If set to true, the connection manager will use the real remote address * of the client connection when determining internal versus external origin and manipulating @@ -528,17 +480,17 @@ 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_config_filter_network_http_connection_manager_v2_HttpConnectionManager_ForwardClientCertDetails | keyof typeof _envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_ForwardClientCertDetails); + '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); /** * This field is valid only when :ref:`forward_client_cert_details - * ` + * ` * is APPEND_FORWARD or SANITIZE_SET and the client connection is mTLS. It specifies the fields in * the client certificate to be forwarded. Note that in the * :ref:`config_http_conn_man_headers_x-forwarded-client-cert` header, *Hash* is always set, and * *By* is always set when the client certificate presents the URI type Subject Alternative Name * value. */ - 'set_current_client_cert_details'?: (_envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_SetCurrentClientCertDetails); + 'set_current_client_cert_details'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails); /** * If proxy_100_continue is true, Envoy will proxy incoming "Expect: * 100-continue" headers upstream, and forward "100 Continue" responses @@ -557,7 +509,7 @@ export interface HttpConnectionManager { /** * If * :ref:`use_remote_address - * ` + * ` * is true and represent_ipv4_remote_address_as_ipv4_mapped_ipv6 is true and the remote address is * an IPv4 address, the address will be mapped to IPv6 before it is appended to *x-forwarded-for*. * This is useful for testing compatibility of upstream services that parse the header value. For @@ -575,7 +527,7 @@ export interface HttpConnectionManager { * :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP header. This may be used in * conjunction with HTTP filters that explicitly manipulate XFF after the HTTP connection manager * has mutated the request headers. While :ref:`use_remote_address - * ` + * ` * will also suppress XFF addition, it has consequences for logging and other * Envoy uses of the remote address, so *skip_xff_append* should be used * when only an elision of XFF addition is intended. @@ -586,7 +538,7 @@ export interface HttpConnectionManager { * empty, no via header will be appended. */ 'via'?: (string); - 'upgrade_configs'?: (_envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_UpgradeConfig)[]; + 'upgrade_configs'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig)[]; /** * The stream idle timeout for connections managed by the connection manager. * If not specified, this defaults to 5 minutes. The default value was selected @@ -596,15 +548,29 @@ export interface HttpConnectionManager { * * This idle timeout applies to new streams and is overridable by the * :ref:`route-level idle_timeout - * `. Even on a stream in + * `. Even on a stream in * which the override applies, prior to receipt of the initial request * headers, the :ref:`stream_idle_timeout - * ` + * ` * applies. Each time an encode/decode event for headers or data is processed * for the stream, the timer will be reset. If the timeout fires, the stream * is terminated with a 408 Request Timeout error code if no upstream response * header has been received, otherwise a stream reset occurs. * + * This timeout also specifies the amount of time that Envoy will wait for the peer to open enough + * window to write any remaining stream data once the entirety of stream data (local end stream is + * true) has been buffered pending available window. In other words, this timeout defends against + * a peer that does not release enough window to completely write the stream, even though all + * data has been proxied within available flow control windows. If the timeout is hit in this + * case, the :ref:`tx_flush_timeout ` counter will be + * incremented. Note that :ref:`max_stream_duration + * ` does not apply to + * this corner case. + * + * If the :ref:`overload action ` "envoy.overload_actions.reduce_timeouts" + * is configured, this timeout is scaled according to the value for + * :ref:`HTTP_DOWNSTREAM_STREAM_IDLE `. + * * Note that it is possible to idle timeout even if the wire traffic for a stream is non-idle, due * to the granularity of events presented to the connection manager. For example, while receiving * very large request headers, it may be the case that there is traffic regularly arriving on the @@ -621,7 +587,7 @@ export interface HttpConnectionManager { * See the documentation for :ref:`config_http_conn_man_headers_x-envoy-internal` for more * information about internal/external addresses. */ - 'internal_address_config'?: (_envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_InternalAddressConfig); + 'internal_address_config'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig); /** * The delayed close timeout is for downstream connections managed by the HTTP connection manager. * It is defined as a grace period after connection close processing has been locally initiated @@ -678,10 +644,10 @@ export interface HttpConnectionManager { * true in the future. When not specified, this value may be overridden by the * runtime variable * :ref:`http_connection_manager.normalize_path`. - * See `Normalization and Comparison ` + * See `Normalization and Comparison `_ * for details of normalization. * Note that Envoy does not perform - * `case normalization ` + * `case normalization `_ */ 'normalize_path'?: (_google_protobuf_BoolValue); /** @@ -689,7 +655,7 @@ export interface HttpConnectionManager { * (e.g., the value of a header). The "routing scopes" (i.e., route tables) and "scope keys" are * specified in this message. */ - 'scoped_routes'?: (_envoy_config_filter_network_http_connection_manager_v2_ScopedRoutes); + 'scoped_routes'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes); /** * Whether the connection manager will keep the :ref:`x-request-id * ` header if passed for a request that is edge @@ -702,7 +668,7 @@ export interface HttpConnectionManager { * requests by HTTP filters or routing. This affects the upstream *:path* header as well. Without * setting this option, incoming requests with path `//dir///file` will not match against route * with `prefix` match set to `/dir`. Defaults to `false`. Note that slash merging is not part of - * `HTTP spec ` and is provided for convenience. + * `HTTP spec `_ and is provided for convenience. */ 'merge_slashes'?: (boolean); /** @@ -710,12 +676,12 @@ export interface HttpConnectionManager { * By default, Envoy will overwrite the header with the value specified in * server_name. */ - 'server_header_transformation'?: (_envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_ServerHeaderTransformation | keyof typeof _envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_ServerHeaderTransformation); + '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); /** * Additional settings for HTTP requests handled by the connection manager. These will be * applicable to both HTTP1 and HTTP2 requests. */ - 'common_http_protocol_options'?: (_envoy_api_v2_core_HttpProtocolOptions); + 'common_http_protocol_options'?: (_envoy_config_core_v3_HttpProtocolOptions); /** * The configuration of the request ID extension. This includes operations such as * generation, validation, and associated tracing operations. @@ -728,18 +694,76 @@ export interface HttpConnectionManager { * * 3. Tracing decision (sampled, forced, etc) is set in 14th byte of the UUID. */ - 'request_id_extension'?: (_envoy_config_filter_network_http_connection_manager_v2_RequestIDExtension); + 'request_id_extension'?: (_envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension); + /** + * If set, Envoy will always set :ref:`x-request-id ` header in response. + * If this is false or not set, the request ID is returned in responses only if tracing is forced using + * :ref:`x-envoy-force-trace ` header. + */ + 'always_set_request_id_in_response'?: (boolean); + /** + * The configuration to customize local reply returned by Envoy. It can customize status code, + * body text and response content type. If not specified, status code and text body are hard + * coded in Envoy, the response content type is plain text. + */ + 'local_reply_config'?: (_envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig); + /** + * Determines if the port part should be removed from host/authority header before any processing + * of request by HTTP filters or routing. The port would be removed only if it is equal to the :ref:`listener's` + * local port and request method is not CONNECT. This affects the upstream host header as well. + * Without setting this option, incoming requests with host `example:443` will not match against + * route with :ref:`domains` match set to `example`. Defaults to `false`. Note that port removal is not part + * of `HTTP spec `_ and is provided for convenience. + * Only one of `strip_matching_host_port` or `strip_any_host_port` can be set. + */ + 'strip_matching_host_port'?: (boolean); + /** + * Governs Envoy's behavior when receiving invalid HTTP from downstream. + * If this option is false (default), Envoy will err on the conservative side handling HTTP + * errors, terminating both HTTP/1.1 and HTTP/2 connections when receiving an invalid request. + * If this option is set to true, Envoy will be more permissive, only resetting the invalid + * stream in the case of HTTP/2 and leaving the connection open where possible (if the entire + * request is read for HTTP/1.1) + * In general this should be true for deployments receiving trusted traffic (L2 Envoys, + * company-internal mesh) and false when receiving untrusted traffic (edge deployments). + * + * If different behaviors for invalid_http_message for HTTP/1 and HTTP/2 are + * desired, one should use the new HTTP/1 option :ref:`override_stream_error_on_invalid_http_message + * ` or the new HTTP/2 option + * :ref:`override_stream_error_on_invalid_http_message + * ` + * *not* the deprecated but similarly named :ref:`stream_error_on_invalid_http_messaging + * ` + */ + 'stream_error_on_invalid_http_message'?: (_google_protobuf_BoolValue); + /** + * The amount of time that Envoy will wait for the request headers to be received. The timer is + * activated when the first byte of the headers is received, and is disarmed when the last byte of + * the headers has been received. If not specified or set to 0, this timeout is disabled. + */ + 'request_headers_timeout'?: (_google_protobuf_Duration); + /** + * Determines if the port part should be removed from host/authority header before any processing + * of request by HTTP filters or routing. The port would be removed only if request method is not CONNECT. + * This affects the upstream host header as well. + * Without setting this option, incoming requests with host `example:443` will not match against + * route with :ref:`domains` match set to `example`. Defaults to `false`. Note that port removal is not part + * of `HTTP spec `_ and is provided for convenience. + * Only one of `strip_matching_host_port` or `strip_any_host_port` can be set. + */ + 'strip_any_host_port'?: (boolean); 'route_specifier'?: "rds"|"route_config"|"scoped_routes"; + 'strip_port_mode'?: "strip_any_host_port"; } /** - * [#next-free-field: 37] + * [#next-free-field: 43] */ export interface HttpConnectionManager__Output { /** * Supplies the type of codec that the connection manager should use. */ - 'codec_type': (keyof typeof _envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_CodecType); + 'codec_type': (keyof typeof _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 @@ -749,17 +773,17 @@ export interface HttpConnectionManager__Output { /** * The connection manager’s route table will be dynamically loaded via the RDS API. */ - 'rds'?: (_envoy_config_filter_network_http_connection_manager_v2_Rds__Output); + 'rds'?: (_envoy_extensions_filters_network_http_connection_manager_v3_Rds__Output); /** * The route table for the connection manager is static and is specified in this property. */ - 'route_config'?: (_envoy_api_v2_RouteConfiguration__Output); + 'route_config'?: (_envoy_config_route_v3_RouteConfiguration__Output); /** * A list of individual HTTP filters that make up the filter chain for * requests made to the connection manager. :ref:`Order matters ` * as the filters are processed sequentially as request events happen. */ - 'http_filters': (_envoy_config_filter_network_http_connection_manager_v2_HttpFilter__Output)[]; + 'http_filters': (_envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter__Output)[]; /** * Whether the connection manager manipulates the :ref:`config_http_conn_man_headers_user-agent` * and :ref:`config_http_conn_man_headers_downstream-service-cluster` headers. See the linked @@ -769,33 +793,22 @@ export interface HttpConnectionManager__Output { /** * Presence of the object defines whether the connection manager * emits :ref:`tracing ` data to the :ref:`configured tracing provider - * `. + * `. */ - 'tracing'?: (_envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_Tracing__Output); + 'tracing'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing__Output); /** * Additional HTTP/1 settings that are passed to the HTTP/1 codec. */ - 'http_protocol_options'?: (_envoy_api_v2_core_Http1ProtocolOptions__Output); + 'http_protocol_options'?: (_envoy_config_core_v3_Http1ProtocolOptions__Output); /** * Additional HTTP/2 settings that are passed directly to the HTTP/2 codec. */ - 'http2_protocol_options'?: (_envoy_api_v2_core_Http2ProtocolOptions__Output); + 'http2_protocol_options'?: (_envoy_config_core_v3_Http2ProtocolOptions__Output); /** * An optional override that the connection manager will write to the server * header in responses. If not set, the default is *envoy*. */ 'server_name': (string); - /** - * The idle timeout for connections managed by the connection manager. The - * idle timeout is defined as the period in which there are no active - * requests. If not set, there is no idle timeout. When the idle timeout is - * reached the connection will be closed. If the connection is an HTTP/2 - * connection a drain sequence will occur prior to closing the connection. - * This field is deprecated. Use :ref:`idle_timeout - * ` - * instead. - */ - 'idle_timeout'?: (_google_protobuf_Duration__Output); /** * The time that Envoy will wait between sending an HTTP/2 “shutdown * notification” (GOAWAY frame with max stream ID) and a final GOAWAY frame. @@ -812,7 +825,7 @@ export interface HttpConnectionManager__Output { * Configuration for :ref:`HTTP access logs ` * emitted by the connection manager. */ - 'access_log': (_envoy_config_filter_accesslog_v2_AccessLog__Output)[]; + 'access_log': (_envoy_config_accesslog_v3_AccessLog__Output)[]; /** * If set to true, the connection manager will use the real remote address * of the client connection when determining internal versus external origin and manipulating @@ -834,17 +847,17 @@ 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_config_filter_network_http_connection_manager_v2_HttpConnectionManager_ForwardClientCertDetails); + 'forward_client_cert_details': (keyof typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ForwardClientCertDetails); /** * This field is valid only when :ref:`forward_client_cert_details - * ` + * ` * is APPEND_FORWARD or SANITIZE_SET and the client connection is mTLS. It specifies the fields in * the client certificate to be forwarded. Note that in the * :ref:`config_http_conn_man_headers_x-forwarded-client-cert` header, *Hash* is always set, and * *By* is always set when the client certificate presents the URI type Subject Alternative Name * value. */ - 'set_current_client_cert_details'?: (_envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_SetCurrentClientCertDetails__Output); + 'set_current_client_cert_details'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails__Output); /** * If proxy_100_continue is true, Envoy will proxy incoming "Expect: * 100-continue" headers upstream, and forward "100 Continue" responses @@ -863,7 +876,7 @@ export interface HttpConnectionManager__Output { /** * If * :ref:`use_remote_address - * ` + * ` * is true and represent_ipv4_remote_address_as_ipv4_mapped_ipv6 is true and the remote address is * an IPv4 address, the address will be mapped to IPv6 before it is appended to *x-forwarded-for*. * This is useful for testing compatibility of upstream services that parse the header value. For @@ -881,7 +894,7 @@ export interface HttpConnectionManager__Output { * :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP header. This may be used in * conjunction with HTTP filters that explicitly manipulate XFF after the HTTP connection manager * has mutated the request headers. While :ref:`use_remote_address - * ` + * ` * will also suppress XFF addition, it has consequences for logging and other * Envoy uses of the remote address, so *skip_xff_append* should be used * when only an elision of XFF addition is intended. @@ -892,7 +905,7 @@ export interface HttpConnectionManager__Output { * empty, no via header will be appended. */ 'via': (string); - 'upgrade_configs': (_envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_UpgradeConfig__Output)[]; + 'upgrade_configs': (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_UpgradeConfig__Output)[]; /** * The stream idle timeout for connections managed by the connection manager. * If not specified, this defaults to 5 minutes. The default value was selected @@ -902,15 +915,29 @@ export interface HttpConnectionManager__Output { * * This idle timeout applies to new streams and is overridable by the * :ref:`route-level idle_timeout - * `. Even on a stream in + * `. Even on a stream in * which the override applies, prior to receipt of the initial request * headers, the :ref:`stream_idle_timeout - * ` + * ` * applies. Each time an encode/decode event for headers or data is processed * for the stream, the timer will be reset. If the timeout fires, the stream * is terminated with a 408 Request Timeout error code if no upstream response * header has been received, otherwise a stream reset occurs. * + * This timeout also specifies the amount of time that Envoy will wait for the peer to open enough + * window to write any remaining stream data once the entirety of stream data (local end stream is + * true) has been buffered pending available window. In other words, this timeout defends against + * a peer that does not release enough window to completely write the stream, even though all + * data has been proxied within available flow control windows. If the timeout is hit in this + * case, the :ref:`tx_flush_timeout ` counter will be + * incremented. Note that :ref:`max_stream_duration + * ` does not apply to + * this corner case. + * + * If the :ref:`overload action ` "envoy.overload_actions.reduce_timeouts" + * is configured, this timeout is scaled according to the value for + * :ref:`HTTP_DOWNSTREAM_STREAM_IDLE `. + * * Note that it is possible to idle timeout even if the wire traffic for a stream is non-idle, due * to the granularity of events presented to the connection manager. For example, while receiving * very large request headers, it may be the case that there is traffic regularly arriving on the @@ -927,7 +954,7 @@ export interface HttpConnectionManager__Output { * See the documentation for :ref:`config_http_conn_man_headers_x-envoy-internal` for more * information about internal/external addresses. */ - 'internal_address_config'?: (_envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_InternalAddressConfig__Output); + 'internal_address_config'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig__Output); /** * The delayed close timeout is for downstream connections managed by the HTTP connection manager. * It is defined as a grace period after connection close processing has been locally initiated @@ -984,10 +1011,10 @@ export interface HttpConnectionManager__Output { * true in the future. When not specified, this value may be overridden by the * runtime variable * :ref:`http_connection_manager.normalize_path`. - * See `Normalization and Comparison ` + * See `Normalization and Comparison `_ * for details of normalization. * Note that Envoy does not perform - * `case normalization ` + * `case normalization `_ */ 'normalize_path'?: (_google_protobuf_BoolValue__Output); /** @@ -995,7 +1022,7 @@ export interface HttpConnectionManager__Output { * (e.g., the value of a header). The "routing scopes" (i.e., route tables) and "scope keys" are * specified in this message. */ - 'scoped_routes'?: (_envoy_config_filter_network_http_connection_manager_v2_ScopedRoutes__Output); + 'scoped_routes'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes__Output); /** * Whether the connection manager will keep the :ref:`x-request-id * ` header if passed for a request that is edge @@ -1008,7 +1035,7 @@ export interface HttpConnectionManager__Output { * requests by HTTP filters or routing. This affects the upstream *:path* header as well. Without * setting this option, incoming requests with path `//dir///file` will not match against route * with `prefix` match set to `/dir`. Defaults to `false`. Note that slash merging is not part of - * `HTTP spec ` and is provided for convenience. + * `HTTP spec `_ and is provided for convenience. */ 'merge_slashes': (boolean); /** @@ -1016,12 +1043,12 @@ export interface HttpConnectionManager__Output { * By default, Envoy will overwrite the header with the value specified in * server_name. */ - 'server_header_transformation': (keyof typeof _envoy_config_filter_network_http_connection_manager_v2_HttpConnectionManager_ServerHeaderTransformation); + 'server_header_transformation': (keyof typeof _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. */ - 'common_http_protocol_options'?: (_envoy_api_v2_core_HttpProtocolOptions__Output); + 'common_http_protocol_options'?: (_envoy_config_core_v3_HttpProtocolOptions__Output); /** * The configuration of the request ID extension. This includes operations such as * generation, validation, and associated tracing operations. @@ -1034,6 +1061,64 @@ export interface HttpConnectionManager__Output { * * 3. Tracing decision (sampled, forced, etc) is set in 14th byte of the UUID. */ - 'request_id_extension'?: (_envoy_config_filter_network_http_connection_manager_v2_RequestIDExtension__Output); + 'request_id_extension'?: (_envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension__Output); + /** + * If set, Envoy will always set :ref:`x-request-id ` header in response. + * If this is false or not set, the request ID is returned in responses only if tracing is forced using + * :ref:`x-envoy-force-trace ` header. + */ + 'always_set_request_id_in_response': (boolean); + /** + * The configuration to customize local reply returned by Envoy. It can customize status code, + * body text and response content type. If not specified, status code and text body are hard + * coded in Envoy, the response content type is plain text. + */ + 'local_reply_config'?: (_envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig__Output); + /** + * Determines if the port part should be removed from host/authority header before any processing + * of request by HTTP filters or routing. The port would be removed only if it is equal to the :ref:`listener's` + * local port and request method is not CONNECT. This affects the upstream host header as well. + * Without setting this option, incoming requests with host `example:443` will not match against + * route with :ref:`domains` match set to `example`. Defaults to `false`. Note that port removal is not part + * of `HTTP spec `_ and is provided for convenience. + * Only one of `strip_matching_host_port` or `strip_any_host_port` can be set. + */ + 'strip_matching_host_port': (boolean); + /** + * Governs Envoy's behavior when receiving invalid HTTP from downstream. + * If this option is false (default), Envoy will err on the conservative side handling HTTP + * errors, terminating both HTTP/1.1 and HTTP/2 connections when receiving an invalid request. + * If this option is set to true, Envoy will be more permissive, only resetting the invalid + * stream in the case of HTTP/2 and leaving the connection open where possible (if the entire + * request is read for HTTP/1.1) + * In general this should be true for deployments receiving trusted traffic (L2 Envoys, + * company-internal mesh) and false when receiving untrusted traffic (edge deployments). + * + * If different behaviors for invalid_http_message for HTTP/1 and HTTP/2 are + * desired, one should use the new HTTP/1 option :ref:`override_stream_error_on_invalid_http_message + * ` or the new HTTP/2 option + * :ref:`override_stream_error_on_invalid_http_message + * ` + * *not* the deprecated but similarly named :ref:`stream_error_on_invalid_http_messaging + * ` + */ + 'stream_error_on_invalid_http_message'?: (_google_protobuf_BoolValue__Output); + /** + * The amount of time that Envoy will wait for the request headers to be received. The timer is + * activated when the first byte of the headers is received, and is disarmed when the last byte of + * the headers has been received. If not specified or set to 0, this timeout is disabled. + */ + 'request_headers_timeout'?: (_google_protobuf_Duration__Output); + /** + * Determines if the port part should be removed from host/authority header before any processing + * of request by HTTP filters or routing. The port would be removed only if request method is not CONNECT. + * This affects the upstream host header as well. + * Without setting this option, incoming requests with host `example:443` will not match against + * route with :ref:`domains` match set to `example`. Defaults to `false`. Note that port removal is not part + * of `HTTP spec `_ and is provided for convenience. + * Only one of `strip_matching_host_port` or `strip_any_host_port` can be set. + */ + 'strip_any_host_port'?: (boolean); 'route_specifier': "rds"|"route_config"|"scoped_routes"; + 'strip_port_mode': "strip_any_host_port"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpFilter.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpFilter.ts new file mode 100644 index 000000000..881e2c714 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpFilter.ts @@ -0,0 +1,66 @@ +// Original file: deps/envoy-api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto + +import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../../../google/protobuf/Any'; +import type { ExtensionConfigSource as _envoy_config_core_v3_ExtensionConfigSource, ExtensionConfigSource__Output as _envoy_config_core_v3_ExtensionConfigSource__Output } from '../../../../../../envoy/config/core/v3/ExtensionConfigSource'; + +/** + * [#next-free-field: 7] + */ +export interface HttpFilter { + /** + * The name of the filter configuration. The name is used as a fallback to + * select an extension if the type of the configuration proto is not + * sufficient. It also serves as a resource name in ExtensionConfigDS. + */ + 'name'?: (string); + /** + * Filter specific configuration which depends on the filter being instantiated. See the supported + * filters for further documentation. + */ + 'typed_config'?: (_google_protobuf_Any); + /** + * Configuration source specifier for an extension configuration discovery service. + * In case of a failure and without the default configuration, the HTTP listener responds with code 500. + * Extension configs delivered through this mechanism are not expected to require warming (see https://github.com/envoyproxy/envoy/issues/12061). + */ + 'config_discovery'?: (_envoy_config_core_v3_ExtensionConfigSource); + /** + * If true, clients that do not support this filter may ignore the + * filter but otherwise accept the config. + * Otherwise, clients that do not support this filter must reject the config. + * [#not-implemented-hide:] + */ + 'is_optional'?: (boolean); + 'config_type'?: "typed_config"|"config_discovery"; +} + +/** + * [#next-free-field: 7] + */ +export interface HttpFilter__Output { + /** + * The name of the filter configuration. The name is used as a fallback to + * select an extension if the type of the configuration proto is not + * sufficient. It also serves as a resource name in ExtensionConfigDS. + */ + 'name': (string); + /** + * Filter specific configuration which depends on the filter being instantiated. See the supported + * filters for further documentation. + */ + 'typed_config'?: (_google_protobuf_Any__Output); + /** + * Configuration source specifier for an extension configuration discovery service. + * In case of a failure and without the default configuration, the HTTP listener responds with code 500. + * Extension configs delivered through this mechanism are not expected to require warming (see https://github.com/envoyproxy/envoy/issues/12061). + */ + 'config_discovery'?: (_envoy_config_core_v3_ExtensionConfigSource__Output); + /** + * If true, clients that do not support this filter may ignore the + * filter but otherwise accept the config. + * Otherwise, clients that do not support this filter must reject the config. + * [#not-implemented-hide:] + */ + 'is_optional': (boolean); + 'config_type': "typed_config"|"config_discovery"; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/LocalReplyConfig.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/LocalReplyConfig.ts new file mode 100644 index 000000000..10bb6e700 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/LocalReplyConfig.ts @@ -0,0 +1,106 @@ +// Original file: deps/envoy-api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto + +import type { ResponseMapper as _envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper, ResponseMapper__Output as _envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper__Output } from '../../../../../../envoy/extensions/filters/network/http_connection_manager/v3/ResponseMapper'; +import type { SubstitutionFormatString as _envoy_config_core_v3_SubstitutionFormatString, SubstitutionFormatString__Output as _envoy_config_core_v3_SubstitutionFormatString__Output } from '../../../../../../envoy/config/core/v3/SubstitutionFormatString'; + +/** + * The configuration to customize local reply returned by Envoy. + */ +export interface LocalReplyConfig { + /** + * Configuration of list of mappers which allows to filter and change local response. + * The mappers will be checked by the specified order until one is matched. + */ + 'mappers'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper)[]; + /** + * The configuration to form response body from the :ref:`command operators ` + * and to specify response content type as one of: plain/text or application/json. + * + * Example one: "plain/text" ``body_format``. + * + * .. validated-code-block:: yaml + * :type-name: envoy.config.core.v3.SubstitutionFormatString + * + * text_format: "%LOCAL_REPLY_BODY%:%RESPONSE_CODE%:path=%REQ(:path)%\n" + * + * The following response body in "plain/text" format will be generated for a request with + * local reply body of "upstream connection error", response_code=503 and path=/foo. + * + * .. code-block:: text + * + * upstream connect error:503:path=/foo + * + * Example two: "application/json" ``body_format``. + * + * .. validated-code-block:: yaml + * :type-name: envoy.config.core.v3.SubstitutionFormatString + * + * json_format: + * status: "%RESPONSE_CODE%" + * message: "%LOCAL_REPLY_BODY%" + * path: "%REQ(:path)%" + * + * The following response body in "application/json" format would be generated for a request with + * local reply body of "upstream connection error", response_code=503 and path=/foo. + * + * .. code-block:: json + * + * { + * "status": 503, + * "message": "upstream connection error", + * "path": "/foo" + * } + */ + 'body_format'?: (_envoy_config_core_v3_SubstitutionFormatString); +} + +/** + * The configuration to customize local reply returned by Envoy. + */ +export interface LocalReplyConfig__Output { + /** + * Configuration of list of mappers which allows to filter and change local response. + * The mappers will be checked by the specified order until one is matched. + */ + 'mappers': (_envoy_extensions_filters_network_http_connection_manager_v3_ResponseMapper__Output)[]; + /** + * The configuration to form response body from the :ref:`command operators ` + * and to specify response content type as one of: plain/text or application/json. + * + * Example one: "plain/text" ``body_format``. + * + * .. validated-code-block:: yaml + * :type-name: envoy.config.core.v3.SubstitutionFormatString + * + * text_format: "%LOCAL_REPLY_BODY%:%RESPONSE_CODE%:path=%REQ(:path)%\n" + * + * The following response body in "plain/text" format will be generated for a request with + * local reply body of "upstream connection error", response_code=503 and path=/foo. + * + * .. code-block:: text + * + * upstream connect error:503:path=/foo + * + * Example two: "application/json" ``body_format``. + * + * .. validated-code-block:: yaml + * :type-name: envoy.config.core.v3.SubstitutionFormatString + * + * json_format: + * status: "%RESPONSE_CODE%" + * message: "%LOCAL_REPLY_BODY%" + * path: "%REQ(:path)%" + * + * The following response body in "application/json" format would be generated for a request with + * local reply body of "upstream connection error", response_code=503 and path=/foo. + * + * .. code-block:: json + * + * { + * "status": 503, + * "message": "upstream connection error", + * "path": "/foo" + * } + */ + 'body_format'?: (_envoy_config_core_v3_SubstitutionFormatString__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/Rds.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/Rds.ts similarity index 63% rename from packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/Rds.ts rename to packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/Rds.ts index be9c038a6..8e06a6d67 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/Rds.ts +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/Rds.ts @@ -1,12 +1,12 @@ -// Original file: deps/envoy-api/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto +// Original file: deps/envoy-api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto -import type { ConfigSource as _envoy_api_v2_core_ConfigSource, ConfigSource__Output as _envoy_api_v2_core_ConfigSource__Output } from '../../../../../../envoy/api/v2/core/ConfigSource'; +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 Rds { /** * Configuration source specifier for RDS. */ - 'config_source'?: (_envoy_api_v2_core_ConfigSource); + 'config_source'?: (_envoy_config_core_v3_ConfigSource); /** * The name of the route configuration. This name will be passed to the RDS * API. This allows an Envoy configuration with multiple HTTP listeners (and @@ -20,7 +20,7 @@ export interface Rds__Output { /** * Configuration source specifier for RDS. */ - 'config_source'?: (_envoy_api_v2_core_ConfigSource__Output); + 'config_source'?: (_envoy_config_core_v3_ConfigSource__Output); /** * The name of the route configuration. This name will be passed to the RDS * API. This allows an Envoy configuration with multiple HTTP listeners (and diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/RequestIDExtension.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/RequestIDExtension.ts similarity index 78% rename from packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/RequestIDExtension.ts rename to packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/RequestIDExtension.ts index 2f043d4a8..24e05ccc3 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/RequestIDExtension.ts +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/RequestIDExtension.ts @@ -1,4 +1,4 @@ -// Original file: deps/envoy-api/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto +// Original file: deps/envoy-api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../../../google/protobuf/Any'; diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ResponseMapper.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ResponseMapper.ts new file mode 100644 index 000000000..67af3aec4 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ResponseMapper.ts @@ -0,0 +1,67 @@ +// Original file: deps/envoy-api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto + +import type { AccessLogFilter as _envoy_config_accesslog_v3_AccessLogFilter, AccessLogFilter__Output as _envoy_config_accesslog_v3_AccessLogFilter__Output } from '../../../../../../envoy/config/accesslog/v3/AccessLogFilter'; +import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../../../google/protobuf/UInt32Value'; +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 { SubstitutionFormatString as _envoy_config_core_v3_SubstitutionFormatString, SubstitutionFormatString__Output as _envoy_config_core_v3_SubstitutionFormatString__Output } from '../../../../../../envoy/config/core/v3/SubstitutionFormatString'; +import type { HeaderValueOption as _envoy_config_core_v3_HeaderValueOption, HeaderValueOption__Output as _envoy_config_core_v3_HeaderValueOption__Output } from '../../../../../../envoy/config/core/v3/HeaderValueOption'; + +/** + * The configuration to filter and change local response. + * [#next-free-field: 6] + */ +export interface ResponseMapper { + /** + * Filter to determine if this mapper should apply. + */ + 'filter'?: (_envoy_config_accesslog_v3_AccessLogFilter); + /** + * The new response status code if specified. + */ + 'status_code'?: (_google_protobuf_UInt32Value); + /** + * The new local reply body text if specified. It will be used in the `%LOCAL_REPLY_BODY%` + * command operator in the `body_format`. + */ + 'body'?: (_envoy_config_core_v3_DataSource); + /** + * A per mapper `body_format` to override the :ref:`body_format `. + * It will be used when this mapper is matched. + */ + 'body_format_override'?: (_envoy_config_core_v3_SubstitutionFormatString); + /** + * HTTP headers to add to a local reply. This allows the response mapper to append, to add + * or to override headers of any local reply before it is sent to a downstream client. + */ + 'headers_to_add'?: (_envoy_config_core_v3_HeaderValueOption)[]; +} + +/** + * The configuration to filter and change local response. + * [#next-free-field: 6] + */ +export interface ResponseMapper__Output { + /** + * Filter to determine if this mapper should apply. + */ + 'filter'?: (_envoy_config_accesslog_v3_AccessLogFilter__Output); + /** + * The new response status code if specified. + */ + 'status_code'?: (_google_protobuf_UInt32Value__Output); + /** + * The new local reply body text if specified. It will be used in the `%LOCAL_REPLY_BODY%` + * command operator in the `body_format`. + */ + 'body'?: (_envoy_config_core_v3_DataSource__Output); + /** + * A per mapper `body_format` to override the :ref:`body_format `. + * It will be used when this mapper is matched. + */ + 'body_format_override'?: (_envoy_config_core_v3_SubstitutionFormatString__Output); + /** + * HTTP headers to add to a local reply. This allows the response mapper to append, to add + * or to override headers of any local reply before it is sent to a downstream client. + */ + 'headers_to_add': (_envoy_config_core_v3_HeaderValueOption__Output)[]; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRds.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRds.ts new file mode 100644 index 000000000..a9995b455 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRds.ts @@ -0,0 +1,17 @@ +// Original file: deps/envoy-api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.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 ScopedRds { + /** + * Configuration source specifier for scoped RDS. + */ + 'scoped_rds_config_source'?: (_envoy_config_core_v3_ConfigSource); +} + +export interface ScopedRds__Output { + /** + * Configuration source specifier for scoped RDS. + */ + 'scoped_rds_config_source'?: (_envoy_config_core_v3_ConfigSource__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRouteConfigurationsList.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRouteConfigurationsList.ts new file mode 100644 index 000000000..e7f05e340 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRouteConfigurationsList.ts @@ -0,0 +1,17 @@ +// Original file: deps/envoy-api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto + +import type { ScopedRouteConfiguration as _envoy_config_route_v3_ScopedRouteConfiguration, ScopedRouteConfiguration__Output as _envoy_config_route_v3_ScopedRouteConfiguration__Output } from '../../../../../../envoy/config/route/v3/ScopedRouteConfiguration'; + +/** + * This message is used to work around the limitations with 'oneof' and repeated fields. + */ +export interface ScopedRouteConfigurationsList { + 'scoped_route_configurations'?: (_envoy_config_route_v3_ScopedRouteConfiguration)[]; +} + +/** + * This message is used to work around the limitations with 'oneof' and repeated fields. + */ +export interface ScopedRouteConfigurationsList__Output { + 'scoped_route_configurations': (_envoy_config_route_v3_ScopedRouteConfiguration__Output)[]; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/ScopedRoutes.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRoutes.ts similarity index 57% rename from packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/ScopedRoutes.ts rename to packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRoutes.ts index b9b20d2bf..a19e59b2a 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/filter/network/http_connection_manager/v2/ScopedRoutes.ts +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRoutes.ts @@ -1,28 +1,28 @@ -// Original file: deps/envoy-api/envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto +// Original file: deps/envoy-api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto -import type { ConfigSource as _envoy_api_v2_core_ConfigSource, ConfigSource__Output as _envoy_api_v2_core_ConfigSource__Output } from '../../../../../../envoy/api/v2/core/ConfigSource'; -import type { ScopedRouteConfigurationsList as _envoy_config_filter_network_http_connection_manager_v2_ScopedRouteConfigurationsList, ScopedRouteConfigurationsList__Output as _envoy_config_filter_network_http_connection_manager_v2_ScopedRouteConfigurationsList__Output } from '../../../../../../envoy/config/filter/network/http_connection_manager/v2/ScopedRouteConfigurationsList'; -import type { ScopedRds as _envoy_config_filter_network_http_connection_manager_v2_ScopedRds, ScopedRds__Output as _envoy_config_filter_network_http_connection_manager_v2_ScopedRds__Output } from '../../../../../../envoy/config/filter/network/http_connection_manager/v2/ScopedRds'; +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 { ScopedRouteConfigurationsList as _envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList, ScopedRouteConfigurationsList__Output as _envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList__Output } from '../../../../../../envoy/extensions/filters/network/http_connection_manager/v3/ScopedRouteConfigurationsList'; +import type { ScopedRds as _envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds, ScopedRds__Output as _envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds__Output } from '../../../../../../envoy/extensions/filters/network/http_connection_manager/v3/ScopedRds'; /** * Specifies the mechanism for constructing key fragments which are composed into scope keys. */ -export interface _envoy_config_filter_network_http_connection_manager_v2_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder { +export interface _envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder { /** * Specifies how a header field's value should be extracted. */ - 'header_value_extractor'?: (_envoy_config_filter_network_http_connection_manager_v2_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor); + 'header_value_extractor'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor); 'type'?: "header_value_extractor"; } /** * Specifies the mechanism for constructing key fragments which are composed into scope keys. */ -export interface _envoy_config_filter_network_http_connection_manager_v2_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder__Output { +export interface _envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder__Output { /** * Specifies how a header field's value should be extracted. */ - 'header_value_extractor'?: (_envoy_config_filter_network_http_connection_manager_v2_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor__Output); + 'header_value_extractor'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor__Output); 'type': "header_value_extractor"; } @@ -45,9 +45,13 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_ScopedR * * Each 'a=b' key-value pair constitutes an 'element' of the header field. */ -export interface _envoy_config_filter_network_http_connection_manager_v2_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor { +export interface _envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor { /** * The name of the header field to extract the value from. + * + * .. note:: + * + * If the header appears multiple times only the first value is used. */ 'name'?: (string); /** @@ -66,7 +70,7 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_ScopedR /** * Specifies the key value pair to extract the value from. */ - 'element'?: (_envoy_config_filter_network_http_connection_manager_v2_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement); + 'element'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement); 'extract_type'?: "index"|"element"; } @@ -89,9 +93,13 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_ScopedR * * Each 'a=b' key-value pair constitutes an 'element' of the header field. */ -export interface _envoy_config_filter_network_http_connection_manager_v2_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor__Output { +export interface _envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor__Output { /** * The name of the header field to extract the value from. + * + * .. note:: + * + * If the header appears multiple times only the first value is used. */ 'name': (string); /** @@ -110,14 +118,14 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_ScopedR /** * Specifies the key value pair to extract the value from. */ - 'element'?: (_envoy_config_filter_network_http_connection_manager_v2_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement__Output); + 'element'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement__Output); 'extract_type': "index"|"element"; } /** * Specifies a header field's key value pair to match on. */ -export interface _envoy_config_filter_network_http_connection_manager_v2_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement { +export interface _envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement { /** * The separator between key and value (e.g., '=' separates 'k=v;...'). * If an element is an empty string, the element is ignored. @@ -135,7 +143,7 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_ScopedR /** * Specifies a header field's key value pair to match on. */ -export interface _envoy_config_filter_network_http_connection_manager_v2_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement__Output { +export interface _envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement__Output { /** * The separator between key and value (e.g., '=' separates 'k=v;...'). * If an element is an empty string, the element is ignored. @@ -152,42 +160,42 @@ export interface _envoy_config_filter_network_http_connection_manager_v2_ScopedR /** * Specifies the mechanism for constructing "scope keys" based on HTTP request attributes. These - * keys are matched against a set of :ref:`Key` - * objects assembled from :ref:`ScopedRouteConfiguration` + * keys are matched against a set of :ref:`Key` + * objects assembled from :ref:`ScopedRouteConfiguration` * messages distributed via SRDS (the Scoped Route Discovery Service) or assigned statically via - * :ref:`scoped_route_configurations_list`. + * :ref:`scoped_route_configurations_list`. * * Upon receiving a request's headers, the Router will build a key using the algorithm specified * by this message. This key will be used to look up the routing table (i.e., the - * :ref:`RouteConfiguration`) to use for the request. + * :ref:`RouteConfiguration`) to use for the request. */ -export interface _envoy_config_filter_network_http_connection_manager_v2_ScopedRoutes_ScopeKeyBuilder { +export interface _envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder { /** * The final(built) scope key consists of the ordered union of these fragments, which are compared in order with the - * fragments of a :ref:`ScopedRouteConfiguration`. + * fragments of a :ref:`ScopedRouteConfiguration`. * A missing fragment during comparison will make the key invalid, i.e., the computed key doesn't match any key. */ - 'fragments'?: (_envoy_config_filter_network_http_connection_manager_v2_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder)[]; + 'fragments'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder)[]; } /** * Specifies the mechanism for constructing "scope keys" based on HTTP request attributes. These - * keys are matched against a set of :ref:`Key` - * objects assembled from :ref:`ScopedRouteConfiguration` + * keys are matched against a set of :ref:`Key` + * objects assembled from :ref:`ScopedRouteConfiguration` * messages distributed via SRDS (the Scoped Route Discovery Service) or assigned statically via - * :ref:`scoped_route_configurations_list`. + * :ref:`scoped_route_configurations_list`. * * Upon receiving a request's headers, the Router will build a key using the algorithm specified * by this message. This key will be used to look up the routing table (i.e., the - * :ref:`RouteConfiguration`) to use for the request. + * :ref:`RouteConfiguration`) to use for the request. */ -export interface _envoy_config_filter_network_http_connection_manager_v2_ScopedRoutes_ScopeKeyBuilder__Output { +export interface _envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder__Output { /** * The final(built) scope key consists of the ordered union of these fragments, which are compared in order with the - * fragments of a :ref:`ScopedRouteConfiguration`. + * fragments of a :ref:`ScopedRouteConfiguration`. * A missing fragment during comparison will make the key invalid, i.e., the computed key doesn't match any key. */ - 'fragments': (_envoy_config_filter_network_http_connection_manager_v2_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder__Output)[]; + 'fragments': (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder__Output)[]; } /** @@ -201,29 +209,29 @@ export interface ScopedRoutes { /** * The algorithm to use for constructing a scope key for each request. */ - 'scope_key_builder'?: (_envoy_config_filter_network_http_connection_manager_v2_ScopedRoutes_ScopeKeyBuilder); + 'scope_key_builder'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder); /** * Configuration source specifier for RDS. * This config source is used to subscribe to RouteConfiguration resources specified in * ScopedRouteConfiguration messages. */ - 'rds_config_source'?: (_envoy_api_v2_core_ConfigSource); + 'rds_config_source'?: (_envoy_config_core_v3_ConfigSource); /** * The set of routing scopes corresponding to the HCM. A scope is assigned to a request by * matching a key constructed from the request's attributes according to the algorithm specified * by the - * :ref:`ScopeKeyBuilder` + * :ref:`ScopeKeyBuilder` * in this message. */ - 'scoped_route_configurations_list'?: (_envoy_config_filter_network_http_connection_manager_v2_ScopedRouteConfigurationsList); + 'scoped_route_configurations_list'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList); /** * The set of routing scopes associated with the HCM will be dynamically loaded via the SRDS * API. A scope is assigned to a request by matching a key constructed from the request's * attributes according to the algorithm specified by the - * :ref:`ScopeKeyBuilder` + * :ref:`ScopeKeyBuilder` * in this message. */ - 'scoped_rds'?: (_envoy_config_filter_network_http_connection_manager_v2_ScopedRds); + 'scoped_rds'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds); 'config_specifier'?: "scoped_route_configurations_list"|"scoped_rds"; } @@ -238,28 +246,28 @@ export interface ScopedRoutes__Output { /** * The algorithm to use for constructing a scope key for each request. */ - 'scope_key_builder'?: (_envoy_config_filter_network_http_connection_manager_v2_ScopedRoutes_ScopeKeyBuilder__Output); + 'scope_key_builder'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder__Output); /** * Configuration source specifier for RDS. * This config source is used to subscribe to RouteConfiguration resources specified in * ScopedRouteConfiguration messages. */ - 'rds_config_source'?: (_envoy_api_v2_core_ConfigSource__Output); + 'rds_config_source'?: (_envoy_config_core_v3_ConfigSource__Output); /** * The set of routing scopes corresponding to the HCM. A scope is assigned to a request by * matching a key constructed from the request's attributes according to the algorithm specified * by the - * :ref:`ScopeKeyBuilder` + * :ref:`ScopeKeyBuilder` * in this message. */ - 'scoped_route_configurations_list'?: (_envoy_config_filter_network_http_connection_manager_v2_ScopedRouteConfigurationsList__Output); + 'scoped_route_configurations_list'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList__Output); /** * The set of routing scopes associated with the HCM will be dynamically loaded via the SRDS * API. A scope is assigned to a request by matching a key constructed from the request's * attributes according to the algorithm specified by the - * :ref:`ScopeKeyBuilder` + * :ref:`ScopeKeyBuilder` * in this message. */ - 'scoped_rds'?: (_envoy_config_filter_network_http_connection_manager_v2_ScopedRds__Output); + 'scoped_rds'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds__Output); 'config_specifier': "scoped_route_configurations_list"|"scoped_rds"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/AdsDummy.ts b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/AdsDummy.ts new file mode 100644 index 000000000..c15510877 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/AdsDummy.ts @@ -0,0 +1,16 @@ +// Original file: deps/envoy-api/envoy/service/discovery/v3/ads.proto + + +/** + * [#not-implemented-hide:] Not configuration. Workaround c++ protobuf issue with importing + * services: https://github.com/google/protobuf/issues/4221 + */ +export interface AdsDummy { +} + +/** + * [#not-implemented-hide:] Not configuration. Workaround c++ protobuf issue with importing + * services: https://github.com/google/protobuf/issues/4221 + */ +export interface AdsDummy__Output { +} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/AggregatedDiscoveryService.ts b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/AggregatedDiscoveryService.ts new file mode 100644 index 000000000..445057d44 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/AggregatedDiscoveryService.ts @@ -0,0 +1,52 @@ +// Original file: deps/envoy-api/envoy/service/discovery/v3/ads.proto + +import type * as grpc from '@grpc/grpc-js' +import type { DeltaDiscoveryRequest as _envoy_service_discovery_v3_DeltaDiscoveryRequest, DeltaDiscoveryRequest__Output as _envoy_service_discovery_v3_DeltaDiscoveryRequest__Output } from '../../../../envoy/service/discovery/v3/DeltaDiscoveryRequest'; +import type { DeltaDiscoveryResponse as _envoy_service_discovery_v3_DeltaDiscoveryResponse, DeltaDiscoveryResponse__Output as _envoy_service_discovery_v3_DeltaDiscoveryResponse__Output } from '../../../../envoy/service/discovery/v3/DeltaDiscoveryResponse'; +import type { DiscoveryRequest as _envoy_service_discovery_v3_DiscoveryRequest, DiscoveryRequest__Output as _envoy_service_discovery_v3_DiscoveryRequest__Output } from '../../../../envoy/service/discovery/v3/DiscoveryRequest'; +import type { DiscoveryResponse as _envoy_service_discovery_v3_DiscoveryResponse, DiscoveryResponse__Output as _envoy_service_discovery_v3_DiscoveryResponse__Output } from '../../../../envoy/service/discovery/v3/DiscoveryResponse'; + +/** + * See https://github.com/lyft/envoy-api#apis for a description of the role of + * ADS and how it is intended to be used by a management server. ADS requests + * have the same structure as their singleton xDS counterparts, but can + * multiplex many resource types on a single stream. The type_url in the + * DiscoveryRequest/DiscoveryResponse provides sufficient information to recover + * the multiplexed singleton APIs at the Envoy instance and management server. + */ +export interface AggregatedDiscoveryServiceClient extends grpc.Client { + DeltaAggregatedResources(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_service_discovery_v3_DeltaDiscoveryRequest, _envoy_service_discovery_v3_DeltaDiscoveryResponse__Output>; + DeltaAggregatedResources(options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_service_discovery_v3_DeltaDiscoveryRequest, _envoy_service_discovery_v3_DeltaDiscoveryResponse__Output>; + deltaAggregatedResources(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_service_discovery_v3_DeltaDiscoveryRequest, _envoy_service_discovery_v3_DeltaDiscoveryResponse__Output>; + deltaAggregatedResources(options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_service_discovery_v3_DeltaDiscoveryRequest, _envoy_service_discovery_v3_DeltaDiscoveryResponse__Output>; + + /** + * This is a gRPC-only API. + */ + StreamAggregatedResources(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_service_discovery_v3_DiscoveryRequest, _envoy_service_discovery_v3_DiscoveryResponse__Output>; + StreamAggregatedResources(options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_service_discovery_v3_DiscoveryRequest, _envoy_service_discovery_v3_DiscoveryResponse__Output>; + /** + * This is a gRPC-only API. + */ + streamAggregatedResources(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_service_discovery_v3_DiscoveryRequest, _envoy_service_discovery_v3_DiscoveryResponse__Output>; + streamAggregatedResources(options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_service_discovery_v3_DiscoveryRequest, _envoy_service_discovery_v3_DiscoveryResponse__Output>; + +} + +/** + * See https://github.com/lyft/envoy-api#apis for a description of the role of + * ADS and how it is intended to be used by a management server. ADS requests + * have the same structure as their singleton xDS counterparts, but can + * multiplex many resource types on a single stream. The type_url in the + * DiscoveryRequest/DiscoveryResponse provides sufficient information to recover + * the multiplexed singleton APIs at the Envoy instance and management server. + */ +export interface AggregatedDiscoveryServiceHandlers extends grpc.UntypedServiceImplementation { + DeltaAggregatedResources: grpc.handleBidiStreamingCall<_envoy_service_discovery_v3_DeltaDiscoveryRequest__Output, _envoy_service_discovery_v3_DeltaDiscoveryResponse>; + + /** + * This is a gRPC-only API. + */ + StreamAggregatedResources: grpc.handleBidiStreamingCall<_envoy_service_discovery_v3_DiscoveryRequest__Output, _envoy_service_discovery_v3_DiscoveryResponse>; + +} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DeltaDiscoveryRequest.ts b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DeltaDiscoveryRequest.ts new file mode 100644 index 000000000..bcf2de4e2 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DeltaDiscoveryRequest.ts @@ -0,0 +1,206 @@ +// Original file: deps/envoy-api/envoy/service/discovery/v3/discovery.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 { Status as _google_rpc_Status, Status__Output as _google_rpc_Status__Output } from '../../../../google/rpc/Status'; + +/** + * DeltaDiscoveryRequest and DeltaDiscoveryResponse are used in a new gRPC + * endpoint for Delta xDS. + * + * With Delta xDS, the DeltaDiscoveryResponses do not need to include a full + * snapshot of the tracked resources. Instead, DeltaDiscoveryResponses are a + * diff to the state of a xDS client. + * In Delta XDS there are per-resource versions, which allow tracking state at + * the resource granularity. + * An xDS Delta session is always in the context of a gRPC bidirectional + * stream. This allows the xDS server to keep track of the state of xDS clients + * connected to it. + * + * In Delta xDS the nonce field is required and used to pair + * DeltaDiscoveryResponse to a DeltaDiscoveryRequest ACK or NACK. + * Optionally, a response message level system_version_info is present for + * debugging purposes only. + * + * DeltaDiscoveryRequest plays two independent roles. Any DeltaDiscoveryRequest + * can be either or both of: [1] informing the server of what resources the + * client has gained/lost interest in (using resource_names_subscribe and + * resource_names_unsubscribe), or [2] (N)ACKing an earlier resource update from + * the server (using response_nonce, with presence of error_detail making it a NACK). + * Additionally, the first message (for a given type_url) of a reconnected gRPC stream + * has a third role: informing the server of the resources (and their versions) + * that the client already possesses, using the initial_resource_versions field. + * + * As with state-of-the-world, when multiple resource types are multiplexed (ADS), + * all requests/acknowledgments/updates are logically walled off by type_url: + * a Cluster ACK exists in a completely separate world from a prior Route NACK. + * In particular, initial_resource_versions being sent at the "start" of every + * gRPC stream actually entails a message for each type_url, each with its own + * initial_resource_versions. + * [#next-free-field: 8] + */ +export interface DeltaDiscoveryRequest { + /** + * The node making the request. + */ + 'node'?: (_envoy_config_core_v3_Node); + /** + * Type of the resource that is being requested, e.g. + * "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment". This does not need to be set if + * resources are only referenced via *xds_resource_subscribe* and + * *xds_resources_unsubscribe*. + */ + 'type_url'?: (string); + /** + * DeltaDiscoveryRequests allow the client to add or remove individual + * resources to the set of tracked resources in the context of a stream. + * All resource names in the resource_names_subscribe list are added to the + * set of tracked resources and all resource names in the resource_names_unsubscribe + * list are removed from the set of tracked resources. + * + * *Unlike* state-of-the-world xDS, an empty resource_names_subscribe or + * resource_names_unsubscribe list simply means that no resources are to be + * added or removed to the resource list. + * *Like* state-of-the-world xDS, the server must send updates for all tracked + * resources, but can also send updates for resources the client has not subscribed to. + * + * NOTE: the server must respond with all resources listed in resource_names_subscribe, + * even if it believes the client has the most recent version of them. The reason: + * the client may have dropped them, but then regained interest before it had a chance + * to send the unsubscribe message. See DeltaSubscriptionStateTest.RemoveThenAdd. + * + * These two fields can be set in any DeltaDiscoveryRequest, including ACKs + * and initial_resource_versions. + * + * A list of Resource names to add to the list of tracked resources. + */ + 'resource_names_subscribe'?: (string)[]; + /** + * A list of Resource names to remove from the list of tracked resources. + */ + 'resource_names_unsubscribe'?: (string)[]; + /** + * Informs the server of the versions of the resources the xDS client knows of, to enable the + * client to continue the same logical xDS session even in the face of gRPC stream reconnection. + * It will not be populated: [1] in the very first stream of a session, since the client will + * not yet have any resources, [2] in any message after the first in a stream (for a given + * type_url), since the server will already be correctly tracking the client's state. + * (In ADS, the first message *of each type_url* of a reconnected stream populates this map.) + * The map's keys are names of xDS resources known to the xDS client. + * The map's values are opaque resource versions. + */ + 'initial_resource_versions'?: ({[key: string]: string}); + /** + * When the DeltaDiscoveryRequest is a ACK or NACK message in response + * to a previous DeltaDiscoveryResponse, the response_nonce must be the + * nonce in the DeltaDiscoveryResponse. + * Otherwise (unlike in DiscoveryRequest) response_nonce must be omitted. + */ + 'response_nonce'?: (string); + /** + * This is populated when the previous :ref:`DiscoveryResponse ` + * failed to update configuration. The *message* field in *error_details* + * provides the Envoy internal exception related to the failure. + */ + 'error_detail'?: (_google_rpc_Status); +} + +/** + * DeltaDiscoveryRequest and DeltaDiscoveryResponse are used in a new gRPC + * endpoint for Delta xDS. + * + * With Delta xDS, the DeltaDiscoveryResponses do not need to include a full + * snapshot of the tracked resources. Instead, DeltaDiscoveryResponses are a + * diff to the state of a xDS client. + * In Delta XDS there are per-resource versions, which allow tracking state at + * the resource granularity. + * An xDS Delta session is always in the context of a gRPC bidirectional + * stream. This allows the xDS server to keep track of the state of xDS clients + * connected to it. + * + * In Delta xDS the nonce field is required and used to pair + * DeltaDiscoveryResponse to a DeltaDiscoveryRequest ACK or NACK. + * Optionally, a response message level system_version_info is present for + * debugging purposes only. + * + * DeltaDiscoveryRequest plays two independent roles. Any DeltaDiscoveryRequest + * can be either or both of: [1] informing the server of what resources the + * client has gained/lost interest in (using resource_names_subscribe and + * resource_names_unsubscribe), or [2] (N)ACKing an earlier resource update from + * the server (using response_nonce, with presence of error_detail making it a NACK). + * Additionally, the first message (for a given type_url) of a reconnected gRPC stream + * has a third role: informing the server of the resources (and their versions) + * that the client already possesses, using the initial_resource_versions field. + * + * As with state-of-the-world, when multiple resource types are multiplexed (ADS), + * all requests/acknowledgments/updates are logically walled off by type_url: + * a Cluster ACK exists in a completely separate world from a prior Route NACK. + * In particular, initial_resource_versions being sent at the "start" of every + * gRPC stream actually entails a message for each type_url, each with its own + * initial_resource_versions. + * [#next-free-field: 8] + */ +export interface DeltaDiscoveryRequest__Output { + /** + * The node making the request. + */ + 'node'?: (_envoy_config_core_v3_Node__Output); + /** + * Type of the resource that is being requested, e.g. + * "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment". This does not need to be set if + * resources are only referenced via *xds_resource_subscribe* and + * *xds_resources_unsubscribe*. + */ + 'type_url': (string); + /** + * DeltaDiscoveryRequests allow the client to add or remove individual + * resources to the set of tracked resources in the context of a stream. + * All resource names in the resource_names_subscribe list are added to the + * set of tracked resources and all resource names in the resource_names_unsubscribe + * list are removed from the set of tracked resources. + * + * *Unlike* state-of-the-world xDS, an empty resource_names_subscribe or + * resource_names_unsubscribe list simply means that no resources are to be + * added or removed to the resource list. + * *Like* state-of-the-world xDS, the server must send updates for all tracked + * resources, but can also send updates for resources the client has not subscribed to. + * + * NOTE: the server must respond with all resources listed in resource_names_subscribe, + * even if it believes the client has the most recent version of them. The reason: + * the client may have dropped them, but then regained interest before it had a chance + * to send the unsubscribe message. See DeltaSubscriptionStateTest.RemoveThenAdd. + * + * These two fields can be set in any DeltaDiscoveryRequest, including ACKs + * and initial_resource_versions. + * + * A list of Resource names to add to the list of tracked resources. + */ + 'resource_names_subscribe': (string)[]; + /** + * A list of Resource names to remove from the list of tracked resources. + */ + 'resource_names_unsubscribe': (string)[]; + /** + * Informs the server of the versions of the resources the xDS client knows of, to enable the + * client to continue the same logical xDS session even in the face of gRPC stream reconnection. + * It will not be populated: [1] in the very first stream of a session, since the client will + * not yet have any resources, [2] in any message after the first in a stream (for a given + * type_url), since the server will already be correctly tracking the client's state. + * (In ADS, the first message *of each type_url* of a reconnected stream populates this map.) + * The map's keys are names of xDS resources known to the xDS client. + * The map's values are opaque resource versions. + */ + 'initial_resource_versions': ({[key: string]: string}); + /** + * When the DeltaDiscoveryRequest is a ACK or NACK message in response + * to a previous DeltaDiscoveryResponse, the response_nonce must be the + * nonce in the DeltaDiscoveryResponse. + * Otherwise (unlike in DiscoveryRequest) response_nonce must be omitted. + */ + 'response_nonce': (string); + /** + * This is populated when the previous :ref:`DiscoveryResponse ` + * failed to update configuration. The *message* field in *error_details* + * provides the Envoy internal exception related to the failure. + */ + 'error_detail'?: (_google_rpc_Status__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DeltaDiscoveryResponse.ts b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DeltaDiscoveryResponse.ts new file mode 100644 index 000000000..c22690cd9 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DeltaDiscoveryResponse.ts @@ -0,0 +1,74 @@ +// Original file: deps/envoy-api/envoy/service/discovery/v3/discovery.proto + +import type { Resource as _envoy_service_discovery_v3_Resource, Resource__Output as _envoy_service_discovery_v3_Resource__Output } from '../../../../envoy/service/discovery/v3/Resource'; +import type { ControlPlane as _envoy_config_core_v3_ControlPlane, ControlPlane__Output as _envoy_config_core_v3_ControlPlane__Output } from '../../../../envoy/config/core/v3/ControlPlane'; + +/** + * [#next-free-field: 8] + */ +export interface DeltaDiscoveryResponse { + /** + * The version of the response data (used for debugging). + */ + 'system_version_info'?: (string); + /** + * The response resources. These are typed resources, whose types must match + * the type_url field. + */ + 'resources'?: (_envoy_service_discovery_v3_Resource)[]; + /** + * Type URL for resources. Identifies the xDS API when muxing over ADS. + * Must be consistent with the type_url in the Any within 'resources' if 'resources' is non-empty. + */ + 'type_url'?: (string); + /** + * The nonce provides a way for DeltaDiscoveryRequests to uniquely + * reference a DeltaDiscoveryResponse when (N)ACKing. The nonce is required. + */ + 'nonce'?: (string); + /** + * Resources names of resources that have be deleted and to be removed from the xDS Client. + * Removed resources for missing resources can be ignored. + */ + 'removed_resources'?: (string)[]; + /** + * [#not-implemented-hide:] + * The control plane instance that sent the response. + */ + 'control_plane'?: (_envoy_config_core_v3_ControlPlane); +} + +/** + * [#next-free-field: 8] + */ +export interface DeltaDiscoveryResponse__Output { + /** + * The version of the response data (used for debugging). + */ + 'system_version_info': (string); + /** + * The response resources. These are typed resources, whose types must match + * the type_url field. + */ + 'resources': (_envoy_service_discovery_v3_Resource__Output)[]; + /** + * Type URL for resources. Identifies the xDS API when muxing over ADS. + * Must be consistent with the type_url in the Any within 'resources' if 'resources' is non-empty. + */ + 'type_url': (string); + /** + * The nonce provides a way for DeltaDiscoveryRequests to uniquely + * reference a DeltaDiscoveryResponse when (N)ACKing. The nonce is required. + */ + 'nonce': (string); + /** + * Resources names of resources that have be deleted and to be removed from the xDS Client. + * Removed resources for missing resources can be ignored. + */ + 'removed_resources': (string)[]; + /** + * [#not-implemented-hide:] + * The control plane instance that sent the response. + */ + 'control_plane'?: (_envoy_config_core_v3_ControlPlane__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DiscoveryRequest.ts b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DiscoveryRequest.ts new file mode 100644 index 000000000..2b23ee869 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DiscoveryRequest.ts @@ -0,0 +1,110 @@ +// Original file: deps/envoy-api/envoy/service/discovery/v3/discovery.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 { Status as _google_rpc_Status, Status__Output as _google_rpc_Status__Output } from '../../../../google/rpc/Status'; + +/** + * A DiscoveryRequest requests a set of versioned resources of the same type for + * a given Envoy node on some API. + * [#next-free-field: 7] + */ +export interface DiscoveryRequest { + /** + * The version_info provided in the request messages will be the version_info + * received with the most recent successfully processed response or empty on + * the first request. It is expected that no new request is sent after a + * response is received until the Envoy instance is ready to ACK/NACK the new + * configuration. ACK/NACK takes place by returning the new API config version + * as applied or the previous API config version respectively. Each type_url + * (see below) has an independent version associated with it. + */ + 'version_info'?: (string); + /** + * The node making the request. + */ + 'node'?: (_envoy_config_core_v3_Node); + /** + * List of resources to subscribe to, e.g. list of cluster names or a route + * configuration name. If this is empty, all resources for the API are + * returned. LDS/CDS may have empty resource_names, which will cause all + * resources for the Envoy instance to be returned. The LDS and CDS responses + * will then imply a number of resources that need to be fetched via EDS/RDS, + * which will be explicitly enumerated in resource_names. + */ + 'resource_names'?: (string)[]; + /** + * Type of the resource that is being requested, e.g. + * "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment". This is implicit + * in requests made via singleton xDS APIs such as CDS, LDS, etc. but is + * required for ADS. + */ + 'type_url'?: (string); + /** + * nonce corresponding to DiscoveryResponse being ACK/NACKed. See above + * discussion on version_info and the DiscoveryResponse nonce comment. This + * may be empty only if 1) this is a non-persistent-stream xDS such as HTTP, + * or 2) the client has not yet accepted an update in this xDS stream (unlike + * delta, where it is populated only for new explicit ACKs). + */ + 'response_nonce'?: (string); + /** + * This is populated when the previous :ref:`DiscoveryResponse ` + * failed to update configuration. The *message* field in *error_details* provides the Envoy + * internal exception related to the failure. It is only intended for consumption during manual + * debugging, the string provided is not guaranteed to be stable across Envoy versions. + */ + 'error_detail'?: (_google_rpc_Status); +} + +/** + * A DiscoveryRequest requests a set of versioned resources of the same type for + * a given Envoy node on some API. + * [#next-free-field: 7] + */ +export interface DiscoveryRequest__Output { + /** + * The version_info provided in the request messages will be the version_info + * received with the most recent successfully processed response or empty on + * the first request. It is expected that no new request is sent after a + * response is received until the Envoy instance is ready to ACK/NACK the new + * configuration. ACK/NACK takes place by returning the new API config version + * as applied or the previous API config version respectively. Each type_url + * (see below) has an independent version associated with it. + */ + 'version_info': (string); + /** + * The node making the request. + */ + 'node'?: (_envoy_config_core_v3_Node__Output); + /** + * List of resources to subscribe to, e.g. list of cluster names or a route + * configuration name. If this is empty, all resources for the API are + * returned. LDS/CDS may have empty resource_names, which will cause all + * resources for the Envoy instance to be returned. The LDS and CDS responses + * will then imply a number of resources that need to be fetched via EDS/RDS, + * which will be explicitly enumerated in resource_names. + */ + 'resource_names': (string)[]; + /** + * Type of the resource that is being requested, e.g. + * "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment". This is implicit + * in requests made via singleton xDS APIs such as CDS, LDS, etc. but is + * required for ADS. + */ + 'type_url': (string); + /** + * nonce corresponding to DiscoveryResponse being ACK/NACKed. See above + * discussion on version_info and the DiscoveryResponse nonce comment. This + * may be empty only if 1) this is a non-persistent-stream xDS such as HTTP, + * or 2) the client has not yet accepted an update in this xDS stream (unlike + * delta, where it is populated only for new explicit ACKs). + */ + 'response_nonce': (string); + /** + * This is populated when the previous :ref:`DiscoveryResponse ` + * failed to update configuration. The *message* field in *error_details* provides the Envoy + * internal exception related to the failure. It is only intended for consumption during manual + * debugging, the string provided is not guaranteed to be stable across Envoy versions. + */ + 'error_detail'?: (_google_rpc_Status__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DiscoveryResponse.ts b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DiscoveryResponse.ts new file mode 100644 index 000000000..f69944b80 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DiscoveryResponse.ts @@ -0,0 +1,106 @@ +// Original file: deps/envoy-api/envoy/service/discovery/v3/discovery.proto + +import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; +import type { ControlPlane as _envoy_config_core_v3_ControlPlane, ControlPlane__Output as _envoy_config_core_v3_ControlPlane__Output } from '../../../../envoy/config/core/v3/ControlPlane'; + +/** + * [#next-free-field: 7] + */ +export interface DiscoveryResponse { + /** + * The version of the response data. + */ + 'version_info'?: (string); + /** + * The response resources. These resources are typed and depend on the API being called. + */ + 'resources'?: (_google_protobuf_Any)[]; + /** + * [#not-implemented-hide:] + * Canary is used to support two Envoy command line flags: + * + * * --terminate-on-canary-transition-failure. When set, Envoy is able to + * terminate if it detects that configuration is stuck at canary. Consider + * this example sequence of updates: + * - Management server applies a canary config successfully. + * - Management server rolls back to a production config. + * - Envoy rejects the new production config. + * Since there is no sensible way to continue receiving configuration + * updates, Envoy will then terminate and apply production config from a + * clean slate. + * * --dry-run-canary. When set, a canary response will never be applied, only + * validated via a dry run. + */ + 'canary'?: (boolean); + /** + * Type URL for resources. Identifies the xDS API when muxing over ADS. + * Must be consistent with the type_url in the 'resources' repeated Any (if non-empty). + */ + 'type_url'?: (string); + /** + * For gRPC based subscriptions, the nonce provides a way to explicitly ack a + * specific DiscoveryResponse in a following DiscoveryRequest. Additional + * messages may have been sent by Envoy to the management server for the + * previous version on the stream prior to this DiscoveryResponse, that were + * unprocessed at response send time. The nonce allows the management server + * to ignore any further DiscoveryRequests for the previous version until a + * DiscoveryRequest bearing the nonce. The nonce is optional and is not + * required for non-stream based xDS implementations. + */ + 'nonce'?: (string); + /** + * The control plane instance that sent the response. + */ + 'control_plane'?: (_envoy_config_core_v3_ControlPlane); +} + +/** + * [#next-free-field: 7] + */ +export interface DiscoveryResponse__Output { + /** + * The version of the response data. + */ + 'version_info': (string); + /** + * The response resources. These resources are typed and depend on the API being called. + */ + 'resources': (_google_protobuf_Any__Output)[]; + /** + * [#not-implemented-hide:] + * Canary is used to support two Envoy command line flags: + * + * * --terminate-on-canary-transition-failure. When set, Envoy is able to + * terminate if it detects that configuration is stuck at canary. Consider + * this example sequence of updates: + * - Management server applies a canary config successfully. + * - Management server rolls back to a production config. + * - Envoy rejects the new production config. + * Since there is no sensible way to continue receiving configuration + * updates, Envoy will then terminate and apply production config from a + * clean slate. + * * --dry-run-canary. When set, a canary response will never be applied, only + * validated via a dry run. + */ + 'canary': (boolean); + /** + * Type URL for resources. Identifies the xDS API when muxing over ADS. + * Must be consistent with the type_url in the 'resources' repeated Any (if non-empty). + */ + 'type_url': (string); + /** + * For gRPC based subscriptions, the nonce provides a way to explicitly ack a + * specific DiscoveryResponse in a following DiscoveryRequest. Additional + * messages may have been sent by Envoy to the management server for the + * previous version on the stream prior to this DiscoveryResponse, that were + * unprocessed at response send time. The nonce allows the management server + * to ignore any further DiscoveryRequests for the previous version until a + * DiscoveryRequest bearing the nonce. The nonce is optional and is not + * required for non-stream based xDS implementations. + */ + 'nonce': (string); + /** + * The control plane instance that sent the response. + */ + 'control_plane'?: (_envoy_config_core_v3_ControlPlane__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/Resource.ts b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/Resource.ts new file mode 100644 index 000000000..27a70c97c --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/Resource.ts @@ -0,0 +1,118 @@ +// Original file: deps/envoy-api/envoy/service/discovery/v3/discovery.proto + +import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; +import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; + +/** + * Cache control properties for the resource. + * [#not-implemented-hide:] + */ +export interface _envoy_service_discovery_v3_Resource_CacheControl { + /** + * If true, xDS proxies may not cache this resource. + * Note that this does not apply to clients other than xDS proxies, which must cache resources + * for their own use, regardless of the value of this field. + */ + 'do_not_cache'?: (boolean); +} + +/** + * Cache control properties for the resource. + * [#not-implemented-hide:] + */ +export interface _envoy_service_discovery_v3_Resource_CacheControl__Output { + /** + * If true, xDS proxies may not cache this resource. + * Note that this does not apply to clients other than xDS proxies, which must cache resources + * for their own use, regardless of the value of this field. + */ + 'do_not_cache': (boolean); +} + +/** + * [#next-free-field: 8] + */ +export interface Resource { + /** + * The resource level version. It allows xDS to track the state of individual + * resources. + */ + 'version'?: (string); + /** + * The resource being tracked. + */ + 'resource'?: (_google_protobuf_Any); + /** + * The resource's name, to distinguish it from others of the same type of resource. + */ + 'name'?: (string); + /** + * The aliases are a list of other names that this resource can go by. + */ + 'aliases'?: (string)[]; + /** + * Time-to-live value for the resource. For each resource, a timer is started. The timer is + * reset each time the resource is received with a new TTL. If the resource is received with + * no TTL set, the timer is removed for the resource. Upon expiration of the timer, the + * configuration for the resource will be removed. + * + * The TTL can be refreshed or changed by sending a response that doesn't change the resource + * version. In this case the resource field does not need to be populated, which allows for + * light-weight "heartbeat" updates to keep a resource with a TTL alive. + * + * The TTL feature is meant to support configurations that should be removed in the event of + * a management server failure. For example, the feature may be used for fault injection + * testing where the fault injection should be terminated in the event that Envoy loses contact + * with the management server. + */ + 'ttl'?: (_google_protobuf_Duration); + /** + * Cache control properties for the resource. + * [#not-implemented-hide:] + */ + 'cache_control'?: (_envoy_service_discovery_v3_Resource_CacheControl); +} + +/** + * [#next-free-field: 8] + */ +export interface Resource__Output { + /** + * The resource level version. It allows xDS to track the state of individual + * resources. + */ + 'version': (string); + /** + * The resource being tracked. + */ + 'resource'?: (_google_protobuf_Any__Output); + /** + * The resource's name, to distinguish it from others of the same type of resource. + */ + 'name': (string); + /** + * The aliases are a list of other names that this resource can go by. + */ + 'aliases': (string)[]; + /** + * Time-to-live value for the resource. For each resource, a timer is started. The timer is + * reset each time the resource is received with a new TTL. If the resource is received with + * no TTL set, the timer is removed for the resource. Upon expiration of the timer, the + * configuration for the resource will be removed. + * + * The TTL can be refreshed or changed by sending a response that doesn't change the resource + * version. In this case the resource field does not need to be populated, which allows for + * light-weight "heartbeat" updates to keep a resource with a TTL alive. + * + * The TTL feature is meant to support configurations that should be removed in the event of + * a management server failure. For example, the feature may be used for fault injection + * testing where the fault injection should be terminated in the event that Envoy loses contact + * with the management server. + */ + 'ttl'?: (_google_protobuf_Duration__Output); + /** + * Cache control properties for the resource. + * [#not-implemented-hide:] + */ + 'cache_control'?: (_envoy_service_discovery_v3_Resource_CacheControl__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadReportingService.ts b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadReportingService.ts new file mode 100644 index 000000000..24a9de55e --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadReportingService.ts @@ -0,0 +1,108 @@ +// Original file: deps/envoy-api/envoy/service/load_stats/v3/lrs.proto + +import type * as grpc from '@grpc/grpc-js' +import type { LoadStatsRequest as _envoy_service_load_stats_v3_LoadStatsRequest, LoadStatsRequest__Output as _envoy_service_load_stats_v3_LoadStatsRequest__Output } from '../../../../envoy/service/load_stats/v3/LoadStatsRequest'; +import type { LoadStatsResponse as _envoy_service_load_stats_v3_LoadStatsResponse, LoadStatsResponse__Output as _envoy_service_load_stats_v3_LoadStatsResponse__Output } from '../../../../envoy/service/load_stats/v3/LoadStatsResponse'; + +export interface LoadReportingServiceClient extends grpc.Client { + /** + * Advanced API to allow for multi-dimensional load balancing by remote + * server. For receiving LB assignments, the steps are: + * 1, The management server is configured with per cluster/zone/load metric + * capacity configuration. The capacity configuration definition is + * outside of the scope of this document. + * 2. Envoy issues a standard {Stream,Fetch}Endpoints request for the clusters + * to balance. + * + * Independently, Envoy will initiate a StreamLoadStats bidi stream with a + * management server: + * 1. Once a connection establishes, the management server publishes a + * LoadStatsResponse for all clusters it is interested in learning load + * stats about. + * 2. For each cluster, Envoy load balances incoming traffic to upstream hosts + * based on per-zone weights and/or per-instance weights (if specified) + * based on intra-zone LbPolicy. This information comes from the above + * {Stream,Fetch}Endpoints. + * 3. When upstream hosts reply, they optionally add header with ASCII representation of EndpointLoadMetricStats. + * 4. Envoy aggregates load reports over the period of time given to it in + * LoadStatsResponse.load_reporting_interval. This includes aggregation + * stats Envoy maintains by itself (total_requests, rpc_errors etc.) as + * well as load metrics from upstream hosts. + * 5. When the timer of load_reporting_interval expires, Envoy sends new + * LoadStatsRequest filled with load reports for each cluster. + * 6. The management server uses the load reports from all reported Envoys + * from around the world, computes global assignment and prepares traffic + * assignment destined for each zone Envoys are located in. Goto 2. + */ + StreamLoadStats(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_service_load_stats_v3_LoadStatsRequest, _envoy_service_load_stats_v3_LoadStatsResponse__Output>; + StreamLoadStats(options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_service_load_stats_v3_LoadStatsRequest, _envoy_service_load_stats_v3_LoadStatsResponse__Output>; + /** + * Advanced API to allow for multi-dimensional load balancing by remote + * server. For receiving LB assignments, the steps are: + * 1, The management server is configured with per cluster/zone/load metric + * capacity configuration. The capacity configuration definition is + * outside of the scope of this document. + * 2. Envoy issues a standard {Stream,Fetch}Endpoints request for the clusters + * to balance. + * + * Independently, Envoy will initiate a StreamLoadStats bidi stream with a + * management server: + * 1. Once a connection establishes, the management server publishes a + * LoadStatsResponse for all clusters it is interested in learning load + * stats about. + * 2. For each cluster, Envoy load balances incoming traffic to upstream hosts + * based on per-zone weights and/or per-instance weights (if specified) + * based on intra-zone LbPolicy. This information comes from the above + * {Stream,Fetch}Endpoints. + * 3. When upstream hosts reply, they optionally add header with ASCII representation of EndpointLoadMetricStats. + * 4. Envoy aggregates load reports over the period of time given to it in + * LoadStatsResponse.load_reporting_interval. This includes aggregation + * stats Envoy maintains by itself (total_requests, rpc_errors etc.) as + * well as load metrics from upstream hosts. + * 5. When the timer of load_reporting_interval expires, Envoy sends new + * LoadStatsRequest filled with load reports for each cluster. + * 6. The management server uses the load reports from all reported Envoys + * from around the world, computes global assignment and prepares traffic + * assignment destined for each zone Envoys are located in. Goto 2. + */ + streamLoadStats(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_service_load_stats_v3_LoadStatsRequest, _envoy_service_load_stats_v3_LoadStatsResponse__Output>; + streamLoadStats(options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_service_load_stats_v3_LoadStatsRequest, _envoy_service_load_stats_v3_LoadStatsResponse__Output>; + +} + +export interface LoadReportingServiceHandlers extends grpc.UntypedServiceImplementation { + /** + * Advanced API to allow for multi-dimensional load balancing by remote + * server. For receiving LB assignments, the steps are: + * 1, The management server is configured with per cluster/zone/load metric + * capacity configuration. The capacity configuration definition is + * outside of the scope of this document. + * 2. Envoy issues a standard {Stream,Fetch}Endpoints request for the clusters + * to balance. + * + * Independently, Envoy will initiate a StreamLoadStats bidi stream with a + * management server: + * 1. Once a connection establishes, the management server publishes a + * LoadStatsResponse for all clusters it is interested in learning load + * stats about. + * 2. For each cluster, Envoy load balances incoming traffic to upstream hosts + * based on per-zone weights and/or per-instance weights (if specified) + * based on intra-zone LbPolicy. This information comes from the above + * {Stream,Fetch}Endpoints. + * 3. When upstream hosts reply, they optionally add header with ASCII representation of EndpointLoadMetricStats. + * 4. Envoy aggregates load reports over the period of time given to it in + * LoadStatsResponse.load_reporting_interval. This includes aggregation + * stats Envoy maintains by itself (total_requests, rpc_errors etc.) as + * well as load metrics from upstream hosts. + * 5. When the timer of load_reporting_interval expires, Envoy sends new + * LoadStatsRequest filled with load reports for each cluster. + * 6. The management server uses the load reports from all reported Envoys + * from around the world, computes global assignment and prepares traffic + * assignment destined for each zone Envoys are located in. Goto 2. + */ + StreamLoadStats: grpc.handleBidiStreamingCall<_envoy_service_load_stats_v3_LoadStatsRequest__Output, _envoy_service_load_stats_v3_LoadStatsResponse>; + +} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadStatsRequest.ts b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadStatsRequest.ts new file mode 100644 index 000000000..6f0e19525 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadStatsRequest.ts @@ -0,0 +1,32 @@ +// Original file: deps/envoy-api/envoy/service/load_stats/v3/lrs.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 { ClusterStats as _envoy_config_endpoint_v3_ClusterStats, ClusterStats__Output as _envoy_config_endpoint_v3_ClusterStats__Output } from '../../../../envoy/config/endpoint/v3/ClusterStats'; + +/** + * A load report Envoy sends to the management server. + */ +export interface LoadStatsRequest { + /** + * Node identifier for Envoy instance. + */ + 'node'?: (_envoy_config_core_v3_Node); + /** + * A list of load stats to report. + */ + 'cluster_stats'?: (_envoy_config_endpoint_v3_ClusterStats)[]; +} + +/** + * A load report Envoy sends to the management server. + */ +export interface LoadStatsRequest__Output { + /** + * Node identifier for Envoy instance. + */ + 'node'?: (_envoy_config_core_v3_Node__Output); + /** + * A list of load stats to report. + */ + 'cluster_stats': (_envoy_config_endpoint_v3_ClusterStats__Output)[]; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadStatsResponse.ts b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadStatsResponse.ts new file mode 100644 index 000000000..51f017474 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadStatsResponse.ts @@ -0,0 +1,71 @@ +// Original file: deps/envoy-api/envoy/service/load_stats/v3/lrs.proto + +import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; + +/** + * The management server sends envoy a LoadStatsResponse with all clusters it + * is interested in learning load stats about. + */ +export interface LoadStatsResponse { + /** + * Clusters to report stats for. + * Not populated if *send_all_clusters* is true. + */ + 'clusters'?: (string)[]; + /** + * The minimum interval of time to collect stats over. This is only a minimum for two reasons: + * + * 1. There may be some delay from when the timer fires until stats sampling occurs. + * 2. For clusters that were already feature in the previous *LoadStatsResponse*, any traffic + * that is observed in between the corresponding previous *LoadStatsRequest* and this + * *LoadStatsResponse* will also be accumulated and billed to the cluster. This avoids a period + * of inobservability that might otherwise exists between the messages. New clusters are not + * subject to this consideration. + */ + 'load_reporting_interval'?: (_google_protobuf_Duration); + /** + * Set to *true* if the management server supports endpoint granularity + * report. + */ + 'report_endpoint_granularity'?: (boolean); + /** + * If true, the client should send all clusters it knows about. + * Only clients that advertise the "envoy.lrs.supports_send_all_clusters" capability in their + * :ref:`client_features` field will honor this field. + */ + 'send_all_clusters'?: (boolean); +} + +/** + * The management server sends envoy a LoadStatsResponse with all clusters it + * is interested in learning load stats about. + */ +export interface LoadStatsResponse__Output { + /** + * Clusters to report stats for. + * Not populated if *send_all_clusters* is true. + */ + 'clusters': (string)[]; + /** + * The minimum interval of time to collect stats over. This is only a minimum for two reasons: + * + * 1. There may be some delay from when the timer fires until stats sampling occurs. + * 2. For clusters that were already feature in the previous *LoadStatsResponse*, any traffic + * that is observed in between the corresponding previous *LoadStatsRequest* and this + * *LoadStatsResponse* will also be accumulated and billed to the cluster. This avoids a period + * of inobservability that might otherwise exists between the messages. New clusters are not + * subject to this consideration. + */ + 'load_reporting_interval'?: (_google_protobuf_Duration__Output); + /** + * Set to *true* if the management server supports endpoint granularity + * report. + */ + 'report_endpoint_granularity': (boolean); + /** + * If true, the client should send all clusters it knows about. + * Only clients that advertise the "envoy.lrs.supports_send_all_clusters" capability in their + * :ref:`client_features` field will honor this field. + */ + 'send_all_clusters': (boolean); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/type/Percent.ts b/packages/grpc-js-xds/src/generated/envoy/type/Percent.ts index f63553acd..364419994 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/Percent.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/Percent.ts @@ -12,5 +12,5 @@ export interface Percent { * Identifies a percentage, in the range [0.0, 100.0]. */ export interface Percent__Output { - 'value': (number | string); + 'value': (number); } diff --git a/packages/grpc-js-xds/src/generated/envoy/type/matcher/ListStringMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/type/matcher/ListStringMatcher.ts deleted file mode 100644 index 42bde031b..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/type/matcher/ListStringMatcher.ts +++ /dev/null @@ -1,17 +0,0 @@ -// Original file: deps/envoy-api/envoy/type/matcher/string.proto - -import type { StringMatcher as _envoy_type_matcher_StringMatcher, StringMatcher__Output as _envoy_type_matcher_StringMatcher__Output } from '../../../envoy/type/matcher/StringMatcher'; - -/** - * Specifies a list of ways to match a string. - */ -export interface ListStringMatcher { - 'patterns'?: (_envoy_type_matcher_StringMatcher)[]; -} - -/** - * Specifies a list of ways to match a string. - */ -export interface ListStringMatcher__Output { - 'patterns': (_envoy_type_matcher_StringMatcher__Output)[]; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/DoubleMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/DoubleMatcher.ts new file mode 100644 index 000000000..e91a4898e --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/DoubleMatcher.ts @@ -0,0 +1,35 @@ +// Original file: deps/envoy-api/envoy/type/matcher/v3/number.proto + +import type { DoubleRange as _envoy_type_v3_DoubleRange, DoubleRange__Output as _envoy_type_v3_DoubleRange__Output } from '../../../../envoy/type/v3/DoubleRange'; + +/** + * Specifies the way to match a double value. + */ +export interface DoubleMatcher { + /** + * If specified, the input double value must be in the range specified here. + * Note: The range is using half-open interval semantics [start, end). + */ + 'range'?: (_envoy_type_v3_DoubleRange); + /** + * If specified, the input double value must be equal to the value specified here. + */ + 'exact'?: (number | string); + 'match_pattern'?: "range"|"exact"; +} + +/** + * Specifies the way to match a double value. + */ +export interface DoubleMatcher__Output { + /** + * If specified, the input double value must be in the range specified here. + * Note: The range is using half-open interval semantics [start, end). + */ + 'range'?: (_envoy_type_v3_DoubleRange__Output); + /** + * If specified, the input double value must be equal to the value specified here. + */ + 'exact'?: (number); + 'match_pattern': "range"|"exact"; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/ListMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/ListMatcher.ts new file mode 100644 index 000000000..c32b72a39 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/ListMatcher.ts @@ -0,0 +1,25 @@ +// Original file: deps/envoy-api/envoy/type/matcher/v3/value.proto + +import type { ValueMatcher as _envoy_type_matcher_v3_ValueMatcher, ValueMatcher__Output as _envoy_type_matcher_v3_ValueMatcher__Output } from '../../../../envoy/type/matcher/v3/ValueMatcher'; + +/** + * Specifies the way to match a list value. + */ +export interface ListMatcher { + /** + * If specified, at least one of the values in the list must match the value specified. + */ + 'one_of'?: (_envoy_type_matcher_v3_ValueMatcher); + 'match_pattern'?: "one_of"; +} + +/** + * Specifies the way to match a list value. + */ +export interface ListMatcher__Output { + /** + * If specified, at least one of the values in the list must match the value specified. + */ + 'one_of'?: (_envoy_type_matcher_v3_ValueMatcher__Output); + 'match_pattern': "one_of"; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/ListStringMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/ListStringMatcher.ts new file mode 100644 index 000000000..4d5062382 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/ListStringMatcher.ts @@ -0,0 +1,17 @@ +// Original file: deps/envoy-api/envoy/type/matcher/v3/string.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 list of ways to match a string. + */ +export interface ListStringMatcher { + 'patterns'?: (_envoy_type_matcher_v3_StringMatcher)[]; +} + +/** + * Specifies a list of ways to match a string. + */ +export interface ListStringMatcher__Output { + 'patterns': (_envoy_type_matcher_v3_StringMatcher__Output)[]; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/MetadataMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/MetadataMatcher.ts new file mode 100644 index 000000000..8d80408a3 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/MetadataMatcher.ts @@ -0,0 +1,65 @@ +// Original file: deps/envoy-api/envoy/type/matcher/v3/metadata.proto + +import type { ValueMatcher as _envoy_type_matcher_v3_ValueMatcher, ValueMatcher__Output as _envoy_type_matcher_v3_ValueMatcher__Output } from '../../../../envoy/type/matcher/v3/ValueMatcher'; + +/** + * Specifies the segment in a path to retrieve value from Metadata. + * Note: Currently it's not supported to retrieve a value from a list in Metadata. This means that + * if the segment key refers to a list, it has to be the last segment in a path. + */ +export interface _envoy_type_matcher_v3_MetadataMatcher_PathSegment { + /** + * If specified, use the key to retrieve the value in a Struct. + */ + 'key'?: (string); + 'segment'?: "key"; +} + +/** + * Specifies the segment in a path to retrieve value from Metadata. + * Note: Currently it's not supported to retrieve a value from a list in Metadata. This means that + * if the segment key refers to a list, it has to be the last segment in a path. + */ +export interface _envoy_type_matcher_v3_MetadataMatcher_PathSegment__Output { + /** + * If specified, use the key to retrieve the value in a Struct. + */ + 'key'?: (string); + 'segment': "key"; +} + +/** + * [#next-major-version: MetadataMatcher should use StructMatcher] + */ +export interface MetadataMatcher { + /** + * The filter name to retrieve the Struct from the Metadata. + */ + 'filter'?: (string); + /** + * The path to retrieve the Value from the Struct. + */ + 'path'?: (_envoy_type_matcher_v3_MetadataMatcher_PathSegment)[]; + /** + * The MetadataMatcher is matched if the value retrieved by path is matched to this value. + */ + 'value'?: (_envoy_type_matcher_v3_ValueMatcher); +} + +/** + * [#next-major-version: MetadataMatcher should use StructMatcher] + */ +export interface MetadataMatcher__Output { + /** + * The filter name to retrieve the Struct from the Metadata. + */ + 'filter': (string); + /** + * The path to retrieve the Value from the Struct. + */ + 'path': (_envoy_type_matcher_v3_MetadataMatcher_PathSegment__Output)[]; + /** + * The MetadataMatcher is matched if the value retrieved by path is matched to this value. + */ + 'value'?: (_envoy_type_matcher_v3_ValueMatcher__Output); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/type/matcher/RegexMatchAndSubstitute.ts b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/RegexMatchAndSubstitute.ts similarity index 89% rename from packages/grpc-js-xds/src/generated/envoy/type/matcher/RegexMatchAndSubstitute.ts rename to packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/RegexMatchAndSubstitute.ts index 17c38c7c0..4abddc655 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/matcher/RegexMatchAndSubstitute.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/RegexMatchAndSubstitute.ts @@ -1,6 +1,6 @@ -// Original file: deps/envoy-api/envoy/type/matcher/regex.proto +// Original file: deps/envoy-api/envoy/type/matcher/v3/regex.proto -import type { RegexMatcher as _envoy_type_matcher_RegexMatcher, RegexMatcher__Output as _envoy_type_matcher_RegexMatcher__Output } from '../../../envoy/type/matcher/RegexMatcher'; +import type { RegexMatcher as _envoy_type_matcher_v3_RegexMatcher, RegexMatcher__Output as _envoy_type_matcher_v3_RegexMatcher__Output } from '../../../../envoy/type/matcher/v3/RegexMatcher'; /** * Describes how to match a string and then produce a new string using a regular @@ -18,7 +18,7 @@ export interface RegexMatchAndSubstitute { * used in the pattern to extract portions of the subject string, and then * referenced in the substitution string. */ - 'pattern'?: (_envoy_type_matcher_RegexMatcher); + 'pattern'?: (_envoy_type_matcher_v3_RegexMatcher); /** * The string that should be substituted into matching portions of the * subject string during a substitution operation to produce a new string. @@ -49,7 +49,7 @@ export interface RegexMatchAndSubstitute__Output { * used in the pattern to extract portions of the subject string, and then * referenced in the substitution string. */ - 'pattern'?: (_envoy_type_matcher_RegexMatcher__Output); + 'pattern'?: (_envoy_type_matcher_v3_RegexMatcher__Output); /** * The string that should be substituted into matching portions of the * subject string during a substitution operation to produce a new string. diff --git a/packages/grpc-js-xds/src/generated/envoy/type/matcher/RegexMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/RegexMatcher.ts similarity index 57% rename from packages/grpc-js-xds/src/generated/envoy/type/matcher/RegexMatcher.ts rename to packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/RegexMatcher.ts index 8a18816b0..0e8b37f08 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/matcher/RegexMatcher.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/RegexMatcher.ts @@ -1,13 +1,23 @@ -// Original file: deps/envoy-api/envoy/type/matcher/regex.proto +// Original file: deps/envoy-api/envoy/type/matcher/v3/regex.proto -import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../google/protobuf/UInt32Value'; +import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; /** * Google's `RE2 `_ regex engine. The regex string must adhere to * the documented `syntax `_. The engine is designed * to complete execution in linear time as well as limit the amount of memory used. + * + * Envoy supports program size checking via runtime. The runtime keys `re2.max_program_size.error_level` + * and `re2.max_program_size.warn_level` can be set to integers as the maximum program size or + * complexity that a compiled regex can have before an exception is thrown or a warning is + * logged, respectively. `re2.max_program_size.error_level` defaults to 100, and + * `re2.max_program_size.warn_level` has no default if unset (will not check/log a warning). + * + * Envoy emits two stats for tracking the program size of regexes: the histogram `re2.program_size`, + * which records the program size, and the counter `re2.exceeded_warn_level`, which is incremented + * each time the program size exceeds the warn level threshold. */ -export interface _envoy_type_matcher_RegexMatcher_GoogleRE2 { +export interface _envoy_type_matcher_v3_RegexMatcher_GoogleRE2 { /** * This field controls the RE2 "program size" which is a rough estimate of how complex a * compiled regex is to evaluate. A regex that has a program size greater than the configured @@ -24,8 +34,18 @@ export interface _envoy_type_matcher_RegexMatcher_GoogleRE2 { * Google's `RE2 `_ regex engine. The regex string must adhere to * the documented `syntax `_. The engine is designed * to complete execution in linear time as well as limit the amount of memory used. + * + * Envoy supports program size checking via runtime. The runtime keys `re2.max_program_size.error_level` + * and `re2.max_program_size.warn_level` can be set to integers as the maximum program size or + * complexity that a compiled regex can have before an exception is thrown or a warning is + * logged, respectively. `re2.max_program_size.error_level` defaults to 100, and + * `re2.max_program_size.warn_level` has no default if unset (will not check/log a warning). + * + * Envoy emits two stats for tracking the program size of regexes: the histogram `re2.program_size`, + * which records the program size, and the counter `re2.exceeded_warn_level`, which is incremented + * each time the program size exceeds the warn level threshold. */ -export interface _envoy_type_matcher_RegexMatcher_GoogleRE2__Output { +export interface _envoy_type_matcher_v3_RegexMatcher_GoogleRE2__Output { /** * This field controls the RE2 "program size" which is a rough estimate of how complex a * compiled regex is to evaluate. A regex that has a program size greater than the configured @@ -45,7 +65,7 @@ export interface RegexMatcher { /** * Google's RE2 regex engine. */ - 'google_re2'?: (_envoy_type_matcher_RegexMatcher_GoogleRE2); + 'google_re2'?: (_envoy_type_matcher_v3_RegexMatcher_GoogleRE2); /** * The regex match string. The string must be supported by the configured engine. */ @@ -60,7 +80,7 @@ export interface RegexMatcher__Output { /** * Google's RE2 regex engine. */ - 'google_re2'?: (_envoy_type_matcher_RegexMatcher_GoogleRE2__Output); + 'google_re2'?: (_envoy_type_matcher_v3_RegexMatcher_GoogleRE2__Output); /** * The regex match string. The string must be supported by the configured engine. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/type/matcher/StringMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/StringMatcher.ts similarity index 58% rename from packages/grpc-js-xds/src/generated/envoy/type/matcher/StringMatcher.ts rename to packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/StringMatcher.ts index e434b1e1b..58616dde8 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/matcher/StringMatcher.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/StringMatcher.ts @@ -1,10 +1,10 @@ -// Original file: deps/envoy-api/envoy/type/matcher/string.proto +// Original file: deps/envoy-api/envoy/type/matcher/v3/string.proto -import type { RegexMatcher as _envoy_type_matcher_RegexMatcher, RegexMatcher__Output as _envoy_type_matcher_RegexMatcher__Output } from '../../../envoy/type/matcher/RegexMatcher'; +import type { RegexMatcher as _envoy_type_matcher_v3_RegexMatcher, RegexMatcher__Output as _envoy_type_matcher_v3_RegexMatcher__Output } from '../../../../envoy/type/matcher/v3/RegexMatcher'; /** * Specifies the way to match a string. - * [#next-free-field: 7] + * [#next-free-field: 8] */ export interface StringMatcher { /** @@ -33,38 +33,31 @@ export interface StringMatcher { * * *abc* matches the value *xyz.abc* */ 'suffix'?: (string); - /** - * The input string must match the regular expression specified here. - * The regex grammar is defined `here - * `_. - * - * Examples: - * - * * The regex ``\d{3}`` matches the value *123* - * * The regex ``\d{3}`` does not match the value *1234* - * * The regex ``\d{3}`` does not match the value *123.456* - * - * .. attention:: - * This field has been deprecated in favor of `safe_regex` as it is not safe for use with - * untrusted input in all cases. - */ - 'regex'?: (string); /** * The input string must match the regular expression specified here. */ - 'safe_regex'?: (_envoy_type_matcher_RegexMatcher); + 'safe_regex'?: (_envoy_type_matcher_v3_RegexMatcher); /** * If true, indicates the exact/prefix/suffix matching should be case insensitive. This has no * effect for the safe_regex match. * For example, the matcher *data* will match both input string *Data* and *data* if set to true. */ 'ignore_case'?: (boolean); - 'match_pattern'?: "exact"|"prefix"|"suffix"|"regex"|"safe_regex"; + /** + * The input string must have the substring specified here. + * Note: empty contains match is not allowed, please use regex instead. + * + * Examples: + * + * * *abc* matches the value *xyz.abc.def* + */ + 'contains'?: (string); + 'match_pattern'?: "exact"|"prefix"|"suffix"|"safe_regex"|"contains"; } /** * Specifies the way to match a string. - * [#next-free-field: 7] + * [#next-free-field: 8] */ export interface StringMatcher__Output { /** @@ -93,31 +86,24 @@ export interface StringMatcher__Output { * * *abc* matches the value *xyz.abc* */ 'suffix'?: (string); - /** - * The input string must match the regular expression specified here. - * The regex grammar is defined `here - * `_. - * - * Examples: - * - * * The regex ``\d{3}`` matches the value *123* - * * The regex ``\d{3}`` does not match the value *1234* - * * The regex ``\d{3}`` does not match the value *123.456* - * - * .. attention:: - * This field has been deprecated in favor of `safe_regex` as it is not safe for use with - * untrusted input in all cases. - */ - 'regex'?: (string); /** * The input string must match the regular expression specified here. */ - 'safe_regex'?: (_envoy_type_matcher_RegexMatcher__Output); + 'safe_regex'?: (_envoy_type_matcher_v3_RegexMatcher__Output); /** * If true, indicates the exact/prefix/suffix matching should be case insensitive. This has no * effect for the safe_regex match. * For example, the matcher *data* will match both input string *Data* and *data* if set to true. */ 'ignore_case': (boolean); - 'match_pattern': "exact"|"prefix"|"suffix"|"regex"|"safe_regex"; + /** + * The input string must have the substring specified here. + * Note: empty contains match is not allowed, please use regex instead. + * + * Examples: + * + * * *abc* matches the value *xyz.abc.def* + */ + 'contains'?: (string); + 'match_pattern': "exact"|"prefix"|"suffix"|"safe_regex"|"contains"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/ValueMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/ValueMatcher.ts new file mode 100644 index 000000000..6c271162a --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/ValueMatcher.ts @@ -0,0 +1,101 @@ +// Original file: deps/envoy-api/envoy/type/matcher/v3/value.proto + +import type { DoubleMatcher as _envoy_type_matcher_v3_DoubleMatcher, DoubleMatcher__Output as _envoy_type_matcher_v3_DoubleMatcher__Output } from '../../../../envoy/type/matcher/v3/DoubleMatcher'; +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 { ListMatcher as _envoy_type_matcher_v3_ListMatcher, ListMatcher__Output as _envoy_type_matcher_v3_ListMatcher__Output } from '../../../../envoy/type/matcher/v3/ListMatcher'; + +/** + * NullMatch is an empty message to specify a null value. + */ +export interface _envoy_type_matcher_v3_ValueMatcher_NullMatch { +} + +/** + * NullMatch is an empty message to specify a null value. + */ +export interface _envoy_type_matcher_v3_ValueMatcher_NullMatch__Output { +} + +/** + * Specifies the way to match a ProtobufWkt::Value. Primitive values and ListValue are supported. + * StructValue is not supported and is always not matched. + * [#next-free-field: 7] + */ +export interface ValueMatcher { + /** + * If specified, a match occurs if and only if the target value is a NullValue. + */ + 'null_match'?: (_envoy_type_matcher_v3_ValueMatcher_NullMatch); + /** + * If specified, a match occurs if and only if the target value is a double value and is + * matched to this field. + */ + 'double_match'?: (_envoy_type_matcher_v3_DoubleMatcher); + /** + * If specified, a match occurs if and only if the target value is a string value and is + * matched to this field. + */ + 'string_match'?: (_envoy_type_matcher_v3_StringMatcher); + /** + * If specified, a match occurs if and only if the target value is a bool value and is equal + * to this field. + */ + 'bool_match'?: (boolean); + /** + * If specified, value match will be performed based on whether the path is referring to a + * valid primitive value in the metadata. If the path is referring to a non-primitive value, + * the result is always not matched. + */ + 'present_match'?: (boolean); + /** + * If specified, a match occurs if and only if the target value is a list value and + * is matched to this field. + */ + 'list_match'?: (_envoy_type_matcher_v3_ListMatcher); + /** + * Specifies how to match a value. + */ + 'match_pattern'?: "null_match"|"double_match"|"string_match"|"bool_match"|"present_match"|"list_match"; +} + +/** + * Specifies the way to match a ProtobufWkt::Value. Primitive values and ListValue are supported. + * StructValue is not supported and is always not matched. + * [#next-free-field: 7] + */ +export interface ValueMatcher__Output { + /** + * If specified, a match occurs if and only if the target value is a NullValue. + */ + 'null_match'?: (_envoy_type_matcher_v3_ValueMatcher_NullMatch__Output); + /** + * If specified, a match occurs if and only if the target value is a double value and is + * matched to this field. + */ + 'double_match'?: (_envoy_type_matcher_v3_DoubleMatcher__Output); + /** + * If specified, a match occurs if and only if the target value is a string value and is + * matched to this field. + */ + 'string_match'?: (_envoy_type_matcher_v3_StringMatcher__Output); + /** + * If specified, a match occurs if and only if the target value is a bool value and is equal + * to this field. + */ + 'bool_match'?: (boolean); + /** + * If specified, value match will be performed based on whether the path is referring to a + * valid primitive value in the metadata. If the path is referring to a non-primitive value, + * the result is always not matched. + */ + 'present_match'?: (boolean); + /** + * If specified, a match occurs if and only if the target value is a list value and + * is matched to this field. + */ + 'list_match'?: (_envoy_type_matcher_v3_ListMatcher__Output); + /** + * Specifies how to match a value. + */ + 'match_pattern': "null_match"|"double_match"|"string_match"|"bool_match"|"present_match"|"list_match"; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/type/metadata/v2/MetadataKind.ts b/packages/grpc-js-xds/src/generated/envoy/type/metadata/v2/MetadataKind.ts deleted file mode 100644 index 665b95f0d..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/type/metadata/v2/MetadataKind.ts +++ /dev/null @@ -1,98 +0,0 @@ -// Original file: deps/envoy-api/envoy/type/metadata/v2/metadata.proto - - -/** - * Represents metadata from :ref:`the upstream cluster`. - */ -export interface _envoy_type_metadata_v2_MetadataKind_Cluster { -} - -/** - * Represents metadata from :ref:`the upstream cluster`. - */ -export interface _envoy_type_metadata_v2_MetadataKind_Cluster__Output { -} - -/** - * Represents metadata from :ref:`the upstream - * host`. - */ -export interface _envoy_type_metadata_v2_MetadataKind_Host { -} - -/** - * Represents metadata from :ref:`the upstream - * host`. - */ -export interface _envoy_type_metadata_v2_MetadataKind_Host__Output { -} - -/** - * Represents dynamic metadata associated with the request. - */ -export interface _envoy_type_metadata_v2_MetadataKind_Request { -} - -/** - * Represents dynamic metadata associated with the request. - */ -export interface _envoy_type_metadata_v2_MetadataKind_Request__Output { -} - -/** - * Represents metadata from :ref:`the route`. - */ -export interface _envoy_type_metadata_v2_MetadataKind_Route { -} - -/** - * Represents metadata from :ref:`the route`. - */ -export interface _envoy_type_metadata_v2_MetadataKind_Route__Output { -} - -/** - * Describes what kind of metadata. - */ -export interface MetadataKind { - /** - * Request kind of metadata. - */ - 'request'?: (_envoy_type_metadata_v2_MetadataKind_Request); - /** - * Route kind of metadata. - */ - 'route'?: (_envoy_type_metadata_v2_MetadataKind_Route); - /** - * Cluster kind of metadata. - */ - 'cluster'?: (_envoy_type_metadata_v2_MetadataKind_Cluster); - /** - * Host kind of metadata. - */ - 'host'?: (_envoy_type_metadata_v2_MetadataKind_Host); - 'kind'?: "request"|"route"|"cluster"|"host"; -} - -/** - * Describes what kind of metadata. - */ -export interface MetadataKind__Output { - /** - * Request kind of metadata. - */ - 'request'?: (_envoy_type_metadata_v2_MetadataKind_Request__Output); - /** - * Route kind of metadata. - */ - 'route'?: (_envoy_type_metadata_v2_MetadataKind_Route__Output); - /** - * Cluster kind of metadata. - */ - 'cluster'?: (_envoy_type_metadata_v2_MetadataKind_Cluster__Output); - /** - * Host kind of metadata. - */ - 'host'?: (_envoy_type_metadata_v2_MetadataKind_Host__Output); - 'kind': "request"|"route"|"cluster"|"host"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/type/metadata/v2/MetadataKey.ts b/packages/grpc-js-xds/src/generated/envoy/type/metadata/v3/MetadataKey.ts similarity index 85% rename from packages/grpc-js-xds/src/generated/envoy/type/metadata/v2/MetadataKey.ts rename to packages/grpc-js-xds/src/generated/envoy/type/metadata/v3/MetadataKey.ts index 94d661879..fcc43b07b 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/metadata/v2/MetadataKey.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/metadata/v3/MetadataKey.ts @@ -1,11 +1,11 @@ -// Original file: deps/envoy-api/envoy/type/metadata/v2/metadata.proto +// Original file: deps/envoy-api/envoy/type/metadata/v3/metadata.proto /** * Specifies the segment in a path to retrieve value from Metadata. * Currently it is only supported to specify the key, i.e. field name, as one segment of a path. */ -export interface _envoy_type_metadata_v2_MetadataKey_PathSegment { +export interface _envoy_type_metadata_v3_MetadataKey_PathSegment { /** * If specified, use the key to retrieve the value in a Struct. */ @@ -17,7 +17,7 @@ export interface _envoy_type_metadata_v2_MetadataKey_PathSegment { * Specifies the segment in a path to retrieve value from Metadata. * Currently it is only supported to specify the key, i.e. field name, as one segment of a path. */ -export interface _envoy_type_metadata_v2_MetadataKey_PathSegment__Output { +export interface _envoy_type_metadata_v3_MetadataKey_PathSegment__Output { /** * If specified, use the key to retrieve the value in a Struct. */ @@ -27,7 +27,7 @@ export interface _envoy_type_metadata_v2_MetadataKey_PathSegment__Output { /** * MetadataKey provides a general interface using `key` and `path` to retrieve value from - * :ref:`Metadata `. + * :ref:`Metadata `. * * For example, for the following Metadata: * @@ -63,12 +63,12 @@ export interface MetadataKey { * Note: Due to that only the key type segment is supported, the path can not specify a list * unless the list is the last segment. */ - 'path'?: (_envoy_type_metadata_v2_MetadataKey_PathSegment)[]; + 'path'?: (_envoy_type_metadata_v3_MetadataKey_PathSegment)[]; } /** * MetadataKey provides a general interface using `key` and `path` to retrieve value from - * :ref:`Metadata `. + * :ref:`Metadata `. * * For example, for the following Metadata: * @@ -104,5 +104,5 @@ export interface MetadataKey__Output { * Note: Due to that only the key type segment is supported, the path can not specify a list * unless the list is the last segment. */ - 'path': (_envoy_type_metadata_v2_MetadataKey_PathSegment__Output)[]; + 'path': (_envoy_type_metadata_v3_MetadataKey_PathSegment__Output)[]; } diff --git a/packages/grpc-js-xds/src/generated/envoy/type/metadata/v3/MetadataKind.ts b/packages/grpc-js-xds/src/generated/envoy/type/metadata/v3/MetadataKind.ts new file mode 100644 index 000000000..c231ecf98 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/type/metadata/v3/MetadataKind.ts @@ -0,0 +1,98 @@ +// Original file: deps/envoy-api/envoy/type/metadata/v3/metadata.proto + + +/** + * Represents metadata from :ref:`the upstream cluster`. + */ +export interface _envoy_type_metadata_v3_MetadataKind_Cluster { +} + +/** + * Represents metadata from :ref:`the upstream cluster`. + */ +export interface _envoy_type_metadata_v3_MetadataKind_Cluster__Output { +} + +/** + * Represents metadata from :ref:`the upstream + * host`. + */ +export interface _envoy_type_metadata_v3_MetadataKind_Host { +} + +/** + * Represents metadata from :ref:`the upstream + * host`. + */ +export interface _envoy_type_metadata_v3_MetadataKind_Host__Output { +} + +/** + * Represents dynamic metadata associated with the request. + */ +export interface _envoy_type_metadata_v3_MetadataKind_Request { +} + +/** + * Represents dynamic metadata associated with the request. + */ +export interface _envoy_type_metadata_v3_MetadataKind_Request__Output { +} + +/** + * Represents metadata from :ref:`the route`. + */ +export interface _envoy_type_metadata_v3_MetadataKind_Route { +} + +/** + * Represents metadata from :ref:`the route`. + */ +export interface _envoy_type_metadata_v3_MetadataKind_Route__Output { +} + +/** + * Describes what kind of metadata. + */ +export interface MetadataKind { + /** + * Request kind of metadata. + */ + 'request'?: (_envoy_type_metadata_v3_MetadataKind_Request); + /** + * Route kind of metadata. + */ + 'route'?: (_envoy_type_metadata_v3_MetadataKind_Route); + /** + * Cluster kind of metadata. + */ + 'cluster'?: (_envoy_type_metadata_v3_MetadataKind_Cluster); + /** + * Host kind of metadata. + */ + 'host'?: (_envoy_type_metadata_v3_MetadataKind_Host); + 'kind'?: "request"|"route"|"cluster"|"host"; +} + +/** + * Describes what kind of metadata. + */ +export interface MetadataKind__Output { + /** + * Request kind of metadata. + */ + 'request'?: (_envoy_type_metadata_v3_MetadataKind_Request__Output); + /** + * Route kind of metadata. + */ + 'route'?: (_envoy_type_metadata_v3_MetadataKind_Route__Output); + /** + * Cluster kind of metadata. + */ + 'cluster'?: (_envoy_type_metadata_v3_MetadataKind_Cluster__Output); + /** + * Host kind of metadata. + */ + 'host'?: (_envoy_type_metadata_v3_MetadataKind_Host__Output); + 'kind': "request"|"route"|"cluster"|"host"; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/type/tracing/v2/CustomTag.ts b/packages/grpc-js-xds/src/generated/envoy/type/tracing/v3/CustomTag.ts similarity index 66% rename from packages/grpc-js-xds/src/generated/envoy/type/tracing/v2/CustomTag.ts rename to packages/grpc-js-xds/src/generated/envoy/type/tracing/v3/CustomTag.ts index 3eed4cf44..ef29c3420 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/tracing/v2/CustomTag.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/tracing/v3/CustomTag.ts @@ -1,12 +1,12 @@ -// Original file: deps/envoy-api/envoy/type/tracing/v2/custom_tag.proto +// Original file: deps/envoy-api/envoy/type/tracing/v3/custom_tag.proto -import type { MetadataKind as _envoy_type_metadata_v2_MetadataKind, MetadataKind__Output as _envoy_type_metadata_v2_MetadataKind__Output } from '../../../../envoy/type/metadata/v2/MetadataKind'; -import type { MetadataKey as _envoy_type_metadata_v2_MetadataKey, MetadataKey__Output as _envoy_type_metadata_v2_MetadataKey__Output } from '../../../../envoy/type/metadata/v2/MetadataKey'; +import type { MetadataKind as _envoy_type_metadata_v3_MetadataKind, MetadataKind__Output as _envoy_type_metadata_v3_MetadataKind__Output } from '../../../../envoy/type/metadata/v3/MetadataKind'; +import type { MetadataKey as _envoy_type_metadata_v3_MetadataKey, MetadataKey__Output as _envoy_type_metadata_v3_MetadataKey__Output } from '../../../../envoy/type/metadata/v3/MetadataKey'; /** * Environment type custom tag with environment name and default value. */ -export interface _envoy_type_tracing_v2_CustomTag_Environment { +export interface _envoy_type_tracing_v3_CustomTag_Environment { /** * Environment variable name to obtain the value to populate the tag value. */ @@ -22,7 +22,7 @@ export interface _envoy_type_tracing_v2_CustomTag_Environment { /** * Environment type custom tag with environment name and default value. */ -export interface _envoy_type_tracing_v2_CustomTag_Environment__Output { +export interface _envoy_type_tracing_v3_CustomTag_Environment__Output { /** * Environment variable name to obtain the value to populate the tag value. */ @@ -38,7 +38,7 @@ export interface _envoy_type_tracing_v2_CustomTag_Environment__Output { /** * Header type custom tag with header name and default value. */ -export interface _envoy_type_tracing_v2_CustomTag_Header { +export interface _envoy_type_tracing_v3_CustomTag_Header { /** * Header name to obtain the value to populate the tag value. */ @@ -54,7 +54,7 @@ export interface _envoy_type_tracing_v2_CustomTag_Header { /** * Header type custom tag with header name and default value. */ -export interface _envoy_type_tracing_v2_CustomTag_Header__Output { +export interface _envoy_type_tracing_v3_CustomTag_Header__Output { /** * Header name to obtain the value to populate the tag value. */ @@ -70,7 +70,7 @@ export interface _envoy_type_tracing_v2_CustomTag_Header__Output { /** * Literal type custom tag with static value for the tag value. */ -export interface _envoy_type_tracing_v2_CustomTag_Literal { +export interface _envoy_type_tracing_v3_CustomTag_Literal { /** * Static literal value to populate the tag value. */ @@ -80,7 +80,7 @@ export interface _envoy_type_tracing_v2_CustomTag_Literal { /** * Literal type custom tag with static value for the tag value. */ -export interface _envoy_type_tracing_v2_CustomTag_Literal__Output { +export interface _envoy_type_tracing_v3_CustomTag_Literal__Output { /** * Static literal value to populate the tag value. */ @@ -89,20 +89,20 @@ export interface _envoy_type_tracing_v2_CustomTag_Literal__Output { /** * Metadata type custom tag using - * :ref:`MetadataKey ` to retrieve the protobuf value - * from :ref:`Metadata `, and populate the tag value with + * :ref:`MetadataKey ` to retrieve the protobuf value + * from :ref:`Metadata `, and populate the tag value with * `the canonical JSON `_ * representation of it. */ -export interface _envoy_type_tracing_v2_CustomTag_Metadata { +export interface _envoy_type_tracing_v3_CustomTag_Metadata { /** * Specify what kind of metadata to obtain tag value from. */ - 'kind'?: (_envoy_type_metadata_v2_MetadataKind); + 'kind'?: (_envoy_type_metadata_v3_MetadataKind); /** * Metadata key to define the path to retrieve the tag value. */ - 'metadata_key'?: (_envoy_type_metadata_v2_MetadataKey); + 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey); /** * When no valid metadata is found, * the tag value would be populated with this default value if specified, @@ -113,20 +113,20 @@ export interface _envoy_type_tracing_v2_CustomTag_Metadata { /** * Metadata type custom tag using - * :ref:`MetadataKey ` to retrieve the protobuf value - * from :ref:`Metadata `, and populate the tag value with + * :ref:`MetadataKey ` to retrieve the protobuf value + * from :ref:`Metadata `, and populate the tag value with * `the canonical JSON `_ * representation of it. */ -export interface _envoy_type_tracing_v2_CustomTag_Metadata__Output { +export interface _envoy_type_tracing_v3_CustomTag_Metadata__Output { /** * Specify what kind of metadata to obtain tag value from. */ - 'kind'?: (_envoy_type_metadata_v2_MetadataKind__Output); + 'kind'?: (_envoy_type_metadata_v3_MetadataKind__Output); /** * Metadata key to define the path to retrieve the tag value. */ - 'metadata_key'?: (_envoy_type_metadata_v2_MetadataKey__Output); + 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey__Output); /** * When no valid metadata is found, * the tag value would be populated with this default value if specified, @@ -147,19 +147,19 @@ export interface CustomTag { /** * A literal custom tag. */ - 'literal'?: (_envoy_type_tracing_v2_CustomTag_Literal); + 'literal'?: (_envoy_type_tracing_v3_CustomTag_Literal); /** * An environment custom tag. */ - 'environment'?: (_envoy_type_tracing_v2_CustomTag_Environment); + 'environment'?: (_envoy_type_tracing_v3_CustomTag_Environment); /** * A request header custom tag. */ - 'request_header'?: (_envoy_type_tracing_v2_CustomTag_Header); + 'request_header'?: (_envoy_type_tracing_v3_CustomTag_Header); /** * A custom tag to obtain tag value from the metadata. */ - 'metadata'?: (_envoy_type_tracing_v2_CustomTag_Metadata); + 'metadata'?: (_envoy_type_tracing_v3_CustomTag_Metadata); /** * Used to specify what kind of custom tag. */ @@ -178,19 +178,19 @@ export interface CustomTag__Output { /** * A literal custom tag. */ - 'literal'?: (_envoy_type_tracing_v2_CustomTag_Literal__Output); + 'literal'?: (_envoy_type_tracing_v3_CustomTag_Literal__Output); /** * An environment custom tag. */ - 'environment'?: (_envoy_type_tracing_v2_CustomTag_Environment__Output); + 'environment'?: (_envoy_type_tracing_v3_CustomTag_Environment__Output); /** * A request header custom tag. */ - 'request_header'?: (_envoy_type_tracing_v2_CustomTag_Header__Output); + 'request_header'?: (_envoy_type_tracing_v3_CustomTag_Header__Output); /** * A custom tag to obtain tag value from the metadata. */ - 'metadata'?: (_envoy_type_tracing_v2_CustomTag_Metadata__Output); + 'metadata'?: (_envoy_type_tracing_v3_CustomTag_Metadata__Output); /** * Used to specify what kind of custom tag. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/type/CodecClientType.ts b/packages/grpc-js-xds/src/generated/envoy/type/v3/CodecClientType.ts similarity index 84% rename from packages/grpc-js-xds/src/generated/envoy/type/CodecClientType.ts rename to packages/grpc-js-xds/src/generated/envoy/type/v3/CodecClientType.ts index a0bf07351..308f14446 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/CodecClientType.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/v3/CodecClientType.ts @@ -1,4 +1,4 @@ -// Original file: deps/envoy-api/envoy/type/http.proto +// Original file: deps/envoy-api/envoy/type/v3/http.proto export enum CodecClientType { HTTP1 = 0, diff --git a/packages/grpc-js-xds/src/generated/envoy/type/DoubleRange.ts b/packages/grpc-js-xds/src/generated/envoy/type/v3/DoubleRange.ts similarity index 82% rename from packages/grpc-js-xds/src/generated/envoy/type/DoubleRange.ts rename to packages/grpc-js-xds/src/generated/envoy/type/v3/DoubleRange.ts index 5ebc3a579..5d13bebdb 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/DoubleRange.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/v3/DoubleRange.ts @@ -1,4 +1,4 @@ -// Original file: deps/envoy-api/envoy/type/range.proto +// Original file: deps/envoy-api/envoy/type/v3/range.proto /** @@ -24,9 +24,9 @@ export interface DoubleRange__Output { /** * start of the range (inclusive) */ - 'start': (number | string); + 'start': (number); /** * end of the range (exclusive) */ - 'end': (number | string); + 'end': (number); } 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 new file mode 100644 index 000000000..564af9a0f --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/type/v3/FractionalPercent.ts @@ -0,0 +1,68 @@ +// Original file: deps/envoy-api/envoy/type/v3/percent.proto + + +// Original file: deps/envoy-api/envoy/type/v3/percent.proto + +/** + * Fraction percentages support several fixed denominator values. + */ +export enum _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, +} + +/** + * A fractional percentage is used in cases in which for performance reasons performing floating + * point to integer conversions during randomness calculations is undesirable. The message includes + * both a numerator and denominator that together determine the final fractional value. + * + * * **Example**: 1/100 = 1%. + * * **Example**: 3/10000 = 0.03%. + */ +export interface FractionalPercent { + /** + * Specifies the numerator. Defaults to 0. + */ + 'numerator'?: (number); + /** + * 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); +} + +/** + * A fractional percentage is used in cases in which for performance reasons performing floating + * point to integer conversions during randomness calculations is undesirable. The message includes + * both a numerator and denominator that together determine the final fractional value. + * + * * **Example**: 1/100 = 1%. + * * **Example**: 3/10000 = 0.03%. + */ +export interface FractionalPercent__Output { + /** + * Specifies the numerator. Defaults to 0. + */ + 'numerator': (number); + /** + * 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); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/type/Int32Range.ts b/packages/grpc-js-xds/src/generated/envoy/type/v3/Int32Range.ts similarity index 90% rename from packages/grpc-js-xds/src/generated/envoy/type/Int32Range.ts rename to packages/grpc-js-xds/src/generated/envoy/type/v3/Int32Range.ts index f5475c2db..826af6c38 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/Int32Range.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/v3/Int32Range.ts @@ -1,4 +1,4 @@ -// Original file: deps/envoy-api/envoy/type/range.proto +// Original file: deps/envoy-api/envoy/type/v3/range.proto /** diff --git a/packages/grpc-js-xds/src/generated/envoy/type/Int64Range.ts b/packages/grpc-js-xds/src/generated/envoy/type/v3/Int64Range.ts similarity index 91% rename from packages/grpc-js-xds/src/generated/envoy/type/Int64Range.ts rename to packages/grpc-js-xds/src/generated/envoy/type/v3/Int64Range.ts index f9664cba4..89ce7fb8d 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/Int64Range.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/v3/Int64Range.ts @@ -1,4 +1,4 @@ -// Original file: deps/envoy-api/envoy/type/range.proto +// Original file: deps/envoy-api/envoy/type/v3/range.proto import type { Long } from '@grpc/proto-loader'; diff --git a/packages/grpc-js-xds/src/generated/envoy/type/v3/Percent.ts b/packages/grpc-js-xds/src/generated/envoy/type/v3/Percent.ts new file mode 100644 index 000000000..01d236c4e --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/type/v3/Percent.ts @@ -0,0 +1,16 @@ +// Original file: deps/envoy-api/envoy/type/v3/percent.proto + + +/** + * Identifies a percentage, in the range [0.0, 100.0]. + */ +export interface Percent { + 'value'?: (number | string); +} + +/** + * Identifies a percentage, in the range [0.0, 100.0]. + */ +export interface Percent__Output { + 'value': (number); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/type/v3/SemanticVersion.ts b/packages/grpc-js-xds/src/generated/envoy/type/v3/SemanticVersion.ts new file mode 100644 index 000000000..3f714a766 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/type/v3/SemanticVersion.ts @@ -0,0 +1,24 @@ +// Original file: deps/envoy-api/envoy/type/v3/semantic_version.proto + + +/** + * Envoy uses SemVer (https://semver.org/). Major/minor versions indicate + * expected behaviors and APIs, the patch version field is used only + * for security fixes and can be generally ignored. + */ +export interface SemanticVersion { + 'major_number'?: (number); + 'minor_number'?: (number); + 'patch'?: (number); +} + +/** + * Envoy uses SemVer (https://semver.org/). Major/minor versions indicate + * expected behaviors and APIs, the patch version field is used only + * for security fixes and can be generally ignored. + */ +export interface SemanticVersion__Output { + 'major_number': (number); + 'minor_number': (number); + 'patch': (number); +} diff --git a/packages/grpc-js-xds/src/generated/google/api/CustomHttpPattern.ts b/packages/grpc-js-xds/src/generated/google/api/CustomHttpPattern.ts deleted file mode 100644 index 2b6490be6..000000000 --- a/packages/grpc-js-xds/src/generated/google/api/CustomHttpPattern.ts +++ /dev/null @@ -1,30 +0,0 @@ -// Original file: deps/googleapis/google/api/http.proto - - -/** - * A custom pattern is used for defining custom HTTP verb. - */ -export interface CustomHttpPattern { - /** - * The name of this custom HTTP verb. - */ - 'kind'?: (string); - /** - * The path matched by this custom verb. - */ - 'path'?: (string); -} - -/** - * A custom pattern is used for defining custom HTTP verb. - */ -export interface CustomHttpPattern__Output { - /** - * The name of this custom HTTP verb. - */ - 'kind': (string); - /** - * The path matched by this custom verb. - */ - 'path': (string); -} diff --git a/packages/grpc-js-xds/src/generated/google/api/Http.ts b/packages/grpc-js-xds/src/generated/google/api/Http.ts deleted file mode 100644 index e9b3cb309..000000000 --- a/packages/grpc-js-xds/src/generated/google/api/Http.ts +++ /dev/null @@ -1,49 +0,0 @@ -// Original file: deps/googleapis/google/api/http.proto - -import type { HttpRule as _google_api_HttpRule, HttpRule__Output as _google_api_HttpRule__Output } from '../../google/api/HttpRule'; - -/** - * Defines the HTTP configuration for an API service. It contains a list of - * [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method - * to one or more HTTP REST API methods. - */ -export interface Http { - /** - * A list of HTTP configuration rules that apply to individual API methods. - * - * **NOTE:** All service configuration rules follow "last one wins" order. - */ - 'rules'?: (_google_api_HttpRule)[]; - /** - * When set to true, URL path parameters will be fully URI-decoded except in - * cases of single segment matches in reserved expansion, where "%2F" will be - * left encoded. - * - * The default behavior is to not decode RFC 6570 reserved characters in multi - * segment matches. - */ - 'fully_decode_reserved_expansion'?: (boolean); -} - -/** - * Defines the HTTP configuration for an API service. It contains a list of - * [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method - * to one or more HTTP REST API methods. - */ -export interface Http__Output { - /** - * A list of HTTP configuration rules that apply to individual API methods. - * - * **NOTE:** All service configuration rules follow "last one wins" order. - */ - 'rules': (_google_api_HttpRule__Output)[]; - /** - * When set to true, URL path parameters will be fully URI-decoded except in - * cases of single segment matches in reserved expansion, where "%2F" will be - * left encoded. - * - * The default behavior is to not decode RFC 6570 reserved characters in multi - * segment matches. - */ - 'fully_decode_reserved_expansion': (boolean); -} diff --git a/packages/grpc-js-xds/src/generated/google/api/HttpRule.ts b/packages/grpc-js-xds/src/generated/google/api/HttpRule.ts deleted file mode 100644 index 21ad897ee..000000000 --- a/packages/grpc-js-xds/src/generated/google/api/HttpRule.ts +++ /dev/null @@ -1,680 +0,0 @@ -// Original file: deps/googleapis/google/api/http.proto - -import type { CustomHttpPattern as _google_api_CustomHttpPattern, CustomHttpPattern__Output as _google_api_CustomHttpPattern__Output } from '../../google/api/CustomHttpPattern'; -import type { HttpRule as _google_api_HttpRule, HttpRule__Output as _google_api_HttpRule__Output } from '../../google/api/HttpRule'; - -/** - * # gRPC Transcoding - * - * gRPC Transcoding is a feature for mapping between a gRPC method and one or - * more HTTP REST endpoints. It allows developers to build a single API service - * that supports both gRPC APIs and REST APIs. Many systems, including [Google - * APIs](https://github.com/googleapis/googleapis), - * [Cloud Endpoints](https://cloud.google.com/endpoints), [gRPC - * Gateway](https://github.com/grpc-ecosystem/grpc-gateway), - * and [Envoy](https://github.com/envoyproxy/envoy) proxy support this feature - * and use it for large scale production services. - * - * `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies - * how different portions of the gRPC request message are mapped to the URL - * path, URL query parameters, and HTTP request body. It also controls how the - * gRPC response message is mapped to the HTTP response body. `HttpRule` is - * typically specified as an `google.api.http` annotation on the gRPC method. - * - * Each mapping specifies a URL path template and an HTTP method. The path - * template may refer to one or more fields in the gRPC request message, as long - * as each field is a non-repeated field with a primitive (non-message) type. - * The path template controls how fields of the request message are mapped to - * the URL path. - * - * Example: - * - * service Messaging { - * rpc GetMessage(GetMessageRequest) returns (Message) { - * option (google.api.http) = { - * get: "/v1/{name=messages/*}" - * }; - * } - * } - * message GetMessageRequest { - * string name = 1; // Mapped to URL path. - * } - * message Message { - * string text = 1; // The resource content. - * } - * - * This enables an HTTP REST to gRPC mapping as below: - * - * HTTP | gRPC - * -----|----- - * `GET /v1/messages/123456` | `GetMessage(name: "messages/123456")` - * - * Any fields in the request message which are not bound by the path template - * automatically become HTTP query parameters if there is no HTTP request body. - * For example: - * - * service Messaging { - * rpc GetMessage(GetMessageRequest) returns (Message) { - * option (google.api.http) = { - * get:"/v1/messages/{message_id}" - * }; - * } - * } - * message GetMessageRequest { - * message SubMessage { - * string subfield = 1; - * } - * string message_id = 1; // Mapped to URL path. - * int64 revision = 2; // Mapped to URL query parameter `revision`. - * SubMessage sub = 3; // Mapped to URL query parameter `sub.subfield`. - * } - * - * This enables a HTTP JSON to RPC mapping as below: - * - * HTTP | gRPC - * -----|----- - * `GET /v1/messages/123456?revision=2&sub.subfield=foo` | - * `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: - * "foo"))` - * - * Note that fields which are mapped to URL query parameters must have a - * primitive type or a repeated primitive type or a non-repeated message type. - * In the case of a repeated type, the parameter can be repeated in the URL - * as `...?param=A¶m=B`. In the case of a message type, each field of the - * message is mapped to a separate parameter, such as - * `...?foo.a=A&foo.b=B&foo.c=C`. - * - * For HTTP methods that allow a request body, the `body` field - * specifies the mapping. Consider a REST update method on the - * message resource collection: - * - * service Messaging { - * rpc UpdateMessage(UpdateMessageRequest) returns (Message) { - * option (google.api.http) = { - * patch: "/v1/messages/{message_id}" - * body: "message" - * }; - * } - * } - * message UpdateMessageRequest { - * string message_id = 1; // mapped to the URL - * Message message = 2; // mapped to the body - * } - * - * The following HTTP JSON to RPC mapping is enabled, where the - * representation of the JSON in the request body is determined by - * protos JSON encoding: - * - * HTTP | gRPC - * -----|----- - * `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: - * "123456" message { text: "Hi!" })` - * - * The special name `*` can be used in the body mapping to define that - * every field not bound by the path template should be mapped to the - * request body. This enables the following alternative definition of - * the update method: - * - * service Messaging { - * rpc UpdateMessage(Message) returns (Message) { - * option (google.api.http) = { - * patch: "/v1/messages/{message_id}" - * body: "*" - * }; - * } - * } - * message Message { - * string message_id = 1; - * string text = 2; - * } - * - * - * The following HTTP JSON to RPC mapping is enabled: - * - * HTTP | gRPC - * -----|----- - * `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: - * "123456" text: "Hi!")` - * - * Note that when using `*` in the body mapping, it is not possible to - * have HTTP parameters, as all fields not bound by the path end in - * the body. This makes this option more rarely used in practice when - * defining REST APIs. The common usage of `*` is in custom methods - * which don't use the URL at all for transferring data. - * - * It is possible to define multiple HTTP methods for one RPC by using - * the `additional_bindings` option. Example: - * - * service Messaging { - * rpc GetMessage(GetMessageRequest) returns (Message) { - * option (google.api.http) = { - * get: "/v1/messages/{message_id}" - * additional_bindings { - * get: "/v1/users/{user_id}/messages/{message_id}" - * } - * }; - * } - * } - * message GetMessageRequest { - * string message_id = 1; - * string user_id = 2; - * } - * - * This enables the following two alternative HTTP JSON to RPC mappings: - * - * HTTP | gRPC - * -----|----- - * `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` - * `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: - * "123456")` - * - * ## Rules for HTTP mapping - * - * 1. Leaf request fields (recursive expansion nested messages in the request - * message) are classified into three categories: - * - Fields referred by the path template. They are passed via the URL path. - * - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They are passed via the HTTP - * request body. - * - All other fields are passed via the URL query parameters, and the - * parameter name is the field path in the request message. A repeated - * field can be represented as multiple query parameters under the same - * name. - * 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL query parameter, all fields - * are passed via URL path and HTTP request body. - * 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP request body, all - * fields are passed via URL path and URL query parameters. - * - * ### Path template syntax - * - * Template = "/" Segments [ Verb ] ; - * Segments = Segment { "/" Segment } ; - * Segment = "*" | "**" | LITERAL | Variable ; - * Variable = "{" FieldPath [ "=" Segments ] "}" ; - * FieldPath = IDENT { "." IDENT } ; - * Verb = ":" LITERAL ; - * - * The syntax `*` matches a single URL path segment. The syntax `**` matches - * zero or more URL path segments, which must be the last part of the URL path - * except the `Verb`. - * - * The syntax `Variable` matches part of the URL path as specified by its - * template. A variable template must not contain other variables. If a variable - * matches a single path segment, its template may be omitted, e.g. `{var}` - * is equivalent to `{var=*}`. - * - * The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL` - * contains any reserved character, such characters should be percent-encoded - * before the matching. - * - * If a variable contains exactly one path segment, such as `"{var}"` or - * `"{var=*}"`, when such a variable is expanded into a URL path on the client - * side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The - * server side does the reverse decoding. Such variables show up in the - * [Discovery - * Document](https://developers.google.com/discovery/v1/reference/apis) as - * `{var}`. - * - * If a variable contains multiple path segments, such as `"{var=foo/*}"` - * or `"{var=**}"`, when such a variable is expanded into a URL path on the - * client side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. - * The server side does the reverse decoding, except "%2F" and "%2f" are left - * unchanged. Such variables show up in the - * [Discovery - * Document](https://developers.google.com/discovery/v1/reference/apis) as - * `{+var}`. - * - * ## Using gRPC API Service Configuration - * - * gRPC API Service Configuration (service config) is a configuration language - * for configuring a gRPC service to become a user-facing product. The - * service config is simply the YAML representation of the `google.api.Service` - * proto message. - * - * As an alternative to annotating your proto file, you can configure gRPC - * transcoding in your service config YAML files. You do this by specifying a - * `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same - * effect as the proto annotation. This can be particularly useful if you - * have a proto that is reused in multiple services. Note that any transcoding - * specified in the service config will override any matching transcoding - * configuration in the proto. - * - * Example: - * - * http: - * rules: - * # Selects a gRPC method and applies HttpRule to it. - * - selector: example.v1.Messaging.GetMessage - * get: /v1/messages/{message_id}/{sub.subfield} - * - * ## Special notes - * - * When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the - * proto to JSON conversion must follow the [proto3 - * specification](https://developers.google.com/protocol-buffers/docs/proto3#json). - * - * While the single segment variable follows the semantics of - * [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String - * Expansion, the multi segment variable **does not** follow RFC 6570 Section - * 3.2.3 Reserved Expansion. The reason is that the Reserved Expansion - * does not expand special characters like `?` and `#`, which would lead - * to invalid URLs. As the result, gRPC Transcoding uses a custom encoding - * for multi segment variables. - * - * The path variables **must not** refer to any repeated or mapped field, - * because client libraries are not capable of handling such variable expansion. - * - * The path variables **must not** capture the leading "/" character. The reason - * is that the most common use case "{var}" does not capture the leading "/" - * character. For consistency, all path variables must share the same behavior. - * - * Repeated message fields must not be mapped to URL query parameters, because - * no client library can support such complicated mapping. - * - * If an API needs to use a JSON array for request or response body, it can map - * the request or response body to a repeated field. However, some gRPC - * Transcoding implementations may not support this feature. - */ -export interface HttpRule { - /** - * Selects a method to which this rule applies. - * - * Refer to [selector][google.api.DocumentationRule.selector] for syntax details. - */ - 'selector'?: (string); - /** - * Maps to HTTP GET. Used for listing and getting information about - * resources. - */ - 'get'?: (string); - /** - * Maps to HTTP PUT. Used for replacing a resource. - */ - 'put'?: (string); - /** - * Maps to HTTP POST. Used for creating a resource or performing an action. - */ - 'post'?: (string); - /** - * Maps to HTTP DELETE. Used for deleting a resource. - */ - 'delete'?: (string); - /** - * Maps to HTTP PATCH. Used for updating a resource. - */ - 'patch'?: (string); - /** - * The name of the request field whose value is mapped to the HTTP request - * body, or `*` for mapping all request fields not captured by the path - * pattern to the HTTP body, or omitted for not having any HTTP request body. - * - * NOTE: the referred field must be present at the top-level of the request - * message type. - */ - 'body'?: (string); - /** - * The custom pattern is used for specifying an HTTP method that is not - * included in the `pattern` field, such as HEAD, or "*" to leave the - * HTTP method unspecified for this rule. The wild-card rule is useful - * for services that provide content to Web (HTML) clients. - */ - 'custom'?: (_google_api_CustomHttpPattern); - /** - * Additional HTTP bindings for the selector. Nested bindings must - * not contain an `additional_bindings` field themselves (that is, - * the nesting may only be one level deep). - */ - 'additional_bindings'?: (_google_api_HttpRule)[]; - /** - * Optional. The name of the response field whose value is mapped to the HTTP - * response body. When omitted, the entire response message will be used - * as the HTTP response body. - * - * NOTE: The referred field must be present at the top-level of the response - * message type. - */ - 'response_body'?: (string); - /** - * Determines the URL pattern is matched by this rules. This pattern can be - * used with any of the {get|put|post|delete|patch} methods. A custom method - * can be defined using the 'custom' field. - */ - 'pattern'?: "get"|"put"|"post"|"delete"|"patch"|"custom"; -} - -/** - * # gRPC Transcoding - * - * gRPC Transcoding is a feature for mapping between a gRPC method and one or - * more HTTP REST endpoints. It allows developers to build a single API service - * that supports both gRPC APIs and REST APIs. Many systems, including [Google - * APIs](https://github.com/googleapis/googleapis), - * [Cloud Endpoints](https://cloud.google.com/endpoints), [gRPC - * Gateway](https://github.com/grpc-ecosystem/grpc-gateway), - * and [Envoy](https://github.com/envoyproxy/envoy) proxy support this feature - * and use it for large scale production services. - * - * `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies - * how different portions of the gRPC request message are mapped to the URL - * path, URL query parameters, and HTTP request body. It also controls how the - * gRPC response message is mapped to the HTTP response body. `HttpRule` is - * typically specified as an `google.api.http` annotation on the gRPC method. - * - * Each mapping specifies a URL path template and an HTTP method. The path - * template may refer to one or more fields in the gRPC request message, as long - * as each field is a non-repeated field with a primitive (non-message) type. - * The path template controls how fields of the request message are mapped to - * the URL path. - * - * Example: - * - * service Messaging { - * rpc GetMessage(GetMessageRequest) returns (Message) { - * option (google.api.http) = { - * get: "/v1/{name=messages/*}" - * }; - * } - * } - * message GetMessageRequest { - * string name = 1; // Mapped to URL path. - * } - * message Message { - * string text = 1; // The resource content. - * } - * - * This enables an HTTP REST to gRPC mapping as below: - * - * HTTP | gRPC - * -----|----- - * `GET /v1/messages/123456` | `GetMessage(name: "messages/123456")` - * - * Any fields in the request message which are not bound by the path template - * automatically become HTTP query parameters if there is no HTTP request body. - * For example: - * - * service Messaging { - * rpc GetMessage(GetMessageRequest) returns (Message) { - * option (google.api.http) = { - * get:"/v1/messages/{message_id}" - * }; - * } - * } - * message GetMessageRequest { - * message SubMessage { - * string subfield = 1; - * } - * string message_id = 1; // Mapped to URL path. - * int64 revision = 2; // Mapped to URL query parameter `revision`. - * SubMessage sub = 3; // Mapped to URL query parameter `sub.subfield`. - * } - * - * This enables a HTTP JSON to RPC mapping as below: - * - * HTTP | gRPC - * -----|----- - * `GET /v1/messages/123456?revision=2&sub.subfield=foo` | - * `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: - * "foo"))` - * - * Note that fields which are mapped to URL query parameters must have a - * primitive type or a repeated primitive type or a non-repeated message type. - * In the case of a repeated type, the parameter can be repeated in the URL - * as `...?param=A¶m=B`. In the case of a message type, each field of the - * message is mapped to a separate parameter, such as - * `...?foo.a=A&foo.b=B&foo.c=C`. - * - * For HTTP methods that allow a request body, the `body` field - * specifies the mapping. Consider a REST update method on the - * message resource collection: - * - * service Messaging { - * rpc UpdateMessage(UpdateMessageRequest) returns (Message) { - * option (google.api.http) = { - * patch: "/v1/messages/{message_id}" - * body: "message" - * }; - * } - * } - * message UpdateMessageRequest { - * string message_id = 1; // mapped to the URL - * Message message = 2; // mapped to the body - * } - * - * The following HTTP JSON to RPC mapping is enabled, where the - * representation of the JSON in the request body is determined by - * protos JSON encoding: - * - * HTTP | gRPC - * -----|----- - * `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: - * "123456" message { text: "Hi!" })` - * - * The special name `*` can be used in the body mapping to define that - * every field not bound by the path template should be mapped to the - * request body. This enables the following alternative definition of - * the update method: - * - * service Messaging { - * rpc UpdateMessage(Message) returns (Message) { - * option (google.api.http) = { - * patch: "/v1/messages/{message_id}" - * body: "*" - * }; - * } - * } - * message Message { - * string message_id = 1; - * string text = 2; - * } - * - * - * The following HTTP JSON to RPC mapping is enabled: - * - * HTTP | gRPC - * -----|----- - * `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: - * "123456" text: "Hi!")` - * - * Note that when using `*` in the body mapping, it is not possible to - * have HTTP parameters, as all fields not bound by the path end in - * the body. This makes this option more rarely used in practice when - * defining REST APIs. The common usage of `*` is in custom methods - * which don't use the URL at all for transferring data. - * - * It is possible to define multiple HTTP methods for one RPC by using - * the `additional_bindings` option. Example: - * - * service Messaging { - * rpc GetMessage(GetMessageRequest) returns (Message) { - * option (google.api.http) = { - * get: "/v1/messages/{message_id}" - * additional_bindings { - * get: "/v1/users/{user_id}/messages/{message_id}" - * } - * }; - * } - * } - * message GetMessageRequest { - * string message_id = 1; - * string user_id = 2; - * } - * - * This enables the following two alternative HTTP JSON to RPC mappings: - * - * HTTP | gRPC - * -----|----- - * `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` - * `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: - * "123456")` - * - * ## Rules for HTTP mapping - * - * 1. Leaf request fields (recursive expansion nested messages in the request - * message) are classified into three categories: - * - Fields referred by the path template. They are passed via the URL path. - * - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They are passed via the HTTP - * request body. - * - All other fields are passed via the URL query parameters, and the - * parameter name is the field path in the request message. A repeated - * field can be represented as multiple query parameters under the same - * name. - * 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL query parameter, all fields - * are passed via URL path and HTTP request body. - * 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP request body, all - * fields are passed via URL path and URL query parameters. - * - * ### Path template syntax - * - * Template = "/" Segments [ Verb ] ; - * Segments = Segment { "/" Segment } ; - * Segment = "*" | "**" | LITERAL | Variable ; - * Variable = "{" FieldPath [ "=" Segments ] "}" ; - * FieldPath = IDENT { "." IDENT } ; - * Verb = ":" LITERAL ; - * - * The syntax `*` matches a single URL path segment. The syntax `**` matches - * zero or more URL path segments, which must be the last part of the URL path - * except the `Verb`. - * - * The syntax `Variable` matches part of the URL path as specified by its - * template. A variable template must not contain other variables. If a variable - * matches a single path segment, its template may be omitted, e.g. `{var}` - * is equivalent to `{var=*}`. - * - * The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL` - * contains any reserved character, such characters should be percent-encoded - * before the matching. - * - * If a variable contains exactly one path segment, such as `"{var}"` or - * `"{var=*}"`, when such a variable is expanded into a URL path on the client - * side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The - * server side does the reverse decoding. Such variables show up in the - * [Discovery - * Document](https://developers.google.com/discovery/v1/reference/apis) as - * `{var}`. - * - * If a variable contains multiple path segments, such as `"{var=foo/*}"` - * or `"{var=**}"`, when such a variable is expanded into a URL path on the - * client side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. - * The server side does the reverse decoding, except "%2F" and "%2f" are left - * unchanged. Such variables show up in the - * [Discovery - * Document](https://developers.google.com/discovery/v1/reference/apis) as - * `{+var}`. - * - * ## Using gRPC API Service Configuration - * - * gRPC API Service Configuration (service config) is a configuration language - * for configuring a gRPC service to become a user-facing product. The - * service config is simply the YAML representation of the `google.api.Service` - * proto message. - * - * As an alternative to annotating your proto file, you can configure gRPC - * transcoding in your service config YAML files. You do this by specifying a - * `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same - * effect as the proto annotation. This can be particularly useful if you - * have a proto that is reused in multiple services. Note that any transcoding - * specified in the service config will override any matching transcoding - * configuration in the proto. - * - * Example: - * - * http: - * rules: - * # Selects a gRPC method and applies HttpRule to it. - * - selector: example.v1.Messaging.GetMessage - * get: /v1/messages/{message_id}/{sub.subfield} - * - * ## Special notes - * - * When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the - * proto to JSON conversion must follow the [proto3 - * specification](https://developers.google.com/protocol-buffers/docs/proto3#json). - * - * While the single segment variable follows the semantics of - * [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String - * Expansion, the multi segment variable **does not** follow RFC 6570 Section - * 3.2.3 Reserved Expansion. The reason is that the Reserved Expansion - * does not expand special characters like `?` and `#`, which would lead - * to invalid URLs. As the result, gRPC Transcoding uses a custom encoding - * for multi segment variables. - * - * The path variables **must not** refer to any repeated or mapped field, - * because client libraries are not capable of handling such variable expansion. - * - * The path variables **must not** capture the leading "/" character. The reason - * is that the most common use case "{var}" does not capture the leading "/" - * character. For consistency, all path variables must share the same behavior. - * - * Repeated message fields must not be mapped to URL query parameters, because - * no client library can support such complicated mapping. - * - * If an API needs to use a JSON array for request or response body, it can map - * the request or response body to a repeated field. However, some gRPC - * Transcoding implementations may not support this feature. - */ -export interface HttpRule__Output { - /** - * Selects a method to which this rule applies. - * - * Refer to [selector][google.api.DocumentationRule.selector] for syntax details. - */ - 'selector': (string); - /** - * Maps to HTTP GET. Used for listing and getting information about - * resources. - */ - 'get'?: (string); - /** - * Maps to HTTP PUT. Used for replacing a resource. - */ - 'put'?: (string); - /** - * Maps to HTTP POST. Used for creating a resource or performing an action. - */ - 'post'?: (string); - /** - * Maps to HTTP DELETE. Used for deleting a resource. - */ - 'delete'?: (string); - /** - * Maps to HTTP PATCH. Used for updating a resource. - */ - 'patch'?: (string); - /** - * The name of the request field whose value is mapped to the HTTP request - * body, or `*` for mapping all request fields not captured by the path - * pattern to the HTTP body, or omitted for not having any HTTP request body. - * - * NOTE: the referred field must be present at the top-level of the request - * message type. - */ - 'body': (string); - /** - * The custom pattern is used for specifying an HTTP method that is not - * included in the `pattern` field, such as HEAD, or "*" to leave the - * HTTP method unspecified for this rule. The wild-card rule is useful - * for services that provide content to Web (HTML) clients. - */ - 'custom'?: (_google_api_CustomHttpPattern__Output); - /** - * Additional HTTP bindings for the selector. Nested bindings must - * not contain an `additional_bindings` field themselves (that is, - * the nesting may only be one level deep). - */ - 'additional_bindings': (_google_api_HttpRule__Output)[]; - /** - * Optional. The name of the response field whose value is mapped to the HTTP - * response body. When omitted, the entire response message will be used - * as the HTTP response body. - * - * NOTE: The referred field must be present at the top-level of the response - * message type. - */ - 'response_body': (string); - /** - * Determines the URL pattern is matched by this rules. This pattern can be - * used with any of the {get|put|post|delete|patch} methods. A custom method - * can be defined using the 'custom' field. - */ - 'pattern': "get"|"put"|"post"|"delete"|"patch"|"custom"; -} diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/Any.ts b/packages/grpc-js-xds/src/generated/google/protobuf/Any.ts index fe0d05f12..fcaa6724e 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/Any.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/Any.ts @@ -7,7 +7,7 @@ export type Any = AnyExtension | { value: Buffer | Uint8Array | string; } -export type Any__Output = AnyExtension | { - type_url: string; - value: Buffer; +export interface Any__Output { + 'type_url': (string); + 'value': (Buffer); } diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/DoubleValue.ts b/packages/grpc-js-xds/src/generated/google/protobuf/DoubleValue.ts index e4f2eb4b8..d70b303c2 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/DoubleValue.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/DoubleValue.ts @@ -6,5 +6,5 @@ export interface DoubleValue { } export interface DoubleValue__Output { - 'value': (number | string); + 'value': (number); } 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 b76a60815..63f8a015f 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/FieldOptions.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/FieldOptions.ts @@ -2,6 +2,7 @@ import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; import type { FieldRules as _validate_FieldRules, FieldRules__Output as _validate_FieldRules__Output } from '../../validate/FieldRules'; +import type { FieldSecurityAnnotation as _udpa_annotations_FieldSecurityAnnotation, FieldSecurityAnnotation__Output as _udpa_annotations_FieldSecurityAnnotation__Output } from '../../udpa/annotations/FieldSecurityAnnotation'; import type { FieldMigrateAnnotation as _udpa_annotations_FieldMigrateAnnotation, FieldMigrateAnnotation__Output as _udpa_annotations_FieldMigrateAnnotation__Output } from '../../udpa/annotations/FieldMigrateAnnotation'; // Original file: null @@ -29,6 +30,7 @@ export interface FieldOptions { 'weak'?: (boolean); 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; '.validate.rules'?: (_validate_FieldRules); + '.udpa.annotations.security'?: (_udpa_annotations_FieldSecurityAnnotation); '.udpa.annotations.sensitive'?: (boolean); '.udpa.annotations.field_migrate'?: (_udpa_annotations_FieldMigrateAnnotation); '.envoy.annotations.disallowed_by_default'?: (boolean); @@ -43,6 +45,7 @@ export interface FieldOptions__Output { 'weak': (boolean); 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; '.validate.rules'?: (_validate_FieldRules__Output); + '.udpa.annotations.security'?: (_udpa_annotations_FieldSecurityAnnotation__Output); '.udpa.annotations.sensitive': (boolean); '.udpa.annotations.field_migrate'?: (_udpa_annotations_FieldMigrateAnnotation__Output); '.envoy.annotations.disallowed_by_default': (boolean); diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/FloatValue.ts b/packages/grpc-js-xds/src/generated/google/protobuf/FloatValue.ts index 144a9a585..54a655fbb 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/FloatValue.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/FloatValue.ts @@ -6,5 +6,5 @@ export interface FloatValue { } export interface FloatValue__Output { - 'value': (number | string); + 'value': (number); } diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/MessageOptions.ts b/packages/grpc-js-xds/src/generated/google/protobuf/MessageOptions.ts index 7560daa28..219e4bfd2 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/MessageOptions.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/MessageOptions.ts @@ -1,6 +1,7 @@ // Original file: null import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; +import type { VersioningAnnotation as _udpa_annotations_VersioningAnnotation, VersioningAnnotation__Output as _udpa_annotations_VersioningAnnotation__Output } from '../../udpa/annotations/VersioningAnnotation'; import type { MigrateAnnotation as _udpa_annotations_MigrateAnnotation, MigrateAnnotation__Output as _udpa_annotations_MigrateAnnotation__Output } from '../../udpa/annotations/MigrateAnnotation'; export interface MessageOptions { @@ -10,6 +11,7 @@ export interface MessageOptions { 'mapEntry'?: (boolean); 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; '.validate.disabled'?: (boolean); + '.udpa.annotations.versioning'?: (_udpa_annotations_VersioningAnnotation); '.udpa.annotations.message_migrate'?: (_udpa_annotations_MigrateAnnotation); } @@ -20,5 +22,6 @@ export interface MessageOptions__Output { 'mapEntry': (boolean); 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; '.validate.disabled': (boolean); + '.udpa.annotations.versioning'?: (_udpa_annotations_VersioningAnnotation__Output); '.udpa.annotations.message_migrate'?: (_udpa_annotations_MigrateAnnotation__Output); } diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/UninterpretedOption.ts b/packages/grpc-js-xds/src/generated/google/protobuf/UninterpretedOption.ts index 433820f55..6e9fc275b 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/UninterpretedOption.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/UninterpretedOption.ts @@ -27,7 +27,7 @@ export interface UninterpretedOption__Output { 'identifierValue': (string); 'positiveIntValue': (string); 'negativeIntValue': (string); - 'doubleValue': (number | string); + 'doubleValue': (number); 'stringValue': (Buffer); 'aggregateValue': (string); } 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 68b665dcb..0860535dc 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/Value.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/Value.ts @@ -16,7 +16,7 @@ export interface Value { export interface Value__Output { 'nullValue'?: (keyof typeof _google_protobuf_NullValue); - 'numberValue'?: (number | string); + 'numberValue'?: (number); 'stringValue'?: (string); 'boolValue'?: (boolean); 'structValue'?: (_google_protobuf_Struct__Output); diff --git a/packages/grpc-js-xds/src/generated/http_connection_manager.ts b/packages/grpc-js-xds/src/generated/http_connection_manager.ts index 7e822564d..9cb81bb0e 100644 --- a/packages/grpc-js-xds/src/generated/http_connection_manager.ts +++ b/packages/grpc-js-xds/src/generated/http_connection_manager.ts @@ -10,12 +10,28 @@ export interface ProtoGrpcType { envoy: { annotations: { } - api: { - v2: { - RouteConfiguration: MessageTypeDefinition - ScopedRouteConfiguration: MessageTypeDefinition - Vhds: MessageTypeDefinition - core: { + config: { + accesslog: { + v3: { + AccessLog: MessageTypeDefinition + AccessLogFilter: MessageTypeDefinition + AndFilter: MessageTypeDefinition + ComparisonFilter: MessageTypeDefinition + DurationFilter: MessageTypeDefinition + ExtensionFilter: MessageTypeDefinition + GrpcStatusFilter: MessageTypeDefinition + HeaderFilter: MessageTypeDefinition + MetadataFilter: MessageTypeDefinition + NotHealthCheckFilter: MessageTypeDefinition + OrFilter: MessageTypeDefinition + ResponseFlagFilter: MessageTypeDefinition + RuntimeFilter: MessageTypeDefinition + StatusCodeFilter: MessageTypeDefinition + TraceableFilter: MessageTypeDefinition + } + } + core: { + v3: { Address: MessageTypeDefinition AggregatedConfigSource: MessageTypeDefinition ApiConfigSource: MessageTypeDefinition @@ -28,7 +44,9 @@ export interface ProtoGrpcType { ConfigSource: MessageTypeDefinition ControlPlane: MessageTypeDefinition DataSource: MessageTypeDefinition + EnvoyInternalAddress: MessageTypeDefinition Extension: MessageTypeDefinition + ExtensionConfigSource: MessageTypeDefinition GrpcProtocolOptions: MessageTypeDefinition GrpcService: MessageTypeDefinition HeaderMap: MessageTypeDefinition @@ -36,12 +54,15 @@ export interface ProtoGrpcType { HeaderValueOption: MessageTypeDefinition Http1ProtocolOptions: MessageTypeDefinition Http2ProtocolOptions: MessageTypeDefinition + Http3ProtocolOptions: MessageTypeDefinition HttpProtocolOptions: MessageTypeDefinition HttpUri: MessageTypeDefinition + KeepaliveSettings: MessageTypeDefinition Locality: MessageTypeDefinition Metadata: MessageTypeDefinition Node: MessageTypeDefinition Pipe: MessageTypeDefinition + ProxyProtocolConfig: MessageTypeDefinition RateLimitSettings: MessageTypeDefinition RemoteDataSource: MessageTypeDefinition RequestMethod: EnumTypeDefinition @@ -50,64 +71,64 @@ export interface ProtoGrpcType { RuntimeDouble: MessageTypeDefinition RuntimeFeatureFlag: MessageTypeDefinition RuntimeFractionalPercent: MessageTypeDefinition + RuntimePercent: MessageTypeDefinition RuntimeUInt32: MessageTypeDefinition SelfConfigSource: MessageTypeDefinition SocketAddress: MessageTypeDefinition SocketOption: MessageTypeDefinition + SubstitutionFormatString: MessageTypeDefinition TcpKeepalive: MessageTypeDefinition TcpProtocolOptions: MessageTypeDefinition TrafficDirection: EnumTypeDefinition TransportSocket: MessageTypeDefinition + TypedExtensionConfig: MessageTypeDefinition UpstreamHttpProtocolOptions: MessageTypeDefinition + WatchedDirectory: MessageTypeDefinition } - route: { + } + route: { + v3: { CorsPolicy: MessageTypeDefinition Decorator: MessageTypeDefinition DirectResponseAction: MessageTypeDefinition FilterAction: MessageTypeDefinition + FilterConfig: MessageTypeDefinition HeaderMatcher: MessageTypeDefinition HedgePolicy: MessageTypeDefinition + InternalRedirectPolicy: MessageTypeDefinition QueryParameterMatcher: MessageTypeDefinition RateLimit: MessageTypeDefinition RedirectAction: MessageTypeDefinition RetryPolicy: MessageTypeDefinition Route: MessageTypeDefinition RouteAction: MessageTypeDefinition + RouteConfiguration: MessageTypeDefinition RouteMatch: MessageTypeDefinition + ScopedRouteConfiguration: MessageTypeDefinition Tracing: MessageTypeDefinition + Vhds: MessageTypeDefinition VirtualCluster: MessageTypeDefinition VirtualHost: MessageTypeDefinition WeightedCluster: MessageTypeDefinition } } - } - config: { - filter: { - accesslog: { - v2: { - AccessLog: MessageTypeDefinition - AccessLogFilter: MessageTypeDefinition - AndFilter: MessageTypeDefinition - ComparisonFilter: MessageTypeDefinition - DurationFilter: MessageTypeDefinition - ExtensionFilter: MessageTypeDefinition - GrpcStatusFilter: MessageTypeDefinition - HeaderFilter: MessageTypeDefinition - NotHealthCheckFilter: MessageTypeDefinition - OrFilter: MessageTypeDefinition - ResponseFlagFilter: MessageTypeDefinition - RuntimeFilter: MessageTypeDefinition - StatusCodeFilter: MessageTypeDefinition - TraceableFilter: MessageTypeDefinition - } + trace: { + v3: { + Tracing: MessageTypeDefinition } + } + } + extensions: { + filters: { network: { http_connection_manager: { - v2: { + v3: { HttpConnectionManager: MessageTypeDefinition HttpFilter: MessageTypeDefinition + LocalReplyConfig: MessageTypeDefinition Rds: MessageTypeDefinition RequestIDExtension: MessageTypeDefinition + ResponseMapper: MessageTypeDefinition ScopedRds: MessageTypeDefinition ScopedRouteConfigurationsList: MessageTypeDefinition ScopedRoutes: MessageTypeDefinition @@ -115,36 +136,39 @@ export interface ProtoGrpcType { } } } - trace: { - v2: { - Tracing: MessageTypeDefinition - } - } } type: { - DoubleRange: MessageTypeDefinition - FractionalPercent: MessageTypeDefinition - Int32Range: MessageTypeDefinition - Int64Range: MessageTypeDefinition - Percent: MessageTypeDefinition - SemanticVersion: MessageTypeDefinition matcher: { - ListStringMatcher: MessageTypeDefinition - RegexMatchAndSubstitute: MessageTypeDefinition - RegexMatcher: MessageTypeDefinition - StringMatcher: MessageTypeDefinition + v3: { + DoubleMatcher: MessageTypeDefinition + ListMatcher: MessageTypeDefinition + ListStringMatcher: MessageTypeDefinition + MetadataMatcher: MessageTypeDefinition + RegexMatchAndSubstitute: MessageTypeDefinition + RegexMatcher: MessageTypeDefinition + StringMatcher: MessageTypeDefinition + ValueMatcher: MessageTypeDefinition + } } metadata: { - v2: { + v3: { MetadataKey: MessageTypeDefinition MetadataKind: MessageTypeDefinition } } tracing: { - v2: { + v3: { CustomTag: MessageTypeDefinition } } + v3: { + DoubleRange: MessageTypeDefinition + FractionalPercent: MessageTypeDefinition + Int32Range: MessageTypeDefinition + Int64Range: MessageTypeDefinition + Percent: MessageTypeDefinition + SemanticVersion: MessageTypeDefinition + } } } google: { @@ -191,10 +215,12 @@ export interface ProtoGrpcType { udpa: { annotations: { FieldMigrateAnnotation: MessageTypeDefinition + FieldSecurityAnnotation: MessageTypeDefinition FileMigrateAnnotation: MessageTypeDefinition MigrateAnnotation: MessageTypeDefinition PackageVersionStatus: EnumTypeDefinition StatusAnnotation: MessageTypeDefinition + VersioningAnnotation: MessageTypeDefinition } } validate: { @@ -223,5 +249,12 @@ export interface ProtoGrpcType { UInt32Rules: MessageTypeDefinition UInt64Rules: MessageTypeDefinition } + xds: { + core: { + v3: { + Authority: MessageTypeDefinition + } + } + } } diff --git a/packages/grpc-js-xds/src/generated/listener.ts b/packages/grpc-js-xds/src/generated/listener.ts index ab67cd096..69454efdc 100644 --- a/packages/grpc-js-xds/src/generated/listener.ts +++ b/packages/grpc-js-xds/src/generated/listener.ts @@ -10,23 +10,28 @@ export interface ProtoGrpcType { envoy: { annotations: { } - api: { - v2: { - Listener: MessageTypeDefinition - auth: { - CertificateValidationContext: MessageTypeDefinition - CommonTlsContext: MessageTypeDefinition - DownstreamTlsContext: MessageTypeDefinition - GenericSecret: MessageTypeDefinition - PrivateKeyProvider: MessageTypeDefinition - SdsSecretConfig: MessageTypeDefinition - Secret: MessageTypeDefinition - TlsCertificate: MessageTypeDefinition - TlsParameters: MessageTypeDefinition - TlsSessionTicketKeys: MessageTypeDefinition - UpstreamTlsContext: MessageTypeDefinition + config: { + accesslog: { + v3: { + AccessLog: MessageTypeDefinition + AccessLogFilter: MessageTypeDefinition + AndFilter: MessageTypeDefinition + ComparisonFilter: MessageTypeDefinition + DurationFilter: MessageTypeDefinition + ExtensionFilter: MessageTypeDefinition + GrpcStatusFilter: MessageTypeDefinition + HeaderFilter: MessageTypeDefinition + MetadataFilter: MessageTypeDefinition + NotHealthCheckFilter: MessageTypeDefinition + OrFilter: MessageTypeDefinition + ResponseFlagFilter: MessageTypeDefinition + RuntimeFilter: MessageTypeDefinition + StatusCodeFilter: MessageTypeDefinition + TraceableFilter: MessageTypeDefinition } - core: { + } + core: { + v3: { Address: MessageTypeDefinition AggregatedConfigSource: MessageTypeDefinition ApiConfigSource: MessageTypeDefinition @@ -39,7 +44,9 @@ export interface ProtoGrpcType { ConfigSource: MessageTypeDefinition ControlPlane: MessageTypeDefinition DataSource: MessageTypeDefinition + EnvoyInternalAddress: MessageTypeDefinition Extension: MessageTypeDefinition + ExtensionConfigSource: MessageTypeDefinition GrpcService: MessageTypeDefinition HeaderMap: MessageTypeDefinition HeaderValue: MessageTypeDefinition @@ -49,6 +56,7 @@ export interface ProtoGrpcType { Metadata: MessageTypeDefinition Node: MessageTypeDefinition Pipe: MessageTypeDefinition + ProxyProtocolConfig: MessageTypeDefinition RateLimitSettings: MessageTypeDefinition RemoteDataSource: MessageTypeDefinition RequestMethod: EnumTypeDefinition @@ -57,6 +65,7 @@ export interface ProtoGrpcType { RuntimeDouble: MessageTypeDefinition RuntimeFeatureFlag: MessageTypeDefinition RuntimeFractionalPercent: MessageTypeDefinition + RuntimePercent: MessageTypeDefinition RuntimeUInt32: MessageTypeDefinition SelfConfigSource: MessageTypeDefinition SocketAddress: MessageTypeDefinition @@ -64,23 +73,34 @@ export interface ProtoGrpcType { TcpKeepalive: MessageTypeDefinition TrafficDirection: EnumTypeDefinition TransportSocket: MessageTypeDefinition + TypedExtensionConfig: MessageTypeDefinition + WatchedDirectory: MessageTypeDefinition } - listener: { + } + listener: { + v3: { ActiveRawUdpListenerConfig: MessageTypeDefinition + ApiListener: MessageTypeDefinition Filter: MessageTypeDefinition FilterChain: MessageTypeDefinition FilterChainMatch: MessageTypeDefinition + Listener: MessageTypeDefinition + ListenerCollection: MessageTypeDefinition ListenerFilter: MessageTypeDefinition ListenerFilterChainMatchPredicate: MessageTypeDefinition UdpListenerConfig: MessageTypeDefinition } - route: { + } + route: { + v3: { CorsPolicy: MessageTypeDefinition Decorator: MessageTypeDefinition DirectResponseAction: MessageTypeDefinition FilterAction: MessageTypeDefinition + FilterConfig: MessageTypeDefinition HeaderMatcher: MessageTypeDefinition HedgePolicy: MessageTypeDefinition + InternalRedirectPolicy: MessageTypeDefinition QueryParameterMatcher: MessageTypeDefinition RateLimit: MessageTypeDefinition RedirectAction: MessageTypeDefinition @@ -95,65 +115,41 @@ export interface ProtoGrpcType { } } } - config: { - filter: { - accesslog: { - v2: { - AccessLog: MessageTypeDefinition - AccessLogFilter: MessageTypeDefinition - AndFilter: MessageTypeDefinition - ComparisonFilter: MessageTypeDefinition - DurationFilter: MessageTypeDefinition - ExtensionFilter: MessageTypeDefinition - GrpcStatusFilter: MessageTypeDefinition - HeaderFilter: MessageTypeDefinition - NotHealthCheckFilter: MessageTypeDefinition - OrFilter: MessageTypeDefinition - ResponseFlagFilter: MessageTypeDefinition - RuntimeFilter: MessageTypeDefinition - StatusCodeFilter: MessageTypeDefinition - TraceableFilter: MessageTypeDefinition - } - } - } - listener: { - v2: { - ApiListener: MessageTypeDefinition - } - } - } type: { - DoubleRange: MessageTypeDefinition - FractionalPercent: MessageTypeDefinition - Int32Range: MessageTypeDefinition - Int64Range: MessageTypeDefinition - Percent: MessageTypeDefinition - SemanticVersion: MessageTypeDefinition matcher: { - ListStringMatcher: MessageTypeDefinition - RegexMatchAndSubstitute: MessageTypeDefinition - RegexMatcher: MessageTypeDefinition - StringMatcher: MessageTypeDefinition + v3: { + DoubleMatcher: MessageTypeDefinition + ListMatcher: MessageTypeDefinition + ListStringMatcher: MessageTypeDefinition + MetadataMatcher: MessageTypeDefinition + RegexMatchAndSubstitute: MessageTypeDefinition + RegexMatcher: MessageTypeDefinition + StringMatcher: MessageTypeDefinition + ValueMatcher: MessageTypeDefinition + } } metadata: { - v2: { + v3: { MetadataKey: MessageTypeDefinition MetadataKind: MessageTypeDefinition } } tracing: { - v2: { + v3: { CustomTag: MessageTypeDefinition } } + v3: { + DoubleRange: MessageTypeDefinition + FractionalPercent: MessageTypeDefinition + Int32Range: MessageTypeDefinition + Int64Range: MessageTypeDefinition + Percent: MessageTypeDefinition + SemanticVersion: MessageTypeDefinition + } } } google: { - api: { - CustomHttpPattern: MessageTypeDefinition - Http: MessageTypeDefinition - HttpRule: MessageTypeDefinition - } protobuf: { Any: MessageTypeDefinition BoolValue: MessageTypeDefinition @@ -197,10 +193,12 @@ export interface ProtoGrpcType { udpa: { annotations: { FieldMigrateAnnotation: MessageTypeDefinition + FieldSecurityAnnotation: MessageTypeDefinition FileMigrateAnnotation: MessageTypeDefinition MigrateAnnotation: MessageTypeDefinition PackageVersionStatus: EnumTypeDefinition StatusAnnotation: MessageTypeDefinition + VersioningAnnotation: MessageTypeDefinition } } validate: { @@ -229,5 +227,15 @@ export interface ProtoGrpcType { UInt32Rules: MessageTypeDefinition UInt64Rules: MessageTypeDefinition } + xds: { + core: { + v3: { + Authority: MessageTypeDefinition + CollectionEntry: MessageTypeDefinition + ContextParams: MessageTypeDefinition + ResourceLocator: MessageTypeDefinition + } + } + } } diff --git a/packages/grpc-js-xds/src/generated/lrs.ts b/packages/grpc-js-xds/src/generated/lrs.ts index f3f180807..9a2864fcf 100644 --- a/packages/grpc-js-xds/src/generated/lrs.ts +++ b/packages/grpc-js-xds/src/generated/lrs.ts @@ -2,6 +2,7 @@ import type * as grpc from '@grpc/grpc-js'; import type { ServiceDefinition, EnumTypeDefinition, MessageTypeDefinition } from '@grpc/proto-loader'; import type { LoadReportingServiceClient as _envoy_service_load_stats_v2_LoadReportingServiceClient } from './envoy/service/load_stats/v2/LoadReportingService'; +import type { LoadReportingServiceClient as _envoy_service_load_stats_v3_LoadReportingServiceClient } from './envoy/service/load_stats/v3/LoadReportingService'; type SubtypeConstructor any, Subtype> = { new(...args: ConstructorParameters): Subtype; @@ -51,6 +52,53 @@ export interface ProtoGrpcType { } } } + config: { + core: { + v3: { + Address: MessageTypeDefinition + AsyncDataSource: MessageTypeDefinition + BackoffStrategy: MessageTypeDefinition + BindConfig: MessageTypeDefinition + BuildVersion: MessageTypeDefinition + CidrRange: MessageTypeDefinition + ControlPlane: MessageTypeDefinition + DataSource: MessageTypeDefinition + EnvoyInternalAddress: MessageTypeDefinition + Extension: MessageTypeDefinition + HeaderMap: MessageTypeDefinition + HeaderValue: MessageTypeDefinition + HeaderValueOption: MessageTypeDefinition + HttpUri: MessageTypeDefinition + Locality: MessageTypeDefinition + Metadata: MessageTypeDefinition + Node: MessageTypeDefinition + Pipe: MessageTypeDefinition + RemoteDataSource: MessageTypeDefinition + RequestMethod: EnumTypeDefinition + RetryPolicy: MessageTypeDefinition + RoutingPriority: EnumTypeDefinition + RuntimeDouble: MessageTypeDefinition + RuntimeFeatureFlag: MessageTypeDefinition + RuntimeFractionalPercent: MessageTypeDefinition + RuntimePercent: MessageTypeDefinition + RuntimeUInt32: MessageTypeDefinition + SocketAddress: MessageTypeDefinition + SocketOption: MessageTypeDefinition + TcpKeepalive: MessageTypeDefinition + TrafficDirection: EnumTypeDefinition + TransportSocket: MessageTypeDefinition + WatchedDirectory: MessageTypeDefinition + } + } + endpoint: { + v3: { + ClusterStats: MessageTypeDefinition + EndpointLoadMetricStats: MessageTypeDefinition + UpstreamEndpointStats: MessageTypeDefinition + UpstreamLocalityStats: MessageTypeDefinition + } + } + } service: { load_stats: { v2: { @@ -58,12 +106,22 @@ export interface ProtoGrpcType { LoadStatsRequest: MessageTypeDefinition LoadStatsResponse: MessageTypeDefinition } + v3: { + LoadReportingService: SubtypeConstructor & { service: ServiceDefinition } + LoadStatsRequest: MessageTypeDefinition + LoadStatsResponse: MessageTypeDefinition + } } } type: { FractionalPercent: MessageTypeDefinition Percent: MessageTypeDefinition SemanticVersion: MessageTypeDefinition + v3: { + FractionalPercent: MessageTypeDefinition + Percent: MessageTypeDefinition + SemanticVersion: MessageTypeDefinition + } } } google: { @@ -113,6 +171,7 @@ export interface ProtoGrpcType { MigrateAnnotation: MessageTypeDefinition PackageVersionStatus: EnumTypeDefinition StatusAnnotation: MessageTypeDefinition + VersioningAnnotation: MessageTypeDefinition } } validate: { diff --git a/packages/grpc-js-xds/src/generated/route.ts b/packages/grpc-js-xds/src/generated/route.ts index 05332fe37..a51060779 100644 --- a/packages/grpc-js-xds/src/generated/route.ts +++ b/packages/grpc-js-xds/src/generated/route.ts @@ -10,11 +10,9 @@ export interface ProtoGrpcType { envoy: { annotations: { } - api: { - v2: { - RouteConfiguration: MessageTypeDefinition - Vhds: MessageTypeDefinition - core: { + config: { + core: { + v3: { Address: MessageTypeDefinition AggregatedConfigSource: MessageTypeDefinition ApiConfigSource: MessageTypeDefinition @@ -27,7 +25,9 @@ export interface ProtoGrpcType { ConfigSource: MessageTypeDefinition ControlPlane: MessageTypeDefinition DataSource: MessageTypeDefinition + EnvoyInternalAddress: MessageTypeDefinition Extension: MessageTypeDefinition + ExtensionConfigSource: MessageTypeDefinition GrpcService: MessageTypeDefinition HeaderMap: MessageTypeDefinition HeaderValue: MessageTypeDefinition @@ -37,6 +37,7 @@ export interface ProtoGrpcType { Metadata: MessageTypeDefinition Node: MessageTypeDefinition Pipe: MessageTypeDefinition + ProxyProtocolConfig: MessageTypeDefinition RateLimitSettings: MessageTypeDefinition RemoteDataSource: MessageTypeDefinition RequestMethod: EnumTypeDefinition @@ -45,6 +46,7 @@ export interface ProtoGrpcType { RuntimeDouble: MessageTypeDefinition RuntimeFeatureFlag: MessageTypeDefinition RuntimeFractionalPercent: MessageTypeDefinition + RuntimePercent: MessageTypeDefinition RuntimeUInt32: MessageTypeDefinition SelfConfigSource: MessageTypeDefinition SocketAddress: MessageTypeDefinition @@ -52,22 +54,30 @@ export interface ProtoGrpcType { TcpKeepalive: MessageTypeDefinition TrafficDirection: EnumTypeDefinition TransportSocket: MessageTypeDefinition + TypedExtensionConfig: MessageTypeDefinition + WatchedDirectory: MessageTypeDefinition } - route: { + } + route: { + v3: { CorsPolicy: MessageTypeDefinition Decorator: MessageTypeDefinition DirectResponseAction: MessageTypeDefinition FilterAction: MessageTypeDefinition + FilterConfig: MessageTypeDefinition HeaderMatcher: MessageTypeDefinition HedgePolicy: MessageTypeDefinition + InternalRedirectPolicy: MessageTypeDefinition QueryParameterMatcher: MessageTypeDefinition RateLimit: MessageTypeDefinition RedirectAction: MessageTypeDefinition RetryPolicy: MessageTypeDefinition Route: MessageTypeDefinition RouteAction: MessageTypeDefinition + RouteConfiguration: MessageTypeDefinition RouteMatch: MessageTypeDefinition Tracing: MessageTypeDefinition + Vhds: MessageTypeDefinition VirtualCluster: MessageTypeDefinition VirtualHost: MessageTypeDefinition WeightedCluster: MessageTypeDefinition @@ -75,29 +85,33 @@ export interface ProtoGrpcType { } } type: { - DoubleRange: MessageTypeDefinition - FractionalPercent: MessageTypeDefinition - Int32Range: MessageTypeDefinition - Int64Range: MessageTypeDefinition - Percent: MessageTypeDefinition - SemanticVersion: MessageTypeDefinition matcher: { - ListStringMatcher: MessageTypeDefinition - RegexMatchAndSubstitute: MessageTypeDefinition - RegexMatcher: MessageTypeDefinition - StringMatcher: MessageTypeDefinition + v3: { + ListStringMatcher: MessageTypeDefinition + RegexMatchAndSubstitute: MessageTypeDefinition + RegexMatcher: MessageTypeDefinition + StringMatcher: MessageTypeDefinition + } } metadata: { - v2: { + v3: { MetadataKey: MessageTypeDefinition MetadataKind: MessageTypeDefinition } } tracing: { - v2: { + v3: { CustomTag: MessageTypeDefinition } } + v3: { + DoubleRange: MessageTypeDefinition + FractionalPercent: MessageTypeDefinition + Int32Range: MessageTypeDefinition + Int64Range: MessageTypeDefinition + Percent: MessageTypeDefinition + SemanticVersion: MessageTypeDefinition + } } } google: { @@ -148,6 +162,7 @@ export interface ProtoGrpcType { MigrateAnnotation: MessageTypeDefinition PackageVersionStatus: EnumTypeDefinition StatusAnnotation: MessageTypeDefinition + VersioningAnnotation: MessageTypeDefinition } } validate: { @@ -176,5 +191,12 @@ export interface ProtoGrpcType { UInt32Rules: MessageTypeDefinition UInt64Rules: MessageTypeDefinition } + xds: { + core: { + v3: { + Authority: MessageTypeDefinition + } + } + } } diff --git a/packages/grpc-js-xds/src/generated/udpa/annotations/FieldSecurityAnnotation.ts b/packages/grpc-js-xds/src/generated/udpa/annotations/FieldSecurityAnnotation.ts new file mode 100644 index 000000000..13d48b5ce --- /dev/null +++ b/packages/grpc-js-xds/src/generated/udpa/annotations/FieldSecurityAnnotation.ts @@ -0,0 +1,32 @@ +// Original file: deps/udpa/udpa/annotations/security.proto + + +/** + * These annotations indicate metadata for the purpose of understanding the + * security significance of fields. + */ +export interface FieldSecurityAnnotation { + /** + * Field should be set in the presence of untrusted downstreams. + */ + 'configure_for_untrusted_downstream'?: (boolean); + /** + * Field should be set in the presence of untrusted upstreams. + */ + 'configure_for_untrusted_upstream'?: (boolean); +} + +/** + * These annotations indicate metadata for the purpose of understanding the + * security significance of fields. + */ +export interface FieldSecurityAnnotation__Output { + /** + * Field should be set in the presence of untrusted downstreams. + */ + 'configure_for_untrusted_downstream': (boolean); + /** + * Field should be set in the presence of untrusted upstreams. + */ + 'configure_for_untrusted_upstream': (boolean); +} diff --git a/packages/grpc-js-xds/src/generated/udpa/annotations/VersioningAnnotation.ts b/packages/grpc-js-xds/src/generated/udpa/annotations/VersioningAnnotation.ts new file mode 100644 index 000000000..1a3d09dc8 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/udpa/annotations/VersioningAnnotation.ts @@ -0,0 +1,20 @@ +// Original file: deps/udpa/udpa/annotations/versioning.proto + + +export interface VersioningAnnotation { + /** + * Track the previous message type. E.g. this message might be + * udpa.foo.v3alpha.Foo and it was previously udpa.bar.v2.Bar. This + * information is consumed by UDPA via proto descriptors. + */ + 'previous_message_type'?: (string); +} + +export interface VersioningAnnotation__Output { + /** + * Track the previous message type. E.g. this message might be + * udpa.foo.v3alpha.Foo and it was previously udpa.bar.v2.Bar. This + * information is consumed by UDPA via proto descriptors. + */ + 'previous_message_type': (string); +} diff --git a/packages/grpc-js-xds/src/generated/validate/DoubleRules.ts b/packages/grpc-js-xds/src/generated/validate/DoubleRules.ts index fead5072a..e756c86b9 100644 --- a/packages/grpc-js-xds/src/generated/validate/DoubleRules.ts +++ b/packages/grpc-js-xds/src/generated/validate/DoubleRules.ts @@ -50,37 +50,37 @@ export interface DoubleRules__Output { /** * Const specifies that this field must be exactly the specified value */ - 'const': (number | string); + 'const': (number); /** * Lt specifies that this field must be less than the specified value, * exclusive */ - 'lt': (number | string); + 'lt': (number); /** * Lte specifies that this field must be less than or equal to the * specified value, inclusive */ - 'lte': (number | string); + 'lte': (number); /** * Gt specifies that this field must be greater than the specified value, * exclusive. If the value of Gt is larger than a specified Lt or Lte, the * range is reversed. */ - 'gt': (number | string); + 'gt': (number); /** * Gte specifies that this field must be greater than or equal to the * specified value, inclusive. If the value of Gte is larger than a * specified Lt or Lte, the range is reversed. */ - 'gte': (number | string); + 'gte': (number); /** * In specifies that this field must be equal to one of the specified * values */ - 'in': (number | string)[]; + 'in': (number)[]; /** * NotIn specifies that this field cannot be equal to one of the specified * values */ - 'not_in': (number | string)[]; + 'not_in': (number)[]; } diff --git a/packages/grpc-js-xds/src/generated/validate/FloatRules.ts b/packages/grpc-js-xds/src/generated/validate/FloatRules.ts index 35aafa809..8d5244c2b 100644 --- a/packages/grpc-js-xds/src/generated/validate/FloatRules.ts +++ b/packages/grpc-js-xds/src/generated/validate/FloatRules.ts @@ -50,37 +50,37 @@ export interface FloatRules__Output { /** * Const specifies that this field must be exactly the specified value */ - 'const': (number | string); + 'const': (number); /** * Lt specifies that this field must be less than the specified value, * exclusive */ - 'lt': (number | string); + 'lt': (number); /** * Lte specifies that this field must be less than or equal to the * specified value, inclusive */ - 'lte': (number | string); + 'lte': (number); /** * Gt specifies that this field must be greater than the specified value, * exclusive. If the value of Gt is larger than a specified Lt or Lte, the * range is reversed. */ - 'gt': (number | string); + 'gt': (number); /** * Gte specifies that this field must be greater than or equal to the * specified value, inclusive. If the value of Gte is larger than a * specified Lt or Lte, the range is reversed. */ - 'gte': (number | string); + 'gte': (number); /** * In specifies that this field must be equal to one of the specified * values */ - 'in': (number | string)[]; + 'in': (number)[]; /** * NotIn specifies that this field cannot be equal to one of the specified * values */ - 'not_in': (number | string)[]; + 'not_in': (number)[]; } diff --git a/packages/grpc-js-xds/src/generated/xds/core/v3/Authority.ts b/packages/grpc-js-xds/src/generated/xds/core/v3/Authority.ts new file mode 100644 index 000000000..8e9211838 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/xds/core/v3/Authority.ts @@ -0,0 +1,16 @@ +// Original file: deps/udpa/xds/core/v3/authority.proto + + +/** + * xDS authority information. + */ +export interface Authority { + 'name'?: (string); +} + +/** + * xDS authority information. + */ +export interface Authority__Output { + 'name': (string); +} diff --git a/packages/grpc-js-xds/src/generated/xds/core/v3/CollectionEntry.ts b/packages/grpc-js-xds/src/generated/xds/core/v3/CollectionEntry.ts new file mode 100644 index 000000000..4a9a45527 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/xds/core/v3/CollectionEntry.ts @@ -0,0 +1,90 @@ +// Original file: deps/udpa/xds/core/v3/collection_entry.proto + +import type { ResourceLocator as _xds_core_v3_ResourceLocator, ResourceLocator__Output as _xds_core_v3_ResourceLocator__Output } from '../../../xds/core/v3/ResourceLocator'; +import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any'; + +/** + * Inlined resource entry. + */ +export interface _xds_core_v3_CollectionEntry_InlineEntry { + /** + * Optional name to describe the inlined resource. Resource names must + * [a-zA-Z0-9_-\./]+ (TODO(htuch): turn this into a PGV constraint once + * finalized, probably should be a RFC3986 pchar). This name allows + * reference via the #entry directive in ResourceLocator. + */ + 'name'?: (string); + /** + * The resource's logical version. It is illegal to have the same named xDS + * resource name at a given version with different resource payloads. + */ + 'version'?: (string); + /** + * The resource payload, including type URL. + */ + 'resource'?: (_google_protobuf_Any); +} + +/** + * Inlined resource entry. + */ +export interface _xds_core_v3_CollectionEntry_InlineEntry__Output { + /** + * Optional name to describe the inlined resource. Resource names must + * [a-zA-Z0-9_-\./]+ (TODO(htuch): turn this into a PGV constraint once + * finalized, probably should be a RFC3986 pchar). This name allows + * reference via the #entry directive in ResourceLocator. + */ + 'name': (string); + /** + * The resource's logical version. It is illegal to have the same named xDS + * resource name at a given version with different resource payloads. + */ + 'version': (string); + /** + * The resource payload, including type URL. + */ + 'resource'?: (_google_protobuf_Any__Output); +} + +/** + * xDS collection resource wrapper. This encapsulates a xDS resource when + * appearing inside a list collection resource. List collection resources are + * regular Resource messages of type: + * + * message Collection { + * repeated CollectionEntry resources = 1; + * } + */ +export interface CollectionEntry { + /** + * A resource locator describing how the member resource is to be located. + */ + 'locator'?: (_xds_core_v3_ResourceLocator); + /** + * The resource is inlined in the list collection. + */ + 'inline_entry'?: (_xds_core_v3_CollectionEntry_InlineEntry); + 'resource_specifier'?: "locator"|"inline_entry"; +} + +/** + * xDS collection resource wrapper. This encapsulates a xDS resource when + * appearing inside a list collection resource. List collection resources are + * regular Resource messages of type: + * + * message Collection { + * repeated CollectionEntry resources = 1; + * } + */ +export interface CollectionEntry__Output { + /** + * A resource locator describing how the member resource is to be located. + */ + 'locator'?: (_xds_core_v3_ResourceLocator__Output); + /** + * The resource is inlined in the list collection. + */ + 'inline_entry'?: (_xds_core_v3_CollectionEntry_InlineEntry__Output); + 'resource_specifier': "locator"|"inline_entry"; +} diff --git a/packages/grpc-js-xds/src/generated/xds/core/v3/ContextParams.ts b/packages/grpc-js-xds/src/generated/xds/core/v3/ContextParams.ts new file mode 100644 index 000000000..f9c57249c --- /dev/null +++ b/packages/grpc-js-xds/src/generated/xds/core/v3/ContextParams.ts @@ -0,0 +1,26 @@ +// Original file: deps/udpa/xds/core/v3/context_params.proto + + +/** + * Additional parameters that can be used to select resource variants. These include any + * global context parameters, per-resource type client feature capabilities and per-resource + * type functional attributes. All per-resource type attributes will be `xds.resource.` + * prefixed and some of these are documented below: + * `xds.resource.listening_address`: The value is "IP:port" (e.g. "10.1.1.3:8080") which is + * the listening address of a Listener. Used in a Listener resource query. + */ +export interface ContextParams { + 'params'?: ({[key: string]: string}); +} + +/** + * Additional parameters that can be used to select resource variants. These include any + * global context parameters, per-resource type client feature capabilities and per-resource + * type functional attributes. All per-resource type attributes will be `xds.resource.` + * prefixed and some of these are documented below: + * `xds.resource.listening_address`: The value is "IP:port" (e.g. "10.1.1.3:8080") which is + * the listening address of a Listener. Used in a Listener resource query. + */ +export interface ContextParams__Output { + 'params': ({[key: string]: string}); +} 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 new file mode 100644 index 000000000..f28a31d20 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/xds/core/v3/ResourceLocator.ts @@ -0,0 +1,220 @@ +// Original file: deps/udpa/xds/core/v3/resource_locator.proto + +import type { ContextParams as _xds_core_v3_ContextParams, ContextParams__Output as _xds_core_v3_ContextParams__Output } from '../../../xds/core/v3/ContextParams'; +import type { ResourceLocator as _xds_core_v3_ResourceLocator, ResourceLocator__Output as _xds_core_v3_ResourceLocator__Output } from '../../../xds/core/v3/ResourceLocator'; + +/** + * Directives provide information to data-plane load balancers on how xDS + * resource names are to be interpreted and potentially further resolved. For + * example, they may provide alternative resource locators for when primary + * resolution fails. Directives are not part of resource names and do not + * appear in a xDS transport discovery request. + * + * When encoding to URIs, directives take the form: + * + * = + * + * For example, we can have alt=xdstp://foo/bar or entry=some%20thing. Each + * directive value type may have its own string encoding, in the case of + * ResourceLocator there is a recursive URI encoding. + * + * Percent encoding applies to the URI encoding of the directive value. + * Multiple directives are comma-separated, so the reserved characters that + * require percent encoding in a directive value are [',', '#', '[', ']', + * '%']. These are the RFC3986 fragment reserved characters with the addition + * of the xDS scheme specific ','. See + * https://tools.ietf.org/html/rfc3986#page-49 for further details on URI ABNF + * and reserved characters. + */ +export interface _xds_core_v3_ResourceLocator_Directive { + /** + * An alternative resource locator for fallback if the resource is + * unavailable. For example, take the resource locator: + * + * xdstp://foo/some-type/some-route-table#alt=xdstp://bar/some-type/another-route-table + * + * If the data-plane load balancer is unable to reach `foo` to fetch the + * resource, it will fallback to `bar`. Alternative resources do not need + * to have equivalent content, but they should be functional substitutes. + */ + 'alt'?: (_xds_core_v3_ResourceLocator); + /** + * List collections support inlining of resources via the entry field in + * Resource. These inlined Resource objects may have an optional name + * field specified. When specified, the entry directive allows + * ResourceLocator to directly reference these inlined resources, e.g. + * xdstp://.../foo#entry=bar. + */ + 'entry'?: (string); + 'directive'?: "alt"|"entry"; +} + +/** + * Directives provide information to data-plane load balancers on how xDS + * resource names are to be interpreted and potentially further resolved. For + * example, they may provide alternative resource locators for when primary + * resolution fails. Directives are not part of resource names and do not + * appear in a xDS transport discovery request. + * + * When encoding to URIs, directives take the form: + * + * = + * + * For example, we can have alt=xdstp://foo/bar or entry=some%20thing. Each + * directive value type may have its own string encoding, in the case of + * ResourceLocator there is a recursive URI encoding. + * + * Percent encoding applies to the URI encoding of the directive value. + * Multiple directives are comma-separated, so the reserved characters that + * require percent encoding in a directive value are [',', '#', '[', ']', + * '%']. These are the RFC3986 fragment reserved characters with the addition + * of the xDS scheme specific ','. See + * https://tools.ietf.org/html/rfc3986#page-49 for further details on URI ABNF + * and reserved characters. + */ +export interface _xds_core_v3_ResourceLocator_Directive__Output { + /** + * An alternative resource locator for fallback if the resource is + * unavailable. For example, take the resource locator: + * + * xdstp://foo/some-type/some-route-table#alt=xdstp://bar/some-type/another-route-table + * + * If the data-plane load balancer is unable to reach `foo` to fetch the + * resource, it will fallback to `bar`. Alternative resources do not need + * to have equivalent content, but they should be functional substitutes. + */ + 'alt'?: (_xds_core_v3_ResourceLocator__Output); + /** + * List collections support inlining of resources via the entry field in + * Resource. These inlined Resource objects may have an optional name + * field specified. When specified, the entry directive allows + * ResourceLocator to directly reference these inlined resources, e.g. + * xdstp://.../foo#entry=bar. + */ + 'entry'?: (string); + 'directive': "alt"|"entry"; +} + +// Original file: deps/udpa/xds/core/v3/resource_locator.proto + +export enum _xds_core_v3_ResourceLocator_Scheme { + XDSTP = 0, + HTTP = 1, + FILE = 2, +} + +/** + * xDS resource locators identify a xDS resource name and instruct the + * data-plane load balancer on how the resource may be located. + * + * Resource locators have a canonical xdstp:// URI representation: + * + * xdstp://{authority}/{type_url}/{id}?{context_params}{#directive,*} + * + * where context_params take the form of URI query parameters. + * + * Resource locators have a similar canonical http:// URI representation: + * + * http://{authority}/{type_url}/{id}?{context_params}{#directive,*} + * + * Resource locators also have a simplified file:// URI representation: + * + * file:///{id}{#directive,*} + */ +export interface ResourceLocator { + /** + * URI scheme. + */ + 'scheme'?: (_xds_core_v3_ResourceLocator_Scheme | keyof typeof _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 + * with ‘*’ for glob collection references. + */ + 'id'?: (string); + /** + * Logical authority for resource (not necessarily transport network address). + * Authorities are opaque in the xDS API, data-plane load balancers will map + * them to concrete network transports such as an xDS management server, e.g. + * via envoy.config.core.v3.ConfigSource. + */ + 'authority'?: (string); + /** + * Fully qualified resource type (as in type URL without types.googleapis.com/ + * prefix). + */ + 'resource_type'?: (string); + /** + * Additional parameters that can be used to select resource variants. + * Matches must be exact, i.e. all context parameters must match exactly and + * there must be no additional context parameters set on the matched + * resource. + */ + 'exact_context'?: (_xds_core_v3_ContextParams); + /** + * A list of directives that appear in the xDS resource locator #fragment. + * + * When encoding to URI form, directives are percent encoded with comma + * separation. + */ + 'directives'?: (_xds_core_v3_ResourceLocator_Directive)[]; + 'context_param_specifier'?: "exact_context"; +} + +/** + * xDS resource locators identify a xDS resource name and instruct the + * data-plane load balancer on how the resource may be located. + * + * Resource locators have a canonical xdstp:// URI representation: + * + * xdstp://{authority}/{type_url}/{id}?{context_params}{#directive,*} + * + * where context_params take the form of URI query parameters. + * + * Resource locators have a similar canonical http:// URI representation: + * + * http://{authority}/{type_url}/{id}?{context_params}{#directive,*} + * + * Resource locators also have a simplified file:// URI representation: + * + * file:///{id}{#directive,*} + */ +export interface ResourceLocator__Output { + /** + * URI scheme. + */ + 'scheme': (keyof typeof _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 + * with ‘*’ for glob collection references. + */ + 'id': (string); + /** + * Logical authority for resource (not necessarily transport network address). + * Authorities are opaque in the xDS API, data-plane load balancers will map + * them to concrete network transports such as an xDS management server, e.g. + * via envoy.config.core.v3.ConfigSource. + */ + 'authority': (string); + /** + * Fully qualified resource type (as in type URL without types.googleapis.com/ + * prefix). + */ + 'resource_type': (string); + /** + * Additional parameters that can be used to select resource variants. + * Matches must be exact, i.e. all context parameters must match exactly and + * there must be no additional context parameters set on the matched + * resource. + */ + 'exact_context'?: (_xds_core_v3_ContextParams__Output); + /** + * A list of directives that appear in the xDS resource locator #fragment. + * + * When encoding to URI form, directives are percent encoded with comma + * separation. + */ + 'directives': (_xds_core_v3_ResourceLocator_Directive__Output)[]; + 'context_param_specifier': "exact_context"; +} From 6711620c1a36dc20ed7609afc2f9f35c53651001 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 14 Apr 2021 14:02:10 -0700 Subject: [PATCH 002/450] grpc-js-xds: Add xDS v3 support to the client Add xDS v3 test job --- packages/grpc-js-xds/scripts/xds-v3.sh | 16 + packages/grpc-js-xds/scripts/xds.sh | 1 + packages/grpc-js-xds/src/load-balancer-cds.ts | 2 +- packages/grpc-js-xds/src/load-balancer-eds.ts | 2 +- packages/grpc-js-xds/src/resolver-xds.ts | 18 +- packages/grpc-js-xds/src/resources.ts | 96 +++ packages/grpc-js-xds/src/xds-bootstrap.ts | 33 +- packages/grpc-js-xds/src/xds-client.ts | 749 +++++++++++------- .../src/xds-stream-state/cds-state.ts | 2 +- .../src/xds-stream-state/eds-state.ts | 2 +- .../src/xds-stream-state/lds-state.ts | 17 +- .../src/xds-stream-state/rds-state.ts | 2 +- test/kokoro/linux.cfg | 3 +- test/kokoro/xds-v3-interop.cfg | 24 + 14 files changed, 661 insertions(+), 306 deletions(-) create mode 100755 packages/grpc-js-xds/scripts/xds-v3.sh mode change 100644 => 100755 packages/grpc-js-xds/scripts/xds.sh create mode 100644 packages/grpc-js-xds/src/resources.ts create mode 100644 test/kokoro/xds-v3-interop.cfg diff --git a/packages/grpc-js-xds/scripts/xds-v3.sh b/packages/grpc-js-xds/scripts/xds-v3.sh new file mode 100755 index 000000000..103cbc429 --- /dev/null +++ b/packages/grpc-js-xds/scripts/xds-v3.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# Copyright 2021 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. + +XDS_V3_OPT="--xds_v3_support" $(dirname $0)/xds.sh \ No newline at end of file diff --git a/packages/grpc-js-xds/scripts/xds.sh b/packages/grpc-js-xds/scripts/xds.sh old mode 100644 new mode 100755 index 714b6fff8..9008b9731 --- a/packages/grpc-js-xds/scripts/xds.sh +++ b/packages/grpc-js-xds/scripts/xds.sh @@ -58,6 +58,7 @@ GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weigh --path_to_server_binary=/java_server/grpc-java/interop-testing/build/install/grpc-interop-testing/bin/xds-test-server \ --gcp_suffix=$(date '+%s') \ --verbose \ + ${XDS_V3_OPT-} \ --client_cmd="$(which node) grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client \ --server=xds:///{server_uri} \ --stats_port={stats_port} \ diff --git a/packages/grpc-js-xds/src/load-balancer-cds.ts b/packages/grpc-js-xds/src/load-balancer-cds.ts index d0fe2338a..6c57a410f 100644 --- a/packages/grpc-js-xds/src/load-balancer-cds.ts +++ b/packages/grpc-js-xds/src/load-balancer-cds.ts @@ -17,7 +17,7 @@ import { connectivityState, status, Metadata, logVerbosity, experimental } from '@grpc/grpc-js'; import { getSingletonXdsClient, XdsClient } from './xds-client'; -import { Cluster__Output } from './generated/envoy/api/v2/Cluster'; +import { Cluster__Output } from './generated/envoy/config/cluster/v3/Cluster'; import SubchannelAddress = experimental.SubchannelAddress; import UnavailablePicker = experimental.UnavailablePicker; import ChildLoadBalancerHandler = experimental.ChildLoadBalancerHandler; diff --git a/packages/grpc-js-xds/src/load-balancer-eds.ts b/packages/grpc-js-xds/src/load-balancer-eds.ts index 657dc3a82..ae9a781bd 100644 --- a/packages/grpc-js-xds/src/load-balancer-eds.ts +++ b/packages/grpc-js-xds/src/load-balancer-eds.ts @@ -17,7 +17,7 @@ import { connectivityState as ConnectivityState, status as Status, Metadata, logVerbosity as LogVerbosity, experimental } from '@grpc/grpc-js'; import { getSingletonXdsClient, XdsClient, XdsClusterDropStats } from './xds-client'; -import { ClusterLoadAssignment__Output } from './generated/envoy/api/v2/ClusterLoadAssignment'; +import { ClusterLoadAssignment__Output } from './generated/envoy/config/endpoint/v3/ClusterLoadAssignment'; import { Locality__Output } from './generated/envoy/api/v2/core/Locality'; import { LocalitySubchannelAddress, PriorityChild, PriorityLoadBalancingConfig } from './load-balancer-priority'; import LoadBalancer = experimental.LoadBalancer; diff --git a/packages/grpc-js-xds/src/resolver-xds.ts b/packages/grpc-js-xds/src/resolver-xds.ts index 102a52349..a9ee1af7d 100644 --- a/packages/grpc-js-xds/src/resolver-xds.ts +++ b/packages/grpc-js-xds/src/resolver-xds.ts @@ -26,20 +26,20 @@ import ResolverListener = experimental.ResolverListener; import uriToString = experimental.uriToString; import ServiceConfig = experimental.ServiceConfig; import registerResolver = experimental.registerResolver; -import { Listener__Output } from './generated/envoy/api/v2/Listener'; +import { Listener__Output } from './generated/envoy/config/listener/v3/Listener'; import { Watcher } from './xds-stream-state/xds-stream-state'; -import { RouteConfiguration__Output } from './generated/envoy/api/v2/RouteConfiguration'; -import { HttpConnectionManager__Output } from './generated/envoy/config/filter/network/http_connection_manager/v2/HttpConnectionManager'; +import { RouteConfiguration__Output } from './generated/envoy/config/route/v3/RouteConfiguration'; +import { HttpConnectionManager__Output } from './generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpConnectionManager'; import { CdsLoadBalancingConfig } from './load-balancer-cds'; -import { VirtualHost__Output } from './generated/envoy/api/v2/route/VirtualHost'; -import { RouteMatch__Output } from './generated/envoy/api/v2/route/RouteMatch'; -import { HeaderMatcher__Output } from './generated/envoy/api/v2/route/HeaderMatcher'; +import { VirtualHost__Output } from './generated/envoy/config/route/v3/VirtualHost'; +import { RouteMatch__Output } from './generated/envoy/config/route/v3/RouteMatch'; +import { HeaderMatcher__Output } from './generated/envoy/config/route/v3/HeaderMatcher'; import ConfigSelector = experimental.ConfigSelector; import LoadBalancingConfig = experimental.LoadBalancingConfig; import { XdsClusterManagerLoadBalancingConfig } from './load-balancer-xds-cluster-manager'; import { ExactValueMatcher, Fraction, FullMatcher, HeaderMatcher, Matcher, PathExactValueMatcher, PathPrefixValueMatcher, PathSafeRegexValueMatcher, PrefixValueMatcher, PresentValueMatcher, RangeValueMatcher, RejectValueMatcher, SafeRegexValueMatcher, SuffixValueMatcher, ValueMatcher } from './matcher'; import { RouteAction, SingleClusterRouteAction, WeightedCluster, WeightedClusterRouteAction } from './route-action'; -import { LogVerbosity } from '@grpc/grpc-js/build/src/constants'; +import { decodeSingleResource, HTTP_CONNECTION_MANGER_TYPE_URL_V3 } from './resources'; const TRACER_NAME = 'xds_resolver'; @@ -210,9 +210,7 @@ class XdsResolver implements Resolver { ) { this.ldsWatcher = { onValidUpdate: (update: Listener__Output) => { - const httpConnectionManager = update.api_listener! - .api_listener as protoLoader.AnyExtension & - HttpConnectionManager__Output; + const httpConnectionManager = decodeSingleResource(HTTP_CONNECTION_MANGER_TYPE_URL_V3, update.api_listener!.api_listener!.value); switch (httpConnectionManager.route_specifier) { case 'rds': { const routeConfigName = httpConnectionManager.rds!.route_config_name; diff --git a/packages/grpc-js-xds/src/resources.ts b/packages/grpc-js-xds/src/resources.ts new file mode 100644 index 000000000..516980de8 --- /dev/null +++ b/packages/grpc-js-xds/src/resources.ts @@ -0,0 +1,96 @@ +/* + * Copyright 2021 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. + * + */ + +// This is a non-public, unstable API, but it's very convenient +import { loadProtosWithOptionsSync } from '@grpc/proto-loader/build/src/util'; +import { Cluster__Output } from './generated/envoy/config/cluster/v3/Cluster'; +import { ClusterLoadAssignment__Output } from './generated/envoy/config/endpoint/v3/ClusterLoadAssignment'; +import { Listener__Output } from './generated/envoy/config/listener/v3/Listener'; +import { RouteConfiguration__Output } from './generated/envoy/config/route/v3/RouteConfiguration'; +import { HttpConnectionManager__Output } from './generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpConnectionManager'; + +export const EDS_TYPE_URL_V2 = 'type.googleapis.com/envoy.api.v2.ClusterLoadAssignment'; +export const CDS_TYPE_URL_V2 = 'type.googleapis.com/envoy.api.v2.Cluster'; +export const LDS_TYPE_URL_V2 = 'type.googleapis.com/envoy.api.v2.Listener'; +export const RDS_TYPE_URL_V2 = 'type.googleapis.com/envoy.api.v2.RouteConfiguration'; + +export const EDS_TYPE_URL_V3 = 'type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment'; +export const CDS_TYPE_URL_V3 = 'type.googleapis.com/envoy.config.cluster.v3.Cluster'; +export const LDS_TYPE_URL_V3 = 'type.googleapis.com/envoy.config.listener.v3.Listener'; +export const RDS_TYPE_URL_V3 = 'type.googleapis.com/envoy.config.route.v3.RouteConfiguration'; + +export type EdsTypeUrl = 'type.googleapis.com/envoy.api.v2.ClusterLoadAssignment' | 'type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment'; +export type CdsTypeUrl = 'type.googleapis.com/envoy.api.v2.Cluster' | 'type.googleapis.com/envoy.config.cluster.v3.Cluster'; +export type LdsTypeUrl = 'type.googleapis.com/envoy.api.v2.Listener' | 'type.googleapis.com/envoy.config.listener.v3.Listener'; +export type RdsTypeUrl = 'type.googleapis.com/envoy.api.v2.RouteConfiguration' | 'type.googleapis.com/envoy.config.route.v3.RouteConfiguration'; + +export type AdsTypeUrl = EdsTypeUrl | CdsTypeUrl | RdsTypeUrl | LdsTypeUrl; + +export const HTTP_CONNECTION_MANGER_TYPE_URL_V2 = + 'type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager'; +export const HTTP_CONNECTION_MANGER_TYPE_URL_V3 = + 'type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager'; + +export type HttpConnectionManagerTypeUrl = 'type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager' | 'type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager'; + +/** + * Map type URLs to their corresponding message types + */ +export type AdsOutputType = T extends EdsTypeUrl + ? ClusterLoadAssignment__Output + : T extends CdsTypeUrl + ? Cluster__Output + : T extends RdsTypeUrl + ? RouteConfiguration__Output + : T extends LdsTypeUrl + ? Listener__Output + : HttpConnectionManager__Output; + +const resourceRoot = loadProtosWithOptionsSync([ + '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'], { + keepCase: true, + includeDirs: [ + // Paths are relative to src/build + __dirname + '/../../deps/envoy-api/', + __dirname + '/../../deps/udpa/', + __dirname + '/../../deps/googleapis/', + __dirname + '/../../deps/protoc-gen-validate/', + ], + } +); + +const toObjectOptions = { + longs: String, + enums: String, + defaults: true, + oneofs: true +} + +export function decodeSingleResource(targetTypeUrl: T, message: Buffer): AdsOutputType { + const name = targetTypeUrl.substring(targetTypeUrl.lastIndexOf('/') + 1); + const type = resourceRoot.lookup(name); + if (type) { + const decodedMessage = (type as any).decode(message); + return decodedMessage.$type.toObject(decodedMessage, toObjectOptions) as AdsOutputType; + } else { + throw new Error(`ADS Error: unknown resource type ${targetTypeUrl}`); + } +} \ No newline at end of file diff --git a/packages/grpc-js-xds/src/xds-bootstrap.ts b/packages/grpc-js-xds/src/xds-bootstrap.ts index 00e13d09f..3da4ec3e6 100644 --- a/packages/grpc-js-xds/src/xds-bootstrap.ts +++ b/packages/grpc-js-xds/src/xds-bootstrap.ts @@ -17,11 +17,23 @@ import * as fs from 'fs'; import { Struct } from './generated/google/protobuf/Struct'; -import { Node } from './generated/envoy/api/v2/core/Node'; import { Value } from './generated/google/protobuf/Value'; /* eslint-disable @typescript-eslint/no-explicit-any */ +export interface Locality { + region?: string; + zone?: string; + sub_zone?: string; +} + +export interface Node { + id: string, + locality: Locality; + cluster?: string; + metadata?: Struct; +} + export interface ChannelCredsConfig { type: string; config?: object; @@ -30,6 +42,7 @@ export interface ChannelCredsConfig { export interface XdsServerConfig { serverUri: string; channelCreds: ChannelCredsConfig[]; + serverFeatures: string[]; } export interface BootstrapInfo { @@ -81,9 +94,22 @@ function validateXdsServerConfig(obj: any): XdsServerConfig { 'xds_servers.channel_creds field: at least one entry is required' ); } + if ('server_features' in obj) { + if (!Array.isArray(obj.server_features)) { + throw new Error( + `xds_servers.server_features field: expected array, got ${typeof obj.server_features}` + ); + } + for (const feature of obj.server_features) { + if (typeof feature !== 'string') { + `xds_servers.server_features field element: expected string, got ${typeof feature}` + } + } + } return { serverUri: obj.server_uri, channelCreds: obj.channel_creds.map(validateChannelCredsConfig), + serverFeatures: obj.server_features }; } @@ -149,7 +175,10 @@ function getStructFromJson(obj: any): Struct { * @param obj */ function validateNode(obj: any): Node { - const result: Node = {}; + const result: Node = { + id: '', + locality: {} + }; if (!('id' in obj)) { throw new Error('id field missing in node element'); } diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index 22d816a03..adc54ed45 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -16,35 +16,26 @@ */ import * as protoLoader from '@grpc/proto-loader'; -import { loadPackageDefinition, StatusObject, status, logVerbosity, Metadata, experimental, ChannelOptions, ClientDuplexStream, ServiceError, ChannelCredentials } from '@grpc/grpc-js'; +// This is a non-public, unstable API, but it's very convenient +import { loadProtosWithOptionsSync } from '@grpc/proto-loader/build/src/util'; +import { loadPackageDefinition, StatusObject, status, logVerbosity, Metadata, experimental, ChannelOptions, ClientDuplexStream, ServiceError, ChannelCredentials, Channel } from '@grpc/grpc-js'; import * as adsTypes from './generated/ads'; import * as lrsTypes from './generated/lrs'; import { loadBootstrapInfo } from './xds-bootstrap'; -import { isIPv4, isIPv6 } from 'net'; -import { Node } from './generated/envoy/api/v2/core/Node'; -import { AggregatedDiscoveryServiceClient } from './generated/envoy/service/discovery/v2/AggregatedDiscoveryService'; -import { DiscoveryRequest } from './generated/envoy/api/v2/DiscoveryRequest'; -import { DiscoveryResponse__Output } from './generated/envoy/api/v2/DiscoveryResponse'; -import { - ClusterLoadAssignment__Output, - ClusterLoadAssignment, -} from './generated/envoy/api/v2/ClusterLoadAssignment'; -import { Cluster__Output } from './generated/envoy/api/v2/Cluster'; -import { LoadReportingServiceClient } from './generated/envoy/service/load_stats/v2/LoadReportingService'; -import { LoadStatsRequest } from './generated/envoy/service/load_stats/v2/LoadStatsRequest'; -import { LoadStatsResponse__Output } from './generated/envoy/service/load_stats/v2/LoadStatsResponse'; -import { - Locality__Output, - Locality, -} from './generated/envoy/api/v2/core/Locality'; -import { - ClusterStats, - _envoy_api_v2_endpoint_ClusterStats_DroppedRequests, -} from './generated/envoy/api/v2/endpoint/ClusterStats'; -import { UpstreamLocalityStats } from './generated/envoy/api/v2/endpoint/UpstreamLocalityStats'; -import { Listener__Output } from './generated/envoy/api/v2/Listener'; -import { HttpConnectionManager__Output } from './generated/envoy/config/filter/network/http_connection_manager/v2/HttpConnectionManager'; -import { RouteConfiguration__Output } from './generated/envoy/api/v2/RouteConfiguration'; +import { Node as NodeV2 } from './generated/envoy/api/v2/core/Node'; +import { Node as NodeV3 } from './generated/envoy/config/core/v3/Node'; +import { AggregatedDiscoveryServiceClient as AggregatedDiscoveryServiceClientV2 } from './generated/envoy/service/discovery/v2/AggregatedDiscoveryService'; +import { AggregatedDiscoveryServiceClient as AggregatedDiscoveryServiceClientV3 } from './generated/envoy/service/discovery/v3/AggregatedDiscoveryService'; +import { DiscoveryRequest as DiscoveryRequestV2 } from './generated/envoy/api/v2/DiscoveryRequest'; +import { DiscoveryRequest as DiscoveryRequestV3 } from './generated/envoy/service/discovery/v3/DiscoveryRequest'; +import { DiscoveryResponse__Output } from './generated/envoy/service/discovery/v3/DiscoveryResponse'; +import { LoadReportingServiceClient as LoadReportingServiceClientV2 } from './generated/envoy/service/load_stats/v2/LoadReportingService'; +import { LoadReportingServiceClient as LoadReportingServiceClientV3 } from './generated/envoy/service/load_stats/v3/LoadReportingService'; +import { LoadStatsRequest as LoadStatsRequestV2 } from './generated/envoy/service/load_stats/v2/LoadStatsRequest'; +import { LoadStatsRequest as LoadStatsRequestV3 } from './generated/envoy/service/load_stats/v3/LoadStatsRequest'; +import { LoadStatsResponse__Output } from './generated/envoy/service/load_stats/v3/LoadStatsResponse'; +import { Locality, Locality__Output } from './generated/envoy/config/core/v3/Locality'; +import { Listener__Output } from './generated/envoy/config/listener/v3/Listener'; import { Any__Output } from './generated/google/protobuf/Any'; import BackoffTimeout = experimental.BackoffTimeout; import ServiceConfig = experimental.ServiceConfig; @@ -55,6 +46,11 @@ import { CdsState } from './xds-stream-state/cds-state'; import { RdsState } from './xds-stream-state/rds-state'; import { LdsState } from './xds-stream-state/lds-state'; import { Watcher } from './xds-stream-state/xds-stream-state'; +import { ClusterLoadAssignment__Output } from './generated/envoy/config/endpoint/v3/ClusterLoadAssignment'; +import { Cluster__Output } from './generated/envoy/config/cluster/v3/Cluster'; +import { RouteConfiguration__Output } from './generated/envoy/config/route/v3/RouteConfiguration'; +import { Duration } from './generated/google/protobuf/Duration'; +import { AdsOutputType, AdsTypeUrl, CDS_TYPE_URL_V2, CDS_TYPE_URL_V3, decodeSingleResource, EDS_TYPE_URL_V2, EDS_TYPE_URL_V3, LDS_TYPE_URL_V2, LDS_TYPE_URL_V3, RDS_TYPE_URL_V2, RDS_TYPE_URL_V3 } from './resources'; const TRACER_NAME = 'xds_client'; @@ -64,21 +60,6 @@ function trace(text: string): void { const clientVersion = require('../../package.json').version; -const EDS_TYPE_URL = 'type.googleapis.com/envoy.api.v2.ClusterLoadAssignment'; -const CDS_TYPE_URL = 'type.googleapis.com/envoy.api.v2.Cluster'; -const LDS_TYPE_URL = 'type.googleapis.com/envoy.api.v2.Listener'; -const RDS_TYPE_URL = 'type.googleapis.com/envoy.api.v2.RouteConfiguration'; - -type EdsTypeUrl = 'type.googleapis.com/envoy.api.v2.ClusterLoadAssignment'; -type CdsTypeUrl = 'type.googleapis.com/envoy.api.v2.Cluster'; -type LdsTypeUrl = 'type.googleapis.com/envoy.api.v2.Listener'; -type RdsTypeUrl = 'type.googleapis.com/envoy.api.v2.RouteConfiguration'; - -type AdsTypeUrl = EdsTypeUrl | CdsTypeUrl | RdsTypeUrl | LdsTypeUrl; - -const HTTP_CONNECTION_MANGER_TYPE_URL = - 'type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager'; - let loadedProtos: Promise< adsTypes.ProtoGrpcType & lrsTypes.ProtoGrpcType > | null = null; @@ -94,11 +75,8 @@ function loadAdsProtos(): Promise< [ 'envoy/service/discovery/v2/ads.proto', 'envoy/service/load_stats/v2/lrs.proto', - 'envoy/api/v2/listener.proto', - 'envoy/api/v2/route.proto', - 'envoy/api/v2/cluster.proto', - 'envoy/api/v2/endpoint.proto', - 'envoy/config/filter/network/http_connection_manager/v2/http_connection_manager.proto', + 'envoy/service/discovery/v3/ads.proto', + 'envoy/service/load_stats/v3/lrs.proto', ], { keepCase: true, @@ -106,7 +84,6 @@ function loadAdsProtos(): Promise< enums: String, defaults: true, oneofs: true, - json: true, includeDirs: [ // Paths are relative to src/build __dirname + '/../../deps/envoy-api/', @@ -145,6 +122,32 @@ export interface XdsClusterLocalityStats { addCallFinished(fail: boolean): void; } +interface DroppedRequests { + category: string; + dropped_count: number; +} + +interface UpstreamLocalityStats { + locality: Locality; + total_issued_requests: number; + total_successful_requests: number; + total_error_requests: number; + total_requests_in_progress: number; +} + +/** + * An interface representing the ClusterStats message type, restricted to the + * fields used in this module to ensure compatibility with both v2 and v3 APIs. + */ +interface ClusterStats { + cluster_name: string; + cluster_service_name: string; + dropped_requests: DroppedRequests[]; + total_dropped_requests: number; + upstream_locality_stats: UpstreamLocalityStats[]; + load_report_interval: Duration +} + interface ClusterLocalityStats { locality: Locality__Output; callsStarted: number; @@ -218,39 +221,32 @@ class ClusterLoadReportMap { } } +type AdsServiceKind = 'eds' | 'cds' | 'rds' | 'lds'; + interface AdsState { - [EDS_TYPE_URL]: EdsState; - [CDS_TYPE_URL]: CdsState; - [RDS_TYPE_URL]: RdsState; - [LDS_TYPE_URL]: LdsState; + eds: EdsState; + cds: CdsState; + rds: RdsState; + lds: LdsState; } -/** - * Map type URLs to their corresponding message types - */ -type OutputType = T extends EdsTypeUrl - ? ClusterLoadAssignment__Output - : T extends CdsTypeUrl - ? Cluster__Output - : T extends RdsTypeUrl - ? RouteConfiguration__Output - : Listener__Output; +enum XdsApiVersion { + V2, + V3 +} function getResponseMessages( - typeUrl: T, + targetTypeUrl: T, + allowedTypeUrls: string[], resources: Any__Output[] -): OutputType[] { - const result: OutputType[] = []; +): AdsOutputType[] { + const result: AdsOutputType[] = []; for (const resource of resources) { - if (protoLoader.isAnyExtension(resource) && resource['@type'] === typeUrl) { - result.push(resource as protoLoader.AnyExtension & OutputType); + if (allowedTypeUrls.includes(resource.type_url)) { + result.push(decodeSingleResource(targetTypeUrl, resource.value)); } else { throw new Error( - `ADS Error: Invalid resource type ${ - protoLoader.isAnyExtension(resource) - ? resource['@type'] - : resource.type_url - }, expected ${typeUrl}` + `ADS Error: Invalid resource type ${resource.type_url}, expected ${allowedTypeUrls}` ); } } @@ -258,20 +254,39 @@ function getResponseMessages( } export class XdsClient { - private adsNode: Node | null = null; - private adsClient: AggregatedDiscoveryServiceClient | null = null; - private adsCall: ClientDuplexStream< - DiscoveryRequest, + private apiVersion: XdsApiVersion = XdsApiVersion.V2; + + private adsNodeV2: NodeV2 | null = null; + private adsNodeV3: NodeV3 | null = null; + /* A client initiates connections lazily, so the client we don't use won't + * use significant extra resources. */ + private adsClientV2: AggregatedDiscoveryServiceClientV2 | null = null; + private adsClientV3: AggregatedDiscoveryServiceClientV3 | null = null; + /* TypeScript typing is structural, so we can take advantage of the fact that + * the output structures for the two call types are identical. */ + private adsCallV2: ClientDuplexStream< + DiscoveryRequestV2, + DiscoveryResponse__Output + > | null = null; + private adsCallV3: ClientDuplexStream< + DiscoveryRequestV3, DiscoveryResponse__Output > | null = null; - private lrsNode: Node | null = null; - private lrsClient: LoadReportingServiceClient | null = null; - private lrsCall: ClientDuplexStream< - LoadStatsRequest, + private lrsNodeV2: NodeV2 | null = null; + private lrsNodeV3: NodeV3 | null = null; + private lrsClientV2: LoadReportingServiceClientV2 | null = null; + private lrsClientV3: LoadReportingServiceClientV3 | null = null; + private lrsCallV2: ClientDuplexStream< + LoadStatsRequestV2, + LoadStatsResponse__Output + > | null = null; + private lrsCallV3: ClientDuplexStream< + LoadStatsRequestV3, LoadStatsResponse__Output > | null = null; private latestLrsSettings: LoadStatsResponse__Output | null = null; + private receivedLrsSettingsForCurrentStream = false; private clusterStatsMap: ClusterLoadReportMap = new ClusterLoadReportMap(); private statsTimer: NodeJS.Timer; @@ -285,22 +300,22 @@ export class XdsClient { constructor() { const edsState = new EdsState(() => { - this.updateNames(EDS_TYPE_URL); + this.updateNames('eds'); }); const cdsState = new CdsState(edsState, () => { - this.updateNames(CDS_TYPE_URL); + this.updateNames('cds'); }); const rdsState = new RdsState(() => { - this.updateNames(RDS_TYPE_URL); + this.updateNames('rds'); }); const ldsState = new LdsState(rdsState, () => { - this.updateNames(LDS_TYPE_URL); + this.updateNames('lds'); }); this.adsState = { - [EDS_TYPE_URL]: edsState, - [CDS_TYPE_URL]: cdsState, - [RDS_TYPE_URL]: rdsState, - [LDS_TYPE_URL]: ldsState, + eds: edsState, + cds: cdsState, + rds: rdsState, + lds: ldsState, }; const channelArgs = { @@ -322,17 +337,34 @@ export class XdsClient { if (this.hasShutdown) { return; } - const node: Node = { + if (bootstrapInfo.xdsServers[0].serverFeatures.indexOf('xds_v3') >= 0) { + this.apiVersion = XdsApiVersion.V3; + } else { + this.apiVersion = XdsApiVersion.V2; + } + const nodeV2: NodeV2 = { ...bootstrapInfo.node, build_version: `gRPC Node Pure JS ${clientVersion}`, user_agent_name: 'gRPC Node Pure JS', }; - this.adsNode = { - ...node, + const nodeV3: NodeV3 = { + ...bootstrapInfo.node, + user_agent_name: 'gRPC Node Pure JS', + }; + this.adsNodeV2 = { + ...nodeV2, client_features: ['envoy.lb.does_not_support_overprovisioning'], }; - this.lrsNode = { - ...node, + this.adsNodeV3 = { + ...nodeV3, + client_features: ['envoy.lb.does_not_support_overprovisioning'], + }; + this.lrsNodeV2 = { + ...nodeV2, + client_features: ['envoy.lrs.supports_send_all_clusters'], + }; + this.lrsNodeV3 = { + ...nodeV3, client_features: ['envoy.lrs.supports_send_all_clusters'], }; const credentialsConfigs = bootstrapInfo.xdsServers[0].channelCreds; @@ -356,18 +388,30 @@ export class XdsClient { }); return; } + const serverUri = bootstrapInfo.xdsServers[0].serverUri trace('Starting xDS client connected to server URI ' + bootstrapInfo.xdsServers[0].serverUri); - this.adsClient = new protoDefinitions.envoy.service.discovery.v2.AggregatedDiscoveryService( - bootstrapInfo.xdsServers[0].serverUri, + const channel = new Channel(serverUri, channelCreds, channelArgs); + this.adsClientV2 = new protoDefinitions.envoy.service.discovery.v2.AggregatedDiscoveryService( + serverUri, channelCreds, - channelArgs + {channelOverride: channel} + ); + this.adsClientV3 = new protoDefinitions.envoy.service.discovery.v3.AggregatedDiscoveryService( + serverUri, + channelCreds, + {channelOverride: channel} ); this.maybeStartAdsStream(); - this.lrsClient = new protoDefinitions.envoy.service.load_stats.v2.LoadReportingService( - bootstrapInfo.xdsServers[0].serverUri, + this.lrsClientV2 = new protoDefinitions.envoy.service.load_stats.v2.LoadReportingService( + serverUri, + channelCreds, + {channelOverride: channel} + ); + this.lrsClientV3 = new protoDefinitions.envoy.service.load_stats.v3.LoadReportingService( + serverUri, channelCreds, - {channelOverride: this.adsClient.getChannel()} + {channelOverride: channel} ); this.maybeStartLrsStream(); }, @@ -387,32 +431,40 @@ export class XdsClient { private handleAdsResponse(message: DiscoveryResponse__Output) { let errorString: string | null; - /* The cases in this switch statement look redundant but separating them - * out like this is necessary for the typechecker to validate the types - * as narrowly as we need it to. */ + let serviceKind: AdsServiceKind; switch (message.type_url) { - case EDS_TYPE_URL: - errorString = this.adsState[message.type_url].handleResponses( - getResponseMessages(message.type_url, message.resources) + case EDS_TYPE_URL_V2: + case EDS_TYPE_URL_V3: + errorString = this.adsState.eds.handleResponses( + getResponseMessages(EDS_TYPE_URL_V3, [EDS_TYPE_URL_V2, EDS_TYPE_URL_V3], message.resources) ); + serviceKind = 'eds'; break; - case CDS_TYPE_URL: - errorString = this.adsState[message.type_url].handleResponses( - getResponseMessages(message.type_url, message.resources) + case CDS_TYPE_URL_V2: + case CDS_TYPE_URL_V3: + errorString = this.adsState.cds.handleResponses( + getResponseMessages(CDS_TYPE_URL_V3, [CDS_TYPE_URL_V2, CDS_TYPE_URL_V3], message.resources) ); + serviceKind = 'cds'; break; - case RDS_TYPE_URL: - errorString = this.adsState[message.type_url].handleResponses( - getResponseMessages(message.type_url, message.resources) + case RDS_TYPE_URL_V2: + case RDS_TYPE_URL_V3: + errorString = this.adsState.rds.handleResponses( + getResponseMessages(RDS_TYPE_URL_V3, [RDS_TYPE_URL_V2, RDS_TYPE_URL_V3], message.resources) ); + serviceKind = 'rds'; break; - case LDS_TYPE_URL: - errorString = this.adsState[message.type_url].handleResponses( - getResponseMessages(message.type_url, message.resources) + case LDS_TYPE_URL_V2: + case LDS_TYPE_URL_V3: + errorString = this.adsState.lds.handleResponses( + getResponseMessages(LDS_TYPE_URL_V3, [LDS_TYPE_URL_V2, LDS_TYPE_URL_V3], message.resources) ); + serviceKind = 'lds'; break; default: errorString = `Unknown type_url ${message.type_url}`; + // This is not used in this branch, but setting it makes the types easier to handle + serviceKind = 'eds'; } if (errorString === null) { trace('Acking message with type URL ' + message.type_url); @@ -420,65 +472,148 @@ export class XdsClient { * implies that message.type_url is one of the 4 known type URLs, which * means that this type assertion is valid. */ const typeUrl = message.type_url as AdsTypeUrl; - this.adsState[typeUrl].nonce = message.nonce; - this.adsState[typeUrl].versionInfo = message.version_info; - this.ack(typeUrl); + this.adsState[serviceKind].nonce = message.nonce; + this.adsState[serviceKind].versionInfo = message.version_info; + this.ack(serviceKind); } else { trace('Nacking message with type URL ' + message.type_url + ': "' + errorString + '"'); this.nack(message.type_url, errorString); } } + private handleAdsCallError(error: ServiceError) { + trace( + 'ADS stream ended. code=' + error.code + ' details= ' + error.details + ); + this.adsCallV2 = null; + this.adsCallV3 = null; + this.reportStreamError(error); + /* If the backoff timer is no longer running, we do not need to wait any + * more to start the new call. */ + if (!this.adsBackoff.isRunning()) { + this.maybeStartAdsStream(); + } + } + + private maybeStartAdsStreamV2(): boolean { + if (this.apiVersion !== XdsApiVersion.V2) { + return false; + } + if (this.adsClientV2 === null) { + return false; + } + if (this.adsCallV2 !== null) { + return false; + } + this.adsCallV2 = this.adsClientV2.StreamAggregatedResources(); + this.adsCallV2.on('data', (message: DiscoveryResponse__Output) => { + this.handleAdsResponse(message); + }); + this.adsCallV2.on('error', (error: ServiceError) => { + this.handleAdsCallError(error); + }); + return true; + } + + private maybeStartAdsStreamV3(): boolean { + if (this.apiVersion !== XdsApiVersion.V3) { + return false; + } + if (this.adsClientV3 === null) { + return false; + } + if (this.adsCallV3 !== null) { + return false; + } + this.adsCallV3 = this.adsClientV3.StreamAggregatedResources(); + this.adsCallV3.on('data', (message: DiscoveryResponse__Output) => { + this.handleAdsResponse(message); + }); + this.adsCallV3.on('error', (error: ServiceError) => { + this.handleAdsCallError(error); + }); + return true; + } + /** * Start the ADS stream if the client exists and there is not already an - * existing stream, and there + * existing stream, and there are resources to request. */ private maybeStartAdsStream() { - if (this.adsClient === null) { - return; - } - if (this.adsCall !== null) { - return; - } if (this.hasShutdown) { return; } - if (this.adsState[EDS_TYPE_URL].getResourceNames().length === 0 && - this.adsState[CDS_TYPE_URL].getResourceNames().length === 0 && - this.adsState[RDS_TYPE_URL].getResourceNames().length === 0 && - this.adsState[LDS_TYPE_URL].getResourceNames().length === 0) { + if (this.adsState.eds.getResourceNames().length === 0 && + this.adsState.cds.getResourceNames().length === 0 && + this.adsState.rds.getResourceNames().length === 0 && + this.adsState.lds.getResourceNames().length === 0) { return; } - trace('Starting ADS stream'); - // Backoff relative to when we start the request - this.adsBackoff.runOnce(); - this.adsCall = this.adsClient.StreamAggregatedResources(); - this.adsCall.on('data', (message: DiscoveryResponse__Output) => { - this.handleAdsResponse(message); - }); - this.adsCall.on('error', (error: ServiceError) => { - trace( - 'ADS stream ended. code=' + error.code + ' details= ' + error.details - ); - this.adsCall = null; - this.reportStreamError(error); - /* If the backoff timer is no longer running, we do not need to wait any - * more to start the new call. */ - if (!this.adsBackoff.isRunning()) { - this.maybeStartAdsStream(); + let streamStarted: boolean; + if (this.apiVersion === XdsApiVersion.V2) { + streamStarted = this.maybeStartAdsStreamV2(); + } else { + streamStarted = this.maybeStartAdsStreamV3(); + } + if (streamStarted) { + trace('Started ADS stream'); + // Backoff relative to when we start the request + this.adsBackoff.runOnce(); + + const allServiceKinds: AdsServiceKind[] = ['eds', 'cds', 'rds', 'lds']; + for (const service of allServiceKinds) { + const state = this.adsState[service]; + if (state.getResourceNames().length > 0) { + this.updateNames(service); + } } - }); + } + } + + private maybeSendAdsMessage(typeUrl: string, resourceNames: string[], responseNonce: string, versionInfo: string, errorMessage?: string) { + if (this.apiVersion === XdsApiVersion.V2) { + this.adsCallV2?.write({ + node: this.adsNodeV2!, + type_url: typeUrl, + resource_names: resourceNames, + response_nonce: responseNonce, + version_info: versionInfo, + error_detail: errorMessage ? { message: errorMessage } : undefined + }); + } else { + this.adsCallV3?.write({ + node: this.adsNodeV3!, + type_url: typeUrl, + resource_names: resourceNames, + response_nonce: responseNonce, + version_info: versionInfo, + error_detail: errorMessage ? { message: errorMessage } : undefined + }); + } + } - const allTypeUrls: AdsTypeUrl[] = [ - EDS_TYPE_URL, - CDS_TYPE_URL, - RDS_TYPE_URL, - LDS_TYPE_URL, - ]; - for (const typeUrl of allTypeUrls) { - const state = this.adsState[typeUrl]; - if (state.getResourceNames().length > 0) { - this.updateNames(typeUrl); + private getTypeUrl(serviceKind: AdsServiceKind): AdsTypeUrl { + if (this.apiVersion === XdsApiVersion.V2) { + switch (serviceKind) { + case 'eds': + return EDS_TYPE_URL_V2; + case 'cds': + return CDS_TYPE_URL_V2; + case 'rds': + return RDS_TYPE_URL_V2; + case 'lds': + return LDS_TYPE_URL_V2; + } + } else { + switch (serviceKind) { + case 'eds': + return EDS_TYPE_URL_V3; + case 'cds': + return CDS_TYPE_URL_V3; + case 'rds': + return RDS_TYPE_URL_V3; + case 'lds': + return LDS_TYPE_URL_V3; } } } @@ -487,13 +622,13 @@ export class XdsClient { * Acknowledge an update. This should be called after the local nonce and * version info are updated so that it sends the post-update values. */ - ack(typeUrl: AdsTypeUrl) { + ack(serviceKind: AdsServiceKind) { /* An ack is the best indication of a successful interaction between the * client and the server, so we can reset the backoff timer here. */ this.adsBackoff.stop(); this.adsBackoff.reset(); - this.updateNames(typeUrl); + this.updateNames(serviceKind); } /** @@ -504,135 +639,196 @@ export class XdsClient { let resourceNames: string[]; let nonce: string; let versionInfo: string; + let serviceKind: AdsServiceKind | null; switch (typeUrl) { - case EDS_TYPE_URL: - case CDS_TYPE_URL: - case RDS_TYPE_URL: - case LDS_TYPE_URL: - resourceNames = this.adsState[typeUrl].getResourceNames(); - nonce = this.adsState[typeUrl].nonce; - versionInfo = this.adsState[typeUrl].versionInfo; + case EDS_TYPE_URL_V2: + case EDS_TYPE_URL_V3: + serviceKind = 'eds'; + break; + case CDS_TYPE_URL_V2: + case CDS_TYPE_URL_V3: + serviceKind = 'cds'; + break; + case RDS_TYPE_URL_V2: + case RDS_TYPE_URL_V3: + serviceKind = 'rds'; + break; + case LDS_TYPE_URL_V2: + case LDS_TYPE_URL_V3: + serviceKind = 'lds'; break; default: - resourceNames = []; - nonce = ''; - versionInfo = ''; - } - this.adsCall?.write({ - node: this.adsNode!, - type_url: typeUrl, - resource_names: resourceNames, - response_nonce: nonce, - version_info: versionInfo, - error_detail: { - message: message, - }, - }); + serviceKind = null; + break; + } + if (serviceKind) { + resourceNames = this.adsState[serviceKind].getResourceNames(); + nonce = this.adsState[serviceKind].nonce; + versionInfo = this.adsState[serviceKind].versionInfo; + } else { + resourceNames = []; + nonce = ''; + versionInfo = ''; + } + this.maybeSendAdsMessage(typeUrl, resourceNames, nonce, versionInfo, message); } - private updateNames(typeUrl: AdsTypeUrl) { - if (this.adsState[EDS_TYPE_URL].getResourceNames().length === 0 && - this.adsState[CDS_TYPE_URL].getResourceNames().length === 0 && - this.adsState[RDS_TYPE_URL].getResourceNames().length === 0 && - this.adsState[LDS_TYPE_URL].getResourceNames().length === 0) { - this.adsCall?.end(); - this.lrsCall?.end(); + private updateNames(serviceKind: AdsServiceKind) { + if (this.adsState.eds.getResourceNames().length === 0 && + this.adsState.cds.getResourceNames().length === 0 && + this.adsState.rds.getResourceNames().length === 0 && + this.adsState.lds.getResourceNames().length === 0) { + this.adsCallV2?.end(); + this.adsCallV2 = null; + this.adsCallV3?.end(); + this.adsCallV3 = null; + this.lrsCallV2?.end(); + this.lrsCallV2 = null; + this.lrsCallV3?.end(); + this.lrsCallV3 = null; return; } this.maybeStartAdsStream(); this.maybeStartLrsStream(); - trace('Sending update for type URL ' + typeUrl + ' with names ' + this.adsState[typeUrl].getResourceNames()); - this.adsCall?.write({ - node: this.adsNode!, - type_url: typeUrl, - resource_names: this.adsState[typeUrl].getResourceNames(), - response_nonce: this.adsState[typeUrl].nonce, - version_info: this.adsState[typeUrl].versionInfo, - }); + trace('Sending update for ' + serviceKind + ' with names ' + this.adsState[serviceKind].getResourceNames()); + const typeUrl = this.getTypeUrl(serviceKind); + this.maybeSendAdsMessage(typeUrl, this.adsState[serviceKind].getResourceNames(), this.adsState[serviceKind].nonce, this.adsState[serviceKind].versionInfo); } private reportStreamError(status: StatusObject) { - this.adsState[EDS_TYPE_URL].reportStreamError(status); - this.adsState[CDS_TYPE_URL].reportStreamError(status); - this.adsState[RDS_TYPE_URL].reportStreamError(status); - this.adsState[LDS_TYPE_URL].reportStreamError(status); + this.adsState.eds.reportStreamError(status); + this.adsState.cds.reportStreamError(status); + this.adsState.rds.reportStreamError(status); + this.adsState.lds.reportStreamError(status); } - private maybeStartLrsStream() { - if (!this.lrsClient) { - return; + private handleLrsResponse(message: LoadStatsResponse__Output) { + trace('Received LRS response'); + /* Once we get any response from the server, we assume that the stream is + * in a good state, so we can reset the backoff timer. */ + this.lrsBackoff.stop(); + this.lrsBackoff.reset(); + if ( + !this.receivedLrsSettingsForCurrentStream || + message.load_reporting_interval?.seconds !== + this.latestLrsSettings?.load_reporting_interval?.seconds || + message.load_reporting_interval?.nanos !== + this.latestLrsSettings?.load_reporting_interval?.nanos + ) { + /* Only reset the timer if the interval has changed or was not set + * before. */ + clearInterval(this.statsTimer); + /* Convert a google.protobuf.Duration to a number of milliseconds for + * use with setInterval. */ + const loadReportingIntervalMs = + Number.parseInt(message.load_reporting_interval!.seconds) * 1000 + + message.load_reporting_interval!.nanos / 1_000_000; + trace('Received LRS response with load reporting interval ' + loadReportingIntervalMs + ' ms'); + this.statsTimer = setInterval(() => { + this.sendStats(); + }, loadReportingIntervalMs); } - if (this.lrsCall) { - return; + this.latestLrsSettings = message; + this.receivedLrsSettingsForCurrentStream = true; + } + + private handleLrsCallError(error: ServiceError) { + trace( + 'LRS stream ended. code=' + error.code + ' details= ' + error.details + ); + this.lrsCallV2 = null; + this.lrsCallV3 = null; + clearInterval(this.statsTimer); + /* If the backoff timer is no longer running, we do not need to wait any + * more to start the new call. */ + if (!this.lrsBackoff.isRunning()) { + this.maybeStartLrsStream(); + } + } + + private maybeStartLrsStreamV2(): boolean { + if (!this.lrsClientV2) { + return false; + } + if (this.lrsCallV2) { + return false; } + this.lrsCallV2 = this.lrsClientV2.streamLoadStats(); + this.receivedLrsSettingsForCurrentStream = false; + this.lrsCallV2.on('data', (message: LoadStatsResponse__Output) => { + this.handleLrsResponse(message); + }); + this.lrsCallV2.on('error', (error: ServiceError) => { + this.handleLrsCallError(error); + }); + return true; + } + + private maybeStartLrsStreamV3(): boolean { + if (!this.lrsClientV3) { + return false; + } + if (this.lrsCallV3) { + return false; + } + this.lrsCallV3 = this.lrsClientV3.streamLoadStats(); + this.receivedLrsSettingsForCurrentStream = false; + this.lrsCallV3.on('data', (message: LoadStatsResponse__Output) => { + this.handleLrsResponse(message); + }); + this.lrsCallV3.on('error', (error: ServiceError) => { + this.handleLrsCallError(error); + }); + return true; + } + + private maybeStartLrsStream() { if (this.hasShutdown) { return; } - if (this.adsState[EDS_TYPE_URL].getResourceNames().length === 0 && - this.adsState[CDS_TYPE_URL].getResourceNames().length === 0 && - this.adsState[RDS_TYPE_URL].getResourceNames().length === 0 && - this.adsState[LDS_TYPE_URL].getResourceNames().length === 0) { + if (this.adsState.eds.getResourceNames().length === 0 && + this.adsState.cds.getResourceNames().length === 0 && + this.adsState.rds.getResourceNames().length === 0 && + this.adsState.lds.getResourceNames().length === 0) { return; } - - trace('Starting LRS stream'); - - this.lrsBackoff.runOnce(); - this.lrsCall = this.lrsClient.streamLoadStats(); - let receivedSettingsForThisStream = false; - this.lrsCall.on('data', (message: LoadStatsResponse__Output) => { - /* Once we get any response from the server, we assume that the stream is - * in a good state, so we can reset the backoff timer. */ - this.lrsBackoff.stop(); - this.lrsBackoff.reset(); - if ( - !receivedSettingsForThisStream || - message.load_reporting_interval?.seconds !== - this.latestLrsSettings?.load_reporting_interval?.seconds || - message.load_reporting_interval?.nanos !== - this.latestLrsSettings?.load_reporting_interval?.nanos - ) { - /* Only reset the timer if the interval has changed or was not set - * before. */ - clearInterval(this.statsTimer); - /* Convert a google.protobuf.Duration to a number of milliseconds for - * use with setInterval. */ - const loadReportingIntervalMs = - Number.parseInt(message.load_reporting_interval!.seconds) * 1000 + - message.load_reporting_interval!.nanos / 1_000_000; - trace('Received LRS request with load reporting interval ' + loadReportingIntervalMs + ' ms'); - this.statsTimer = setInterval(() => { - this.sendStats(); - }, loadReportingIntervalMs); - } - this.latestLrsSettings = message; - receivedSettingsForThisStream = true; - }); - this.lrsCall.on('error', (error: ServiceError) => { - trace( - 'LRS stream ended. code=' + error.code + ' details= ' + error.details - ); - this.lrsCall = null; - clearInterval(this.statsTimer); - /* If the backoff timer is no longer running, we do not need to wait any - * more to start the new call. */ - if (!this.lrsBackoff.isRunning()) { - this.maybeStartLrsStream(); - } - }); - /* Send buffered stats information when starting LRS stream. If there is no - * buffered stats information, it will still send the node field. */ - this.sendStats(); + + let streamStarted: boolean; + if (this.apiVersion === XdsApiVersion.V2) { + streamStarted = this.maybeStartLrsStreamV2(); + } else { + streamStarted = this.maybeStartLrsStreamV3(); + } + + if (streamStarted) { + trace('Starting LRS stream'); + this.lrsBackoff.runOnce(); + /* Send buffered stats information when starting LRS stream. If there is no + * buffered stats information, it will still send the node field. */ + this.sendStats(); + } + } + + private maybeSendLrsMessage(clusterStats: ClusterStats[]) { + if (this.apiVersion === XdsApiVersion.V2) { + this.lrsCallV2?.write({ + node: this.lrsNodeV2!, + cluster_stats: clusterStats + }); + } else { + this.lrsCallV3?.write({ + node: this.lrsNodeV3!, + cluster_stats: clusterStats + }); + } } private sendStats() { - if (!this.lrsCall) { + if (this.lrsCallV2 === null && this.lrsCallV3 === null) { return; } if (!this.latestLrsSettings) { - this.lrsCall.write({ - node: this.lrsNode!, - }); + this.maybeSendLrsMessage([]); return; } const clusterStats: ClusterStats[] = []; @@ -664,7 +860,7 @@ export class XdsClient { localityStats.callsFailed = 0; } } - const droppedRequests: _envoy_api_v2_endpoint_ClusterStats_DroppedRequests[] = []; + const droppedRequests: DroppedRequests[] = []; let totalDroppedRequests = 0; for (const [category, count] of stats.callsDropped.entries()) { if (count > 0) { @@ -696,10 +892,7 @@ export class XdsClient { } } trace('Sending LRS stats ' + JSON.stringify(clusterStats, undefined, 2)); - this.lrsCall.write({ - node: this.lrsNode!, - cluster_stats: clusterStats, - }); + this.maybeSendLrsMessage(clusterStats); } addEndpointWatcher( @@ -707,7 +900,7 @@ export class XdsClient { watcher: Watcher ) { trace('Watcher added for endpoint ' + edsServiceName); - this.adsState[EDS_TYPE_URL].addWatcher(edsServiceName, watcher); + this.adsState.eds.addWatcher(edsServiceName, watcher); } removeEndpointWatcher( @@ -715,37 +908,37 @@ export class XdsClient { watcher: Watcher ) { trace('Watcher removed for endpoint ' + edsServiceName); - this.adsState[EDS_TYPE_URL].removeWatcher(edsServiceName, watcher); + this.adsState.eds.removeWatcher(edsServiceName, watcher); } addClusterWatcher(clusterName: string, watcher: Watcher) { trace('Watcher added for cluster ' + clusterName); - this.adsState[CDS_TYPE_URL].addWatcher(clusterName, watcher); + this.adsState.cds.addWatcher(clusterName, watcher); } removeClusterWatcher(clusterName: string, watcher: Watcher) { trace('Watcher removed for cluster ' + clusterName); - this.adsState[CDS_TYPE_URL].removeWatcher(clusterName, watcher); + this.adsState.cds.removeWatcher(clusterName, watcher); } addRouteWatcher(routeConfigName: string, watcher: Watcher) { trace('Watcher added for route ' + routeConfigName); - this.adsState[RDS_TYPE_URL].addWatcher(routeConfigName, watcher); + this.adsState.rds.addWatcher(routeConfigName, watcher); } removeRouteWatcher(routeConfigName: string, watcher: Watcher) { trace('Watcher removed for route ' + routeConfigName); - this.adsState[RDS_TYPE_URL].removeWatcher(routeConfigName, watcher); + this.adsState.rds.removeWatcher(routeConfigName, watcher); } addListenerWatcher(targetName: string, watcher: Watcher) { trace('Watcher added for listener ' + targetName); - this.adsState[LDS_TYPE_URL].addWatcher(targetName, watcher); + this.adsState.lds.addWatcher(targetName, watcher); } removeListenerWatcher(targetName: string, watcher: Watcher) { trace('Watcher removed for listener ' + targetName); - this.adsState[LDS_TYPE_URL].removeWatcher(targetName, watcher); + this.adsState.lds.removeWatcher(targetName, watcher); } /** @@ -833,10 +1026,14 @@ export class XdsClient { } private shutdown(): void { - this.adsCall?.cancel(); - this.adsClient?.close(); - this.lrsCall?.cancel(); - this.lrsClient?.close(); + this.adsCallV2?.cancel(); + this.adsCallV3?.cancel(); + this.adsClientV2?.close(); + this.adsClientV3?.close(); + this.lrsCallV2?.cancel(); + this.lrsCallV3?.cancel(); + this.lrsClientV2?.close(); + this.lrsClientV3?.close(); this.hasShutdown = true; } } diff --git a/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts index 343089958..a6e89805d 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts @@ -16,7 +16,7 @@ */ import { experimental, logVerbosity, StatusObject } from "@grpc/grpc-js"; -import { Cluster__Output } from "../generated/envoy/api/v2/Cluster"; +import { Cluster__Output } from "../generated/envoy/config/cluster/v3/Cluster"; import { EdsState } from "./eds-state"; import { Watcher, XdsStreamState } from "./xds-stream-state"; diff --git a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts index c9beef292..a0fb5f4dc 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts @@ -17,7 +17,7 @@ import { experimental, logVerbosity, StatusObject } from "@grpc/grpc-js"; import { isIPv4, isIPv6 } from "net"; -import { ClusterLoadAssignment__Output } from "../generated/envoy/api/v2/ClusterLoadAssignment"; +import { ClusterLoadAssignment__Output } from "../generated/envoy/config/endpoint/v3/ClusterLoadAssignment"; import { Watcher, XdsStreamState } from "./xds-stream-state"; const TRACER_NAME = 'xds_client'; diff --git a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts index 554712727..eb76f7994 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts @@ -17,10 +17,11 @@ import * as protoLoader from '@grpc/proto-loader'; import { experimental, logVerbosity, StatusObject } from "@grpc/grpc-js"; -import { Listener__Output } from "../generated/envoy/api/v2/Listener"; +import { Listener__Output } from '../generated/envoy/config/listener/v3/Listener'; import { RdsState } from "./rds-state"; import { Watcher, XdsStreamState } from "./xds-stream-state"; -import { HttpConnectionManager__Output } from '../generated/envoy/config/filter/network/http_connection_manager/v2/HttpConnectionManager'; +import { HttpConnectionManager__Output } from '../generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpConnectionManager'; +import { decodeSingleResource, HTTP_CONNECTION_MANGER_TYPE_URL_V2, HTTP_CONNECTION_MANGER_TYPE_URL_V3 } from '../resources'; const TRACER_NAME = 'xds_client'; @@ -28,9 +29,6 @@ function trace(text: string): void { experimental.trace(logVerbosity.DEBUG, TRACER_NAME, text); } -const HTTP_CONNECTION_MANGER_TYPE_URL = - 'type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager'; - export class LdsState implements XdsStreamState { versionInfo = ''; nonce = ''; @@ -95,16 +93,13 @@ export class LdsState implements XdsStreamState { if ( !( message.api_listener?.api_listener && - protoLoader.isAnyExtension(message.api_listener.api_listener) && - message.api_listener?.api_listener['@type'] === - HTTP_CONNECTION_MANGER_TYPE_URL + (message.api_listener.api_listener.type_url === HTTP_CONNECTION_MANGER_TYPE_URL_V2 || + message.api_listener.api_listener.type_url === HTTP_CONNECTION_MANGER_TYPE_URL_V3) ) ) { return false; } - const httpConnectionManager = message.api_listener - ?.api_listener as protoLoader.AnyExtension & - HttpConnectionManager__Output; + const httpConnectionManager = decodeSingleResource(HTTP_CONNECTION_MANGER_TYPE_URL_V3, message.api_listener!.api_listener.value); switch (httpConnectionManager.route_specifier) { case 'rds': return !!httpConnectionManager.rds?.config_source?.ads; diff --git a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts index 8f795e0f5..1e50f22e7 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts @@ -16,7 +16,7 @@ */ import { experimental, logVerbosity, StatusObject } from "@grpc/grpc-js"; -import { RouteConfiguration__Output } from "../generated/envoy/api/v2/RouteConfiguration"; +import { RouteConfiguration__Output } from "../generated/envoy/config/route/v3/RouteConfiguration"; import { CdsLoadBalancingConfig } from "../load-balancer-cds"; import { Watcher, XdsStreamState } from "./xds-stream-state"; import ServiceConfig = experimental.ServiceConfig; diff --git a/test/kokoro/linux.cfg b/test/kokoro/linux.cfg index f40e6db43..63f88d399 100644 --- a/test/kokoro/linux.cfg +++ b/test/kokoro/linux.cfg @@ -11,7 +11,6 @@ # 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. @@ -21,4 +20,4 @@ action { define_artifacts { regex: "github/grpc-node/reports/**/sponge_log.xml" } -} +} \ No newline at end of file diff --git a/test/kokoro/xds-v3-interop.cfg b/test/kokoro/xds-v3-interop.cfg new file mode 100644 index 000000000..d7ffa8fab --- /dev/null +++ b/test/kokoro/xds-v3-interop.cfg @@ -0,0 +1,24 @@ +# Copyright 2021 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-v3.sh" +timeout_mins: 120 +action { + define_artifacts { + regex: "github/grpc/reports/**" + } +} From 4c767ca94624f938aa86f8c53994fa88c9ad61c3 Mon Sep 17 00:00:00 2001 From: "@EduardoLaranjo" Date: Tue, 4 May 2021 19:27:24 +0100 Subject: [PATCH 003/450] Fix auto-generated service definition relate to issue #1766 --- packages/proto-loader/bin/proto-loader-gen-types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index 04717f3fb..82a13a123 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -542,7 +542,7 @@ function generateServiceHandlerInterface(formatter: TextFormatter, serviceType: } function generateServiceDefinitionInterface(formatter: TextFormatter, serviceType: Protobuf.Service) { - formatter.writeLine(`export interface ${serviceType.name}Definition {`); + formatter.writeLine(`export interface ${serviceType.name}Definition extends grpc.ServiceDefinition {`); formatter.indent(); for (const methodName of Object.keys(serviceType.methods).sort()) { const method = serviceType.methods[methodName]; From a5fb029e7054a5be4b8791144139fb0b8631abbf Mon Sep 17 00:00:00 2001 From: Eduardo Laranjo Date: Wed, 5 May 2021 13:41:45 +0100 Subject: [PATCH 004/450] Add new generated golden files --- .../golden-generated/google/longrunning/Operations.ts | 2 +- .../golden-generated/google/showcase/v1beta1/Echo.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/proto-loader/golden-generated/google/longrunning/Operations.ts b/packages/proto-loader/golden-generated/google/longrunning/Operations.ts index 8e5684ada..7644f974d 100644 --- a/packages/proto-loader/golden-generated/google/longrunning/Operations.ts +++ b/packages/proto-loader/golden-generated/google/longrunning/Operations.ts @@ -232,7 +232,7 @@ export interface OperationsHandlers extends grpc.UntypedServiceImplementation { } -export interface OperationsDefinition { +export interface OperationsDefinition extends grpc.ServiceDefinition { CancelOperation: MethodDefinition<_google_longrunning_CancelOperationRequest, _google_protobuf_Empty, _google_longrunning_CancelOperationRequest__Output, _google_protobuf_Empty__Output> DeleteOperation: MethodDefinition<_google_longrunning_DeleteOperationRequest, _google_protobuf_Empty, _google_longrunning_DeleteOperationRequest__Output, _google_protobuf_Empty__Output> GetOperation: MethodDefinition<_google_longrunning_GetOperationRequest, _google_longrunning_Operation, _google_longrunning_GetOperationRequest__Output, _google_longrunning_Operation__Output> diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/Echo.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/Echo.ts index acb911270..8e75c6c1a 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/Echo.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/Echo.ts @@ -191,7 +191,7 @@ export interface EchoHandlers extends grpc.UntypedServiceImplementation { } -export interface EchoDefinition { +export interface EchoDefinition extends grpc.ServiceDefinition { Block: MethodDefinition<_google_showcase_v1beta1_BlockRequest, _google_showcase_v1beta1_BlockResponse, _google_showcase_v1beta1_BlockRequest__Output, _google_showcase_v1beta1_BlockResponse__Output> Chat: MethodDefinition<_google_showcase_v1beta1_EchoRequest, _google_showcase_v1beta1_EchoResponse, _google_showcase_v1beta1_EchoRequest__Output, _google_showcase_v1beta1_EchoResponse__Output> Collect: MethodDefinition<_google_showcase_v1beta1_EchoRequest, _google_showcase_v1beta1_EchoResponse, _google_showcase_v1beta1_EchoRequest__Output, _google_showcase_v1beta1_EchoResponse__Output> From 7c2acccff51a2b6cf6cd8911b3902112a449a030 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 6 May 2021 14:28:15 -0700 Subject: [PATCH 005/450] proto-loader: Bump to 0.6.2 --- packages/proto-loader/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index ee49abc40..0d9ff4437 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/proto-loader", - "version": "0.6.1", + "version": "0.6.2", "author": "Google Inc.", "contributors": [ { From 03a72a1d2e8f1b9bb70e9a40e5c72d4b232b61bf Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 7 May 2021 09:36:10 +0200 Subject: [PATCH 006/450] add emulated aarch64 linux tests --- run-tests.sh | 3 ++- test/aarch64/prepare_qemu.sh | 26 ++++++++++++++++++++++ test/kokoro/linux_aarch64.cfg | 24 ++++++++++++++++++++ test/kokoro_linux_aarch64.sh | 42 +++++++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 1 deletion(-) create mode 100755 test/aarch64/prepare_qemu.sh create mode 100644 test/kokoro/linux_aarch64.cfg create mode 100755 test/kokoro_linux_aarch64.sh diff --git a/run-tests.sh b/run-tests.sh index c4bffacda..2808e2af6 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -46,6 +46,7 @@ export JOBS=8 export JUNIT_REPORT_STACK=1 OS=$(uname) +ARCH=$(uname -m) # TODO(mlumish): Add electron tests @@ -87,7 +88,7 @@ if [ "$FAILED" = "true" ] then exit 1 else - if [ "$OS" = "Linux" ] + if [ "$OS" = "Linux" ] && [ "$ARCH" != "aarch64"] then # If we can't download the token file, just skip reporting coverage gsutil cp gs://grpc-testing-secrets/coveralls_credentials/grpc-node.rc /tmp || exit 0 diff --git a/test/aarch64/prepare_qemu.sh b/test/aarch64/prepare_qemu.sh new file mode 100755 index 000000000..f61320222 --- /dev/null +++ b/test/aarch64/prepare_qemu.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Setup and configure qemu userspace emulator on kokoro worker so that we can seamlessly emulate processes running +# inside docker containers. + +set -ex + +# show pre-existing qemu registration +cat /proc/sys/fs/binfmt_misc/qemu-aarch64 + +# Kokoro ubuntu1604 workers have already qemu-user and qemu-user-static packages installed, but it's and old version that: +# * prints warning about some syscalls (e.g "qemu: Unsupported syscall: 278") +# * doesn't register with binfmt_misc with the persistent ("F") flag we need (see below) +# +# To overcome the above limitations, we use the https://github.com/multiarch/qemu-user-static +# docker image to provide a new enough version of qemu-user-static and register it with +# the desired binfmt_misc flags. The most important flag we need is "F" (set by "--persistent yes"), +# which allows the qemu-aarch64-static binary to be loaded eagerly at the time of registration with binfmt_misc. +# That way, we can emulate aarch64 binaries running inside docker containers transparently, without needing the emulator +# binary to be accessible from the docker image we're emulating. +# Note that on newer distributions (such as glinux), simply "apt install qemu-user-static" is sufficient +# to install qemu-user-static with the right flags. +docker run --rm --privileged multiarch/qemu-user-static:5.2.0-2 --reset --credential yes --persistent yes + +# Print current qemu reqistration to make sure everything is setup correctly. +cat /proc/sys/fs/binfmt_misc/qemu-aarch64 diff --git a/test/kokoro/linux_aarch64.cfg b/test/kokoro/linux_aarch64.cfg new file mode 100644 index 000000000..638748ab8 --- /dev/null +++ b/test/kokoro/linux_aarch64.cfg @@ -0,0 +1,24 @@ +# 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/test/kokoro_linux_aarch64.sh" +timeout_mins: 60 +action { + define_artifacts { + regex: "github/grpc-node/reports/**/sponge_log.xml" + } +} diff --git a/test/kokoro_linux_aarch64.sh b/test/kokoro_linux_aarch64.sh new file mode 100755 index 000000000..8a4752c41 --- /dev/null +++ b/test/kokoro_linux_aarch64.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# Copyright 2021 The 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 -ex +cd $(dirname $0)/.. + +test/aarch64/prepare_qemu.sh + +# better update submodules here. We could update the submodule when running +# under an emulator as well, but it comes with performance penalty. +git submodule update --init --recursive + +if [[ -t 0 ]]; then + DOCKER_TTY_ARGS="-it" +else + # The input device on kokoro is not a TTY, so -it does not work. + DOCKER_TTY_ARGS= +fi + +# the test command to run under an emulated aarch64 docker container. +# we only run tests for a single version of node, since tests under an emulator are significantly slower. +TEST_NODE_COMMAND="node_versions='8' ./run-tests.sh" + +# use an actual aarch64 docker image (with a real aarch64 node) to run build & test grpc-js under an emulator +# * mount the protobuf root as /work to be able to access the crosscompiled files +# * to avoid running the process inside docker as root (which can pollute the workspace with files owned by root), we force +# running under current user's UID and GID. To be able to do that, we need to provide a home directory for the user +# otherwise the UID would be homeless under the docker container (which can lead to various issues). For simplicity, +# we just run map the user's home to a throwaway temporary directory. +docker run $DOCKER_TTY_ARGS --rm --user "$(id -u):$(id -g)" -e "HOME=/home/fake-user" -v "$(mktemp -d):/home/fake-user" -v "$(pwd)":/work -w /work arm64v8/node:8-buster bash -c "$TEST_NODE_COMMAND" From 2b8322ef90dd3e51159c7e1ededc0be19cb9d25d Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 10 May 2021 11:54:10 +0200 Subject: [PATCH 007/450] update aarch64 tests to test with node12 --- test/kokoro_linux_aarch64.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/kokoro_linux_aarch64.sh b/test/kokoro_linux_aarch64.sh index 8a4752c41..9dd6ad86a 100755 --- a/test/kokoro_linux_aarch64.sh +++ b/test/kokoro_linux_aarch64.sh @@ -31,7 +31,7 @@ fi # the test command to run under an emulated aarch64 docker container. # we only run tests for a single version of node, since tests under an emulator are significantly slower. -TEST_NODE_COMMAND="node_versions='8' ./run-tests.sh" +TEST_NODE_COMMAND="node_versions='12' ./run-tests.sh" # use an actual aarch64 docker image (with a real aarch64 node) to run build & test grpc-js under an emulator # * mount the protobuf root as /work to be able to access the crosscompiled files @@ -39,4 +39,4 @@ TEST_NODE_COMMAND="node_versions='8' ./run-tests.sh" # running under current user's UID and GID. To be able to do that, we need to provide a home directory for the user # otherwise the UID would be homeless under the docker container (which can lead to various issues). For simplicity, # we just run map the user's home to a throwaway temporary directory. -docker run $DOCKER_TTY_ARGS --rm --user "$(id -u):$(id -g)" -e "HOME=/home/fake-user" -v "$(mktemp -d):/home/fake-user" -v "$(pwd)":/work -w /work arm64v8/node:8-buster bash -c "$TEST_NODE_COMMAND" +docker run $DOCKER_TTY_ARGS --rm --user "$(id -u):$(id -g)" -e "HOME=/home/fake-user" -v "$(mktemp -d):/home/fake-user" -v "$(pwd)":/work -w /work arm64v8/node:12-buster bash -c "$TEST_NODE_COMMAND" From 7de0d08e299a339a8b156ed56f508e76de35077a Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 12 May 2021 14:30:25 -0700 Subject: [PATCH 008/450] grpc-js: Apply timeouts from service configs --- packages/grpc-js/src/call-stream.ts | 30 +++++++++++++++++++------ packages/grpc-js/src/channel.ts | 8 +++++++ packages/grpc-js/src/deadline-filter.ts | 24 ++++++++++++++++---- packages/grpc-js/src/filter-stack.ts | 6 +++++ packages/grpc-js/src/filter.ts | 5 +++++ packages/grpc-js/src/service-config.ts | 27 +++++++++++++++++----- 6 files changed, 84 insertions(+), 16 deletions(-) diff --git a/packages/grpc-js/src/call-stream.ts b/packages/grpc-js/src/call-stream.ts index 8fcc7065e..3a81cbe94 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -70,6 +70,17 @@ function getSystemErrorName(errno: number): string { export type Deadline = Date | number; +function getMinDeadline(deadlineList: Deadline[]): Deadline { + let minValue: number = Infinity; + for (const deadline of deadlineList) { + const deadlineMsecs = deadline instanceof Date ? deadline.getTime() : deadline; + if (deadlineMsecs < minValue) { + minValue = deadlineMsecs; + } + } + return minValue; +} + export interface CallStreamOptions { deadline: Deadline; flags: number; @@ -235,6 +246,8 @@ export class Http2CallStream implements Call { private internalError: SystemError | null = null; + private configDeadline: Deadline = Infinity; + constructor( private readonly methodName: string, private readonly channel: ChannelImplementation, @@ -675,15 +688,14 @@ export class Http2CallStream implements Call { } getDeadline(): Deadline { + const deadlineList = [this.options.deadline]; if (this.options.parentCall && this.options.flags & Propagate.DEADLINE) { - const parentDeadline = this.options.parentCall.getDeadline(); - const selfDeadline = this.options.deadline; - const parentDeadlineMsecs = parentDeadline instanceof Date ? parentDeadline.getTime() : parentDeadline; - const selfDeadlineMsecs = selfDeadline instanceof Date ? selfDeadline.getTime() : selfDeadline; - return Math.min(parentDeadlineMsecs, selfDeadlineMsecs); - } else { - return this.options.deadline; + deadlineList.push(this.options.parentCall.getDeadline()); + } + if (this.configDeadline) { + deadlineList.push(this.configDeadline); } + return getMinDeadline(deadlineList); } getCredentials(): CallCredentials { @@ -710,6 +722,10 @@ export class Http2CallStream implements Call { return this.options.host; } + setConfigDeadline(configDeadline: Deadline) { + this.configDeadline = configDeadline; + } + startRead() { /* If the stream has ended with an error, we should not emit any more * messages and we should communicate that the stream has ended */ diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 41715c41e..88b1d4998 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -523,6 +523,14 @@ export class ChannelImplementation implements Channel { } else { const callConfig = this.configSelector(stream.getMethod(), metadata); if (callConfig.status === Status.OK) { + if (callConfig.methodConfig.timeout) { + const deadline = new Date(); + deadline.setSeconds(deadline.getSeconds() + callConfig.methodConfig.timeout.seconds); + deadline.setMilliseconds(deadline.getMilliseconds() + callConfig.methodConfig.timeout.nanos / 1_000_000); + stream.setConfigDeadline(deadline); + // Refreshing the filters makes the deadline filter pick up the new deadline + stream.filterStack.refresh(); + } this.tryPick(stream, metadata, callConfig); } else { stream.cancelWithStatus(callConfig.status, "Failed to route call to method " + stream.getMethod()); diff --git a/packages/grpc-js/src/deadline-filter.ts b/packages/grpc-js/src/deadline-filter.ts index 99bfa2bec..afc015546 100644 --- a/packages/grpc-js/src/deadline-filter.ts +++ b/packages/grpc-js/src/deadline-filter.ts @@ -42,30 +42,41 @@ function getDeadline(deadline: number) { export class DeadlineFilter extends BaseFilter implements Filter { private timer: NodeJS.Timer | null = null; - private deadline: number; + private deadline: number = Infinity; constructor( private readonly channel: Channel, private readonly callStream: Call ) { super(); - const callDeadline = callStream.getDeadline(); + this.retreiveDeadline(); + this.runTimer(); + } + + private retreiveDeadline() { + const callDeadline = this.callStream.getDeadline(); if (callDeadline instanceof Date) { this.deadline = callDeadline.getTime(); } else { this.deadline = callDeadline; } + } + + private runTimer() { + if (this.timer) { + clearTimeout(this.timer); + } const now: number = new Date().getTime(); let timeout = this.deadline - now; if (timeout <= 0) { process.nextTick(() => { - callStream.cancelWithStatus( + this.callStream.cancelWithStatus( Status.DEADLINE_EXCEEDED, 'Deadline exceeded' ); }); } else if (this.deadline !== Infinity) { this.timer = setTimeout(() => { - callStream.cancelWithStatus( + this.callStream.cancelWithStatus( Status.DEADLINE_EXCEEDED, 'Deadline exceeded' ); @@ -74,6 +85,11 @@ export class DeadlineFilter extends BaseFilter implements Filter { } } + refresh() { + this.retreiveDeadline(); + this.runTimer(); + } + async sendMetadata(metadata: Promise) { if (this.deadline === Infinity) { return metadata; diff --git a/packages/grpc-js/src/filter-stack.ts b/packages/grpc-js/src/filter-stack.ts index a656a4099..4fd888549 100644 --- a/packages/grpc-js/src/filter-stack.ts +++ b/packages/grpc-js/src/filter-stack.ts @@ -71,6 +71,12 @@ export class FilterStack implements Filter { return result; } + + refresh(): void { + for (const filter of this.filters) { + filter.refresh(); + } + } } export class FilterStackFactory implements FilterFactory { diff --git a/packages/grpc-js/src/filter.ts b/packages/grpc-js/src/filter.ts index c1e412ae5..eb67bd32e 100644 --- a/packages/grpc-js/src/filter.ts +++ b/packages/grpc-js/src/filter.ts @@ -32,6 +32,8 @@ export interface Filter { receiveMessage(message: Promise): Promise; receiveTrailers(status: StatusObject): StatusObject; + + refresh(): void; } export abstract class BaseFilter implements Filter { @@ -54,6 +56,9 @@ export abstract class BaseFilter implements Filter { receiveTrailers(status: StatusObject): StatusObject { return status; } + + refresh(): void { + } } export interface FilterFactory { diff --git a/packages/grpc-js/src/service-config.ts b/packages/grpc-js/src/service-config.ts index ed225e087..efc09f9c4 100644 --- a/packages/grpc-js/src/service-config.ts +++ b/packages/grpc-js/src/service-config.ts @@ -34,10 +34,15 @@ export interface MethodConfigName { method?: string; } +export interface Duration { + seconds: number; + nanos: number; +} + export interface MethodConfig { name: MethodConfigName[]; waitForReady?: boolean; - timeout?: string; + timeout?: Duration; maxRequestBytes?: number; maxResponseBytes?: number; } @@ -101,13 +106,25 @@ function validateMethodConfig(obj: any): MethodConfig { result.waitForReady = obj.waitForReady; } if ('timeout' in obj) { - if ( - !(typeof obj.timeout === 'string') || - !TIMEOUT_REGEX.test(obj.timeout) + if (typeof obj.timeout === 'object') { + if (!('seconds' in obj.timeout) || !(typeof obj.timeout.seconds === 'number')) { + throw new Error('Invalid method config: invalid timeout.seconds'); + } + if (!('nanos' in obj.timeout) || !(typeof obj.timeout.nanos === 'number')) { + throw new Error('Invalid method config: invalid timeout.nanos'); + } + result.timeout = obj.timeout; + } else if ( + (typeof obj.timeout === 'string') && TIMEOUT_REGEX.test(obj.timeout) ) { + const timeoutParts = obj.timeout.substring(0, obj.timeout.length - 1).split('.'); + result.timeout = { + seconds: timeoutParts[0] | 0, + nanos: (timeoutParts[1] ?? 0) | 0 + } + } else { throw new Error('Invalid method config: invalid timeout'); } - result.timeout = obj.timeout; } if ('maxRequestBytes' in obj) { if (typeof obj.maxRequestBytes !== 'number') { From e3106b99ca9fcebf8db9eedf9cc2a044d82f551c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 12 May 2021 14:38:02 -0700 Subject: [PATCH 009/450] Don't query the config selector for calls that have ended --- packages/grpc-js/src/channel.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 88b1d4998..8b2658f37 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -509,6 +509,11 @@ export class ChannelImplementation implements Channel { } private tryGetConfig(stream: Http2CallStream, metadata: Metadata) { + if (stream.getStatus() !== null) { + /* If the stream has a status, it has already finished and we don't need + * to take any more actions on it. */ + return; + } if (this.configSelector === null) { /* This branch will only be taken at the beginning of the channel's life, * before the resolver ever returns a result. So, the From f4f1d54031b3788687b21901f92547f42a993866 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 17 May 2021 11:07:45 -0700 Subject: [PATCH 010/450] grpc-js-xds: Propagate timeouts from xDS responses to method config --- packages/grpc-js-xds/src/resolver-xds.ts | 45 ++++++++++++++++++++++-- packages/grpc-js-xds/src/route-action.ts | 16 +++++++-- packages/grpc-js/src/experimental.ts | 2 +- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/packages/grpc-js-xds/src/resolver-xds.ts b/packages/grpc-js-xds/src/resolver-xds.ts index a9ee1af7d..892cf5711 100644 --- a/packages/grpc-js-xds/src/resolver-xds.ts +++ b/packages/grpc-js-xds/src/resolver-xds.ts @@ -40,6 +40,8 @@ import { XdsClusterManagerLoadBalancingConfig } from './load-balancer-xds-cluste import { ExactValueMatcher, Fraction, FullMatcher, HeaderMatcher, Matcher, PathExactValueMatcher, PathPrefixValueMatcher, PathSafeRegexValueMatcher, PrefixValueMatcher, PresentValueMatcher, RangeValueMatcher, RejectValueMatcher, SafeRegexValueMatcher, SuffixValueMatcher, ValueMatcher } from './matcher'; import { RouteAction, SingleClusterRouteAction, WeightedCluster, WeightedClusterRouteAction } from './route-action'; import { decodeSingleResource, HTTP_CONNECTION_MANGER_TYPE_URL_V3 } from './resources'; +import Duration = experimental.Duration; +import { Duration__Output } from './generated/google/protobuf/Duration'; const TRACER_NAME = 'xds_resolver'; @@ -187,6 +189,20 @@ function getPredicateForMatcher(routeMatch: RouteMatch__Output): Matcher { return new FullMatcher(pathMatcher, headerMatchers, runtimeFraction); } +/** + * Convert a Duration protobuf message object to a Duration object as used in + * the ServiceConfig definition. The difference is that the protobuf message + * defines seconds as a long, which is represented as a string in JavaScript, + * and the one used in the service config defines it as a number. + * @param duration + */ +function protoDurationToDuration(duration: Duration__Output): Duration { + return { + seconds: Number.parseInt(duration.seconds), + nanos: duration.nanos + } +} + class XdsResolver implements Resolver { private hasReportedSuccess = false; @@ -203,6 +219,8 @@ class XdsResolver implements Resolver { private clusterRefcounts = new Map(); + private latestDefaultTimeout: Duration | undefined = undefined; + constructor( private target: GrpcUri, private listener: ResolverListener, @@ -211,6 +229,12 @@ class XdsResolver implements Resolver { this.ldsWatcher = { onValidUpdate: (update: Listener__Output) => { const httpConnectionManager = decodeSingleResource(HTTP_CONNECTION_MANGER_TYPE_URL_V3, update.api_listener!.api_listener!.value); + const defaultTimeout = httpConnectionManager.common_http_protocol_options?.idle_timeout; + if (defaultTimeout === undefined) { + this.latestDefaultTimeout = undefined; + } else { + this.latestDefaultTimeout = protoDurationToDuration(defaultTimeout); + } switch (httpConnectionManager.route_specifier) { case 'rds': { const routeConfigName = httpConnectionManager.rds!.route_config_name; @@ -295,13 +319,28 @@ class XdsResolver implements Resolver { const matchList: {matcher: Matcher, action: RouteAction}[] = []; for (const route of virtualHost.routes) { let routeAction: RouteAction; + let timeout: Duration | undefined; + /* For field prioritization see + * https://github.com/grpc/proposal/blob/master/A31-xds-timeout-support-and-config-selector.md#supported-fields + */ + if (route.route?.max_stream_duration?.grpc_timeout_header_max) { + timeout = protoDurationToDuration(route.route.max_stream_duration.grpc_timeout_header_max); + } else if (route.route?.max_stream_duration?.max_stream_duration) { + timeout = protoDurationToDuration(route.route.max_stream_duration.max_stream_duration); + } else { + timeout = this.latestDefaultTimeout; + } + // "A value of 0 indicates the application's deadline is used without modification." + if (timeout?.seconds === 0 && timeout.nanos === 0) { + timeout = undefined; + } switch (route.route!.cluster_specifier) { case 'cluster_header': continue; case 'cluster':{ const cluster = route.route!.cluster!; allConfigClusters.add(cluster); - routeAction = new SingleClusterRouteAction(cluster); + routeAction = new SingleClusterRouteAction(cluster, timeout); break; } case 'weighted_clusters': { @@ -310,7 +349,7 @@ class XdsResolver implements Resolver { allConfigClusters.add(clusterWeight.name); weightedClusters.push({name: clusterWeight.name, weight: clusterWeight.weight?.value ?? 0}); } - routeAction = new WeightedClusterRouteAction(weightedClusters, route.route!.weighted_clusters!.total_weight?.value ?? 100); + routeAction = new WeightedClusterRouteAction(weightedClusters, route.route!.weighted_clusters!.total_weight?.value ?? 100, timeout); } } const routeMatcher = getPredicateForMatcher(route.match!); @@ -343,7 +382,7 @@ class XdsResolver implements Resolver { this.unrefCluster(clusterName); } return { - methodConfig: {name: []}, + methodConfig: {name: [], timeout: action.getTimeout()}, onCommitted: onCommitted, pickInformation: {cluster: clusterName}, status: status.OK diff --git a/packages/grpc-js-xds/src/route-action.ts b/packages/grpc-js-xds/src/route-action.ts index 4ba2b5908..b43874d8f 100644 --- a/packages/grpc-js-xds/src/route-action.ts +++ b/packages/grpc-js-xds/src/route-action.ts @@ -14,13 +14,17 @@ * limitations under the License. */ +import { experimental } from '@grpc/grpc-js'; +import Duration = experimental.Duration; + export interface RouteAction { toString(): string; getCluster(): string; + getTimeout(): Duration | undefined; } export class SingleClusterRouteAction implements RouteAction { - constructor(private cluster: string) {} + constructor(private cluster: string, private timeout: Duration | undefined) {} getCluster() { return this.cluster; @@ -29,6 +33,10 @@ export class SingleClusterRouteAction implements RouteAction { toString() { return 'SingleCluster(' + this.cluster + ')'; } + + getTimeout() { + return this.timeout; + } } export interface WeightedCluster { @@ -46,7 +54,7 @@ export class WeightedClusterRouteAction implements RouteAction { * The weighted cluster choices represented as a CDF */ private clusterChoices: ClusterChoice[]; - constructor(private clusters: WeightedCluster[], private totalWeight: number) { + constructor(private clusters: WeightedCluster[], private totalWeight: number, private timeout: Duration | undefined) { this.clusterChoices = []; let lastNumerator = 0; for (const clusterWeight of clusters) { @@ -69,4 +77,8 @@ export class WeightedClusterRouteAction implements RouteAction { toString() { return 'WeightedCluster(' + this.clusters.map(({name, weight}) => '(' + name + ':' + weight + ')').join(', ') + ')'; } + + getTimeout() { + return this.timeout; + } } \ No newline at end of file diff --git a/packages/grpc-js/src/experimental.ts b/packages/grpc-js/src/experimental.ts index f62838c12..cf84ba6b8 100644 --- a/packages/grpc-js/src/experimental.ts +++ b/packages/grpc-js/src/experimental.ts @@ -1,7 +1,7 @@ export { trace } from './logging'; export { Resolver, ResolverListener, registerResolver, ConfigSelector } from './resolver'; export { GrpcUri, uriToString } from './uri-parser'; -export { ServiceConfig } from './service-config'; +export { ServiceConfig, Duration } from './service-config'; export { BackoffTimeout } from './backoff-timeout'; export { LoadBalancer, LoadBalancingConfig, ChannelControlHelper, registerLoadBalancerType, getFirstUsableConfig, validateLoadBalancingConfig } from './load-balancer'; export { SubchannelAddress, subchannelAddressToString } from './subchannel'; From f5b9e7bab15dcd65aff3c66aa8e8ad6f476621bc Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 17 May 2021 14:52:45 -0700 Subject: [PATCH 011/450] grpc-js-xds: Add circuit breaking functionality --- packages/grpc-js-xds/src/load-balancer-eds.ts | 70 ++++++++++++++++--- packages/grpc-js-xds/src/xds-client.ts | 9 +++ 2 files changed, 69 insertions(+), 10 deletions(-) diff --git a/packages/grpc-js-xds/src/load-balancer-eds.ts b/packages/grpc-js-xds/src/load-balancer-eds.ts index ae9a781bd..76bdd6655 100644 --- a/packages/grpc-js-xds/src/load-balancer-eds.ts +++ b/packages/grpc-js-xds/src/load-balancer-eds.ts @@ -15,7 +15,7 @@ * */ -import { connectivityState as ConnectivityState, status as Status, Metadata, logVerbosity as LogVerbosity, experimental } from '@grpc/grpc-js'; +import { connectivityState as ConnectivityState, status as Status, Metadata, logVerbosity as LogVerbosity, experimental, StatusObject } from '@grpc/grpc-js'; import { getSingletonXdsClient, XdsClient, XdsClusterDropStats } from './xds-client'; import { ClusterLoadAssignment__Output } from './generated/envoy/config/endpoint/v3/ClusterLoadAssignment'; import { Locality__Output } from './generated/envoy/api/v2/core/Locality'; @@ -34,6 +34,10 @@ import { validateLoadBalancingConfig } from '@grpc/grpc-js/build/src/experimenta import { WeightedTarget, WeightedTargetLoadBalancingConfig } from './load-balancer-weighted-target'; import { LrsLoadBalancingConfig } from './load-balancer-lrs'; import { Watcher } from './xds-stream-state/xds-stream-state'; +import Filter = experimental.Filter; +import BaseFilter = experimental.BaseFilter; +import FilterFactory = experimental.FilterFactory; +import CallStream = experimental.CallStream; const TRACER_NAME = 'eds_balancer'; @@ -47,7 +51,10 @@ function localityToName(locality: Locality__Output) { return `{region=${locality.region},zone=${locality.zone},sub_zone=${locality.sub_zone}}`; } +const DEFAULT_MAX_CONCURRENT_REQUESTS = 1024; + export class EdsLoadBalancingConfig implements LoadBalancingConfig { + private maxConcurrentRequests: number; getLoadBalancerName(): string { return TYPE_NAME; } @@ -55,7 +62,8 @@ export class EdsLoadBalancingConfig implements LoadBalancingConfig { const jsonObj: {[key: string]: any} = { cluster: this.cluster, locality_picking_policy: this.localityPickingPolicy.map(policy => policy.toJsonObject()), - endpoint_picking_policy: this.endpointPickingPolicy.map(policy => policy.toJsonObject()) + endpoint_picking_policy: this.endpointPickingPolicy.map(policy => policy.toJsonObject()), + max_concurrent_requests: this.maxConcurrentRequests }; if (this.edsServiceName !== undefined) { jsonObj.eds_service_name = this.edsServiceName; @@ -68,8 +76,8 @@ export class EdsLoadBalancingConfig implements LoadBalancingConfig { }; } - constructor(private cluster: string, private localityPickingPolicy: LoadBalancingConfig[], private endpointPickingPolicy: LoadBalancingConfig[], private edsServiceName?: string, private lrsLoadReportingServerName?: string) { - + constructor(private cluster: string, private localityPickingPolicy: LoadBalancingConfig[], private endpointPickingPolicy: LoadBalancingConfig[], private edsServiceName?: string, private lrsLoadReportingServerName?: string, maxConcurrentRequests?: number) { + this.maxConcurrentRequests = maxConcurrentRequests ?? DEFAULT_MAX_CONCURRENT_REQUESTS; } getCluster() { @@ -92,6 +100,10 @@ export class EdsLoadBalancingConfig implements LoadBalancingConfig { return this.lrsLoadReportingServerName; } + getMaxConcurrentRequests() { + return this.maxConcurrentRequests; + } + static createFromJson(obj: any): EdsLoadBalancingConfig { if (!('cluster' in obj && typeof obj.cluster === 'string')) { throw new Error('eds config must have a string field cluster'); @@ -108,7 +120,28 @@ export class EdsLoadBalancingConfig implements LoadBalancingConfig { if ('lrs_load_reporting_server_name' in obj && (!obj.lrs_load_reporting_server_name === undefined || typeof obj.lrs_load_reporting_server_name === 'string')) { throw new Error('eds config lrs_load_reporting_server_name must be a string if provided'); } - return new EdsLoadBalancingConfig(obj.cluster, obj.locality_picking_policy.map(validateLoadBalancingConfig), obj.endpoint_picking_policy.map(validateLoadBalancingConfig), obj.eds_service_name, obj.lrs_load_reporting_server_name); + if ('max_concurrent_requests' in obj && (!obj.max_concurrent_requests === undefined || typeof obj.max_concurrent_requests === 'number')) { + throw new Error('eds config max_concurrent_requests must be a number if provided'); + } + return new EdsLoadBalancingConfig(obj.cluster, obj.locality_picking_policy.map(validateLoadBalancingConfig), obj.endpoint_picking_policy.map(validateLoadBalancingConfig), obj.eds_service_name, obj.lrs_load_reporting_server_name, obj.max_concurrent_requests); + } +} + +class CallEndTrackingFilter extends BaseFilter implements Filter { + constructor(private onCallEnd: () => void) { + super(); + } + receiveTrailers(status: StatusObject) { + this.onCallEnd(); + return status; + } +} + +class CallTrackingFilterFactory implements FilterFactory { + constructor(private onCallEnd: () => void) {} + + createFilter(callStream: CallStream) { + return new CallEndTrackingFilter(this.onCallEnd); } } @@ -149,6 +182,8 @@ export class EdsLoadBalancer implements LoadBalancer { private clusterDropStats: XdsClusterDropStats | null = null; + private concurrentRequests: number = 0; + constructor(private readonly channelControlHelper: ChannelControlHelper) { this.childBalancer = new ChildLoadBalancerHandler({ createSubchannel: (subchannelAddress, subchannelArgs) => @@ -171,7 +206,11 @@ export class EdsLoadBalancer implements LoadBalancer { if (dropCategory === null) { return originalPicker.pick(pickArgs); } else { - this.clusterDropStats?.addCallDropped(dropCategory); + if (dropCategory === true) { + this.clusterDropStats?.addUncategorizedCallDropped(); + } else { + this.clusterDropStats?.addCallDropped(dropCategory); + } return { pickResultType: PickResultType.DROP, status: { @@ -180,8 +219,12 @@ export class EdsLoadBalancer implements LoadBalancer { metadata: new Metadata(), }, subchannel: null, - extraFilterFactory: null, - onCallStarted: null, + extraFilterFactory: new CallTrackingFilterFactory(() => { + this.concurrentRequests -= 1; + }), + onCallStarted: () => { + this.concurrentRequests += 1; + }, }; } }, @@ -218,12 +261,19 @@ export class EdsLoadBalancer implements LoadBalancer { /** * Check whether a single call should be dropped according to the current * policy, based on randomly chosen numbers. Returns the drop category if - * the call should be dropped, and null otherwise. + * the call should be dropped, and null otherwise. true is a valid + * output, as a sentinel value indicating a drop with no category. */ - private checkForDrop(): string | null { + private checkForDrop(): string | true | null { if (!this.latestEdsUpdate?.policy) { return null; } + if (!this.lastestConfig) { + return null; + } + if (this.concurrentRequests >= this.lastestConfig.getMaxConcurrentRequests()) { + return true; + } /* The drop_overloads policy is a list of pairs of category names and * probabilities. For each one, if the random number is within that * probability range, we drop the call citing that category. Otherwise, the diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index adc54ed45..ddca9284f 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -114,6 +114,7 @@ function localityEqual( } export interface XdsClusterDropStats { + addUncategorizedCallDropped(): void; addCallDropped(category: string): void; } @@ -158,6 +159,7 @@ interface ClusterLocalityStats { interface ClusterLoadReport { callsDropped: Map; + uncategorizedCallsDropped: number; localityStats: ClusterLocalityStats[]; intervalStart: [number, number]; } @@ -195,6 +197,7 @@ class ClusterLoadReportMap { } const newStats: ClusterLoadReport = { callsDropped: new Map(), + uncategorizedCallsDropped: 0, localityStats: [], intervalStart: process.hrtime(), }; @@ -871,8 +874,10 @@ export class XdsClient { totalDroppedRequests += count; } } + totalDroppedRequests += stats.uncategorizedCallsDropped; // Clear out dropped call stats after sending them stats.callsDropped.clear(); + stats.uncategorizedCallsDropped = 0; const interval = process.hrtime(stats.intervalStart); stats.intervalStart = process.hrtime(); // Skip clusters with 0 requests @@ -957,6 +962,7 @@ export class XdsClient { trace('addClusterDropStats(lrsServer=' + lrsServer + ', clusterName=' + clusterName + ', edsServiceName=' + edsServiceName + ')'); if (lrsServer !== '') { return { + addUncategorizedCallDropped: () => {}, addCallDropped: (category) => {}, }; } @@ -965,6 +971,9 @@ export class XdsClient { edsServiceName ); return { + addUncategorizedCallDropped: () => { + clusterStats.uncategorizedCallsDropped += 1; + }, addCallDropped: (category) => { const prevCount = clusterStats.callsDropped.get(category) ?? 0; clusterStats.callsDropped.set(category, prevCount + 1); From bdc8d2de9db276f2adec7ccf6c432bcf8425215f Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 19 May 2021 13:19:36 -0700 Subject: [PATCH 012/450] Don't clean after testing on each Node version --- run-tests.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/run-tests.sh b/run-tests.sh index 2808e2af6..03fd970b5 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -71,7 +71,6 @@ do node -e 'process.exit(process.version.startsWith("v'$version'") ? 0 : -1)' # Install dependencies and link packages together. - ./node_modules/.bin/gulp cleanAll ./node_modules/.bin/gulp setup # npm test calls nyc gulp test From d51551f6d71b05fa6934045022a961bfc1d4d1b4 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 17 May 2021 11:08:54 -0700 Subject: [PATCH 013/450] grpc-js-xds: Add support for timeout xDS interop test Add more logging --- .../grpc-js-xds/interop/xds-interop-client.ts | 45 ++++++++-- packages/grpc-js-xds/scripts/xds.sh | 4 +- packages/grpc-js-xds/src/route-action.ts | 22 ++++- packages/grpc-js/src/metadata.ts | 12 +++ packages/grpc-js/test/test-deadline.ts | 90 +++++++++++++++++++ test/kokoro/xds-interop.cfg | 2 +- test/kokoro/xds-v3-interop.cfg | 2 +- 7 files changed, 164 insertions(+), 13 deletions(-) create mode 100644 packages/grpc-js/test/test-deadline.ts diff --git a/packages/grpc-js-xds/interop/xds-interop-client.ts b/packages/grpc-js-xds/interop/xds-interop-client.ts index 5f32831c1..f6beccbf0 100644 --- a/packages/grpc-js-xds/interop/xds-interop-client.ts +++ b/packages/grpc-js-xds/interop/xds-interop-client.ts @@ -197,29 +197,44 @@ let anyCallSucceeded = false; const accumulatedStats: LoadBalancerAccumulatedStatsResponse = { stats_per_method: { - EmptyCall: { + EMPTY_CALL: { rpcs_started: 0, result: {} }, - UnaryCall: { + UNARY_CALL: { rpcs_started: 0, result: {} } } }; +const callTimeHistogram: {[callType: string]: {[status: number]: number[]}} = { + UnaryCall: {}, + EmptyCall: {} +} + function makeSingleRequest(client: TestServiceClient, type: CallType, failOnFailedRpcs: boolean, callStatsTracker: CallStatsTracker) { - const callTypeStats = accumulatedStats.stats_per_method![type]; + const callTypeStats = accumulatedStats.stats_per_method![callTypeEnumMapReverse[type]]; callTypeStats.rpcs_started! += 1; const notifier = callStatsTracker.startCall(); let gotMetadata: boolean = false; let hostname: string | null = null; let completed: boolean = false; let completedWithError: boolean = false; + const startTime = process.hrtime(); const deadline = new Date(); deadline.setSeconds(deadline.getSeconds() + currentConfig.timeoutSec); const callback = (error: grpc.ServiceError | undefined, value: Empty__Output | undefined) => { const statusCode = error?.code ?? grpc.status.OK; + const duration = process.hrtime(startTime); + if (!callTimeHistogram[type][statusCode]) { + callTimeHistogram[type][statusCode] = []; + } + if (callTimeHistogram[type][statusCode][duration[0]]) { + callTimeHistogram[type][statusCode][duration[0]] += 1; + } else { + callTimeHistogram[type][statusCode][duration[0]] = 1; + } callTypeStats.result![statusCode] = (callTypeStats.result![statusCode] ?? 0) + 1; if (error) { if (failOnFailedRpcs && anyCallSucceeded) { @@ -269,18 +284,27 @@ const callTypeEnumMap = { 'UNARY_CALL': 'UnaryCall' as CallType }; +const callTypeEnumMapReverse = { + 'EmptyCall': 'EMPTY_CALL', + 'UnaryCall': 'UNARY_CALL' +} + +const DEFAULT_TIMEOUT_SEC = 20; + function main() { const argv = yargs .string(['fail_on_failed_rpcs', 'server', 'stats_port', 'rpc', 'metadata']) - .number(['num_channels', 'qps']) + .number(['num_channels', 'qps', 'rpc_timeout_sec']) .demandOption(['server', 'stats_port']) .default('num_channels', 1) .default('qps', 1) .default('rpc', 'UnaryCall') .default('metadata', '') + .default('rpc_timeout_sec', DEFAULT_TIMEOUT_SEC) .argv; console.log('Starting xDS interop client. Args: ', argv); currentConfig.callTypes = argv.rpc.split(',').filter(value => value === 'EmptyCall' || value === 'UnaryCall') as CallType[]; + currentConfig.timeoutSec = argv.rpc_timeout_sec; for (const item of argv.metadata.split(',')) { const [method, key, value] = item.split(':'); if (value === undefined) { @@ -316,23 +340,30 @@ function main() { }); }, GetClientAccumulatedStats: (call, callback) => { + console.log(`Sending accumulated stats response: ${JSON.stringify(accumulatedStats)}`); + console.log(`Call durations: ${JSON.stringify(callTimeHistogram, undefined, 2)}`); callback(null, accumulatedStats); } } const xdsUpdateClientConfigureServiceImpl: XdsUpdateClientConfigureServiceHandlers = { Configure: (call, callback) => { + console.log('Received new client configuration: ' + JSON.stringify(call.request, undefined, 2)); const callMetadata = { EmptyCall: new grpc.Metadata(), UnaryCall: new grpc.Metadata() - } + }; for (const metadataItem of call.request.metadata) { callMetadata[callTypeEnumMap[metadataItem.type]].add(metadataItem.key, metadataItem.value); } currentConfig.callTypes = call.request.types.map(value => callTypeEnumMap[value]); currentConfig.metadata = callMetadata; - currentConfig.timeoutSec = call.request.timeout_sec - console.log('Received new client configuration: ' + JSON.stringify(currentConfig, undefined, 2)); + if (call.request.timeout_sec > 0) { + currentConfig.timeoutSec = call.request.timeout_sec; + } else { + currentConfig.timeoutSec = DEFAULT_TIMEOUT_SEC; + } + console.log('Updated to new client configuration: ' + JSON.stringify(currentConfig, undefined, 2)); callback(null, {}); } } diff --git a/packages/grpc-js-xds/scripts/xds.sh b/packages/grpc-js-xds/scripts/xds.sh index 9008b9731..68225faef 100755 --- a/packages/grpc-js-xds/scripts/xds.sh +++ b/packages/grpc-js-xds/scripts/xds.sh @@ -52,9 +52,9 @@ GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weigh GRPC_NODE_VERBOSITY=DEBUG \ NODE_XDS_INTEROP_VERBOSITY=1 \ python3 grpc/tools/run_tests/run_xds_tests.py \ - --test_case="all,path_matching,header_matching" \ + --test_case="all,timeout" \ --project_id=grpc-testing \ - --source_image=projects/grpc-testing/global/images/xds-test-server-2 \ + --source_image=projects/grpc-testing/global/images/xds-test-server-4 \ --path_to_server_binary=/java_server/grpc-java/interop-testing/build/install/grpc-interop-testing/bin/xds-test-server \ --gcp_suffix=$(date '+%s') \ --verbose \ diff --git a/packages/grpc-js-xds/src/route-action.ts b/packages/grpc-js-xds/src/route-action.ts index b43874d8f..5574bcd91 100644 --- a/packages/grpc-js-xds/src/route-action.ts +++ b/packages/grpc-js-xds/src/route-action.ts @@ -23,6 +23,15 @@ export interface RouteAction { getTimeout(): Duration | undefined; } +function durationToLogString(duration: Duration) { + const millis = Math.floor(duration.nanos / 1_000_000); + if (millis > 0) { + return duration.seconds + '.' + millis; + } else { + return '' + duration.seconds; + } +} + export class SingleClusterRouteAction implements RouteAction { constructor(private cluster: string, private timeout: Duration | undefined) {} @@ -31,7 +40,11 @@ export class SingleClusterRouteAction implements RouteAction { } toString() { - return 'SingleCluster(' + this.cluster + ')'; + if (this.timeout) { + return 'SingleCluster(' + this.cluster + ', ' + 'timeout=' + durationToLogString(this.timeout) + 's)'; + } else { + return 'SingleCluster(' + this.cluster + ')'; + } } getTimeout() { @@ -75,7 +88,12 @@ export class WeightedClusterRouteAction implements RouteAction { } toString() { - return 'WeightedCluster(' + this.clusters.map(({name, weight}) => '(' + name + ':' + weight + ')').join(', ') + ')'; + const clusterListString = this.clusters.map(({name, weight}) => '(' + name + ':' + weight + ')').join(', ') + if (this.timeout) { + return 'WeightedCluster(' + clusterListString + ', ' + 'timeout=' + durationToLogString(this.timeout) + 's)'; + } else { + return 'WeightedCluster(' + clusterListString + ')'; + } } getTimeout() { diff --git a/packages/grpc-js/src/metadata.ts b/packages/grpc-js/src/metadata.ts index 4947bf0ad..bc66012ce 100644 --- a/packages/grpc-js/src/metadata.ts +++ b/packages/grpc-js/src/metadata.ts @@ -242,6 +242,18 @@ export class Metadata { return this.internalRepr; } + /** + * This modifies the behavior of JSON.stringify to show an object + * representation of the metadata map. + */ + toJSON() { + const result: {[key: string]: MetadataValue[]} = {}; + for (const [key, values] of this.internalRepr.entries()) { + result[key] = values; + } + return result; + } + /** * Returns a new Metadata object based fields in a given IncomingHttpHeaders * object. diff --git a/packages/grpc-js/test/test-deadline.ts b/packages/grpc-js/test/test-deadline.ts new file mode 100644 index 000000000..bb6b3ba9b --- /dev/null +++ b/packages/grpc-js/test/test-deadline.ts @@ -0,0 +1,90 @@ +/* + * Copyright 2021 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 * as assert from 'assert'; + +import * as grpc from '../src'; +import { experimental } from '../src'; +import { ServerCredentials } from '../src'; +import { ServiceClient, ServiceClientConstructor } from '../src/make-client'; +import { loadProtoFile } from './common'; +import ServiceConfig = experimental.ServiceConfig; + +const clientInsecureCreds = grpc.credentials.createInsecure(); +const serverInsecureCreds = ServerCredentials.createInsecure(); + +const TIMEOUT_SERVICE_CONFIG: ServiceConfig = { + loadBalancingConfig: [], + methodConfig: [{ + name: [ + {service: 'TestService'} + ], + timeout: { + seconds: 1, + nanos: 0 + } + }] +}; + +describe('Client with configured timeout', () => { + let server: grpc.Server; + let Client: ServiceClientConstructor; + let client: ServiceClient; + + before(done => { + Client = loadProtoFile(__dirname + '/fixtures/test_service.proto').TestService as ServiceClientConstructor; + server = new grpc.Server(); + server.addService(Client.service, { + unary: () => {}, + clientStream: () => {}, + serverStream: () => {}, + bidiStream: () => {} + }); + server.bindAsync('localhost:0', grpc.ServerCredentials.createInsecure(), (error, port) => { + if (error) { + done(error); + return; + } + server.start(); + client = new Client(`localhost:${port}`, grpc.credentials.createInsecure(), {'grpc.service_config': JSON.stringify(TIMEOUT_SERVICE_CONFIG)}); + done(); + }); + }); + + after(done => { + client.close(); + server.tryShutdown(done); + }); + + it('Should end calls without explicit deadline with DEADLINE_EXCEEDED', done => { + client.unary({}, (error: grpc.ServiceError, value: unknown) =>{ + assert(error); + assert.strictEqual(error.code, grpc.status.DEADLINE_EXCEEDED); + done(); + }); + }); + + it('Should end calls with a long explicit deadline with DEADLINE_EXCEEDED', done => { + const deadline = new Date(); + deadline.setSeconds(deadline.getSeconds() + 20); + client.unary({}, (error: grpc.ServiceError, value: unknown) =>{ + assert(error); + assert.strictEqual(error.code, grpc.status.DEADLINE_EXCEEDED); + done(); + }); + }); +}); \ No newline at end of file diff --git a/test/kokoro/xds-interop.cfg b/test/kokoro/xds-interop.cfg index 16a7dc7dc..a615d0530 100644 --- a/test/kokoro/xds-interop.cfg +++ b/test/kokoro/xds-interop.cfg @@ -16,7 +16,7 @@ # Location of the continuous shell script in repository. build_file: "grpc-node/packages/grpc-js-xds/scripts/xds.sh" -timeout_mins: 120 +timeout_mins: 180 action { define_artifacts { regex: "github/grpc/reports/**" diff --git a/test/kokoro/xds-v3-interop.cfg b/test/kokoro/xds-v3-interop.cfg index d7ffa8fab..4480f1590 100644 --- a/test/kokoro/xds-v3-interop.cfg +++ b/test/kokoro/xds-v3-interop.cfg @@ -16,7 +16,7 @@ # Location of the continuous shell script in repository. build_file: "grpc-node/packages/grpc-js-xds/scripts/xds-v3.sh" -timeout_mins: 120 +timeout_mins: 180 action { define_artifacts { regex: "github/grpc/reports/**" From ec7c819181bf24770e010e81378293dea6d799e5 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 20 May 2021 10:30:28 -0700 Subject: [PATCH 014/450] grpc-js-xds: Enable circuit breaking test --- packages/grpc-js-xds/scripts/xds.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/scripts/xds.sh b/packages/grpc-js-xds/scripts/xds.sh index 68225faef..66fe4d568 100755 --- a/packages/grpc-js-xds/scripts/xds.sh +++ b/packages/grpc-js-xds/scripts/xds.sh @@ -52,7 +52,7 @@ GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weigh GRPC_NODE_VERBOSITY=DEBUG \ NODE_XDS_INTEROP_VERBOSITY=1 \ python3 grpc/tools/run_tests/run_xds_tests.py \ - --test_case="all,timeout" \ + --test_case="all,timeout,circuit_breaking" \ --project_id=grpc-testing \ --source_image=projects/grpc-testing/global/images/xds-test-server-4 \ --path_to_server_binary=/java_server/grpc-java/interop-testing/build/install/grpc-interop-testing/bin/xds-test-server \ From 42d016d979c28ea288923c2b4a6a9426b8d89fd9 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 21 May 2021 10:22:14 +0200 Subject: [PATCH 015/450] workaround "key too small" problem in aarch64 tests --- test/kokoro_linux_aarch64.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/kokoro_linux_aarch64.sh b/test/kokoro_linux_aarch64.sh index 9dd6ad86a..508881e5f 100755 --- a/test/kokoro_linux_aarch64.sh +++ b/test/kokoro_linux_aarch64.sh @@ -39,4 +39,8 @@ TEST_NODE_COMMAND="node_versions='12' ./run-tests.sh" # running under current user's UID and GID. To be able to do that, we need to provide a home directory for the user # otherwise the UID would be homeless under the docker container (which can lead to various issues). For simplicity, # we just run map the user's home to a throwaway temporary directory. -docker run $DOCKER_TTY_ARGS --rm --user "$(id -u):$(id -g)" -e "HOME=/home/fake-user" -v "$(mktemp -d):/home/fake-user" -v "$(pwd)":/work -w /work arm64v8/node:12-buster bash -c "$TEST_NODE_COMMAND" +# TODO(jtattermusch): we're using arm64v8/node:12-stretch instead of arm64v8/node:12-buster because the buster-based image +# has a newer version of ssl that considers some of the ssl keys used for testing too short, making the tests +# fails with "error:140AB18F:SSL routines:SSL_CTX_use_certificate:ee key too small". +# See https://github.com/grpc/grpc-node/issues/1795 +docker run $DOCKER_TTY_ARGS --rm --user "$(id -u):$(id -g)" -e "HOME=/home/fake-user" -v "$(mktemp -d):/home/fake-user" -v "$(pwd)":/work -w /work arm64v8/node:12-stretch bash -c "$TEST_NODE_COMMAND" From accc82fd111e75685b0631f0aa411490032608ca Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 1 Jun 2021 14:56:54 +0200 Subject: [PATCH 016/450] increase timeout for tests that timeout under emulator --- test/api/interop_extra_test.js | 6 ++++++ test/api/interop_sanity_test.js | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/test/api/interop_extra_test.js b/test/api/interop_extra_test.js index f8db35b38..319ccb536 100644 --- a/test/api/interop_extra_test.js +++ b/test/api/interop_extra_test.js @@ -197,6 +197,8 @@ describe(`${anyGrpc.clientName} client -> ${anyGrpc.serverName} server`, functio }); }); describe('max message size', function() { + // with the default timeout the test times out under aarch64 emulator + this.timeout(6000); // A size that is larger than the default limit const largeMessageSize = 8 * 1024 * 1024; const largeMessage = Buffer.alloc(largeMessageSize); @@ -238,6 +240,8 @@ describe(`${anyGrpc.clientName} client -> ${anyGrpc.serverName} server`, functio }); }); describe('with a client with no message size limits', function() { + // with the default timeout the test times out under aarch64 emulator + this.timeout(6000); let unrestrictedClient; before(function() { const ca_path = path.join(__dirname, '../data/ca.pem'); @@ -283,6 +287,8 @@ describe(`${anyGrpc.clientName} client -> ${anyGrpc.serverName} server`, functio }); }); describe('with a server with message size limits and a client without limits', function() { + // with the default timeout the test times out under aarch64 emulator + this.timeout(6000); let restrictedServer; let restrictedServerClient; let restrictedServerClient2; diff --git a/test/api/interop_sanity_test.js b/test/api/interop_sanity_test.js index 995650e20..c1e5d92b5 100644 --- a/test/api/interop_sanity_test.js +++ b/test/api/interop_sanity_test.js @@ -48,7 +48,8 @@ var childExecArgv = []; describe(`${anyGrpc.clientName} client -> ${anyGrpc.serverName} server`, function() { describe('Interop tests', function() { - this.timeout(4000); + // with the default timeout the test times out under aarch64 emulator + this.timeout(10000); before(function(done) { for (let arg of process.argv) { if (arg.startsWith('--require=')) { From 43a3bad54903bf85dd44ad2bc2e985c97942fa34 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 20 May 2021 10:31:00 -0700 Subject: [PATCH 017/450] Fix circuit breaking functionality --- .../grpc-js-xds/interop/xds-interop-client.ts | 32 +++++++++++++-- packages/grpc-js-xds/src/load-balancer-cds.ts | 8 +++- packages/grpc-js-xds/src/load-balancer-eds.ts | 41 ++++++++++++------- 3 files changed, 63 insertions(+), 18 deletions(-) diff --git a/packages/grpc-js-xds/interop/xds-interop-client.ts b/packages/grpc-js-xds/interop/xds-interop-client.ts index f6beccbf0..a414ffe7f 100644 --- a/packages/grpc-js-xds/interop/xds-interop-client.ts +++ b/packages/grpc-js-xds/interop/xds-interop-client.ts @@ -196,6 +196,18 @@ const currentConfig: ClientConfiguration = { let anyCallSucceeded = false; const accumulatedStats: LoadBalancerAccumulatedStatsResponse = { + num_rpcs_started_by_method: { + EMPTY_CALL: 0, + UNARY_CALL: 0 + }, + num_rpcs_succeeded_by_method: { + EMPTY_CALL: 0, + UNARY_CALL: 0 + }, + num_rpcs_failed_by_method: { + EMPTY_CALL: 0, + UNARY_CALL: 0 + }, stats_per_method: { EMPTY_CALL: { rpcs_started: 0, @@ -208,14 +220,28 @@ const accumulatedStats: LoadBalancerAccumulatedStatsResponse = { } }; +function addAccumulatedCallStarted(callName: string) { + accumulatedStats.stats_per_method![callName].rpcs_started! += 1; + accumulatedStats.num_rpcs_started_by_method![callName] += 1; +} + +function addAccumulatedCallEnded(callName: string, result: grpc.status) { + accumulatedStats.stats_per_method![callName].result![result] = (accumulatedStats.stats_per_method![callName].result![result] ?? 0) + 1; + if (result === grpc.status.OK) { + accumulatedStats.num_rpcs_succeeded_by_method![callName] += 1; + } else { + accumulatedStats.num_rpcs_failed_by_method![callName] += 1; + } +} + const callTimeHistogram: {[callType: string]: {[status: number]: number[]}} = { UnaryCall: {}, EmptyCall: {} } function makeSingleRequest(client: TestServiceClient, type: CallType, failOnFailedRpcs: boolean, callStatsTracker: CallStatsTracker) { - const callTypeStats = accumulatedStats.stats_per_method![callTypeEnumMapReverse[type]]; - callTypeStats.rpcs_started! += 1; + const callEnumName = callTypeEnumMapReverse[type]; + addAccumulatedCallStarted(callEnumName); const notifier = callStatsTracker.startCall(); let gotMetadata: boolean = false; let hostname: string | null = null; @@ -235,7 +261,7 @@ function makeSingleRequest(client: TestServiceClient, type: CallType, failOnFail } else { callTimeHistogram[type][statusCode][duration[0]] = 1; } - callTypeStats.result![statusCode] = (callTypeStats.result![statusCode] ?? 0) + 1; + addAccumulatedCallEnded(callEnumName, statusCode); if (error) { if (failOnFailedRpcs && anyCallSucceeded) { console.error('A call failed after a call succeeded'); diff --git a/packages/grpc-js-xds/src/load-balancer-cds.ts b/packages/grpc-js-xds/src/load-balancer-cds.ts index 6c57a410f..4829edd44 100644 --- a/packages/grpc-js-xds/src/load-balancer-cds.ts +++ b/packages/grpc-js-xds/src/load-balancer-cds.ts @@ -80,11 +80,17 @@ export class CdsLoadBalancer implements LoadBalancer { this.watcher = { onValidUpdate: (update) => { this.latestCdsUpdate = update; + let maxConcurrentRequests: number | undefined = undefined; + for (const threshold of update.circuit_breakers?.thresholds ?? []) { + if (threshold.priority === 'DEFAULT') { + maxConcurrentRequests = threshold.max_requests?.value; + } + } /* the lrs_server.self field indicates that the same server should be * used for load reporting as for other xDS operations. Setting * lrsLoadReportingServerName to the empty string sets that behavior. * Otherwise, if the field is omitted, load reporting is disabled. */ - const edsConfig: EdsLoadBalancingConfig = new EdsLoadBalancingConfig(update.name, [], [], update.eds_cluster_config!.service_name === '' ? undefined : update.eds_cluster_config!.service_name, update.lrs_server?.self ? '' : undefined); + const edsConfig: EdsLoadBalancingConfig = new EdsLoadBalancingConfig(update.name, [], [], update.eds_cluster_config!.service_name === '' ? undefined : update.eds_cluster_config!.service_name, update.lrs_server?.self ? '' : undefined, maxConcurrentRequests); trace('Child update EDS config: ' + JSON.stringify(edsConfig)); this.childBalancer.updateAddressList( [], diff --git a/packages/grpc-js-xds/src/load-balancer-eds.ts b/packages/grpc-js-xds/src/load-balancer-eds.ts index 76bdd6655..183e0d670 100644 --- a/packages/grpc-js-xds/src/load-balancer-eds.ts +++ b/packages/grpc-js-xds/src/load-balancer-eds.ts @@ -37,6 +37,7 @@ import { Watcher } from './xds-stream-state/xds-stream-state'; import Filter = experimental.Filter; import BaseFilter = experimental.BaseFilter; import FilterFactory = experimental.FilterFactory; +import FilterStackFactory = experimental.FilterStackFactory; import CallStream = experimental.CallStream; const TRACER_NAME = 'eds_balancer'; @@ -204,27 +205,42 @@ export class EdsLoadBalancer implements LoadBalancer { * Otherwise, delegate picking the subchannel to the child * balancer. */ if (dropCategory === null) { - return originalPicker.pick(pickArgs); + const originalPick = originalPicker.pick(pickArgs); + let extraFilterFactory: FilterFactory = new CallTrackingFilterFactory(() => { + this.concurrentRequests -= 1; + }); + if (originalPick.extraFilterFactory) { + extraFilterFactory = new FilterStackFactory([originalPick.extraFilterFactory, extraFilterFactory]); + } + return { + pickResultType: originalPick.pickResultType, + status: originalPick.status, + subchannel: originalPick.subchannel, + onCallStarted: () => { + originalPick.onCallStarted?.(); + this.concurrentRequests += 1; + }, + extraFilterFactory: extraFilterFactory + }; } else { + let details: string; if (dropCategory === true) { + details = 'Call dropped by load balancing policy.'; this.clusterDropStats?.addUncategorizedCallDropped(); } else { + details = `Call dropped by load balancing policy. Category: ${dropCategory}`; this.clusterDropStats?.addCallDropped(dropCategory); } return { pickResultType: PickResultType.DROP, status: { code: Status.UNAVAILABLE, - details: `Call dropped by load balancing policy. Category: ${dropCategory}`, + details: details, metadata: new Metadata(), }, subchannel: null, - extraFilterFactory: new CallTrackingFilterFactory(() => { - this.concurrentRequests -= 1; - }), - onCallStarted: () => { - this.concurrentRequests += 1; - }, + extraFilterFactory: null, + onCallStarted: null }; } }, @@ -265,15 +281,12 @@ export class EdsLoadBalancer implements LoadBalancer { * output, as a sentinel value indicating a drop with no category. */ private checkForDrop(): string | true | null { - if (!this.latestEdsUpdate?.policy) { - return null; + if (this.lastestConfig && this.concurrentRequests >= this.lastestConfig.getMaxConcurrentRequests()) { + return true; } - if (!this.lastestConfig) { + if (!this.latestEdsUpdate?.policy) { return null; } - if (this.concurrentRequests >= this.lastestConfig.getMaxConcurrentRequests()) { - return true; - } /* The drop_overloads policy is a list of pairs of category names and * probabilities. For each one, if the random number is within that * probability range, we drop the call citing that category. Otherwise, the From 8bc20b28fd1191902dac745665f3dc661ddded54 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 2 Jun 2021 16:02:42 +0200 Subject: [PATCH 018/450] increase timeout for make emulated aarch64 tests green --- test/api/interop_extra_test.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/api/interop_extra_test.js b/test/api/interop_extra_test.js index 319ccb536..fa7e03276 100644 --- a/test/api/interop_extra_test.js +++ b/test/api/interop_extra_test.js @@ -147,7 +147,8 @@ describe(`${anyGrpc.clientName} client -> ${anyGrpc.serverName} server`, functio }); }); it('should receive all messages in a long stream', function(done) { - this.timeout(20000); + // the test is slow under aarch64 emulator + this.timeout(80000); var arg = { response_type: 'COMPRESSABLE', response_parameters: [ From f01b6d9fcad9fcd199dc13ddbea220fd0917faf9 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 2 Jun 2021 13:42:41 -0700 Subject: [PATCH 019/450] grpc-js: Export ServerErrorResponse type, which is used in public APIs --- packages/grpc-js/src/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index 308074640..05a82e94d 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -62,6 +62,7 @@ import { ServerReadableStream, ServerWritableStream, ServerDuplexStream, + ServerErrorResponse, } from './server-call'; export { OAuth2Client }; @@ -173,6 +174,7 @@ export { ServerReadableStream, ServerWritableStream, ServerDuplexStream, + ServerErrorResponse, ServiceDefinition, UntypedHandleCall, UntypedServiceImplementation, From 8a38cd8549dd804b2bf070e3ec4620c446d411e8 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 10 Jun 2021 14:48:33 -0700 Subject: [PATCH 020/450] grpc-js: Refactor FilterStack usage --- packages/grpc-js-xds/src/load-balancer-eds.ts | 10 +++------- packages/grpc-js-xds/src/load-balancer-lrs.ts | 11 +---------- .../src/load-balancer-xds-cluster-manager.ts | 2 +- packages/grpc-js/src/call-stream.ts | 11 +++-------- packages/grpc-js/src/channel.ts | 2 +- packages/grpc-js/src/filter-stack.ts | 8 ++++++++ packages/grpc-js/src/load-balancer-pick-first.ts | 2 +- packages/grpc-js/src/load-balancer-round-robin.ts | 2 +- packages/grpc-js/src/picker.ts | 14 +++++++------- packages/grpc-js/src/subchannel.ts | 4 ++-- 10 files changed, 28 insertions(+), 38 deletions(-) diff --git a/packages/grpc-js-xds/src/load-balancer-eds.ts b/packages/grpc-js-xds/src/load-balancer-eds.ts index 183e0d670..efb05eb78 100644 --- a/packages/grpc-js-xds/src/load-balancer-eds.ts +++ b/packages/grpc-js-xds/src/load-balancer-eds.ts @@ -37,7 +37,6 @@ import { Watcher } from './xds-stream-state/xds-stream-state'; import Filter = experimental.Filter; import BaseFilter = experimental.BaseFilter; import FilterFactory = experimental.FilterFactory; -import FilterStackFactory = experimental.FilterStackFactory; import CallStream = experimental.CallStream; const TRACER_NAME = 'eds_balancer'; @@ -206,12 +205,9 @@ export class EdsLoadBalancer implements LoadBalancer { * balancer. */ if (dropCategory === null) { const originalPick = originalPicker.pick(pickArgs); - let extraFilterFactory: FilterFactory = new CallTrackingFilterFactory(() => { + const trackingFilterFactory: FilterFactory = new CallTrackingFilterFactory(() => { this.concurrentRequests -= 1; }); - if (originalPick.extraFilterFactory) { - extraFilterFactory = new FilterStackFactory([originalPick.extraFilterFactory, extraFilterFactory]); - } return { pickResultType: originalPick.pickResultType, status: originalPick.status, @@ -220,7 +216,7 @@ export class EdsLoadBalancer implements LoadBalancer { originalPick.onCallStarted?.(); this.concurrentRequests += 1; }, - extraFilterFactory: extraFilterFactory + extraFilterFactories: originalPick.extraFilterFactories.concat(trackingFilterFactory) }; } else { let details: string; @@ -239,7 +235,7 @@ export class EdsLoadBalancer implements LoadBalancer { metadata: new Metadata(), }, subchannel: null, - extraFilterFactory: null, + extraFilterFactories: [], onCallStarted: null }; } diff --git a/packages/grpc-js-xds/src/load-balancer-lrs.ts b/packages/grpc-js-xds/src/load-balancer-lrs.ts index 0792b11c2..566aa04c5 100644 --- a/packages/grpc-js-xds/src/load-balancer-lrs.ts +++ b/packages/grpc-js-xds/src/load-balancer-lrs.ts @@ -32,7 +32,6 @@ import PickResult = experimental.PickResult; import Filter = experimental.Filter; import BaseFilter = experimental.BaseFilter; import FilterFactory = experimental.FilterFactory; -import FilterStackFactory = experimental.FilterStackFactory; import Call = experimental.CallStream; import validateLoadBalancingConfig = experimental.validateLoadBalancingConfig @@ -148,14 +147,6 @@ class LoadReportingPicker implements Picker { const trackingFilterFactory = new CallEndTrackingFilterFactory( this.localityStatsReporter ); - /* In the unlikely event that the wrappedPick already has an - * extraFilterFactory, preserve it in a FilterStackFactory. */ - const extraFilterFactory = wrappedPick.extraFilterFactory - ? new FilterStackFactory([ - wrappedPick.extraFilterFactory, - trackingFilterFactory, - ]) - : trackingFilterFactory; return { pickResultType: PickResultType.COMPLETE, subchannel: wrappedPick.subchannel, @@ -164,7 +155,7 @@ class LoadReportingPicker implements Picker { wrappedPick.onCallStarted?.(); this.localityStatsReporter.addCallStarted(); }, - extraFilterFactory: extraFilterFactory, + extraFilterFactories: wrappedPick.extraFilterFactories.concat(trackingFilterFactory), }; } else { return wrappedPick; diff --git a/packages/grpc-js-xds/src/load-balancer-xds-cluster-manager.ts b/packages/grpc-js-xds/src/load-balancer-xds-cluster-manager.ts index 920a43db9..7df79e26b 100644 --- a/packages/grpc-js-xds/src/load-balancer-xds-cluster-manager.ts +++ b/packages/grpc-js-xds/src/load-balancer-xds-cluster-manager.ts @@ -107,7 +107,7 @@ class XdsClusterManagerPicker implements Picker { metadata: new Metadata(), }, subchannel: null, - extraFilterFactory: null, + extraFilterFactories: [], onCallStarted: null }; } diff --git a/packages/grpc-js/src/call-stream.ts b/packages/grpc-js/src/call-stream.ts index 3a81cbe94..ae6342604 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -210,7 +210,7 @@ export interface Call { export class Http2CallStream implements Call { credentials: CallCredentials; - filterStack: Filter; + filterStack: FilterStack; private http2Stream: http2.ClientHttp2Stream | null = null; private pendingRead = false; private isWriteFilterPending = false; @@ -462,14 +462,9 @@ export class Http2CallStream implements Call { attachHttp2Stream( stream: http2.ClientHttp2Stream, subchannel: Subchannel, - extraFilterFactory?: FilterFactory + extraFilters: FilterFactory[] ): void { - if (extraFilterFactory !== undefined) { - this.filterStack = new FilterStack([ - this.filterStack, - extraFilterFactory.createFilter(this), - ]); - } + this.filterStack.push(extraFilters.map(filterFactory => filterFactory.createFilter(this))); if (this.finalStatus !== null) { stream.close(NGHTTP2_CANCEL); } else { diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 8b2658f37..cd2fc94a2 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -373,7 +373,7 @@ export class ChannelImplementation implements Channel { pickResult.subchannel!.startCallStream( finalMetadata, callStream, - pickResult.extraFilterFactory ?? undefined + pickResult.extraFilterFactories ); /* If we reach this point, the call stream has started * successfully */ diff --git a/packages/grpc-js/src/filter-stack.ts b/packages/grpc-js/src/filter-stack.ts index 4fd888549..4e0ccf07f 100644 --- a/packages/grpc-js/src/filter-stack.ts +++ b/packages/grpc-js/src/filter-stack.ts @@ -77,11 +77,19 @@ export class FilterStack implements Filter { filter.refresh(); } } + + push(filters: Filter[]) { + this.filters.unshift(...filters); + } } export class FilterStackFactory implements FilterFactory { constructor(private readonly factories: Array>) {} + push(filterFactories: FilterFactory[]) { + this.factories.unshift(...filterFactories); + } + createFilter(callStream: Call): FilterStack { return new FilterStack( this.factories.map((factory) => factory.createFilter(callStream)) diff --git a/packages/grpc-js/src/load-balancer-pick-first.ts b/packages/grpc-js/src/load-balancer-pick-first.ts index 31dc17847..688f95562 100644 --- a/packages/grpc-js/src/load-balancer-pick-first.ts +++ b/packages/grpc-js/src/load-balancer-pick-first.ts @@ -83,7 +83,7 @@ class PickFirstPicker implements Picker { pickResultType: PickResultType.COMPLETE, subchannel: this.subchannel, status: null, - extraFilterFactory: null, + extraFilterFactories: [], onCallStarted: null, }; } diff --git a/packages/grpc-js/src/load-balancer-round-robin.ts b/packages/grpc-js/src/load-balancer-round-robin.ts index daba45941..2159e64c7 100644 --- a/packages/grpc-js/src/load-balancer-round-robin.ts +++ b/packages/grpc-js/src/load-balancer-round-robin.ts @@ -78,7 +78,7 @@ class RoundRobinPicker implements Picker { pickResultType: PickResultType.COMPLETE, subchannel: pickedSubchannel, status: null, - extraFilterFactory: null, + extraFilterFactories: [], onCallStarted: null, }; } diff --git a/packages/grpc-js/src/picker.ts b/packages/grpc-js/src/picker.ts index 6df61b59a..25929884b 100644 --- a/packages/grpc-js/src/picker.ts +++ b/packages/grpc-js/src/picker.ts @@ -47,7 +47,7 @@ export interface PickResult { * provided by the load balancer to be used with the call. For technical * reasons filters from this factory will not see sendMetadata events. */ - extraFilterFactory: FilterFactory | null; + extraFilterFactories: FilterFactory[]; onCallStarted: (() => void) | null; } @@ -55,7 +55,7 @@ export interface CompletePickResult extends PickResult { pickResultType: PickResultType.COMPLETE; subchannel: Subchannel | null; status: null; - extraFilterFactory: FilterFactory | null; + extraFilterFactories: FilterFactory[]; onCallStarted: (() => void) | null; } @@ -63,7 +63,7 @@ export interface QueuePickResult extends PickResult { pickResultType: PickResultType.QUEUE; subchannel: null; status: null; - extraFilterFactory: null; + extraFilterFactories: []; onCallStarted: null; } @@ -71,7 +71,7 @@ export interface TransientFailurePickResult extends PickResult { pickResultType: PickResultType.TRANSIENT_FAILURE; subchannel: null; status: StatusObject; - extraFilterFactory: null; + extraFilterFactories: []; onCallStarted: null; } @@ -79,7 +79,7 @@ export interface DropCallPickResult extends PickResult { pickResultType: PickResultType.DROP; subchannel: null; status: StatusObject; - extraFilterFactory: null; + extraFilterFactories: []; onCallStarted: null; } @@ -119,7 +119,7 @@ export class UnavailablePicker implements Picker { pickResultType: PickResultType.TRANSIENT_FAILURE, subchannel: null, status: this.status, - extraFilterFactory: null, + extraFilterFactories: [], onCallStarted: null, }; } @@ -148,7 +148,7 @@ export class QueuePicker { pickResultType: PickResultType.QUEUE, subchannel: null, status: null, - extraFilterFactory: null, + extraFilterFactories: [], onCallStarted: null, }; } diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 772bdb228..c50a68e77 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -688,7 +688,7 @@ export class Subchannel { startCallStream( metadata: Metadata, callStream: Http2CallStream, - extraFilterFactory?: FilterFactory + extraFilterFactories: FilterFactory[] ) { const headers = metadata.toHttp2Headers(); headers[HTTP2_HEADER_AUTHORITY] = callStream.getHost(); @@ -720,7 +720,7 @@ export class Subchannel { headersString += '\t\t' + header + ': ' + headers[header] + '\n'; } logging.trace(LogVerbosity.DEBUG, 'call_stream', 'Starting stream on subchannel ' + this.subchannelAddressString + ' with headers\n' + headersString); - callStream.attachHttp2Stream(http2Stream, this, extraFilterFactory); + callStream.attachHttp2Stream(http2Stream, this, extraFilterFactories); } /** From acfb3c28298742a105e653c5235501a80879c459 Mon Sep 17 00:00:00 2001 From: David Goitia Date: Thu, 17 Jun 2021 14:35:29 +0200 Subject: [PATCH 021/450] Update node-pre-gyp dependency --- packages/grpc-tools/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-tools/package.json b/packages/grpc-tools/package.json index b1f83ce45..25ba1da73 100644 --- a/packages/grpc-tools/package.json +++ b/packages/grpc-tools/package.json @@ -24,7 +24,7 @@ "prepublishOnly": "git submodule update --init --recursive && node copy_well_known_protos.js" }, "dependencies": { - "node-pre-gyp": "^0.15.0" + "@mapbox/node-pre-gyp": "^1.0.5" }, "binary": { "module_name": "grpc_tools", From 948fc6c1223c6de9d159c9ef24fce4b94c09ff12 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 17 Jun 2021 09:49:42 -0700 Subject: [PATCH 022/450] Don't install docker in the docker image --- tools/release/native/Dockerfile | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/release/native/Dockerfile b/tools/release/native/Dockerfile index bc03bf178..d065bddbe 100644 --- a/tools/release/native/Dockerfile +++ b/tools/release/native/Dockerfile @@ -6,7 +6,6 @@ RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt RUN apt-get update RUN apt-get -t jessie-backports install -y cmake RUN apt-get install -y curl build-essential python libc6-dev-i386 lib32stdc++-4.9-dev jq -RUN curl -fsSL get.docker.com | bash RUN mkdir /usr/local/nvm ENV NVM_DIR /usr/local/nvm From cb505b455646e2a9ba0e853ca1b61d161fe638e6 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 17 Jun 2021 11:12:35 -0700 Subject: [PATCH 023/450] grpc-tools: Bump to version 1.11.2 --- packages/grpc-tools/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-tools/package.json b/packages/grpc-tools/package.json index 25ba1da73..95faa84c4 100644 --- a/packages/grpc-tools/package.json +++ b/packages/grpc-tools/package.json @@ -1,6 +1,6 @@ { "name": "grpc-tools", - "version": "1.11.1", + "version": "1.11.2", "author": "Google Inc.", "description": "Tools for developing with gRPC on Node.js", "homepage": "https://grpc.io/", From 237ea8308a0298aeded01de83a225eda092e9cf4 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 18 Jun 2021 14:37:03 -0700 Subject: [PATCH 024/450] grpc-js: Make logging behavior more similar to core --- packages/grpc-js/src/constants.ts | 1 + packages/grpc-js/src/logging.ts | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/grpc-js/src/constants.ts b/packages/grpc-js/src/constants.ts index d30b78f08..94763cfe1 100644 --- a/packages/grpc-js/src/constants.ts +++ b/packages/grpc-js/src/constants.ts @@ -39,6 +39,7 @@ export enum LogVerbosity { DEBUG = 0, INFO, ERROR, + NONE, } /** diff --git a/packages/grpc-js/src/logging.ts b/packages/grpc-js/src/logging.ts index 1140e8d8a..de8d2d056 100644 --- a/packages/grpc-js/src/logging.ts +++ b/packages/grpc-js/src/logging.ts @@ -32,6 +32,9 @@ switch (verbosityString) { case 'ERROR': _logVerbosity = LogVerbosity.ERROR; break; + case 'NONE': + _logVerbosity = LogVerbosity.NONE; + break; default: // Ignore any other values } @@ -56,15 +59,23 @@ export const log = (severity: LogVerbosity, ...args: any[]): void => { }; const tracersString = process.env.GRPC_NODE_TRACE ?? process.env.GRPC_TRACE ?? ''; -const enabledTracers = tracersString.split(','); -const allEnabled = enabledTracers.includes('all'); +const enabledTracers = new Set(); +const disabledTracers = new Set(); +for (const tracerName of tracersString.split(',')) { + if (tracerName.startsWith('-')) { + disabledTracers.add(tracerName.substring(1)); + } else { + enabledTracers.add(tracerName) + } +} +const allEnabled = enabledTracers.has('all'); export function trace( severity: LogVerbosity, tracer: string, text: string ): void { - if (allEnabled || enabledTracers.includes(tracer)) { + if (!disabledTracers.has(tracer) && (allEnabled || enabledTracers.has(tracer))) { log(severity, new Date().toISOString() + ' | ' + tracer + ' | ' + text); } } From a214aca7686bb8ba0a104885c4e6ed869932e38f Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 18 Jun 2021 14:37:26 -0700 Subject: [PATCH 025/450] Document environment variables, particularly for logging --- TROUBLESHOOTING.md | 38 +++++++++++++++++++++++ doc/environment_variables.md | 58 ++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 TROUBLESHOOTING.md create mode 100644 doc/environment_variables.md diff --git a/TROUBLESHOOTING.md b/TROUBLESHOOTING.md new file mode 100644 index 000000000..dd5bce7af --- /dev/null +++ b/TROUBLESHOOTING.md @@ -0,0 +1,38 @@ +# Troubleshooting grpc-js + +This guide is for troubleshooting the `grpc-js` library for Node.js + +## Enabling extra logging and tracing + +Extra logging can be very useful for diagnosing problems. `grpc-js` supporst +the `GRPC_VERBOSITY` and `GRPC_TRACE` environment variables that can be used to increase the amount of information +that gets printed to stderr. + +## GRPC_VERBOSITY + +`GRPC_VERBOSITY` is used to set the minimum level of log messages printed by gRPC (supported values are `DEBUG`, `INFO` and `ERROR`). If this environment variable is unset, only `ERROR` logs will be printed. + +## GRPC_TRACE + +`GRPC_TRACE` can be used to enable extra logging for some internal gRPC components. Enabling the right traces can be invaluable +for diagnosing for what is going wrong when things aren't working as intended. Possible values for `GRPC_TRACE` are listed in [Environment Variables Overview](doc/environment_variables.md). +Multiple traces can be enabled at once (use comma as separator). + +``` +# Enable debug logs for an application +GRPC_VERBOSITY=debug ./helloworld_application_using_grpc +``` + +``` +# Print information about channel state changes +GRPC_VERBOSITY=debug GRPC_TRACE=connectivity_state ./helloworld_application_using_grpc +``` + +``` +# Print info from 3 different tracers, including tracing logs with log level DEBUG +GRPC_VERBOSITY=debug GRPC_TRACE=channel,subchannel,call_stream ./helloworld_application_using_grpc +``` + +Please note that the `GRPC_TRACE` environment variable has nothing to do with gRPC's "tracing" feature (= tracing RPCs in +microservice environment to gain insight about how requests are processed by deployment), it is merely used to enable printing +of extra logs. diff --git a/doc/environment_variables.md b/doc/environment_variables.md new file mode 100644 index 000000000..f2a32294c --- /dev/null +++ b/doc/environment_variables.md @@ -0,0 +1,58 @@ +# grpc-js environment variables + +`@grpc/grpc-js` exposes some configuration as environment variables that +can be set. + +*For the legacy `grpc` library, the environment variables are documented +[in the main gRPC repository](https://github.com/grpc/grpc/blob/master/doc/environment_variables.md)* + +* grpc_proxy, https_proxy, http_proxy + The URI of the proxy to use for HTTP CONNECT support. These variables are + checked in order, and the first one that has a value is used. + +* no_grpc_proxy, no_proxy + A comma separated list of hostnames to connect to without using a proxy even + if a proxy is set. These variables are checked in order, and the first one + that has a value is used. + +* GRPC_SSL_CIPHER_SUITES + A colon separated list of cipher suites to use with OpenSSL + Defaults to the defaults for Node.js + +* GRPC_DEFAULT_SSL_ROOTS_FILE_PATH + PEM file to load SSL roots from + +* GRPC_NODE_TRACE, GRPC_TRACE + A comma separated list of tracers that provide additional insight into how + grpc-js is processing requests via debug logs. Available tracers include: + - `call_stream` - Traces client request internals + - `channel` - Traces channel events + - `connectivity_state` - Traces channel connectivity state changes + - `dns_resolver` - Traces DNS resolution + - `pick_first` - Traces the pick first load balancing policy + - `proxy` - Traces proxy operations + - `resolving_load_balancer` - Traces the resolving load balancer + - `round_robin` - Traces the round robin load balancing policy + - `server` - Traces high-level server events + - `server_call` - Traces server handling of individual requests + - `subchannel` - Traces subchannel connectivity state and errors + - `subchannel_refcount` - Traces subchannel refcount changes + + The following tracers are added by the `@grpc/grpc-js-xds` library: + - `cds_balancer` - Traces the CDS load balancing policy + - `eds_balancer` - Traces the EDS load balancing policy + - `priority` - Traces the priority load balancing policy + - `weighted_target` - Traces the weighted target load balancing policy + - `xds_client` - Traces the xDS Client + - `xds_cluster_manager` - Traces the xDS cluster manager load balancing policy + - `xds_resolver` - Traces the xDS name resolver + + 'all' can additionally be used to turn all traces on. + Individual traces can be disabled by prefixing them with '-'. + +* GRPC_NODE_VERBOSITY, GRPC_VERBOSITY + Default gRPC logging verbosity - one of: + - DEBUG - log all gRPC messages + - INFO - log INFO and ERROR message + - ERROR - log only errors (default) + - NONE - won't log any \ No newline at end of file From f289c343b3393aad73795c0657415f4160bcdcb5 Mon Sep 17 00:00:00 2001 From: Mike Lewis Date: Wed, 23 Jun 2021 16:42:39 +0100 Subject: [PATCH 026/450] Avoid unused definition imports from proto-loader Since proto files don't always contain all types of definition, it was possible to get into a state where generated code contained unused imports which caused TS errors. This change makes those imports conditional on the existence of the corresponding definitions in the proto file. Co-authored-by: Austin Puri Co-authored-by: Joe Porpeglia Signed-off-by: Mike Lewis --- .../bin/proto-loader-gen-types.ts | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index 82a13a123..fedaadc38 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -579,6 +579,34 @@ function generateServiceInterfaces(formatter: TextFormatter, serviceType: Protob generateServiceDefinitionInterface(formatter, serviceType); } +function containsDefinition(definitionType: typeof Protobuf.Type | typeof Protobuf.Enum, namespace: Protobuf.NamespaceBase): boolean { + for (const nested of namespace.nestedArray.sort(compareName)) { + if (nested instanceof definitionType) { + return true; + } else if (isNamespaceBase(nested) && !(nested instanceof Protobuf.Type) && !(nested instanceof Protobuf.Enum)) { + return containsDefinition(definitionType, nested); + } + } + + return false; +} + +function generateDefinitionImports(formatter: TextFormatter, namespace: Protobuf.NamespaceBase, options: GeneratorOptions) { + const imports = []; + + if (containsDefinition(Protobuf.Enum, namespace)) { + imports.push('EnumTypeDefinition'); + } + + if (containsDefinition(Protobuf.Type, namespace)) { + imports.push('MessageTypeDefinition'); + } + + if (imports.length) { + formatter.writeLine(`import type { ${imports.join(', ')} } from '@grpc/proto-loader';`); + } +} + function generateServiceImports(formatter: TextFormatter, namespace: Protobuf.NamespaceBase, options: GeneratorOptions) { for (const nested of namespace.nestedArray.sort(compareName)) { if (nested instanceof Protobuf.Service) { @@ -617,7 +645,7 @@ function generateLoadedDefinitionTypes(formatter: TextFormatter, namespace: Prot function generateRootFile(formatter: TextFormatter, root: Protobuf.Root, options: GeneratorOptions) { formatter.writeLine(`import type * as grpc from '${options.grpcLib}';`); - formatter.writeLine("import type { ServiceDefinition, EnumTypeDefinition, MessageTypeDefinition } from '@grpc/proto-loader';"); + generateDefinitionImports(formatter, root, options); formatter.writeLine(''); generateServiceImports(formatter, root, options); From 61e64a3c4f684e1671fd27b9e47ca9755e042f22 Mon Sep 17 00:00:00 2001 From: Mike Lewis Date: Wed, 23 Jun 2021 17:55:38 +0100 Subject: [PATCH 027/450] Update golden-generated in proto-loader Signed-off-by: Mike Lewis --- packages/proto-loader/golden-generated/echo.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/proto-loader/golden-generated/echo.ts b/packages/proto-loader/golden-generated/echo.ts index f257a40e4..600e2864c 100644 --- a/packages/proto-loader/golden-generated/echo.ts +++ b/packages/proto-loader/golden-generated/echo.ts @@ -1,5 +1,5 @@ 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 { OperationsClient as _google_longrunning_OperationsClient, OperationsDefinition as _google_longrunning_OperationsDefinition } from './google/longrunning/Operations'; import type { EchoClient as _google_showcase_v1beta1_EchoClient, EchoDefinition as _google_showcase_v1beta1_EchoDefinition } from './google/showcase/v1beta1/Echo'; From 12b2412356e287700c5e38e0cb0d120a820f2c19 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 23 Jun 2021 12:46:53 -0700 Subject: [PATCH 028/450] proto-loader: Bump to version 0.6.3 --- packages/proto-loader/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index 0d9ff4437..cbda6680d 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/proto-loader", - "version": "0.6.2", + "version": "0.6.3", "author": "Google Inc.", "contributors": [ { From 031ae9472e7ce0592dd34f344a50c6cded861203 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 24 Jun 2021 09:40:30 -0700 Subject: [PATCH 029/450] grpc-js: Refactor code to eliminate runtime dependency cycles --- packages/grpc-js/package.json | 3 +- packages/grpc-js/src/channel.ts | 11 +--- packages/grpc-js/src/client.ts | 3 +- packages/grpc-js/src/connectivity-state.ts | 24 +++++++ packages/grpc-js/src/experimental.ts | 2 +- packages/grpc-js/src/http_proxy.ts | 4 +- packages/grpc-js/src/index.ts | 15 +++-- .../src/load-balancer-child-handler.ts | 9 +-- .../grpc-js/src/load-balancer-pick-first.ts | 14 +++-- .../grpc-js/src/load-balancer-round-robin.ts | 12 ++-- packages/grpc-js/src/load-balancer.ts | 36 ++++++----- packages/grpc-js/src/resolver-dns.ts | 2 +- packages/grpc-js/src/resolver-uds.ts | 2 +- packages/grpc-js/src/resolver.ts | 9 +-- .../grpc-js/src/resolving-load-balancer.ts | 8 +-- packages/grpc-js/src/server.ts | 4 +- packages/grpc-js/src/subchannel-address.ts | 62 +++++++++++++++++++ packages/grpc-js/src/subchannel-pool.ts | 6 +- packages/grpc-js/src/subchannel.ts | 49 +-------------- packages/grpc-js/test/test-client.ts | 2 +- packages/grpc-js/test/test-resolver.ts | 7 ++- 21 files changed, 167 insertions(+), 117 deletions(-) create mode 100644 packages/grpc-js/src/connectivity-state.ts create mode 100644 packages/grpc-js/src/subchannel-address.ts diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 6a027d391..3733e06fc 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -29,6 +29,7 @@ "gulp": "^4.0.2", "gulp-mocha": "^6.0.0", "lodash": "^4.17.4", + "madge": "^5.0.1", "mocha-jenkins-reporter": "^0.4.1", "ncp": "^2.0.0", "pify": "^4.0.1", @@ -53,7 +54,7 @@ "check": "gts check src/**/*.ts", "fix": "gts fix src/*.ts", "pretest": "npm run compile", - "posttest": "npm run check" + "posttest": "npm run check && madge -c ./build/src" }, "dependencies": { "@types/node": ">=12.12.47" diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index cd2fc94a2..58726ccc7 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -35,20 +35,13 @@ import { DeadlineFilterFactory } from './deadline-filter'; import { CompressionFilterFactory } from './compression-filter'; import { CallConfig, ConfigSelector, getDefaultAuthority, mapUriDefaultScheme } from './resolver'; import { trace, log } from './logging'; -import { SubchannelAddress } from './subchannel'; +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'; import { SurfaceCall } from './call'; - -export enum ConnectivityState { - IDLE, - CONNECTING, - READY, - TRANSIENT_FAILURE, - SHUTDOWN, -} +import { ConnectivityState } from './connectivity-state'; /** * See https://nodejs.org/api/timers.html#timers_setinterval_callback_delay_args diff --git a/packages/grpc-js/src/client.ts b/packages/grpc-js/src/client.ts index 5f78ffe59..7a2199b02 100644 --- a/packages/grpc-js/src/client.ts +++ b/packages/grpc-js/src/client.ts @@ -30,7 +30,8 @@ import { } from './call'; import { CallCredentials } from './call-credentials'; import { Deadline, StatusObject } from './call-stream'; -import { Channel, ConnectivityState, ChannelImplementation } from './channel'; +import { Channel, ChannelImplementation } from './channel'; +import { ConnectivityState } from "./connectivity-state"; import { ChannelCredentials } from './channel-credentials'; import { ChannelOptions } from './channel-options'; import { Status } from './constants'; diff --git a/packages/grpc-js/src/connectivity-state.ts b/packages/grpc-js/src/connectivity-state.ts new file mode 100644 index 000000000..8e1812274 --- /dev/null +++ b/packages/grpc-js/src/connectivity-state.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2021 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. + * + */ + +export enum ConnectivityState { + IDLE, + CONNECTING, + READY, + TRANSIENT_FAILURE, + SHUTDOWN +} diff --git a/packages/grpc-js/src/experimental.ts b/packages/grpc-js/src/experimental.ts index cf84ba6b8..438ca71a8 100644 --- a/packages/grpc-js/src/experimental.ts +++ b/packages/grpc-js/src/experimental.ts @@ -4,7 +4,7 @@ export { GrpcUri, uriToString } from './uri-parser'; export { ServiceConfig, Duration } from './service-config'; export { BackoffTimeout } from './backoff-timeout'; export { LoadBalancer, LoadBalancingConfig, ChannelControlHelper, registerLoadBalancerType, getFirstUsableConfig, validateLoadBalancingConfig } from './load-balancer'; -export { SubchannelAddress, subchannelAddressToString } from './subchannel'; +export { SubchannelAddress, subchannelAddressToString } from './subchannel-address'; export { ChildLoadBalancerHandler } from './load-balancer-child-handler'; export { Picker, UnavailablePicker, QueuePicker, PickResult, PickArgs, PickResultType } from './picker'; export { Call as CallStream } from './call-stream'; diff --git a/packages/grpc-js/src/http_proxy.ts b/packages/grpc-js/src/http_proxy.ts index f6921378b..d62be597c 100644 --- a/packages/grpc-js/src/http_proxy.ts +++ b/packages/grpc-js/src/http_proxy.ts @@ -25,8 +25,8 @@ import * as logging from './logging'; import { SubchannelAddress, isTcpSubchannelAddress, - subchannelAddressToString, -} from './subchannel'; + subchannelAddressToString +} from "./subchannel-address"; import { ChannelOptions } from './channel-options'; import { GrpcUri, parseUri, splitHostPort, uriToString } from './uri-parser'; import { URL } from 'url'; diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index 05a82e94d..d0eb2a37c 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -24,7 +24,8 @@ import { } from './call'; import { CallCredentials, OAuth2Client } from './call-credentials'; import { Deadline, StatusObject } from './call-stream'; -import { Channel, ConnectivityState, ChannelImplementation } from './channel'; +import { Channel, ChannelImplementation } from './channel'; +import { ConnectivityState } from "./connectivity-state"; import { ChannelCredentials } from './channel-credentials'; import { CallOptions, @@ -246,10 +247,14 @@ export { ChannelOptions } from './channel-options'; import * as experimental from './experimental'; export { experimental }; -import * as resolver from './resolver'; -import * as load_balancer from './load-balancer'; +import * as resolver_dns from './resolver-dns'; +import * as resolver_uds from './resolver-uds'; +import * as load_balancer_pick_first from './load-balancer-pick-first'; +import * as load_balancer_round_robin from './load-balancer-round-robin'; (() => { - resolver.registerAll(); - load_balancer.registerAll(); + resolver_dns.setup(); + resolver_uds.setup(); + load_balancer_pick_first.setup(); + load_balancer_round_robin.setup(); })(); diff --git a/packages/grpc-js/src/load-balancer-child-handler.ts b/packages/grpc-js/src/load-balancer-child-handler.ts index 337174c0d..25cba4528 100644 --- a/packages/grpc-js/src/load-balancer-child-handler.ts +++ b/packages/grpc-js/src/load-balancer-child-handler.ts @@ -18,12 +18,13 @@ import { LoadBalancer, ChannelControlHelper, - createLoadBalancer, - LoadBalancingConfig + LoadBalancingConfig, + createLoadBalancer } from './load-balancer'; -import { SubchannelAddress, Subchannel } from './subchannel'; +import { Subchannel } from './subchannel'; +import { SubchannelAddress } from "./subchannel-address"; import { ChannelOptions } from './channel-options'; -import { ConnectivityState } from './channel'; +import { ConnectivityState } from "./connectivity-state"; import { Picker } from './picker'; const TYPE_NAME = 'child_load_balancer_helper'; diff --git a/packages/grpc-js/src/load-balancer-pick-first.ts b/packages/grpc-js/src/load-balancer-pick-first.ts index 688f95562..f7e9dd917 100644 --- a/packages/grpc-js/src/load-balancer-pick-first.ts +++ b/packages/grpc-js/src/load-balancer-pick-first.ts @@ -18,10 +18,11 @@ import { LoadBalancer, ChannelControlHelper, - registerLoadBalancerType, - LoadBalancingConfig + LoadBalancingConfig, + registerDefaultLoadBalancerType, + registerLoadBalancerType } from './load-balancer'; -import { ConnectivityState } from './channel'; +import { ConnectivityState } from "./connectivity-state"; import { QueuePicker, Picker, @@ -33,9 +34,11 @@ import { import { Subchannel, ConnectivityStateListener, - SubchannelAddress, - subchannelAddressToString, } from './subchannel'; +import { + SubchannelAddress, + subchannelAddressToString +} from "./subchannel-address"; import * as logging from './logging'; import { LogVerbosity } from './constants'; @@ -458,4 +461,5 @@ export class PickFirstLoadBalancer implements LoadBalancer { export function setup(): void { registerLoadBalancerType(TYPE_NAME, PickFirstLoadBalancer, PickFirstLoadBalancingConfig); + registerDefaultLoadBalancerType(TYPE_NAME); } diff --git a/packages/grpc-js/src/load-balancer-round-robin.ts b/packages/grpc-js/src/load-balancer-round-robin.ts index 2159e64c7..fabd334e3 100644 --- a/packages/grpc-js/src/load-balancer-round-robin.ts +++ b/packages/grpc-js/src/load-balancer-round-robin.ts @@ -18,10 +18,10 @@ import { LoadBalancer, ChannelControlHelper, - registerLoadBalancerType, - LoadBalancingConfig + LoadBalancingConfig, + registerLoadBalancerType } from './load-balancer'; -import { ConnectivityState } from './channel'; +import { ConnectivityState } from "./connectivity-state"; import { QueuePicker, Picker, @@ -33,9 +33,11 @@ import { import { Subchannel, ConnectivityStateListener, - SubchannelAddress, - subchannelAddressToString, } from './subchannel'; +import { + SubchannelAddress, + subchannelAddressToString +} from "./subchannel-address"; import * as logging from './logging'; import { LogVerbosity } from './constants'; diff --git a/packages/grpc-js/src/load-balancer.ts b/packages/grpc-js/src/load-balancer.ts index 8d5c7c837..7fe0b9b3d 100644 --- a/packages/grpc-js/src/load-balancer.ts +++ b/packages/grpc-js/src/load-balancer.ts @@ -16,11 +16,10 @@ */ import { ChannelOptions } from './channel-options'; -import { Subchannel, SubchannelAddress } from './subchannel'; -import { ConnectivityState } from './channel'; +import { Subchannel } from './subchannel'; +import { SubchannelAddress } from "./subchannel-address"; +import { ConnectivityState } from "./connectivity-state"; import { Picker } from './picker'; -import * as load_balancer_pick_first from './load-balancer-pick-first'; -import * as load_balancer_round_robin from './load-balancer-round-robin'; /** * A collection of functions associated with a channel that a load balancer @@ -108,11 +107,13 @@ export interface LoadBalancingConfigConstructor { const registeredLoadBalancerTypes: { [name: string]: { - LoadBalancer: LoadBalancerConstructor, - LoadBalancingConfig: LoadBalancingConfigConstructor + LoadBalancer: LoadBalancerConstructor; + LoadBalancingConfig: LoadBalancingConfigConstructor; }; } = {}; +let defaultLoadBalancerType: string | null = null; + export function registerLoadBalancerType( typeName: string, loadBalancerType: LoadBalancerConstructor, @@ -124,6 +125,10 @@ export function registerLoadBalancerType( }; } +export function registerDefaultLoadBalancerType(typeName: string) { + defaultLoadBalancerType = typeName; +} + export function createLoadBalancer( config: LoadBalancingConfig, channelControlHelper: ChannelControlHelper @@ -140,25 +145,29 @@ export function isLoadBalancerNameRegistered(typeName: string): boolean { return typeName in registeredLoadBalancerTypes; } -export function getFirstUsableConfig(configs: LoadBalancingConfig[], defaultPickFirst?: true): LoadBalancingConfig; +export function getFirstUsableConfig(configs: LoadBalancingConfig[], fallbackTodefault?: true): LoadBalancingConfig; export function getFirstUsableConfig( configs: LoadBalancingConfig[], - defaultPickFirst: boolean = false + fallbackTodefault: boolean = false ): LoadBalancingConfig | null { for (const config of configs) { if (config.getLoadBalancerName() in registeredLoadBalancerTypes) { return config; } } - if (defaultPickFirst) { - return new load_balancer_pick_first.PickFirstLoadBalancingConfig() + if (fallbackTodefault) { + if (defaultLoadBalancerType) { + return new registeredLoadBalancerTypes[defaultLoadBalancerType]!.LoadBalancingConfig(); + } else { + return null; + } } else { return null; } } export function validateLoadBalancingConfig(obj: any): LoadBalancingConfig { - if (!(obj !== null && (typeof obj === 'object'))) { + if (!(obj !== null && (typeof obj === 'object'))) { throw new Error('Load balancing config must be an object'); } const keys = Object.keys(obj); @@ -172,8 +181,3 @@ export function validateLoadBalancingConfig(obj: any): LoadBalancingConfig { throw new Error(`Unrecognized load balancing config name ${typeName}`); } } - -export function registerAll() { - load_balancer_pick_first.setup(); - load_balancer_round_robin.setup(); -} diff --git a/packages/grpc-js/src/resolver-dns.ts b/packages/grpc-js/src/resolver-dns.ts index 67f1f8c45..44246c779 100644 --- a/packages/grpc-js/src/resolver-dns.ts +++ b/packages/grpc-js/src/resolver-dns.ts @@ -28,7 +28,7 @@ import { StatusObject } from './call-stream'; import { Metadata } from './metadata'; import * as logging from './logging'; import { LogVerbosity } from './constants'; -import { SubchannelAddress, TcpSubchannelAddress } from './subchannel'; +import { SubchannelAddress, TcpSubchannelAddress } from "./subchannel-address"; import { GrpcUri, uriToString, splitHostPort } from './uri-parser'; import { isIPv6, isIPv4 } from 'net'; import { ChannelOptions } from './channel-options'; diff --git a/packages/grpc-js/src/resolver-uds.ts b/packages/grpc-js/src/resolver-uds.ts index 40502f113..1c5a7a64c 100644 --- a/packages/grpc-js/src/resolver-uds.ts +++ b/packages/grpc-js/src/resolver-uds.ts @@ -15,7 +15,7 @@ */ import { Resolver, ResolverListener, registerResolver } from './resolver'; -import { SubchannelAddress } from './subchannel'; +import { SubchannelAddress } from "./subchannel-address"; import { GrpcUri } from './uri-parser'; import { ChannelOptions } from './channel-options'; diff --git a/packages/grpc-js/src/resolver.ts b/packages/grpc-js/src/resolver.ts index 147ace30d..5bf7df2e7 100644 --- a/packages/grpc-js/src/resolver.ts +++ b/packages/grpc-js/src/resolver.ts @@ -16,10 +16,8 @@ */ import { MethodConfig, ServiceConfig } from './service-config'; -import * as resolver_dns from './resolver-dns'; -import * as resolver_uds from './resolver-uds'; import { StatusObject } from './call-stream'; -import { SubchannelAddress } from './subchannel'; +import { SubchannelAddress } from "./subchannel-address"; import { GrpcUri, uriToString } from './uri-parser'; import { ChannelOptions } from './channel-options'; import { Metadata } from './metadata'; @@ -175,8 +173,3 @@ export function mapUriDefaultScheme(target: GrpcUri): GrpcUri | null { } return target; } - -export function registerAll() { - resolver_dns.setup(); - resolver_uds.setup(); -} diff --git a/packages/grpc-js/src/resolving-load-balancer.ts b/packages/grpc-js/src/resolving-load-balancer.ts index 94dd8c4a9..9825086c1 100644 --- a/packages/grpc-js/src/resolving-load-balancer.ts +++ b/packages/grpc-js/src/resolving-load-balancer.ts @@ -18,11 +18,11 @@ import { ChannelControlHelper, LoadBalancer, - getFirstUsableConfig, - LoadBalancingConfig + LoadBalancingConfig, + getFirstUsableConfig } from './load-balancer'; import { ServiceConfig, validateServiceConfig } from './service-config'; -import { ConnectivityState } from './channel'; +import { ConnectivityState } from "./connectivity-state"; import { ConfigSelector, createResolver, Resolver } from './resolver'; import { ServiceError } from './call'; import { Picker, UnavailablePicker, QueuePicker } from './picker'; @@ -32,7 +32,7 @@ import { StatusObject } from './call-stream'; import { Metadata } from './metadata'; import * as logging from './logging'; import { LogVerbosity } from './constants'; -import { SubchannelAddress } from './subchannel'; +import { SubchannelAddress } from "./subchannel-address"; import { GrpcUri, uriToString } from './uri-parser'; import { ChildLoadBalancerHandler } from './load-balancer-child-handler'; import { ChannelOptions } from './channel-options'; diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 255e210b6..aec149556 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -55,8 +55,8 @@ import { SubchannelAddress, TcpSubchannelAddress, isTcpSubchannelAddress, - subchannelAddressToString, -} from './subchannel'; + subchannelAddressToString +} from "./subchannel-address"; import { parseUri } from './uri-parser'; const TRACER_NAME = 'server'; diff --git a/packages/grpc-js/src/subchannel-address.ts b/packages/grpc-js/src/subchannel-address.ts new file mode 100644 index 000000000..4b08d8ba1 --- /dev/null +++ b/packages/grpc-js/src/subchannel-address.ts @@ -0,0 +1,62 @@ +/* + * Copyright 2021 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. + * + */ + +export interface TcpSubchannelAddress { + port: number; + host: string; +} + +export interface IpcSubchannelAddress { + path: string; +} +/** + * This represents a single backend address to connect to. This interface is a + * subset of net.SocketConnectOpts, i.e. the options described at + * https://nodejs.org/api/net.html#net_socket_connect_options_connectlistener. + * Those are in turn a subset of the options that can be passed to http2.connect. + */ + +export type SubchannelAddress = TcpSubchannelAddress | IpcSubchannelAddress; + +export function isTcpSubchannelAddress( + address: SubchannelAddress +): address is TcpSubchannelAddress { + return 'port' in address; +} + +export function subchannelAddressEqual( + address1: SubchannelAddress, + address2: SubchannelAddress +): boolean { + if (isTcpSubchannelAddress(address1)) { + return ( + isTcpSubchannelAddress(address2) && + address1.host === address2.host && + address1.port === address2.port + ); + } else { + return !isTcpSubchannelAddress(address2) && address1.path === address2.path; + } +} + +export function subchannelAddressToString(address: SubchannelAddress): string { + if (isTcpSubchannelAddress(address)) { + return address.host + ':' + address.port; + } else { + return address.path; + } +} diff --git a/packages/grpc-js/src/subchannel-pool.ts b/packages/grpc-js/src/subchannel-pool.ts index d28e3eac8..65c5f2177 100644 --- a/packages/grpc-js/src/subchannel-pool.ts +++ b/packages/grpc-js/src/subchannel-pool.ts @@ -18,9 +18,11 @@ import { ChannelOptions, channelOptionsEqual } from './channel-options'; import { Subchannel, - SubchannelAddress, - subchannelAddressEqual, } from './subchannel'; +import { + SubchannelAddress, + subchannelAddressEqual +} from "./subchannel-address"; import { ChannelCredentials } from './channel-credentials'; import { GrpcUri, uriToString } from './uri-parser'; diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index c50a68e77..a76ea963c 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -21,7 +21,7 @@ import { Metadata } from './metadata'; import { Http2CallStream } from './call-stream'; import { ChannelOptions } from './channel-options'; import { PeerCertificate, checkServerIdentity } from 'tls'; -import { ConnectivityState } from './channel'; +import { ConnectivityState } from "./connectivity-state"; import { BackoffTimeout, BackoffOptions } from './backoff-timeout'; import { getDefaultAuthority } from './resolver'; import * as logging from './logging'; @@ -31,6 +31,7 @@ import * as net from 'net'; import { GrpcUri, parseUri, splitHostPort, uriToString } from './uri-parser'; import { ConnectionOptions } from 'tls'; import { FilterFactory, Filter } from './filter'; +import { SubchannelAddress, subchannelAddressToString } from './subchannel-address'; const clientVersion = require('../../package.json').version; @@ -82,52 +83,6 @@ function uniformRandom(min: number, max: number) { const tooManyPingsData: Buffer = Buffer.from('too_many_pings', 'ascii'); -export interface TcpSubchannelAddress { - port: number; - host: string; -} - -export interface IpcSubchannelAddress { - path: string; -} - -/** - * This represents a single backend address to connect to. This interface is a - * subset of net.SocketConnectOpts, i.e. the options described at - * https://nodejs.org/api/net.html#net_socket_connect_options_connectlistener. - * Those are in turn a subset of the options that can be passed to http2.connect. - */ -export type SubchannelAddress = TcpSubchannelAddress | IpcSubchannelAddress; - -export function isTcpSubchannelAddress( - address: SubchannelAddress -): address is TcpSubchannelAddress { - return 'port' in address; -} - -export function subchannelAddressEqual( - address1: SubchannelAddress, - address2: SubchannelAddress -): boolean { - if (isTcpSubchannelAddress(address1)) { - return ( - isTcpSubchannelAddress(address2) && - address1.host === address2.host && - address1.port === address2.port - ); - } else { - return !isTcpSubchannelAddress(address2) && address1.path === address2.path; - } -} - -export function subchannelAddressToString(address: SubchannelAddress): string { - if (isTcpSubchannelAddress(address)) { - return address.host + ':' + address.port; - } else { - return address.path; - } -} - export class Subchannel { /** * The subchannel's current connectivity state. Invariant: `session` === `null` diff --git a/packages/grpc-js/test/test-client.ts b/packages/grpc-js/test/test-client.ts index 0d2878cbc..51af05416 100644 --- a/packages/grpc-js/test/test-client.ts +++ b/packages/grpc-js/test/test-client.ts @@ -20,7 +20,7 @@ import * as assert from 'assert'; import * as grpc from '../src'; import { Server, ServerCredentials } from '../src'; import { Client } from '../src'; -import { ConnectivityState } from '../src/channel'; +import { ConnectivityState } from "../src/connectivity-state"; const clientInsecureCreds = grpc.credentials.createInsecure(); const serverInsecureCreds = ServerCredentials.createInsecure(); diff --git a/packages/grpc-js/test/test-resolver.ts b/packages/grpc-js/test/test-resolver.ts index c4f42f6eb..976e64895 100644 --- a/packages/grpc-js/test/test-resolver.ts +++ b/packages/grpc-js/test/test-resolver.ts @@ -19,9 +19,11 @@ // tslint:disable no-any import * as assert from 'assert'; import * as resolverManager from '../src/resolver'; +import * as load_balancer_pick_first from '../src/load-balancer-pick-first'; +import * as load_balancer_round_robin from '../src/load-balancer-round-robin'; import { ServiceConfig } from '../src/service-config'; import { StatusObject } from '../src/call-stream'; -import { SubchannelAddress, isTcpSubchannelAddress } from '../src/subchannel'; +import { SubchannelAddress, isTcpSubchannelAddress } from "../src/subchannel-address"; import { parseUri, GrpcUri } from '../src/uri-parser'; describe('Name Resolver', () => { @@ -29,7 +31,8 @@ describe('Name Resolver', () => { // For some reason DNS queries sometimes take a long time on Windows this.timeout(4000); before(() => { - resolverManager.registerAll(); + load_balancer_pick_first.setup(); + load_balancer_round_robin.setup(); }); it('Should resolve localhost properly', done => { const target = resolverManager.mapUriDefaultScheme(parseUri('localhost:50051')!)!; From 32cd3504cccec9fcfee67dc87a6a9e8f66fa40f3 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 28 Jun 2021 11:24:43 -0700 Subject: [PATCH 030/450] grpc-js: Add note in README about feature parity requests --- packages/grpc-js/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/grpc-js/README.md b/packages/grpc-js/README.md index 4bb4da024..df44264ce 100644 --- a/packages/grpc-js/README.md +++ b/packages/grpc-js/README.md @@ -25,6 +25,8 @@ Documentation specifically for the `@grpc/grpc-js` package is currently not avai - Connection Keepalives - HTTP Connect support (proxies) +If you need a feature from the `grpc` package that is not provided by the `@grpc/grpc-js`, please file a feature request with that information. + This library does not directly handle `.proto` files. To use `.proto` files with this library we recommend using the `@grpc/proto-loader` package. ## Migrating from [`grpc`](https://www.npmjs.com/package/grpc) From 41e09f7d12b05d74f37e3fd30bf08a7398ad12d2 Mon Sep 17 00:00:00 2001 From: Mike Lewis Date: Mon, 28 Jun 2021 19:04:58 +0100 Subject: [PATCH 031/450] Prevent early return in proto-loader containsDefinition f289c343b3393aad73795c0657415f4160bcdcb5 introduced a bug - the recursive for-loop descended into the first elements nested array and returned that value without iterating over the other members of the array. This means that the code would only work correctly when the protofile contained a definition whose name was alphabetically first amongst its siblings. This commit fixes the issue by moving the call to containsDefinition into the if statement to allow iteration to continue if containsDefinition returns false. --- packages/proto-loader/bin/proto-loader-gen-types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index fedaadc38..b441d425e 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -583,8 +583,8 @@ function containsDefinition(definitionType: typeof Protobuf.Type | typeof Protob for (const nested of namespace.nestedArray.sort(compareName)) { if (nested instanceof definitionType) { return true; - } else if (isNamespaceBase(nested) && !(nested instanceof Protobuf.Type) && !(nested instanceof Protobuf.Enum)) { - return containsDefinition(definitionType, nested); + } else if (isNamespaceBase(nested) && !(nested instanceof Protobuf.Type) && !(nested instanceof Protobuf.Enum) && containsDefinition(definitionType, nested)) { + return true; } } From 6ba982548e58a89641f3377c863b263ab094101f Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 28 Jun 2021 13:17:16 -0700 Subject: [PATCH 032/450] proto-loader: bump to 0.6.4 --- packages/proto-loader/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index cbda6680d..824fa6f5e 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/proto-loader", - "version": "0.6.3", + "version": "0.6.4", "author": "Google Inc.", "contributors": [ { From 1452ed93aa86df36e2d18093455be8bb20637a56 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 29 Jun 2021 10:04:32 -0700 Subject: [PATCH 033/450] grpc-js: Register IP resolver in index --- packages/grpc-js/src/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index d0eb2a37c..52c122b12 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -249,12 +249,14 @@ export { experimental }; import * as resolver_dns from './resolver-dns'; import * as resolver_uds from './resolver-uds'; +import * as resolver_ip from './resolver-ip'; import * as load_balancer_pick_first from './load-balancer-pick-first'; import * as load_balancer_round_robin from './load-balancer-round-robin'; (() => { resolver_dns.setup(); resolver_uds.setup(); + resolver_ip.setup(); load_balancer_pick_first.setup(); load_balancer_round_robin.setup(); })(); From 8605ef2ded12f4eff3dded61736f1741e075add0 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 29 Jun 2021 10:43:45 -0700 Subject: [PATCH 034/450] Fix subchannel address import, resolver test setup --- packages/grpc-js/src/resolver-ip.ts | 2 +- packages/grpc-js/test/test-resolver.ts | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/grpc-js/src/resolver-ip.ts b/packages/grpc-js/src/resolver-ip.ts index 5c9e29c46..18bbe54aa 100644 --- a/packages/grpc-js/src/resolver-ip.ts +++ b/packages/grpc-js/src/resolver-ip.ts @@ -20,7 +20,7 @@ import { ChannelOptions } from "./channel-options"; import { LogVerbosity, Status } from "./constants"; import { Metadata } from "./metadata"; import { registerResolver, Resolver, ResolverListener } from "./resolver"; -import { SubchannelAddress } from "./subchannel"; +import { SubchannelAddress } from "./subchannel-address"; import { GrpcUri, splitHostPort, uriToString } from "./uri-parser"; import * as logging from './logging'; diff --git a/packages/grpc-js/test/test-resolver.ts b/packages/grpc-js/test/test-resolver.ts index b5a4c1640..7addfa232 100644 --- a/packages/grpc-js/test/test-resolver.ts +++ b/packages/grpc-js/test/test-resolver.ts @@ -19,21 +19,23 @@ // tslint:disable no-any import * as assert from 'assert'; import * as resolverManager from '../src/resolver'; -import * as load_balancer_pick_first from '../src/load-balancer-pick-first'; -import * as load_balancer_round_robin from '../src/load-balancer-round-robin'; +import * as resolver_dns from '../src/resolver-dns'; +import * as resolver_uds from '../src/resolver-uds'; +import * as resolver_ip from '../src/resolver-ip'; import { ServiceConfig } from '../src/service-config'; import { StatusObject } from '../src/call-stream'; import { SubchannelAddress, isTcpSubchannelAddress } from "../src/subchannel-address"; import { parseUri, GrpcUri } from '../src/uri-parser'; describe('Name Resolver', () => { + before(() => { + resolver_dns.setup(); + resolver_uds.setup(); + resolver_ip.setup(); + }); describe('DNS Names', function() { // For some reason DNS queries sometimes take a long time on Windows this.timeout(4000); - before(() => { - load_balancer_pick_first.setup(); - load_balancer_round_robin.setup(); - }); it('Should resolve localhost properly', done => { const target = resolverManager.mapUriDefaultScheme(parseUri('localhost:50051')!)!; const listener: resolverManager.ResolverListener = { From 1037b23ba62b4d1205f3dd57f50e553b804d7a04 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 29 Jun 2021 14:40:24 -0700 Subject: [PATCH 035/450] grpc-js: Format source files and fix lint errors --- .../grpc-js/src/call-credentials-filter.ts | 4 +- packages/grpc-js/src/call-stream.ts | 29 ++++-- packages/grpc-js/src/call.ts | 12 ++- packages/grpc-js/src/channel-options.ts | 1 + packages/grpc-js/src/channel.ts | 94 ++++++++++++++----- packages/grpc-js/src/client-interceptors.ts | 11 ++- packages/grpc-js/src/client.ts | 33 +++---- packages/grpc-js/src/connectivity-state.ts | 2 +- packages/grpc-js/src/constants.ts | 6 +- packages/grpc-js/src/deadline-filter.ts | 4 +- packages/grpc-js/src/experimental.ts | 46 ++++++--- packages/grpc-js/src/filter.ts | 3 +- packages/grpc-js/src/http_proxy.ts | 12 ++- packages/grpc-js/src/index.ts | 9 +- .../src/load-balancer-child-handler.ts | 6 +- .../grpc-js/src/load-balancer-pick-first.ts | 24 ++--- .../grpc-js/src/load-balancer-round-robin.ts | 24 ++--- packages/grpc-js/src/load-balancer.ts | 36 ++++--- packages/grpc-js/src/logging.ts | 13 ++- packages/grpc-js/src/make-client.ts | 2 +- .../grpc-js/src/max-message-size-filter.ts | 25 +++-- packages/grpc-js/src/metadata.ts | 2 +- packages/grpc-js/src/picker.ts | 2 +- packages/grpc-js/src/resolver-dns.ts | 10 +- packages/grpc-js/src/resolver-ip.ts | 41 ++++---- packages/grpc-js/src/resolver-uds.ts | 2 +- packages/grpc-js/src/resolver.ts | 6 +- .../grpc-js/src/resolving-load-balancer.ts | 42 ++++++--- packages/grpc-js/src/server-call.ts | 6 +- packages/grpc-js/src/server.ts | 15 ++- packages/grpc-js/src/service-config.ts | 26 +++-- packages/grpc-js/src/subchannel-pool.ts | 8 +- packages/grpc-js/src/subchannel.ts | 44 ++++++--- 33 files changed, 399 insertions(+), 201 deletions(-) diff --git a/packages/grpc-js/src/call-credentials-filter.ts b/packages/grpc-js/src/call-credentials-filter.ts index 53bdba2f1..5c746297e 100644 --- a/packages/grpc-js/src/call-credentials-filter.ts +++ b/packages/grpc-js/src/call-credentials-filter.ts @@ -66,7 +66,9 @@ export class CallCredentialsFilter extends BaseFilter implements Filter { Status.INTERNAL, '"authorization" metadata cannot have multiple values' ); - return Promise.reject('"authorization" metadata cannot have multiple values'); + return Promise.reject( + '"authorization" metadata cannot have multiple values' + ); } return resultMetadata; } diff --git a/packages/grpc-js/src/call-stream.ts b/packages/grpc-js/src/call-stream.ts index 083ebe851..87121154d 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -57,7 +57,7 @@ interface SystemError extends Error { * Should do approximately the same thing as util.getSystemErrorName but the * TypeScript types don't have that function for some reason so I just made my * own. - * @param errno + * @param errno */ function getSystemErrorName(errno: number): string { for (const [name, num] of Object.entries(os.constants.errno)) { @@ -71,9 +71,10 @@ function getSystemErrorName(errno: number): string { export type Deadline = Date | number; function getMinDeadline(deadlineList: Deadline[]): Deadline { - let minValue: number = Infinity; + let minValue = Infinity; for (const deadline of deadlineList) { - const deadlineMsecs = deadline instanceof Date ? deadline.getTime() : deadline; + const deadlineMsecs = + deadline instanceof Date ? deadline.getTime() : deadline; if (deadlineMsecs < minValue) { minValue = deadlineMsecs; } @@ -265,7 +266,10 @@ export class Http2CallStream implements Call { metadata: new Metadata(), }); }; - if (this.options.parentCall && this.options.flags & Propagate.CANCELLATION) { + if ( + this.options.parentCall && + this.options.flags & Propagate.CANCELLATION + ) { this.options.parentCall.on('cancelled', () => { this.cancelWithStatus(Status.CANCELLED, 'Cancelled by parent call'); }); @@ -464,7 +468,9 @@ export class Http2CallStream implements Call { subchannel: Subchannel, extraFilters: FilterFactory[] ): void { - this.filterStack.push(extraFilters.map(filterFactory => filterFactory.createFilter(this))); + this.filterStack.push( + extraFilters.map((filterFactory) => filterFactory.createFilter(this)) + ); if (this.finalStatus !== null) { stream.close(NGHTTP2_CANCEL); } else { @@ -548,7 +554,7 @@ export class Http2CallStream implements Call { stream.on('close', () => { /* 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. */ + * we can bubble up the error message from that event. */ process.nextTick(() => { this.trace('HTTP/2 stream closed with code ' + stream.rstCode); /* If we have a final status with an OK status code, that means that @@ -629,7 +635,16 @@ export class Http2CallStream implements Call { * https://github.com/nodejs/node/blob/8b8620d580314050175983402dfddf2674e8e22a/lib/internal/http2/core.js#L2267 */ if (err.code !== 'ERR_HTTP2_STREAM_ERROR') { - this.trace('Node error event: message=' + err.message + ' code=' + err.code + ' errno=' + getSystemErrorName(err.errno) + ' syscall=' + err.syscall); + this.trace( + 'Node error event: message=' + + err.message + + ' code=' + + err.code + + ' errno=' + + getSystemErrorName(err.errno) + + ' syscall=' + + err.syscall + ); this.internalError = err; } }); diff --git a/packages/grpc-js/src/call.ts b/packages/grpc-js/src/call.ts index cfe37ecfb..fcc3159db 100644 --- a/packages/grpc-js/src/call.ts +++ b/packages/grpc-js/src/call.ts @@ -81,7 +81,8 @@ export function callErrorFromStatus(status: StatusObject): ServiceError { return Object.assign(new Error(message), status); } -export class ClientUnaryCallImpl extends EventEmitter +export class ClientUnaryCallImpl + extends EventEmitter implements ClientUnaryCall { public call?: InterceptingCallInterface; constructor() { @@ -97,7 +98,8 @@ export class ClientUnaryCallImpl extends EventEmitter } } -export class ClientReadableStreamImpl extends Readable +export class ClientReadableStreamImpl + extends Readable implements ClientReadableStream { public call?: InterceptingCallInterface; constructor(readonly deserialize: (chunk: Buffer) => ResponseType) { @@ -117,7 +119,8 @@ export class ClientReadableStreamImpl extends Readable } } -export class ClientWritableStreamImpl extends Writable +export class ClientWritableStreamImpl + extends Writable implements ClientWritableStream { public call?: InterceptingCallInterface; constructor(readonly serialize: (value: RequestType) => Buffer) { @@ -149,7 +152,8 @@ export class ClientWritableStreamImpl extends Writable } } -export class ClientDuplexStreamImpl extends Duplex +export class ClientDuplexStreamImpl + extends Duplex implements ClientDuplexStream { public call?: InterceptingCallInterface; constructor( diff --git a/packages/grpc-js/src/channel-options.ts b/packages/grpc-js/src/channel-options.ts index ebb724b0e..604fd8685 100644 --- a/packages/grpc-js/src/channel-options.ts +++ b/packages/grpc-js/src/channel-options.ts @@ -37,6 +37,7 @@ export interface ChannelOptions { 'grpc.http_connect_target'?: string; 'grpc.http_connect_creds'?: string; 'grpc-node.max_session_memory'?: number; + // eslint-disable-next-line @typescript-eslint/no-explicit-any [key: string]: any; } diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 58726ccc7..9200043e4 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -33,9 +33,14 @@ import { FilterStackFactory } from './filter-stack'; import { CallCredentialsFilterFactory } from './call-credentials-filter'; import { DeadlineFilterFactory } from './deadline-filter'; import { CompressionFilterFactory } from './compression-filter'; -import { CallConfig, ConfigSelector, getDefaultAuthority, mapUriDefaultScheme } from './resolver'; +import { + CallConfig, + ConfigSelector, + getDefaultAuthority, + mapUriDefaultScheme, +} from './resolver'; import { trace, log } from './logging'; -import { SubchannelAddress } from "./subchannel-address"; +import { SubchannelAddress } from './subchannel-address'; import { MaxMessageSizeFilterFactory } from './max-message-size-filter'; import { mapProxyName } from './http_proxy'; import { GrpcUri, parseUri, uriToString } from './uri-parser'; @@ -253,8 +258,8 @@ export class ChannelImplementation implements Channel { process.nextTick(() => { const localQueue = this.configSelectionQueue; this.configSelectionQueue = []; - this.callRefTimerUnref() - for (const {callStream, callMetadata} of localQueue) { + this.callRefTimerUnref(); + for (const { callStream, callMetadata } of localQueue) { this.tryGetConfig(callStream, callMetadata); } this.configSelectionQueue = []; @@ -262,15 +267,21 @@ export class ChannelImplementation implements Channel { }, (status) => { if (this.configSelectionQueue.length > 0) { - trace(LogVerbosity.DEBUG, 'channel', 'Name resolution failed for target ' + uriToString(this.target) + ' with calls queued for config selection'); + trace( + LogVerbosity.DEBUG, + 'channel', + 'Name resolution failed for target ' + + uriToString(this.target) + + ' with calls queued for config selection' + ); } const localQueue = this.configSelectionQueue; this.configSelectionQueue = []; this.callRefTimerUnref(); - for (const {callStream, callMetadata} of localQueue) { + for (const { callStream, callMetadata } of localQueue) { if (callMetadata.getOptions().waitForReady) { this.callRefTimerRef(); - this.configSelectionQueue.push({callStream, callMetadata}); + this.configSelectionQueue.push({ callStream, callMetadata }); } else { callStream.cancelWithStatus(status.code, status.details); } @@ -288,20 +299,38 @@ export class ChannelImplementation implements Channel { private callRefTimerRef() { // If the hasRef function does not exist, always run the code if (!this.callRefTimer.hasRef?.()) { - trace(LogVerbosity.DEBUG, 'channel', 'callRefTimer.ref | configSelectionQueue.length=' + this.configSelectionQueue.length + ' pickQueue.length=' + this.pickQueue.length); + trace( + LogVerbosity.DEBUG, + 'channel', + 'callRefTimer.ref | configSelectionQueue.length=' + + this.configSelectionQueue.length + + ' pickQueue.length=' + + this.pickQueue.length + ); this.callRefTimer.ref?.(); } } private callRefTimerUnref() { // If the hasRef function does not exist, always run the code - if ((!this.callRefTimer.hasRef) || (this.callRefTimer.hasRef())) { - trace(LogVerbosity.DEBUG, 'channel', 'callRefTimer.unref | configSelectionQueue.length=' + this.configSelectionQueue.length + ' pickQueue.length=' + this.pickQueue.length); + if (!this.callRefTimer.hasRef || this.callRefTimer.hasRef()) { + trace( + LogVerbosity.DEBUG, + 'channel', + 'callRefTimer.unref | configSelectionQueue.length=' + + this.configSelectionQueue.length + + ' pickQueue.length=' + + this.pickQueue.length + ); this.callRefTimer.unref?.(); } } - private pushPick(callStream: Http2CallStream, callMetadata: Metadata, callConfig: CallConfig) { + private pushPick( + callStream: Http2CallStream, + callMetadata: Metadata, + callConfig: CallConfig + ) { this.pickQueue.push({ callStream, callMetadata, callConfig }); this.callRefTimerRef(); } @@ -313,8 +342,15 @@ export class ChannelImplementation implements Channel { * @param callStream * @param callMetadata */ - private tryPick(callStream: Http2CallStream, callMetadata: Metadata, callConfig: CallConfig) { - const pickResult = this.currentPicker.pick({ metadata: callMetadata, extraPickInfo: callConfig.pickInformation }); + private tryPick( + callStream: Http2CallStream, + callMetadata: Metadata, + callConfig: CallConfig + ) { + const pickResult = this.currentPicker.pick({ + metadata: callMetadata, + extraPickInfo: callConfig.pickInformation, + }); trace( LogVerbosity.DEBUG, 'channel', @@ -412,7 +448,9 @@ export class ChannelImplementation implements Channel { ); callStream.cancelWithStatus( Status.INTERNAL, - `Failed to start HTTP/2 stream with error: ${(error as Error).message}` + `Failed to start HTTP/2 stream with error: ${ + (error as Error).message + }` ); } } @@ -434,7 +472,7 @@ export class ChannelImplementation implements Channel { (error: Error & { code: number }) => { // We assume the error code isn't 0 (Status.OK) callStream.cancelWithStatus( - (typeof error.code === 'number') ? error.code : Status.UNKNOWN, + typeof error.code === 'number' ? error.code : Status.UNKNOWN, `Getting metadata from plugin failed with error: ${error.message}` ); } @@ -492,7 +530,7 @@ export class ChannelImplementation implements Channel { const watchersCopy = this.connectivityStateWatchers.slice(); for (const watcherObject of watchersCopy) { if (newState !== watcherObject.currentState) { - if(watcherObject.timer) { + if (watcherObject.timer) { clearTimeout(watcherObject.timer); } this.removeConnectivityStateWatcher(watcherObject); @@ -513,9 +551,9 @@ export class ChannelImplementation implements Channel { * ResolvingLoadBalancer may be idle and if so it needs to be kicked * because it now has a pending request. */ this.resolvingLoadBalancer.exitIdle(); - this.configSelectionQueue.push({ + this.configSelectionQueue.push({ callStream: stream, - callMetadata: metadata + callMetadata: metadata, }); this.callRefTimerRef(); } else { @@ -523,15 +561,23 @@ export class ChannelImplementation implements Channel { if (callConfig.status === Status.OK) { if (callConfig.methodConfig.timeout) { const deadline = new Date(); - deadline.setSeconds(deadline.getSeconds() + callConfig.methodConfig.timeout.seconds); - deadline.setMilliseconds(deadline.getMilliseconds() + callConfig.methodConfig.timeout.nanos / 1_000_000); + deadline.setSeconds( + deadline.getSeconds() + callConfig.methodConfig.timeout.seconds + ); + deadline.setMilliseconds( + deadline.getMilliseconds() + + callConfig.methodConfig.timeout.nanos / 1_000_000 + ); stream.setConfigDeadline(deadline); // Refreshing the filters makes the deadline filter pick up the new deadline stream.filterStack.refresh(); } this.tryPick(stream, metadata, callConfig); } else { - stream.cancelWithStatus(callConfig.status, "Failed to route call to method " + stream.getMethod()); + stream.cancelWithStatus( + callConfig.status, + 'Failed to route call to method ' + stream.getMethod() + ); } } } @@ -569,7 +615,7 @@ export class ChannelImplementation implements Channel { throw new Error('Channel has been shut down'); } let timer = null; - if(deadline !== Infinity) { + if (deadline !== Infinity) { const deadlineDate: Date = deadline instanceof Date ? deadline : new Date(deadline); const now = new Date(); @@ -585,12 +631,12 @@ export class ChannelImplementation implements Channel { callback( new Error('Deadline passed without connectivity state change') ); - }, deadlineDate.getTime() - now.getTime()) + }, deadlineDate.getTime() - now.getTime()); } const watcherObject = { currentState, callback, - timer + timer, }; this.connectivityStateWatchers.push(watcherObject); } diff --git a/packages/grpc-js/src/client-interceptors.ts b/packages/grpc-js/src/client-interceptors.ts index a7cc2f878..5dfbeba14 100644 --- a/packages/grpc-js/src/client-interceptors.ts +++ b/packages/grpc-js/src/client-interceptors.ts @@ -348,7 +348,10 @@ class BaseInterceptingCall implements InterceptingCallInterface { try { serialized = this.methodDefinition.requestSerialize(message); } catch (e) { - this.call.cancelWithStatus(Status.INTERNAL, `Request message serialization failure: ${e.message}`); + this.call.cancelWithStatus( + Status.INTERNAL, + `Request message serialization failure: ${e.message}` + ); return; } this.call.sendMessageWithContext(context, serialized); @@ -403,7 +406,8 @@ class BaseInterceptingCall implements InterceptingCallInterface { * BaseInterceptingCall with special-cased behavior for methods with unary * responses. */ -class BaseUnaryInterceptingCall extends BaseInterceptingCall +class BaseUnaryInterceptingCall + extends BaseInterceptingCall implements InterceptingCallInterface { // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(call: Call, methodDefinition: ClientMethodDefinition) { @@ -435,7 +439,8 @@ class BaseUnaryInterceptingCall extends BaseInterceptingCall * BaseInterceptingCall with special-cased behavior for methods with streaming * responses. */ -class BaseStreamingInterceptingCall extends BaseInterceptingCall +class BaseStreamingInterceptingCall + extends BaseInterceptingCall implements InterceptingCallInterface {} function getBottomInterceptingCall( diff --git a/packages/grpc-js/src/client.ts b/packages/grpc-js/src/client.ts index d19fe7d07..ed9407cd8 100644 --- a/packages/grpc-js/src/client.ts +++ b/packages/grpc-js/src/client.ts @@ -31,7 +31,7 @@ import { import { CallCredentials } from './call-credentials'; import { Deadline, StatusObject } from './call-stream'; import { Channel, ChannelImplementation } from './channel'; -import { ConnectivityState } from "./connectivity-state"; +import { ConnectivityState } from './connectivity-state'; import { ChannelCredentials } from './channel-credentials'; import { ChannelOptions } from './channel-options'; import { Status } from './constants'; @@ -56,7 +56,9 @@ const INTERCEPTOR_SYMBOL = Symbol(); const INTERCEPTOR_PROVIDER_SYMBOL = Symbol(); const CALL_INVOCATION_TRANSFORMER_SYMBOL = Symbol(); -function isFunction(arg: Metadata | CallOptions | UnaryCallback | undefined): arg is UnaryCallback{ +function isFunction( + arg: Metadata | CallOptions | UnaryCallback | undefined +): arg is UnaryCallback { return typeof arg === 'function'; } @@ -266,9 +268,11 @@ export class Client { options?: CallOptions | UnaryCallback, callback?: UnaryCallback ): ClientUnaryCall { - const checkedArguments = this.checkOptionalUnaryResponseArguments< - ResponseType - >(metadata, options, callback); + const checkedArguments = this.checkOptionalUnaryResponseArguments( + metadata, + options, + callback + ); const methodDefinition: ClientMethodDefinition< RequestType, ResponseType @@ -382,9 +386,11 @@ export class Client { options?: CallOptions | UnaryCallback, callback?: UnaryCallback ): ClientWritableStream { - const checkedArguments = this.checkOptionalUnaryResponseArguments< - ResponseType - >(metadata, options, callback); + const checkedArguments = this.checkOptionalUnaryResponseArguments( + metadata, + options, + callback + ); const methodDefinition: ClientMethodDefinition< RequestType, ResponseType @@ -408,9 +414,7 @@ export class Client { callProperties ) as CallProperties; } - const emitter: ClientWritableStream = callProperties.call as ClientWritableStream< - RequestType - >; + const emitter: ClientWritableStream = callProperties.call as ClientWritableStream; const interceptorArgs: InterceptorArguments = { clientInterceptors: this[INTERCEPTOR_SYMBOL], clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL], @@ -532,9 +536,7 @@ export class Client { callProperties ) as CallProperties; } - const stream: ClientReadableStream = callProperties.call as ClientReadableStream< - ResponseType - >; + const stream: ClientReadableStream = callProperties.call as ClientReadableStream; const interceptorArgs: InterceptorArguments = { clientInterceptors: this[INTERCEPTOR_SYMBOL], clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL], @@ -659,7 +661,7 @@ export class Client { stream.emit('metadata', metadata); }, onReceiveMessage(message: Buffer) { - stream.push(message) + stream.push(message); }, onReceiveStatus(status: StatusObject) { if (receivedStatus) { @@ -676,4 +678,3 @@ export class Client { return stream; } } - diff --git a/packages/grpc-js/src/connectivity-state.ts b/packages/grpc-js/src/connectivity-state.ts index 8e1812274..560ab9c39 100644 --- a/packages/grpc-js/src/connectivity-state.ts +++ b/packages/grpc-js/src/connectivity-state.ts @@ -20,5 +20,5 @@ export enum ConnectivityState { CONNECTING, READY, TRANSIENT_FAILURE, - SHUTDOWN + SHUTDOWN, } diff --git a/packages/grpc-js/src/constants.ts b/packages/grpc-js/src/constants.ts index 94763cfe1..865b24c94 100644 --- a/packages/grpc-js/src/constants.ts +++ b/packages/grpc-js/src/constants.ts @@ -52,7 +52,11 @@ export enum Propagate { CENSUS_TRACING_CONTEXT = 4, CANCELLATION = 8, // https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/propagation_bits.h#L43 - DEFAULTS = 0xffff | Propagate.DEADLINE | Propagate.CENSUS_STATS_CONTEXT | Propagate.CENSUS_TRACING_CONTEXT | Propagate.CANCELLATION, + DEFAULTS = 0xffff | + Propagate.DEADLINE | + Propagate.CENSUS_STATS_CONTEXT | + Propagate.CENSUS_TRACING_CONTEXT | + Propagate.CANCELLATION, } // -1 means unlimited diff --git a/packages/grpc-js/src/deadline-filter.ts b/packages/grpc-js/src/deadline-filter.ts index afc015546..7bdd764f2 100644 --- a/packages/grpc-js/src/deadline-filter.ts +++ b/packages/grpc-js/src/deadline-filter.ts @@ -42,7 +42,7 @@ function getDeadline(deadline: number) { export class DeadlineFilter extends BaseFilter implements Filter { private timer: NodeJS.Timer | null = null; - private deadline: number = Infinity; + private deadline = Infinity; constructor( private readonly channel: Channel, private readonly callStream: Call @@ -66,7 +66,7 @@ export class DeadlineFilter extends BaseFilter implements Filter { clearTimeout(this.timer); } const now: number = new Date().getTime(); - let timeout = this.deadline - now; + const timeout = this.deadline - now; if (timeout <= 0) { process.nextTick(() => { this.callStream.cancelWithStatus( diff --git a/packages/grpc-js/src/experimental.ts b/packages/grpc-js/src/experimental.ts index 438ca71a8..24b795f06 100644 --- a/packages/grpc-js/src/experimental.ts +++ b/packages/grpc-js/src/experimental.ts @@ -1,12 +1,34 @@ -export { trace } from './logging'; -export { Resolver, ResolverListener, registerResolver, ConfigSelector } from './resolver'; -export { GrpcUri, uriToString } from './uri-parser'; -export { ServiceConfig, Duration } from './service-config'; -export { BackoffTimeout } from './backoff-timeout'; -export { LoadBalancer, LoadBalancingConfig, ChannelControlHelper, registerLoadBalancerType, getFirstUsableConfig, validateLoadBalancingConfig } from './load-balancer'; -export { SubchannelAddress, subchannelAddressToString } from './subchannel-address'; -export { ChildLoadBalancerHandler } from './load-balancer-child-handler'; -export { Picker, UnavailablePicker, QueuePicker, PickResult, PickArgs, PickResultType } from './picker'; -export { Call as CallStream } from './call-stream'; -export { Filter, BaseFilter, FilterFactory } from './filter'; -export { FilterStackFactory } from './filter-stack'; \ No newline at end of file +export { trace } from './logging'; +export { + Resolver, + ResolverListener, + registerResolver, + ConfigSelector, +} from './resolver'; +export { GrpcUri, uriToString } from './uri-parser'; +export { ServiceConfig, Duration } from './service-config'; +export { BackoffTimeout } from './backoff-timeout'; +export { + LoadBalancer, + LoadBalancingConfig, + ChannelControlHelper, + registerLoadBalancerType, + getFirstUsableConfig, + validateLoadBalancingConfig, +} from './load-balancer'; +export { + SubchannelAddress, + subchannelAddressToString, +} from './subchannel-address'; +export { ChildLoadBalancerHandler } from './load-balancer-child-handler'; +export { + Picker, + UnavailablePicker, + QueuePicker, + PickResult, + PickArgs, + PickResultType, +} from './picker'; +export { Call as CallStream } from './call-stream'; +export { Filter, BaseFilter, FilterFactory } from './filter'; +export { FilterStackFactory } from './filter-stack'; diff --git a/packages/grpc-js/src/filter.ts b/packages/grpc-js/src/filter.ts index eb67bd32e..8475a0a5a 100644 --- a/packages/grpc-js/src/filter.ts +++ b/packages/grpc-js/src/filter.ts @@ -57,8 +57,7 @@ export abstract class BaseFilter implements Filter { return status; } - refresh(): void { - } + refresh(): void {} } export interface FilterFactory { diff --git a/packages/grpc-js/src/http_proxy.ts b/packages/grpc-js/src/http_proxy.ts index d62be597c..149aa3648 100644 --- a/packages/grpc-js/src/http_proxy.ts +++ b/packages/grpc-js/src/http_proxy.ts @@ -25,8 +25,8 @@ import * as logging from './logging'; import { SubchannelAddress, isTcpSubchannelAddress, - subchannelAddressToString -} from "./subchannel-address"; + subchannelAddressToString, +} from './subchannel-address'; import { ChannelOptions } from './channel-options'; import { GrpcUri, parseUri, splitHostPort, uriToString } from './uri-parser'; import { URL } from 'url'; @@ -93,7 +93,7 @@ function getProxyInfo(): ProxyInfo { port = '80'; } const result: ProxyInfo = { - address: `${hostname}:${port}` + address: `${hostname}:${port}`, }; if (userCred) { result.creds = userCred; @@ -147,7 +147,9 @@ export function mapProxyName( const serverHost = hostPort.host; for (const host of getNoProxyHostList()) { if (host === serverHost) { - trace('Not using proxy for target in no_proxy list: ' + uriToString(target)); + trace( + 'Not using proxy for target in no_proxy list: ' + uriToString(target) + ); return noProxyResult; } } @@ -226,7 +228,7 @@ export function getProxiedConnection( const targetPath = getDefaultAuthority(parsedTarget); const hostPort = splitHostPort(targetPath); const remoteHost = hostPort?.host ?? targetPath; - + const cts = tls.connect( { host: remoteHost, diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index 52c122b12..0730a26eb 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -25,7 +25,7 @@ import { import { CallCredentials, OAuth2Client } from './call-credentials'; import { Deadline, StatusObject } from './call-stream'; import { Channel, ChannelImplementation } from './channel'; -import { ConnectivityState } from "./connectivity-state"; +import { ConnectivityState } from './connectivity-state'; import { ChannelCredentials } from './channel-credentials'; import { CallOptions, @@ -183,7 +183,12 @@ export { /**** Server ****/ -export { handleBidiStreamingCall, handleServerStreamingCall, handleUnaryCall, handleClientStreamingCall }; +export { + handleBidiStreamingCall, + handleServerStreamingCall, + handleUnaryCall, + handleClientStreamingCall, +}; /* eslint-disable @typescript-eslint/no-explicit-any */ export type Call = diff --git a/packages/grpc-js/src/load-balancer-child-handler.ts b/packages/grpc-js/src/load-balancer-child-handler.ts index 25cba4528..8fae7b8a6 100644 --- a/packages/grpc-js/src/load-balancer-child-handler.ts +++ b/packages/grpc-js/src/load-balancer-child-handler.ts @@ -19,12 +19,12 @@ import { LoadBalancer, ChannelControlHelper, LoadBalancingConfig, - createLoadBalancer + createLoadBalancer, } from './load-balancer'; import { Subchannel } from './subchannel'; -import { SubchannelAddress } from "./subchannel-address"; +import { SubchannelAddress } from './subchannel-address'; import { ChannelOptions } from './channel-options'; -import { ConnectivityState } from "./connectivity-state"; +import { ConnectivityState } from './connectivity-state'; import { Picker } from './picker'; const TYPE_NAME = 'child_load_balancer_helper'; diff --git a/packages/grpc-js/src/load-balancer-pick-first.ts b/packages/grpc-js/src/load-balancer-pick-first.ts index f7e9dd917..65179b163 100644 --- a/packages/grpc-js/src/load-balancer-pick-first.ts +++ b/packages/grpc-js/src/load-balancer-pick-first.ts @@ -19,10 +19,10 @@ import { LoadBalancer, ChannelControlHelper, LoadBalancingConfig, - registerDefaultLoadBalancerType, - registerLoadBalancerType + registerDefaultLoadBalancerType, + registerLoadBalancerType, } from './load-balancer'; -import { ConnectivityState } from "./connectivity-state"; +import { ConnectivityState } from './connectivity-state'; import { QueuePicker, Picker, @@ -31,14 +31,11 @@ import { PickResultType, UnavailablePicker, } from './picker'; -import { - Subchannel, - ConnectivityStateListener, -} from './subchannel'; +import { Subchannel, ConnectivityStateListener } from './subchannel'; import { SubchannelAddress, - subchannelAddressToString -} from "./subchannel-address"; + subchannelAddressToString, +} from './subchannel-address'; import * as logging from './logging'; import { LogVerbosity } from './constants'; @@ -65,10 +62,11 @@ export class PickFirstLoadBalancingConfig implements LoadBalancingConfig { toJsonObject(): object { return { - [TYPE_NAME]: {} + [TYPE_NAME]: {}, }; } + // eslint-disable-next-line @typescript-eslint/no-explicit-any static createFromJson(obj: any) { return new PickFirstLoadBalancingConfig(); } @@ -460,6 +458,10 @@ export class PickFirstLoadBalancer implements LoadBalancer { } export function setup(): void { - registerLoadBalancerType(TYPE_NAME, PickFirstLoadBalancer, PickFirstLoadBalancingConfig); + registerLoadBalancerType( + TYPE_NAME, + PickFirstLoadBalancer, + PickFirstLoadBalancingConfig + ); registerDefaultLoadBalancerType(TYPE_NAME); } diff --git a/packages/grpc-js/src/load-balancer-round-robin.ts b/packages/grpc-js/src/load-balancer-round-robin.ts index fabd334e3..56703397f 100644 --- a/packages/grpc-js/src/load-balancer-round-robin.ts +++ b/packages/grpc-js/src/load-balancer-round-robin.ts @@ -19,9 +19,9 @@ import { LoadBalancer, ChannelControlHelper, LoadBalancingConfig, - registerLoadBalancerType + registerLoadBalancerType, } from './load-balancer'; -import { ConnectivityState } from "./connectivity-state"; +import { ConnectivityState } from './connectivity-state'; import { QueuePicker, Picker, @@ -30,14 +30,11 @@ import { PickResultType, UnavailablePicker, } from './picker'; -import { - Subchannel, - ConnectivityStateListener, -} from './subchannel'; +import { Subchannel, ConnectivityStateListener } from './subchannel'; import { SubchannelAddress, - subchannelAddressToString -} from "./subchannel-address"; + subchannelAddressToString, +} from './subchannel-address'; import * as logging from './logging'; import { LogVerbosity } from './constants'; @@ -58,10 +55,11 @@ class RoundRobinLoadBalancingConfig implements LoadBalancingConfig { toJsonObject(): object { return { - [TYPE_NAME]: {} + [TYPE_NAME]: {}, }; } + // eslint-disable-next-line @typescript-eslint/no-explicit-any static createFromJson(obj: any) { return new RoundRobinLoadBalancingConfig(); } @@ -130,7 +128,7 @@ export class RoundRobinLoadBalancer implements LoadBalancer { this.subchannelStateCounts[previousState] -= 1; this.subchannelStateCounts[newState] += 1; this.calculateAndUpdateState(); - + if ( newState === ConnectivityState.TRANSIENT_FAILURE || newState === ConnectivityState.IDLE @@ -249,5 +247,9 @@ export class RoundRobinLoadBalancer implements LoadBalancer { } export function setup() { - registerLoadBalancerType(TYPE_NAME, RoundRobinLoadBalancer, RoundRobinLoadBalancingConfig); + registerLoadBalancerType( + TYPE_NAME, + RoundRobinLoadBalancer, + RoundRobinLoadBalancingConfig + ); } diff --git a/packages/grpc-js/src/load-balancer.ts b/packages/grpc-js/src/load-balancer.ts index 7fe0b9b3d..f509f73eb 100644 --- a/packages/grpc-js/src/load-balancer.ts +++ b/packages/grpc-js/src/load-balancer.ts @@ -17,8 +17,8 @@ import { ChannelOptions } from './channel-options'; import { Subchannel } from './subchannel'; -import { SubchannelAddress } from "./subchannel-address"; -import { ConnectivityState } from "./connectivity-state"; +import { SubchannelAddress } from './subchannel-address'; +import { ConnectivityState } from './connectivity-state'; import { Picker } from './picker'; /** @@ -101,7 +101,9 @@ export interface LoadBalancingConfig { } export interface LoadBalancingConfigConstructor { - new(...args: any): LoadBalancingConfig; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + new (...args: any): LoadBalancingConfig; + // eslint-disable-next-line @typescript-eslint/no-explicit-any createFromJson(obj: any): LoadBalancingConfig; } @@ -121,7 +123,7 @@ export function registerLoadBalancerType( ) { registeredLoadBalancerTypes[typeName] = { LoadBalancer: loadBalancerType, - LoadBalancingConfig: loadBalancingConfigType + LoadBalancingConfig: loadBalancingConfigType, }; } @@ -135,7 +137,9 @@ export function createLoadBalancer( ): LoadBalancer | null { const typeName = config.getLoadBalancerName(); if (typeName in registeredLoadBalancerTypes) { - return new registeredLoadBalancerTypes[typeName].LoadBalancer(channelControlHelper); + return new registeredLoadBalancerTypes[typeName].LoadBalancer( + channelControlHelper + ); } else { return null; } @@ -145,10 +149,13 @@ export function isLoadBalancerNameRegistered(typeName: string): boolean { return typeName in registeredLoadBalancerTypes; } -export function getFirstUsableConfig(configs: LoadBalancingConfig[], fallbackTodefault?: true): LoadBalancingConfig; export function getFirstUsableConfig( configs: LoadBalancingConfig[], - fallbackTodefault: boolean = false + fallbackTodefault?: true +): LoadBalancingConfig; +export function getFirstUsableConfig( + configs: LoadBalancingConfig[], + fallbackTodefault = false ): LoadBalancingConfig | null { for (const config of configs) { if (config.getLoadBalancerName() in registeredLoadBalancerTypes) { @@ -157,7 +164,9 @@ export function getFirstUsableConfig( } if (fallbackTodefault) { if (defaultLoadBalancerType) { - return new registeredLoadBalancerTypes[defaultLoadBalancerType]!.LoadBalancingConfig(); + return new registeredLoadBalancerTypes[ + defaultLoadBalancerType + ]!.LoadBalancingConfig(); } else { return null; } @@ -166,17 +175,22 @@ export function getFirstUsableConfig( } } +// eslint-disable-next-line @typescript-eslint/no-explicit-any export function validateLoadBalancingConfig(obj: any): LoadBalancingConfig { - if (!(obj !== null && (typeof obj === 'object'))) { + if (!(obj !== null && typeof obj === 'object')) { throw new Error('Load balancing config must be an object'); } const keys = Object.keys(obj); if (keys.length !== 1) { - throw new Error('Provided load balancing config has multiple conflicting entries'); + throw new Error( + 'Provided load balancing config has multiple conflicting entries' + ); } const typeName = keys[0]; if (typeName in registeredLoadBalancerTypes) { - return registeredLoadBalancerTypes[typeName].LoadBalancingConfig.createFromJson(obj[typeName]); + return registeredLoadBalancerTypes[ + typeName + ].LoadBalancingConfig.createFromJson(obj[typeName]); } else { throw new Error(`Unrecognized load balancing config name ${typeName}`); } diff --git a/packages/grpc-js/src/logging.ts b/packages/grpc-js/src/logging.ts index 71683dbf7..352496240 100644 --- a/packages/grpc-js/src/logging.ts +++ b/packages/grpc-js/src/logging.ts @@ -20,7 +20,8 @@ import { LogVerbosity } from './constants'; let _logger: Partial = console; let _logVerbosity: LogVerbosity = LogVerbosity.ERROR; -const verbosityString = process.env.GRPC_NODE_VERBOSITY ?? process.env.GRPC_VERBOSITY ?? ''; +const verbosityString = + process.env.GRPC_NODE_VERBOSITY ?? process.env.GRPC_VERBOSITY ?? ''; switch (verbosityString.toUpperCase()) { case 'DEBUG': @@ -58,14 +59,15 @@ export const log = (severity: LogVerbosity, ...args: any[]): void => { } }; -const tracersString = process.env.GRPC_NODE_TRACE ?? process.env.GRPC_TRACE ?? ''; +const tracersString = + process.env.GRPC_NODE_TRACE ?? process.env.GRPC_TRACE ?? ''; const enabledTracers = new Set(); const disabledTracers = new Set(); for (const tracerName of tracersString.split(',')) { if (tracerName.startsWith('-')) { disabledTracers.add(tracerName.substring(1)); } else { - enabledTracers.add(tracerName) + enabledTracers.add(tracerName); } } const allEnabled = enabledTracers.has('all'); @@ -75,7 +77,10 @@ export function trace( tracer: string, text: string ): void { - if (!disabledTracers.has(tracer) && (allEnabled || enabledTracers.has(tracer))) { + if ( + !disabledTracers.has(tracer) && + (allEnabled || enabledTracers.has(tracer)) + ) { log(severity, new Date().toISOString() + ' | ' + tracer + ' | ' + text); } } diff --git a/packages/grpc-js/src/make-client.ts b/packages/grpc-js/src/make-client.ts index a6cb91007..b8ddda29f 100644 --- a/packages/grpc-js/src/make-client.ts +++ b/packages/grpc-js/src/make-client.ts @@ -98,7 +98,7 @@ export interface ServiceClientConstructor { * keys. * @param key key for check, string. */ -function isPrototypePolluted(key: string): Boolean { +function isPrototypePolluted(key: string): boolean { return ['__proto__', 'prototype', 'constructor'].includes(key); } diff --git a/packages/grpc-js/src/max-message-size-filter.ts b/packages/grpc-js/src/max-message-size-filter.ts index f820c02e6..9a3bc9c0a 100644 --- a/packages/grpc-js/src/max-message-size-filter.ts +++ b/packages/grpc-js/src/max-message-size-filter.ts @@ -15,10 +15,14 @@ * */ -import { BaseFilter, Filter, FilterFactory } from "./filter"; -import { Call, WriteObject } from "./call-stream"; -import { Status, DEFAULT_MAX_SEND_MESSAGE_LENGTH, DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH } from "./constants"; -import { ChannelOptions } from "./channel-options"; +import { BaseFilter, Filter, FilterFactory } from './filter'; +import { Call, WriteObject } from './call-stream'; +import { + Status, + DEFAULT_MAX_SEND_MESSAGE_LENGTH, + DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH, +} from './constants'; +import { ChannelOptions } from './channel-options'; export class MaxMessageSizeFilter extends BaseFilter implements Filter { private maxSendMessageSize: number = DEFAULT_MAX_SEND_MESSAGE_LENGTH; @@ -44,7 +48,10 @@ export class MaxMessageSizeFilter extends BaseFilter implements Filter { } else { const concreteMessage = await message; if (concreteMessage.message.length > this.maxSendMessageSize) { - this.callStream.cancelWithStatus(Status.RESOURCE_EXHAUSTED, `Sent message larger than max (${concreteMessage.message.length} vs. ${this.maxSendMessageSize})`); + this.callStream.cancelWithStatus( + Status.RESOURCE_EXHAUSTED, + `Sent message larger than max (${concreteMessage.message.length} vs. ${this.maxSendMessageSize})` + ); return Promise.reject('Message too large'); } else { return concreteMessage; @@ -60,7 +67,10 @@ export class MaxMessageSizeFilter extends BaseFilter implements Filter { } else { const concreteMessage = await message; if (concreteMessage.length > this.maxReceiveMessageSize) { - this.callStream.cancelWithStatus(Status.RESOURCE_EXHAUSTED, `Received message larger than max (${concreteMessage.length} vs. ${this.maxReceiveMessageSize})`); + this.callStream.cancelWithStatus( + Status.RESOURCE_EXHAUSTED, + `Received message larger than max (${concreteMessage.length} vs. ${this.maxReceiveMessageSize})` + ); return Promise.reject('Message too large'); } else { return concreteMessage; @@ -69,7 +79,8 @@ export class MaxMessageSizeFilter extends BaseFilter implements Filter { } } -export class MaxMessageSizeFilterFactory implements FilterFactory { +export class MaxMessageSizeFilterFactory + implements FilterFactory { constructor(private readonly options: ChannelOptions) {} createFilter(callStream: Call): MaxMessageSizeFilter { diff --git a/packages/grpc-js/src/metadata.ts b/packages/grpc-js/src/metadata.ts index bc66012ce..04db642ef 100644 --- a/packages/grpc-js/src/metadata.ts +++ b/packages/grpc-js/src/metadata.ts @@ -247,7 +247,7 @@ export class Metadata { * representation of the metadata map. */ toJSON() { - const result: {[key: string]: MetadataValue[]} = {}; + const result: { [key: string]: MetadataValue[] } = {}; for (const [key, values] of this.internalRepr.entries()) { result[key] = values; } diff --git a/packages/grpc-js/src/picker.ts b/packages/grpc-js/src/picker.ts index 25929884b..7aeed89b3 100644 --- a/packages/grpc-js/src/picker.ts +++ b/packages/grpc-js/src/picker.ts @@ -85,7 +85,7 @@ export interface DropCallPickResult extends PickResult { export interface PickArgs { metadata: Metadata; - extraPickInfo: {[key: string]: string}; + extraPickInfo: { [key: string]: string }; } /** diff --git a/packages/grpc-js/src/resolver-dns.ts b/packages/grpc-js/src/resolver-dns.ts index 44246c779..9077228b8 100644 --- a/packages/grpc-js/src/resolver-dns.ts +++ b/packages/grpc-js/src/resolver-dns.ts @@ -28,7 +28,7 @@ import { StatusObject } from './call-stream'; import { Metadata } from './metadata'; import * as logging from './logging'; import { LogVerbosity } from './constants'; -import { SubchannelAddress, TcpSubchannelAddress } from "./subchannel-address"; +import { SubchannelAddress, TcpSubchannelAddress } from './subchannel-address'; import { GrpcUri, uriToString, splitHostPort } from './uri-parser'; import { isIPv6, isIPv4 } from 'net'; import { ChannelOptions } from './channel-options'; @@ -129,7 +129,13 @@ class DnsResolver implements Resolver { if (this.ipResult !== null) { trace('Returning IP address for target ' + uriToString(this.target)); setImmediate(() => { - this.listener.onSuccessfulResolution(this.ipResult!, null, null, null, {}); + this.listener.onSuccessfulResolution( + this.ipResult!, + null, + null, + null, + {} + ); }); return; } diff --git a/packages/grpc-js/src/resolver-ip.ts b/packages/grpc-js/src/resolver-ip.ts index 18bbe54aa..24efc3fdc 100644 --- a/packages/grpc-js/src/resolver-ip.ts +++ b/packages/grpc-js/src/resolver-ip.ts @@ -14,14 +14,14 @@ * limitations under the License. */ -import { isIPv4, isIPv6 } from "net"; -import { StatusObject } from "./call-stream"; -import { ChannelOptions } from "./channel-options"; -import { LogVerbosity, Status } from "./constants"; -import { Metadata } from "./metadata"; -import { registerResolver, Resolver, ResolverListener } from "./resolver"; -import { SubchannelAddress } from "./subchannel-address"; -import { GrpcUri, splitHostPort, uriToString } from "./uri-parser"; +import { isIPv4, isIPv6 } from 'net'; +import { StatusObject } from './call-stream'; +import { ChannelOptions } from './channel-options'; +import { LogVerbosity, Status } from './constants'; +import { Metadata } from './metadata'; +import { registerResolver, Resolver, ResolverListener } from './resolver'; +import { SubchannelAddress } from './subchannel-address'; +import { GrpcUri, splitHostPort, uriToString } from './uri-parser'; import * as logging from './logging'; const TRACER_NAME = 'ip_resolver'; @@ -52,7 +52,7 @@ class IpResolver implements Resolver { this.error = { code: Status.UNAVAILABLE, details: `Unrecognized scheme ${target.scheme} in IP resolver`, - metadata: new Metadata() + metadata: new Metadata(), }; return; } @@ -63,21 +63,24 @@ class IpResolver implements Resolver { this.error = { code: Status.UNAVAILABLE, details: `Failed to parse ${target.scheme} address ${path}`, - metadata: new Metadata() + metadata: new Metadata(), }; return; } - if ((target.scheme === IPV4_SCHEME && !isIPv4(hostPort.host)) || (target.scheme === IPV6_SCHEME && !isIPv6(hostPort.host))) { + if ( + (target.scheme === IPV4_SCHEME && !isIPv4(hostPort.host)) || + (target.scheme === IPV6_SCHEME && !isIPv6(hostPort.host)) + ) { this.error = { code: Status.UNAVAILABLE, details: `Failed to parse ${target.scheme} address ${path}`, - metadata: new Metadata() + metadata: new Metadata(), }; return; } addresses.push({ host: hostPort.host, - port: hostPort.port ?? DEFAULT_PORT + port: hostPort.port ?? DEFAULT_PORT, }); } this.addresses = addresses; @@ -86,9 +89,15 @@ class IpResolver implements Resolver { updateResolution(): void { process.nextTick(() => { if (this.error) { - this.listener.onError(this.error) + this.listener.onError(this.error); } else { - this.listener.onSuccessfulResolution(this.addresses, null, null, null, {}); + this.listener.onSuccessfulResolution( + this.addresses, + null, + null, + null, + {} + ); } }); } @@ -104,4 +113,4 @@ class IpResolver implements Resolver { export function setup() { registerResolver(IPV4_SCHEME, IpResolver); registerResolver(IPV6_SCHEME, IpResolver); -} \ No newline at end of file +} diff --git a/packages/grpc-js/src/resolver-uds.ts b/packages/grpc-js/src/resolver-uds.ts index 1c5a7a64c..24095ec29 100644 --- a/packages/grpc-js/src/resolver-uds.ts +++ b/packages/grpc-js/src/resolver-uds.ts @@ -15,7 +15,7 @@ */ import { Resolver, ResolverListener, registerResolver } from './resolver'; -import { SubchannelAddress } from "./subchannel-address"; +import { SubchannelAddress } from './subchannel-address'; import { GrpcUri } from './uri-parser'; import { ChannelOptions } from './channel-options'; diff --git a/packages/grpc-js/src/resolver.ts b/packages/grpc-js/src/resolver.ts index 5bf7df2e7..59c5400f1 100644 --- a/packages/grpc-js/src/resolver.ts +++ b/packages/grpc-js/src/resolver.ts @@ -17,7 +17,7 @@ import { MethodConfig, ServiceConfig } from './service-config'; import { StatusObject } from './call-stream'; -import { SubchannelAddress } from "./subchannel-address"; +import { SubchannelAddress } from './subchannel-address'; import { GrpcUri, uriToString } from './uri-parser'; import { ChannelOptions } from './channel-options'; import { Metadata } from './metadata'; @@ -26,7 +26,7 @@ import { Status } from './constants'; export interface CallConfig { methodConfig: MethodConfig; onCommitted?: () => void; - pickInformation: {[key: string]: string}; + pickInformation: { [key: string]: string }; status: Status; } @@ -78,7 +78,7 @@ export interface Resolver { * called synchronously with the constructor or updateResolution. */ updateResolution(): void; - + /** * Destroy the resolver. Should be called when the owning channel shuts down. */ diff --git a/packages/grpc-js/src/resolving-load-balancer.ts b/packages/grpc-js/src/resolving-load-balancer.ts index 9825086c1..5729937d1 100644 --- a/packages/grpc-js/src/resolving-load-balancer.ts +++ b/packages/grpc-js/src/resolving-load-balancer.ts @@ -19,10 +19,10 @@ import { ChannelControlHelper, LoadBalancer, LoadBalancingConfig, - getFirstUsableConfig + getFirstUsableConfig, } from './load-balancer'; import { ServiceConfig, validateServiceConfig } from './service-config'; -import { ConnectivityState } from "./connectivity-state"; +import { ConnectivityState } from './connectivity-state'; import { ConfigSelector, createResolver, Resolver } from './resolver'; import { ServiceError } from './call'; import { Picker, UnavailablePicker, QueuePicker } from './picker'; @@ -32,7 +32,7 @@ import { StatusObject } from './call-stream'; import { Metadata } from './metadata'; import * as logging from './logging'; import { LogVerbosity } from './constants'; -import { SubchannelAddress } from "./subchannel-address"; +import { SubchannelAddress } from './subchannel-address'; import { GrpcUri, uriToString } from './uri-parser'; import { ChildLoadBalancerHandler } from './load-balancer-child-handler'; import { ChannelOptions } from './channel-options'; @@ -46,30 +46,38 @@ function trace(text: string): void { const DEFAULT_LOAD_BALANCER_NAME = 'pick_first'; -function getDefaultConfigSelector(serviceConfig: ServiceConfig | null): ConfigSelector { - return function defaultConfigSelector(methodName: string, metadata: Metadata) { - const splitName = methodName.split('/').filter(x => x.length > 0); +function getDefaultConfigSelector( + serviceConfig: ServiceConfig | null +): ConfigSelector { + return function defaultConfigSelector( + methodName: string, + metadata: Metadata + ) { + const splitName = methodName.split('/').filter((x) => x.length > 0); const service = splitName[0] ?? ''; const method = splitName[1] ?? ''; if (serviceConfig && serviceConfig.methodConfig) { for (const methodConfig of serviceConfig.methodConfig) { for (const name of methodConfig.name) { - if (name.service === service && (name.method === undefined || name.method === method)) { + if ( + name.service === service && + (name.method === undefined || name.method === method) + ) { return { methodConfig: methodConfig, pickInformation: {}, - status: Status.OK + status: Status.OK, }; } } } } return { - methodConfig: {name: []}, + methodConfig: { name: [] }, pickInformation: {}, - status: Status.OK + status: Status.OK, }; - } + }; } export interface ResolutionCallback { @@ -201,7 +209,10 @@ export class ResolvingLoadBalancer implements LoadBalancer { } const workingConfigList = workingServiceConfig?.loadBalancingConfig ?? []; - const loadBalancingConfig = getFirstUsableConfig(workingConfigList, true); + const loadBalancingConfig = getFirstUsableConfig( + workingConfigList, + true + ); if (loadBalancingConfig === null) { // There were load balancing configs but none are supported. This counts as a resolution failure this.handleResolutionFailure({ @@ -217,8 +228,11 @@ export class ResolvingLoadBalancer implements LoadBalancer { loadBalancingConfig, attributes ); - const finalServiceConfig = workingServiceConfig ?? this.defaultServiceConfig; - this.onSuccessfulResolution(configSelector ?? getDefaultConfigSelector(finalServiceConfig)); + const finalServiceConfig = + workingServiceConfig ?? this.defaultServiceConfig; + this.onSuccessfulResolution( + configSelector ?? getDefaultConfigSelector(finalServiceConfig) + ); }, onError: (error: StatusObject) => { this.handleResolutionFailure(error); diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index aa8bd647e..4d24cdc86 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -100,7 +100,8 @@ export type ServerDuplexStream = ServerSurfaceCall & ObjectReadable & ObjectWritable & { end: (metadata?: Metadata) => void }; -export class ServerUnaryCallImpl extends EventEmitter +export class ServerUnaryCallImpl + extends EventEmitter implements ServerUnaryCall { cancelled: boolean; @@ -239,7 +240,8 @@ export class ServerWritableStreamImpl } } -export class ServerDuplexStreamImpl extends Duplex +export class ServerDuplexStreamImpl + extends Duplex implements ServerDuplexStream { cancelled: boolean; private trailingMetadata: Metadata; diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index aec149556..017312219 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -55,8 +55,8 @@ import { SubchannelAddress, TcpSubchannelAddress, isTcpSubchannelAddress, - subchannelAddressToString -} from "./subchannel-address"; + subchannelAddressToString, +} from './subchannel-address'; import { parseUri } from './uri-parser'; const TRACER_NAME = 'server'; @@ -209,10 +209,7 @@ export class Server { } removeService(service: ServiceDefinition): void { - if ( - service === null || - typeof service !== 'object' - ) { + if (service === null || typeof service !== 'object') { throw new Error('removeService() requires object as argument'); } @@ -258,10 +255,12 @@ export class Server { } const serverOptions: http2.ServerOptions = { - maxSendHeaderBlockLength: Number.MAX_SAFE_INTEGER + maxSendHeaderBlockLength: Number.MAX_SAFE_INTEGER, }; if ('grpc-node.max_session_memory' in this.options) { - serverOptions.maxSessionMemory = this.options['grpc-node.max_session_memory']; + serverOptions.maxSessionMemory = this.options[ + 'grpc-node.max_session_memory' + ]; } if ('grpc.max_concurrent_streams' in this.options) { serverOptions.settings = { diff --git a/packages/grpc-js/src/service-config.ts b/packages/grpc-js/src/service-config.ts index efc09f9c4..3f0a00868 100644 --- a/packages/grpc-js/src/service-config.ts +++ b/packages/grpc-js/src/service-config.ts @@ -27,7 +27,10 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import * as os from 'os'; -import { LoadBalancingConfig, validateLoadBalancingConfig } from './load-balancer'; +import { + LoadBalancingConfig, + validateLoadBalancingConfig, +} from './load-balancer'; export interface MethodConfigName { service: string; @@ -107,21 +110,30 @@ function validateMethodConfig(obj: any): MethodConfig { } if ('timeout' in obj) { if (typeof obj.timeout === 'object') { - if (!('seconds' in obj.timeout) || !(typeof obj.timeout.seconds === 'number')) { + if ( + !('seconds' in obj.timeout) || + !(typeof obj.timeout.seconds === 'number') + ) { throw new Error('Invalid method config: invalid timeout.seconds'); } - if (!('nanos' in obj.timeout) || !(typeof obj.timeout.nanos === 'number')) { + if ( + !('nanos' in obj.timeout) || + !(typeof obj.timeout.nanos === 'number') + ) { throw new Error('Invalid method config: invalid timeout.nanos'); } result.timeout = obj.timeout; } else if ( - (typeof obj.timeout === 'string') && TIMEOUT_REGEX.test(obj.timeout) + typeof obj.timeout === 'string' && + TIMEOUT_REGEX.test(obj.timeout) ) { - const timeoutParts = obj.timeout.substring(0, obj.timeout.length - 1).split('.'); + const timeoutParts = obj.timeout + .substring(0, obj.timeout.length - 1) + .split('.'); result.timeout = { seconds: timeoutParts[0] | 0, - nanos: (timeoutParts[1] ?? 0) | 0 - } + nanos: (timeoutParts[1] ?? 0) | 0, + }; } else { throw new Error('Invalid method config: invalid timeout'); } diff --git a/packages/grpc-js/src/subchannel-pool.ts b/packages/grpc-js/src/subchannel-pool.ts index 65c5f2177..cd74cad81 100644 --- a/packages/grpc-js/src/subchannel-pool.ts +++ b/packages/grpc-js/src/subchannel-pool.ts @@ -16,13 +16,11 @@ */ import { ChannelOptions, channelOptionsEqual } from './channel-options'; -import { - Subchannel, -} from './subchannel'; +import { Subchannel } from './subchannel'; import { SubchannelAddress, - subchannelAddressEqual -} from "./subchannel-address"; + subchannelAddressEqual, +} from './subchannel-address'; import { ChannelCredentials } from './channel-credentials'; import { GrpcUri, uriToString } from './uri-parser'; diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 7d3e6e871..ae23feb3d 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -21,7 +21,7 @@ import { Metadata } from './metadata'; import { Http2CallStream } from './call-stream'; import { ChannelOptions } from './channel-options'; import { PeerCertificate, checkServerIdentity } from 'tls'; -import { ConnectivityState } from "./connectivity-state"; +import { ConnectivityState } from './connectivity-state'; import { BackoffTimeout, BackoffOptions } from './backoff-timeout'; import { getDefaultAuthority } from './resolver'; import * as logging from './logging'; @@ -31,7 +31,10 @@ import * as net from 'net'; import { GrpcUri, parseUri, splitHostPort, uriToString } from './uri-parser'; import { ConnectionOptions } from 'tls'; import { FilterFactory, Filter } from './filter'; -import { SubchannelAddress, subchannelAddressToString } from './subchannel-address'; +import { + SubchannelAddress, + subchannelAddressToString, +} from './subchannel-address'; const clientVersion = require('../../package.json').version; @@ -138,7 +141,7 @@ export class Subchannel { /** * Indicates whether keepalive pings should be sent without any active calls */ - private keepaliveWithoutCalls: boolean = false; + private keepaliveWithoutCalls = false; /** * Tracks calls with references to this subchannel @@ -186,7 +189,8 @@ export class Subchannel { this.keepaliveTimeoutMs = options['grpc.keepalive_timeout_ms']!; } if ('grpc.keepalive_permit_without_calls' in options) { - this.keepaliveWithoutCalls = options['grpc.keepalive_permit_without_calls'] === 1; + this.keepaliveWithoutCalls = + options['grpc.keepalive_permit_without_calls'] === 1; } else { this.keepaliveWithoutCalls = false; } @@ -231,7 +235,11 @@ export class Subchannel { } private sendPing() { - logging.trace(LogVerbosity.DEBUG, 'keepalive', 'Sending ping to ' + this.subchannelAddressString); + logging.trace( + LogVerbosity.DEBUG, + 'keepalive', + 'Sending ping to ' + this.subchannelAddressString + ); this.keepaliveTimeoutId = setTimeout(() => { this.transitionToState([ConnectivityState.READY], ConnectivityState.IDLE); }, this.keepaliveTimeoutMs); @@ -247,7 +255,7 @@ export class Subchannel { this.keepaliveIntervalId = setInterval(() => { this.sendPing(); }, this.keepaliveTimeMs); - this.keepaliveIntervalId.unref?.() + this.keepaliveIntervalId.unref?.(); /* Don't send a ping immediately because whatever caused us to start * sending pings should also involve some network activity. */ } @@ -265,7 +273,9 @@ export class Subchannel { this.credentials._getConnectionOptions() || {}; connectionOptions.maxSendHeaderBlockLength = Number.MAX_SAFE_INTEGER; if ('grpc-node.max_session_memory' in this.options) { - connectionOptions.maxSessionMemory = this.options['grpc-node.max_session_memory']; + connectionOptions.maxSessionMemory = this.options[ + 'grpc-node.max_session_memory' + ]; } let addressScheme = 'http://'; if ('secureContext' in connectionOptions) { @@ -387,7 +397,11 @@ export class Subchannel { ); logging.log( LogVerbosity.ERROR, - `Connection to ${uriToString(this.channelTarget)} at ${this.subchannelAddressString} rejected by server because of excess pings. Increasing ping interval to ${this.keepaliveTimeMs} ms` + `Connection to ${uriToString(this.channelTarget)} at ${ + this.subchannelAddressString + } rejected by server because of excess pings. Increasing ping interval to ${ + this.keepaliveTimeMs + } ms` ); } trace( @@ -553,10 +567,7 @@ export class Subchannel { * this subchannel, we can be sure it will never be used again. */ if (this.callRefcount === 0 && this.refcount === 0) { this.transitionToState( - [ - ConnectivityState.CONNECTING, - ConnectivityState.READY, - ], + [ConnectivityState.CONNECTING, ConnectivityState.READY], ConnectivityState.TRANSIENT_FAILURE ); } @@ -675,7 +686,14 @@ export class Subchannel { for (const header of Object.keys(headers)) { headersString += '\t\t' + header + ': ' + headers[header] + '\n'; } - logging.trace(LogVerbosity.DEBUG, 'call_stream', 'Starting stream on subchannel ' + this.subchannelAddressString + ' with headers\n' + headersString); + logging.trace( + LogVerbosity.DEBUG, + 'call_stream', + 'Starting stream on subchannel ' + + this.subchannelAddressString + + ' with headers\n' + + headersString + ); callStream.attachHttp2Stream(http2Stream, this, extraFilterFactories); } From 728acf3853723642e6f3edf944ee3072e393e43e Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 30 Jun 2021 14:52:55 -0700 Subject: [PATCH 036/450] grpc-js-xds: Increase interop test timeout --- test/kokoro/xds-interop.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/kokoro/xds-interop.cfg b/test/kokoro/xds-interop.cfg index 16a7dc7dc..a615d0530 100644 --- a/test/kokoro/xds-interop.cfg +++ b/test/kokoro/xds-interop.cfg @@ -16,7 +16,7 @@ # Location of the continuous shell script in repository. build_file: "grpc-node/packages/grpc-js-xds/scripts/xds.sh" -timeout_mins: 120 +timeout_mins: 180 action { define_artifacts { regex: "github/grpc/reports/**" From 972281770fd288330939764c7d4a5c6f39c28180 Mon Sep 17 00:00:00 2001 From: Eric Gribkoff Date: Thu, 1 Jul 2021 05:14:50 -0700 Subject: [PATCH 037/450] Increase xDS job timeouts to match Java and Go --- test/kokoro/xds-interop.cfg | 2 +- test/kokoro/xds-v3-interop.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/kokoro/xds-interop.cfg b/test/kokoro/xds-interop.cfg index a615d0530..866cb4b58 100644 --- a/test/kokoro/xds-interop.cfg +++ b/test/kokoro/xds-interop.cfg @@ -16,7 +16,7 @@ # Location of the continuous shell script in repository. build_file: "grpc-node/packages/grpc-js-xds/scripts/xds.sh" -timeout_mins: 180 +timeout_mins: 360 action { define_artifacts { regex: "github/grpc/reports/**" diff --git a/test/kokoro/xds-v3-interop.cfg b/test/kokoro/xds-v3-interop.cfg index 4480f1590..75377fe16 100644 --- a/test/kokoro/xds-v3-interop.cfg +++ b/test/kokoro/xds-v3-interop.cfg @@ -16,7 +16,7 @@ # Location of the continuous shell script in repository. build_file: "grpc-node/packages/grpc-js-xds/scripts/xds-v3.sh" -timeout_mins: 180 +timeout_mins: 360 action { define_artifacts { regex: "github/grpc/reports/**" From 6b3ebbb82921e1e42d8a0974a7e900ff606a66cc Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 8 Jul 2021 10:27:31 -0700 Subject: [PATCH 038/450] grpc-js: Add logging for TLS over proxy connection errors --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/http_proxy.ts | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 8acb8a145..97d7e2758 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.3.4", + "version": "1.3.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/http_proxy.ts b/packages/grpc-js/src/http_proxy.ts index f6921378b..8c461d4f8 100644 --- a/packages/grpc-js/src/http_proxy.ts +++ b/packages/grpc-js/src/http_proxy.ts @@ -244,7 +244,13 @@ export function getProxiedConnection( resolve({ socket: cts, realTarget: parsedTarget }); } ); - cts.on('error', () => { + cts.on('error', (error: Error) => { + trace('Failed to establish a TLS connection to ' + + options.path + + ' through proxy ' + + proxyAddressString + + ' with error ' + + error.message); reject(); }); } else { From 194aeec0513786cba009d0fc910ccba828ecca34 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 8 Jul 2021 10:32:12 -0700 Subject: [PATCH 039/450] grpc-js-xds: Increase interop test timeout to 6 hours --- test/kokoro/xds-interop.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/kokoro/xds-interop.cfg b/test/kokoro/xds-interop.cfg index 16a7dc7dc..866cb4b58 100644 --- a/test/kokoro/xds-interop.cfg +++ b/test/kokoro/xds-interop.cfg @@ -16,7 +16,7 @@ # Location of the continuous shell script in repository. build_file: "grpc-node/packages/grpc-js-xds/scripts/xds.sh" -timeout_mins: 120 +timeout_mins: 360 action { define_artifacts { regex: "github/grpc/reports/**" From 311aca31e411da18e542686665aa14711aa7ec3e Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 17 Jun 2021 09:45:19 -0700 Subject: [PATCH 040/450] grpc-js-xds: Add HTTP Filters support --- packages/grpc-js-xds/package.json | 2 +- packages/grpc-js-xds/src/environment.ts | 4 +- .../generated/google/protobuf/EnumOptions.ts | 3 - .../google/protobuf/EnumValueOptions.ts | 5 - .../generated/google/protobuf/FieldOptions.ts | 10 - .../generated/google/protobuf/FileOptions.ts | 6 - .../google/protobuf/MessageOptions.ts | 6 - .../grpc-js-xds/src/generated/typed_struct.ts | 74 ++++++ .../src/generated/udpa/type/v1/TypedStruct.ts | 77 ++++++ packages/grpc-js-xds/src/http-filter.ts | 221 ++++++++++++++++++ packages/grpc-js-xds/src/protobuf-any.ts | 23 ++ packages/grpc-js-xds/src/resolver-xds.ts | 139 ++++++++++- packages/grpc-js-xds/src/route-action.ts | 27 ++- .../src/xds-stream-state/lds-state.ts | 9 + .../src/xds-stream-state/rds-state.ts | 25 ++ packages/grpc-js/src/call-stream.ts | 4 + packages/grpc-js/src/channel.ts | 1 + packages/grpc-js/src/resolver.ts | 2 + .../grpc-js/src/resolving-load-balancer.ts | 6 +- 19 files changed, 596 insertions(+), 48 deletions(-) create mode 100644 packages/grpc-js-xds/src/generated/typed_struct.ts create mode 100644 packages/grpc-js-xds/src/generated/udpa/type/v1/TypedStruct.ts create mode 100644 packages/grpc-js-xds/src/http-filter.ts create mode 100644 packages/grpc-js-xds/src/protobuf-any.ts diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index f69c8bf49..8b6005d5c 100644 --- a/packages/grpc-js-xds/package.json +++ b/packages/grpc-js-xds/package.json @@ -12,7 +12,7 @@ "prepare": "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/udpa/ deps/googleapis/ deps/protoc-gen-validate/ -O src/generated/ --grpcLib @grpc/grpc-js envoy/service/discovery/v2/ads.proto envoy/service/load_stats/v2/lrs.proto 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", + "generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs deps/envoy-api/ deps/udpa/ deps/googleapis/ deps/protoc-gen-validate/ -O src/generated/ --grpcLib @grpc/grpc-js envoy/service/discovery/v2/ads.proto envoy/service/load_stats/v2/lrs.proto 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", "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" }, "repository": { diff --git a/packages/grpc-js-xds/src/environment.ts b/packages/grpc-js-xds/src/environment.ts index c2c7f2e05..18e9e70bd 100644 --- a/packages/grpc-js-xds/src/environment.ts +++ b/packages/grpc-js-xds/src/environment.ts @@ -13,4 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. * - */ \ No newline at end of file + */ + +export const EXPERIMENTAL_FAULT_INJECTION = process.env.GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION; \ No newline at end of file diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/EnumOptions.ts b/packages/grpc-js-xds/src/generated/google/protobuf/EnumOptions.ts index b92f699a0..b92ade4f9 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/EnumOptions.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/EnumOptions.ts @@ -1,18 +1,15 @@ // Original file: null import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; -import type { MigrateAnnotation as _udpa_annotations_MigrateAnnotation, MigrateAnnotation__Output as _udpa_annotations_MigrateAnnotation__Output } from '../../udpa/annotations/MigrateAnnotation'; export interface EnumOptions { 'allowAlias'?: (boolean); 'deprecated'?: (boolean); 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; - '.udpa.annotations.enum_migrate'?: (_udpa_annotations_MigrateAnnotation); } export interface EnumOptions__Output { 'allowAlias': (boolean); 'deprecated': (boolean); 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; - '.udpa.annotations.enum_migrate'?: (_udpa_annotations_MigrateAnnotation__Output); } diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/EnumValueOptions.ts b/packages/grpc-js-xds/src/generated/google/protobuf/EnumValueOptions.ts index db2770534..e60ee6f4c 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/EnumValueOptions.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/EnumValueOptions.ts @@ -1,18 +1,13 @@ // Original file: null import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; -import type { MigrateAnnotation as _udpa_annotations_MigrateAnnotation, MigrateAnnotation__Output as _udpa_annotations_MigrateAnnotation__Output } from '../../udpa/annotations/MigrateAnnotation'; export interface EnumValueOptions { 'deprecated'?: (boolean); 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; - '.envoy.annotations.disallowed_by_default_enum'?: (boolean); - '.udpa.annotations.enum_value_migrate'?: (_udpa_annotations_MigrateAnnotation); } export interface EnumValueOptions__Output { 'deprecated': (boolean); 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; - '.envoy.annotations.disallowed_by_default_enum': (boolean); - '.udpa.annotations.enum_value_migrate'?: (_udpa_annotations_MigrateAnnotation__Output); } 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 63f8a015f..530022afe 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/FieldOptions.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/FieldOptions.ts @@ -2,8 +2,6 @@ import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; import type { FieldRules as _validate_FieldRules, FieldRules__Output as _validate_FieldRules__Output } from '../../validate/FieldRules'; -import type { FieldSecurityAnnotation as _udpa_annotations_FieldSecurityAnnotation, FieldSecurityAnnotation__Output as _udpa_annotations_FieldSecurityAnnotation__Output } from '../../udpa/annotations/FieldSecurityAnnotation'; -import type { FieldMigrateAnnotation as _udpa_annotations_FieldMigrateAnnotation, FieldMigrateAnnotation__Output as _udpa_annotations_FieldMigrateAnnotation__Output } from '../../udpa/annotations/FieldMigrateAnnotation'; // Original file: null @@ -30,10 +28,6 @@ export interface FieldOptions { 'weak'?: (boolean); 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; '.validate.rules'?: (_validate_FieldRules); - '.udpa.annotations.security'?: (_udpa_annotations_FieldSecurityAnnotation); - '.udpa.annotations.sensitive'?: (boolean); - '.udpa.annotations.field_migrate'?: (_udpa_annotations_FieldMigrateAnnotation); - '.envoy.annotations.disallowed_by_default'?: (boolean); } export interface FieldOptions__Output { @@ -45,8 +39,4 @@ export interface FieldOptions__Output { 'weak': (boolean); 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; '.validate.rules'?: (_validate_FieldRules__Output); - '.udpa.annotations.security'?: (_udpa_annotations_FieldSecurityAnnotation__Output); - '.udpa.annotations.sensitive': (boolean); - '.udpa.annotations.field_migrate'?: (_udpa_annotations_FieldMigrateAnnotation__Output); - '.envoy.annotations.disallowed_by_default': (boolean); } 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 b2ddbb374..573e847c0 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/FileOptions.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/FileOptions.ts @@ -1,8 +1,6 @@ // Original file: null import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; -import type { FileMigrateAnnotation as _udpa_annotations_FileMigrateAnnotation, FileMigrateAnnotation__Output as _udpa_annotations_FileMigrateAnnotation__Output } from '../../udpa/annotations/FileMigrateAnnotation'; -import type { StatusAnnotation as _udpa_annotations_StatusAnnotation, StatusAnnotation__Output as _udpa_annotations_StatusAnnotation__Output } from '../../udpa/annotations/StatusAnnotation'; // Original file: null @@ -28,8 +26,6 @@ export interface FileOptions { 'objcClassPrefix'?: (string); 'csharpNamespace'?: (string); 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; - '.udpa.annotations.file_migrate'?: (_udpa_annotations_FileMigrateAnnotation); - '.udpa.annotations.file_status'?: (_udpa_annotations_StatusAnnotation); } export interface FileOptions__Output { @@ -48,6 +44,4 @@ export interface FileOptions__Output { 'objcClassPrefix': (string); 'csharpNamespace': (string); 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; - '.udpa.annotations.file_migrate'?: (_udpa_annotations_FileMigrateAnnotation__Output); - '.udpa.annotations.file_status'?: (_udpa_annotations_StatusAnnotation__Output); } diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/MessageOptions.ts b/packages/grpc-js-xds/src/generated/google/protobuf/MessageOptions.ts index 219e4bfd2..d3b5a54b8 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/MessageOptions.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/MessageOptions.ts @@ -1,8 +1,6 @@ // Original file: null import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; -import type { VersioningAnnotation as _udpa_annotations_VersioningAnnotation, VersioningAnnotation__Output as _udpa_annotations_VersioningAnnotation__Output } from '../../udpa/annotations/VersioningAnnotation'; -import type { MigrateAnnotation as _udpa_annotations_MigrateAnnotation, MigrateAnnotation__Output as _udpa_annotations_MigrateAnnotation__Output } from '../../udpa/annotations/MigrateAnnotation'; export interface MessageOptions { 'messageSetWireFormat'?: (boolean); @@ -11,8 +9,6 @@ export interface MessageOptions { 'mapEntry'?: (boolean); 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; '.validate.disabled'?: (boolean); - '.udpa.annotations.versioning'?: (_udpa_annotations_VersioningAnnotation); - '.udpa.annotations.message_migrate'?: (_udpa_annotations_MigrateAnnotation); } export interface MessageOptions__Output { @@ -22,6 +18,4 @@ export interface MessageOptions__Output { 'mapEntry': (boolean); 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; '.validate.disabled': (boolean); - '.udpa.annotations.versioning'?: (_udpa_annotations_VersioningAnnotation__Output); - '.udpa.annotations.message_migrate'?: (_udpa_annotations_MigrateAnnotation__Output); } diff --git a/packages/grpc-js-xds/src/generated/typed_struct.ts b/packages/grpc-js-xds/src/generated/typed_struct.ts new file mode 100644 index 000000000..78d781a29 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/typed_struct.ts @@ -0,0 +1,74 @@ +import type * as grpc from '@grpc/grpc-js'; +import type { ServiceDefinition, EnumTypeDefinition, MessageTypeDefinition } from '@grpc/proto-loader'; + + +type SubtypeConstructor any, Subtype> = { + new(...args: ConstructorParameters): Subtype; +}; + +export interface ProtoGrpcType { + google: { + protobuf: { + DescriptorProto: MessageTypeDefinition + Duration: MessageTypeDefinition + EnumDescriptorProto: MessageTypeDefinition + EnumOptions: MessageTypeDefinition + EnumValueDescriptorProto: MessageTypeDefinition + EnumValueOptions: MessageTypeDefinition + FieldDescriptorProto: MessageTypeDefinition + FieldOptions: MessageTypeDefinition + FileDescriptorProto: MessageTypeDefinition + FileDescriptorSet: MessageTypeDefinition + FileOptions: MessageTypeDefinition + GeneratedCodeInfo: MessageTypeDefinition + ListValue: MessageTypeDefinition + MessageOptions: MessageTypeDefinition + MethodDescriptorProto: MessageTypeDefinition + MethodOptions: MessageTypeDefinition + NullValue: EnumTypeDefinition + OneofDescriptorProto: MessageTypeDefinition + OneofOptions: MessageTypeDefinition + ServiceDescriptorProto: MessageTypeDefinition + ServiceOptions: MessageTypeDefinition + SourceCodeInfo: MessageTypeDefinition + Struct: MessageTypeDefinition + Timestamp: MessageTypeDefinition + UninterpretedOption: MessageTypeDefinition + Value: MessageTypeDefinition + } + } + udpa: { + type: { + v1: { + TypedStruct: MessageTypeDefinition + } + } + } + validate: { + AnyRules: MessageTypeDefinition + BoolRules: MessageTypeDefinition + BytesRules: MessageTypeDefinition + DoubleRules: MessageTypeDefinition + DurationRules: MessageTypeDefinition + EnumRules: MessageTypeDefinition + FieldRules: MessageTypeDefinition + Fixed32Rules: MessageTypeDefinition + Fixed64Rules: MessageTypeDefinition + FloatRules: MessageTypeDefinition + Int32Rules: MessageTypeDefinition + Int64Rules: MessageTypeDefinition + KnownRegex: EnumTypeDefinition + MapRules: MessageTypeDefinition + MessageRules: MessageTypeDefinition + RepeatedRules: MessageTypeDefinition + SFixed32Rules: MessageTypeDefinition + SFixed64Rules: MessageTypeDefinition + SInt32Rules: MessageTypeDefinition + SInt64Rules: MessageTypeDefinition + StringRules: MessageTypeDefinition + TimestampRules: MessageTypeDefinition + UInt32Rules: MessageTypeDefinition + UInt64Rules: MessageTypeDefinition + } +} + diff --git a/packages/grpc-js-xds/src/generated/udpa/type/v1/TypedStruct.ts b/packages/grpc-js-xds/src/generated/udpa/type/v1/TypedStruct.ts new file mode 100644 index 000000000..f9d842982 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/udpa/type/v1/TypedStruct.ts @@ -0,0 +1,77 @@ +// Original file: deps/udpa/udpa/type/v1/typed_struct.proto + +import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../google/protobuf/Struct'; + +/** + * A TypedStruct contains an arbitrary JSON serialized protocol buffer message with a URL that + * describes the type of the serialized message. This is very similar to google.protobuf.Any, + * instead of having protocol buffer binary, this employs google.protobuf.Struct as value. + * + * This message is intended to be embedded inside Any, so it shouldn't be directly referred + * from other UDPA messages. + * + * When packing an opaque extension config, packing the expected type into Any is preferred + * wherever possible for its efficiency. TypedStruct should be used only if a proto descriptor + * is not available, for example if: + * - A control plane sends opaque message that is originally from external source in human readable + * format such as JSON or YAML. + * - The control plane doesn't have the knowledge of the protocol buffer schema hence it cannot + * serialize the message in protocol buffer binary format. + * - The DPLB doesn't have have the knowledge of the protocol buffer schema its plugin or extension + * uses. This has to be indicated in the DPLB capability negotiation. + * + * When a DPLB receives a TypedStruct in Any, it should: + * - Check if the type_url of the TypedStruct matches the type the extension expects. + * - Convert value to the type described in type_url and perform validation. + * TODO(lizan): Figure out how TypeStruct should be used with DPLB extensions that doesn't link + * protobuf descriptor with DPLB itself, (e.g. gRPC LB Plugin, Envoy WASM extensions). + */ +export interface TypedStruct { + /** + * A URL that uniquely identifies the type of the serialize protocol buffer message. + * This has same semantics and format described in google.protobuf.Any: + * https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto + */ + 'type_url'?: (string); + /** + * A JSON representation of the above specified type. + */ + 'value'?: (_google_protobuf_Struct); +} + +/** + * A TypedStruct contains an arbitrary JSON serialized protocol buffer message with a URL that + * describes the type of the serialized message. This is very similar to google.protobuf.Any, + * instead of having protocol buffer binary, this employs google.protobuf.Struct as value. + * + * This message is intended to be embedded inside Any, so it shouldn't be directly referred + * from other UDPA messages. + * + * When packing an opaque extension config, packing the expected type into Any is preferred + * wherever possible for its efficiency. TypedStruct should be used only if a proto descriptor + * is not available, for example if: + * - A control plane sends opaque message that is originally from external source in human readable + * format such as JSON or YAML. + * - The control plane doesn't have the knowledge of the protocol buffer schema hence it cannot + * serialize the message in protocol buffer binary format. + * - The DPLB doesn't have have the knowledge of the protocol buffer schema its plugin or extension + * uses. This has to be indicated in the DPLB capability negotiation. + * + * When a DPLB receives a TypedStruct in Any, it should: + * - Check if the type_url of the TypedStruct matches the type the extension expects. + * - Convert value to the type described in type_url and perform validation. + * TODO(lizan): Figure out how TypeStruct should be used with DPLB extensions that doesn't link + * protobuf descriptor with DPLB itself, (e.g. gRPC LB Plugin, Envoy WASM extensions). + */ +export interface TypedStruct__Output { + /** + * A URL that uniquely identifies the type of the serialize protocol buffer message. + * This has same semantics and format described in google.protobuf.Any: + * https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto + */ + 'type_url': (string); + /** + * A JSON representation of the above specified type. + */ + 'value'?: (_google_protobuf_Struct__Output); +} diff --git a/packages/grpc-js-xds/src/http-filter.ts b/packages/grpc-js-xds/src/http-filter.ts new file mode 100644 index 000000000..e7ea32957 --- /dev/null +++ b/packages/grpc-js-xds/src/http-filter.ts @@ -0,0 +1,221 @@ +/* + * Copyright 2021 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. + */ + +// This is a non-public, unstable API, but it's very convenient +import { loadProtosWithOptionsSync } from '@grpc/proto-loader/build/src/util'; +import { experimental } from '@grpc/grpc-js'; +import { Any__Output } from './generated/google/protobuf/Any'; +import Filter = experimental.Filter; +import FilterFactory = experimental.FilterFactory; +import { TypedStruct__Output } from './generated/udpa/type/v1/TypedStruct'; +import { FilterConfig__Output } from './generated/envoy/config/route/v3/FilterConfig'; +import { HttpFilter__Output } from './generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpFilter'; + +const TYPED_STRUCT_URL = 'type.googleapis.com/udpa.type.v1.TypedStruct'; +const TYPED_STRUCT_NAME = 'udpa.type.v1.TypedStruct'; + +const FILTER_CONFIG_URL = 'type.googleapis.com/envoy.config.route.v3.FilterConfig'; +const FILTER_CONFIG_NAME = 'envoy.config.route.v3.FilterConfig'; + +const resourceRoot = loadProtosWithOptionsSync([ + 'udpa/type/v1/typed_struct.proto', + 'envoy/config/route/v3/route_components.proto'], { + keepCase: true, + includeDirs: [ + // Paths are relative to src/build + __dirname + '/../../deps/udpa/', + __dirname + '/../../deps/envoy-api/' + ], + } +); + +export interface HttpFilterConfig { + typeUrl: string; + config: any; +} + +export interface HttpFilterFactoryConstructor { + new(config: HttpFilterConfig, overrideConfig?: HttpFilterConfig): FilterFactory; +} + +export interface HttpFilterRegistryEntry { + parseTopLevelFilterConfig(encodedConfig: Any__Output): HttpFilterConfig | null; + parseOverrideFilterConfig(encodedConfig: Any__Output): HttpFilterConfig | null; + httpFilterConstructor: HttpFilterFactoryConstructor; +} + +const FILTER_REGISTRY = new Map(); + +export function registerHttpFilter(typeName: string, entry: HttpFilterRegistryEntry) { + FILTER_REGISTRY.set(typeName, entry); +} + +const toObjectOptions = { + longs: String, + enums: String, + defaults: true, + oneofs: true +} + +function parseAnyMessage(message: Any__Output): MessageType | null { + const messageType = resourceRoot.lookup(message.type_url); + if (messageType) { + const decodedMessage = (messageType as any).decode(message.value); + return decodedMessage.$type.toObject(decodedMessage, toObjectOptions) as MessageType; + } else { + return null; + } +} + +function getTopLevelFilterUrl(encodedConfig: Any__Output): string { + let typeUrl: string; + if (encodedConfig.type_url === TYPED_STRUCT_URL) { + const typedStruct = parseAnyMessage(encodedConfig) + if (typedStruct) { + return typedStruct.type_url; + } else { + throw new Error('Failed to parse TypedStruct'); + } + } else { + return encodedConfig.type_url; + } +} + +export function validateTopLevelFilter(httpFilter: HttpFilter__Output): boolean { + if (!httpFilter.typed_config) { + return false; + } + const encodedConfig = httpFilter.typed_config; + let typeUrl: string; + try { + typeUrl = getTopLevelFilterUrl(encodedConfig); + } catch (e) { + return false; + } + const registryEntry = FILTER_REGISTRY.get(typeUrl); + if (registryEntry) { + const parsedConfig = registryEntry.parseTopLevelFilterConfig(encodedConfig); + return parsedConfig !== null; + } else { + if (httpFilter.is_optional) { + return true; + } else { + return false; + } + } +} + +export function validateOverrideFilter(encodedConfig: Any__Output): boolean { + let typeUrl: string; + let realConfig: Any__Output; + let isOptional = false; + if (encodedConfig.type_url === FILTER_CONFIG_URL) { + const filterConfig = parseAnyMessage(encodedConfig); + if (filterConfig) { + isOptional = filterConfig.is_optional; + if (filterConfig.config) { + realConfig = filterConfig.config; + } else { + return false; + } + } else { + return false; + } + } else { + realConfig = encodedConfig; + } + if (realConfig.type_url === TYPED_STRUCT_URL) { + const typedStruct = parseAnyMessage(encodedConfig); + if (typedStruct) { + typeUrl = typedStruct.type_url; + } else { + return false; + } + } else { + typeUrl = realConfig.type_url; + } + const registryEntry = FILTER_REGISTRY.get(typeUrl); + if (registryEntry) { + const parsedConfig = registryEntry.parseOverrideFilterConfig(encodedConfig); + return parsedConfig !== null; + } else { + if (isOptional) { + return true; + } else { + return false; + } + } +} + +export function parseTopLevelFilterConfig(encodedConfig: Any__Output) { + let typeUrl: string; + try { + typeUrl = getTopLevelFilterUrl(encodedConfig); + } catch (e) { + return null; + } + const registryEntry = FILTER_REGISTRY.get(typeUrl); + if (registryEntry) { + return registryEntry.parseTopLevelFilterConfig(encodedConfig); + } else { + // Filter type URL not found in registry + return null; + } +} + +export function parseOverrideFilterConfig(encodedConfig: Any__Output) { + let typeUrl: string; + let realConfig: Any__Output; + if (encodedConfig.type_url === FILTER_CONFIG_URL) { + const filterConfig = parseAnyMessage(encodedConfig); + if (filterConfig) { + if (filterConfig.config) { + realConfig = filterConfig.config; + } else { + return null; + } + } else { + return null; + } + } else { + realConfig = encodedConfig; + } + if (realConfig.type_url === TYPED_STRUCT_URL) { + const typedStruct = parseAnyMessage(encodedConfig); + if (typedStruct) { + typeUrl = typedStruct.type_url; + } else { + return null; + } + } else { + typeUrl = realConfig.type_url; + } + const registryEntry = FILTER_REGISTRY.get(typeUrl); + if (registryEntry) { + return registryEntry.parseOverrideFilterConfig(encodedConfig); + } else { + return null; + } +} + +export function createHttpFilter(config: HttpFilterConfig, overrideConfig?: HttpFilterConfig): FilterFactory | null { + const registryEntry = FILTER_REGISTRY.get(config.typeUrl); + if (registryEntry) { + return new registryEntry.httpFilterConstructor(config, overrideConfig); + } else { + return null; + } +} \ No newline at end of file diff --git a/packages/grpc-js-xds/src/protobuf-any.ts b/packages/grpc-js-xds/src/protobuf-any.ts new file mode 100644 index 000000000..cfee35f91 --- /dev/null +++ b/packages/grpc-js-xds/src/protobuf-any.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2021 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. + */ + +// This is a non-public, unstable API, but it's very convenient +import { loadProtosWithOptionsSync } from '@grpc/proto-loader/build/src/util'; +import { Any__Output } from './generated/google/protobuf/Any'; + +function parseAnyMessage(encodedMessage: Any__Output) { + +} \ No newline at end of file diff --git a/packages/grpc-js-xds/src/resolver-xds.ts b/packages/grpc-js-xds/src/resolver-xds.ts index 892cf5711..372d8b052 100644 --- a/packages/grpc-js-xds/src/resolver-xds.ts +++ b/packages/grpc-js-xds/src/resolver-xds.ts @@ -42,6 +42,12 @@ import { RouteAction, SingleClusterRouteAction, WeightedCluster, WeightedCluster import { decodeSingleResource, HTTP_CONNECTION_MANGER_TYPE_URL_V3 } from './resources'; import Duration = experimental.Duration; import { Duration__Output } from './generated/google/protobuf/Duration'; +import { createHttpFilter, HttpFilterConfig, parseOverrideFilterConfig, parseTopLevelFilterConfig } from './http-filter'; +import { EXPERIMENTAL_FAULT_INJECTION } from './environment'; +import Filter = experimental.Filter; +import FilterFactory = experimental.FilterFactory; +import BaseFilter = experimental.BaseFilter; +import CallStream = experimental.CallStream; const TRACER_NAME = 'xds_resolver'; @@ -203,6 +209,25 @@ function protoDurationToDuration(duration: Duration__Output): Duration { } } +class NoRouterFilter extends BaseFilter implements Filter { + constructor(private call: CallStream) { + super(); + } + + sendMetadata(metadata: Promise): Promise { + this.call.cancelWithStatus(status.UNAVAILABLE, 'no xDS HTTP router filter configured'); + return Promise.reject(new Error('no xDS HTTP router filter configured')); + } +} + +class NoRouterFilterFactory implements FilterFactory { + createFilter(callStream: CallStream): NoRouterFilter { + return new NoRouterFilter(callStream); + } +} + +const ROUTER_FILTER_URL = 'type.googleapis.com/envoy.extensions.filters.http.router.v3.Router'; + class XdsResolver implements Resolver { private hasReportedSuccess = false; @@ -221,6 +246,9 @@ class XdsResolver implements Resolver { private latestDefaultTimeout: Duration | undefined = undefined; + private ldsHttpFilterConfigs: {name: string, config: HttpFilterConfig}[] = []; + private hasRouterFilter = false; + constructor( private target: GrpcUri, private listener: ResolverListener, @@ -235,6 +263,21 @@ class XdsResolver implements Resolver { } else { this.latestDefaultTimeout = protoDurationToDuration(defaultTimeout); } + if (EXPERIMENTAL_FAULT_INJECTION) { + this.ldsHttpFilterConfigs = []; + this.hasRouterFilter = false; + for (const filter of httpConnectionManager.http_filters) { + if (filter.typed_config?.type_url === ROUTER_FILTER_URL) { + this.hasRouterFilter = true; + break; + } + // typed_config must be set here, or validation would have failed + const filterConfig = parseTopLevelFilterConfig(filter.typed_config!); + if (filterConfig) { + this.ldsHttpFilterConfigs.push({name: filter.name, config: filterConfig}); + } + } + } switch (httpConnectionManager.route_specifier) { case 'rds': { const routeConfigName = httpConnectionManager.rds!.route_config_name; @@ -314,6 +357,15 @@ class XdsResolver implements Resolver { this.reportResolutionError('No matching route found'); return; } + const virtualHostHttpFilterOverrides = new Map(); + if (EXPERIMENTAL_FAULT_INJECTION) { + for (const [name, filter] of Object.entries(virtualHost.typed_per_filter_config ?? {})) { + const parsedConfig = parseOverrideFilterConfig(filter); + if (parsedConfig) { + virtualHostHttpFilterOverrides.set(name, parsedConfig); + } + } + } trace('Received virtual host config ' + JSON.stringify(virtualHost, undefined, 2)); const allConfigClusters = new Set(); const matchList: {matcher: Matcher, action: RouteAction}[] = []; @@ -334,20 +386,89 @@ class XdsResolver implements Resolver { if (timeout?.seconds === 0 && timeout.nanos === 0) { timeout = undefined; } + const routeHttpFilterOverrides = new Map(); + if (EXPERIMENTAL_FAULT_INJECTION) { + for (const [name, filter] of Object.entries(route.typed_per_filter_config ?? {})) { + const parsedConfig = parseOverrideFilterConfig(filter); + if (parsedConfig) { + routeHttpFilterOverrides.set(name, parsedConfig); + } + } + } switch (route.route!.cluster_specifier) { case 'cluster_header': continue; case 'cluster':{ const cluster = route.route!.cluster!; allConfigClusters.add(cluster); - routeAction = new SingleClusterRouteAction(cluster, timeout); + const extraFilterFactories: FilterFactory[] = []; + if (EXPERIMENTAL_FAULT_INJECTION) { + for (const filterConfig of this.ldsHttpFilterConfigs) { + if (routeHttpFilterOverrides.has(filterConfig.name)) { + const filter = createHttpFilter(filterConfig.config, routeHttpFilterOverrides.get(filterConfig.name)!); + if (filter) { + extraFilterFactories.push(filter); + } + } else if (virtualHostHttpFilterOverrides.has(filterConfig.name)) { + const filter = createHttpFilter(filterConfig.config, virtualHostHttpFilterOverrides.get(filterConfig.name)!); + if (filter) { + extraFilterFactories.push(filter); + } + } else { + const filter = createHttpFilter(filterConfig.config); + if (filter) { + extraFilterFactories.push(filter); + } + } + } + if (!this.hasRouterFilter) { + extraFilterFactories.push(new NoRouterFilterFactory()); + } + } + routeAction = new SingleClusterRouteAction(cluster, timeout, extraFilterFactories); break; } case 'weighted_clusters': { const weightedClusters: WeightedCluster[] = []; for (const clusterWeight of route.route!.weighted_clusters!.clusters) { allConfigClusters.add(clusterWeight.name); - weightedClusters.push({name: clusterWeight.name, weight: clusterWeight.weight?.value ?? 0}); + const extraFilterFactories: FilterFactory[] = []; + const clusterHttpFilterOverrides = new Map(); + if (EXPERIMENTAL_FAULT_INJECTION) { + for (const [name, filter] of Object.entries(clusterWeight.typed_per_filter_config ?? {})) { + const parsedConfig = parseOverrideFilterConfig(filter); + if (parsedConfig) { + clusterHttpFilterOverrides.set(name, parsedConfig); + } + } + for (const filterConfig of this.ldsHttpFilterConfigs) { + if (clusterHttpFilterOverrides.has(filterConfig.name)) { + const filter = createHttpFilter(filterConfig.config, clusterHttpFilterOverrides.get(filterConfig.name)!); + if (filter) { + extraFilterFactories.push(filter); + } + } else if (routeHttpFilterOverrides.has(filterConfig.name)) { + const filter = createHttpFilter(filterConfig.config, routeHttpFilterOverrides.get(filterConfig.name)!); + if (filter) { + extraFilterFactories.push(filter); + } + } else if (virtualHostHttpFilterOverrides.has(filterConfig.name)) { + const filter = createHttpFilter(filterConfig.config, virtualHostHttpFilterOverrides.get(filterConfig.name)!); + if (filter) { + extraFilterFactories.push(filter); + } + } else { + const filter = createHttpFilter(filterConfig.config); + if (filter) { + extraFilterFactories.push(filter); + } + } + } + if (!this.hasRouterFilter) { + extraFilterFactories.push(new NoRouterFilterFactory()); + } + } + weightedClusters.push({name: clusterWeight.name, weight: clusterWeight.weight?.value ?? 0, extraFilterFactories: extraFilterFactories}); } routeAction = new WeightedClusterRouteAction(weightedClusters, route.route!.weighted_clusters!.total_weight?.value ?? 100, timeout); } @@ -376,16 +497,17 @@ class XdsResolver implements Resolver { const configSelector: ConfigSelector = (methodName, metadata) => { for (const {matcher, action} of matchList) { if (matcher.apply(methodName, metadata)) { - const clusterName = action.getCluster(); - this.refCluster(clusterName); + const clusterResult = action.getCluster(); + this.refCluster(clusterResult.name); const onCommitted = () => { - this.unrefCluster(clusterName); + this.unrefCluster(clusterResult.name); } return { methodConfig: {name: [], timeout: action.getTimeout()}, onCommitted: onCommitted, - pickInformation: {cluster: clusterName}, - status: status.OK + pickInformation: {cluster: clusterResult.name}, + status: status.OK, + extraFilterFactories: clusterResult.extraFilterFactories }; } } @@ -393,7 +515,8 @@ class XdsResolver implements Resolver { methodConfig: {name: []}, // cluster won't be used here, but it's set because of some TypeScript weirdness pickInformation: {cluster: ''}, - status: status.UNAVAILABLE + status: status.UNAVAILABLE, + extraFilterFactories: [] }; }; trace('Created ConfigSelector with configuration:'); diff --git a/packages/grpc-js-xds/src/route-action.ts b/packages/grpc-js-xds/src/route-action.ts index 5574bcd91..a45bf02a4 100644 --- a/packages/grpc-js-xds/src/route-action.ts +++ b/packages/grpc-js-xds/src/route-action.ts @@ -16,10 +16,17 @@ import { experimental } from '@grpc/grpc-js'; import Duration = experimental.Duration; +import Filter = experimental.Filter; +import FilterFactory = experimental.FilterFactory; + +export interface ClusterResult { + name: string; + extraFilterFactories: FilterFactory[]; +} export interface RouteAction { toString(): string; - getCluster(): string; + getCluster(): ClusterResult; getTimeout(): Duration | undefined; } @@ -33,10 +40,13 @@ function durationToLogString(duration: Duration) { } export class SingleClusterRouteAction implements RouteAction { - constructor(private cluster: string, private timeout: Duration | undefined) {} + constructor(private cluster: string, private timeout: Duration | undefined, private extraFilterFactories: FilterFactory[]) {} getCluster() { - return this.cluster; + return { + name: this.cluster, + extraFilterFactories: this.extraFilterFactories + }; } toString() { @@ -55,11 +65,13 @@ export class SingleClusterRouteAction implements RouteAction { export interface WeightedCluster { name: string; weight: number; + extraFilterFactories: FilterFactory[]; } interface ClusterChoice { name: string; numerator: number; + extraFilterFactories: FilterFactory[]; } export class WeightedClusterRouteAction implements RouteAction { @@ -72,7 +84,7 @@ export class WeightedClusterRouteAction implements RouteAction { let lastNumerator = 0; for (const clusterWeight of clusters) { lastNumerator += clusterWeight.weight; - this.clusterChoices.push({name: clusterWeight.name, numerator: lastNumerator}); + this.clusterChoices.push({name: clusterWeight.name, numerator: lastNumerator, extraFilterFactories: clusterWeight.extraFilterFactories}); } } @@ -80,11 +92,14 @@ export class WeightedClusterRouteAction implements RouteAction { const randomNumber = Math.random() * this.totalWeight; for (const choice of this.clusterChoices) { if (randomNumber < choice.numerator) { - return choice.name; + return { + name: choice.name, + extraFilterFactories: choice.extraFilterFactories + }; } } // This should be prevented by the validation rules - return ''; + return {name: '', extraFilterFactories: []}; } toString() { diff --git a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts index eb76f7994..10ada540b 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts @@ -22,6 +22,8 @@ import { RdsState } from "./rds-state"; import { Watcher, XdsStreamState } from "./xds-stream-state"; import { HttpConnectionManager__Output } from '../generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpConnectionManager'; import { decodeSingleResource, HTTP_CONNECTION_MANGER_TYPE_URL_V2, HTTP_CONNECTION_MANGER_TYPE_URL_V3 } from '../resources'; +import { validateTopLevelFilter } from '../http-filter'; +import { EXPERIMENTAL_FAULT_INJECTION } from '../environment'; const TRACER_NAME = 'xds_client'; @@ -100,6 +102,13 @@ export class LdsState implements XdsStreamState { return false; } const httpConnectionManager = decodeSingleResource(HTTP_CONNECTION_MANGER_TYPE_URL_V3, message.api_listener!.api_listener.value); + if (EXPERIMENTAL_FAULT_INJECTION) { + for (const httpFilter of httpConnectionManager.http_filters) { + if (!validateTopLevelFilter(httpFilter)) { + return false; + } + } + } switch (httpConnectionManager.route_specifier) { case 'rds': return !!httpConnectionManager.rds?.config_source?.ads; diff --git a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts index 1e50f22e7..9441a7ecc 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts @@ -16,7 +16,9 @@ */ import { experimental, logVerbosity, StatusObject } from "@grpc/grpc-js"; +import { EXPERIMENTAL_FAULT_INJECTION } from "../environment"; import { RouteConfiguration__Output } from "../generated/envoy/config/route/v3/RouteConfiguration"; +import { validateOverrideFilter } from "../http-filter"; import { CdsLoadBalancingConfig } from "../load-balancer-cds"; import { Watcher, XdsStreamState } from "./xds-stream-state"; import ServiceConfig = experimental.ServiceConfig; @@ -112,6 +114,13 @@ export class RdsState implements XdsStreamState { return false; } } + if (EXPERIMENTAL_FAULT_INJECTION) { + for (const filterConfig of Object.values(virtualHost.typed_per_filter_config ?? {})) { + if (!validateOverrideFilter(filterConfig)) { + return false; + } + } + } for (const route of virtualHost.routes) { const match = route.match; if (!match) { @@ -131,6 +140,13 @@ export class RdsState implements XdsStreamState { if ((route.route === undefined) || SUPPORTED_CLUSTER_SPECIFIERS.indexOf(route.route.cluster_specifier) < 0) { return false; } + if (EXPERIMENTAL_FAULT_INJECTION) { + for (const filterConfig of Object.values(route.typed_per_filter_config ?? {})) { + if (!validateOverrideFilter(filterConfig)) { + return false; + } + } + } if (route.route!.cluster_specifier === 'weighted_clusters') { let weightSum = 0; for (const clusterWeight of route.route.weighted_clusters!.clusters) { @@ -139,6 +155,15 @@ export class RdsState implements XdsStreamState { if (weightSum !== route.route.weighted_clusters!.total_weight?.value ?? 100) { return false; } + if (EXPERIMENTAL_FAULT_INJECTION) { + for (const weightedCluster of route.route!.weighted_clusters!.clusters) { + for (const filterConfig of Object.values(weightedCluster.typed_per_filter_config ?? {})) { + if (!validateOverrideFilter(filterConfig)) { + return false; + } + } + } + } } } } diff --git a/packages/grpc-js/src/call-stream.ts b/packages/grpc-js/src/call-stream.ts index ae6342604..e9e1cb8de 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -721,6 +721,10 @@ export class Http2CallStream implements Call { this.configDeadline = configDeadline; } + addFilterFactories(extraFilterFactories: FilterFactory[]) { + this.filterStack.push(extraFilterFactories.map(filterFactory => filterFactory.createFilter(this))); + } + startRead() { /* If the stream has ended with an error, we should not emit any more * messages and we should communicate that the stream has ended */ diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index cd2fc94a2..859a6e76d 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -536,6 +536,7 @@ export class ChannelImplementation implements Channel { // Refreshing the filters makes the deadline filter pick up the new deadline stream.filterStack.refresh(); } + stream.addFilterFactories(callConfig.extraFilterFactories); this.tryPick(stream, metadata, callConfig); } else { stream.cancelWithStatus(callConfig.status, "Failed to route call to method " + stream.getMethod()); diff --git a/packages/grpc-js/src/resolver.ts b/packages/grpc-js/src/resolver.ts index 147ace30d..cf5f7ee26 100644 --- a/packages/grpc-js/src/resolver.ts +++ b/packages/grpc-js/src/resolver.ts @@ -24,12 +24,14 @@ import { GrpcUri, uriToString } from './uri-parser'; import { ChannelOptions } from './channel-options'; import { Metadata } from './metadata'; import { Status } from './constants'; +import { Filter, FilterFactory } from './filter'; export interface CallConfig { methodConfig: MethodConfig; onCommitted?: () => void; pickInformation: {[key: string]: string}; status: Status; + extraFilterFactories: FilterFactory[]; } /** diff --git a/packages/grpc-js/src/resolving-load-balancer.ts b/packages/grpc-js/src/resolving-load-balancer.ts index 94dd8c4a9..3f84af378 100644 --- a/packages/grpc-js/src/resolving-load-balancer.ts +++ b/packages/grpc-js/src/resolving-load-balancer.ts @@ -58,7 +58,8 @@ function getDefaultConfigSelector(serviceConfig: ServiceConfig | null): ConfigSe return { methodConfig: methodConfig, pickInformation: {}, - status: Status.OK + status: Status.OK, + extraFilterFactories: [] }; } } @@ -67,7 +68,8 @@ function getDefaultConfigSelector(serviceConfig: ServiceConfig | null): ConfigSe return { methodConfig: {name: []}, pickInformation: {}, - status: Status.OK + status: Status.OK, + extraFilterFactories: [] }; } } From a0f298c514c6ac56e33c149f8477d35deecbb4d2 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 15 Jul 2021 10:08:05 -0700 Subject: [PATCH 041/450] grpc-js: Split out logs for different severity levels --- packages/grpc-js/src/logging.ts | 37 ++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/packages/grpc-js/src/logging.ts b/packages/grpc-js/src/logging.ts index 352496240..549cd860e 100644 --- a/packages/grpc-js/src/logging.ts +++ b/packages/grpc-js/src/logging.ts @@ -17,7 +17,19 @@ import { LogVerbosity } from './constants'; -let _logger: Partial = console; +const DEFAULT_LOGGER: Partial = { + error: (message?: any, ...optionalParams: any[]) => { + console.error('E ' + message, ...optionalParams); + }, + info: (message?: any, ...optionalParams: any[]) => { + console.error('I ' + message, ...optionalParams); + }, + debug: (message?: any, ...optionalParams: any[]) => { + console.error('D ' + message, ...optionalParams); + }, +} + +let _logger: Partial = DEFAULT_LOGGER; let _logVerbosity: LogVerbosity = LogVerbosity.ERROR; const verbosityString = @@ -54,8 +66,27 @@ export const setLoggerVerbosity = (verbosity: LogVerbosity): void => { // eslint-disable-next-line @typescript-eslint/no-explicit-any export const log = (severity: LogVerbosity, ...args: any[]): void => { - if (severity >= _logVerbosity && typeof _logger.error === 'function') { - _logger.error(...args); + let logFunction: typeof DEFAULT_LOGGER.error; + if (severity >= _logVerbosity) { + switch (severity) { + case LogVerbosity.DEBUG: + logFunction = _logger.debug; + break; + case LogVerbosity.INFO: + logFunction = _logger.info; + break; + case LogVerbosity.ERROR: + logFunction = _logger.error; + break; + } + /* Fall back to _logger.error when other methods are not available for + * compatiblity with older behavior that always logged to _logger.error */ + if (!logFunction) { + logFunction = _logger.error; + } + if (logFunction) { + logFunction.bind(_logger)(...args); + } } }; From 312b7613def2b0b418e84bb51d304776ae4ebfce Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 15 Jul 2021 10:28:15 -0700 Subject: [PATCH 042/450] grpc-js: Tighten server.bindAsync creds typecheck --- packages/grpc-js/src/server.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 017312219..42b79a3cf 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -237,8 +237,8 @@ export class Server { throw new TypeError('port must be a string'); } - if (creds === null || typeof creds !== 'object') { - throw new TypeError('creds must be an object'); + if (creds === null || !(creds instanceof ServerCredentials)) { + throw new TypeError('creds must be a ServerCredentials object'); } if (typeof callback !== 'function') { From 6359bf066f481d51efb2a63f3a477e0fc151bbab Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 15 Jul 2021 10:55:50 -0700 Subject: [PATCH 043/450] Remove test for exact default logger identity --- packages/grpc-js/test/test-logging.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/grpc-js/test/test-logging.ts b/packages/grpc-js/test/test-logging.ts index c1601cbc5..d275158cf 100644 --- a/packages/grpc-js/test/test-logging.ts +++ b/packages/grpc-js/test/test-logging.ts @@ -27,10 +27,6 @@ describe('Logging', () => { grpc.setLogVerbosity(grpc.logVerbosity.DEBUG); }); - it('logger defaults to console', () => { - assert.strictEqual(logging.getLogger(), console); - }); - it('sets the logger to a new value', () => { const logger: Partial = {}; From a5449155049351c81b4ffead4a3004217e504568 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 15 Jul 2021 11:29:28 -0700 Subject: [PATCH 044/450] Add router filter registry entry --- .../src/http-filter/router-filter.ts | 49 +++++++++++++++++++ packages/grpc-js-xds/src/index.ts | 2 + 2 files changed, 51 insertions(+) create mode 100644 packages/grpc-js-xds/src/http-filter/router-filter.ts diff --git a/packages/grpc-js-xds/src/http-filter/router-filter.ts b/packages/grpc-js-xds/src/http-filter/router-filter.ts new file mode 100644 index 000000000..81450c0ff --- /dev/null +++ b/packages/grpc-js-xds/src/http-filter/router-filter.ts @@ -0,0 +1,49 @@ +/* + * Copyright 2021 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 { experimental } from '@grpc/grpc-js'; +import { Any__Output } from '../generated/google/protobuf/Any'; +import { HttpFilterConfig, registerHttpFilter } from '../http-filter'; +import Filter = experimental.Filter; +import FilterFactory = experimental.FilterFactory; +import BaseFilter = experimental.BaseFilter; + +class RouterFilter extends BaseFilter implements Filter {} + +class RouterFilterFactory implements FilterFactory { + constructor(config: HttpFilterConfig, overrideConfig?: HttpFilterConfig) {} + + createFilter(callStream: experimental.CallStream): RouterFilter { + return new RouterFilter(); + } +} + +const ROUTER_FILTER_URL = 'type.googleapis.com/envoy.extensions.filters.http.router.v3.Router'; + +function parseConfig(encodedConfig: Any__Output): HttpFilterConfig | null { + return { + typeUrl: ROUTER_FILTER_URL, + config: null + }; +} + +export function setup() { + registerHttpFilter(ROUTER_FILTER_URL, { + parseTopLevelFilterConfig: parseConfig, + parseOverrideFilterConfig: parseConfig, + httpFilterConstructor: RouterFilterFactory + }); +} \ No newline at end of file diff --git a/packages/grpc-js-xds/src/index.ts b/packages/grpc-js-xds/src/index.ts index 1b24d25e6..2fee339d1 100644 --- a/packages/grpc-js-xds/src/index.ts +++ b/packages/grpc-js-xds/src/index.ts @@ -22,6 +22,7 @@ import * as load_balancer_lrs from './load-balancer-lrs'; import * as load_balancer_priority from './load-balancer-priority'; import * as load_balancer_weighted_target from './load-balancer-weighted-target'; import * as load_balancer_xds_cluster_manager from './load-balancer-xds-cluster-manager'; +import * as router_filter from './http-filter/router-filter'; /** * Register the "xds:" name scheme with the @grpc/grpc-js library. @@ -34,4 +35,5 @@ export function register() { load_balancer_priority.setup(); load_balancer_weighted_target.setup(); load_balancer_xds_cluster_manager.setup(); + router_filter.setup(); } \ No newline at end of file From d0745b3a4caf84525357cbcca7f62ad625dd16fd Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Thu, 15 Jul 2021 14:56:47 -0700 Subject: [PATCH 045/450] Run call config filter factories before load balancing --- packages/grpc-js-xds/src/resolver-xds.ts | 6 +-- packages/grpc-js-xds/src/route-action.ts | 14 ++--- packages/grpc-js/src/call-stream.ts | 8 +-- packages/grpc-js/src/channel.ts | 51 ++++++++++++++----- packages/grpc-js/src/filter-stack.ts | 4 ++ packages/grpc-js/src/resolver.ts | 2 +- .../grpc-js/src/resolving-load-balancer.ts | 4 +- packages/grpc-js/src/subchannel.ts | 4 +- 8 files changed, 61 insertions(+), 32 deletions(-) diff --git a/packages/grpc-js-xds/src/resolver-xds.ts b/packages/grpc-js-xds/src/resolver-xds.ts index 372d8b052..c48cc251c 100644 --- a/packages/grpc-js-xds/src/resolver-xds.ts +++ b/packages/grpc-js-xds/src/resolver-xds.ts @@ -468,7 +468,7 @@ class XdsResolver implements Resolver { extraFilterFactories.push(new NoRouterFilterFactory()); } } - weightedClusters.push({name: clusterWeight.name, weight: clusterWeight.weight?.value ?? 0, extraFilterFactories: extraFilterFactories}); + weightedClusters.push({name: clusterWeight.name, weight: clusterWeight.weight?.value ?? 0, dynamicFilterFactories: extraFilterFactories}); } routeAction = new WeightedClusterRouteAction(weightedClusters, route.route!.weighted_clusters!.total_weight?.value ?? 100, timeout); } @@ -507,7 +507,7 @@ class XdsResolver implements Resolver { onCommitted: onCommitted, pickInformation: {cluster: clusterResult.name}, status: status.OK, - extraFilterFactories: clusterResult.extraFilterFactories + dynamicFilterFactories: clusterResult.dynamicFilterFactories }; } } @@ -516,7 +516,7 @@ class XdsResolver implements Resolver { // cluster won't be used here, but it's set because of some TypeScript weirdness pickInformation: {cluster: ''}, status: status.UNAVAILABLE, - extraFilterFactories: [] + dynamicFilterFactories: [] }; }; trace('Created ConfigSelector with configuration:'); diff --git a/packages/grpc-js-xds/src/route-action.ts b/packages/grpc-js-xds/src/route-action.ts index a45bf02a4..d29e67b9b 100644 --- a/packages/grpc-js-xds/src/route-action.ts +++ b/packages/grpc-js-xds/src/route-action.ts @@ -21,7 +21,7 @@ import FilterFactory = experimental.FilterFactory; export interface ClusterResult { name: string; - extraFilterFactories: FilterFactory[]; + dynamicFilterFactories: FilterFactory[]; } export interface RouteAction { @@ -45,7 +45,7 @@ export class SingleClusterRouteAction implements RouteAction { getCluster() { return { name: this.cluster, - extraFilterFactories: this.extraFilterFactories + dynamicFilterFactories: this.extraFilterFactories }; } @@ -65,13 +65,13 @@ export class SingleClusterRouteAction implements RouteAction { export interface WeightedCluster { name: string; weight: number; - extraFilterFactories: FilterFactory[]; + dynamicFilterFactories: FilterFactory[]; } interface ClusterChoice { name: string; numerator: number; - extraFilterFactories: FilterFactory[]; + dynamicFilterFactories: FilterFactory[]; } export class WeightedClusterRouteAction implements RouteAction { @@ -84,7 +84,7 @@ export class WeightedClusterRouteAction implements RouteAction { let lastNumerator = 0; for (const clusterWeight of clusters) { lastNumerator += clusterWeight.weight; - this.clusterChoices.push({name: clusterWeight.name, numerator: lastNumerator, extraFilterFactories: clusterWeight.extraFilterFactories}); + this.clusterChoices.push({name: clusterWeight.name, numerator: lastNumerator, dynamicFilterFactories: clusterWeight.dynamicFilterFactories}); } } @@ -94,12 +94,12 @@ export class WeightedClusterRouteAction implements RouteAction { if (randomNumber < choice.numerator) { return { name: choice.name, - extraFilterFactories: choice.extraFilterFactories + dynamicFilterFactories: choice.dynamicFilterFactories }; } } // This should be prevented by the validation rules - return {name: '', extraFilterFactories: []}; + return {name: '', dynamicFilterFactories: []}; } toString() { diff --git a/packages/grpc-js/src/call-stream.ts b/packages/grpc-js/src/call-stream.ts index e9e1cb8de..accc275fc 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -462,9 +462,9 @@ export class Http2CallStream implements Call { attachHttp2Stream( stream: http2.ClientHttp2Stream, subchannel: Subchannel, - extraFilters: FilterFactory[] + extraFilters: Filter[] ): void { - this.filterStack.push(extraFilters.map(filterFactory => filterFactory.createFilter(this))); + this.filterStack.push(extraFilters); if (this.finalStatus !== null) { stream.close(NGHTTP2_CANCEL); } else { @@ -721,8 +721,8 @@ export class Http2CallStream implements Call { this.configDeadline = configDeadline; } - addFilterFactories(extraFilterFactories: FilterFactory[]) { - this.filterStack.push(extraFilterFactories.map(filterFactory => filterFactory.createFilter(this))); + addFilters(extraFilters: Filter[]) { + this.filterStack.push(extraFilters); } startRead() { diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 859a6e76d..8b5f31bfb 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -41,6 +41,7 @@ import { mapProxyName } from './http_proxy'; import { GrpcUri, parseUri, uriToString } from './uri-parser'; import { ServerSurfaceCall } from './server-call'; import { SurfaceCall } from './call'; +import { Filter } from './filter'; export enum ConnectivityState { IDLE, @@ -148,6 +149,7 @@ export class ChannelImplementation implements Channel { callStream: Http2CallStream; callMetadata: Metadata; callConfig: CallConfig; + dynamicFilters: Filter[]; }> = []; private connectivityStateWatchers: ConnectivityStateWatcher[] = []; private defaultAuthority: string; @@ -237,8 +239,8 @@ export class ChannelImplementation implements Channel { const queueCopy = this.pickQueue.slice(); this.pickQueue = []; this.callRefTimerUnref(); - for (const { callStream, callMetadata, callConfig } of queueCopy) { - this.tryPick(callStream, callMetadata, callConfig); + for (const { callStream, callMetadata, callConfig, dynamicFilters } of queueCopy) { + this.tryPick(callStream, callMetadata, callConfig, dynamicFilters); } this.updateState(connectivityState); }, @@ -308,8 +310,8 @@ export class ChannelImplementation implements Channel { } } - private pushPick(callStream: Http2CallStream, callMetadata: Metadata, callConfig: CallConfig) { - this.pickQueue.push({ callStream, callMetadata, callConfig }); + private pushPick(callStream: Http2CallStream, callMetadata: Metadata, callConfig: CallConfig, dynamicFilters: Filter[]) { + this.pickQueue.push({ callStream, callMetadata, callConfig, dynamicFilters }); this.callRefTimerRef(); } @@ -320,7 +322,10 @@ export class ChannelImplementation implements Channel { * @param callStream * @param callMetadata */ - private tryPick(callStream: Http2CallStream, callMetadata: Metadata, callConfig: CallConfig) { + private tryPick(callStream: Http2CallStream, callMetadata: Metadata, callConfig: CallConfig, dynamicFilters: Filter[]) { + if (callStream.getStatus() !== null) { + return; + } const pickResult = this.currentPicker.pick({ metadata: callMetadata, extraPickInfo: callConfig.pickInformation }); trace( LogVerbosity.DEBUG, @@ -357,7 +362,7 @@ export class ChannelImplementation implements Channel { ' has state ' + ConnectivityState[pickResult.subchannel!.getConnectivityState()] ); - this.pushPick(callStream, callMetadata, callConfig); + this.pushPick(callStream, callMetadata, callConfig, dynamicFilters); break; } /* We need to clone the callMetadata here because the transparent @@ -370,10 +375,11 @@ export class ChannelImplementation implements Channel { const subchannelState: ConnectivityState = pickResult.subchannel!.getConnectivityState(); if (subchannelState === ConnectivityState.READY) { try { + const pickExtraFilters = pickResult.extraFilterFactories.map(factory => factory.createFilter(callStream)); pickResult.subchannel!.startCallStream( finalMetadata, callStream, - pickResult.extraFilterFactories + [...dynamicFilters, ...pickExtraFilters] ); /* If we reach this point, the call stream has started * successfully */ @@ -406,7 +412,7 @@ export class ChannelImplementation implements Channel { (error as Error).message + '. Retrying pick' ); - this.tryPick(callStream, callMetadata, callConfig); + this.tryPick(callStream, callMetadata, callConfig, dynamicFilters); } else { trace( LogVerbosity.INFO, @@ -435,7 +441,7 @@ export class ChannelImplementation implements Channel { ConnectivityState[subchannelState] + ' after metadata filters. Retrying pick' ); - this.tryPick(callStream, callMetadata, callConfig); + this.tryPick(callStream, callMetadata, callConfig, dynamicFilters); } }, (error: Error & { code: number }) => { @@ -449,11 +455,11 @@ export class ChannelImplementation implements Channel { } break; case PickResultType.QUEUE: - this.pushPick(callStream, callMetadata, callConfig); + this.pushPick(callStream, callMetadata, callConfig, dynamicFilters); break; case PickResultType.TRANSIENT_FAILURE: if (callMetadata.getOptions().waitForReady) { - this.pushPick(callStream, callMetadata, callConfig); + this.pushPick(callStream, callMetadata, callConfig, dynamicFilters); } else { callStream.cancelWithStatus( pickResult.status!.code, @@ -536,8 +542,27 @@ export class ChannelImplementation implements Channel { // Refreshing the filters makes the deadline filter pick up the new deadline stream.filterStack.refresh(); } - stream.addFilterFactories(callConfig.extraFilterFactories); - this.tryPick(stream, metadata, callConfig); + if (callConfig.dynamicFilterFactories.length > 0) { + /* These dynamicFilters are the mechanism for implementing gRFC A39: + * https://github.com/grpc/proposal/blob/master/A39-xds-http-filters.md + * We run them here instead of with the rest of the filters because + * that spec says "the xDS HTTP filters will run in between name + * resolution and load balancing". + * + * We use the filter stack here to simplify the multi-filter async + * waterfall logic, but we pass along the underlying list of filters + * to avoid having nested filter stacks when combining it with the + * original filter stack. We do not pass along the original filter + * factory list because these filters may need to persist data + * between sending headers and other operations. */ + const dynamicFilterStackFactory = new FilterStackFactory(callConfig.dynamicFilterFactories); + const dynamicFilterStack = dynamicFilterStackFactory.createFilter(stream); + dynamicFilterStack.sendMetadata(Promise.resolve(metadata)).then(filteredMetadata => { + this.tryPick(stream, filteredMetadata, callConfig, dynamicFilterStack.getFilters()); + }); + } else { + this.tryPick(stream, metadata, callConfig, []); + } } else { stream.cancelWithStatus(callConfig.status, "Failed to route call to method " + stream.getMethod()); } diff --git a/packages/grpc-js/src/filter-stack.ts b/packages/grpc-js/src/filter-stack.ts index 4e0ccf07f..a9e754428 100644 --- a/packages/grpc-js/src/filter-stack.ts +++ b/packages/grpc-js/src/filter-stack.ts @@ -81,6 +81,10 @@ export class FilterStack implements Filter { push(filters: Filter[]) { this.filters.unshift(...filters); } + + getFilters(): Filter[] { + return this.filters; + } } export class FilterStackFactory implements FilterFactory { diff --git a/packages/grpc-js/src/resolver.ts b/packages/grpc-js/src/resolver.ts index cf5f7ee26..57db665cd 100644 --- a/packages/grpc-js/src/resolver.ts +++ b/packages/grpc-js/src/resolver.ts @@ -31,7 +31,7 @@ export interface CallConfig { onCommitted?: () => void; pickInformation: {[key: string]: string}; status: Status; - extraFilterFactories: FilterFactory[]; + dynamicFilterFactories: FilterFactory[]; } /** diff --git a/packages/grpc-js/src/resolving-load-balancer.ts b/packages/grpc-js/src/resolving-load-balancer.ts index 3f84af378..7f6b41fdb 100644 --- a/packages/grpc-js/src/resolving-load-balancer.ts +++ b/packages/grpc-js/src/resolving-load-balancer.ts @@ -59,7 +59,7 @@ function getDefaultConfigSelector(serviceConfig: ServiceConfig | null): ConfigSe methodConfig: methodConfig, pickInformation: {}, status: Status.OK, - extraFilterFactories: [] + dynamicFilterFactories: [] }; } } @@ -69,7 +69,7 @@ function getDefaultConfigSelector(serviceConfig: ServiceConfig | null): ConfigSe methodConfig: {name: []}, pickInformation: {}, status: Status.OK, - extraFilterFactories: [] + dynamicFilterFactories: [] }; } } diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index c50a68e77..6dc3e9b37 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -688,7 +688,7 @@ export class Subchannel { startCallStream( metadata: Metadata, callStream: Http2CallStream, - extraFilterFactories: FilterFactory[] + extraFilters: Filter[] ) { const headers = metadata.toHttp2Headers(); headers[HTTP2_HEADER_AUTHORITY] = callStream.getHost(); @@ -720,7 +720,7 @@ export class Subchannel { headersString += '\t\t' + header + ': ' + headers[header] + '\n'; } logging.trace(LogVerbosity.DEBUG, 'call_stream', 'Starting stream on subchannel ' + this.subchannelAddressString + ' with headers\n' + headersString); - callStream.attachHttp2Stream(http2Stream, this, extraFilterFactories); + callStream.attachHttp2Stream(http2Stream, this, extraFilters); } /** From 9e4039d86b1acbe4c072863171b4b2e3bb49a2fc Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 16 Jul 2021 10:45:40 -0700 Subject: [PATCH 046/450] Updated text in bindAsync error test --- packages/grpc-js/test/test-server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/test/test-server.ts b/packages/grpc-js/test/test-server.ts index 58b102883..c4b5e30a0 100644 --- a/packages/grpc-js/test/test-server.ts +++ b/packages/grpc-js/test/test-server.ts @@ -116,7 +116,7 @@ describe('Server', () => { assert.throws(() => { server.bindAsync('localhost:0', null as any, noop); - }, /creds must be an object/); + }, /creds must be a ServerCredentials object/); assert.throws(() => { server.bindAsync( From af1676a5a5b26de4f41fa600ef1e20d58b600ab1 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Fri, 16 Jul 2021 16:39:26 -0700 Subject: [PATCH 047/450] Add test for passing client credentials to server --- packages/grpc-js/test/test-server.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/grpc-js/test/test-server.ts b/packages/grpc-js/test/test-server.ts index c4b5e30a0..8b2815745 100644 --- a/packages/grpc-js/test/test-server.ts +++ b/packages/grpc-js/test/test-server.ts @@ -118,6 +118,10 @@ describe('Server', () => { server.bindAsync('localhost:0', null as any, noop); }, /creds must be a ServerCredentials object/); + assert.throws(() => { + server.bindAsync('localhost:0', grpc.credentials.createInsecure() as any, noop); + }, /creds must be a ServerCredentials object/); + assert.throws(() => { server.bindAsync( 'localhost:0', From f03b4dd87fdc9a56e4ef652ccdb9213f7553e97c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 20 Jul 2021 14:12:59 -0700 Subject: [PATCH 048/450] Validate uniqueness of http filter names --- packages/grpc-js-xds/src/xds-stream-state/rds-state.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts index 9441a7ecc..0322218d2 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts @@ -141,7 +141,12 @@ export class RdsState implements XdsStreamState { return false; } if (EXPERIMENTAL_FAULT_INJECTION) { - for (const filterConfig of Object.values(route.typed_per_filter_config ?? {})) { + const filterNames = new Set(); + for (const [name, filterConfig] of Object.entries(route.typed_per_filter_config ?? {})) { + if (filterNames.has(name)) { + return false; + } + filterNames.add(name); if (!validateOverrideFilter(filterConfig)) { return false; } From 215cdcd1344b4b1426d989772ae6219770476777 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 22 Jul 2021 12:42:11 -0700 Subject: [PATCH 049/450] Check for router filter in validation step --- packages/grpc-js-xds/src/resolver-xds.ts | 33 ------------------- .../src/xds-stream-state/lds-state.ts | 20 ++++++++++- .../src/xds-stream-state/rds-state.ts | 5 --- 3 files changed, 19 insertions(+), 39 deletions(-) diff --git a/packages/grpc-js-xds/src/resolver-xds.ts b/packages/grpc-js-xds/src/resolver-xds.ts index 59a3fec47..3eaabb111 100644 --- a/packages/grpc-js-xds/src/resolver-xds.ts +++ b/packages/grpc-js-xds/src/resolver-xds.ts @@ -46,8 +46,6 @@ import { createHttpFilter, HttpFilterConfig, parseOverrideFilterConfig, parseTop import { EXPERIMENTAL_FAULT_INJECTION } from './environment'; import Filter = experimental.Filter; import FilterFactory = experimental.FilterFactory; -import BaseFilter = experimental.BaseFilter; -import CallStream = experimental.CallStream; const TRACER_NAME = 'xds_resolver'; @@ -209,25 +207,6 @@ function protoDurationToDuration(duration: Duration__Output): Duration { } } -class NoRouterFilter extends BaseFilter implements Filter { - constructor(private call: CallStream) { - super(); - } - - sendMetadata(metadata: Promise): Promise { - this.call.cancelWithStatus(status.UNAVAILABLE, 'no xDS HTTP router filter configured'); - return Promise.reject(new Error('no xDS HTTP router filter configured')); - } -} - -class NoRouterFilterFactory implements FilterFactory { - createFilter(callStream: CallStream): NoRouterFilter { - return new NoRouterFilter(callStream); - } -} - -const ROUTER_FILTER_URL = 'type.googleapis.com/envoy.extensions.filters.http.router.v3.Router'; - class XdsResolver implements Resolver { private hasReportedSuccess = false; @@ -247,7 +226,6 @@ class XdsResolver implements Resolver { private latestDefaultTimeout: Duration | undefined = undefined; private ldsHttpFilterConfigs: {name: string, config: HttpFilterConfig}[] = []; - private hasRouterFilter = false; constructor( private target: GrpcUri, @@ -265,12 +243,7 @@ class XdsResolver implements Resolver { } if (EXPERIMENTAL_FAULT_INJECTION) { this.ldsHttpFilterConfigs = []; - this.hasRouterFilter = false; for (const filter of httpConnectionManager.http_filters) { - if (filter.typed_config?.type_url === ROUTER_FILTER_URL) { - this.hasRouterFilter = true; - break; - } // typed_config must be set here, or validation would have failed const filterConfig = parseTopLevelFilterConfig(filter.typed_config!); if (filterConfig) { @@ -421,9 +394,6 @@ class XdsResolver implements Resolver { } } } - if (!this.hasRouterFilter) { - extraFilterFactories.push(new NoRouterFilterFactory()); - } } routeAction = new SingleClusterRouteAction(cluster, timeout, extraFilterFactories); break; @@ -464,9 +434,6 @@ class XdsResolver implements Resolver { } } } - if (!this.hasRouterFilter) { - extraFilterFactories.push(new NoRouterFilterFactory()); - } } weightedClusters.push({name: clusterWeight.name, weight: clusterWeight.weight?.value ?? 0, dynamicFilterFactories: extraFilterFactories}); } diff --git a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts index 10ada540b..3efc64b92 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts @@ -31,6 +31,8 @@ function trace(text: string): void { experimental.trace(logVerbosity.DEBUG, TRACER_NAME, text); } +const ROUTER_FILTER_URL = 'type.googleapis.com/envoy.extensions.filters.http.router.v3.Router'; + export class LdsState implements XdsStreamState { versionInfo = ''; nonce = ''; @@ -103,10 +105,26 @@ export class LdsState implements XdsStreamState { } const httpConnectionManager = decodeSingleResource(HTTP_CONNECTION_MANGER_TYPE_URL_V3, message.api_listener!.api_listener.value); if (EXPERIMENTAL_FAULT_INJECTION) { - for (const httpFilter of httpConnectionManager.http_filters) { + const filterNames = new Set(); + for (const [index, httpFilter] of httpConnectionManager.http_filters.entries()) { + if (filterNames.has(httpFilter.name)) { + return false; + } + filterNames.add(httpFilter.name); if (!validateTopLevelFilter(httpFilter)) { return false; } + /* Validate that the last filter, and only the last filter, is the + * router filter. */ + if (index < httpConnectionManager.http_filters.length - 1) { + if (httpFilter.name === ROUTER_FILTER_URL) { + return false; + } + } else { + if (httpFilter.name !== ROUTER_FILTER_URL) { + return false; + } + } } } switch (httpConnectionManager.route_specifier) { diff --git a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts index 0322218d2..f04692859 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts @@ -141,12 +141,7 @@ export class RdsState implements XdsStreamState { return false; } if (EXPERIMENTAL_FAULT_INJECTION) { - const filterNames = new Set(); for (const [name, filterConfig] of Object.entries(route.typed_per_filter_config ?? {})) { - if (filterNames.has(name)) { - return false; - } - filterNames.add(name); if (!validateOverrideFilter(filterConfig)) { return false; } From 2455c3d50aad13e8198c7b7583267bec5064e09c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 26 Jul 2021 10:52:11 -0700 Subject: [PATCH 050/450] grpc-js-xds: notify watchers when NACKing resource updates --- packages/grpc-js-xds/src/xds-client.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index ddca9284f..6828a8a8e 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -665,6 +665,11 @@ export class XdsClient { break; } if (serviceKind) { + this.adsState[serviceKind].reportStreamError({ + code: status.UNAVAILABLE, + details: message, + metadata: new Metadata() + }); resourceNames = this.adsState[serviceKind].getResourceNames(); nonce = this.adsState[serviceKind].nonce; versionInfo = this.adsState[serviceKind].versionInfo; From 82d5eb82f8babaac793f88eef3b54df37c05198b Mon Sep 17 00:00:00 2001 From: April Kyle Nassi Date: Wed, 28 Jul 2021 12:38:24 -0700 Subject: [PATCH 051/450] Update MAINTAINERS.md Moved 3 to emeritus --- MAINTAINERS.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/MAINTAINERS.md b/MAINTAINERS.md index c9e0522a1..bdcef2e26 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -8,16 +8,17 @@ See [CONTRIBUTING.md](https://github.com/grpc/grpc-community/blob/master/CONTRIB for general contribution guidelines. ## Maintainers (in alphabetical order) - - [jiangtaoli2016](https://github.com/jiangtaoli2016), Google Inc. + - [jtattermusch](https://github.com/jtattermusch), Google Inc. - [murgatroid99](https://github.com/murgatroid99), Google Inc. - [nicolasnoble](https://github.com/nicolasnoble), Google Inc. - - [ofrobots](https://github.com/ofrobots), Google Inc. - [srini100](https://github.com/srini100), Google Inc. - - [WeiranFang](https://github.com/WeiranFang), Google Inc. - [wenbozhu](https://github.com/wenbozhu), Google Inc. ## Emeritus Maintainers (in alphabetical order) + - [jiangtaoli2016](https://github.com/jiangtaoli2016), Google Inc. - [kjin](https://github.com/kjin), Google Inc. - [matt-kwong](https://github.com/matt-kwong), Google Inc. - \ No newline at end of file + - [ofrobots](https://github.com/ofrobots), Google Inc. + - [WeiranFang](https://github.com/WeiranFang), Google Inc. + From 5518d0e8f4de98624202d664c3d797c97346055a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Huan=20LI=20=28=E6=9D=8E=E5=8D=93=E6=A1=93=29?= Date: Mon, 2 Aug 2021 11:28:24 +0800 Subject: [PATCH 052/450] add xds support reading bootstrap config directly from env var (#1868) --- packages/grpc-js-xds/src/xds-bootstrap.ts | 88 +++++++++++++++-------- 1 file changed, 60 insertions(+), 28 deletions(-) diff --git a/packages/grpc-js-xds/src/xds-bootstrap.ts b/packages/grpc-js-xds/src/xds-bootstrap.ts index 3da4ec3e6..28e926058 100644 --- a/packages/grpc-js-xds/src/xds-bootstrap.ts +++ b/packages/grpc-js-xds/src/xds-bootstrap.ts @@ -244,34 +244,66 @@ export async function loadBootstrapInfo(): Promise { if (loadedBootstrapInfo !== null) { return loadedBootstrapInfo; } + + /** + * If GRPC_XDS_BOOTSTRAP exists + * then use its value as the name of the bootstrap file. + * + * If the file is missing or the contents of the file are malformed, + * return an error. + */ const bootstrapPath = process.env.GRPC_XDS_BOOTSTRAP; - if (bootstrapPath === undefined) { - return Promise.reject( - new Error( - 'The GRPC_XDS_BOOTSTRAP environment variable needs to be set to the path to the bootstrap file to use xDS' - ) - ); - } - loadedBootstrapInfo = new Promise((resolve, reject) => { - fs.readFile(bootstrapPath, { encoding: 'utf8' }, (err, data) => { - if (err) { - reject( - new Error( - `Failed to read xDS bootstrap file from path ${bootstrapPath} with error ${err.message}` - ) - ); - } - try { - const parsedFile = JSON.parse(data); - resolve(validateBootstrapFile(parsedFile)); - } catch (e) { - reject( - new Error( - `Failed to parse xDS bootstrap file at path ${bootstrapPath} with error ${e.message}` - ) - ); - } + if (bootstrapPath) { + loadedBootstrapInfo = new Promise((resolve, reject) => { + fs.readFile(bootstrapPath, { encoding: 'utf8' }, (err, data) => { + if (err) { + reject( + new Error( + `Failed to read xDS bootstrap file from path ${bootstrapPath} with error ${err.message}` + ) + ); + } + try { + const parsedFile = JSON.parse(data); + resolve(validateBootstrapFile(parsedFile)); + } catch (e) { + reject( + new Error( + `Failed to parse xDS bootstrap file at path ${bootstrapPath} with error ${e.message}` + ) + ); + } + }); }); - }); - return loadedBootstrapInfo; + return loadedBootstrapInfo; + } + + /** + * Else, if GRPC_XDS_BOOTSTRAP_CONFIG exists + * then use its value as the bootstrap config. + * + * If the value is malformed, return an error. + * + * See: https://github.com/grpc/grpc-node/issues/1868 + */ + const bootstrapConfig = process.env.GRPC_XDS_BOOTSTRAP_CONFIG; + if (bootstrapConfig) { + try { + const parsedConfig = JSON.parse(bootstrapConfig); + const loadedBootstrapInfoValue = validateBootstrapFile(parsedConfig); + loadedBootstrapInfo = Promise.resolve(loadedBootstrapInfoValue); + } catch (e) { + throw new Error( + `Failed to parse xDS bootstrap config from process.env.GRPC_XDS_BOOTSTRAP_CONFIG with error ${e.message}` + ); + } + + return loadedBootstrapInfo; + } + + return Promise.reject( + new Error( + 'The GRPC_XDS_BOOTSTRAP environment variable needs to be set to the path to the bootstrap file to use xDS' + ) + ); } From 6404ef7014b24d1cba2434fd57af7f0d85cd92e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Huan=20LI=20=28=E6=9D=8E=E5=8D=93=E6=A1=93=29?= Date: Mon, 2 Aug 2021 11:32:21 +0800 Subject: [PATCH 053/450] better error msg for both env vars --- packages/grpc-js-xds/src/xds-bootstrap.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/src/xds-bootstrap.ts b/packages/grpc-js-xds/src/xds-bootstrap.ts index 28e926058..830ad0bba 100644 --- a/packages/grpc-js-xds/src/xds-bootstrap.ts +++ b/packages/grpc-js-xds/src/xds-bootstrap.ts @@ -303,7 +303,7 @@ export async function loadBootstrapInfo(): Promise { return Promise.reject( new Error( - 'The GRPC_XDS_BOOTSTRAP environment variable needs to be set to the path to the bootstrap file to use xDS' + 'The GRPC_XDS_BOOTSTRAP or GRPC_XDS_BOOTSTRAP_CONFIG environment variables need to be set to the path to the bootstrap file to use xDS' ) ); } From d9bbd013f4b3090f780f7916ac1b5ff66a891e93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Huan=20=28=E6=9D=8E=E5=8D=93=E6=A1=93=29?= Date: Tue, 3 Aug 2021 00:31:07 +0800 Subject: [PATCH 054/450] Update xds-bootstrap.ts --- packages/grpc-js-xds/src/xds-bootstrap.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/src/xds-bootstrap.ts b/packages/grpc-js-xds/src/xds-bootstrap.ts index 830ad0bba..64a7bcb94 100644 --- a/packages/grpc-js-xds/src/xds-bootstrap.ts +++ b/packages/grpc-js-xds/src/xds-bootstrap.ts @@ -294,7 +294,7 @@ export async function loadBootstrapInfo(): Promise { loadedBootstrapInfo = Promise.resolve(loadedBootstrapInfoValue); } catch (e) { throw new Error( - `Failed to parse xDS bootstrap config from process.env.GRPC_XDS_BOOTSTRAP_CONFIG with error ${e.message}` + `Failed to parse xDS bootstrap config from environment variable GRPC_XDS_BOOTSTRAP_CONFIG with error ${e.message}` ); } From faaad56c73a2f8982e92f8c71f218c78bb3408bc Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 3 Aug 2021 14:57:58 -0700 Subject: [PATCH 055/450] grpc-js-xds: Regenerate files with new proto-loader version --- packages/grpc-js-xds/src/generated/ads.ts | 10 +- packages/grpc-js-xds/src/generated/cluster.ts | 2 +- .../grpc-js-xds/src/generated/endpoint.ts | 2 +- .../envoy/api/v2/DeltaDiscoveryRequest.ts | 8 +- .../envoy/api/v2/DiscoveryRequest.ts | 8 +- .../envoy/api/v2/DiscoveryResponse.ts | 4 +- .../src/generated/envoy/api/v2/Resource.ts | 4 +- .../generated/envoy/api/v2/core/Address.ts | 8 +- .../envoy/api/v2/core/AsyncDataSource.ts | 8 +- .../envoy/api/v2/core/BackoffStrategy.ts | 8 +- .../generated/envoy/api/v2/core/BindConfig.ts | 8 +- .../envoy/api/v2/core/BuildVersion.ts | 8 +- .../generated/envoy/api/v2/core/CidrRange.ts | 4 +- .../generated/envoy/api/v2/core/Extension.ts | 4 +- .../envoy/api/v2/core/HeaderValueOption.ts | 8 +- .../generated/envoy/api/v2/core/HttpUri.ts | 4 +- .../generated/envoy/api/v2/core/Metadata.ts | 2 +- .../src/generated/envoy/api/v2/core/Node.ts | 12 +- .../envoy/api/v2/core/RemoteDataSource.ts | 8 +- .../envoy/api/v2/core/RetryPolicy.ts | 8 +- .../envoy/api/v2/core/RuntimeFeatureFlag.ts | 4 +- .../api/v2/core/RuntimeFractionalPercent.ts | 4 +- .../envoy/api/v2/core/TcpKeepalive.ts | 12 +- .../envoy/api/v2/core/TransportSocket.ts | 8 +- .../envoy/api/v2/endpoint/ClusterStats.ts | 4 +- .../api/v2/endpoint/UpstreamEndpointStats.ts | 8 +- .../api/v2/endpoint/UpstreamLocalityStats.ts | 4 +- .../envoy/config/accesslog/v3/AccessLog.ts | 8 +- .../config/accesslog/v3/AccessLogFilter.ts | 48 ++-- .../config/accesslog/v3/ComparisonFilter.ts | 4 +- .../config/accesslog/v3/DurationFilter.ts | 4 +- .../config/accesslog/v3/ExtensionFilter.ts | 4 +- .../envoy/config/accesslog/v3/HeaderFilter.ts | 4 +- .../config/accesslog/v3/MetadataFilter.ts | 8 +- .../config/accesslog/v3/RuntimeFilter.ts | 4 +- .../config/accesslog/v3/StatusCodeFilter.ts | 4 +- .../config/cluster/v3/CircuitBreakers.ts | 32 +-- .../envoy/config/cluster/v3/Cluster.ts | 210 +++++++++--------- .../config/cluster/v3/ClusterCollection.ts | 4 +- .../envoy/config/cluster/v3/Filter.ts | 4 +- .../config/cluster/v3/LoadBalancingPolicy.ts | 4 +- .../config/cluster/v3/OutlierDetection.ts | 80 +++---- .../config/cluster/v3/UpstreamBindConfig.ts | 4 +- .../cluster/v3/UpstreamConnectionOptions.ts | 4 +- .../generated/envoy/config/core/v3/Address.ts | 12 +- .../envoy/config/core/v3/ApiConfigSource.ts | 12 +- .../envoy/config/core/v3/AsyncDataSource.ts | 8 +- .../envoy/config/core/v3/BackoffStrategy.ts | 8 +- .../envoy/config/core/v3/BindConfig.ts | 8 +- .../envoy/config/core/v3/BuildVersion.ts | 8 +- .../envoy/config/core/v3/CidrRange.ts | 4 +- .../envoy/config/core/v3/ConfigSource.ts | 16 +- .../config/core/v3/EventServiceConfig.ts | 4 +- .../envoy/config/core/v3/Extension.ts | 4 +- .../config/core/v3/ExtensionConfigSource.ts | 8 +- .../config/core/v3/GrpcProtocolOptions.ts | 4 +- .../envoy/config/core/v3/GrpcService.ts | 78 +++---- .../envoy/config/core/v3/HeaderValueOption.ts | 8 +- .../envoy/config/core/v3/HealthCheck.ts | 100 ++++----- .../config/core/v3/Http1ProtocolOptions.ts | 16 +- .../config/core/v3/Http2ProtocolOptions.ts | 52 ++--- .../config/core/v3/HttpProtocolOptions.ts | 16 +- .../generated/envoy/config/core/v3/HttpUri.ts | 4 +- .../envoy/config/core/v3/KeepaliveSettings.ts | 12 +- .../envoy/config/core/v3/Metadata.ts | 2 +- .../generated/envoy/config/core/v3/Node.ts | 12 +- .../envoy/config/core/v3/RateLimitSettings.ts | 8 +- .../envoy/config/core/v3/RemoteDataSource.ts | 8 +- .../envoy/config/core/v3/RetryPolicy.ts | 8 +- .../config/core/v3/RuntimeFeatureFlag.ts | 4 +- .../core/v3/RuntimeFractionalPercent.ts | 4 +- .../envoy/config/core/v3/RuntimePercent.ts | 4 +- .../core/v3/SubstitutionFormatString.ts | 8 +- .../envoy/config/core/v3/TcpKeepalive.ts | 12 +- .../envoy/config/core/v3/TransportSocket.ts | 4 +- .../config/core/v3/TypedExtensionConfig.ts | 4 +- .../endpoint/v3/ClusterLoadAssignment.ts | 18 +- .../envoy/config/endpoint/v3/ClusterStats.ts | 4 +- .../envoy/config/endpoint/v3/Endpoint.ts | 8 +- .../envoy/config/endpoint/v3/LbEndpoint.ts | 12 +- .../config/endpoint/v3/LocalityLbEndpoints.ts | 12 +- .../endpoint/v3/UpstreamEndpointStats.ts | 8 +- .../endpoint/v3/UpstreamLocalityStats.ts | 4 +- .../envoy/config/listener/v3/ApiListener.ts | 4 +- .../envoy/config/listener/v3/Filter.ts | 8 +- .../envoy/config/listener/v3/FilterChain.ts | 28 +-- .../config/listener/v3/FilterChainMatch.ts | 8 +- .../envoy/config/listener/v3/Listener.ts | 72 +++--- .../config/listener/v3/ListenerFilter.ts | 8 +- .../v3/ListenerFilterChainMatchPredicate.ts | 16 +- .../config/listener/v3/UdpListenerConfig.ts | 4 +- .../envoy/config/route/v3/CorsPolicy.ts | 12 +- .../envoy/config/route/v3/Decorator.ts | 4 +- .../config/route/v3/DirectResponseAction.ts | 4 +- .../envoy/config/route/v3/FilterAction.ts | 4 +- .../envoy/config/route/v3/FilterConfig.ts | 4 +- .../envoy/config/route/v3/HeaderMatcher.ts | 8 +- .../envoy/config/route/v3/HedgePolicy.ts | 8 +- .../config/route/v3/InternalRedirectPolicy.ts | 4 +- .../config/route/v3/QueryParameterMatcher.ts | 4 +- .../envoy/config/route/v3/RateLimit.ts | 64 +++--- .../envoy/config/route/v3/RedirectAction.ts | 4 +- .../envoy/config/route/v3/RetryPolicy.ts | 40 ++-- .../generated/envoy/config/route/v3/Route.ts | 38 ++-- .../envoy/config/route/v3/RouteAction.ts | 128 +++++------ .../config/route/v3/RouteConfiguration.ts | 12 +- .../envoy/config/route/v3/RouteMatch.ts | 32 +-- .../route/v3/ScopedRouteConfiguration.ts | 4 +- .../envoy/config/route/v3/Tracing.ts | 12 +- .../generated/envoy/config/route/v3/Vhds.ts | 4 +- .../envoy/config/route/v3/VirtualHost.ts | 22 +- .../envoy/config/route/v3/WeightedCluster.ts | 14 +- .../envoy/config/trace/v3/Tracing.ts | 8 +- .../v3/HttpConnectionManager.ts | 116 +++++----- .../http_connection_manager/v3/HttpFilter.ts | 8 +- .../v3/LocalReplyConfig.ts | 4 +- .../network/http_connection_manager/v3/Rds.ts | 4 +- .../v3/RequestIDExtension.ts | 4 +- .../v3/ResponseMapper.ts | 16 +- .../http_connection_manager/v3/ScopedRds.ts | 4 +- .../v3/ScopedRoutes.ts | 24 +- .../v2/AggregatedDiscoveryService.ts | 6 + .../v3/AggregatedDiscoveryService.ts | 6 + .../discovery/v3/DeltaDiscoveryRequest.ts | 8 +- .../discovery/v3/DeltaDiscoveryResponse.ts | 4 +- .../service/discovery/v3/DiscoveryRequest.ts | 8 +- .../service/discovery/v3/DiscoveryResponse.ts | 4 +- .../envoy/service/discovery/v3/Resource.ts | 12 +- .../load_stats/v2/LoadReportingService.ts | 5 + .../service/load_stats/v2/LoadStatsRequest.ts | 4 +- .../load_stats/v2/LoadStatsResponse.ts | 4 +- .../load_stats/v3/LoadReportingService.ts | 5 + .../service/load_stats/v3/LoadStatsRequest.ts | 4 +- .../load_stats/v3/LoadStatsResponse.ts | 4 +- .../envoy/type/matcher/v3/DoubleMatcher.ts | 4 +- .../envoy/type/matcher/v3/ListMatcher.ts | 4 +- .../envoy/type/matcher/v3/MetadataMatcher.ts | 4 +- .../matcher/v3/RegexMatchAndSubstitute.ts | 4 +- .../envoy/type/matcher/v3/RegexMatcher.ts | 8 +- .../envoy/type/matcher/v3/StringMatcher.ts | 4 +- .../envoy/type/matcher/v3/ValueMatcher.ts | 16 +- .../envoy/type/metadata/v3/MetadataKind.ts | 16 +- .../envoy/type/tracing/v3/CustomTag.ts | 24 +- .../google/protobuf/DescriptorProto.ts | 4 +- .../google/protobuf/EnumDescriptorProto.ts | 4 +- .../generated/google/protobuf/EnumOptions.ts | 3 + .../protobuf/EnumValueDescriptorProto.ts | 4 +- .../google/protobuf/EnumValueOptions.ts | 5 + .../google/protobuf/FieldDescriptorProto.ts | 4 +- .../generated/google/protobuf/FieldOptions.ts | 11 +- .../google/protobuf/FileDescriptorProto.ts | 8 +- .../generated/google/protobuf/FileOptions.ts | 6 + .../google/protobuf/MessageOptions.ts | 6 + .../google/protobuf/MethodDescriptorProto.ts | 4 +- .../google/protobuf/OneofDescriptorProto.ts | 4 +- .../google/protobuf/ServiceDescriptorProto.ts | 4 +- .../src/generated/google/protobuf/Struct.ts | 2 +- .../src/generated/google/protobuf/Value.ts | 8 +- .../src/generated/http_connection_manager.ts | 2 +- .../grpc-js-xds/src/generated/listener.ts | 2 +- packages/grpc-js-xds/src/generated/lrs.ts | 10 +- packages/grpc-js-xds/src/generated/route.ts | 2 +- .../grpc-js-xds/src/generated/typed_struct.ts | 2 +- .../src/generated/udpa/type/v1/TypedStruct.ts | 4 +- .../src/generated/validate/DurationRules.ts | 20 +- .../src/generated/validate/FieldRules.ts | 88 ++++---- .../src/generated/validate/MapRules.ts | 8 +- .../src/generated/validate/RepeatedRules.ts | 4 +- .../src/generated/validate/TimestampRules.ts | 24 +- .../generated/xds/core/v3/CollectionEntry.ts | 12 +- .../generated/xds/core/v3/ResourceLocator.ts | 8 +- 171 files changed, 1180 insertions(+), 1131 deletions(-) diff --git a/packages/grpc-js-xds/src/generated/ads.ts b/packages/grpc-js-xds/src/generated/ads.ts index 665374958..f8e336131 100644 --- a/packages/grpc-js-xds/src/generated/ads.ts +++ b/packages/grpc-js-xds/src/generated/ads.ts @@ -1,8 +1,8 @@ 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 { AggregatedDiscoveryServiceClient as _envoy_service_discovery_v2_AggregatedDiscoveryServiceClient } from './envoy/service/discovery/v2/AggregatedDiscoveryService'; -import type { AggregatedDiscoveryServiceClient as _envoy_service_discovery_v3_AggregatedDiscoveryServiceClient } from './envoy/service/discovery/v3/AggregatedDiscoveryService'; +import type { AggregatedDiscoveryServiceClient as _envoy_service_discovery_v2_AggregatedDiscoveryServiceClient, AggregatedDiscoveryServiceDefinition as _envoy_service_discovery_v2_AggregatedDiscoveryServiceDefinition } from './envoy/service/discovery/v2/AggregatedDiscoveryService'; +import type { AggregatedDiscoveryServiceClient as _envoy_service_discovery_v3_AggregatedDiscoveryServiceClient, AggregatedDiscoveryServiceDefinition as _envoy_service_discovery_v3_AggregatedDiscoveryServiceDefinition } from './envoy/service/discovery/v3/AggregatedDiscoveryService'; type SubtypeConstructor any, Subtype> = { new(...args: ConstructorParameters): Subtype; @@ -102,7 +102,7 @@ export interface ProtoGrpcType { * DiscoveryRequest/DiscoveryResponse provides sufficient information to recover * the multiplexed singleton APIs at the Envoy instance and management server. */ - AggregatedDiscoveryService: SubtypeConstructor & { service: ServiceDefinition } + AggregatedDiscoveryService: SubtypeConstructor & { service: _envoy_service_discovery_v2_AggregatedDiscoveryServiceDefinition } } v3: { AdsDummy: MessageTypeDefinition @@ -114,7 +114,7 @@ export interface ProtoGrpcType { * DiscoveryRequest/DiscoveryResponse provides sufficient information to recover * the multiplexed singleton APIs at the Envoy instance and management server. */ - AggregatedDiscoveryService: SubtypeConstructor & { service: ServiceDefinition } + AggregatedDiscoveryService: SubtypeConstructor & { service: _envoy_service_discovery_v3_AggregatedDiscoveryServiceDefinition } DeltaDiscoveryRequest: MessageTypeDefinition DeltaDiscoveryResponse: MessageTypeDefinition DiscoveryRequest: MessageTypeDefinition diff --git a/packages/grpc-js-xds/src/generated/cluster.ts b/packages/grpc-js-xds/src/generated/cluster.ts index 5e4683580..bc4465a30 100644 --- a/packages/grpc-js-xds/src/generated/cluster.ts +++ b/packages/grpc-js-xds/src/generated/cluster.ts @@ -1,5 +1,5 @@ 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'; type SubtypeConstructor any, Subtype> = { diff --git a/packages/grpc-js-xds/src/generated/endpoint.ts b/packages/grpc-js-xds/src/generated/endpoint.ts index dda6a78da..630bdeb62 100644 --- a/packages/grpc-js-xds/src/generated/endpoint.ts +++ b/packages/grpc-js-xds/src/generated/endpoint.ts @@ -1,5 +1,5 @@ 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'; type SubtypeConstructor any, Subtype> = { diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/DeltaDiscoveryRequest.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/DeltaDiscoveryRequest.ts index 11cbe8c2c..20ddb1b14 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/DeltaDiscoveryRequest.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/DeltaDiscoveryRequest.ts @@ -42,7 +42,7 @@ export interface DeltaDiscoveryRequest { /** * The node making the request. */ - 'node'?: (_envoy_api_v2_core_Node); + 'node'?: (_envoy_api_v2_core_Node | null); /** * Type of the resource that is being requested, e.g. * "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment". @@ -99,7 +99,7 @@ export interface DeltaDiscoveryRequest { * failed to update configuration. The *message* field in *error_details* * provides the Envoy internal exception related to the failure. */ - 'error_detail'?: (_google_rpc_Status); + 'error_detail'?: (_google_rpc_Status | null); } /** @@ -141,7 +141,7 @@ export interface DeltaDiscoveryRequest__Output { /** * The node making the request. */ - 'node'?: (_envoy_api_v2_core_Node__Output); + 'node': (_envoy_api_v2_core_Node__Output | null); /** * Type of the resource that is being requested, e.g. * "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment". @@ -198,5 +198,5 @@ export interface DeltaDiscoveryRequest__Output { * failed to update configuration. The *message* field in *error_details* * provides the Envoy internal exception related to the failure. */ - 'error_detail'?: (_google_rpc_Status__Output); + 'error_detail': (_google_rpc_Status__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/DiscoveryRequest.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/DiscoveryRequest.ts index 2150c41bc..2386e71c4 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/DiscoveryRequest.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/DiscoveryRequest.ts @@ -22,7 +22,7 @@ export interface DiscoveryRequest { /** * The node making the request. */ - 'node'?: (_envoy_api_v2_core_Node); + 'node'?: (_envoy_api_v2_core_Node | null); /** * List of resources to subscribe to, e.g. list of cluster names or a route * configuration name. If this is empty, all resources for the API are @@ -53,7 +53,7 @@ export interface DiscoveryRequest { * internal exception related to the failure. It is only intended for consumption during manual * debugging, the string provided is not guaranteed to be stable across Envoy versions. */ - 'error_detail'?: (_google_rpc_Status); + 'error_detail'?: (_google_rpc_Status | null); } /** @@ -75,7 +75,7 @@ export interface DiscoveryRequest__Output { /** * The node making the request. */ - 'node'?: (_envoy_api_v2_core_Node__Output); + 'node': (_envoy_api_v2_core_Node__Output | null); /** * List of resources to subscribe to, e.g. list of cluster names or a route * configuration name. If this is empty, all resources for the API are @@ -106,5 +106,5 @@ export interface DiscoveryRequest__Output { * internal exception related to the failure. It is only intended for consumption during manual * debugging, the string provided is not guaranteed to be stable across Envoy versions. */ - 'error_detail'?: (_google_rpc_Status__Output); + 'error_detail': (_google_rpc_Status__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/DiscoveryResponse.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/DiscoveryResponse.ts index dd7e70d4d..179143c67 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/DiscoveryResponse.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/DiscoveryResponse.ts @@ -52,7 +52,7 @@ export interface DiscoveryResponse { * [#not-implemented-hide:] * The control plane instance that sent the response. */ - 'control_plane'?: (_envoy_api_v2_core_ControlPlane); + 'control_plane'?: (_envoy_api_v2_core_ControlPlane | null); } /** @@ -104,5 +104,5 @@ export interface DiscoveryResponse__Output { * [#not-implemented-hide:] * The control plane instance that sent the response. */ - 'control_plane'?: (_envoy_api_v2_core_ControlPlane__Output); + 'control_plane': (_envoy_api_v2_core_ControlPlane__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/Resource.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/Resource.ts index 4804201bd..6ce856ee7 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/Resource.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/Resource.ts @@ -11,7 +11,7 @@ export interface Resource { /** * The resource being tracked. */ - 'resource'?: (_google_protobuf_Any); + 'resource'?: (_google_protobuf_Any | null); /** * The resource's name, to distinguish it from others of the same type of resource. */ @@ -31,7 +31,7 @@ export interface Resource__Output { /** * The resource being tracked. */ - 'resource'?: (_google_protobuf_Any__Output); + 'resource': (_google_protobuf_Any__Output | null); /** * The resource's name, to distinguish it from others of the same type of resource. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Address.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Address.ts index b12c8d9b0..65044b74a 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Address.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Address.ts @@ -9,8 +9,8 @@ import type { Pipe as _envoy_api_v2_core_Pipe, Pipe__Output as _envoy_api_v2_cor * management servers. */ export interface Address { - 'socket_address'?: (_envoy_api_v2_core_SocketAddress); - 'pipe'?: (_envoy_api_v2_core_Pipe); + 'socket_address'?: (_envoy_api_v2_core_SocketAddress | null); + 'pipe'?: (_envoy_api_v2_core_Pipe | null); 'address'?: "socket_address"|"pipe"; } @@ -20,7 +20,7 @@ export interface Address { * management servers. */ export interface Address__Output { - 'socket_address'?: (_envoy_api_v2_core_SocketAddress__Output); - 'pipe'?: (_envoy_api_v2_core_Pipe__Output); + 'socket_address'?: (_envoy_api_v2_core_SocketAddress__Output | null); + 'pipe'?: (_envoy_api_v2_core_Pipe__Output | null); 'address': "socket_address"|"pipe"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/AsyncDataSource.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/AsyncDataSource.ts index fb312bb40..139f82689 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/AsyncDataSource.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/AsyncDataSource.ts @@ -10,11 +10,11 @@ export interface AsyncDataSource { /** * Local async data source. */ - 'local'?: (_envoy_api_v2_core_DataSource); + 'local'?: (_envoy_api_v2_core_DataSource | null); /** * Remote async data source. */ - 'remote'?: (_envoy_api_v2_core_RemoteDataSource); + 'remote'?: (_envoy_api_v2_core_RemoteDataSource | null); 'specifier'?: "local"|"remote"; } @@ -25,10 +25,10 @@ export interface AsyncDataSource__Output { /** * Local async data source. */ - 'local'?: (_envoy_api_v2_core_DataSource__Output); + 'local'?: (_envoy_api_v2_core_DataSource__Output | null); /** * Remote async data source. */ - 'remote'?: (_envoy_api_v2_core_RemoteDataSource__Output); + 'remote'?: (_envoy_api_v2_core_RemoteDataSource__Output | null); 'specifier': "local"|"remote"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BackoffStrategy.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BackoffStrategy.ts index 48f9d904d..173aff0e1 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BackoffStrategy.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BackoffStrategy.ts @@ -11,7 +11,7 @@ export interface BackoffStrategy { * be greater than zero and less than or equal to :ref:`max_interval * `. */ - 'base_interval'?: (_google_protobuf_Duration); + 'base_interval'?: (_google_protobuf_Duration | null); /** * Specifies the maximum interval between retries. This parameter is optional, * but must be greater than or equal to the :ref:`base_interval @@ -19,7 +19,7 @@ export interface BackoffStrategy { * is 10 times the :ref:`base_interval * `. */ - 'max_interval'?: (_google_protobuf_Duration); + 'max_interval'?: (_google_protobuf_Duration | null); } /** @@ -31,7 +31,7 @@ export interface BackoffStrategy__Output { * be greater than zero and less than or equal to :ref:`max_interval * `. */ - 'base_interval'?: (_google_protobuf_Duration__Output); + 'base_interval': (_google_protobuf_Duration__Output | null); /** * Specifies the maximum interval between retries. This parameter is optional, * but must be greater than or equal to the :ref:`base_interval @@ -39,5 +39,5 @@ export interface BackoffStrategy__Output { * is 10 times the :ref:`base_interval * `. */ - 'max_interval'?: (_google_protobuf_Duration__Output); + 'max_interval': (_google_protobuf_Duration__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BindConfig.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BindConfig.ts index f989494ea..d4765c1ba 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BindConfig.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BindConfig.ts @@ -8,7 +8,7 @@ export interface BindConfig { /** * The address to bind to when creating a socket. */ - 'source_address'?: (_envoy_api_v2_core_SocketAddress); + 'source_address'?: (_envoy_api_v2_core_SocketAddress | null); /** * Whether to set the *IP_FREEBIND* option when creating the socket. When this * flag is set to true, allows the :ref:`source_address @@ -18,7 +18,7 @@ export interface BindConfig { * flag is not set (default), the socket is not modified, i.e. the option is * neither enabled nor disabled. */ - 'freebind'?: (_google_protobuf_BoolValue); + 'freebind'?: (_google_protobuf_BoolValue | null); /** * Additional socket options that may not be present in Envoy source code or * precompiled binaries. @@ -30,7 +30,7 @@ export interface BindConfig__Output { /** * The address to bind to when creating a socket. */ - 'source_address'?: (_envoy_api_v2_core_SocketAddress__Output); + 'source_address': (_envoy_api_v2_core_SocketAddress__Output | null); /** * Whether to set the *IP_FREEBIND* option when creating the socket. When this * flag is set to true, allows the :ref:`source_address @@ -40,7 +40,7 @@ export interface BindConfig__Output { * flag is not set (default), the socket is not modified, i.e. the option is * neither enabled nor disabled. */ - 'freebind'?: (_google_protobuf_BoolValue__Output); + 'freebind': (_google_protobuf_BoolValue__Output | null); /** * Additional socket options that may not be present in Envoy source code or * precompiled binaries. diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BuildVersion.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BuildVersion.ts index 50a44a3b2..a33015d89 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BuildVersion.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BuildVersion.ts @@ -11,12 +11,12 @@ export interface BuildVersion { /** * SemVer version of extension. */ - 'version'?: (_envoy_type_SemanticVersion); + 'version'?: (_envoy_type_SemanticVersion | null); /** * Free-form build information. * Envoy defines several well known keys in the source/common/version/version.h file */ - 'metadata'?: (_google_protobuf_Struct); + 'metadata'?: (_google_protobuf_Struct | null); } /** @@ -27,10 +27,10 @@ export interface BuildVersion__Output { /** * SemVer version of extension. */ - 'version'?: (_envoy_type_SemanticVersion__Output); + 'version': (_envoy_type_SemanticVersion__Output | null); /** * Free-form build information. * Envoy defines several well known keys in the source/common/version/version.h file */ - 'metadata'?: (_google_protobuf_Struct__Output); + 'metadata': (_google_protobuf_Struct__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/CidrRange.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/CidrRange.ts index 00c67734f..cca1bc2d8 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/CidrRange.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/CidrRange.ts @@ -14,7 +14,7 @@ export interface CidrRange { /** * Length of prefix, e.g. 0, 32. */ - 'prefix_len'?: (_google_protobuf_UInt32Value); + 'prefix_len'?: (_google_protobuf_UInt32Value | null); } /** @@ -29,5 +29,5 @@ export interface CidrRange__Output { /** * Length of prefix, e.g. 0, 32. */ - 'prefix_len'?: (_google_protobuf_UInt32Value__Output); + 'prefix_len': (_google_protobuf_UInt32Value__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Extension.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Extension.ts index 418c7a360..67c5e1736 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Extension.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Extension.ts @@ -31,7 +31,7 @@ export interface Extension { * of other extensions and the Envoy API. * This field is not set when extension did not provide version information. */ - 'version'?: (_envoy_api_v2_core_BuildVersion); + 'version'?: (_envoy_api_v2_core_BuildVersion | null); /** * Indicates that the extension is present but was disabled via dynamic configuration. */ @@ -67,7 +67,7 @@ export interface Extension__Output { * of other extensions and the Envoy API. * This field is not set when extension did not provide version information. */ - 'version'?: (_envoy_api_v2_core_BuildVersion__Output); + 'version': (_envoy_api_v2_core_BuildVersion__Output | null); /** * Indicates that the extension is present but was disabled via dynamic configuration. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HeaderValueOption.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HeaderValueOption.ts index b90bd85e1..12421d8f4 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HeaderValueOption.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HeaderValueOption.ts @@ -10,12 +10,12 @@ export interface HeaderValueOption { /** * Header name/value pair that this option applies to. */ - 'header'?: (_envoy_api_v2_core_HeaderValue); + 'header'?: (_envoy_api_v2_core_HeaderValue | null); /** * Should the value be appended? If true (default), the value is appended to * existing values. */ - 'append'?: (_google_protobuf_BoolValue); + 'append'?: (_google_protobuf_BoolValue | null); } /** @@ -25,10 +25,10 @@ export interface HeaderValueOption__Output { /** * Header name/value pair that this option applies to. */ - 'header'?: (_envoy_api_v2_core_HeaderValue__Output); + 'header': (_envoy_api_v2_core_HeaderValue__Output | null); /** * Should the value be appended? If true (default), the value is appended to * existing values. */ - 'append'?: (_google_protobuf_BoolValue__Output); + 'append': (_google_protobuf_BoolValue__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HttpUri.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HttpUri.ts index 19711dde7..c206a2454 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HttpUri.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HttpUri.ts @@ -30,7 +30,7 @@ export interface HttpUri { /** * Sets the maximum duration in milliseconds that a response can take to arrive upon request. */ - 'timeout'?: (_google_protobuf_Duration); + 'timeout'?: (_google_protobuf_Duration | null); /** * Specify how `uri` is to be fetched. Today, this requires an explicit * cluster, but in the future we may support dynamic cluster creation or @@ -68,7 +68,7 @@ export interface HttpUri__Output { /** * Sets the maximum duration in milliseconds that a response can take to arrive upon request. */ - 'timeout'?: (_google_protobuf_Duration__Output); + 'timeout': (_google_protobuf_Duration__Output | null); /** * Specify how `uri` is to be fetched. Today, this requires an explicit * cluster, but in the future we may support dynamic cluster creation or diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Metadata.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Metadata.ts index ca823a27c..7a6871eeb 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Metadata.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Metadata.ts @@ -63,5 +63,5 @@ export interface Metadata__Output { * Key is the reverse DNS filter name, e.g. com.acme.widget. The envoy.* * namespace is reserved for Envoy's built-in filters. */ - 'filter_metadata'?: ({[key: string]: _google_protobuf_Struct__Output}); + 'filter_metadata': ({[key: string]: _google_protobuf_Struct__Output}); } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Node.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Node.ts index c6ddea9d4..ddf10f08b 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Node.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Node.ts @@ -41,11 +41,11 @@ export interface Node { * Opaque metadata extending the node identifier. Envoy will pass this * directly to the management server. */ - 'metadata'?: (_google_protobuf_Struct); + 'metadata'?: (_google_protobuf_Struct | null); /** * Locality specifying where the Envoy instance is running. */ - 'locality'?: (_envoy_api_v2_core_Locality); + 'locality'?: (_envoy_api_v2_core_Locality | null); /** * This is motivated by informing a management server during canary which * version of Envoy is being tested in a heterogeneous fleet. This will be set @@ -66,7 +66,7 @@ export interface Node { /** * Structured version of the entity requesting config. */ - 'user_agent_build_version'?: (_envoy_api_v2_core_BuildVersion); + 'user_agent_build_version'?: (_envoy_api_v2_core_BuildVersion | null); /** * List of extensions and their versions supported by the node. */ @@ -124,11 +124,11 @@ export interface Node__Output { * Opaque metadata extending the node identifier. Envoy will pass this * directly to the management server. */ - 'metadata'?: (_google_protobuf_Struct__Output); + 'metadata': (_google_protobuf_Struct__Output | null); /** * Locality specifying where the Envoy instance is running. */ - 'locality'?: (_envoy_api_v2_core_Locality__Output); + 'locality': (_envoy_api_v2_core_Locality__Output | null); /** * This is motivated by informing a management server during canary which * version of Envoy is being tested in a heterogeneous fleet. This will be set @@ -149,7 +149,7 @@ export interface Node__Output { /** * Structured version of the entity requesting config. */ - 'user_agent_build_version'?: (_envoy_api_v2_core_BuildVersion__Output); + 'user_agent_build_version'?: (_envoy_api_v2_core_BuildVersion__Output | null); /** * List of extensions and their versions supported by the node. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RemoteDataSource.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RemoteDataSource.ts index 93e722eef..516dbf864 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RemoteDataSource.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RemoteDataSource.ts @@ -10,7 +10,7 @@ export interface RemoteDataSource { /** * The HTTP URI to fetch the remote data. */ - 'http_uri'?: (_envoy_api_v2_core_HttpUri); + 'http_uri'?: (_envoy_api_v2_core_HttpUri | null); /** * SHA256 string for verifying data. */ @@ -18,7 +18,7 @@ export interface RemoteDataSource { /** * Retry policy for fetching remote data. */ - 'retry_policy'?: (_envoy_api_v2_core_RetryPolicy); + 'retry_policy'?: (_envoy_api_v2_core_RetryPolicy | null); } /** @@ -28,7 +28,7 @@ export interface RemoteDataSource__Output { /** * The HTTP URI to fetch the remote data. */ - 'http_uri'?: (_envoy_api_v2_core_HttpUri__Output); + 'http_uri': (_envoy_api_v2_core_HttpUri__Output | null); /** * SHA256 string for verifying data. */ @@ -36,5 +36,5 @@ export interface RemoteDataSource__Output { /** * Retry policy for fetching remote data. */ - 'retry_policy'?: (_envoy_api_v2_core_RetryPolicy__Output); + 'retry_policy': (_envoy_api_v2_core_RetryPolicy__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RetryPolicy.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RetryPolicy.ts index 27c1096b7..7ff35e375 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RetryPolicy.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RetryPolicy.ts @@ -12,12 +12,12 @@ export interface RetryPolicy { * This parameter is optional, in which case the default base interval is 1000 milliseconds. The * default maximum interval is 10 times the base interval. */ - 'retry_back_off'?: (_envoy_api_v2_core_BackoffStrategy); + 'retry_back_off'?: (_envoy_api_v2_core_BackoffStrategy | null); /** * Specifies the allowed number of retries. This parameter is optional and * defaults to 1. */ - 'num_retries'?: (_google_protobuf_UInt32Value); + 'num_retries'?: (_google_protobuf_UInt32Value | null); } /** @@ -29,10 +29,10 @@ export interface RetryPolicy__Output { * This parameter is optional, in which case the default base interval is 1000 milliseconds. The * default maximum interval is 10 times the base interval. */ - 'retry_back_off'?: (_envoy_api_v2_core_BackoffStrategy__Output); + 'retry_back_off': (_envoy_api_v2_core_BackoffStrategy__Output | null); /** * Specifies the allowed number of retries. This parameter is optional and * defaults to 1. */ - 'num_retries'?: (_google_protobuf_UInt32Value__Output); + 'num_retries': (_google_protobuf_UInt32Value__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeFeatureFlag.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeFeatureFlag.ts index 47cf24097..4ad57de46 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeFeatureFlag.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeFeatureFlag.ts @@ -9,7 +9,7 @@ export interface RuntimeFeatureFlag { /** * Default value if runtime value is not available. */ - 'default_value'?: (_google_protobuf_BoolValue); + 'default_value'?: (_google_protobuf_BoolValue | null); /** * Runtime key to get value for comparison. This value is used if defined. The boolean value must * be represented via its @@ -25,7 +25,7 @@ export interface RuntimeFeatureFlag__Output { /** * Default value if runtime value is not available. */ - 'default_value'?: (_google_protobuf_BoolValue__Output); + 'default_value': (_google_protobuf_BoolValue__Output | null); /** * Runtime key to get value for comparison. This value is used if defined. The boolean value must * be represented via its diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeFractionalPercent.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeFractionalPercent.ts index 08e29de1f..a168af60c 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeFractionalPercent.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeFractionalPercent.ts @@ -18,7 +18,7 @@ export interface RuntimeFractionalPercent { /** * Default value if the runtime value's for the numerator/denominator keys are not available. */ - 'default_value'?: (_envoy_type_FractionalPercent); + 'default_value'?: (_envoy_type_FractionalPercent | null); /** * Runtime key for a YAML representation of a FractionalPercent. */ @@ -41,7 +41,7 @@ export interface RuntimeFractionalPercent__Output { /** * Default value if the runtime value's for the numerator/denominator keys are not available. */ - 'default_value'?: (_envoy_type_FractionalPercent__Output); + 'default_value': (_envoy_type_FractionalPercent__Output | null); /** * Runtime key for a YAML representation of a FractionalPercent. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/TcpKeepalive.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/TcpKeepalive.ts index 394a54feb..e9d805c76 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/TcpKeepalive.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/TcpKeepalive.ts @@ -8,18 +8,18 @@ export interface TcpKeepalive { * the connection is dead. Default is to use the OS level configuration (unless * overridden, Linux defaults to 9.) */ - 'keepalive_probes'?: (_google_protobuf_UInt32Value); + 'keepalive_probes'?: (_google_protobuf_UInt32Value | null); /** * The number of seconds a connection needs to be idle before keep-alive probes * start being sent. Default is to use the OS level configuration (unless * overridden, Linux defaults to 7200s (i.e., 2 hours.) */ - 'keepalive_time'?: (_google_protobuf_UInt32Value); + 'keepalive_time'?: (_google_protobuf_UInt32Value | null); /** * The number of seconds between keep-alive probes. Default is to use the OS * level configuration (unless overridden, Linux defaults to 75s.) */ - 'keepalive_interval'?: (_google_protobuf_UInt32Value); + 'keepalive_interval'?: (_google_protobuf_UInt32Value | null); } export interface TcpKeepalive__Output { @@ -28,16 +28,16 @@ export interface TcpKeepalive__Output { * the connection is dead. Default is to use the OS level configuration (unless * overridden, Linux defaults to 9.) */ - 'keepalive_probes'?: (_google_protobuf_UInt32Value__Output); + 'keepalive_probes': (_google_protobuf_UInt32Value__Output | null); /** * The number of seconds a connection needs to be idle before keep-alive probes * start being sent. Default is to use the OS level configuration (unless * overridden, Linux defaults to 7200s (i.e., 2 hours.) */ - 'keepalive_time'?: (_google_protobuf_UInt32Value__Output); + 'keepalive_time': (_google_protobuf_UInt32Value__Output | null); /** * The number of seconds between keep-alive probes. Default is to use the OS * level configuration (unless overridden, Linux defaults to 75s.) */ - 'keepalive_interval'?: (_google_protobuf_UInt32Value__Output); + 'keepalive_interval': (_google_protobuf_UInt32Value__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/TransportSocket.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/TransportSocket.ts index b45767eb2..87fbcaf38 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/TransportSocket.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/TransportSocket.ts @@ -15,8 +15,8 @@ export interface TransportSocket { * socket implementation. */ 'name'?: (string); - 'config'?: (_google_protobuf_Struct); - 'typed_config'?: (_google_protobuf_Any); + 'config'?: (_google_protobuf_Struct | null); + 'typed_config'?: (_google_protobuf_Any | null); /** * Implementation specific configuration which depends on the implementation being instantiated. * See the supported transport socket implementations for further documentation. @@ -36,8 +36,8 @@ export interface TransportSocket__Output { * socket implementation. */ 'name': (string); - 'config'?: (_google_protobuf_Struct__Output); - 'typed_config'?: (_google_protobuf_Any__Output); + 'config'?: (_google_protobuf_Struct__Output | null); + 'typed_config'?: (_google_protobuf_Any__Output | null); /** * Implementation specific configuration which depends on the implementation being instantiated. * See the supported transport socket implementations for further documentation. diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/ClusterStats.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/ClusterStats.ts index 4b5c30f4c..3609ea1e4 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/ClusterStats.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/ClusterStats.ts @@ -57,7 +57,7 @@ export interface ClusterStats { * and the *LoadStatsResponse* message sent from the management server, this may be longer than * the requested load reporting interval in the *LoadStatsResponse*. */ - 'load_report_interval'?: (_google_protobuf_Duration); + 'load_report_interval'?: (_google_protobuf_Duration | null); /** * Information about deliberately dropped requests for each category specified * in the DropOverload policy. @@ -102,7 +102,7 @@ export interface ClusterStats__Output { * and the *LoadStatsResponse* message sent from the management server, this may be longer than * the requested load reporting interval in the *LoadStatsResponse*. */ - 'load_report_interval'?: (_google_protobuf_Duration__Output); + 'load_report_interval': (_google_protobuf_Duration__Output | null); /** * Information about deliberately dropped requests for each category specified * in the DropOverload policy. diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/UpstreamEndpointStats.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/UpstreamEndpointStats.ts index 5b5c62b32..e4551bd37 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/UpstreamEndpointStats.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/UpstreamEndpointStats.ts @@ -13,7 +13,7 @@ export interface UpstreamEndpointStats { /** * Upstream host address. */ - 'address'?: (_envoy_api_v2_core_Address); + 'address'?: (_envoy_api_v2_core_Address | null); /** * The total number of requests successfully completed by the endpoints in the * locality. These include non-5xx responses for HTTP, where errors @@ -46,7 +46,7 @@ export interface UpstreamEndpointStats { * Opaque and implementation dependent metadata of the * endpoint. Envoy will pass this directly to the management server. */ - 'metadata'?: (_google_protobuf_Struct); + 'metadata'?: (_google_protobuf_Struct | null); /** * The total number of requests that were issued to this endpoint * since the last report. A single TCP connection, HTTP or gRPC @@ -63,7 +63,7 @@ export interface UpstreamEndpointStats__Output { /** * Upstream host address. */ - 'address'?: (_envoy_api_v2_core_Address__Output); + 'address': (_envoy_api_v2_core_Address__Output | null); /** * The total number of requests successfully completed by the endpoints in the * locality. These include non-5xx responses for HTTP, where errors @@ -96,7 +96,7 @@ export interface UpstreamEndpointStats__Output { * Opaque and implementation dependent metadata of the * endpoint. Envoy will pass this directly to the management server. */ - 'metadata'?: (_google_protobuf_Struct__Output); + 'metadata': (_google_protobuf_Struct__Output | null); /** * The total number of requests that were issued to this endpoint * since the last report. A single TCP connection, HTTP or gRPC diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/UpstreamLocalityStats.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/UpstreamLocalityStats.ts index a1b20897e..df4d4eb89 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/UpstreamLocalityStats.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/UpstreamLocalityStats.ts @@ -18,7 +18,7 @@ export interface UpstreamLocalityStats { * Name of zone, region and optionally endpoint group these metrics were * collected from. Zone and region names could be empty if unknown. */ - 'locality'?: (_envoy_api_v2_core_Locality); + 'locality'?: (_envoy_api_v2_core_Locality | null); /** * The total number of requests successfully completed by the endpoints in the * locality. @@ -69,7 +69,7 @@ export interface UpstreamLocalityStats__Output { * Name of zone, region and optionally endpoint group these metrics were * collected from. Zone and region names could be empty if unknown. */ - 'locality'?: (_envoy_api_v2_core_Locality__Output); + 'locality': (_envoy_api_v2_core_Locality__Output | null); /** * The total number of requests successfully completed by the endpoints in the * locality. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AccessLog.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AccessLog.ts index 413f569ce..369f36bc2 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AccessLog.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AccessLog.ts @@ -16,8 +16,8 @@ export interface AccessLog { /** * Filter which is used to determine if the access log needs to be written. */ - 'filter'?: (_envoy_config_accesslog_v3_AccessLogFilter); - 'typed_config'?: (_google_protobuf_Any); + 'filter'?: (_envoy_config_accesslog_v3_AccessLogFilter | null); + 'typed_config'?: (_google_protobuf_Any | null); /** * Custom configuration that depends on the access log being instantiated. * Built-in configurations include: @@ -45,8 +45,8 @@ export interface AccessLog__Output { /** * Filter which is used to determine if the access log needs to be written. */ - 'filter'?: (_envoy_config_accesslog_v3_AccessLogFilter__Output); - 'typed_config'?: (_google_protobuf_Any__Output); + 'filter': (_envoy_config_accesslog_v3_AccessLogFilter__Output | null); + 'typed_config'?: (_google_protobuf_Any__Output | null); /** * Custom configuration that depends on the access log being instantiated. * Built-in configurations include: diff --git a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AccessLogFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AccessLogFilter.ts index 9470b6eaa..85a952c9c 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AccessLogFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AccessLogFilter.ts @@ -20,51 +20,51 @@ export interface AccessLogFilter { /** * Status code filter. */ - 'status_code_filter'?: (_envoy_config_accesslog_v3_StatusCodeFilter); + 'status_code_filter'?: (_envoy_config_accesslog_v3_StatusCodeFilter | null); /** * Duration filter. */ - 'duration_filter'?: (_envoy_config_accesslog_v3_DurationFilter); + 'duration_filter'?: (_envoy_config_accesslog_v3_DurationFilter | null); /** * Not health check filter. */ - 'not_health_check_filter'?: (_envoy_config_accesslog_v3_NotHealthCheckFilter); + 'not_health_check_filter'?: (_envoy_config_accesslog_v3_NotHealthCheckFilter | null); /** * Traceable filter. */ - 'traceable_filter'?: (_envoy_config_accesslog_v3_TraceableFilter); + 'traceable_filter'?: (_envoy_config_accesslog_v3_TraceableFilter | null); /** * Runtime filter. */ - 'runtime_filter'?: (_envoy_config_accesslog_v3_RuntimeFilter); + 'runtime_filter'?: (_envoy_config_accesslog_v3_RuntimeFilter | null); /** * And filter. */ - 'and_filter'?: (_envoy_config_accesslog_v3_AndFilter); + 'and_filter'?: (_envoy_config_accesslog_v3_AndFilter | null); /** * Or filter. */ - 'or_filter'?: (_envoy_config_accesslog_v3_OrFilter); + 'or_filter'?: (_envoy_config_accesslog_v3_OrFilter | null); /** * Header filter. */ - 'header_filter'?: (_envoy_config_accesslog_v3_HeaderFilter); + 'header_filter'?: (_envoy_config_accesslog_v3_HeaderFilter | null); /** * Response flag filter. */ - 'response_flag_filter'?: (_envoy_config_accesslog_v3_ResponseFlagFilter); + 'response_flag_filter'?: (_envoy_config_accesslog_v3_ResponseFlagFilter | null); /** * gRPC status filter. */ - 'grpc_status_filter'?: (_envoy_config_accesslog_v3_GrpcStatusFilter); + 'grpc_status_filter'?: (_envoy_config_accesslog_v3_GrpcStatusFilter | null); /** * Extension filter. */ - 'extension_filter'?: (_envoy_config_accesslog_v3_ExtensionFilter); + 'extension_filter'?: (_envoy_config_accesslog_v3_ExtensionFilter | null); /** * Metadata Filter */ - 'metadata_filter'?: (_envoy_config_accesslog_v3_MetadataFilter); + 'metadata_filter'?: (_envoy_config_accesslog_v3_MetadataFilter | null); 'filter_specifier'?: "status_code_filter"|"duration_filter"|"not_health_check_filter"|"traceable_filter"|"runtime_filter"|"and_filter"|"or_filter"|"header_filter"|"response_flag_filter"|"grpc_status_filter"|"extension_filter"|"metadata_filter"; } @@ -75,50 +75,50 @@ export interface AccessLogFilter__Output { /** * Status code filter. */ - 'status_code_filter'?: (_envoy_config_accesslog_v3_StatusCodeFilter__Output); + 'status_code_filter'?: (_envoy_config_accesslog_v3_StatusCodeFilter__Output | null); /** * Duration filter. */ - 'duration_filter'?: (_envoy_config_accesslog_v3_DurationFilter__Output); + 'duration_filter'?: (_envoy_config_accesslog_v3_DurationFilter__Output | null); /** * Not health check filter. */ - 'not_health_check_filter'?: (_envoy_config_accesslog_v3_NotHealthCheckFilter__Output); + 'not_health_check_filter'?: (_envoy_config_accesslog_v3_NotHealthCheckFilter__Output | null); /** * Traceable filter. */ - 'traceable_filter'?: (_envoy_config_accesslog_v3_TraceableFilter__Output); + 'traceable_filter'?: (_envoy_config_accesslog_v3_TraceableFilter__Output | null); /** * Runtime filter. */ - 'runtime_filter'?: (_envoy_config_accesslog_v3_RuntimeFilter__Output); + 'runtime_filter'?: (_envoy_config_accesslog_v3_RuntimeFilter__Output | null); /** * And filter. */ - 'and_filter'?: (_envoy_config_accesslog_v3_AndFilter__Output); + 'and_filter'?: (_envoy_config_accesslog_v3_AndFilter__Output | null); /** * Or filter. */ - 'or_filter'?: (_envoy_config_accesslog_v3_OrFilter__Output); + 'or_filter'?: (_envoy_config_accesslog_v3_OrFilter__Output | null); /** * Header filter. */ - 'header_filter'?: (_envoy_config_accesslog_v3_HeaderFilter__Output); + 'header_filter'?: (_envoy_config_accesslog_v3_HeaderFilter__Output | null); /** * Response flag filter. */ - 'response_flag_filter'?: (_envoy_config_accesslog_v3_ResponseFlagFilter__Output); + 'response_flag_filter'?: (_envoy_config_accesslog_v3_ResponseFlagFilter__Output | null); /** * gRPC status filter. */ - 'grpc_status_filter'?: (_envoy_config_accesslog_v3_GrpcStatusFilter__Output); + 'grpc_status_filter'?: (_envoy_config_accesslog_v3_GrpcStatusFilter__Output | null); /** * Extension filter. */ - 'extension_filter'?: (_envoy_config_accesslog_v3_ExtensionFilter__Output); + 'extension_filter'?: (_envoy_config_accesslog_v3_ExtensionFilter__Output | null); /** * Metadata Filter */ - 'metadata_filter'?: (_envoy_config_accesslog_v3_MetadataFilter__Output); + 'metadata_filter'?: (_envoy_config_accesslog_v3_MetadataFilter__Output | null); 'filter_specifier': "status_code_filter"|"duration_filter"|"not_health_check_filter"|"traceable_filter"|"runtime_filter"|"and_filter"|"or_filter"|"header_filter"|"response_flag_filter"|"grpc_status_filter"|"extension_filter"|"metadata_filter"; } 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 118a47a75..07893f2dd 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 @@ -30,7 +30,7 @@ export interface ComparisonFilter { /** * Value to compare against. */ - 'value'?: (_envoy_config_core_v3_RuntimeUInt32); + 'value'?: (_envoy_config_core_v3_RuntimeUInt32 | null); } /** @@ -44,5 +44,5 @@ export interface ComparisonFilter__Output { /** * Value to compare against. */ - 'value'?: (_envoy_config_core_v3_RuntimeUInt32__Output); + 'value': (_envoy_config_core_v3_RuntimeUInt32__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/DurationFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/DurationFilter.ts index 03b0500e8..ee61e55fa 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/DurationFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/DurationFilter.ts @@ -9,7 +9,7 @@ export interface DurationFilter { /** * Comparison. */ - 'comparison'?: (_envoy_config_accesslog_v3_ComparisonFilter); + 'comparison'?: (_envoy_config_accesslog_v3_ComparisonFilter | null); } /** @@ -19,5 +19,5 @@ export interface DurationFilter__Output { /** * Comparison. */ - 'comparison'?: (_envoy_config_accesslog_v3_ComparisonFilter__Output); + 'comparison': (_envoy_config_accesslog_v3_ComparisonFilter__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/ExtensionFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/ExtensionFilter.ts index 127618eef..19edb671b 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/ExtensionFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/ExtensionFilter.ts @@ -11,7 +11,7 @@ export interface ExtensionFilter { * match a statically registered filter. */ 'name'?: (string); - 'typed_config'?: (_google_protobuf_Any); + 'typed_config'?: (_google_protobuf_Any | null); /** * Custom configuration that depends on the filter being instantiated. */ @@ -27,7 +27,7 @@ export interface ExtensionFilter__Output { * match a statically registered filter. */ 'name': (string); - 'typed_config'?: (_google_protobuf_Any__Output); + 'typed_config'?: (_google_protobuf_Any__Output | null); /** * Custom configuration that depends on the filter being instantiated. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/HeaderFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/HeaderFilter.ts index 9cda884b3..294084d1c 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/HeaderFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/HeaderFilter.ts @@ -10,7 +10,7 @@ export interface HeaderFilter { * Only requests with a header which matches the specified HeaderMatcher will * pass the filter check. */ - 'header'?: (_envoy_config_route_v3_HeaderMatcher); + 'header'?: (_envoy_config_route_v3_HeaderMatcher | null); } /** @@ -21,5 +21,5 @@ export interface HeaderFilter__Output { * Only requests with a header which matches the specified HeaderMatcher will * pass the filter check. */ - 'header'?: (_envoy_config_route_v3_HeaderMatcher__Output); + 'header': (_envoy_config_route_v3_HeaderMatcher__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/MetadataFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/MetadataFilter.ts index 7fdd1d447..cd821fef6 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/MetadataFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/MetadataFilter.ts @@ -17,12 +17,12 @@ export interface MetadataFilter { * access_log_hint metadata, set the filter to "envoy.common" and the path to * "access_log_hint", and the value to "true". */ - 'matcher'?: (_envoy_type_matcher_v3_MetadataMatcher); + 'matcher'?: (_envoy_type_matcher_v3_MetadataMatcher | null); /** * Default result if the key does not exist in dynamic metadata: if unset or * true, then log; if false, then don't log. */ - 'match_if_key_not_found'?: (_google_protobuf_BoolValue); + 'match_if_key_not_found'?: (_google_protobuf_BoolValue | null); } /** @@ -39,10 +39,10 @@ export interface MetadataFilter__Output { * access_log_hint metadata, set the filter to "envoy.common" and the path to * "access_log_hint", and the value to "true". */ - 'matcher'?: (_envoy_type_matcher_v3_MetadataMatcher__Output); + 'matcher': (_envoy_type_matcher_v3_MetadataMatcher__Output | null); /** * Default result if the key does not exist in dynamic metadata: if unset or * true, then log; if false, then don't log. */ - 'match_if_key_not_found'?: (_google_protobuf_BoolValue__Output); + 'match_if_key_not_found': (_google_protobuf_BoolValue__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/RuntimeFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/RuntimeFilter.ts index 9388f49ec..e605fa1a4 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/RuntimeFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/RuntimeFilter.ts @@ -16,7 +16,7 @@ export interface RuntimeFilter { * The default sampling percentage. If not specified, defaults to 0% with * denominator of 100. */ - 'percent_sampled'?: (_envoy_type_v3_FractionalPercent); + 'percent_sampled'?: (_envoy_type_v3_FractionalPercent | null); /** * By default, sampling pivots on the header * :ref:`x-request-id` being @@ -51,7 +51,7 @@ export interface RuntimeFilter__Output { * The default sampling percentage. If not specified, defaults to 0% with * denominator of 100. */ - 'percent_sampled'?: (_envoy_type_v3_FractionalPercent__Output); + 'percent_sampled': (_envoy_type_v3_FractionalPercent__Output | null); /** * By default, sampling pivots on the header * :ref:`x-request-id` being diff --git a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/StatusCodeFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/StatusCodeFilter.ts index 313ed86ca..a071b5cbb 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/StatusCodeFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/StatusCodeFilter.ts @@ -9,7 +9,7 @@ export interface StatusCodeFilter { /** * Comparison. */ - 'comparison'?: (_envoy_config_accesslog_v3_ComparisonFilter); + 'comparison'?: (_envoy_config_accesslog_v3_ComparisonFilter | null); } /** @@ -19,5 +19,5 @@ export interface StatusCodeFilter__Output { /** * Comparison. */ - 'comparison'?: (_envoy_config_accesslog_v3_ComparisonFilter__Output); + 'comparison': (_envoy_config_accesslog_v3_ComparisonFilter__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 c4f4add69..e64afb780 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 @@ -12,14 +12,14 @@ export interface _envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget * * This parameter is optional. Defaults to 20%. */ - 'budget_percent'?: (_envoy_type_v3_Percent); + 'budget_percent'?: (_envoy_type_v3_Percent | null); /** * Specifies the minimum retry concurrency allowed for the retry budget. The limit on the * number of active retries may never go below this number. * * This parameter is optional. Defaults to 3. */ - 'min_retry_concurrency'?: (_google_protobuf_UInt32Value); + 'min_retry_concurrency'?: (_google_protobuf_UInt32Value | null); } export interface _envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget__Output { @@ -30,14 +30,14 @@ export interface _envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget * * This parameter is optional. Defaults to 20%. */ - 'budget_percent'?: (_envoy_type_v3_Percent__Output); + 'budget_percent': (_envoy_type_v3_Percent__Output | null); /** * Specifies the minimum retry concurrency allowed for the retry budget. The limit on the * number of active retries may never go below this number. * * This parameter is optional. Defaults to 3. */ - 'min_retry_concurrency'?: (_google_protobuf_UInt32Value__Output); + 'min_retry_concurrency': (_google_protobuf_UInt32Value__Output | null); } /** @@ -55,22 +55,22 @@ export interface _envoy_config_cluster_v3_CircuitBreakers_Thresholds { * The maximum number of connections that Envoy will make to the upstream * cluster. If not specified, the default is 1024. */ - 'max_connections'?: (_google_protobuf_UInt32Value); + 'max_connections'?: (_google_protobuf_UInt32Value | null); /** * The maximum number of pending requests that Envoy will allow to the * upstream cluster. If not specified, the default is 1024. */ - 'max_pending_requests'?: (_google_protobuf_UInt32Value); + 'max_pending_requests'?: (_google_protobuf_UInt32Value | null); /** * The maximum number of parallel requests that Envoy will make to the * upstream cluster. If not specified, the default is 1024. */ - 'max_requests'?: (_google_protobuf_UInt32Value); + 'max_requests'?: (_google_protobuf_UInt32Value | null); /** * The maximum number of parallel retries that Envoy will allow to the * upstream cluster. If not specified, the default is 3. */ - 'max_retries'?: (_google_protobuf_UInt32Value); + 'max_retries'?: (_google_protobuf_UInt32Value | null); /** * Specifies a limit on concurrent retries in relation to the number of active requests. This * parameter is optional. @@ -80,7 +80,7 @@ export interface _envoy_config_cluster_v3_CircuitBreakers_Thresholds { * If this field is set, the retry budget will override any configured retry circuit * breaker. */ - 'retry_budget'?: (_envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget); + 'retry_budget'?: (_envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget | null); /** * If track_remaining is true, then stats will be published that expose * the number of resources remaining until the circuit breakers open. If @@ -99,7 +99,7 @@ export interface _envoy_config_cluster_v3_CircuitBreakers_Thresholds { * :ref:`Circuit Breaking ` for * more details. */ - 'max_connection_pools'?: (_google_protobuf_UInt32Value); + 'max_connection_pools'?: (_google_protobuf_UInt32Value | null); } /** @@ -117,22 +117,22 @@ export interface _envoy_config_cluster_v3_CircuitBreakers_Thresholds__Output { * The maximum number of connections that Envoy will make to the upstream * cluster. If not specified, the default is 1024. */ - 'max_connections'?: (_google_protobuf_UInt32Value__Output); + 'max_connections': (_google_protobuf_UInt32Value__Output | null); /** * The maximum number of pending requests that Envoy will allow to the * upstream cluster. If not specified, the default is 1024. */ - 'max_pending_requests'?: (_google_protobuf_UInt32Value__Output); + 'max_pending_requests': (_google_protobuf_UInt32Value__Output | null); /** * The maximum number of parallel requests that Envoy will make to the * upstream cluster. If not specified, the default is 1024. */ - 'max_requests'?: (_google_protobuf_UInt32Value__Output); + 'max_requests': (_google_protobuf_UInt32Value__Output | null); /** * The maximum number of parallel retries that Envoy will allow to the * upstream cluster. If not specified, the default is 3. */ - 'max_retries'?: (_google_protobuf_UInt32Value__Output); + 'max_retries': (_google_protobuf_UInt32Value__Output | null); /** * Specifies a limit on concurrent retries in relation to the number of active requests. This * parameter is optional. @@ -142,7 +142,7 @@ export interface _envoy_config_cluster_v3_CircuitBreakers_Thresholds__Output { * If this field is set, the retry budget will override any configured retry circuit * breaker. */ - 'retry_budget'?: (_envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget__Output); + 'retry_budget': (_envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget__Output | null); /** * If track_remaining is true, then stats will be published that expose * the number of resources remaining until the circuit breakers open. If @@ -161,7 +161,7 @@ export interface _envoy_config_cluster_v3_CircuitBreakers_Thresholds__Output { * :ref:`Circuit Breaking ` for * more details. */ - 'max_connection_pools'?: (_google_protobuf_UInt32Value__Output); + 'max_connection_pools': (_google_protobuf_UInt32Value__Output | null); } /** 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 fa76fba89..c20440704 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 @@ -56,9 +56,9 @@ export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig { * .. note:: * The specified percent will be truncated to the nearest 1%. */ - 'healthy_panic_threshold'?: (_envoy_type_v3_Percent); - 'zone_aware_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig); - 'locality_weighted_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig); + 'healthy_panic_threshold'?: (_envoy_type_v3_Percent | null); + 'zone_aware_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig | null); + 'locality_weighted_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig | null); /** * If set, all health check/weight/metadata updates that happen within this duration will be * merged and delivered in one shot when the duration expires. The start of the duration is when @@ -75,7 +75,7 @@ export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig { * because merging those updates isn't currently safe. See * https://github.com/envoyproxy/envoy/pull/3941. */ - 'update_merge_window'?: (_google_protobuf_Duration); + 'update_merge_window'?: (_google_protobuf_Duration | null); /** * If set to true, Envoy will :ref:`exclude ` new hosts * when computing load balancing weights until they have been health checked for the first time. @@ -90,7 +90,7 @@ export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig { /** * Common Configuration for all consistent hashing load balancers (MaglevLb, RingHashLb, etc.) */ - 'consistent_hashing_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig); + 'consistent_hashing_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig | null); 'locality_config_specifier'?: "zone_aware_lb_config"|"locality_weighted_lb_config"; } @@ -107,9 +107,9 @@ export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig__Output { * .. note:: * The specified percent will be truncated to the nearest 1%. */ - 'healthy_panic_threshold'?: (_envoy_type_v3_Percent__Output); - 'zone_aware_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig__Output); - 'locality_weighted_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig__Output); + 'healthy_panic_threshold': (_envoy_type_v3_Percent__Output | null); + 'zone_aware_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConfig__Output | null); + 'locality_weighted_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig_LocalityWeightedLbConfig__Output | null); /** * If set, all health check/weight/metadata updates that happen within this duration will be * merged and delivered in one shot when the duration expires. The start of the duration is when @@ -126,7 +126,7 @@ export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig__Output { * because merging those updates isn't currently safe. See * https://github.com/envoyproxy/envoy/pull/3941. */ - 'update_merge_window'?: (_google_protobuf_Duration__Output); + 'update_merge_window': (_google_protobuf_Duration__Output | null); /** * If set to true, Envoy will :ref:`exclude ` new hosts * when computing load balancing weights until they have been health checked for the first time. @@ -141,7 +141,7 @@ export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig__Output { /** * Common Configuration for all consistent hashing load balancers (MaglevLb, RingHashLb, etc.) */ - 'consistent_hashing_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig__Output); + 'consistent_hashing_lb_config': (_envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashingLbConfig__Output | null); 'locality_config_specifier': "zone_aware_lb_config"|"locality_weighted_lb_config"; } @@ -174,7 +174,7 @@ export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashi * This is an O(N) algorithm, unlike other load balancers. Using a lower `hash_balance_factor` results in more hosts * being probed, so use a higher value if you require better performance. */ - 'hash_balance_factor'?: (_google_protobuf_UInt32Value); + 'hash_balance_factor'?: (_google_protobuf_UInt32Value | null); } /** @@ -206,7 +206,7 @@ export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig_ConsistentHashi * This is an O(N) algorithm, unlike other load balancers. Using a lower `hash_balance_factor` results in more hosts * being probed, so use a higher value if you require better performance. */ - 'hash_balance_factor'?: (_google_protobuf_UInt32Value__Output); + 'hash_balance_factor': (_google_protobuf_UInt32Value__Output | null); } /** @@ -221,7 +221,7 @@ export interface _envoy_config_cluster_v3_Cluster_CustomClusterType { * Cluster specific configuration which depends on the cluster being instantiated. * See the supported cluster for further documentation. */ - 'typed_config'?: (_google_protobuf_Any); + 'typed_config'?: (_google_protobuf_Any | null); } /** @@ -236,7 +236,7 @@ export interface _envoy_config_cluster_v3_Cluster_CustomClusterType__Output { * Cluster specific configuration which depends on the cluster being instantiated. * See the supported cluster for further documentation. */ - 'typed_config'?: (_google_protobuf_Any__Output); + 'typed_config': (_google_protobuf_Any__Output | null); } // Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto @@ -303,7 +303,7 @@ export interface _envoy_config_cluster_v3_Cluster_EdsClusterConfig { /** * Configuration for the source of EDS updates for this Cluster. */ - 'eds_config'?: (_envoy_config_core_v3_ConfigSource); + 'eds_config'?: (_envoy_config_core_v3_ConfigSource | null); /** * Optional alternative to cluster name to present to EDS. This does not * have the same restrictions as cluster name, i.e. it may be arbitrary @@ -319,7 +319,7 @@ export interface _envoy_config_cluster_v3_Cluster_EdsClusterConfig__Output { /** * Configuration for the source of EDS updates for this Cluster. */ - 'eds_config'?: (_envoy_config_core_v3_ConfigSource__Output); + 'eds_config': (_envoy_config_core_v3_ConfigSource__Output | null); /** * Optional alternative to cluster name to present to EDS. This does not * have the same restrictions as cluster name, i.e. it may be arbitrary @@ -420,7 +420,7 @@ export interface _envoy_config_cluster_v3_Cluster_LbSubsetConfig { * is the same as a fallback_policy of * :ref:`NO_FALLBACK`. */ - 'default_subset'?: (_google_protobuf_Struct); + 'default_subset'?: (_google_protobuf_Struct | null); /** * For each entry, LbEndpoint.Metadata's * *envoy.lb* namespace is traversed and a subset is created for each unique @@ -497,7 +497,7 @@ export interface _envoy_config_cluster_v3_Cluster_LbSubsetConfig__Output { * is the same as a fallback_policy of * :ref:`NO_FALLBACK`. */ - 'default_subset'?: (_google_protobuf_Struct__Output); + 'default_subset': (_google_protobuf_Struct__Output | null); /** * For each entry, LbEndpoint.Metadata's * *envoy.lb* namespace is traversed and a subset is created for each unique @@ -693,7 +693,7 @@ export interface _envoy_config_cluster_v3_Cluster_LeastRequestLbConfig { * The number of random healthy hosts from which the host with the fewest active requests will * be chosen. Defaults to 2 so that we perform two-choice selection if the field is not set. */ - 'choice_count'?: (_google_protobuf_UInt32Value); + 'choice_count'?: (_google_protobuf_UInt32Value | null); /** * The following formula is used to calculate the dynamic weights when hosts have different load * balancing weights: @@ -719,7 +719,7 @@ export interface _envoy_config_cluster_v3_Cluster_LeastRequestLbConfig { * .. note:: * This setting only takes effect if all host weights are not equal. */ - 'active_request_bias'?: (_envoy_config_core_v3_RuntimeDouble); + 'active_request_bias'?: (_envoy_config_core_v3_RuntimeDouble | null); } /** @@ -730,7 +730,7 @@ export interface _envoy_config_cluster_v3_Cluster_LeastRequestLbConfig__Output { * The number of random healthy hosts from which the host with the fewest active requests will * be chosen. Defaults to 2 so that we perform two-choice selection if the field is not set. */ - 'choice_count'?: (_google_protobuf_UInt32Value__Output); + 'choice_count': (_google_protobuf_UInt32Value__Output | null); /** * The following formula is used to calculate the dynamic weights when hosts have different load * balancing weights: @@ -756,7 +756,7 @@ export interface _envoy_config_cluster_v3_Cluster_LeastRequestLbConfig__Output { * .. note:: * This setting only takes effect if all host weights are not equal. */ - 'active_request_bias'?: (_envoy_config_core_v3_RuntimeDouble__Output); + 'active_request_bias': (_envoy_config_core_v3_RuntimeDouble__Output | null); } /** @@ -784,7 +784,7 @@ export interface _envoy_config_cluster_v3_Cluster_MaglevLbConfig { * upstream as it was before. Increasing the table size reduces the amount of disruption. * The table size must be prime number. If it is not specified, the default is 65537. */ - 'table_size'?: (_google_protobuf_UInt64Value); + 'table_size'?: (_google_protobuf_UInt64Value | null); } /** @@ -798,7 +798,7 @@ export interface _envoy_config_cluster_v3_Cluster_MaglevLbConfig__Output { * upstream as it was before. Increasing the table size reduces the amount of disruption. * The table size must be prime number. If it is not specified, the default is 65537. */ - 'table_size'?: (_google_protobuf_UInt64Value__Output); + 'table_size': (_google_protobuf_UInt64Value__Output | null); } /** @@ -876,7 +876,7 @@ export interface _envoy_config_cluster_v3_Cluster_PreconnectPolicy { * This is limited somewhat arbitrarily to 3 because preconnecting too aggressively can * harm latency more than the preconnecting helps. */ - 'per_upstream_preconnect_ratio'?: (_google_protobuf_DoubleValue); + 'per_upstream_preconnect_ratio'?: (_google_protobuf_DoubleValue | null); /** * Indicates how many many streams (rounded up) can be anticipated across a cluster for each * stream, useful for low QPS services. This is currently supported for a subset of @@ -901,7 +901,7 @@ export interface _envoy_config_cluster_v3_Cluster_PreconnectPolicy { * basically preconnecting max(predictive-preconnect, per-upstream-preconnect), for each * upstream. */ - 'predictive_preconnect_ratio'?: (_google_protobuf_DoubleValue); + 'predictive_preconnect_ratio'?: (_google_protobuf_DoubleValue | null); } export interface _envoy_config_cluster_v3_Cluster_PreconnectPolicy__Output { @@ -931,7 +931,7 @@ export interface _envoy_config_cluster_v3_Cluster_PreconnectPolicy__Output { * This is limited somewhat arbitrarily to 3 because preconnecting too aggressively can * harm latency more than the preconnecting helps. */ - 'per_upstream_preconnect_ratio'?: (_google_protobuf_DoubleValue__Output); + 'per_upstream_preconnect_ratio': (_google_protobuf_DoubleValue__Output | null); /** * Indicates how many many streams (rounded up) can be anticipated across a cluster for each * stream, useful for low QPS services. This is currently supported for a subset of @@ -956,7 +956,7 @@ export interface _envoy_config_cluster_v3_Cluster_PreconnectPolicy__Output { * basically preconnecting max(predictive-preconnect, per-upstream-preconnect), for each * upstream. */ - 'predictive_preconnect_ratio'?: (_google_protobuf_DoubleValue__Output); + 'predictive_preconnect_ratio': (_google_protobuf_DoubleValue__Output | null); } export interface _envoy_config_cluster_v3_Cluster_RefreshRate { @@ -965,14 +965,14 @@ export interface _envoy_config_cluster_v3_Cluster_RefreshRate { * than zero and less than * :ref:`max_interval `. */ - 'base_interval'?: (_google_protobuf_Duration); + 'base_interval'?: (_google_protobuf_Duration | null); /** * Specifies the maximum interval between refreshes. This parameter is optional, but must be * greater than or equal to the * :ref:`base_interval ` if set. The default * is 10 times the :ref:`base_interval `. */ - 'max_interval'?: (_google_protobuf_Duration); + 'max_interval'?: (_google_protobuf_Duration | null); } export interface _envoy_config_cluster_v3_Cluster_RefreshRate__Output { @@ -981,14 +981,14 @@ export interface _envoy_config_cluster_v3_Cluster_RefreshRate__Output { * than zero and less than * :ref:`max_interval `. */ - 'base_interval'?: (_google_protobuf_Duration__Output); + 'base_interval': (_google_protobuf_Duration__Output | null); /** * Specifies the maximum interval between refreshes. This parameter is optional, but must be * greater than or equal to the * :ref:`base_interval ` if set. The default * is 10 times the :ref:`base_interval `. */ - 'max_interval'?: (_google_protobuf_Duration__Output); + 'max_interval': (_google_protobuf_Duration__Output | null); } /** @@ -1002,7 +1002,7 @@ export interface _envoy_config_cluster_v3_Cluster_RingHashLbConfig { * to 1024 entries, and limited to 8M entries. See also * :ref:`maximum_ring_size`. */ - 'minimum_ring_size'?: (_google_protobuf_UInt64Value); + 'minimum_ring_size'?: (_google_protobuf_UInt64Value | null); /** * The hash function used to hash hosts onto the ketama ring. The value defaults to * :ref:`XX_HASH`. @@ -1013,7 +1013,7 @@ export interface _envoy_config_cluster_v3_Cluster_RingHashLbConfig { * to further constrain resource use. See also * :ref:`minimum_ring_size`. */ - 'maximum_ring_size'?: (_google_protobuf_UInt64Value); + 'maximum_ring_size'?: (_google_protobuf_UInt64Value | null); } /** @@ -1027,7 +1027,7 @@ export interface _envoy_config_cluster_v3_Cluster_RingHashLbConfig__Output { * to 1024 entries, and limited to 8M entries. See also * :ref:`maximum_ring_size`. */ - 'minimum_ring_size'?: (_google_protobuf_UInt64Value__Output); + 'minimum_ring_size': (_google_protobuf_UInt64Value__Output | null); /** * The hash function used to hash hosts onto the ketama ring. The value defaults to * :ref:`XX_HASH`. @@ -1038,7 +1038,7 @@ export interface _envoy_config_cluster_v3_Cluster_RingHashLbConfig__Output { * to further constrain resource use. See also * :ref:`minimum_ring_size`. */ - 'maximum_ring_size'?: (_google_protobuf_UInt64Value__Output); + 'maximum_ring_size': (_google_protobuf_UInt64Value__Output | null); } /** @@ -1057,11 +1057,11 @@ export interface _envoy_config_cluster_v3_Cluster_TransportSocketMatch { * The endpoint's metadata entry in *envoy.transport_socket_match* is used to match * against the values specified in this field. */ - 'match'?: (_google_protobuf_Struct); + 'match'?: (_google_protobuf_Struct | null); /** * The configuration of the transport socket. */ - 'transport_socket'?: (_envoy_config_core_v3_TransportSocket); + 'transport_socket'?: (_envoy_config_core_v3_TransportSocket | null); } /** @@ -1080,11 +1080,11 @@ export interface _envoy_config_cluster_v3_Cluster_TransportSocketMatch__Output { * The endpoint's metadata entry in *envoy.transport_socket_match* is used to match * against the values specified in this field. */ - 'match'?: (_google_protobuf_Struct__Output); + 'match': (_google_protobuf_Struct__Output | null); /** * The configuration of the transport socket. */ - 'transport_socket'?: (_envoy_config_core_v3_TransportSocket__Output); + 'transport_socket': (_envoy_config_core_v3_TransportSocket__Output | null); } /** @@ -1098,7 +1098,7 @@ export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConf * * :ref:`runtime values `. * * :ref:`Zone aware routing support `. */ - 'routing_enabled'?: (_envoy_type_v3_Percent); + 'routing_enabled'?: (_envoy_type_v3_Percent | null); /** * Configures minimum upstream cluster size required for zone aware routing * If upstream cluster size is less than specified, zone aware routing is not performed @@ -1106,7 +1106,7 @@ export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConf * * :ref:`runtime values `. * * :ref:`Zone aware routing support `. */ - 'min_cluster_size'?: (_google_protobuf_UInt64Value); + 'min_cluster_size'?: (_google_protobuf_UInt64Value | null); /** * If set to true, Envoy will not consider any hosts when the cluster is in :ref:`panic * mode`. Instead, the cluster will fail all @@ -1127,7 +1127,7 @@ export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConf * * :ref:`runtime values `. * * :ref:`Zone aware routing support `. */ - 'routing_enabled'?: (_envoy_type_v3_Percent__Output); + 'routing_enabled': (_envoy_type_v3_Percent__Output | null); /** * Configures minimum upstream cluster size required for zone aware routing * If upstream cluster size is less than specified, zone aware routing is not performed @@ -1135,7 +1135,7 @@ export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConf * * :ref:`runtime values `. * * :ref:`Zone aware routing support `. */ - 'min_cluster_size'?: (_google_protobuf_UInt64Value__Output); + 'min_cluster_size': (_google_protobuf_UInt64Value__Output | null); /** * If set to true, Envoy will not consider any hosts when the cluster is in :ref:`panic * mode`. Instead, the cluster will fail all @@ -1166,16 +1166,16 @@ export interface Cluster { /** * Configuration to use for EDS updates for the Cluster. */ - 'eds_cluster_config'?: (_envoy_config_cluster_v3_Cluster_EdsClusterConfig); + 'eds_cluster_config'?: (_envoy_config_cluster_v3_Cluster_EdsClusterConfig | null); /** * The timeout for new network connections to hosts in the cluster. */ - 'connect_timeout'?: (_google_protobuf_Duration); + 'connect_timeout'?: (_google_protobuf_Duration | null); /** * Soft limit on size of the cluster’s connections read and write buffers. If * unspecified, an implementation defined default is applied (1MiB). */ - 'per_connection_buffer_limit_bytes'?: (_google_protobuf_UInt32Value); + 'per_connection_buffer_limit_bytes'?: (_google_protobuf_UInt32Value | null); /** * The :ref:`load balancer type ` to use * when picking a host in the cluster. @@ -1195,11 +1195,11 @@ export interface Cluster { * implementations. If not specified, there is no limit. Setting this * parameter to 1 will effectively disable keep alive. */ - 'max_requests_per_connection'?: (_google_protobuf_UInt32Value); + 'max_requests_per_connection'?: (_google_protobuf_UInt32Value | null); /** * Optional :ref:`circuit breaking ` for the cluster. */ - 'circuit_breakers'?: (_envoy_config_cluster_v3_CircuitBreakers); + 'circuit_breakers'?: (_envoy_config_cluster_v3_CircuitBreakers | null); /** * Additional options when handling HTTP1 requests. * This has been deprecated in favor of http_protocol_options fields in the in the @@ -1210,7 +1210,7 @@ export interface Cluster { * ` * for example usage. */ - 'http_protocol_options'?: (_envoy_config_core_v3_Http1ProtocolOptions); + 'http_protocol_options'?: (_envoy_config_core_v3_Http1ProtocolOptions | null); /** * Even if default HTTP2 protocol options are desired, this field must be * set so that Envoy will assume that the upstream supports HTTP/2 when @@ -1226,7 +1226,7 @@ export interface Cluster { * ` * for example usage. */ - 'http2_protocol_options'?: (_envoy_config_core_v3_Http2ProtocolOptions); + 'http2_protocol_options'?: (_envoy_config_core_v3_Http2ProtocolOptions | null); /** * If the DNS refresh rate is specified and the cluster type is either * :ref:`STRICT_DNS`, @@ -1238,7 +1238,7 @@ export interface Cluster { * and :ref:`LOGICAL_DNS` * this setting is ignored. */ - 'dns_refresh_rate'?: (_google_protobuf_Duration); + 'dns_refresh_rate'?: (_google_protobuf_Duration | null); /** * The DNS IP address resolution policy. If this setting is not specified, the * value defaults to @@ -1266,7 +1266,7 @@ export interface Cluster { * Each of the configuration values can be overridden via * :ref:`runtime values `. */ - 'outlier_detection'?: (_envoy_config_cluster_v3_OutlierDetection); + 'outlier_detection'?: (_envoy_config_cluster_v3_OutlierDetection | null); /** * The interval for removing stale hosts from a cluster type * :ref:`ORIGINAL_DST`. @@ -1282,21 +1282,21 @@ export interface Cluster { * :ref:`ORIGINAL_DST` * this setting is ignored. */ - 'cleanup_interval'?: (_google_protobuf_Duration); + 'cleanup_interval'?: (_google_protobuf_Duration | null); /** * Optional configuration used to bind newly established upstream connections. * This overrides any bind_config specified in the bootstrap proto. * If the address and port are empty, no bind will be performed. */ - 'upstream_bind_config'?: (_envoy_config_core_v3_BindConfig); + 'upstream_bind_config'?: (_envoy_config_core_v3_BindConfig | null); /** * Configuration for load balancing subsetting. */ - 'lb_subset_config'?: (_envoy_config_cluster_v3_Cluster_LbSubsetConfig); + 'lb_subset_config'?: (_envoy_config_cluster_v3_Cluster_LbSubsetConfig | null); /** * Optional configuration for the Ring Hash load balancing policy. */ - 'ring_hash_lb_config'?: (_envoy_config_cluster_v3_Cluster_RingHashLbConfig); + 'ring_hash_lb_config'?: (_envoy_config_cluster_v3_Cluster_RingHashLbConfig | null); /** * Optional custom transport socket implementation to use for upstream connections. * To setup TLS, set a transport socket with name `tls` and @@ -1304,7 +1304,7 @@ export interface Cluster { * If no transport socket configuration is specified, new connections * will be set up with plaintext. */ - 'transport_socket'?: (_envoy_config_core_v3_TransportSocket); + 'transport_socket'?: (_envoy_config_core_v3_TransportSocket | null); /** * The Metadata field can be used to provide additional information about the * cluster. It can be used for stats, logging, and varying filter behavior. @@ -1312,7 +1312,7 @@ export interface Cluster { * will need the information. For instance, if the metadata is intended for * the Router filter, the filter name should be specified as *envoy.filters.http.router*. */ - 'metadata'?: (_envoy_config_core_v3_Metadata); + 'metadata'?: (_envoy_config_core_v3_Metadata | null); /** * Determines how Envoy selects the protocol used to speak to upstream hosts. * This has been deprecated in favor of setting explicit protocol selection @@ -1325,7 +1325,7 @@ export interface Cluster { /** * Common configuration for all load balancer implementations. */ - 'common_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig); + 'common_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig | null); /** * An optional alternative to the cluster name to be used while emitting stats. * Any ``:`` in the name will be converted to ``_`` when emitting statistics. This should not be @@ -1345,11 +1345,11 @@ export interface Cluster { * ` * for example usage. */ - 'common_http_protocol_options'?: (_envoy_config_core_v3_HttpProtocolOptions); + 'common_http_protocol_options'?: (_envoy_config_core_v3_HttpProtocolOptions | null); /** * Optional options for upstream connections. */ - 'upstream_connection_options'?: (_envoy_config_cluster_v3_UpstreamConnectionOptions); + 'upstream_connection_options'?: (_envoy_config_cluster_v3_UpstreamConnectionOptions | null); /** * If an upstream host becomes unhealthy (as determined by the configured health checks * or outlier detection), immediately close all connections to the failed host. @@ -1384,11 +1384,11 @@ export interface Cluster { * Setting this allows non-EDS cluster types to contain embedded EDS equivalent * :ref:`endpoint assignments`. */ - 'load_assignment'?: (_envoy_config_endpoint_v3_ClusterLoadAssignment); + 'load_assignment'?: (_envoy_config_endpoint_v3_ClusterLoadAssignment | null); /** * Optional configuration for the Original Destination load balancing policy. */ - 'original_dst_lb_config'?: (_envoy_config_cluster_v3_Cluster_OriginalDstLbConfig); + 'original_dst_lb_config'?: (_envoy_config_cluster_v3_Cluster_OriginalDstLbConfig | null); /** * The extension_protocol_options field is used to provide extension-specific protocol options * for upstream connections. The key should match the extension filter name, such as @@ -1400,11 +1400,11 @@ export interface Cluster { /** * Optional configuration for the LeastRequest load balancing policy. */ - 'least_request_lb_config'?: (_envoy_config_cluster_v3_Cluster_LeastRequestLbConfig); + 'least_request_lb_config'?: (_envoy_config_cluster_v3_Cluster_LeastRequestLbConfig | null); /** * The custom cluster type. */ - 'cluster_type'?: (_envoy_config_cluster_v3_Cluster_CustomClusterType); + 'cluster_type'?: (_envoy_config_cluster_v3_Cluster_CustomClusterType | null); /** * Optional configuration for setting cluster's DNS refresh rate. If the value is set to true, * cluster's DNS refresh rate will be set to resource record's TTL which comes from DNS @@ -1422,7 +1422,7 @@ export interface Cluster { * :ref:`lb_policy` field has the value * :ref:`LOAD_BALANCING_POLICY_CONFIG`. */ - 'load_balancing_policy'?: (_envoy_config_cluster_v3_LoadBalancingPolicy); + 'load_balancing_policy'?: (_envoy_config_cluster_v3_LoadBalancingPolicy | null); /** * [#not-implemented-hide:] * If present, tells the client where to send load reports via LRS. If not present, the @@ -1439,7 +1439,7 @@ export interface Cluster { * maybe by allowing LRS to go on the ADS stream, or maybe by moving some of the negotiation * from the LRS stream here.] */ - 'lrs_server'?: (_envoy_config_core_v3_ConfigSource); + 'lrs_server'?: (_envoy_config_core_v3_ConfigSource | null); /** * Configuration to use different transport sockets for different endpoints. * The entry of *envoy.transport_socket_match* in the @@ -1502,7 +1502,7 @@ export interface Cluster { * :ref:`LOGICAL_DNS` this setting is * ignored. */ - 'dns_failure_refresh_rate'?: (_envoy_config_cluster_v3_Cluster_RefreshRate); + 'dns_failure_refresh_rate'?: (_envoy_config_cluster_v3_Cluster_RefreshRate | null); /** * [#next-major-version: Reconcile DNS options in a single message.] * Always use TCP queries instead of UDP queries for DNS lookups. @@ -1523,7 +1523,7 @@ export interface Cluster { * ` * for example usage. */ - 'upstream_http_protocol_options'?: (_envoy_config_core_v3_UpstreamHttpProtocolOptions); + 'upstream_http_protocol_options'?: (_envoy_config_core_v3_UpstreamHttpProtocolOptions | null); /** * If track_timeout_budgets is true, the :ref:`timeout budget histograms * ` will be published for each @@ -1556,15 +1556,15 @@ export interface Cluster { * CONNECT only if a custom filter indicates it is appropriate, the custom factories * can be registered and configured here. */ - 'upstream_config'?: (_envoy_config_core_v3_TypedExtensionConfig); + 'upstream_config'?: (_envoy_config_core_v3_TypedExtensionConfig | null); /** * Configuration to track optional cluster stats. */ - 'track_cluster_stats'?: (_envoy_config_cluster_v3_TrackClusterStats); + 'track_cluster_stats'?: (_envoy_config_cluster_v3_TrackClusterStats | null); /** * Preconnect configuration for this cluster. */ - 'preconnect_policy'?: (_envoy_config_cluster_v3_Cluster_PreconnectPolicy); + 'preconnect_policy'?: (_envoy_config_cluster_v3_Cluster_PreconnectPolicy | null); /** * If `connection_pool_per_downstream_connection` is true, the cluster will use a separate * connection pool for every downstream connection @@ -1573,7 +1573,7 @@ export interface Cluster { /** * Optional configuration for the Maglev load balancing policy. */ - 'maglev_lb_config'?: (_envoy_config_cluster_v3_Cluster_MaglevLbConfig); + 'maglev_lb_config'?: (_envoy_config_cluster_v3_Cluster_MaglevLbConfig | null); 'cluster_discovery_type'?: "type"|"cluster_type"; /** * Optional configuration for the load balancing algorithm selected by @@ -1609,16 +1609,16 @@ export interface Cluster__Output { /** * Configuration to use for EDS updates for the Cluster. */ - 'eds_cluster_config'?: (_envoy_config_cluster_v3_Cluster_EdsClusterConfig__Output); + 'eds_cluster_config': (_envoy_config_cluster_v3_Cluster_EdsClusterConfig__Output | null); /** * The timeout for new network connections to hosts in the cluster. */ - 'connect_timeout'?: (_google_protobuf_Duration__Output); + 'connect_timeout': (_google_protobuf_Duration__Output | null); /** * Soft limit on size of the cluster’s connections read and write buffers. If * unspecified, an implementation defined default is applied (1MiB). */ - 'per_connection_buffer_limit_bytes'?: (_google_protobuf_UInt32Value__Output); + 'per_connection_buffer_limit_bytes': (_google_protobuf_UInt32Value__Output | null); /** * The :ref:`load balancer type ` to use * when picking a host in the cluster. @@ -1638,11 +1638,11 @@ export interface Cluster__Output { * implementations. If not specified, there is no limit. Setting this * parameter to 1 will effectively disable keep alive. */ - 'max_requests_per_connection'?: (_google_protobuf_UInt32Value__Output); + 'max_requests_per_connection': (_google_protobuf_UInt32Value__Output | null); /** * Optional :ref:`circuit breaking ` for the cluster. */ - 'circuit_breakers'?: (_envoy_config_cluster_v3_CircuitBreakers__Output); + 'circuit_breakers': (_envoy_config_cluster_v3_CircuitBreakers__Output | null); /** * Additional options when handling HTTP1 requests. * This has been deprecated in favor of http_protocol_options fields in the in the @@ -1653,7 +1653,7 @@ export interface Cluster__Output { * ` * for example usage. */ - 'http_protocol_options'?: (_envoy_config_core_v3_Http1ProtocolOptions__Output); + 'http_protocol_options': (_envoy_config_core_v3_Http1ProtocolOptions__Output | null); /** * Even if default HTTP2 protocol options are desired, this field must be * set so that Envoy will assume that the upstream supports HTTP/2 when @@ -1669,7 +1669,7 @@ export interface Cluster__Output { * ` * for example usage. */ - 'http2_protocol_options'?: (_envoy_config_core_v3_Http2ProtocolOptions__Output); + 'http2_protocol_options': (_envoy_config_core_v3_Http2ProtocolOptions__Output | null); /** * If the DNS refresh rate is specified and the cluster type is either * :ref:`STRICT_DNS`, @@ -1681,7 +1681,7 @@ export interface Cluster__Output { * and :ref:`LOGICAL_DNS` * this setting is ignored. */ - 'dns_refresh_rate'?: (_google_protobuf_Duration__Output); + 'dns_refresh_rate': (_google_protobuf_Duration__Output | null); /** * The DNS IP address resolution policy. If this setting is not specified, the * value defaults to @@ -1709,7 +1709,7 @@ export interface Cluster__Output { * Each of the configuration values can be overridden via * :ref:`runtime values `. */ - 'outlier_detection'?: (_envoy_config_cluster_v3_OutlierDetection__Output); + 'outlier_detection': (_envoy_config_cluster_v3_OutlierDetection__Output | null); /** * The interval for removing stale hosts from a cluster type * :ref:`ORIGINAL_DST`. @@ -1725,21 +1725,21 @@ export interface Cluster__Output { * :ref:`ORIGINAL_DST` * this setting is ignored. */ - 'cleanup_interval'?: (_google_protobuf_Duration__Output); + 'cleanup_interval': (_google_protobuf_Duration__Output | null); /** * Optional configuration used to bind newly established upstream connections. * This overrides any bind_config specified in the bootstrap proto. * If the address and port are empty, no bind will be performed. */ - 'upstream_bind_config'?: (_envoy_config_core_v3_BindConfig__Output); + 'upstream_bind_config': (_envoy_config_core_v3_BindConfig__Output | null); /** * Configuration for load balancing subsetting. */ - 'lb_subset_config'?: (_envoy_config_cluster_v3_Cluster_LbSubsetConfig__Output); + 'lb_subset_config': (_envoy_config_cluster_v3_Cluster_LbSubsetConfig__Output | null); /** * Optional configuration for the Ring Hash load balancing policy. */ - 'ring_hash_lb_config'?: (_envoy_config_cluster_v3_Cluster_RingHashLbConfig__Output); + 'ring_hash_lb_config'?: (_envoy_config_cluster_v3_Cluster_RingHashLbConfig__Output | null); /** * Optional custom transport socket implementation to use for upstream connections. * To setup TLS, set a transport socket with name `tls` and @@ -1747,7 +1747,7 @@ export interface Cluster__Output { * If no transport socket configuration is specified, new connections * will be set up with plaintext. */ - 'transport_socket'?: (_envoy_config_core_v3_TransportSocket__Output); + 'transport_socket': (_envoy_config_core_v3_TransportSocket__Output | null); /** * The Metadata field can be used to provide additional information about the * cluster. It can be used for stats, logging, and varying filter behavior. @@ -1755,7 +1755,7 @@ export interface Cluster__Output { * will need the information. For instance, if the metadata is intended for * the Router filter, the filter name should be specified as *envoy.filters.http.router*. */ - 'metadata'?: (_envoy_config_core_v3_Metadata__Output); + 'metadata': (_envoy_config_core_v3_Metadata__Output | null); /** * Determines how Envoy selects the protocol used to speak to upstream hosts. * This has been deprecated in favor of setting explicit protocol selection @@ -1768,7 +1768,7 @@ export interface Cluster__Output { /** * Common configuration for all load balancer implementations. */ - 'common_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig__Output); + 'common_lb_config': (_envoy_config_cluster_v3_Cluster_CommonLbConfig__Output | null); /** * An optional alternative to the cluster name to be used while emitting stats. * Any ``:`` in the name will be converted to ``_`` when emitting statistics. This should not be @@ -1788,11 +1788,11 @@ export interface Cluster__Output { * ` * for example usage. */ - 'common_http_protocol_options'?: (_envoy_config_core_v3_HttpProtocolOptions__Output); + 'common_http_protocol_options': (_envoy_config_core_v3_HttpProtocolOptions__Output | null); /** * Optional options for upstream connections. */ - 'upstream_connection_options'?: (_envoy_config_cluster_v3_UpstreamConnectionOptions__Output); + 'upstream_connection_options': (_envoy_config_cluster_v3_UpstreamConnectionOptions__Output | null); /** * If an upstream host becomes unhealthy (as determined by the configured health checks * or outlier detection), immediately close all connections to the failed host. @@ -1827,11 +1827,11 @@ export interface Cluster__Output { * Setting this allows non-EDS cluster types to contain embedded EDS equivalent * :ref:`endpoint assignments`. */ - 'load_assignment'?: (_envoy_config_endpoint_v3_ClusterLoadAssignment__Output); + 'load_assignment': (_envoy_config_endpoint_v3_ClusterLoadAssignment__Output | null); /** * Optional configuration for the Original Destination load balancing policy. */ - 'original_dst_lb_config'?: (_envoy_config_cluster_v3_Cluster_OriginalDstLbConfig__Output); + 'original_dst_lb_config'?: (_envoy_config_cluster_v3_Cluster_OriginalDstLbConfig__Output | null); /** * The extension_protocol_options field is used to provide extension-specific protocol options * for upstream connections. The key should match the extension filter name, such as @@ -1839,15 +1839,15 @@ export interface Cluster__Output { * specific options. * [#next-major-version: make this a list of typed extensions.] */ - 'typed_extension_protocol_options'?: ({[key: string]: _google_protobuf_Any__Output}); + 'typed_extension_protocol_options': ({[key: string]: _google_protobuf_Any__Output}); /** * Optional configuration for the LeastRequest load balancing policy. */ - 'least_request_lb_config'?: (_envoy_config_cluster_v3_Cluster_LeastRequestLbConfig__Output); + 'least_request_lb_config'?: (_envoy_config_cluster_v3_Cluster_LeastRequestLbConfig__Output | null); /** * The custom cluster type. */ - 'cluster_type'?: (_envoy_config_cluster_v3_Cluster_CustomClusterType__Output); + 'cluster_type'?: (_envoy_config_cluster_v3_Cluster_CustomClusterType__Output | null); /** * Optional configuration for setting cluster's DNS refresh rate. If the value is set to true, * cluster's DNS refresh rate will be set to resource record's TTL which comes from DNS @@ -1865,7 +1865,7 @@ export interface Cluster__Output { * :ref:`lb_policy` field has the value * :ref:`LOAD_BALANCING_POLICY_CONFIG`. */ - 'load_balancing_policy'?: (_envoy_config_cluster_v3_LoadBalancingPolicy__Output); + 'load_balancing_policy': (_envoy_config_cluster_v3_LoadBalancingPolicy__Output | null); /** * [#not-implemented-hide:] * If present, tells the client where to send load reports via LRS. If not present, the @@ -1882,7 +1882,7 @@ export interface Cluster__Output { * maybe by allowing LRS to go on the ADS stream, or maybe by moving some of the negotiation * from the LRS stream here.] */ - 'lrs_server'?: (_envoy_config_core_v3_ConfigSource__Output); + 'lrs_server': (_envoy_config_core_v3_ConfigSource__Output | null); /** * Configuration to use different transport sockets for different endpoints. * The entry of *envoy.transport_socket_match* in the @@ -1945,7 +1945,7 @@ export interface Cluster__Output { * :ref:`LOGICAL_DNS` this setting is * ignored. */ - 'dns_failure_refresh_rate'?: (_envoy_config_cluster_v3_Cluster_RefreshRate__Output); + 'dns_failure_refresh_rate': (_envoy_config_cluster_v3_Cluster_RefreshRate__Output | null); /** * [#next-major-version: Reconcile DNS options in a single message.] * Always use TCP queries instead of UDP queries for DNS lookups. @@ -1966,7 +1966,7 @@ export interface Cluster__Output { * ` * for example usage. */ - 'upstream_http_protocol_options'?: (_envoy_config_core_v3_UpstreamHttpProtocolOptions__Output); + 'upstream_http_protocol_options': (_envoy_config_core_v3_UpstreamHttpProtocolOptions__Output | null); /** * If track_timeout_budgets is true, the :ref:`timeout budget histograms * ` will be published for each @@ -1999,15 +1999,15 @@ export interface Cluster__Output { * CONNECT only if a custom filter indicates it is appropriate, the custom factories * can be registered and configured here. */ - 'upstream_config'?: (_envoy_config_core_v3_TypedExtensionConfig__Output); + 'upstream_config': (_envoy_config_core_v3_TypedExtensionConfig__Output | null); /** * Configuration to track optional cluster stats. */ - 'track_cluster_stats'?: (_envoy_config_cluster_v3_TrackClusterStats__Output); + 'track_cluster_stats': (_envoy_config_cluster_v3_TrackClusterStats__Output | null); /** * Preconnect configuration for this cluster. */ - 'preconnect_policy'?: (_envoy_config_cluster_v3_Cluster_PreconnectPolicy__Output); + 'preconnect_policy': (_envoy_config_cluster_v3_Cluster_PreconnectPolicy__Output | null); /** * If `connection_pool_per_downstream_connection` is true, the cluster will use a separate * connection pool for every downstream connection @@ -2016,7 +2016,7 @@ export interface Cluster__Output { /** * Optional configuration for the Maglev load balancing policy. */ - 'maglev_lb_config'?: (_envoy_config_cluster_v3_Cluster_MaglevLbConfig__Output); + 'maglev_lb_config'?: (_envoy_config_cluster_v3_Cluster_MaglevLbConfig__Output | null); 'cluster_discovery_type': "type"|"cluster_type"; /** * Optional configuration for the load balancing algorithm selected by diff --git a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/ClusterCollection.ts b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/ClusterCollection.ts index aab9c6281..8b1394d4b 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/ClusterCollection.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/ClusterCollection.ts @@ -7,7 +7,7 @@ import type { CollectionEntry as _xds_core_v3_CollectionEntry, CollectionEntry__ * [#not-implemented-hide:] */ export interface ClusterCollection { - 'entries'?: (_xds_core_v3_CollectionEntry); + 'entries'?: (_xds_core_v3_CollectionEntry | null); } /** @@ -15,5 +15,5 @@ export interface ClusterCollection { * [#not-implemented-hide:] */ export interface ClusterCollection__Output { - 'entries'?: (_xds_core_v3_CollectionEntry__Output); + 'entries': (_xds_core_v3_CollectionEntry__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/Filter.ts b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/Filter.ts index 53feedb98..b2ccda5e4 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/Filter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/Filter.ts @@ -12,7 +12,7 @@ export interface Filter { * Filter specific configuration which depends on the filter being * instantiated. See the supported filters for further documentation. */ - 'typed_config'?: (_google_protobuf_Any); + 'typed_config'?: (_google_protobuf_Any | null); } export interface Filter__Output { @@ -25,5 +25,5 @@ export interface Filter__Output { * Filter specific configuration which depends on the filter being * instantiated. See the supported filters for further documentation. */ - 'typed_config'?: (_google_protobuf_Any__Output); + 'typed_config': (_google_protobuf_Any__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/LoadBalancingPolicy.ts b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/LoadBalancingPolicy.ts index 29e343218..128a6458a 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/LoadBalancingPolicy.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/LoadBalancingPolicy.ts @@ -7,7 +7,7 @@ export interface _envoy_config_cluster_v3_LoadBalancingPolicy_Policy { * Required. The name of the LB policy. */ 'name'?: (string); - 'typed_config'?: (_google_protobuf_Any); + 'typed_config'?: (_google_protobuf_Any | null); } export interface _envoy_config_cluster_v3_LoadBalancingPolicy_Policy__Output { @@ -15,7 +15,7 @@ export interface _envoy_config_cluster_v3_LoadBalancingPolicy_Policy__Output { * Required. The name of the LB policy. */ 'name': (string); - 'typed_config'?: (_google_protobuf_Any__Output); + 'typed_config': (_google_protobuf_Any__Output | null); } /** diff --git a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/OutlierDetection.ts b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/OutlierDetection.ts index f37001691..abae2e270 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/OutlierDetection.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/OutlierDetection.ts @@ -14,44 +14,44 @@ export interface OutlierDetection { * to 5xx error codes before a consecutive 5xx ejection * occurs. Defaults to 5. */ - 'consecutive_5xx'?: (_google_protobuf_UInt32Value); + 'consecutive_5xx'?: (_google_protobuf_UInt32Value | null); /** * The time interval between ejection analysis sweeps. This can result in * both new ejections as well as hosts being returned to service. Defaults * to 10000ms or 10s. */ - 'interval'?: (_google_protobuf_Duration); + 'interval'?: (_google_protobuf_Duration | null); /** * The base time that a host is ejected for. The real time is equal to the * base time multiplied by the number of times the host has been ejected and is * capped by :ref:`max_ejection_time`. * Defaults to 30000ms or 30s. */ - 'base_ejection_time'?: (_google_protobuf_Duration); + 'base_ejection_time'?: (_google_protobuf_Duration | null); /** * The maximum % of an upstream cluster that can be ejected due to outlier * detection. Defaults to 10% but will eject at least one host regardless of the value. */ - 'max_ejection_percent'?: (_google_protobuf_UInt32Value); + 'max_ejection_percent'?: (_google_protobuf_UInt32Value | null); /** * The % chance that a host will be actually ejected when an outlier status * is detected through consecutive 5xx. This setting can be used to disable * ejection or to ramp it up slowly. Defaults to 100. */ - 'enforcing_consecutive_5xx'?: (_google_protobuf_UInt32Value); + 'enforcing_consecutive_5xx'?: (_google_protobuf_UInt32Value | null); /** * The % chance that a host will be actually ejected when an outlier status * is detected through success rate statistics. This setting can be used to * disable ejection or to ramp it up slowly. Defaults to 100. */ - 'enforcing_success_rate'?: (_google_protobuf_UInt32Value); + 'enforcing_success_rate'?: (_google_protobuf_UInt32Value | null); /** * The number of hosts in a cluster that must have enough request volume to * detect success rate outliers. If the number of hosts is less than this * setting, outlier detection via success rate statistics is not performed * for any host in the cluster. Defaults to 5. */ - 'success_rate_minimum_hosts'?: (_google_protobuf_UInt32Value); + 'success_rate_minimum_hosts'?: (_google_protobuf_UInt32Value | null); /** * The minimum number of total requests that must be collected in one * interval (as defined by the interval duration above) to include this host @@ -59,7 +59,7 @@ export interface OutlierDetection { * setting, outlier detection via success rate statistics is not performed * for that host. Defaults to 100. */ - 'success_rate_request_volume'?: (_google_protobuf_UInt32Value); + 'success_rate_request_volume'?: (_google_protobuf_UInt32Value | null); /** * This factor is used to determine the ejection threshold for success rate * outlier ejection. The ejection threshold is the difference between the @@ -69,18 +69,18 @@ export interface OutlierDetection { * double. That is, if the desired factor is 1.9, the runtime value should * be 1900. Defaults to 1900. */ - 'success_rate_stdev_factor'?: (_google_protobuf_UInt32Value); + 'success_rate_stdev_factor'?: (_google_protobuf_UInt32Value | null); /** * The number of consecutive gateway failures (502, 503, 504 status codes) * before a consecutive gateway failure ejection occurs. Defaults to 5. */ - 'consecutive_gateway_failure'?: (_google_protobuf_UInt32Value); + 'consecutive_gateway_failure'?: (_google_protobuf_UInt32Value | null); /** * The % chance that a host will be actually ejected when an outlier status * is detected through consecutive gateway failures. This setting can be * used to disable ejection or to ramp it up slowly. Defaults to 0. */ - 'enforcing_consecutive_gateway_failure'?: (_google_protobuf_UInt32Value); + 'enforcing_consecutive_gateway_failure'?: (_google_protobuf_UInt32Value | null); /** * Determines whether to distinguish local origin failures from external errors. If set to true * the following configuration parameters are taken into account: @@ -97,7 +97,7 @@ export interface OutlierDetection { * :ref:`split_external_local_origin_errors` * is set to true. */ - 'consecutive_local_origin_failure'?: (_google_protobuf_UInt32Value); + 'consecutive_local_origin_failure'?: (_google_protobuf_UInt32Value | null); /** * The % chance that a host will be actually ejected when an outlier status * is detected through consecutive locally originated failures. This setting can be @@ -106,7 +106,7 @@ export interface OutlierDetection { * :ref:`split_external_local_origin_errors` * is set to true. */ - 'enforcing_consecutive_local_origin_failure'?: (_google_protobuf_UInt32Value); + 'enforcing_consecutive_local_origin_failure'?: (_google_protobuf_UInt32Value | null); /** * The % chance that a host will be actually ejected when an outlier status * is detected through success rate statistics for locally originated errors. @@ -115,13 +115,13 @@ export interface OutlierDetection { * :ref:`split_external_local_origin_errors` * is set to true. */ - 'enforcing_local_origin_success_rate'?: (_google_protobuf_UInt32Value); + 'enforcing_local_origin_success_rate'?: (_google_protobuf_UInt32Value | null); /** * The failure percentage to use when determining failure percentage-based outlier detection. If * the failure percentage of a given host is greater than or equal to this value, it will be * ejected. Defaults to 85. */ - 'failure_percentage_threshold'?: (_google_protobuf_UInt32Value); + 'failure_percentage_threshold'?: (_google_protobuf_UInt32Value | null); /** * The % chance that a host will be actually ejected when an outlier status is detected through * failure percentage statistics. This setting can be used to disable ejection or to ramp it up @@ -130,32 +130,32 @@ export interface OutlierDetection { * [#next-major-version: setting this without setting failure_percentage_threshold should be * invalid in v4.] */ - 'enforcing_failure_percentage'?: (_google_protobuf_UInt32Value); + 'enforcing_failure_percentage'?: (_google_protobuf_UInt32Value | null); /** * The % chance that a host will be actually ejected when an outlier status is detected through * local-origin failure percentage statistics. This setting can be used to disable ejection or to * ramp it up slowly. Defaults to 0. */ - 'enforcing_failure_percentage_local_origin'?: (_google_protobuf_UInt32Value); + 'enforcing_failure_percentage_local_origin'?: (_google_protobuf_UInt32Value | null); /** * The minimum number of hosts in a cluster in order to perform failure percentage-based ejection. * If the total number of hosts in the cluster is less than this value, failure percentage-based * ejection will not be performed. Defaults to 5. */ - 'failure_percentage_minimum_hosts'?: (_google_protobuf_UInt32Value); + 'failure_percentage_minimum_hosts'?: (_google_protobuf_UInt32Value | null); /** * The minimum number of total requests that must be collected in one interval (as defined by the * interval duration above) to perform failure percentage-based ejection for this host. If the * volume is lower than this setting, failure percentage-based ejection will not be performed for * this host. Defaults to 50. */ - 'failure_percentage_request_volume'?: (_google_protobuf_UInt32Value); + 'failure_percentage_request_volume'?: (_google_protobuf_UInt32Value | null); /** * The maximum time that a host is ejected for. See :ref:`base_ejection_time` * for more information. * Defaults to 300000ms or 300s. */ - 'max_ejection_time'?: (_google_protobuf_Duration); + 'max_ejection_time'?: (_google_protobuf_Duration | null); } /** @@ -169,44 +169,44 @@ export interface OutlierDetection__Output { * to 5xx error codes before a consecutive 5xx ejection * occurs. Defaults to 5. */ - 'consecutive_5xx'?: (_google_protobuf_UInt32Value__Output); + 'consecutive_5xx': (_google_protobuf_UInt32Value__Output | null); /** * The time interval between ejection analysis sweeps. This can result in * both new ejections as well as hosts being returned to service. Defaults * to 10000ms or 10s. */ - 'interval'?: (_google_protobuf_Duration__Output); + 'interval': (_google_protobuf_Duration__Output | null); /** * The base time that a host is ejected for. The real time is equal to the * base time multiplied by the number of times the host has been ejected and is * capped by :ref:`max_ejection_time`. * Defaults to 30000ms or 30s. */ - 'base_ejection_time'?: (_google_protobuf_Duration__Output); + 'base_ejection_time': (_google_protobuf_Duration__Output | null); /** * The maximum % of an upstream cluster that can be ejected due to outlier * detection. Defaults to 10% but will eject at least one host regardless of the value. */ - 'max_ejection_percent'?: (_google_protobuf_UInt32Value__Output); + 'max_ejection_percent': (_google_protobuf_UInt32Value__Output | null); /** * The % chance that a host will be actually ejected when an outlier status * is detected through consecutive 5xx. This setting can be used to disable * ejection or to ramp it up slowly. Defaults to 100. */ - 'enforcing_consecutive_5xx'?: (_google_protobuf_UInt32Value__Output); + 'enforcing_consecutive_5xx': (_google_protobuf_UInt32Value__Output | null); /** * The % chance that a host will be actually ejected when an outlier status * is detected through success rate statistics. This setting can be used to * disable ejection or to ramp it up slowly. Defaults to 100. */ - 'enforcing_success_rate'?: (_google_protobuf_UInt32Value__Output); + 'enforcing_success_rate': (_google_protobuf_UInt32Value__Output | null); /** * The number of hosts in a cluster that must have enough request volume to * detect success rate outliers. If the number of hosts is less than this * setting, outlier detection via success rate statistics is not performed * for any host in the cluster. Defaults to 5. */ - 'success_rate_minimum_hosts'?: (_google_protobuf_UInt32Value__Output); + 'success_rate_minimum_hosts': (_google_protobuf_UInt32Value__Output | null); /** * The minimum number of total requests that must be collected in one * interval (as defined by the interval duration above) to include this host @@ -214,7 +214,7 @@ export interface OutlierDetection__Output { * setting, outlier detection via success rate statistics is not performed * for that host. Defaults to 100. */ - 'success_rate_request_volume'?: (_google_protobuf_UInt32Value__Output); + 'success_rate_request_volume': (_google_protobuf_UInt32Value__Output | null); /** * This factor is used to determine the ejection threshold for success rate * outlier ejection. The ejection threshold is the difference between the @@ -224,18 +224,18 @@ export interface OutlierDetection__Output { * double. That is, if the desired factor is 1.9, the runtime value should * be 1900. Defaults to 1900. */ - 'success_rate_stdev_factor'?: (_google_protobuf_UInt32Value__Output); + 'success_rate_stdev_factor': (_google_protobuf_UInt32Value__Output | null); /** * The number of consecutive gateway failures (502, 503, 504 status codes) * before a consecutive gateway failure ejection occurs. Defaults to 5. */ - 'consecutive_gateway_failure'?: (_google_protobuf_UInt32Value__Output); + 'consecutive_gateway_failure': (_google_protobuf_UInt32Value__Output | null); /** * The % chance that a host will be actually ejected when an outlier status * is detected through consecutive gateway failures. This setting can be * used to disable ejection or to ramp it up slowly. Defaults to 0. */ - 'enforcing_consecutive_gateway_failure'?: (_google_protobuf_UInt32Value__Output); + 'enforcing_consecutive_gateway_failure': (_google_protobuf_UInt32Value__Output | null); /** * Determines whether to distinguish local origin failures from external errors. If set to true * the following configuration parameters are taken into account: @@ -252,7 +252,7 @@ export interface OutlierDetection__Output { * :ref:`split_external_local_origin_errors` * is set to true. */ - 'consecutive_local_origin_failure'?: (_google_protobuf_UInt32Value__Output); + 'consecutive_local_origin_failure': (_google_protobuf_UInt32Value__Output | null); /** * The % chance that a host will be actually ejected when an outlier status * is detected through consecutive locally originated failures. This setting can be @@ -261,7 +261,7 @@ export interface OutlierDetection__Output { * :ref:`split_external_local_origin_errors` * is set to true. */ - 'enforcing_consecutive_local_origin_failure'?: (_google_protobuf_UInt32Value__Output); + 'enforcing_consecutive_local_origin_failure': (_google_protobuf_UInt32Value__Output | null); /** * The % chance that a host will be actually ejected when an outlier status * is detected through success rate statistics for locally originated errors. @@ -270,13 +270,13 @@ export interface OutlierDetection__Output { * :ref:`split_external_local_origin_errors` * is set to true. */ - 'enforcing_local_origin_success_rate'?: (_google_protobuf_UInt32Value__Output); + 'enforcing_local_origin_success_rate': (_google_protobuf_UInt32Value__Output | null); /** * The failure percentage to use when determining failure percentage-based outlier detection. If * the failure percentage of a given host is greater than or equal to this value, it will be * ejected. Defaults to 85. */ - 'failure_percentage_threshold'?: (_google_protobuf_UInt32Value__Output); + 'failure_percentage_threshold': (_google_protobuf_UInt32Value__Output | null); /** * The % chance that a host will be actually ejected when an outlier status is detected through * failure percentage statistics. This setting can be used to disable ejection or to ramp it up @@ -285,30 +285,30 @@ export interface OutlierDetection__Output { * [#next-major-version: setting this without setting failure_percentage_threshold should be * invalid in v4.] */ - 'enforcing_failure_percentage'?: (_google_protobuf_UInt32Value__Output); + 'enforcing_failure_percentage': (_google_protobuf_UInt32Value__Output | null); /** * The % chance that a host will be actually ejected when an outlier status is detected through * local-origin failure percentage statistics. This setting can be used to disable ejection or to * ramp it up slowly. Defaults to 0. */ - 'enforcing_failure_percentage_local_origin'?: (_google_protobuf_UInt32Value__Output); + 'enforcing_failure_percentage_local_origin': (_google_protobuf_UInt32Value__Output | null); /** * The minimum number of hosts in a cluster in order to perform failure percentage-based ejection. * If the total number of hosts in the cluster is less than this value, failure percentage-based * ejection will not be performed. Defaults to 5. */ - 'failure_percentage_minimum_hosts'?: (_google_protobuf_UInt32Value__Output); + 'failure_percentage_minimum_hosts': (_google_protobuf_UInt32Value__Output | null); /** * The minimum number of total requests that must be collected in one interval (as defined by the * interval duration above) to perform failure percentage-based ejection for this host. If the * volume is lower than this setting, failure percentage-based ejection will not be performed for * this host. Defaults to 50. */ - 'failure_percentage_request_volume'?: (_google_protobuf_UInt32Value__Output); + 'failure_percentage_request_volume': (_google_protobuf_UInt32Value__Output | null); /** * The maximum time that a host is ejected for. See :ref:`base_ejection_time` * for more information. * Defaults to 300000ms or 300s. */ - 'max_ejection_time'?: (_google_protobuf_Duration__Output); + 'max_ejection_time': (_google_protobuf_Duration__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 index 0f95c0816..f2dbd0608 100644 --- 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 @@ -10,7 +10,7 @@ export interface UpstreamBindConfig { /** * The address Envoy should bind to when establishing upstream connections. */ - 'source_address'?: (_envoy_config_core_v3_Address); + 'source_address'?: (_envoy_config_core_v3_Address | null); } /** @@ -21,5 +21,5 @@ export interface UpstreamBindConfig__Output { /** * The address Envoy should bind to when establishing upstream connections. */ - 'source_address'?: (_envoy_config_core_v3_Address__Output); + 'source_address': (_envoy_config_core_v3_Address__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/UpstreamConnectionOptions.ts b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/UpstreamConnectionOptions.ts index 2e7f23894..483d1072d 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/UpstreamConnectionOptions.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/UpstreamConnectionOptions.ts @@ -6,12 +6,12 @@ export interface UpstreamConnectionOptions { /** * If set then set SO_KEEPALIVE on the socket to enable TCP Keepalives. */ - 'tcp_keepalive'?: (_envoy_config_core_v3_TcpKeepalive); + 'tcp_keepalive'?: (_envoy_config_core_v3_TcpKeepalive | null); } export interface UpstreamConnectionOptions__Output { /** * If set then set SO_KEEPALIVE on the socket to enable TCP Keepalives. */ - 'tcp_keepalive'?: (_envoy_config_core_v3_TcpKeepalive__Output); + 'tcp_keepalive': (_envoy_config_core_v3_TcpKeepalive__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Address.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Address.ts index 4d5881baf..32c483344 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Address.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Address.ts @@ -10,12 +10,12 @@ import type { EnvoyInternalAddress as _envoy_config_core_v3_EnvoyInternalAddress * management servers. */ export interface Address { - 'socket_address'?: (_envoy_config_core_v3_SocketAddress); - 'pipe'?: (_envoy_config_core_v3_Pipe); + 'socket_address'?: (_envoy_config_core_v3_SocketAddress | null); + 'pipe'?: (_envoy_config_core_v3_Pipe | null); /** * [#not-implemented-hide:] */ - 'envoy_internal_address'?: (_envoy_config_core_v3_EnvoyInternalAddress); + 'envoy_internal_address'?: (_envoy_config_core_v3_EnvoyInternalAddress | null); 'address'?: "socket_address"|"pipe"|"envoy_internal_address"; } @@ -25,11 +25,11 @@ export interface Address { * management servers. */ export interface Address__Output { - 'socket_address'?: (_envoy_config_core_v3_SocketAddress__Output); - 'pipe'?: (_envoy_config_core_v3_Pipe__Output); + 'socket_address'?: (_envoy_config_core_v3_SocketAddress__Output | null); + 'pipe'?: (_envoy_config_core_v3_Pipe__Output | null); /** * [#not-implemented-hide:] */ - 'envoy_internal_address'?: (_envoy_config_core_v3_EnvoyInternalAddress__Output); + 'envoy_internal_address'?: (_envoy_config_core_v3_EnvoyInternalAddress__Output | null); 'address': "socket_address"|"pipe"|"envoy_internal_address"; } 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 99afe9a26..b303a08d8 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 @@ -70,7 +70,7 @@ export interface ApiConfigSource { /** * For REST APIs, the delay between successive polls. */ - 'refresh_delay'?: (_google_protobuf_Duration); + 'refresh_delay'?: (_google_protobuf_Duration | null); /** * Multiple gRPC services be provided for GRPC. If > 1 cluster is defined, * services will be cycled through if any kind of failure occurs. @@ -79,12 +79,12 @@ export interface ApiConfigSource { /** * For REST APIs, the request timeout. If not set, a default value of 1s will be used. */ - 'request_timeout'?: (_google_protobuf_Duration); + 'request_timeout'?: (_google_protobuf_Duration | null); /** * For GRPC APIs, the rate limit settings. If present, discovery requests made by Envoy will be * rate limited. */ - 'rate_limit_settings'?: (_envoy_config_core_v3_RateLimitSettings); + 'rate_limit_settings'?: (_envoy_config_core_v3_RateLimitSettings | null); /** * Skip the node identifier in subsequent discovery requests for streaming gRPC config types. */ @@ -120,7 +120,7 @@ export interface ApiConfigSource__Output { /** * For REST APIs, the delay between successive polls. */ - 'refresh_delay'?: (_google_protobuf_Duration__Output); + 'refresh_delay': (_google_protobuf_Duration__Output | null); /** * Multiple gRPC services be provided for GRPC. If > 1 cluster is defined, * services will be cycled through if any kind of failure occurs. @@ -129,12 +129,12 @@ export interface ApiConfigSource__Output { /** * For REST APIs, the request timeout. If not set, a default value of 1s will be used. */ - 'request_timeout'?: (_google_protobuf_Duration__Output); + 'request_timeout': (_google_protobuf_Duration__Output | null); /** * For GRPC APIs, the rate limit settings. If present, discovery requests made by Envoy will be * rate limited. */ - 'rate_limit_settings'?: (_envoy_config_core_v3_RateLimitSettings__Output); + 'rate_limit_settings': (_envoy_config_core_v3_RateLimitSettings__Output | null); /** * Skip the node identifier in subsequent discovery requests for streaming gRPC config types. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/AsyncDataSource.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/AsyncDataSource.ts index 476ea851f..aa152155b 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/AsyncDataSource.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/AsyncDataSource.ts @@ -10,11 +10,11 @@ export interface AsyncDataSource { /** * Local async data source. */ - 'local'?: (_envoy_config_core_v3_DataSource); + 'local'?: (_envoy_config_core_v3_DataSource | null); /** * Remote async data source. */ - 'remote'?: (_envoy_config_core_v3_RemoteDataSource); + 'remote'?: (_envoy_config_core_v3_RemoteDataSource | null); 'specifier'?: "local"|"remote"; } @@ -25,10 +25,10 @@ export interface AsyncDataSource__Output { /** * Local async data source. */ - 'local'?: (_envoy_config_core_v3_DataSource__Output); + 'local'?: (_envoy_config_core_v3_DataSource__Output | null); /** * Remote async data source. */ - 'remote'?: (_envoy_config_core_v3_RemoteDataSource__Output); + 'remote'?: (_envoy_config_core_v3_RemoteDataSource__Output | null); 'specifier': "local"|"remote"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BackoffStrategy.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BackoffStrategy.ts index 9878375d6..b85b8d5de 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BackoffStrategy.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BackoffStrategy.ts @@ -11,7 +11,7 @@ export interface BackoffStrategy { * be greater than zero and less than or equal to :ref:`max_interval * `. */ - 'base_interval'?: (_google_protobuf_Duration); + 'base_interval'?: (_google_protobuf_Duration | null); /** * Specifies the maximum interval between retries. This parameter is optional, * but must be greater than or equal to the :ref:`base_interval @@ -19,7 +19,7 @@ export interface BackoffStrategy { * is 10 times the :ref:`base_interval * `. */ - 'max_interval'?: (_google_protobuf_Duration); + 'max_interval'?: (_google_protobuf_Duration | null); } /** @@ -31,7 +31,7 @@ export interface BackoffStrategy__Output { * be greater than zero and less than or equal to :ref:`max_interval * `. */ - 'base_interval'?: (_google_protobuf_Duration__Output); + 'base_interval': (_google_protobuf_Duration__Output | null); /** * Specifies the maximum interval between retries. This parameter is optional, * but must be greater than or equal to the :ref:`base_interval @@ -39,5 +39,5 @@ export interface BackoffStrategy__Output { * is 10 times the :ref:`base_interval * `. */ - 'max_interval'?: (_google_protobuf_Duration__Output); + 'max_interval': (_google_protobuf_Duration__Output | null); } 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 eb2bc7626..db6b1f654 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 @@ -8,7 +8,7 @@ export interface BindConfig { /** * The address to bind to when creating a socket. */ - 'source_address'?: (_envoy_config_core_v3_SocketAddress); + 'source_address'?: (_envoy_config_core_v3_SocketAddress | null); /** * Whether to set the *IP_FREEBIND* option when creating the socket. When this * flag is set to true, allows the :ref:`source_address @@ -18,7 +18,7 @@ export interface BindConfig { * flag is not set (default), the socket is not modified, i.e. the option is * neither enabled nor disabled. */ - 'freebind'?: (_google_protobuf_BoolValue); + 'freebind'?: (_google_protobuf_BoolValue | null); /** * Additional socket options that may not be present in Envoy source code or * precompiled binaries. @@ -30,7 +30,7 @@ export interface BindConfig__Output { /** * The address to bind to when creating a socket. */ - 'source_address'?: (_envoy_config_core_v3_SocketAddress__Output); + 'source_address': (_envoy_config_core_v3_SocketAddress__Output | null); /** * Whether to set the *IP_FREEBIND* option when creating the socket. When this * flag is set to true, allows the :ref:`source_address @@ -40,7 +40,7 @@ export interface BindConfig__Output { * flag is not set (default), the socket is not modified, i.e. the option is * neither enabled nor disabled. */ - 'freebind'?: (_google_protobuf_BoolValue__Output); + 'freebind': (_google_protobuf_BoolValue__Output | null); /** * Additional socket options that may not be present in Envoy source code or * precompiled binaries. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BuildVersion.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BuildVersion.ts index a3a33e4a3..1a86e918e 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BuildVersion.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BuildVersion.ts @@ -11,12 +11,12 @@ export interface BuildVersion { /** * SemVer version of extension. */ - 'version'?: (_envoy_type_v3_SemanticVersion); + 'version'?: (_envoy_type_v3_SemanticVersion | null); /** * Free-form build information. * Envoy defines several well known keys in the source/common/version/version.h file */ - 'metadata'?: (_google_protobuf_Struct); + 'metadata'?: (_google_protobuf_Struct | null); } /** @@ -27,10 +27,10 @@ export interface BuildVersion__Output { /** * SemVer version of extension. */ - 'version'?: (_envoy_type_v3_SemanticVersion__Output); + 'version': (_envoy_type_v3_SemanticVersion__Output | null); /** * Free-form build information. * Envoy defines several well known keys in the source/common/version/version.h file */ - 'metadata'?: (_google_protobuf_Struct__Output); + 'metadata': (_google_protobuf_Struct__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/CidrRange.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/CidrRange.ts index c4a01b0da..df4ff39ff 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/CidrRange.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/CidrRange.ts @@ -14,7 +14,7 @@ export interface CidrRange { /** * Length of prefix, e.g. 0, 32. */ - 'prefix_len'?: (_google_protobuf_UInt32Value); + 'prefix_len'?: (_google_protobuf_UInt32Value | null); } /** @@ -29,5 +29,5 @@ export interface CidrRange__Output { /** * Length of prefix, e.g. 0, 32. */ - 'prefix_len'?: (_google_protobuf_UInt32Value__Output); + 'prefix_len': (_google_protobuf_UInt32Value__Output | null); } 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 9462f4844..aaf4d9564 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 @@ -36,12 +36,12 @@ export interface ConfigSource { /** * API configuration source. */ - 'api_config_source'?: (_envoy_config_core_v3_ApiConfigSource); + 'api_config_source'?: (_envoy_config_core_v3_ApiConfigSource | null); /** * When set, ADS will be used to fetch resources. The ADS API configuration * source in the bootstrap configuration is used. */ - 'ads'?: (_envoy_config_core_v3_AggregatedConfigSource); + 'ads'?: (_envoy_config_core_v3_AggregatedConfigSource | null); /** * When this timeout is specified, Envoy will wait no longer than the specified time for first * config response on this xDS subscription during the :ref:`initialization process @@ -51,7 +51,7 @@ export interface ConfigSource { * means no timeout - Envoy will wait indefinitely for the first xDS config (unless another * timeout applies). The default is 15s. */ - 'initial_fetch_timeout'?: (_google_protobuf_Duration); + 'initial_fetch_timeout'?: (_google_protobuf_Duration | null); /** * [#not-implemented-hide:] * When set, the client will access the resources from the same server it got the @@ -65,7 +65,7 @@ export interface ConfigSource { * this field can implicitly mean to use the same stream in the case where the ConfigSource * is provided via ADS and the specified data can also be obtained via ADS.] */ - 'self'?: (_envoy_config_core_v3_SelfConfigSource); + 'self'?: (_envoy_config_core_v3_SelfConfigSource | null); /** * API version for xDS resources. This implies the type URLs that the client * will request for resources and the resource type that the client will in @@ -111,12 +111,12 @@ export interface ConfigSource__Output { /** * API configuration source. */ - 'api_config_source'?: (_envoy_config_core_v3_ApiConfigSource__Output); + 'api_config_source'?: (_envoy_config_core_v3_ApiConfigSource__Output | null); /** * When set, ADS will be used to fetch resources. The ADS API configuration * source in the bootstrap configuration is used. */ - 'ads'?: (_envoy_config_core_v3_AggregatedConfigSource__Output); + 'ads'?: (_envoy_config_core_v3_AggregatedConfigSource__Output | null); /** * When this timeout is specified, Envoy will wait no longer than the specified time for first * config response on this xDS subscription during the :ref:`initialization process @@ -126,7 +126,7 @@ export interface ConfigSource__Output { * means no timeout - Envoy will wait indefinitely for the first xDS config (unless another * timeout applies). The default is 15s. */ - 'initial_fetch_timeout'?: (_google_protobuf_Duration__Output); + 'initial_fetch_timeout': (_google_protobuf_Duration__Output | null); /** * [#not-implemented-hide:] * When set, the client will access the resources from the same server it got the @@ -140,7 +140,7 @@ export interface ConfigSource__Output { * this field can implicitly mean to use the same stream in the case where the ConfigSource * is provided via ADS and the specified data can also be obtained via ADS.] */ - 'self'?: (_envoy_config_core_v3_SelfConfigSource__Output); + 'self'?: (_envoy_config_core_v3_SelfConfigSource__Output | null); /** * API version for xDS resources. This implies the type URLs that the client * will request for resources and the resource type that the client will in diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/EventServiceConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/EventServiceConfig.ts index 72aedc6ab..6226b97c8 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/EventServiceConfig.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/EventServiceConfig.ts @@ -10,7 +10,7 @@ export interface EventServiceConfig { /** * Specifies the gRPC service that hosts the event reporting service. */ - 'grpc_service'?: (_envoy_config_core_v3_GrpcService); + 'grpc_service'?: (_envoy_config_core_v3_GrpcService | null); 'config_source_specifier'?: "grpc_service"; } @@ -22,6 +22,6 @@ export interface EventServiceConfig__Output { /** * Specifies the gRPC service that hosts the event reporting service. */ - 'grpc_service'?: (_envoy_config_core_v3_GrpcService__Output); + 'grpc_service'?: (_envoy_config_core_v3_GrpcService__Output | null); 'config_source_specifier': "grpc_service"; } 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 0c7e0abd3..5f730bd22 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 @@ -31,7 +31,7 @@ export interface Extension { * of other extensions and the Envoy API. * This field is not set when extension did not provide version information. */ - 'version'?: (_envoy_config_core_v3_BuildVersion); + 'version'?: (_envoy_config_core_v3_BuildVersion | null); /** * Indicates that the extension is present but was disabled via dynamic configuration. */ @@ -67,7 +67,7 @@ export interface Extension__Output { * of other extensions and the Envoy API. * This field is not set when extension did not provide version information. */ - 'version'?: (_envoy_config_core_v3_BuildVersion__Output); + 'version': (_envoy_config_core_v3_BuildVersion__Output | null); /** * Indicates that the extension is present but was disabled via dynamic configuration. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ExtensionConfigSource.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ExtensionConfigSource.ts index 085324b6d..805762ef5 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ExtensionConfigSource.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/ExtensionConfigSource.ts @@ -17,13 +17,13 @@ import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__ * filter chain with a disabled extension filter rejects all incoming streams. */ export interface ExtensionConfigSource { - 'config_source'?: (_envoy_config_core_v3_ConfigSource); + 'config_source'?: (_envoy_config_core_v3_ConfigSource | null); /** * Optional default configuration to use as the initial configuration if * there is a failure to receive the initial extension configuration or if * `apply_default_config_without_warming` flag is set. */ - 'default_config'?: (_google_protobuf_Any); + 'default_config'?: (_google_protobuf_Any | null); /** * Use the default config as the initial configuration without warming and * waiting for the first discovery response. Requires the default configuration @@ -51,13 +51,13 @@ export interface ExtensionConfigSource { * filter chain with a disabled extension filter rejects all incoming streams. */ export interface ExtensionConfigSource__Output { - 'config_source'?: (_envoy_config_core_v3_ConfigSource__Output); + 'config_source': (_envoy_config_core_v3_ConfigSource__Output | null); /** * Optional default configuration to use as the initial configuration if * there is a failure to receive the initial extension configuration or if * `apply_default_config_without_warming` flag is set. */ - 'default_config'?: (_google_protobuf_Any__Output); + 'default_config': (_google_protobuf_Any__Output | null); /** * Use the default config as the initial configuration without warming and * waiting for the first discovery response. Requires the default configuration diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/GrpcProtocolOptions.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/GrpcProtocolOptions.ts index b0486cc37..1f0376a1c 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/GrpcProtocolOptions.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/GrpcProtocolOptions.ts @@ -6,12 +6,12 @@ import type { Http2ProtocolOptions as _envoy_config_core_v3_Http2ProtocolOptions * [#not-implemented-hide:] */ export interface GrpcProtocolOptions { - 'http2_protocol_options'?: (_envoy_config_core_v3_Http2ProtocolOptions); + 'http2_protocol_options'?: (_envoy_config_core_v3_Http2ProtocolOptions | null); } /** * [#not-implemented-hide:] */ export interface GrpcProtocolOptions__Output { - 'http2_protocol_options'?: (_envoy_config_core_v3_Http2ProtocolOptions__Output); + 'http2_protocol_options': (_envoy_config_core_v3_Http2ProtocolOptions__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/GrpcService.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/GrpcService.ts index 24249309b..0e55d018b 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/GrpcService.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/GrpcService.ts @@ -22,7 +22,7 @@ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials { * Google Compute Engine credentials. * https://grpc.io/grpc/cpp/namespacegrpc.html#a6beb3ac70ff94bd2ebbd89b8f21d1f61 */ - 'google_compute_engine'?: (_google_protobuf_Empty); + 'google_compute_engine'?: (_google_protobuf_Empty | null); /** * Google refresh token credentials. * https://grpc.io/grpc/cpp/namespacegrpc.html#a96901c997b91bc6513b08491e0dca37c. @@ -32,24 +32,24 @@ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials { * Service Account JWT Access credentials. * https://grpc.io/grpc/cpp/namespacegrpc.html#a92a9f959d6102461f66ee973d8e9d3aa. */ - 'service_account_jwt_access'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials); + 'service_account_jwt_access'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials | null); /** * Google IAM credentials. * https://grpc.io/grpc/cpp/namespacegrpc.html#a9fc1fc101b41e680d47028166e76f9d0. */ - 'google_iam'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials); + 'google_iam'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials | null); /** * Custom authenticator credentials. * https://grpc.io/grpc/cpp/namespacegrpc.html#a823c6a4b19ffc71fb33e90154ee2ad07. * https://grpc.io/docs/guides/auth.html#extending-grpc-to-support-other-authentication-mechanisms. */ - 'from_plugin'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin); + 'from_plugin'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin | null); /** * Custom security token service which implements OAuth 2.0 token exchange. * https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-16 * See https://github.com/grpc/grpc/pull/19587. */ - 'sts_service'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService); + 'sts_service'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService | null); 'credential_specifier'?: "access_token"|"google_compute_engine"|"google_refresh_token"|"service_account_jwt_access"|"google_iam"|"from_plugin"|"sts_service"; } @@ -66,7 +66,7 @@ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials__O * Google Compute Engine credentials. * https://grpc.io/grpc/cpp/namespacegrpc.html#a6beb3ac70ff94bd2ebbd89b8f21d1f61 */ - 'google_compute_engine'?: (_google_protobuf_Empty__Output); + 'google_compute_engine'?: (_google_protobuf_Empty__Output | null); /** * Google refresh token credentials. * https://grpc.io/grpc/cpp/namespacegrpc.html#a96901c997b91bc6513b08491e0dca37c. @@ -76,24 +76,24 @@ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials__O * Service Account JWT Access credentials. * https://grpc.io/grpc/cpp/namespacegrpc.html#a92a9f959d6102461f66ee973d8e9d3aa. */ - 'service_account_jwt_access'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials__Output); + 'service_account_jwt_access'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_ServiceAccountJWTAccessCredentials__Output | null); /** * Google IAM credentials. * https://grpc.io/grpc/cpp/namespacegrpc.html#a9fc1fc101b41e680d47028166e76f9d0. */ - 'google_iam'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials__Output); + 'google_iam'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials__Output | null); /** * Custom authenticator credentials. * https://grpc.io/grpc/cpp/namespacegrpc.html#a823c6a4b19ffc71fb33e90154ee2ad07. * https://grpc.io/docs/guides/auth.html#extending-grpc-to-support-other-authentication-mechanisms. */ - 'from_plugin'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin__Output); + 'from_plugin'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin__Output | null); /** * Custom security token service which implements OAuth 2.0 token exchange. * https://tools.ietf.org/html/draft-ietf-oauth-token-exchange-16 * See https://github.com/grpc/grpc/pull/19587. */ - 'sts_service'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService__Output); + 'sts_service'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_StsService__Output | null); 'credential_specifier': "access_token"|"google_compute_engine"|"google_refresh_token"|"service_account_jwt_access"|"google_iam"|"from_plugin"|"sts_service"; } @@ -114,7 +114,7 @@ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs__Outpu /** * See grpc_types.h GRPC_ARG #defines for keys that work here. */ - 'args'?: ({[key: string]: _envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value__Output}); + 'args': ({[key: string]: _envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value__Output}); } /** @@ -122,12 +122,12 @@ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs__Outpu * credential types. */ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials { - 'ssl_credentials'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials); + 'ssl_credentials'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials | null); /** * https://grpc.io/grpc/cpp/namespacegrpc.html#a6beb3ac70ff94bd2ebbd89b8f21d1f61 */ - 'google_default'?: (_google_protobuf_Empty); - 'local_credentials'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials); + 'google_default'?: (_google_protobuf_Empty | null); + 'local_credentials'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials | null); 'credential_specifier'?: "ssl_credentials"|"google_default"|"local_credentials"; } @@ -136,12 +136,12 @@ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials * credential types. */ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials__Output { - 'ssl_credentials'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials__Output); + 'ssl_credentials'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials__Output | null); /** * https://grpc.io/grpc/cpp/namespacegrpc.html#a6beb3ac70ff94bd2ebbd89b8f21d1f61 */ - 'google_default'?: (_google_protobuf_Empty__Output); - 'local_credentials'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials__Output); + 'google_default'?: (_google_protobuf_Empty__Output | null); + 'local_credentials'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredentials__Output | null); 'credential_specifier': "ssl_credentials"|"google_default"|"local_credentials"; } @@ -183,7 +183,7 @@ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc { * :ref:`channel_credentials `. */ 'target_uri'?: (string); - 'channel_credentials'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials); + 'channel_credentials'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials | null); /** * A set of call credentials that can be composed with `channel credentials * `_. @@ -211,16 +211,16 @@ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc { * Additional configuration for site-specific customizations of the Google * gRPC library. */ - 'config'?: (_google_protobuf_Struct); + 'config'?: (_google_protobuf_Struct | null); /** * How many bytes each stream can buffer internally. * If not set an implementation defined default is applied (1MiB). */ - 'per_stream_buffer_limit_bytes'?: (_google_protobuf_UInt32Value); + 'per_stream_buffer_limit_bytes'?: (_google_protobuf_UInt32Value | null); /** * Custom channels args. */ - 'channel_args'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs); + 'channel_args'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs | null); } /** @@ -233,7 +233,7 @@ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc__Output { * :ref:`channel_credentials `. */ 'target_uri': (string); - 'channel_credentials'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials__Output); + 'channel_credentials': (_envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials__Output | null); /** * A set of call credentials that can be composed with `channel credentials * `_. @@ -261,16 +261,16 @@ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc__Output { * Additional configuration for site-specific customizations of the Google * gRPC library. */ - 'config'?: (_google_protobuf_Struct__Output); + 'config': (_google_protobuf_Struct__Output | null); /** * How many bytes each stream can buffer internally. * If not set an implementation defined default is applied (1MiB). */ - 'per_stream_buffer_limit_bytes'?: (_google_protobuf_UInt32Value__Output); + 'per_stream_buffer_limit_bytes': (_google_protobuf_UInt32Value__Output | null); /** * Custom channels args. */ - 'channel_args'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs__Output); + 'channel_args': (_envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs__Output | null); } export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_GoogleIAMCredentials { @@ -299,13 +299,13 @@ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredent export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin { 'name'?: (string); - 'typed_config'?: (_google_protobuf_Any); + 'typed_config'?: (_google_protobuf_Any | null); 'config_type'?: "typed_config"; } export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin__Output { 'name': (string); - 'typed_config'?: (_google_protobuf_Any__Output); + 'typed_config'?: (_google_protobuf_Any__Output | null); 'config_type': "typed_config"; } @@ -326,15 +326,15 @@ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials { /** * PEM encoded server root certificates. */ - 'root_certs'?: (_envoy_config_core_v3_DataSource); + 'root_certs'?: (_envoy_config_core_v3_DataSource | null); /** * PEM encoded client private key. */ - 'private_key'?: (_envoy_config_core_v3_DataSource); + 'private_key'?: (_envoy_config_core_v3_DataSource | null); /** * PEM encoded client certificate chain. */ - 'cert_chain'?: (_envoy_config_core_v3_DataSource); + 'cert_chain'?: (_envoy_config_core_v3_DataSource | null); } /** @@ -344,15 +344,15 @@ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_SslCredentials__Ou /** * PEM encoded server root certificates. */ - 'root_certs'?: (_envoy_config_core_v3_DataSource__Output); + 'root_certs': (_envoy_config_core_v3_DataSource__Output | null); /** * PEM encoded client private key. */ - 'private_key'?: (_envoy_config_core_v3_DataSource__Output); + 'private_key': (_envoy_config_core_v3_DataSource__Output | null); /** * PEM encoded client certificate chain. */ - 'cert_chain'?: (_envoy_config_core_v3_DataSource__Output); + 'cert_chain': (_envoy_config_core_v3_DataSource__Output | null); } /** @@ -494,18 +494,18 @@ export interface GrpcService { * See the :ref:`gRPC services overview ` * documentation for discussion on gRPC client selection. */ - 'envoy_grpc'?: (_envoy_config_core_v3_GrpcService_EnvoyGrpc); + 'envoy_grpc'?: (_envoy_config_core_v3_GrpcService_EnvoyGrpc | null); /** * `Google C++ gRPC client `_ * See the :ref:`gRPC services overview ` * documentation for discussion on gRPC client selection. */ - 'google_grpc'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc); + 'google_grpc'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc | null); /** * The timeout for the gRPC request. This is the timeout for a specific * request. */ - 'timeout'?: (_google_protobuf_Duration); + 'timeout'?: (_google_protobuf_Duration | null); /** * Additional metadata to include in streams initiated to the GrpcService. This can be used for * scenarios in which additional ad hoc authorization headers (e.g. ``x-foo-bar: baz-key``) are to @@ -528,18 +528,18 @@ export interface GrpcService__Output { * See the :ref:`gRPC services overview ` * documentation for discussion on gRPC client selection. */ - 'envoy_grpc'?: (_envoy_config_core_v3_GrpcService_EnvoyGrpc__Output); + 'envoy_grpc'?: (_envoy_config_core_v3_GrpcService_EnvoyGrpc__Output | null); /** * `Google C++ gRPC client `_ * See the :ref:`gRPC services overview ` * documentation for discussion on gRPC client selection. */ - 'google_grpc'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc__Output); + 'google_grpc'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc__Output | null); /** * The timeout for the gRPC request. This is the timeout for a specific * request. */ - 'timeout'?: (_google_protobuf_Duration__Output); + 'timeout': (_google_protobuf_Duration__Output | null); /** * Additional metadata to include in streams initiated to the GrpcService. This can be used for * scenarios in which additional ad hoc authorization headers (e.g. ``x-foo-bar: baz-key``) are to 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 4a0fe7120..29f9d6695 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 @@ -10,12 +10,12 @@ export interface HeaderValueOption { /** * Header name/value pair that this option applies to. */ - 'header'?: (_envoy_config_core_v3_HeaderValue); + 'header'?: (_envoy_config_core_v3_HeaderValue | null); /** * Should the value be appended? If true (default), the value is appended to * existing values. Otherwise it replaces any existing values. */ - 'append'?: (_google_protobuf_BoolValue); + 'append'?: (_google_protobuf_BoolValue | null); } /** @@ -25,10 +25,10 @@ export interface HeaderValueOption__Output { /** * Header name/value pair that this option applies to. */ - 'header'?: (_envoy_config_core_v3_HeaderValue__Output); + 'header': (_envoy_config_core_v3_HeaderValue__Output | null); /** * Should the value be appended? If true (default), the value is appended to * existing values. Otherwise it replaces any existing values. */ - 'append'?: (_google_protobuf_BoolValue__Output); + 'append': (_google_protobuf_BoolValue__Output | null); } 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 3a7320a08..6dbbf6f4d 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 @@ -20,7 +20,7 @@ export interface _envoy_config_core_v3_HealthCheck_CustomHealthCheck { * The registered name of the custom health checker. */ 'name'?: (string); - 'typed_config'?: (_google_protobuf_Any); + 'typed_config'?: (_google_protobuf_Any | null); /** * A custom health checker specific configuration which depends on the custom health checker * being instantiated. See :api:`envoy/config/health_checker` for reference. @@ -36,7 +36,7 @@ export interface _envoy_config_core_v3_HealthCheck_CustomHealthCheck__Output { * The registered name of the custom health checker. */ 'name': (string); - 'typed_config'?: (_google_protobuf_Any__Output); + 'typed_config'?: (_google_protobuf_Any__Output | null); /** * A custom health checker specific configuration which depends on the custom health checker * being instantiated. See :api:`envoy/config/health_checker` for reference. @@ -111,11 +111,11 @@ export interface _envoy_config_core_v3_HealthCheck_HttpHealthCheck { /** * [#not-implemented-hide:] HTTP specific payload. */ - 'send'?: (_envoy_config_core_v3_HealthCheck_Payload); + 'send'?: (_envoy_config_core_v3_HealthCheck_Payload | null); /** * [#not-implemented-hide:] HTTP specific response. */ - 'receive'?: (_envoy_config_core_v3_HealthCheck_Payload); + 'receive'?: (_envoy_config_core_v3_HealthCheck_Payload | null); /** * Specifies a list of HTTP headers that should be added to each request that is sent to the * health checked cluster. For more information, including details on header value syntax, see @@ -145,7 +145,7 @@ export interface _envoy_config_core_v3_HealthCheck_HttpHealthCheck { * `. See the :ref:`architecture overview * ` for more information. */ - 'service_name_matcher'?: (_envoy_type_matcher_v3_StringMatcher); + 'service_name_matcher'?: (_envoy_type_matcher_v3_StringMatcher | null); } /** @@ -167,11 +167,11 @@ export interface _envoy_config_core_v3_HealthCheck_HttpHealthCheck__Output { /** * [#not-implemented-hide:] HTTP specific payload. */ - 'send'?: (_envoy_config_core_v3_HealthCheck_Payload__Output); + 'send': (_envoy_config_core_v3_HealthCheck_Payload__Output | null); /** * [#not-implemented-hide:] HTTP specific response. */ - 'receive'?: (_envoy_config_core_v3_HealthCheck_Payload__Output); + 'receive': (_envoy_config_core_v3_HealthCheck_Payload__Output | null); /** * Specifies a list of HTTP headers that should be added to each request that is sent to the * health checked cluster. For more information, including details on header value syntax, see @@ -201,7 +201,7 @@ export interface _envoy_config_core_v3_HealthCheck_HttpHealthCheck__Output { * `. See the :ref:`architecture overview * ` for more information. */ - 'service_name_matcher'?: (_envoy_type_matcher_v3_StringMatcher__Output); + 'service_name_matcher': (_envoy_type_matcher_v3_StringMatcher__Output | null); } /** @@ -258,7 +258,7 @@ export interface _envoy_config_core_v3_HealthCheck_TcpHealthCheck { /** * Empty payloads imply a connect-only health check. */ - 'send'?: (_envoy_config_core_v3_HealthCheck_Payload); + 'send'?: (_envoy_config_core_v3_HealthCheck_Payload | null); /** * When checking the response, “fuzzy” matching is performed such that each * binary block must be found, and in the order specified, but not @@ -271,7 +271,7 @@ export interface _envoy_config_core_v3_HealthCheck_TcpHealthCheck__Output { /** * Empty payloads imply a connect-only health check. */ - 'send'?: (_envoy_config_core_v3_HealthCheck_Payload__Output); + 'send': (_envoy_config_core_v3_HealthCheck_Payload__Output | null); /** * When checking the response, “fuzzy” matching is performed such that each * binary block must be found, and in the order specified, but not @@ -320,48 +320,48 @@ export interface HealthCheck { * The time to wait for a health check response. If the timeout is reached the * health check attempt will be considered a failure. */ - 'timeout'?: (_google_protobuf_Duration); + 'timeout'?: (_google_protobuf_Duration | null); /** * The interval between health checks. */ - 'interval'?: (_google_protobuf_Duration); + 'interval'?: (_google_protobuf_Duration | null); /** * An optional jitter amount in milliseconds. If specified, during every * interval Envoy will add interval_jitter to the wait time. */ - 'interval_jitter'?: (_google_protobuf_Duration); + 'interval_jitter'?: (_google_protobuf_Duration | null); /** * The number of unhealthy health checks required before a host is marked * unhealthy. Note that for *http* health checking if a host responds with 503 * this threshold is ignored and the host is considered unhealthy immediately. */ - 'unhealthy_threshold'?: (_google_protobuf_UInt32Value); + 'unhealthy_threshold'?: (_google_protobuf_UInt32Value | null); /** * The number of healthy health checks required before a host is marked * healthy. Note that during startup, only a single successful health check is * required to mark a host healthy. */ - 'healthy_threshold'?: (_google_protobuf_UInt32Value); + 'healthy_threshold'?: (_google_protobuf_UInt32Value | null); /** * [#not-implemented-hide:] Non-serving port for health checking. */ - 'alt_port'?: (_google_protobuf_UInt32Value); + 'alt_port'?: (_google_protobuf_UInt32Value | null); /** * Reuse health check connection between health checks. Default is true. */ - 'reuse_connection'?: (_google_protobuf_BoolValue); + 'reuse_connection'?: (_google_protobuf_BoolValue | null); /** * HTTP health check. */ - 'http_health_check'?: (_envoy_config_core_v3_HealthCheck_HttpHealthCheck); + 'http_health_check'?: (_envoy_config_core_v3_HealthCheck_HttpHealthCheck | null); /** * TCP health check. */ - 'tcp_health_check'?: (_envoy_config_core_v3_HealthCheck_TcpHealthCheck); + 'tcp_health_check'?: (_envoy_config_core_v3_HealthCheck_TcpHealthCheck | null); /** * gRPC health check. */ - 'grpc_health_check'?: (_envoy_config_core_v3_HealthCheck_GrpcHealthCheck); + 'grpc_health_check'?: (_envoy_config_core_v3_HealthCheck_GrpcHealthCheck | null); /** * The "no traffic interval" is a special health check interval that is used when a cluster has * never had traffic routed to it. This lower interval allows cluster information to be kept up to @@ -372,11 +372,11 @@ export interface HealthCheck { * * The default value for "no traffic interval" is 60 seconds. */ - 'no_traffic_interval'?: (_google_protobuf_Duration); + 'no_traffic_interval'?: (_google_protobuf_Duration | null); /** * Custom health check. */ - 'custom_health_check'?: (_envoy_config_core_v3_HealthCheck_CustomHealthCheck); + 'custom_health_check'?: (_envoy_config_core_v3_HealthCheck_CustomHealthCheck | null); /** * The "unhealthy interval" is a health check interval that is used for hosts that are marked as * unhealthy. As soon as the host is marked as healthy, Envoy will shift back to using the @@ -384,7 +384,7 @@ export interface HealthCheck { * * The default value for "unhealthy interval" is the same as "interval". */ - 'unhealthy_interval'?: (_google_protobuf_Duration); + 'unhealthy_interval'?: (_google_protobuf_Duration | null); /** * The "unhealthy edge interval" is a special health check interval that is used for the first * health check right after a host is marked as unhealthy. For subsequent health checks @@ -393,7 +393,7 @@ export interface HealthCheck { * * The default value for "unhealthy edge interval" is the same as "unhealthy interval". */ - 'unhealthy_edge_interval'?: (_google_protobuf_Duration); + 'unhealthy_edge_interval'?: (_google_protobuf_Duration | null); /** * The "healthy edge interval" is a special health check interval that is used for the first * health check right after a host is marked as healthy. For subsequent health checks @@ -401,7 +401,7 @@ export interface HealthCheck { * * The default value for "healthy edge interval" is the same as the default interval. */ - 'healthy_edge_interval'?: (_google_protobuf_Duration); + 'healthy_edge_interval'?: (_google_protobuf_Duration | null); /** * Specifies the path to the :ref:`health check event log `. * If empty, no event log will be written. @@ -427,17 +427,17 @@ export interface HealthCheck { * checking after for a random time in ms between 0 and initial_jitter. This only * applies to the first health check. */ - 'initial_jitter'?: (_google_protobuf_Duration); + 'initial_jitter'?: (_google_protobuf_Duration | null); /** * This allows overriding the cluster TLS settings, just for health check connections. */ - 'tls_options'?: (_envoy_config_core_v3_HealthCheck_TlsOptions); + 'tls_options'?: (_envoy_config_core_v3_HealthCheck_TlsOptions | null); /** * [#not-implemented-hide:] * The gRPC service for the health check event service. * If empty, health check events won't be sent to a remote endpoint. */ - 'event_service'?: (_envoy_config_core_v3_EventServiceConfig); + 'event_service'?: (_envoy_config_core_v3_EventServiceConfig | null); /** * Optional key/value pairs that will be used to match a transport socket from those specified in the cluster's * :ref:`tranport socket matches `. @@ -470,7 +470,7 @@ export interface HealthCheck { * the cluster's :ref:`transport socket ` * will be used for health check socket configuration. */ - 'transport_socket_match_criteria'?: (_google_protobuf_Struct); + 'transport_socket_match_criteria'?: (_google_protobuf_Struct | null); /** * The "no traffic healthy interval" is a special health check interval that * is used for hosts that are currently passing active health checking @@ -486,7 +486,7 @@ export interface HealthCheck { * If no_traffic_healthy_interval is not set, it will default to the * no traffic interval and send that interval regardless of health state. */ - 'no_traffic_healthy_interval'?: (_google_protobuf_Duration); + 'no_traffic_healthy_interval'?: (_google_protobuf_Duration | null); 'health_checker'?: "http_health_check"|"tcp_health_check"|"grpc_health_check"|"custom_health_check"; } @@ -498,48 +498,48 @@ export interface HealthCheck__Output { * The time to wait for a health check response. If the timeout is reached the * health check attempt will be considered a failure. */ - 'timeout'?: (_google_protobuf_Duration__Output); + 'timeout': (_google_protobuf_Duration__Output | null); /** * The interval between health checks. */ - 'interval'?: (_google_protobuf_Duration__Output); + 'interval': (_google_protobuf_Duration__Output | null); /** * An optional jitter amount in milliseconds. If specified, during every * interval Envoy will add interval_jitter to the wait time. */ - 'interval_jitter'?: (_google_protobuf_Duration__Output); + 'interval_jitter': (_google_protobuf_Duration__Output | null); /** * The number of unhealthy health checks required before a host is marked * unhealthy. Note that for *http* health checking if a host responds with 503 * this threshold is ignored and the host is considered unhealthy immediately. */ - 'unhealthy_threshold'?: (_google_protobuf_UInt32Value__Output); + 'unhealthy_threshold': (_google_protobuf_UInt32Value__Output | null); /** * The number of healthy health checks required before a host is marked * healthy. Note that during startup, only a single successful health check is * required to mark a host healthy. */ - 'healthy_threshold'?: (_google_protobuf_UInt32Value__Output); + 'healthy_threshold': (_google_protobuf_UInt32Value__Output | null); /** * [#not-implemented-hide:] Non-serving port for health checking. */ - 'alt_port'?: (_google_protobuf_UInt32Value__Output); + 'alt_port': (_google_protobuf_UInt32Value__Output | null); /** * Reuse health check connection between health checks. Default is true. */ - 'reuse_connection'?: (_google_protobuf_BoolValue__Output); + 'reuse_connection': (_google_protobuf_BoolValue__Output | null); /** * HTTP health check. */ - 'http_health_check'?: (_envoy_config_core_v3_HealthCheck_HttpHealthCheck__Output); + 'http_health_check'?: (_envoy_config_core_v3_HealthCheck_HttpHealthCheck__Output | null); /** * TCP health check. */ - 'tcp_health_check'?: (_envoy_config_core_v3_HealthCheck_TcpHealthCheck__Output); + 'tcp_health_check'?: (_envoy_config_core_v3_HealthCheck_TcpHealthCheck__Output | null); /** * gRPC health check. */ - 'grpc_health_check'?: (_envoy_config_core_v3_HealthCheck_GrpcHealthCheck__Output); + 'grpc_health_check'?: (_envoy_config_core_v3_HealthCheck_GrpcHealthCheck__Output | null); /** * The "no traffic interval" is a special health check interval that is used when a cluster has * never had traffic routed to it. This lower interval allows cluster information to be kept up to @@ -550,11 +550,11 @@ export interface HealthCheck__Output { * * The default value for "no traffic interval" is 60 seconds. */ - 'no_traffic_interval'?: (_google_protobuf_Duration__Output); + 'no_traffic_interval': (_google_protobuf_Duration__Output | null); /** * Custom health check. */ - 'custom_health_check'?: (_envoy_config_core_v3_HealthCheck_CustomHealthCheck__Output); + 'custom_health_check'?: (_envoy_config_core_v3_HealthCheck_CustomHealthCheck__Output | null); /** * The "unhealthy interval" is a health check interval that is used for hosts that are marked as * unhealthy. As soon as the host is marked as healthy, Envoy will shift back to using the @@ -562,7 +562,7 @@ export interface HealthCheck__Output { * * The default value for "unhealthy interval" is the same as "interval". */ - 'unhealthy_interval'?: (_google_protobuf_Duration__Output); + 'unhealthy_interval': (_google_protobuf_Duration__Output | null); /** * The "unhealthy edge interval" is a special health check interval that is used for the first * health check right after a host is marked as unhealthy. For subsequent health checks @@ -571,7 +571,7 @@ export interface HealthCheck__Output { * * The default value for "unhealthy edge interval" is the same as "unhealthy interval". */ - 'unhealthy_edge_interval'?: (_google_protobuf_Duration__Output); + 'unhealthy_edge_interval': (_google_protobuf_Duration__Output | null); /** * The "healthy edge interval" is a special health check interval that is used for the first * health check right after a host is marked as healthy. For subsequent health checks @@ -579,7 +579,7 @@ export interface HealthCheck__Output { * * The default value for "healthy edge interval" is the same as the default interval. */ - 'healthy_edge_interval'?: (_google_protobuf_Duration__Output); + 'healthy_edge_interval': (_google_protobuf_Duration__Output | null); /** * Specifies the path to the :ref:`health check event log `. * If empty, no event log will be written. @@ -605,17 +605,17 @@ export interface HealthCheck__Output { * checking after for a random time in ms between 0 and initial_jitter. This only * applies to the first health check. */ - 'initial_jitter'?: (_google_protobuf_Duration__Output); + 'initial_jitter': (_google_protobuf_Duration__Output | null); /** * This allows overriding the cluster TLS settings, just for health check connections. */ - 'tls_options'?: (_envoy_config_core_v3_HealthCheck_TlsOptions__Output); + 'tls_options': (_envoy_config_core_v3_HealthCheck_TlsOptions__Output | null); /** * [#not-implemented-hide:] * The gRPC service for the health check event service. * If empty, health check events won't be sent to a remote endpoint. */ - 'event_service'?: (_envoy_config_core_v3_EventServiceConfig__Output); + 'event_service': (_envoy_config_core_v3_EventServiceConfig__Output | null); /** * Optional key/value pairs that will be used to match a transport socket from those specified in the cluster's * :ref:`tranport socket matches `. @@ -648,7 +648,7 @@ export interface HealthCheck__Output { * the cluster's :ref:`transport socket ` * will be used for health check socket configuration. */ - 'transport_socket_match_criteria'?: (_google_protobuf_Struct__Output); + 'transport_socket_match_criteria': (_google_protobuf_Struct__Output | null); /** * The "no traffic healthy interval" is a special health check interval that * is used for hosts that are currently passing active health checking @@ -664,6 +664,6 @@ export interface HealthCheck__Output { * If no_traffic_healthy_interval is not set, it will default to the * no traffic interval and send that interval regardless of health state. */ - 'no_traffic_healthy_interval'?: (_google_protobuf_Duration__Output); + 'no_traffic_healthy_interval': (_google_protobuf_Duration__Output | null); 'health_checker': "http_health_check"|"tcp_health_check"|"grpc_health_check"|"custom_health_check"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http1ProtocolOptions.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http1ProtocolOptions.ts index 982f58b0e..89889d390 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http1ProtocolOptions.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http1ProtocolOptions.ts @@ -10,7 +10,7 @@ export interface _envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat { * Note that while this results in most headers following conventional casing, certain headers * are not covered. For example, the "TE" header will be formatted as "Te". */ - 'proper_case_words'?: (_envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords); + 'proper_case_words'?: (_envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords | null); 'header_format'?: "proper_case_words"; } @@ -22,7 +22,7 @@ export interface _envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat__Out * Note that while this results in most headers following conventional casing, certain headers * are not covered. For example, the "TE" header will be formatted as "Te". */ - 'proper_case_words'?: (_envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords__Output); + 'proper_case_words'?: (_envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords__Output | null); 'header_format': "proper_case_words"; } @@ -42,7 +42,7 @@ export interface Http1ProtocolOptions { * envoy as their HTTP proxy. In Unix, for example, this is typically done by setting the * *http_proxy* environment variable. */ - 'allow_absolute_url'?: (_google_protobuf_BoolValue); + 'allow_absolute_url'?: (_google_protobuf_BoolValue | null); /** * Handle incoming HTTP/1.0 and HTTP 0.9 requests. * This is off by default, and not fully standards compliant. There is support for pre-HTTP/1.1 @@ -60,7 +60,7 @@ export interface Http1ProtocolOptions { * Describes how the keys for response headers should be formatted. By default, all header keys * are lower cased. */ - 'header_key_format'?: (_envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat); + 'header_key_format'?: (_envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat | null); /** * Enables trailers for HTTP/1. By default the HTTP/1 codec drops proxied trailers. * @@ -92,7 +92,7 @@ export interface Http1ProtocolOptions { * If set, this overrides any HCM :ref:`stream_error_on_invalid_http_messaging * `. */ - 'override_stream_error_on_invalid_http_message'?: (_google_protobuf_BoolValue); + 'override_stream_error_on_invalid_http_message'?: (_google_protobuf_BoolValue | null); } /** @@ -105,7 +105,7 @@ export interface Http1ProtocolOptions__Output { * envoy as their HTTP proxy. In Unix, for example, this is typically done by setting the * *http_proxy* environment variable. */ - 'allow_absolute_url'?: (_google_protobuf_BoolValue__Output); + 'allow_absolute_url': (_google_protobuf_BoolValue__Output | null); /** * Handle incoming HTTP/1.0 and HTTP 0.9 requests. * This is off by default, and not fully standards compliant. There is support for pre-HTTP/1.1 @@ -123,7 +123,7 @@ export interface Http1ProtocolOptions__Output { * Describes how the keys for response headers should be formatted. By default, all header keys * are lower cased. */ - 'header_key_format'?: (_envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat__Output); + 'header_key_format': (_envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat__Output | null); /** * Enables trailers for HTTP/1. By default the HTTP/1 codec drops proxied trailers. * @@ -155,5 +155,5 @@ export interface Http1ProtocolOptions__Output { * If set, this overrides any HCM :ref:`stream_error_on_invalid_http_messaging * `. */ - 'override_stream_error_on_invalid_http_message'?: (_google_protobuf_BoolValue__Output); + 'override_stream_error_on_invalid_http_message': (_google_protobuf_BoolValue__Output | null); } 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 e379d44be..52908c961 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 @@ -12,11 +12,11 @@ export interface _envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter { /** * The 16 bit parameter identifier. */ - 'identifier'?: (_google_protobuf_UInt32Value); + 'identifier'?: (_google_protobuf_UInt32Value | null); /** * The 32 bit parameter value. */ - 'value'?: (_google_protobuf_UInt32Value); + 'value'?: (_google_protobuf_UInt32Value | null); } /** @@ -27,11 +27,11 @@ export interface _envoy_config_core_v3_Http2ProtocolOptions_SettingsParameter__O /** * The 16 bit parameter identifier. */ - 'identifier'?: (_google_protobuf_UInt32Value__Output); + 'identifier': (_google_protobuf_UInt32Value__Output | null); /** * The 32 bit parameter value. */ - 'value'?: (_google_protobuf_UInt32Value__Output); + 'value': (_google_protobuf_UInt32Value__Output | null); } /** @@ -44,7 +44,7 @@ export interface Http2ProtocolOptions { * range from 0 to 4294967295 (2^32 - 1) and defaults to 4096. 0 effectively disables header * compression. */ - 'hpack_table_size'?: (_google_protobuf_UInt32Value); + 'hpack_table_size'?: (_google_protobuf_UInt32Value | null); /** * `Maximum concurrent streams `_ * allowed for peer on one HTTP/2 connection. Valid values range from 1 to 2147483647 (2^31 - 1) @@ -54,7 +54,7 @@ export interface Http2ProtocolOptions { * on a single connection. If the limit is reached, Envoy may queue requests or establish * additional connections (as allowed per circuit breaker limits). */ - 'max_concurrent_streams'?: (_google_protobuf_UInt32Value); + 'max_concurrent_streams'?: (_google_protobuf_UInt32Value | null); /** * `Initial stream-level flow-control window * `_ size. Valid values range from 65535 @@ -68,12 +68,12 @@ export interface Http2ProtocolOptions { * HTTP/2 codec buffers. Once the buffer reaches this pointer, watermark callbacks will fire to * stop the flow of data to the codec buffers. */ - 'initial_stream_window_size'?: (_google_protobuf_UInt32Value); + 'initial_stream_window_size'?: (_google_protobuf_UInt32Value | null); /** * Similar to *initial_stream_window_size*, but for connection-level flow-control * window. Currently, this has the same minimum/maximum/default as *initial_stream_window_size*. */ - 'initial_connection_window_size'?: (_google_protobuf_UInt32Value); + 'initial_connection_window_size'?: (_google_protobuf_UInt32Value | null); /** * Allows proxying Websocket and other upgrades over H2 connect. */ @@ -95,7 +95,7 @@ export interface Http2ProtocolOptions { * NOTE: flood and abuse mitigation for upstream connections is presently enabled by the * `envoy.reloadable_features.upstream_http2_flood_checks` flag. */ - 'max_outbound_frames'?: (_google_protobuf_UInt32Value); + 'max_outbound_frames'?: (_google_protobuf_UInt32Value | null); /** * Limit the number of pending outbound downstream frames of types PING, SETTINGS and RST_STREAM, * preventing high memory utilization when receiving continuous stream of these frames. Exceeding @@ -105,7 +105,7 @@ export interface Http2ProtocolOptions { * NOTE: flood and abuse mitigation for upstream connections is presently enabled by the * `envoy.reloadable_features.upstream_http2_flood_checks` flag. */ - 'max_outbound_control_frames'?: (_google_protobuf_UInt32Value); + 'max_outbound_control_frames'?: (_google_protobuf_UInt32Value | null); /** * Limit the number of consecutive inbound frames of types HEADERS, CONTINUATION and DATA with an * empty payload and no end stream flag. Those frames have no legitimate use and are abusive, but @@ -116,7 +116,7 @@ export interface Http2ProtocolOptions { * NOTE: flood and abuse mitigation for upstream connections is presently enabled by the * `envoy.reloadable_features.upstream_http2_flood_checks` flag. */ - 'max_consecutive_inbound_frames_with_empty_payload'?: (_google_protobuf_UInt32Value); + 'max_consecutive_inbound_frames_with_empty_payload'?: (_google_protobuf_UInt32Value | null); /** * Limit the number of inbound PRIORITY frames allowed per each opened stream. If the number * of PRIORITY frames received over the lifetime of connection exceeds the value calculated @@ -132,7 +132,7 @@ export interface Http2ProtocolOptions { * NOTE: flood and abuse mitigation for upstream connections is presently enabled by the * `envoy.reloadable_features.upstream_http2_flood_checks` flag. */ - 'max_inbound_priority_frames_per_stream'?: (_google_protobuf_UInt32Value); + 'max_inbound_priority_frames_per_stream'?: (_google_protobuf_UInt32Value | null); /** * Limit the number of inbound WINDOW_UPDATE frames allowed per DATA frame sent. If the number * of WINDOW_UPDATE frames received over the lifetime of connection exceeds the value calculated @@ -151,7 +151,7 @@ export interface Http2ProtocolOptions { * NOTE: flood and abuse mitigation for upstream connections is presently enabled by the * `envoy.reloadable_features.upstream_http2_flood_checks` flag. */ - 'max_inbound_window_update_frames_per_data_frame_sent'?: (_google_protobuf_UInt32Value); + 'max_inbound_window_update_frames_per_data_frame_sent'?: (_google_protobuf_UInt32Value | null); /** * Allows invalid HTTP messaging and headers. When this option is disabled (default), then * the whole HTTP/2 connection is terminated upon receiving invalid HEADERS frame. However, @@ -206,12 +206,12 @@ export interface Http2ProtocolOptions { * * See `RFC7540, sec. 8.1 `_ for details. */ - 'override_stream_error_on_invalid_http_message'?: (_google_protobuf_BoolValue); + 'override_stream_error_on_invalid_http_message'?: (_google_protobuf_BoolValue | null); /** * Send HTTP/2 PING frames to verify that the connection is still healthy. If the remote peer * does not respond within the configured timeout, the connection will be aborted. */ - 'connection_keepalive'?: (_envoy_config_core_v3_KeepaliveSettings); + 'connection_keepalive'?: (_envoy_config_core_v3_KeepaliveSettings | null); } /** @@ -224,7 +224,7 @@ export interface Http2ProtocolOptions__Output { * range from 0 to 4294967295 (2^32 - 1) and defaults to 4096. 0 effectively disables header * compression. */ - 'hpack_table_size'?: (_google_protobuf_UInt32Value__Output); + 'hpack_table_size': (_google_protobuf_UInt32Value__Output | null); /** * `Maximum concurrent streams `_ * allowed for peer on one HTTP/2 connection. Valid values range from 1 to 2147483647 (2^31 - 1) @@ -234,7 +234,7 @@ export interface Http2ProtocolOptions__Output { * on a single connection. If the limit is reached, Envoy may queue requests or establish * additional connections (as allowed per circuit breaker limits). */ - 'max_concurrent_streams'?: (_google_protobuf_UInt32Value__Output); + 'max_concurrent_streams': (_google_protobuf_UInt32Value__Output | null); /** * `Initial stream-level flow-control window * `_ size. Valid values range from 65535 @@ -248,12 +248,12 @@ export interface Http2ProtocolOptions__Output { * HTTP/2 codec buffers. Once the buffer reaches this pointer, watermark callbacks will fire to * stop the flow of data to the codec buffers. */ - 'initial_stream_window_size'?: (_google_protobuf_UInt32Value__Output); + 'initial_stream_window_size': (_google_protobuf_UInt32Value__Output | null); /** * Similar to *initial_stream_window_size*, but for connection-level flow-control * window. Currently, this has the same minimum/maximum/default as *initial_stream_window_size*. */ - 'initial_connection_window_size'?: (_google_protobuf_UInt32Value__Output); + 'initial_connection_window_size': (_google_protobuf_UInt32Value__Output | null); /** * Allows proxying Websocket and other upgrades over H2 connect. */ @@ -275,7 +275,7 @@ export interface Http2ProtocolOptions__Output { * NOTE: flood and abuse mitigation for upstream connections is presently enabled by the * `envoy.reloadable_features.upstream_http2_flood_checks` flag. */ - 'max_outbound_frames'?: (_google_protobuf_UInt32Value__Output); + 'max_outbound_frames': (_google_protobuf_UInt32Value__Output | null); /** * Limit the number of pending outbound downstream frames of types PING, SETTINGS and RST_STREAM, * preventing high memory utilization when receiving continuous stream of these frames. Exceeding @@ -285,7 +285,7 @@ export interface Http2ProtocolOptions__Output { * NOTE: flood and abuse mitigation for upstream connections is presently enabled by the * `envoy.reloadable_features.upstream_http2_flood_checks` flag. */ - 'max_outbound_control_frames'?: (_google_protobuf_UInt32Value__Output); + 'max_outbound_control_frames': (_google_protobuf_UInt32Value__Output | null); /** * Limit the number of consecutive inbound frames of types HEADERS, CONTINUATION and DATA with an * empty payload and no end stream flag. Those frames have no legitimate use and are abusive, but @@ -296,7 +296,7 @@ export interface Http2ProtocolOptions__Output { * NOTE: flood and abuse mitigation for upstream connections is presently enabled by the * `envoy.reloadable_features.upstream_http2_flood_checks` flag. */ - 'max_consecutive_inbound_frames_with_empty_payload'?: (_google_protobuf_UInt32Value__Output); + 'max_consecutive_inbound_frames_with_empty_payload': (_google_protobuf_UInt32Value__Output | null); /** * Limit the number of inbound PRIORITY frames allowed per each opened stream. If the number * of PRIORITY frames received over the lifetime of connection exceeds the value calculated @@ -312,7 +312,7 @@ export interface Http2ProtocolOptions__Output { * NOTE: flood and abuse mitigation for upstream connections is presently enabled by the * `envoy.reloadable_features.upstream_http2_flood_checks` flag. */ - 'max_inbound_priority_frames_per_stream'?: (_google_protobuf_UInt32Value__Output); + 'max_inbound_priority_frames_per_stream': (_google_protobuf_UInt32Value__Output | null); /** * Limit the number of inbound WINDOW_UPDATE frames allowed per DATA frame sent. If the number * of WINDOW_UPDATE frames received over the lifetime of connection exceeds the value calculated @@ -331,7 +331,7 @@ export interface Http2ProtocolOptions__Output { * NOTE: flood and abuse mitigation for upstream connections is presently enabled by the * `envoy.reloadable_features.upstream_http2_flood_checks` flag. */ - 'max_inbound_window_update_frames_per_data_frame_sent'?: (_google_protobuf_UInt32Value__Output); + 'max_inbound_window_update_frames_per_data_frame_sent': (_google_protobuf_UInt32Value__Output | null); /** * Allows invalid HTTP messaging and headers. When this option is disabled (default), then * the whole HTTP/2 connection is terminated upon receiving invalid HEADERS frame. However, @@ -386,10 +386,10 @@ export interface Http2ProtocolOptions__Output { * * See `RFC7540, sec. 8.1 `_ for details. */ - 'override_stream_error_on_invalid_http_message'?: (_google_protobuf_BoolValue__Output); + 'override_stream_error_on_invalid_http_message': (_google_protobuf_BoolValue__Output | null); /** * Send HTTP/2 PING frames to verify that the connection is still healthy. If the remote peer * does not respond within the configured timeout, the connection will be aborted. */ - 'connection_keepalive'?: (_envoy_config_core_v3_KeepaliveSettings__Output); + 'connection_keepalive': (_envoy_config_core_v3_KeepaliveSettings__Output | null); } 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 4a5efeebd..f689ba802 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 @@ -53,13 +53,13 @@ export interface HttpProtocolOptions { * is configured, this timeout is scaled for downstream connections according to the value for * :ref:`HTTP_DOWNSTREAM_CONNECTION_IDLE `. */ - 'idle_timeout'?: (_google_protobuf_Duration); + 'idle_timeout'?: (_google_protobuf_Duration | null); /** * The maximum number of headers. If unconfigured, the default * maximum number of request headers allowed is 100. Requests that exceed this limit will receive * a 431 response for HTTP/1.x and cause a stream reset for HTTP/2. */ - 'max_headers_count'?: (_google_protobuf_UInt32Value); + 'max_headers_count'?: (_google_protobuf_UInt32Value | null); /** * The maximum duration of a connection. The duration is defined as a period since a connection * was established. If not set, there is no max duration. When max_connection_duration is reached @@ -68,12 +68,12 @@ export interface HttpProtocolOptions { * `. * Note: not implemented for upstream connections. */ - 'max_connection_duration'?: (_google_protobuf_Duration); + 'max_connection_duration'?: (_google_protobuf_Duration | null); /** * Total duration to keep alive an HTTP request/response stream. If the time limit is reached the stream will be * reset independent of any other timeouts. If not specified, this value is not set. */ - 'max_stream_duration'?: (_google_protobuf_Duration); + 'max_stream_duration'?: (_google_protobuf_Duration | null); /** * Action to take when a client request with a header name containing underscore characters is received. * If this setting is not specified, the value defaults to ALLOW. @@ -104,13 +104,13 @@ export interface HttpProtocolOptions__Output { * is configured, this timeout is scaled for downstream connections according to the value for * :ref:`HTTP_DOWNSTREAM_CONNECTION_IDLE `. */ - 'idle_timeout'?: (_google_protobuf_Duration__Output); + 'idle_timeout': (_google_protobuf_Duration__Output | null); /** * The maximum number of headers. If unconfigured, the default * maximum number of request headers allowed is 100. Requests that exceed this limit will receive * a 431 response for HTTP/1.x and cause a stream reset for HTTP/2. */ - 'max_headers_count'?: (_google_protobuf_UInt32Value__Output); + 'max_headers_count': (_google_protobuf_UInt32Value__Output | null); /** * The maximum duration of a connection. The duration is defined as a period since a connection * was established. If not set, there is no max duration. When max_connection_duration is reached @@ -119,12 +119,12 @@ export interface HttpProtocolOptions__Output { * `. * Note: not implemented for upstream connections. */ - 'max_connection_duration'?: (_google_protobuf_Duration__Output); + 'max_connection_duration': (_google_protobuf_Duration__Output | null); /** * Total duration to keep alive an HTTP request/response stream. If the time limit is reached the stream will be * reset independent of any other timeouts. If not specified, this value is not set. */ - 'max_stream_duration'?: (_google_protobuf_Duration__Output); + 'max_stream_duration': (_google_protobuf_Duration__Output | null); /** * Action to take when a client request with a header name containing underscore characters is received. * If this setting is not specified, the value defaults to ALLOW. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HttpUri.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HttpUri.ts index 5da6ed4c0..0bac9ac51 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HttpUri.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/HttpUri.ts @@ -30,7 +30,7 @@ export interface HttpUri { /** * Sets the maximum duration in milliseconds that a response can take to arrive upon request. */ - 'timeout'?: (_google_protobuf_Duration); + 'timeout'?: (_google_protobuf_Duration | null); /** * Specify how `uri` is to be fetched. Today, this requires an explicit * cluster, but in the future we may support dynamic cluster creation or @@ -68,7 +68,7 @@ export interface HttpUri__Output { /** * Sets the maximum duration in milliseconds that a response can take to arrive upon request. */ - 'timeout'?: (_google_protobuf_Duration__Output); + 'timeout': (_google_protobuf_Duration__Output | null); /** * Specify how `uri` is to be fetched. Today, this requires an explicit * cluster, but in the future we may support dynamic cluster creation or diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/KeepaliveSettings.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/KeepaliveSettings.ts index cb2e14c58..81344f864 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/KeepaliveSettings.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/KeepaliveSettings.ts @@ -7,34 +7,34 @@ export interface KeepaliveSettings { /** * Send HTTP/2 PING frames at this period, in order to test that the connection is still alive. */ - 'interval'?: (_google_protobuf_Duration); + 'interval'?: (_google_protobuf_Duration | null); /** * How long to wait for a response to a keepalive PING. If a response is not received within this * time period, the connection will be aborted. */ - 'timeout'?: (_google_protobuf_Duration); + 'timeout'?: (_google_protobuf_Duration | null); /** * A random jitter amount as a percentage of interval that will be added to each interval. * A value of zero means there will be no jitter. * The default value is 15%. */ - 'interval_jitter'?: (_envoy_type_v3_Percent); + 'interval_jitter'?: (_envoy_type_v3_Percent | null); } export interface KeepaliveSettings__Output { /** * Send HTTP/2 PING frames at this period, in order to test that the connection is still alive. */ - 'interval'?: (_google_protobuf_Duration__Output); + 'interval': (_google_protobuf_Duration__Output | null); /** * How long to wait for a response to a keepalive PING. If a response is not received within this * time period, the connection will be aborted. */ - 'timeout'?: (_google_protobuf_Duration__Output); + 'timeout': (_google_protobuf_Duration__Output | null); /** * A random jitter amount as a percentage of interval that will be added to each interval. * A value of zero means there will be no jitter. * The default value is 15%. */ - 'interval_jitter'?: (_envoy_type_v3_Percent__Output); + 'interval_jitter': (_envoy_type_v3_Percent__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Metadata.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Metadata.ts index 6d7181f18..8d1811c67 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Metadata.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Metadata.ts @@ -63,5 +63,5 @@ export interface Metadata__Output { * Key is the reverse DNS filter name, e.g. com.acme.widget. The envoy.* * namespace is reserved for Envoy's built-in filters. */ - 'filter_metadata'?: ({[key: string]: _google_protobuf_Struct__Output}); + 'filter_metadata': ({[key: string]: _google_protobuf_Struct__Output}); } 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 717263976..7218b802e 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 @@ -41,11 +41,11 @@ export interface Node { * Opaque metadata extending the node identifier. Envoy will pass this * directly to the management server. */ - 'metadata'?: (_google_protobuf_Struct); + 'metadata'?: (_google_protobuf_Struct | null); /** * Locality specifying where the Envoy instance is running. */ - 'locality'?: (_envoy_config_core_v3_Locality); + 'locality'?: (_envoy_config_core_v3_Locality | null); /** * Free-form string that identifies the entity requesting config. * E.g. "envoy" or "grpc" @@ -59,7 +59,7 @@ export interface Node { /** * Structured version of the entity requesting config. */ - 'user_agent_build_version'?: (_envoy_config_core_v3_BuildVersion); + 'user_agent_build_version'?: (_envoy_config_core_v3_BuildVersion | null); /** * List of extensions and their versions supported by the node. */ @@ -117,11 +117,11 @@ export interface Node__Output { * Opaque metadata extending the node identifier. Envoy will pass this * directly to the management server. */ - 'metadata'?: (_google_protobuf_Struct__Output); + 'metadata': (_google_protobuf_Struct__Output | null); /** * Locality specifying where the Envoy instance is running. */ - 'locality'?: (_envoy_config_core_v3_Locality__Output); + 'locality': (_envoy_config_core_v3_Locality__Output | null); /** * Free-form string that identifies the entity requesting config. * E.g. "envoy" or "grpc" @@ -135,7 +135,7 @@ export interface Node__Output { /** * Structured version of the entity requesting config. */ - 'user_agent_build_version'?: (_envoy_config_core_v3_BuildVersion__Output); + 'user_agent_build_version'?: (_envoy_config_core_v3_BuildVersion__Output | null); /** * List of extensions and their versions supported by the node. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RateLimitSettings.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RateLimitSettings.ts index 8f4093fd4..bf002d99c 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RateLimitSettings.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RateLimitSettings.ts @@ -11,12 +11,12 @@ export interface RateLimitSettings { * Maximum number of tokens to be used for rate limiting discovery request calls. If not set, a * default value of 100 will be used. */ - 'max_tokens'?: (_google_protobuf_UInt32Value); + 'max_tokens'?: (_google_protobuf_UInt32Value | null); /** * Rate at which tokens will be filled per second. If not set, a default fill rate of 10 tokens * per second will be used. */ - 'fill_rate'?: (_google_protobuf_DoubleValue); + 'fill_rate'?: (_google_protobuf_DoubleValue | null); } /** @@ -27,10 +27,10 @@ export interface RateLimitSettings__Output { * Maximum number of tokens to be used for rate limiting discovery request calls. If not set, a * default value of 100 will be used. */ - 'max_tokens'?: (_google_protobuf_UInt32Value__Output); + 'max_tokens': (_google_protobuf_UInt32Value__Output | null); /** * Rate at which tokens will be filled per second. If not set, a default fill rate of 10 tokens * per second will be used. */ - 'fill_rate'?: (_google_protobuf_DoubleValue__Output); + 'fill_rate': (_google_protobuf_DoubleValue__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RemoteDataSource.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RemoteDataSource.ts index 99634015f..917304d97 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RemoteDataSource.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RemoteDataSource.ts @@ -10,7 +10,7 @@ export interface RemoteDataSource { /** * The HTTP URI to fetch the remote data. */ - 'http_uri'?: (_envoy_config_core_v3_HttpUri); + 'http_uri'?: (_envoy_config_core_v3_HttpUri | null); /** * SHA256 string for verifying data. */ @@ -18,7 +18,7 @@ export interface RemoteDataSource { /** * Retry policy for fetching remote data. */ - 'retry_policy'?: (_envoy_config_core_v3_RetryPolicy); + 'retry_policy'?: (_envoy_config_core_v3_RetryPolicy | null); } /** @@ -28,7 +28,7 @@ export interface RemoteDataSource__Output { /** * The HTTP URI to fetch the remote data. */ - 'http_uri'?: (_envoy_config_core_v3_HttpUri__Output); + 'http_uri': (_envoy_config_core_v3_HttpUri__Output | null); /** * SHA256 string for verifying data. */ @@ -36,5 +36,5 @@ export interface RemoteDataSource__Output { /** * Retry policy for fetching remote data. */ - 'retry_policy'?: (_envoy_config_core_v3_RetryPolicy__Output); + 'retry_policy': (_envoy_config_core_v3_RetryPolicy__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RetryPolicy.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RetryPolicy.ts index 6d0d9927b..def6f7311 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RetryPolicy.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RetryPolicy.ts @@ -12,12 +12,12 @@ export interface RetryPolicy { * This parameter is optional, in which case the default base interval is 1000 milliseconds. The * default maximum interval is 10 times the base interval. */ - 'retry_back_off'?: (_envoy_config_core_v3_BackoffStrategy); + 'retry_back_off'?: (_envoy_config_core_v3_BackoffStrategy | null); /** * Specifies the allowed number of retries. This parameter is optional and * defaults to 1. */ - 'num_retries'?: (_google_protobuf_UInt32Value); + 'num_retries'?: (_google_protobuf_UInt32Value | null); } /** @@ -29,10 +29,10 @@ export interface RetryPolicy__Output { * This parameter is optional, in which case the default base interval is 1000 milliseconds. The * default maximum interval is 10 times the base interval. */ - 'retry_back_off'?: (_envoy_config_core_v3_BackoffStrategy__Output); + 'retry_back_off': (_envoy_config_core_v3_BackoffStrategy__Output | null); /** * Specifies the allowed number of retries. This parameter is optional and * defaults to 1. */ - 'num_retries'?: (_google_protobuf_UInt32Value__Output); + 'num_retries': (_google_protobuf_UInt32Value__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeFeatureFlag.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeFeatureFlag.ts index 413a4f931..b6df8d617 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeFeatureFlag.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeFeatureFlag.ts @@ -9,7 +9,7 @@ export interface RuntimeFeatureFlag { /** * Default value if runtime value is not available. */ - 'default_value'?: (_google_protobuf_BoolValue); + 'default_value'?: (_google_protobuf_BoolValue | null); /** * Runtime key to get value for comparison. This value is used if defined. The boolean value must * be represented via its @@ -25,7 +25,7 @@ export interface RuntimeFeatureFlag__Output { /** * Default value if runtime value is not available. */ - 'default_value'?: (_google_protobuf_BoolValue__Output); + 'default_value': (_google_protobuf_BoolValue__Output | null); /** * Runtime key to get value for comparison. This value is used if defined. The boolean value must * be represented via its diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeFractionalPercent.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeFractionalPercent.ts index 5610f7bdd..619bfd484 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeFractionalPercent.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeFractionalPercent.ts @@ -18,7 +18,7 @@ export interface RuntimeFractionalPercent { /** * Default value if the runtime value's for the numerator/denominator keys are not available. */ - 'default_value'?: (_envoy_type_v3_FractionalPercent); + 'default_value'?: (_envoy_type_v3_FractionalPercent | null); /** * Runtime key for a YAML representation of a FractionalPercent. */ @@ -41,7 +41,7 @@ export interface RuntimeFractionalPercent__Output { /** * Default value if the runtime value's for the numerator/denominator keys are not available. */ - 'default_value'?: (_envoy_type_v3_FractionalPercent__Output); + 'default_value': (_envoy_type_v3_FractionalPercent__Output | null); /** * Runtime key for a YAML representation of a FractionalPercent. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimePercent.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimePercent.ts index b317b5aa2..1dbe6ea4a 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimePercent.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimePercent.ts @@ -9,7 +9,7 @@ export interface RuntimePercent { /** * Default value if runtime value is not available. */ - 'default_value'?: (_envoy_type_v3_Percent); + 'default_value'?: (_envoy_type_v3_Percent | null); /** * Runtime key to get value for comparison. This value is used if defined. */ @@ -23,7 +23,7 @@ export interface RuntimePercent__Output { /** * Default value if runtime value is not available. */ - 'default_value'?: (_envoy_type_v3_Percent__Output); + 'default_value': (_envoy_type_v3_Percent__Output | null); /** * Runtime key to get value for comparison. This value is used if defined. */ 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 41bd5e539..ae3003189 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 @@ -53,7 +53,7 @@ export interface SubstitutionFormatString { * "message": "My error message" * } */ - 'json_format'?: (_google_protobuf_Struct); + 'json_format'?: (_google_protobuf_Struct | null); /** * If set to true, when command operators are evaluated to null, * @@ -91,7 +91,7 @@ export interface SubstitutionFormatString { * * upstream connect error:503:path=/foo */ - 'text_format_source'?: (_envoy_config_core_v3_DataSource); + 'text_format_source'?: (_envoy_config_core_v3_DataSource | null); /** * Specifies a collection of Formatter plugins that can be called from the access log configuration. * See the formatters extensions documentation for details. @@ -149,7 +149,7 @@ export interface SubstitutionFormatString__Output { * "message": "My error message" * } */ - 'json_format'?: (_google_protobuf_Struct__Output); + 'json_format'?: (_google_protobuf_Struct__Output | null); /** * If set to true, when command operators are evaluated to null, * @@ -187,7 +187,7 @@ export interface SubstitutionFormatString__Output { * * upstream connect error:503:path=/foo */ - 'text_format_source'?: (_envoy_config_core_v3_DataSource__Output); + 'text_format_source'?: (_envoy_config_core_v3_DataSource__Output | null); /** * Specifies a collection of Formatter plugins that can be called from the access log configuration. * See the formatters extensions documentation for details. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TcpKeepalive.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TcpKeepalive.ts index a1bac359e..1ad81091d 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TcpKeepalive.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TcpKeepalive.ts @@ -8,18 +8,18 @@ export interface TcpKeepalive { * the connection is dead. Default is to use the OS level configuration (unless * overridden, Linux defaults to 9.) */ - 'keepalive_probes'?: (_google_protobuf_UInt32Value); + 'keepalive_probes'?: (_google_protobuf_UInt32Value | null); /** * The number of seconds a connection needs to be idle before keep-alive probes * start being sent. Default is to use the OS level configuration (unless * overridden, Linux defaults to 7200s (i.e., 2 hours.) */ - 'keepalive_time'?: (_google_protobuf_UInt32Value); + 'keepalive_time'?: (_google_protobuf_UInt32Value | null); /** * The number of seconds between keep-alive probes. Default is to use the OS * level configuration (unless overridden, Linux defaults to 75s.) */ - 'keepalive_interval'?: (_google_protobuf_UInt32Value); + 'keepalive_interval'?: (_google_protobuf_UInt32Value | null); } export interface TcpKeepalive__Output { @@ -28,16 +28,16 @@ export interface TcpKeepalive__Output { * the connection is dead. Default is to use the OS level configuration (unless * overridden, Linux defaults to 9.) */ - 'keepalive_probes'?: (_google_protobuf_UInt32Value__Output); + 'keepalive_probes': (_google_protobuf_UInt32Value__Output | null); /** * The number of seconds a connection needs to be idle before keep-alive probes * start being sent. Default is to use the OS level configuration (unless * overridden, Linux defaults to 7200s (i.e., 2 hours.) */ - 'keepalive_time'?: (_google_protobuf_UInt32Value__Output); + 'keepalive_time': (_google_protobuf_UInt32Value__Output | null); /** * The number of seconds between keep-alive probes. Default is to use the OS * level configuration (unless overridden, Linux defaults to 75s.) */ - 'keepalive_interval'?: (_google_protobuf_UInt32Value__Output); + 'keepalive_interval': (_google_protobuf_UInt32Value__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TransportSocket.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TransportSocket.ts index b14402783..0031ad52f 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TransportSocket.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TransportSocket.ts @@ -14,7 +14,7 @@ export interface TransportSocket { * socket implementation. */ 'name'?: (string); - 'typed_config'?: (_google_protobuf_Any); + 'typed_config'?: (_google_protobuf_Any | null); /** * Implementation specific configuration which depends on the implementation being instantiated. * See the supported transport socket implementations for further documentation. @@ -34,7 +34,7 @@ export interface TransportSocket__Output { * socket implementation. */ 'name': (string); - 'typed_config'?: (_google_protobuf_Any__Output); + 'typed_config'?: (_google_protobuf_Any__Output | null); /** * Implementation specific configuration which depends on the implementation being instantiated. * See the supported transport socket implementations for further documentation. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TypedExtensionConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TypedExtensionConfig.ts index 788826a1b..d653f9373 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TypedExtensionConfig.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TypedExtensionConfig.ts @@ -19,7 +19,7 @@ export interface TypedExtensionConfig { * :ref:`extension configuration overview * ` for further details. */ - 'typed_config'?: (_google_protobuf_Any); + 'typed_config'?: (_google_protobuf_Any | null); } /** @@ -39,5 +39,5 @@ export interface TypedExtensionConfig__Output { * :ref:`extension configuration overview * ` for further details. */ - 'typed_config'?: (_google_protobuf_Any__Output); + 'typed_config': (_google_protobuf_Any__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterLoadAssignment.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterLoadAssignment.ts index a092f0dde..03ceb570e 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterLoadAssignment.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterLoadAssignment.ts @@ -17,7 +17,7 @@ export interface _envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOver /** * Percentage of traffic that should be dropped for the category. */ - 'drop_percentage'?: (_envoy_type_v3_FractionalPercent); + 'drop_percentage'?: (_envoy_type_v3_FractionalPercent | null); } /** @@ -31,7 +31,7 @@ export interface _envoy_config_endpoint_v3_ClusterLoadAssignment_Policy_DropOver /** * Percentage of traffic that should be dropped for the category. */ - 'drop_percentage'?: (_envoy_type_v3_FractionalPercent__Output); + 'drop_percentage': (_envoy_type_v3_FractionalPercent__Output | null); } /** @@ -78,14 +78,14 @@ export interface _envoy_config_endpoint_v3_ClusterLoadAssignment_Policy { * Read more at :ref:`priority levels ` and * :ref:`localities `. */ - 'overprovisioning_factor'?: (_google_protobuf_UInt32Value); + 'overprovisioning_factor'?: (_google_protobuf_UInt32Value | null); /** * The max time until which the endpoints from this assignment can be used. * If no new assignments are received before this time expires the endpoints * are considered stale and should be marked unhealthy. * Defaults to 0 which means endpoints never go stale. */ - 'endpoint_stale_after'?: (_google_protobuf_Duration); + 'endpoint_stale_after'?: (_google_protobuf_Duration | null); } /** @@ -132,14 +132,14 @@ export interface _envoy_config_endpoint_v3_ClusterLoadAssignment_Policy__Output * Read more at :ref:`priority levels ` and * :ref:`localities `. */ - 'overprovisioning_factor'?: (_google_protobuf_UInt32Value__Output); + 'overprovisioning_factor': (_google_protobuf_UInt32Value__Output | null); /** * The max time until which the endpoints from this assignment can be used. * If no new assignments are received before this time expires the endpoints * are considered stale and should be marked unhealthy. * Defaults to 0 which means endpoints never go stale. */ - 'endpoint_stale_after'?: (_google_protobuf_Duration__Output); + 'endpoint_stale_after': (_google_protobuf_Duration__Output | null); } /** @@ -169,7 +169,7 @@ export interface ClusterLoadAssignment { /** * Load balancing policy settings. */ - 'policy'?: (_envoy_config_endpoint_v3_ClusterLoadAssignment_Policy); + 'policy'?: (_envoy_config_endpoint_v3_ClusterLoadAssignment_Policy | null); /** * Map of named endpoints that can be referenced in LocalityLbEndpoints. * [#not-implemented-hide:] @@ -204,10 +204,10 @@ export interface ClusterLoadAssignment__Output { /** * Load balancing policy settings. */ - 'policy'?: (_envoy_config_endpoint_v3_ClusterLoadAssignment_Policy__Output); + 'policy': (_envoy_config_endpoint_v3_ClusterLoadAssignment_Policy__Output | null); /** * Map of named endpoints that can be referenced in LocalityLbEndpoints. * [#not-implemented-hide:] */ - 'named_endpoints'?: ({[key: string]: _envoy_config_endpoint_v3_Endpoint__Output}); + 'named_endpoints': ({[key: string]: _envoy_config_endpoint_v3_Endpoint__Output}); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterStats.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterStats.ts index 4d15bee14..db820b0b3 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterStats.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterStats.ts @@ -56,7 +56,7 @@ export interface ClusterStats { * and the *LoadStatsResponse* message sent from the management server, this may be longer than * the requested load reporting interval in the *LoadStatsResponse*. */ - 'load_report_interval'?: (_google_protobuf_Duration); + 'load_report_interval'?: (_google_protobuf_Duration | null); /** * Information about deliberately dropped requests for each category specified * in the DropOverload policy. @@ -100,7 +100,7 @@ export interface ClusterStats__Output { * and the *LoadStatsResponse* message sent from the management server, this may be longer than * the requested load reporting interval in the *LoadStatsResponse*. */ - 'load_report_interval'?: (_google_protobuf_Duration__Output); + 'load_report_interval': (_google_protobuf_Duration__Output | null); /** * Information about deliberately dropped requests for each category specified * in the DropOverload policy. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/Endpoint.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/Endpoint.ts index 7e1a7b346..c01987cce 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/Endpoint.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/Endpoint.ts @@ -63,7 +63,7 @@ export interface Endpoint { * in the Address). For LOGICAL or STRICT DNS, it is expected to be hostname, * and will be resolved via DNS. */ - 'address'?: (_envoy_config_core_v3_Address); + 'address'?: (_envoy_config_core_v3_Address | null); /** * The optional health check configuration is used as configuration for the * health checker to contact the health checked host. @@ -73,7 +73,7 @@ export interface Endpoint { * This takes into effect only for upstream clusters with * :ref:`active health checking ` enabled. */ - 'health_check_config'?: (_envoy_config_endpoint_v3_Endpoint_HealthCheckConfig); + 'health_check_config'?: (_envoy_config_endpoint_v3_Endpoint_HealthCheckConfig | null); /** * The hostname associated with this endpoint. This hostname is not used for routing or address * resolution. If provided, it will be associated with the endpoint, and can be used for features @@ -98,7 +98,7 @@ export interface Endpoint__Output { * in the Address). For LOGICAL or STRICT DNS, it is expected to be hostname, * and will be resolved via DNS. */ - 'address'?: (_envoy_config_core_v3_Address__Output); + 'address': (_envoy_config_core_v3_Address__Output | null); /** * The optional health check configuration is used as configuration for the * health checker to contact the health checked host. @@ -108,7 +108,7 @@ export interface Endpoint__Output { * This takes into effect only for upstream clusters with * :ref:`active health checking ` enabled. */ - 'health_check_config'?: (_envoy_config_endpoint_v3_Endpoint_HealthCheckConfig__Output); + 'health_check_config': (_envoy_config_endpoint_v3_Endpoint_HealthCheckConfig__Output | null); /** * The hostname associated with this endpoint. This hostname is not used for routing or address * resolution. If provided, it will be associated with the endpoint, and can be used for features 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 449dd8aa3..3952a6928 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 @@ -10,7 +10,7 @@ import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output a * [#next-free-field: 6] */ export interface LbEndpoint { - 'endpoint'?: (_envoy_config_endpoint_v3_Endpoint); + 'endpoint'?: (_envoy_config_endpoint_v3_Endpoint | null); /** * Optional health status when known and supplied by EDS server. */ @@ -24,7 +24,7 @@ export interface LbEndpoint { * :ref:`RouteAction ` metadata_match field * to subset the endpoints considered in cluster load balancing. */ - 'metadata'?: (_envoy_config_core_v3_Metadata); + 'metadata'?: (_envoy_config_core_v3_Metadata | null); /** * The optional load balancing weight of the upstream host; at least 1. * Envoy uses the load balancing weight in some of the built in load @@ -36,7 +36,7 @@ export interface LbEndpoint { * weight in a locality. The sum of the weights of all endpoints in the * endpoint's locality must not exceed uint32_t maximal value (4294967295). */ - 'load_balancing_weight'?: (_google_protobuf_UInt32Value); + 'load_balancing_weight'?: (_google_protobuf_UInt32Value | null); /** * [#not-implemented-hide:] */ @@ -52,7 +52,7 @@ export interface LbEndpoint { * [#next-free-field: 6] */ export interface LbEndpoint__Output { - 'endpoint'?: (_envoy_config_endpoint_v3_Endpoint__Output); + 'endpoint'?: (_envoy_config_endpoint_v3_Endpoint__Output | null); /** * Optional health status when known and supplied by EDS server. */ @@ -66,7 +66,7 @@ export interface LbEndpoint__Output { * :ref:`RouteAction ` metadata_match field * to subset the endpoints considered in cluster load balancing. */ - 'metadata'?: (_envoy_config_core_v3_Metadata__Output); + 'metadata': (_envoy_config_core_v3_Metadata__Output | null); /** * The optional load balancing weight of the upstream host; at least 1. * Envoy uses the load balancing weight in some of the built in load @@ -78,7 +78,7 @@ export interface LbEndpoint__Output { * weight in a locality. The sum of the weights of all endpoints in the * endpoint's locality must not exceed uint32_t maximal value (4294967295). */ - 'load_balancing_weight'?: (_google_protobuf_UInt32Value__Output); + 'load_balancing_weight': (_google_protobuf_UInt32Value__Output | null); /** * [#not-implemented-hide:] */ diff --git a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LocalityLbEndpoints.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LocalityLbEndpoints.ts index 9924d2466..22f053ed0 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LocalityLbEndpoints.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LocalityLbEndpoints.ts @@ -15,7 +15,7 @@ export interface LocalityLbEndpoints { /** * Identifies location of where the upstream hosts run. */ - 'locality'?: (_envoy_config_core_v3_Locality); + 'locality'?: (_envoy_config_core_v3_Locality | null); /** * The group of endpoints belonging to the locality specified. */ @@ -33,7 +33,7 @@ export interface LocalityLbEndpoints { * specified when locality weighted load balancing is enabled, the locality is * assigned no load. */ - 'load_balancing_weight'?: (_google_protobuf_UInt32Value); + 'load_balancing_weight'?: (_google_protobuf_UInt32Value | null); /** * Optional: the priority for this LocalityLbEndpoints. If unspecified this will * default to the highest priority (0). @@ -54,7 +54,7 @@ export interface LocalityLbEndpoints { * to determine where to route the requests. * [#not-implemented-hide:] */ - 'proximity'?: (_google_protobuf_UInt32Value); + 'proximity'?: (_google_protobuf_UInt32Value | null); } /** @@ -68,7 +68,7 @@ export interface LocalityLbEndpoints__Output { /** * Identifies location of where the upstream hosts run. */ - 'locality'?: (_envoy_config_core_v3_Locality__Output); + 'locality': (_envoy_config_core_v3_Locality__Output | null); /** * The group of endpoints belonging to the locality specified. */ @@ -86,7 +86,7 @@ export interface LocalityLbEndpoints__Output { * specified when locality weighted load balancing is enabled, the locality is * assigned no load. */ - 'load_balancing_weight'?: (_google_protobuf_UInt32Value__Output); + 'load_balancing_weight': (_google_protobuf_UInt32Value__Output | null); /** * Optional: the priority for this LocalityLbEndpoints. If unspecified this will * default to the highest priority (0). @@ -107,5 +107,5 @@ export interface LocalityLbEndpoints__Output { * to determine where to route the requests. * [#not-implemented-hide:] */ - 'proximity'?: (_google_protobuf_UInt32Value__Output); + 'proximity': (_google_protobuf_UInt32Value__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/UpstreamEndpointStats.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/UpstreamEndpointStats.ts index 8fe66d6c4..ab06afb39 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/UpstreamEndpointStats.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/UpstreamEndpointStats.ts @@ -12,7 +12,7 @@ export interface UpstreamEndpointStats { /** * Upstream host address. */ - 'address'?: (_envoy_config_core_v3_Address); + 'address'?: (_envoy_config_core_v3_Address | null); /** * The total number of requests successfully completed by the endpoints in the * locality. These include non-5xx responses for HTTP, where errors @@ -45,7 +45,7 @@ export interface UpstreamEndpointStats { * Opaque and implementation dependent metadata of the * endpoint. Envoy will pass this directly to the management server. */ - 'metadata'?: (_google_protobuf_Struct); + 'metadata'?: (_google_protobuf_Struct | null); /** * The total number of requests that were issued to this endpoint * since the last report. A single TCP connection, HTTP or gRPC @@ -61,7 +61,7 @@ export interface UpstreamEndpointStats__Output { /** * Upstream host address. */ - 'address'?: (_envoy_config_core_v3_Address__Output); + 'address': (_envoy_config_core_v3_Address__Output | null); /** * The total number of requests successfully completed by the endpoints in the * locality. These include non-5xx responses for HTTP, where errors @@ -94,7 +94,7 @@ export interface UpstreamEndpointStats__Output { * Opaque and implementation dependent metadata of the * endpoint. Envoy will pass this directly to the management server. */ - 'metadata'?: (_google_protobuf_Struct__Output); + 'metadata': (_google_protobuf_Struct__Output | null); /** * The total number of requests that were issued to this endpoint * since the last report. A single TCP connection, HTTP or gRPC diff --git a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/UpstreamLocalityStats.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/UpstreamLocalityStats.ts index 3eb8cc4eb..f00607d00 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/UpstreamLocalityStats.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/UpstreamLocalityStats.ts @@ -16,7 +16,7 @@ export interface UpstreamLocalityStats { * Name of zone, region and optionally endpoint group these metrics were * collected from. Zone and region names could be empty if unknown. */ - 'locality'?: (_envoy_config_core_v3_Locality); + 'locality'?: (_envoy_config_core_v3_Locality | null); /** * The total number of requests successfully completed by the endpoints in the * locality. @@ -65,7 +65,7 @@ export interface UpstreamLocalityStats__Output { * Name of zone, region and optionally endpoint group these metrics were * collected from. Zone and region names could be empty if unknown. */ - 'locality'?: (_envoy_config_core_v3_Locality__Output); + 'locality': (_envoy_config_core_v3_Locality__Output | null); /** * The total number of requests successfully completed by the endpoints in the * locality. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ApiListener.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ApiListener.ts index 508236641..4977911fb 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ApiListener.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ApiListener.ts @@ -17,7 +17,7 @@ export interface ApiListener { * and http_connection_manager.proto depends on rds.proto, which is in the same directory as * lds.proto, so lds.proto cannot depend on this file.] */ - 'api_listener'?: (_google_protobuf_Any); + 'api_listener'?: (_google_protobuf_Any | null); } /** @@ -35,5 +35,5 @@ export interface ApiListener__Output { * and http_connection_manager.proto depends on rds.proto, which is in the same directory as * lds.proto, so lds.proto cannot depend on this file.] */ - 'api_listener'?: (_google_protobuf_Any__Output); + 'api_listener': (_google_protobuf_Any__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/Filter.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/Filter.ts index a3d26c904..3e38fbc00 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/Filter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/Filter.ts @@ -16,14 +16,14 @@ export interface Filter { * Filter specific configuration which depends on the filter being * instantiated. See the supported filters for further documentation. */ - 'typed_config'?: (_google_protobuf_Any); + 'typed_config'?: (_google_protobuf_Any | null); /** * Configuration source specifier for an extension configuration discovery * service. In case of a failure and without the default configuration, the * listener closes the connections. * [#not-implemented-hide:] */ - 'config_discovery'?: (_envoy_config_core_v3_ExtensionConfigSource); + 'config_discovery'?: (_envoy_config_core_v3_ExtensionConfigSource | null); 'config_type'?: "typed_config"|"config_discovery"; } @@ -40,13 +40,13 @@ export interface Filter__Output { * Filter specific configuration which depends on the filter being * instantiated. See the supported filters for further documentation. */ - 'typed_config'?: (_google_protobuf_Any__Output); + 'typed_config'?: (_google_protobuf_Any__Output | null); /** * Configuration source specifier for an extension configuration discovery * service. In case of a failure and without the default configuration, the * listener closes the connections. * [#not-implemented-hide:] */ - 'config_discovery'?: (_envoy_config_core_v3_ExtensionConfigSource__Output); + 'config_discovery'?: (_envoy_config_core_v3_ExtensionConfigSource__Output | null); 'config_type': "typed_config"|"config_discovery"; } 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 e7f0adb7c..d72fa824c 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 @@ -23,7 +23,7 @@ export interface _envoy_config_listener_v3_FilterChain_OnDemandConfiguration { * Upon failure or timeout, all connections related to this filter chain will be closed. * Rebuilding will start again on the next new connection. */ - 'rebuild_timeout'?: (_google_protobuf_Duration); + 'rebuild_timeout'?: (_google_protobuf_Duration | null); } /** @@ -42,7 +42,7 @@ export interface _envoy_config_listener_v3_FilterChain_OnDemandConfiguration__Ou * Upon failure or timeout, all connections related to this filter chain will be closed. * Rebuilding will start again on the next new connection. */ - 'rebuild_timeout'?: (_google_protobuf_Duration__Output); + 'rebuild_timeout': (_google_protobuf_Duration__Output | null); } /** @@ -54,7 +54,7 @@ export interface FilterChain { /** * The criteria to use when matching a connection to this filter chain. */ - 'filter_chain_match'?: (_envoy_config_listener_v3_FilterChainMatch); + 'filter_chain_match'?: (_envoy_config_listener_v3_FilterChainMatch | null); /** * A list of individual network filters that make up the filter chain for * connections established with the listener. Order matters as the filters are @@ -74,11 +74,11 @@ export interface FilterChain { * :ref:`PROXY protocol listener filter ` * explicitly instead. */ - 'use_proxy_proto'?: (_google_protobuf_BoolValue); + 'use_proxy_proto'?: (_google_protobuf_BoolValue | null); /** * [#not-implemented-hide:] filter chain metadata. */ - 'metadata'?: (_envoy_config_core_v3_Metadata); + 'metadata'?: (_envoy_config_core_v3_Metadata | null); /** * Optional custom transport socket implementation to use for downstream connections. * To setup TLS, set a transport socket with name `tls` and @@ -86,7 +86,7 @@ export interface FilterChain { * If no transport socket configuration is specified, new connections * will be set up with plaintext. */ - 'transport_socket'?: (_envoy_config_core_v3_TransportSocket); + 'transport_socket'?: (_envoy_config_core_v3_TransportSocket | null); /** * [#not-implemented-hide:] The unique name (or empty) by which this filter chain is known. If no * name is provided, Envoy will allocate an internal UUID for the filter chain. If the filter @@ -98,13 +98,13 @@ export interface FilterChain { * If this field is not empty, the filter chain will be built on-demand. * Otherwise, the filter chain will be built normally and block listener warming. */ - 'on_demand_configuration'?: (_envoy_config_listener_v3_FilterChain_OnDemandConfiguration); + 'on_demand_configuration'?: (_envoy_config_listener_v3_FilterChain_OnDemandConfiguration | null); /** * If present and nonzero, the amount of time to allow incoming connections to complete any * transport socket negotiations. If this expires before the transport reports connection * establishment, the connection is summarily closed. */ - 'transport_socket_connect_timeout'?: (_google_protobuf_Duration); + 'transport_socket_connect_timeout'?: (_google_protobuf_Duration | null); } /** @@ -116,7 +116,7 @@ export interface FilterChain__Output { /** * The criteria to use when matching a connection to this filter chain. */ - 'filter_chain_match'?: (_envoy_config_listener_v3_FilterChainMatch__Output); + 'filter_chain_match': (_envoy_config_listener_v3_FilterChainMatch__Output | null); /** * A list of individual network filters that make up the filter chain for * connections established with the listener. Order matters as the filters are @@ -136,11 +136,11 @@ export interface FilterChain__Output { * :ref:`PROXY protocol listener filter ` * explicitly instead. */ - 'use_proxy_proto'?: (_google_protobuf_BoolValue__Output); + 'use_proxy_proto': (_google_protobuf_BoolValue__Output | null); /** * [#not-implemented-hide:] filter chain metadata. */ - 'metadata'?: (_envoy_config_core_v3_Metadata__Output); + 'metadata': (_envoy_config_core_v3_Metadata__Output | null); /** * Optional custom transport socket implementation to use for downstream connections. * To setup TLS, set a transport socket with name `tls` and @@ -148,7 +148,7 @@ export interface FilterChain__Output { * If no transport socket configuration is specified, new connections * will be set up with plaintext. */ - 'transport_socket'?: (_envoy_config_core_v3_TransportSocket__Output); + 'transport_socket': (_envoy_config_core_v3_TransportSocket__Output | null); /** * [#not-implemented-hide:] The unique name (or empty) by which this filter chain is known. If no * name is provided, Envoy will allocate an internal UUID for the filter chain. If the filter @@ -160,11 +160,11 @@ export interface FilterChain__Output { * If this field is not empty, the filter chain will be built on-demand. * Otherwise, the filter chain will be built normally and block listener warming. */ - 'on_demand_configuration'?: (_envoy_config_listener_v3_FilterChain_OnDemandConfiguration__Output); + 'on_demand_configuration': (_envoy_config_listener_v3_FilterChain_OnDemandConfiguration__Output | null); /** * If present and nonzero, the amount of time to allow incoming connections to complete any * transport socket negotiations. If this expires before the transport reports connection * establishment, the connection is summarily closed. */ - 'transport_socket_connect_timeout'?: (_google_protobuf_Duration__Output); + 'transport_socket_connect_timeout': (_google_protobuf_Duration__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 1170232ae..042df6dea 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 @@ -78,7 +78,7 @@ export interface FilterChainMatch { /** * [#not-implemented-hide:] */ - 'suffix_len'?: (_google_protobuf_UInt32Value); + 'suffix_len'?: (_google_protobuf_UInt32Value | null); /** * The criteria is satisfied if the source IP address of the downstream * connection is contained in at least one of the specified subnets. If the @@ -96,7 +96,7 @@ export interface FilterChainMatch { * Optional destination port to consider when use_original_dst is set on the * listener in determining a filter chain match. */ - 'destination_port'?: (_google_protobuf_UInt32Value); + 'destination_port'?: (_google_protobuf_UInt32Value | null); /** * If non-empty, a transport protocol to consider when determining a filter chain match. * This value will be compared against the transport protocol of a new connection, when @@ -211,7 +211,7 @@ export interface FilterChainMatch__Output { /** * [#not-implemented-hide:] */ - 'suffix_len'?: (_google_protobuf_UInt32Value__Output); + 'suffix_len': (_google_protobuf_UInt32Value__Output | null); /** * The criteria is satisfied if the source IP address of the downstream * connection is contained in at least one of the specified subnets. If the @@ -229,7 +229,7 @@ export interface FilterChainMatch__Output { * Optional destination port to consider when use_original_dst is set on the * listener in determining a filter chain match. */ - 'destination_port'?: (_google_protobuf_UInt32Value__Output); + 'destination_port': (_google_protobuf_UInt32Value__Output | null); /** * If non-empty, a transport protocol to consider when determining a filter chain match. * This value will be compared against the transport protocol of a new connection, when 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 ebcac4381..8e0fc55f6 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 @@ -21,7 +21,7 @@ export interface _envoy_config_listener_v3_Listener_ConnectionBalanceConfig { /** * If specified, the listener will use the exact connection balancer. */ - 'exact_balance'?: (_envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalance); + 'exact_balance'?: (_envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalance | null); 'balance_type'?: "exact_balance"; } @@ -32,7 +32,7 @@ export interface _envoy_config_listener_v3_Listener_ConnectionBalanceConfig__Out /** * If specified, the listener will use the exact connection balancer. */ - 'exact_balance'?: (_envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalance__Output); + 'exact_balance'?: (_envoy_config_listener_v3_Listener_ConnectionBalanceConfig_ExactBalance__Output | null); 'balance_type': "exact_balance"; } @@ -48,7 +48,7 @@ export interface _envoy_config_listener_v3_Listener_DeprecatedV1 { * This is deprecated. Use :ref:`Listener.bind_to_port * ` */ - 'bind_to_port'?: (_google_protobuf_BoolValue); + 'bind_to_port'?: (_google_protobuf_BoolValue | null); } /** @@ -63,7 +63,7 @@ export interface _envoy_config_listener_v3_Listener_DeprecatedV1__Output { * This is deprecated. Use :ref:`Listener.bind_to_port * ` */ - 'bind_to_port'?: (_google_protobuf_BoolValue__Output); + 'bind_to_port': (_google_protobuf_BoolValue__Output | null); } // Original file: deps/envoy-api/envoy/config/listener/v3/listener.proto @@ -119,7 +119,7 @@ export interface Listener { * that is governed by the bind rules of the OS. E.g., multiple listeners can listen on port 0 on * Linux as the actual port will be allocated by the OS. */ - 'address'?: (_envoy_config_core_v3_Address); + 'address'?: (_envoy_config_core_v3_Address | null); /** * A list of filter chains to consider for this listener. The * :ref:`FilterChain ` with the most specific @@ -137,20 +137,20 @@ export interface Listener { * original destination address. If there is no listener associated with the original destination * address, the connection is handled by the listener that receives it. Defaults to false. */ - 'use_original_dst'?: (_google_protobuf_BoolValue); + 'use_original_dst'?: (_google_protobuf_BoolValue | null); /** * Soft limit on size of the listener’s new connection read and write buffers. * If unspecified, an implementation defined default is applied (1MiB). */ - 'per_connection_buffer_limit_bytes'?: (_google_protobuf_UInt32Value); + 'per_connection_buffer_limit_bytes'?: (_google_protobuf_UInt32Value | null); /** * Listener metadata. */ - 'metadata'?: (_envoy_config_core_v3_Metadata); + 'metadata'?: (_envoy_config_core_v3_Metadata | null); /** * [#not-implemented-hide:] */ - 'deprecated_v1'?: (_envoy_config_listener_v3_Listener_DeprecatedV1); + 'deprecated_v1'?: (_envoy_config_listener_v3_Listener_DeprecatedV1 | null); /** * The type of draining to perform at a listener-wide level. */ @@ -183,7 +183,7 @@ export interface Listener { * When this flag is not set (default), the socket is not modified, i.e. the transparent option * is neither set nor reset. */ - 'transparent'?: (_google_protobuf_BoolValue); + 'transparent'?: (_google_protobuf_BoolValue | null); /** * Whether the listener should set the *IP_FREEBIND* socket option. When this * flag is set to true, listeners can be bound to an IP address that is not @@ -192,7 +192,7 @@ export interface Listener { * (default), the socket is not modified, i.e. the option is neither enabled * nor disabled. */ - 'freebind'?: (_google_protobuf_BoolValue); + 'freebind'?: (_google_protobuf_BoolValue | null); /** * Whether the listener should accept TCP Fast Open (TFO) connections. * When this flag is set to a value greater than 0, the option TCP_FASTOPEN is enabled on @@ -209,7 +209,7 @@ export interface Listener { * On macOS, only values of 0, 1, and unset are valid; other values may result in an error. * To set the queue length on macOS, set the net.inet.tcp.fastopen_backlog kernel parameter. */ - 'tcp_fast_open_queue_length'?: (_google_protobuf_UInt32Value); + 'tcp_fast_open_queue_length'?: (_google_protobuf_UInt32Value | null); /** * Additional socket options that may not be present in Envoy source code or * precompiled binaries. @@ -221,7 +221,7 @@ export interface Listener { * `continue_on_listener_filters_timeout` is set to true. Specify 0 to disable the * timeout. If not specified, a default timeout of 15s is used. */ - 'listener_filters_timeout'?: (_google_protobuf_Duration); + 'listener_filters_timeout'?: (_google_protobuf_Duration | null); /** * Specifies the intended direction of the traffic relative to the local Envoy. */ @@ -244,7 +244,7 @@ export interface Listener { * ` = "raw_udp_listener" for * creating a packet-oriented UDP listener. If not present, treat it as "raw_udp_listener". */ - 'udp_listener_config'?: (_envoy_config_listener_v3_UdpListenerConfig); + 'udp_listener_config'?: (_envoy_config_listener_v3_UdpListenerConfig | null); /** * Used to represent an API listener, which is used in non-proxy clients. The type of API * exposed to the non-proxy application depends on the type of API listener. @@ -263,13 +263,13 @@ export interface Listener { * socket listener and the various types of API listener. That way, a given Listener message * can structurally only contain the fields of the relevant type.] */ - 'api_listener'?: (_envoy_config_listener_v3_ApiListener); + 'api_listener'?: (_envoy_config_listener_v3_ApiListener | null); /** * The listener's connection balancer configuration, currently only applicable to TCP listeners. * If no configuration is specified, Envoy will not attempt to balance active connections between * worker threads. */ - 'connection_balance_config'?: (_envoy_config_listener_v3_Listener_ConnectionBalanceConfig); + 'connection_balance_config'?: (_envoy_config_listener_v3_Listener_ConnectionBalanceConfig | null); /** * When this flag is set to true, listeners set the *SO_REUSEPORT* socket option and * create one socket for each worker thread. This makes inbound connections @@ -298,24 +298,24 @@ export interface Listener { * If not present, treat it as "udp_default_writer". * [#not-implemented-hide:] */ - 'udp_writer_config'?: (_envoy_config_core_v3_TypedExtensionConfig); + 'udp_writer_config'?: (_envoy_config_core_v3_TypedExtensionConfig | null); /** * The maximum length a tcp listener's pending connections queue can grow to. If no value is * provided net.core.somaxconn will be used on Linux and 128 otherwise. */ - 'tcp_backlog_size'?: (_google_protobuf_UInt32Value); + 'tcp_backlog_size'?: (_google_protobuf_UInt32Value | null); /** * The default filter chain if none of the filter chain matches. If no default filter chain is supplied, * the connection will be closed. The filter chain match is ignored in this field. */ - 'default_filter_chain'?: (_envoy_config_listener_v3_FilterChain); + 'default_filter_chain'?: (_envoy_config_listener_v3_FilterChain | null); /** * Whether the listener should bind to the port. A listener that doesn't * bind can only receive connections redirected from other listeners that set * :ref:`use_original_dst ` * to true. Default is true. */ - 'bind_to_port'?: (_google_protobuf_BoolValue); + 'bind_to_port'?: (_google_protobuf_BoolValue | null); } /** @@ -333,7 +333,7 @@ export interface Listener__Output { * that is governed by the bind rules of the OS. E.g., multiple listeners can listen on port 0 on * Linux as the actual port will be allocated by the OS. */ - 'address'?: (_envoy_config_core_v3_Address__Output); + 'address': (_envoy_config_core_v3_Address__Output | null); /** * A list of filter chains to consider for this listener. The * :ref:`FilterChain ` with the most specific @@ -351,20 +351,20 @@ export interface Listener__Output { * original destination address. If there is no listener associated with the original destination * address, the connection is handled by the listener that receives it. Defaults to false. */ - 'use_original_dst'?: (_google_protobuf_BoolValue__Output); + 'use_original_dst': (_google_protobuf_BoolValue__Output | null); /** * Soft limit on size of the listener’s new connection read and write buffers. * If unspecified, an implementation defined default is applied (1MiB). */ - 'per_connection_buffer_limit_bytes'?: (_google_protobuf_UInt32Value__Output); + 'per_connection_buffer_limit_bytes': (_google_protobuf_UInt32Value__Output | null); /** * Listener metadata. */ - 'metadata'?: (_envoy_config_core_v3_Metadata__Output); + 'metadata': (_envoy_config_core_v3_Metadata__Output | null); /** * [#not-implemented-hide:] */ - 'deprecated_v1'?: (_envoy_config_listener_v3_Listener_DeprecatedV1__Output); + 'deprecated_v1': (_envoy_config_listener_v3_Listener_DeprecatedV1__Output | null); /** * The type of draining to perform at a listener-wide level. */ @@ -397,7 +397,7 @@ export interface Listener__Output { * When this flag is not set (default), the socket is not modified, i.e. the transparent option * is neither set nor reset. */ - 'transparent'?: (_google_protobuf_BoolValue__Output); + 'transparent': (_google_protobuf_BoolValue__Output | null); /** * Whether the listener should set the *IP_FREEBIND* socket option. When this * flag is set to true, listeners can be bound to an IP address that is not @@ -406,7 +406,7 @@ export interface Listener__Output { * (default), the socket is not modified, i.e. the option is neither enabled * nor disabled. */ - 'freebind'?: (_google_protobuf_BoolValue__Output); + 'freebind': (_google_protobuf_BoolValue__Output | null); /** * Whether the listener should accept TCP Fast Open (TFO) connections. * When this flag is set to a value greater than 0, the option TCP_FASTOPEN is enabled on @@ -423,7 +423,7 @@ export interface Listener__Output { * On macOS, only values of 0, 1, and unset are valid; other values may result in an error. * To set the queue length on macOS, set the net.inet.tcp.fastopen_backlog kernel parameter. */ - 'tcp_fast_open_queue_length'?: (_google_protobuf_UInt32Value__Output); + 'tcp_fast_open_queue_length': (_google_protobuf_UInt32Value__Output | null); /** * Additional socket options that may not be present in Envoy source code or * precompiled binaries. @@ -435,7 +435,7 @@ export interface Listener__Output { * `continue_on_listener_filters_timeout` is set to true. Specify 0 to disable the * timeout. If not specified, a default timeout of 15s is used. */ - 'listener_filters_timeout'?: (_google_protobuf_Duration__Output); + 'listener_filters_timeout': (_google_protobuf_Duration__Output | null); /** * Specifies the intended direction of the traffic relative to the local Envoy. */ @@ -458,7 +458,7 @@ export interface Listener__Output { * ` = "raw_udp_listener" for * creating a packet-oriented UDP listener. If not present, treat it as "raw_udp_listener". */ - 'udp_listener_config'?: (_envoy_config_listener_v3_UdpListenerConfig__Output); + 'udp_listener_config': (_envoy_config_listener_v3_UdpListenerConfig__Output | null); /** * Used to represent an API listener, which is used in non-proxy clients. The type of API * exposed to the non-proxy application depends on the type of API listener. @@ -477,13 +477,13 @@ export interface Listener__Output { * socket listener and the various types of API listener. That way, a given Listener message * can structurally only contain the fields of the relevant type.] */ - 'api_listener'?: (_envoy_config_listener_v3_ApiListener__Output); + 'api_listener': (_envoy_config_listener_v3_ApiListener__Output | null); /** * The listener's connection balancer configuration, currently only applicable to TCP listeners. * If no configuration is specified, Envoy will not attempt to balance active connections between * worker threads. */ - 'connection_balance_config'?: (_envoy_config_listener_v3_Listener_ConnectionBalanceConfig__Output); + 'connection_balance_config': (_envoy_config_listener_v3_Listener_ConnectionBalanceConfig__Output | null); /** * When this flag is set to true, listeners set the *SO_REUSEPORT* socket option and * create one socket for each worker thread. This makes inbound connections @@ -512,22 +512,22 @@ export interface Listener__Output { * If not present, treat it as "udp_default_writer". * [#not-implemented-hide:] */ - 'udp_writer_config'?: (_envoy_config_core_v3_TypedExtensionConfig__Output); + 'udp_writer_config': (_envoy_config_core_v3_TypedExtensionConfig__Output | null); /** * The maximum length a tcp listener's pending connections queue can grow to. If no value is * provided net.core.somaxconn will be used on Linux and 128 otherwise. */ - 'tcp_backlog_size'?: (_google_protobuf_UInt32Value__Output); + 'tcp_backlog_size': (_google_protobuf_UInt32Value__Output | null); /** * The default filter chain if none of the filter chain matches. If no default filter chain is supplied, * the connection will be closed. The filter chain match is ignored in this field. */ - 'default_filter_chain'?: (_envoy_config_listener_v3_FilterChain__Output); + 'default_filter_chain': (_envoy_config_listener_v3_FilterChain__Output | null); /** * Whether the listener should bind to the port. A listener that doesn't * bind can only receive connections redirected from other listeners that set * :ref:`use_original_dst ` * to true. Default is true. */ - 'bind_to_port'?: (_google_protobuf_BoolValue__Output); + 'bind_to_port': (_google_protobuf_BoolValue__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilter.ts index e8a827618..beba60dce 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilter.ts @@ -9,13 +9,13 @@ export interface ListenerFilter { * :ref:`supported filter `. */ 'name'?: (string); - 'typed_config'?: (_google_protobuf_Any); + 'typed_config'?: (_google_protobuf_Any | null); /** * Optional match predicate used to disable the filter. The filter is enabled when this field is empty. * See :ref:`ListenerFilterChainMatchPredicate ` * for further examples. */ - 'filter_disabled'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate); + 'filter_disabled'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate | null); /** * Filter specific configuration which depends on the filter being instantiated. * See the supported filters for further documentation. @@ -29,13 +29,13 @@ export interface ListenerFilter__Output { * :ref:`supported filter `. */ 'name': (string); - 'typed_config'?: (_google_protobuf_Any__Output); + 'typed_config'?: (_google_protobuf_Any__Output | null); /** * Optional match predicate used to disable the filter. The filter is enabled when this field is empty. * See :ref:`ListenerFilterChainMatchPredicate ` * for further examples. */ - 'filter_disabled'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate__Output); + 'filter_disabled': (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate__Output | null); /** * Filter specific configuration which depends on the filter being instantiated. * See the supported filters for further documentation. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilterChainMatchPredicate.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilterChainMatchPredicate.ts index e0d9ccc3e..34f937fa1 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilterChainMatchPredicate.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilterChainMatchPredicate.ts @@ -57,16 +57,16 @@ export interface ListenerFilterChainMatchPredicate { * A set that describes a logical OR. If any member of the set matches, the match configuration * matches. */ - 'or_match'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet); + 'or_match'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet | null); /** * A set that describes a logical AND. If all members of the set match, the match configuration * matches. */ - 'and_match'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet); + 'and_match'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet | null); /** * A negation match. The match configuration will match if the negated match condition matches. */ - 'not_match'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate); + 'not_match'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate | null); /** * The match configuration will always match. */ @@ -75,7 +75,7 @@ export interface ListenerFilterChainMatchPredicate { * Match destination port. Particularly, the match evaluation must use the recovered local port if * the owning listener filter is after :ref:`an original_dst listener filter `. */ - 'destination_port_range'?: (_envoy_type_v3_Int32Range); + 'destination_port_range'?: (_envoy_type_v3_Int32Range | null); 'rule'?: "or_match"|"and_match"|"not_match"|"any_match"|"destination_port_range"; } @@ -113,16 +113,16 @@ export interface ListenerFilterChainMatchPredicate__Output { * A set that describes a logical OR. If any member of the set matches, the match configuration * matches. */ - 'or_match'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet__Output); + 'or_match'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet__Output | null); /** * A set that describes a logical AND. If all members of the set match, the match configuration * matches. */ - 'and_match'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet__Output); + 'and_match'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate_MatchSet__Output | null); /** * A negation match. The match configuration will match if the negated match condition matches. */ - 'not_match'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate__Output); + 'not_match'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate__Output | null); /** * The match configuration will always match. */ @@ -131,6 +131,6 @@ export interface ListenerFilterChainMatchPredicate__Output { * Match destination port. Particularly, the match evaluation must use the recovered local port if * the owning listener filter is after :ref:`an original_dst listener filter `. */ - 'destination_port_range'?: (_envoy_type_v3_Int32Range__Output); + 'destination_port_range'?: (_envoy_type_v3_Int32Range__Output | null); 'rule': "or_match"|"and_match"|"not_match"|"any_match"|"destination_port_range"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/UdpListenerConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/UdpListenerConfig.ts index c7475c42b..2ac4463fb 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/UdpListenerConfig.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/UdpListenerConfig.ts @@ -9,7 +9,7 @@ export interface UdpListenerConfig { * If not specified, treat as "raw_udp_listener". */ 'udp_listener_name'?: (string); - 'typed_config'?: (_google_protobuf_Any); + 'typed_config'?: (_google_protobuf_Any | null); /** * Used to create a specific listener factory. To some factory, e.g. * "raw_udp_listener", config is not needed. @@ -24,7 +24,7 @@ export interface UdpListenerConfig__Output { * If not specified, treat as "raw_udp_listener". */ 'udp_listener_name': (string); - 'typed_config'?: (_google_protobuf_Any__Output); + 'typed_config'?: (_google_protobuf_Any__Output | null); /** * Used to create a specific listener factory. To some factory, e.g. * "raw_udp_listener", config is not needed. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/CorsPolicy.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/CorsPolicy.ts index c292a199a..03ec3218d 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/CorsPolicy.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/CorsPolicy.ts @@ -27,7 +27,7 @@ export interface CorsPolicy { /** * Specifies whether the resource allows credentials. */ - 'allow_credentials'?: (_google_protobuf_BoolValue); + 'allow_credentials'?: (_google_protobuf_BoolValue | null); /** * Specifies the % of requests for which the CORS filter is enabled. * @@ -37,7 +37,7 @@ export interface CorsPolicy { * If :ref:`runtime_key ` is * specified, Envoy will lookup the runtime key to get the percentage of requests to filter. */ - 'filter_enabled'?: (_envoy_config_core_v3_RuntimeFractionalPercent); + 'filter_enabled'?: (_envoy_config_core_v3_RuntimeFractionalPercent | null); /** * Specifies the % of requests for which the CORS policies will be evaluated and tracked, but not * enforced. @@ -49,7 +49,7 @@ export interface CorsPolicy { * Envoy will lookup the runtime key to get the percentage of requests for which it will evaluate * and track the request's *Origin* to determine if it's valid but will not enforce any policies. */ - 'shadow_enabled'?: (_envoy_config_core_v3_RuntimeFractionalPercent); + 'shadow_enabled'?: (_envoy_config_core_v3_RuntimeFractionalPercent | null); /** * Specifies string patterns that match allowed origins. An origin is allowed if any of the * string matchers match. @@ -81,7 +81,7 @@ export interface CorsPolicy__Output { /** * Specifies whether the resource allows credentials. */ - 'allow_credentials'?: (_google_protobuf_BoolValue__Output); + 'allow_credentials': (_google_protobuf_BoolValue__Output | null); /** * Specifies the % of requests for which the CORS filter is enabled. * @@ -91,7 +91,7 @@ export interface CorsPolicy__Output { * If :ref:`runtime_key ` is * specified, Envoy will lookup the runtime key to get the percentage of requests to filter. */ - 'filter_enabled'?: (_envoy_config_core_v3_RuntimeFractionalPercent__Output); + 'filter_enabled'?: (_envoy_config_core_v3_RuntimeFractionalPercent__Output | null); /** * Specifies the % of requests for which the CORS policies will be evaluated and tracked, but not * enforced. @@ -103,7 +103,7 @@ export interface CorsPolicy__Output { * Envoy will lookup the runtime key to get the percentage of requests for which it will evaluate * and track the request's *Origin* to determine if it's valid but will not enforce any policies. */ - 'shadow_enabled'?: (_envoy_config_core_v3_RuntimeFractionalPercent__Output); + 'shadow_enabled': (_envoy_config_core_v3_RuntimeFractionalPercent__Output | null); /** * Specifies string patterns that match allowed origins. An origin is allowed if any of the * string matchers match. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Decorator.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Decorator.ts index 00e37d98f..fa8bef1d8 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Decorator.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Decorator.ts @@ -17,7 +17,7 @@ export interface Decorator { /** * Whether the decorated details should be propagated to the other party. The default is true. */ - 'propagate'?: (_google_protobuf_BoolValue); + 'propagate'?: (_google_protobuf_BoolValue | null); } export interface Decorator__Output { @@ -35,5 +35,5 @@ export interface Decorator__Output { /** * Whether the decorated details should be propagated to the other party. The default is true. */ - 'propagate'?: (_google_protobuf_BoolValue__Output); + 'propagate': (_google_protobuf_BoolValue__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/DirectResponseAction.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/DirectResponseAction.ts index 9088fe712..7e0c3a1b7 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/DirectResponseAction.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/DirectResponseAction.ts @@ -17,7 +17,7 @@ export interface DirectResponseAction { * :ref:`envoy_api_msg_config.route.v3.Route`, :ref:`envoy_api_msg_config.route.v3.RouteConfiguration` or * :ref:`envoy_api_msg_config.route.v3.VirtualHost`. */ - 'body'?: (_envoy_config_core_v3_DataSource); + 'body'?: (_envoy_config_core_v3_DataSource | null); } export interface DirectResponseAction__Output { @@ -35,5 +35,5 @@ export interface DirectResponseAction__Output { * :ref:`envoy_api_msg_config.route.v3.Route`, :ref:`envoy_api_msg_config.route.v3.RouteConfiguration` or * :ref:`envoy_api_msg_config.route.v3.VirtualHost`. */ - 'body'?: (_envoy_config_core_v3_DataSource__Output); + 'body': (_envoy_config_core_v3_DataSource__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/FilterAction.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/FilterAction.ts index 78221b2c7..2765c0799 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/FilterAction.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/FilterAction.ts @@ -6,12 +6,12 @@ import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__ * A filter-defined action type. */ export interface FilterAction { - 'action'?: (_google_protobuf_Any); + 'action'?: (_google_protobuf_Any | null); } /** * A filter-defined action type. */ export interface FilterAction__Output { - 'action'?: (_google_protobuf_Any__Output); + 'action': (_google_protobuf_Any__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/FilterConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/FilterConfig.ts index ff5976e0b..9a566c2bb 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/FilterConfig.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/FilterConfig.ts @@ -15,7 +15,7 @@ export interface FilterConfig { /** * The filter config. */ - 'config'?: (_google_protobuf_Any); + 'config'?: (_google_protobuf_Any | null); /** * If true, the filter is optional, meaning that if the client does * not support the specified filter, it may ignore the map entry rather @@ -37,7 +37,7 @@ export interface FilterConfig__Output { /** * The filter config. */ - 'config'?: (_google_protobuf_Any__Output); + 'config': (_google_protobuf_Any__Output | null); /** * If true, the filter is optional, meaning that if the client does * not support the specified filter, it may ignore the map entry rather 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 8d20c5c63..ee03d1fe7 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 @@ -53,7 +53,7 @@ export interface HeaderMatcher { * * For range [-10,0), route will match for header value -1, but not for 0, "somestring", 10.9, * "-1somestring" */ - 'range_match'?: (_envoy_type_v3_Int64Range); + 'range_match'?: (_envoy_type_v3_Int64Range | null); /** * If specified, header match will be performed based on whether the header is in the * request. @@ -91,7 +91,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. */ - 'safe_regex_match'?: (_envoy_type_matcher_v3_RegexMatcher); + 'safe_regex_match'?: (_envoy_type_matcher_v3_RegexMatcher | null); /** * If specified, header match will be performed based on whether the header value contains * the given value or not. @@ -157,7 +157,7 @@ export interface HeaderMatcher__Output { * * For range [-10,0), route will match for header value -1, but not for 0, "somestring", 10.9, * "-1somestring" */ - 'range_match'?: (_envoy_type_v3_Int64Range__Output); + 'range_match'?: (_envoy_type_v3_Int64Range__Output | null); /** * If specified, header match will be performed based on whether the header is in the * request. @@ -195,7 +195,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. */ - 'safe_regex_match'?: (_envoy_type_matcher_v3_RegexMatcher__Output); + 'safe_regex_match'?: (_envoy_type_matcher_v3_RegexMatcher__Output | null); /** * If specified, header match will be performed based on whether the header value contains * the given value or not. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/HedgePolicy.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/HedgePolicy.ts index 344d825e7..413e93b27 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/HedgePolicy.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/HedgePolicy.ts @@ -13,14 +13,14 @@ export interface HedgePolicy { * Defaults to 1. * [#not-implemented-hide:] */ - 'initial_requests'?: (_google_protobuf_UInt32Value); + 'initial_requests'?: (_google_protobuf_UInt32Value | null); /** * Specifies a probability that an additional upstream request should be sent * on top of what is specified by initial_requests. * Defaults to 0. * [#not-implemented-hide:] */ - 'additional_request_chance'?: (_envoy_type_v3_FractionalPercent); + 'additional_request_chance'?: (_envoy_type_v3_FractionalPercent | null); /** * Indicates that a hedged request should be sent when the per-try timeout is hit. * This means that a retry will be issued without resetting the original request, leaving multiple upstream requests in flight. @@ -49,14 +49,14 @@ export interface HedgePolicy__Output { * Defaults to 1. * [#not-implemented-hide:] */ - 'initial_requests'?: (_google_protobuf_UInt32Value__Output); + 'initial_requests': (_google_protobuf_UInt32Value__Output | null); /** * Specifies a probability that an additional upstream request should be sent * on top of what is specified by initial_requests. * Defaults to 0. * [#not-implemented-hide:] */ - 'additional_request_chance'?: (_envoy_type_v3_FractionalPercent__Output); + 'additional_request_chance': (_envoy_type_v3_FractionalPercent__Output | null); /** * Indicates that a hedged request should be sent when the per-try timeout is hit. * This means that a retry will be issued without resetting the original request, leaving multiple upstream requests in flight. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/InternalRedirectPolicy.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/InternalRedirectPolicy.ts index 73a2bb32e..93a96c247 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/InternalRedirectPolicy.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/InternalRedirectPolicy.ts @@ -17,7 +17,7 @@ export interface InternalRedirectPolicy { * * If not specified, at most one redirect will be followed. */ - 'max_internal_redirects'?: (_google_protobuf_UInt32Value); + 'max_internal_redirects'?: (_google_protobuf_UInt32Value | null); /** * Defines what upstream response codes are allowed to trigger internal redirect. If unspecified, * only 302 will be treated as internal redirect. @@ -51,7 +51,7 @@ export interface InternalRedirectPolicy__Output { * * If not specified, at most one redirect will be followed. */ - 'max_internal_redirects'?: (_google_protobuf_UInt32Value__Output); + 'max_internal_redirects': (_google_protobuf_UInt32Value__Output | null); /** * Defines what upstream response codes are allowed to trigger internal redirect. If unspecified, * only 302 will be treated as internal redirect. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/QueryParameterMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/QueryParameterMatcher.ts index c88fa8ff7..d511259b0 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/QueryParameterMatcher.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/QueryParameterMatcher.ts @@ -16,7 +16,7 @@ export interface QueryParameterMatcher { /** * Specifies whether a query parameter value should match against a string. */ - 'string_match'?: (_envoy_type_matcher_v3_StringMatcher); + 'string_match'?: (_envoy_type_matcher_v3_StringMatcher | null); /** * Specifies whether a query parameter should be present. */ @@ -38,7 +38,7 @@ export interface QueryParameterMatcher__Output { /** * Specifies whether a query parameter value should match against a string. */ - 'string_match'?: (_envoy_type_matcher_v3_StringMatcher__Output); + 'string_match'?: (_envoy_type_matcher_v3_StringMatcher__Output | null); /** * Specifies whether a query parameter should be present. */ 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 33d93af7d..484044bdf 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 @@ -13,42 +13,42 @@ export interface _envoy_config_route_v3_RateLimit_Action { /** * Rate limit on source cluster. */ - 'source_cluster'?: (_envoy_config_route_v3_RateLimit_Action_SourceCluster); + 'source_cluster'?: (_envoy_config_route_v3_RateLimit_Action_SourceCluster | null); /** * Rate limit on destination cluster. */ - 'destination_cluster'?: (_envoy_config_route_v3_RateLimit_Action_DestinationCluster); + 'destination_cluster'?: (_envoy_config_route_v3_RateLimit_Action_DestinationCluster | null); /** * Rate limit on request headers. */ - 'request_headers'?: (_envoy_config_route_v3_RateLimit_Action_RequestHeaders); + 'request_headers'?: (_envoy_config_route_v3_RateLimit_Action_RequestHeaders | null); /** * Rate limit on remote address. */ - 'remote_address'?: (_envoy_config_route_v3_RateLimit_Action_RemoteAddress); + 'remote_address'?: (_envoy_config_route_v3_RateLimit_Action_RemoteAddress | null); /** * Rate limit on a generic key. */ - 'generic_key'?: (_envoy_config_route_v3_RateLimit_Action_GenericKey); + 'generic_key'?: (_envoy_config_route_v3_RateLimit_Action_GenericKey | null); /** * Rate limit on the existence of request headers. */ - 'header_value_match'?: (_envoy_config_route_v3_RateLimit_Action_HeaderValueMatch); + 'header_value_match'?: (_envoy_config_route_v3_RateLimit_Action_HeaderValueMatch | null); /** * Rate limit on dynamic metadata. * * .. attention:: * This field has been deprecated in favor of the :ref:`metadata ` field */ - 'dynamic_metadata'?: (_envoy_config_route_v3_RateLimit_Action_DynamicMetaData); + 'dynamic_metadata'?: (_envoy_config_route_v3_RateLimit_Action_DynamicMetaData | null); /** * Rate limit on metadata. */ - 'metadata'?: (_envoy_config_route_v3_RateLimit_Action_MetaData); + 'metadata'?: (_envoy_config_route_v3_RateLimit_Action_MetaData | null); /** * Rate limit descriptor extension. See the rate limit descriptor extensions documentation. */ - 'extension'?: (_envoy_config_core_v3_TypedExtensionConfig); + 'extension'?: (_envoy_config_core_v3_TypedExtensionConfig | null); 'action_specifier'?: "source_cluster"|"destination_cluster"|"request_headers"|"remote_address"|"generic_key"|"header_value_match"|"dynamic_metadata"|"metadata"|"extension"; } @@ -59,42 +59,42 @@ export interface _envoy_config_route_v3_RateLimit_Action__Output { /** * Rate limit on source cluster. */ - 'source_cluster'?: (_envoy_config_route_v3_RateLimit_Action_SourceCluster__Output); + 'source_cluster'?: (_envoy_config_route_v3_RateLimit_Action_SourceCluster__Output | null); /** * Rate limit on destination cluster. */ - 'destination_cluster'?: (_envoy_config_route_v3_RateLimit_Action_DestinationCluster__Output); + 'destination_cluster'?: (_envoy_config_route_v3_RateLimit_Action_DestinationCluster__Output | null); /** * Rate limit on request headers. */ - 'request_headers'?: (_envoy_config_route_v3_RateLimit_Action_RequestHeaders__Output); + 'request_headers'?: (_envoy_config_route_v3_RateLimit_Action_RequestHeaders__Output | null); /** * Rate limit on remote address. */ - 'remote_address'?: (_envoy_config_route_v3_RateLimit_Action_RemoteAddress__Output); + 'remote_address'?: (_envoy_config_route_v3_RateLimit_Action_RemoteAddress__Output | null); /** * Rate limit on a generic key. */ - 'generic_key'?: (_envoy_config_route_v3_RateLimit_Action_GenericKey__Output); + 'generic_key'?: (_envoy_config_route_v3_RateLimit_Action_GenericKey__Output | null); /** * Rate limit on the existence of request headers. */ - 'header_value_match'?: (_envoy_config_route_v3_RateLimit_Action_HeaderValueMatch__Output); + 'header_value_match'?: (_envoy_config_route_v3_RateLimit_Action_HeaderValueMatch__Output | null); /** * Rate limit on dynamic metadata. * * .. attention:: * This field has been deprecated in favor of the :ref:`metadata ` field */ - 'dynamic_metadata'?: (_envoy_config_route_v3_RateLimit_Action_DynamicMetaData__Output); + 'dynamic_metadata'?: (_envoy_config_route_v3_RateLimit_Action_DynamicMetaData__Output | null); /** * Rate limit on metadata. */ - 'metadata'?: (_envoy_config_route_v3_RateLimit_Action_MetaData__Output); + 'metadata'?: (_envoy_config_route_v3_RateLimit_Action_MetaData__Output | null); /** * Rate limit descriptor extension. See the rate limit descriptor extensions documentation. */ - 'extension'?: (_envoy_config_core_v3_TypedExtensionConfig__Output); + 'extension'?: (_envoy_config_core_v3_TypedExtensionConfig__Output | null); 'action_specifier': "source_cluster"|"destination_cluster"|"request_headers"|"remote_address"|"generic_key"|"header_value_match"|"dynamic_metadata"|"metadata"|"extension"; } @@ -160,7 +160,7 @@ export interface _envoy_config_route_v3_RateLimit_Action_DynamicMetaData { * Metadata struct that defines the key and path to retrieve the string value. A match will * only happen if the value in the dynamic metadata is of type string. */ - 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey); + 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey | null); /** * An optional value to use if *metadata_key* is empty. If not set and * no value is present under the metadata_key then no descriptor is generated. @@ -188,7 +188,7 @@ export interface _envoy_config_route_v3_RateLimit_Action_DynamicMetaData__Output * Metadata struct that defines the key and path to retrieve the string value. A match will * only happen if the value in the dynamic metadata is of type string. */ - 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey__Output); + 'metadata_key': (_envoy_type_metadata_v3_MetadataKey__Output | null); /** * An optional value to use if *metadata_key* is empty. If not set and * no value is present under the metadata_key then no descriptor is generated. @@ -206,7 +206,7 @@ export interface _envoy_config_route_v3_RateLimit_Override_DynamicMetadata { * and a "unit" property with a value parseable to :ref:`RateLimitUnit * enum ` */ - 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey); + 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey | null); } /** @@ -219,7 +219,7 @@ export interface _envoy_config_route_v3_RateLimit_Override_DynamicMetadata__Outp * and a "unit" property with a value parseable to :ref:`RateLimitUnit * enum ` */ - 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey__Output); + 'metadata_key': (_envoy_type_metadata_v3_MetadataKey__Output | null); } /** @@ -278,7 +278,7 @@ export interface _envoy_config_route_v3_RateLimit_Action_HeaderValueMatch { * descriptor entry when the request does not match the headers. The * default value is true. */ - 'expect_match'?: (_google_protobuf_BoolValue); + 'expect_match'?: (_google_protobuf_BoolValue | null); /** * Specifies a set of headers that the rate limit action should match * on. The action will check the request’s headers against all the @@ -307,7 +307,7 @@ export interface _envoy_config_route_v3_RateLimit_Action_HeaderValueMatch__Outpu * descriptor entry when the request does not match the headers. The * default value is true. */ - 'expect_match'?: (_google_protobuf_BoolValue__Output); + 'expect_match': (_google_protobuf_BoolValue__Output | null); /** * Specifies a set of headers that the rate limit action should match * on. The action will check the request’s headers against all the @@ -334,7 +334,7 @@ export interface _envoy_config_route_v3_RateLimit_Action_MetaData { * Metadata struct that defines the key and path to retrieve the string value. A match will * only happen if the value in the metadata is of type string. */ - 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey); + 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey | null); /** * An optional value to use if *metadata_key* is empty. If not set and * no value is present under the metadata_key then no descriptor is generated. @@ -362,7 +362,7 @@ export interface _envoy_config_route_v3_RateLimit_Action_MetaData__Output { * Metadata struct that defines the key and path to retrieve the string value. A match will * only happen if the value in the metadata is of type string. */ - 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey__Output); + 'metadata_key': (_envoy_type_metadata_v3_MetadataKey__Output | null); /** * An optional value to use if *metadata_key* is empty. If not set and * no value is present under the metadata_key then no descriptor is generated. @@ -378,7 +378,7 @@ export interface _envoy_config_route_v3_RateLimit_Override { /** * Limit override from dynamic metadata. */ - 'dynamic_metadata'?: (_envoy_config_route_v3_RateLimit_Override_DynamicMetadata); + 'dynamic_metadata'?: (_envoy_config_route_v3_RateLimit_Override_DynamicMetadata | null); 'override_specifier'?: "dynamic_metadata"; } @@ -386,7 +386,7 @@ export interface _envoy_config_route_v3_RateLimit_Override__Output { /** * Limit override from dynamic metadata. */ - 'dynamic_metadata'?: (_envoy_config_route_v3_RateLimit_Override_DynamicMetadata__Output); + 'dynamic_metadata'?: (_envoy_config_route_v3_RateLimit_Override_DynamicMetadata__Output | null); 'override_specifier': "dynamic_metadata"; } @@ -517,7 +517,7 @@ export interface RateLimit { * * The filter supports a range of 0 - 10 inclusively for stage numbers. */ - 'stage'?: (_google_protobuf_UInt32Value); + 'stage'?: (_google_protobuf_UInt32Value | null); /** * The key to be set in runtime to disable this rate limit configuration. */ @@ -537,7 +537,7 @@ export interface RateLimit { * from metadata, no override is provided. See :ref:`rate limit override * ` for more information. */ - 'limit'?: (_envoy_config_route_v3_RateLimit_Override); + 'limit'?: (_envoy_config_route_v3_RateLimit_Override | null); } /** @@ -554,7 +554,7 @@ export interface RateLimit__Output { * * The filter supports a range of 0 - 10 inclusively for stage numbers. */ - 'stage'?: (_google_protobuf_UInt32Value__Output); + 'stage': (_google_protobuf_UInt32Value__Output | null); /** * The key to be set in runtime to disable this rate limit configuration. */ @@ -574,5 +574,5 @@ export interface RateLimit__Output { * from metadata, no override is provided. See :ref:`rate limit override * ` for more information. */ - 'limit'?: (_envoy_config_route_v3_RateLimit_Override__Output); + 'limit': (_envoy_config_route_v3_RateLimit_Override__Output | null); } 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 baea6bc4e..750946934 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 @@ -112,7 +112,7 @@ export interface RedirectAction { * would do a case-insensitive match and transform path ``/aaa/XxX/bbb`` to * ``/aaa/yyy/bbb``. */ - 'regex_rewrite'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute); + 'regex_rewrite'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute | null); /** * When the scheme redirection take place, the following rules apply: * 1. If the source URI scheme is `http` and the port is explicitly @@ -209,7 +209,7 @@ export interface RedirectAction__Output { * would do a case-insensitive match and transform path ``/aaa/XxX/bbb`` to * ``/aaa/yyy/bbb``. */ - 'regex_rewrite'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute__Output); + 'regex_rewrite'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute__Output | null); /** * When the scheme redirection take place, the following rules apply: * 1. If the source URI scheme is `http` and the port is explicitly 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 52f391dd9..d4712b2df 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 @@ -64,7 +64,7 @@ export interface _envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff { * header contains an interval longer than this then it will be discarded and * the next header will be tried. Defaults to 300 seconds. */ - 'max_interval'?: (_google_protobuf_Duration); + 'max_interval'?: (_google_protobuf_Duration | null); } /** @@ -125,7 +125,7 @@ export interface _envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff__Out * header contains an interval longer than this then it will be discarded and * the next header will be tried. Defaults to 300 seconds. */ - 'max_interval'?: (_google_protobuf_Duration__Output); + 'max_interval': (_google_protobuf_Duration__Output | null); } export interface _envoy_config_route_v3_RetryPolicy_ResetHeader { @@ -172,14 +172,14 @@ export interface _envoy_config_route_v3_RetryPolicy_RetryBackOff { * See :ref:`config_http_filters_router_x-envoy-max-retries` for a discussion of Envoy's * back-off algorithm. */ - 'base_interval'?: (_google_protobuf_Duration); + 'base_interval'?: (_google_protobuf_Duration | null); /** * Specifies the maximum interval between retries. This parameter is optional, but must be * greater than or equal to the `base_interval` if set. The default is 10 times the * `base_interval`. See :ref:`config_http_filters_router_x-envoy-max-retries` for a discussion * of Envoy's back-off algorithm. */ - 'max_interval'?: (_google_protobuf_Duration); + 'max_interval'?: (_google_protobuf_Duration | null); } export interface _envoy_config_route_v3_RetryPolicy_RetryBackOff__Output { @@ -189,37 +189,37 @@ export interface _envoy_config_route_v3_RetryPolicy_RetryBackOff__Output { * See :ref:`config_http_filters_router_x-envoy-max-retries` for a discussion of Envoy's * back-off algorithm. */ - 'base_interval'?: (_google_protobuf_Duration__Output); + 'base_interval': (_google_protobuf_Duration__Output | null); /** * Specifies the maximum interval between retries. This parameter is optional, but must be * greater than or equal to the `base_interval` if set. The default is 10 times the * `base_interval`. See :ref:`config_http_filters_router_x-envoy-max-retries` for a discussion * of Envoy's back-off algorithm. */ - 'max_interval'?: (_google_protobuf_Duration__Output); + 'max_interval': (_google_protobuf_Duration__Output | null); } export interface _envoy_config_route_v3_RetryPolicy_RetryHostPredicate { 'name'?: (string); - 'typed_config'?: (_google_protobuf_Any); + 'typed_config'?: (_google_protobuf_Any | null); 'config_type'?: "typed_config"; } export interface _envoy_config_route_v3_RetryPolicy_RetryHostPredicate__Output { 'name': (string); - 'typed_config'?: (_google_protobuf_Any__Output); + 'typed_config'?: (_google_protobuf_Any__Output | null); 'config_type': "typed_config"; } export interface _envoy_config_route_v3_RetryPolicy_RetryPriority { 'name'?: (string); - 'typed_config'?: (_google_protobuf_Any); + 'typed_config'?: (_google_protobuf_Any | null); 'config_type'?: "typed_config"; } export interface _envoy_config_route_v3_RetryPolicy_RetryPriority__Output { 'name': (string); - 'typed_config'?: (_google_protobuf_Any__Output); + 'typed_config'?: (_google_protobuf_Any__Output | null); 'config_type': "typed_config"; } @@ -239,7 +239,7 @@ export interface RetryPolicy { * defaults to 1. These are the same conditions documented for * :ref:`config_http_filters_router_x-envoy-max-retries`. */ - 'num_retries'?: (_google_protobuf_UInt32Value); + 'num_retries'?: (_google_protobuf_UInt32Value | null); /** * Specifies a non-zero upstream timeout per retry attempt. This parameter is optional. The * same conditions documented for @@ -253,13 +253,13 @@ export interface RetryPolicy { * retry policy, a request that times out will not be retried as the total timeout budget * would have been exhausted. */ - 'per_try_timeout'?: (_google_protobuf_Duration); + 'per_try_timeout'?: (_google_protobuf_Duration | null); /** * Specifies an implementation of a RetryPriority which is used to determine the * distribution of load across priorities used for retries. Refer to * :ref:`retry plugin configuration ` for more details. */ - 'retry_priority'?: (_envoy_config_route_v3_RetryPolicy_RetryPriority); + 'retry_priority'?: (_envoy_config_route_v3_RetryPolicy_RetryPriority | null); /** * Specifies a collection of RetryHostPredicates that will be consulted when selecting a host * for retries. If any of the predicates reject the host, host selection will be reattempted. @@ -284,7 +284,7 @@ export interface RetryPolicy { * the base interval. The documentation for :ref:`config_http_filters_router_x-envoy-max-retries` * describes Envoy's back-off algorithm. */ - 'retry_back_off'?: (_envoy_config_route_v3_RetryPolicy_RetryBackOff); + 'retry_back_off'?: (_envoy_config_route_v3_RetryPolicy_RetryBackOff | null); /** * HTTP response headers that trigger a retry if present in the response. A retry will be * triggered if any of the header matches match the upstream response headers. @@ -304,7 +304,7 @@ export interface RetryPolicy { * default exponential back off strategy (configured using `retry_back_off`) * whenever a response includes the matching headers. */ - 'rate_limited_retry_back_off'?: (_envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff); + 'rate_limited_retry_back_off'?: (_envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff | null); } /** @@ -323,7 +323,7 @@ export interface RetryPolicy__Output { * defaults to 1. These are the same conditions documented for * :ref:`config_http_filters_router_x-envoy-max-retries`. */ - 'num_retries'?: (_google_protobuf_UInt32Value__Output); + 'num_retries': (_google_protobuf_UInt32Value__Output | null); /** * Specifies a non-zero upstream timeout per retry attempt. This parameter is optional. The * same conditions documented for @@ -337,13 +337,13 @@ export interface RetryPolicy__Output { * retry policy, a request that times out will not be retried as the total timeout budget * would have been exhausted. */ - 'per_try_timeout'?: (_google_protobuf_Duration__Output); + 'per_try_timeout': (_google_protobuf_Duration__Output | null); /** * Specifies an implementation of a RetryPriority which is used to determine the * distribution of load across priorities used for retries. Refer to * :ref:`retry plugin configuration ` for more details. */ - 'retry_priority'?: (_envoy_config_route_v3_RetryPolicy_RetryPriority__Output); + 'retry_priority': (_envoy_config_route_v3_RetryPolicy_RetryPriority__Output | null); /** * Specifies a collection of RetryHostPredicates that will be consulted when selecting a host * for retries. If any of the predicates reject the host, host selection will be reattempted. @@ -368,7 +368,7 @@ export interface RetryPolicy__Output { * the base interval. The documentation for :ref:`config_http_filters_router_x-envoy-max-retries` * describes Envoy's back-off algorithm. */ - 'retry_back_off'?: (_envoy_config_route_v3_RetryPolicy_RetryBackOff__Output); + 'retry_back_off': (_envoy_config_route_v3_RetryPolicy_RetryBackOff__Output | null); /** * HTTP response headers that trigger a retry if present in the response. A retry will be * triggered if any of the header matches match the upstream response headers. @@ -388,5 +388,5 @@ export interface RetryPolicy__Output { * default exponential back off strategy (configured using `retry_back_off`) * whenever a response includes the matching headers. */ - 'rate_limited_retry_back_off'?: (_envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff__Output); + 'rate_limited_retry_back_off': (_envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Route.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Route.ts index ea00564f8..7bc223f82 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Route.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Route.ts @@ -26,15 +26,15 @@ export interface Route { /** * Route matching parameters. */ - 'match'?: (_envoy_config_route_v3_RouteMatch); + 'match'?: (_envoy_config_route_v3_RouteMatch | null); /** * Route request to some upstream cluster. */ - 'route'?: (_envoy_config_route_v3_RouteAction); + 'route'?: (_envoy_config_route_v3_RouteAction | null); /** * Return a redirect. */ - 'redirect'?: (_envoy_config_route_v3_RedirectAction); + 'redirect'?: (_envoy_config_route_v3_RedirectAction | null); /** * The Metadata field can be used to provide additional information * about the route. It can be used for configuration, stats, and logging. @@ -42,15 +42,15 @@ export interface Route { * For instance, if the metadata is intended for the Router filter, * the filter name should be specified as *envoy.filters.http.router*. */ - 'metadata'?: (_envoy_config_core_v3_Metadata); + 'metadata'?: (_envoy_config_core_v3_Metadata | null); /** * Decorator for the matched route. */ - 'decorator'?: (_envoy_config_route_v3_Decorator); + 'decorator'?: (_envoy_config_route_v3_Decorator | null); /** * Return an arbitrary HTTP response directly, without proxying. */ - 'direct_response'?: (_envoy_config_route_v3_DirectResponseAction); + 'direct_response'?: (_envoy_config_route_v3_DirectResponseAction | null); /** * Specifies a set of headers that will be added to requests matching this * route. Headers specified at this level are applied before headers from the @@ -98,13 +98,13 @@ export interface Route { * Presence of the object defines whether the connection manager's tracing configuration * is overridden by this route specific instance. */ - 'tracing'?: (_envoy_config_route_v3_Tracing); + 'tracing'?: (_envoy_config_route_v3_Tracing | null); /** * The maximum bytes which will be buffered for retries and shadowing. * If set, the bytes actually buffered will be the minimum value of this and the * listener per_connection_buffer_limit_bytes. */ - 'per_request_buffer_limit_bytes'?: (_google_protobuf_UInt32Value); + 'per_request_buffer_limit_bytes'?: (_google_protobuf_UInt32Value | null); /** * [#not-implemented-hide:] * If true, a filter will define the action (e.g., it could dynamically generate the @@ -112,7 +112,7 @@ export interface Route { * [#comment: TODO(samflattery): Remove cleanup in route_fuzz_test.cc when * implemented] */ - 'filter_action'?: (_envoy_config_route_v3_FilterAction); + 'filter_action'?: (_envoy_config_route_v3_FilterAction | null); 'action'?: "route"|"redirect"|"direct_response"|"filter_action"; } @@ -130,15 +130,15 @@ export interface Route__Output { /** * Route matching parameters. */ - 'match'?: (_envoy_config_route_v3_RouteMatch__Output); + 'match': (_envoy_config_route_v3_RouteMatch__Output | null); /** * Route request to some upstream cluster. */ - 'route'?: (_envoy_config_route_v3_RouteAction__Output); + 'route'?: (_envoy_config_route_v3_RouteAction__Output | null); /** * Return a redirect. */ - 'redirect'?: (_envoy_config_route_v3_RedirectAction__Output); + 'redirect'?: (_envoy_config_route_v3_RedirectAction__Output | null); /** * The Metadata field can be used to provide additional information * about the route. It can be used for configuration, stats, and logging. @@ -146,15 +146,15 @@ export interface Route__Output { * For instance, if the metadata is intended for the Router filter, * the filter name should be specified as *envoy.filters.http.router*. */ - 'metadata'?: (_envoy_config_core_v3_Metadata__Output); + 'metadata': (_envoy_config_core_v3_Metadata__Output | null); /** * Decorator for the matched route. */ - 'decorator'?: (_envoy_config_route_v3_Decorator__Output); + 'decorator': (_envoy_config_route_v3_Decorator__Output | null); /** * Return an arbitrary HTTP response directly, without proxying. */ - 'direct_response'?: (_envoy_config_route_v3_DirectResponseAction__Output); + 'direct_response'?: (_envoy_config_route_v3_DirectResponseAction__Output | null); /** * Specifies a set of headers that will be added to requests matching this * route. Headers specified at this level are applied before headers from the @@ -193,7 +193,7 @@ export interface Route__Output { * :ref:`FilterConfig` * message to specify additional options.] */ - 'typed_per_filter_config'?: ({[key: string]: _google_protobuf_Any__Output}); + 'typed_per_filter_config': ({[key: string]: _google_protobuf_Any__Output}); /** * Name for the route. */ @@ -202,13 +202,13 @@ export interface Route__Output { * Presence of the object defines whether the connection manager's tracing configuration * is overridden by this route specific instance. */ - 'tracing'?: (_envoy_config_route_v3_Tracing__Output); + 'tracing': (_envoy_config_route_v3_Tracing__Output | null); /** * The maximum bytes which will be buffered for retries and shadowing. * If set, the bytes actually buffered will be the minimum value of this and the * listener per_connection_buffer_limit_bytes. */ - 'per_request_buffer_limit_bytes'?: (_google_protobuf_UInt32Value__Output); + 'per_request_buffer_limit_bytes': (_google_protobuf_UInt32Value__Output | null); /** * [#not-implemented-hide:] * If true, a filter will define the action (e.g., it could dynamically generate the @@ -216,6 +216,6 @@ export interface Route__Output { * [#comment: TODO(samflattery): Remove cleanup in route_fuzz_test.cc when * implemented] */ - 'filter_action'?: (_envoy_config_route_v3_FilterAction__Output); + 'filter_action'?: (_envoy_config_route_v3_FilterAction__Output | null); 'action': "route"|"redirect"|"direct_response"|"filter_action"; } 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 797d6eda6..234aa25e0 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 @@ -37,7 +37,7 @@ export interface _envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig /** * If present, the proxy protocol header will be prepended to the CONNECT payload sent upstream. */ - 'proxy_protocol_config'?: (_envoy_config_core_v3_ProxyProtocolConfig); + 'proxy_protocol_config'?: (_envoy_config_core_v3_ProxyProtocolConfig | null); /** * If set, the route will also allow forwarding POST payload as raw TCP. */ @@ -52,7 +52,7 @@ export interface _envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig_ /** * If present, the proxy protocol header will be prepended to the CONNECT payload sent upstream. */ - 'proxy_protocol_config'?: (_envoy_config_core_v3_ProxyProtocolConfig__Output); + 'proxy_protocol_config': (_envoy_config_core_v3_ProxyProtocolConfig__Output | null); /** * If set, the route will also allow forwarding POST payload as raw TCP. */ @@ -101,7 +101,7 @@ export interface _envoy_config_route_v3_RouteAction_HashPolicy_Cookie { * not present. If the TTL is present and zero, the generated cookie will * be a session cookie. */ - 'ttl'?: (_google_protobuf_Duration); + 'ttl'?: (_google_protobuf_Duration | null); /** * The name of the path for the cookie. If no path is specified here, no path * will be set for the cookie. @@ -137,7 +137,7 @@ export interface _envoy_config_route_v3_RouteAction_HashPolicy_Cookie__Output { * not present. If the TTL is present and zero, the generated cookie will * be a session cookie. */ - 'ttl'?: (_google_protobuf_Duration__Output); + 'ttl': (_google_protobuf_Duration__Output | null); /** * The name of the path for the cookie. If no path is specified here, no path * will be set for the cookie. @@ -172,23 +172,23 @@ export interface _envoy_config_route_v3_RouteAction_HashPolicy { /** * Header hash policy. */ - 'header'?: (_envoy_config_route_v3_RouteAction_HashPolicy_Header); + 'header'?: (_envoy_config_route_v3_RouteAction_HashPolicy_Header | null); /** * Cookie hash policy. */ - 'cookie'?: (_envoy_config_route_v3_RouteAction_HashPolicy_Cookie); + 'cookie'?: (_envoy_config_route_v3_RouteAction_HashPolicy_Cookie | null); /** * Connection properties hash policy. */ - 'connection_properties'?: (_envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties); + 'connection_properties'?: (_envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties | null); /** * Query parameter hash policy. */ - 'query_parameter'?: (_envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter); + 'query_parameter'?: (_envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter | null); /** * Filter state hash policy. */ - 'filter_state'?: (_envoy_config_route_v3_RouteAction_HashPolicy_FilterState); + 'filter_state'?: (_envoy_config_route_v3_RouteAction_HashPolicy_FilterState | null); /** * The flag that short-circuits the hash computing. This field provides a * 'fallback' style of configuration: "if a terminal policy doesn't work, @@ -223,23 +223,23 @@ export interface _envoy_config_route_v3_RouteAction_HashPolicy__Output { /** * Header hash policy. */ - 'header'?: (_envoy_config_route_v3_RouteAction_HashPolicy_Header__Output); + 'header'?: (_envoy_config_route_v3_RouteAction_HashPolicy_Header__Output | null); /** * Cookie hash policy. */ - 'cookie'?: (_envoy_config_route_v3_RouteAction_HashPolicy_Cookie__Output); + 'cookie'?: (_envoy_config_route_v3_RouteAction_HashPolicy_Cookie__Output | null); /** * Connection properties hash policy. */ - 'connection_properties'?: (_envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties__Output); + 'connection_properties'?: (_envoy_config_route_v3_RouteAction_HashPolicy_ConnectionProperties__Output | null); /** * Query parameter hash policy. */ - 'query_parameter'?: (_envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter__Output); + 'query_parameter'?: (_envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter__Output | null); /** * Filter state hash policy. */ - 'filter_state'?: (_envoy_config_route_v3_RouteAction_HashPolicy_FilterState__Output); + 'filter_state'?: (_envoy_config_route_v3_RouteAction_HashPolicy_FilterState__Output | null); /** * The flag that short-circuits the hash computing. This field provides a * 'fallback' style of configuration: "if a terminal policy doesn't work, @@ -275,7 +275,7 @@ export interface _envoy_config_route_v3_RouteAction_HashPolicy_Header { * If specified, the request header value will be rewritten and used * to produce the hash key. */ - 'regex_rewrite'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute); + 'regex_rewrite'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute | null); } export interface _envoy_config_route_v3_RouteAction_HashPolicy_Header__Output { @@ -288,7 +288,7 @@ export interface _envoy_config_route_v3_RouteAction_HashPolicy_Header__Output { * If specified, the request header value will be rewritten and used * to produce the hash key. */ - 'regex_rewrite'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute__Output); + 'regex_rewrite': (_envoy_type_matcher_v3_RegexMatchAndSubstitute__Output | null); } // Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto @@ -313,14 +313,14 @@ export interface _envoy_config_route_v3_RouteAction_MaxStreamDuration { * HttpConnectionManager max_stream_duration timeout will be disabled for * this route. */ - 'max_stream_duration'?: (_google_protobuf_Duration); + 'max_stream_duration'?: (_google_protobuf_Duration | null); /** * If present, and the request contains a `grpc-timeout header * `_, use that value as the * *max_stream_duration*, but limit the applied timeout to the maximum value specified here. * If set to 0, the `grpc-timeout` header is used without modification. */ - 'grpc_timeout_header_max'?: (_google_protobuf_Duration); + 'grpc_timeout_header_max'?: (_google_protobuf_Duration | null); /** * If present, Envoy will adjust the timeout provided by the `grpc-timeout` header by * subtracting the provided duration from the header. This is useful for allowing Envoy to set @@ -329,7 +329,7 @@ export interface _envoy_config_route_v3_RouteAction_MaxStreamDuration { * by the client. If, after applying the offset, the resulting timeout is zero or negative, * the stream will timeout immediately. */ - 'grpc_timeout_header_offset'?: (_google_protobuf_Duration); + 'grpc_timeout_header_offset'?: (_google_protobuf_Duration | null); } export interface _envoy_config_route_v3_RouteAction_MaxStreamDuration__Output { @@ -343,14 +343,14 @@ export interface _envoy_config_route_v3_RouteAction_MaxStreamDuration__Output { * HttpConnectionManager max_stream_duration timeout will be disabled for * this route. */ - 'max_stream_duration'?: (_google_protobuf_Duration__Output); + 'max_stream_duration': (_google_protobuf_Duration__Output | null); /** * If present, and the request contains a `grpc-timeout header * `_, use that value as the * *max_stream_duration*, but limit the applied timeout to the maximum value specified here. * If set to 0, the `grpc-timeout` header is used without modification. */ - 'grpc_timeout_header_max'?: (_google_protobuf_Duration__Output); + 'grpc_timeout_header_max': (_google_protobuf_Duration__Output | null); /** * If present, Envoy will adjust the timeout provided by the `grpc-timeout` header by * subtracting the provided duration from the header. This is useful for allowing Envoy to set @@ -359,7 +359,7 @@ export interface _envoy_config_route_v3_RouteAction_MaxStreamDuration__Output { * by the client. If, after applying the offset, the resulting timeout is zero or negative, * the stream will timeout immediately. */ - 'grpc_timeout_header_offset'?: (_google_protobuf_Duration__Output); + 'grpc_timeout_header_offset': (_google_protobuf_Duration__Output | null); } export interface _envoy_config_route_v3_RouteAction_HashPolicy_QueryParameter { @@ -409,11 +409,11 @@ export interface _envoy_config_route_v3_RouteAction_RequestMirrorPolicy { * number is <= the value of the numerator N, or if the key is not present, the default * value, the request will be mirrored. */ - 'runtime_fraction'?: (_envoy_config_core_v3_RuntimeFractionalPercent); + 'runtime_fraction'?: (_envoy_config_core_v3_RuntimeFractionalPercent | null); /** * Determines if the trace span should be sampled. Defaults to true. */ - 'trace_sampled'?: (_google_protobuf_BoolValue); + 'trace_sampled'?: (_google_protobuf_BoolValue | null); } /** @@ -445,11 +445,11 @@ export interface _envoy_config_route_v3_RouteAction_RequestMirrorPolicy__Output * number is <= the value of the numerator N, or if the key is not present, the default * value, the request will be mirrored. */ - 'runtime_fraction'?: (_envoy_config_core_v3_RuntimeFractionalPercent__Output); + 'runtime_fraction': (_envoy_config_core_v3_RuntimeFractionalPercent__Output | null); /** * Determines if the trace span should be sampled. Defaults to true. */ - 'trace_sampled'?: (_google_protobuf_BoolValue__Output); + 'trace_sampled': (_google_protobuf_BoolValue__Output | null); } /** @@ -470,14 +470,14 @@ export interface _envoy_config_route_v3_RouteAction_UpgradeConfig { /** * Determines if upgrades are available on this route. Defaults to true. */ - 'enabled'?: (_google_protobuf_BoolValue); + 'enabled'?: (_google_protobuf_BoolValue | null); /** * Configuration for sending data upstream as a raw data payload. This is used for * CONNECT requests, when forwarding CONNECT payload as raw TCP. * Note that CONNECT support is currently considered alpha in Envoy. * [#comment:TODO(htuch): Replace the above comment with an alpha tag. */ - 'connect_config'?: (_envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig); + 'connect_config'?: (_envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig | null); } /** @@ -498,14 +498,14 @@ export interface _envoy_config_route_v3_RouteAction_UpgradeConfig__Output { /** * Determines if upgrades are available on this route. Defaults to true. */ - 'enabled'?: (_google_protobuf_BoolValue__Output); + 'enabled': (_google_protobuf_BoolValue__Output | null); /** * Configuration for sending data upstream as a raw data payload. This is used for * CONNECT requests, when forwarding CONNECT payload as raw TCP. * Note that CONNECT support is currently considered alpha in Envoy. * [#comment:TODO(htuch): Replace the above comment with an alpha tag. */ - 'connect_config'?: (_envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig__Output); + 'connect_config': (_envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig__Output | null); } /** @@ -540,7 +540,7 @@ export interface RouteAction { * :ref:`traffic splitting ` * for additional documentation. */ - 'weighted_clusters'?: (_envoy_config_route_v3_WeightedCluster); + 'weighted_clusters'?: (_envoy_config_route_v3_WeightedCluster | null); /** * Optional endpoint metadata match criteria used by the subset load balancer. Only endpoints * in the upstream cluster with metadata matching what's set in this field will be considered @@ -548,7 +548,7 @@ export interface RouteAction { * `, metadata will be merged, with values * provided there taking precedence. The filter name should be specified as *envoy.lb*. */ - 'metadata_match'?: (_envoy_config_core_v3_Metadata); + 'metadata_match'?: (_envoy_config_core_v3_Metadata | null); /** * Indicates that during forwarding, the matched prefix (or path) should be * swapped with this value. This option allows application URLs to be rooted @@ -595,7 +595,7 @@ export interface RouteAction { * type *strict_dns* or *logical_dns*. Setting this to true with other cluster * types has no effect. */ - 'auto_host_rewrite'?: (_google_protobuf_BoolValue); + 'auto_host_rewrite'?: (_google_protobuf_BoolValue | null); /** * Specifies the upstream timeout for the route. If not specified, the default is 15s. This * spans between the point at which the entire downstream request (i.e. end-of-stream) has been @@ -609,13 +609,13 @@ export interface RouteAction { * :ref:`config_http_filters_router_x-envoy-upstream-rq-per-try-timeout-ms`, and the * :ref:`retry overview `. */ - 'timeout'?: (_google_protobuf_Duration); + 'timeout'?: (_google_protobuf_Duration | null); /** * Indicates that the route has a retry policy. Note that if this is set, * it'll take precedence over the virtual host level retry policy entirely * (e.g.: policies are not merged, most internal one becomes the enforced policy). */ - 'retry_policy'?: (_envoy_config_route_v3_RetryPolicy); + 'retry_policy'?: (_envoy_config_route_v3_RetryPolicy | null); /** * Optionally specifies the :ref:`routing priority `. */ @@ -633,7 +633,7 @@ export interface RouteAction { * * This field is deprecated. Please use :ref:`vh_rate_limits ` */ - 'include_vh_rate_limits'?: (_google_protobuf_BoolValue); + 'include_vh_rate_limits'?: (_google_protobuf_BoolValue | null); /** * Specifies a list of hash policies to use for ring hash load balancing. Each * hash policy is evaluated individually and the combined result is used to @@ -652,7 +652,7 @@ export interface RouteAction { /** * Indicates that the route has a CORS policy. */ - 'cors'?: (_envoy_config_route_v3_CorsPolicy); + '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. @@ -680,7 +680,7 @@ export interface RouteAction { * :ref:`config_http_filters_router_x-envoy-upstream-rq-per-try-timeout-ms`, and the * :ref:`retry overview `. */ - 'max_grpc_timeout'?: (_google_protobuf_Duration); + 'max_grpc_timeout'?: (_google_protobuf_Duration | null); /** * Specifies the idle timeout for the route. If not specified, there is no per-route idle timeout, * although the connection manager wide :ref:`stream_idle_timeout @@ -705,7 +705,7 @@ export interface RouteAction { * is configured, this timeout is scaled according to the value for * :ref:`HTTP_DOWNSTREAM_STREAM_IDLE `. */ - 'idle_timeout'?: (_google_protobuf_Duration); + '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); /** @@ -713,7 +713,7 @@ export interface RouteAction { * it'll take precedence over the virtual host level hedge policy entirely * (e.g.: policies are not merged, most internal one becomes the enforced policy). */ - 'hedge_policy'?: (_envoy_config_route_v3_HedgePolicy); + 'hedge_policy'?: (_envoy_config_route_v3_HedgePolicy | null); /** * Deprecated by :ref:`grpc_timeout_header_offset `. * If present, Envoy will adjust the timeout provided by the `grpc-timeout` header by subtracting @@ -724,7 +724,7 @@ export interface RouteAction { * ensures that the offset will only ever decrease the timeout and never set it to 0 (meaning * infinity). */ - 'grpc_timeout_offset'?: (_google_protobuf_Duration); + 'grpc_timeout_offset'?: (_google_protobuf_Duration | null); /** * Indicates that during forwarding, the host header will be swapped with the content of given * downstream or :ref:`custom ` header. @@ -760,7 +760,7 @@ export interface RouteAction { * * If not specified, at most one redirect will be followed. */ - 'max_internal_redirects'?: (_google_protobuf_UInt32Value); + 'max_internal_redirects'?: (_google_protobuf_UInt32Value | null); /** * Indicates that during forwarding, portions of the path that match the * pattern should be rewritten, even allowing the substitution of capture @@ -791,7 +791,7 @@ export interface RouteAction { * would do a case-insensitive match and transform path ``/aaa/XxX/bbb`` to * ``/aaa/yyy/bbb``. */ - 'regex_rewrite'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute); + 'regex_rewrite'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute | null); /** * [#not-implemented-hide:] * Specifies the configuration for retry policy extension. Note that if this is set, it'll take @@ -799,14 +799,14 @@ export interface RouteAction { * most internal one becomes the enforced policy). :ref:`Retry policy ` * should not be set if this field is used. */ - 'retry_policy_typed_config'?: (_google_protobuf_Any); + 'retry_policy_typed_config'?: (_google_protobuf_Any | null); /** * If present, Envoy will try to follow an upstream redirect response instead of proxying the * response back to the downstream. An upstream redirect response is defined * by :ref:`redirect_response_codes * `. */ - 'internal_redirect_policy'?: (_envoy_config_route_v3_InternalRedirectPolicy); + 'internal_redirect_policy'?: (_envoy_config_route_v3_InternalRedirectPolicy | null); /** * Indicates that during forwarding, the host header will be swapped with * the result of the regex substitution executed on path value with query and fragment removed. @@ -824,11 +824,11 @@ export interface RouteAction { * * Would rewrite the host header to `envoyproxy.io` given the path `/envoyproxy.io/some/path`. */ - 'host_rewrite_path_regex'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute); + 'host_rewrite_path_regex'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute | null); /** * Specifies the maximum stream duration for this route. */ - 'max_stream_duration'?: (_envoy_config_route_v3_RouteAction_MaxStreamDuration); + 'max_stream_duration'?: (_envoy_config_route_v3_RouteAction_MaxStreamDuration | null); 'cluster_specifier'?: "cluster"|"cluster_header"|"weighted_clusters"; 'host_rewrite_specifier'?: "host_rewrite_literal"|"auto_host_rewrite"|"host_rewrite_header"|"host_rewrite_path_regex"; } @@ -865,7 +865,7 @@ export interface RouteAction__Output { * :ref:`traffic splitting ` * for additional documentation. */ - 'weighted_clusters'?: (_envoy_config_route_v3_WeightedCluster__Output); + 'weighted_clusters'?: (_envoy_config_route_v3_WeightedCluster__Output | null); /** * Optional endpoint metadata match criteria used by the subset load balancer. Only endpoints * in the upstream cluster with metadata matching what's set in this field will be considered @@ -873,7 +873,7 @@ export interface RouteAction__Output { * `, metadata will be merged, with values * provided there taking precedence. The filter name should be specified as *envoy.lb*. */ - 'metadata_match'?: (_envoy_config_core_v3_Metadata__Output); + 'metadata_match': (_envoy_config_core_v3_Metadata__Output | null); /** * Indicates that during forwarding, the matched prefix (or path) should be * swapped with this value. This option allows application URLs to be rooted @@ -920,7 +920,7 @@ export interface RouteAction__Output { * type *strict_dns* or *logical_dns*. Setting this to true with other cluster * types has no effect. */ - 'auto_host_rewrite'?: (_google_protobuf_BoolValue__Output); + 'auto_host_rewrite'?: (_google_protobuf_BoolValue__Output | null); /** * Specifies the upstream timeout for the route. If not specified, the default is 15s. This * spans between the point at which the entire downstream request (i.e. end-of-stream) has been @@ -934,13 +934,13 @@ export interface RouteAction__Output { * :ref:`config_http_filters_router_x-envoy-upstream-rq-per-try-timeout-ms`, and the * :ref:`retry overview `. */ - 'timeout'?: (_google_protobuf_Duration__Output); + 'timeout': (_google_protobuf_Duration__Output | null); /** * Indicates that the route has a retry policy. Note that if this is set, * it'll take precedence over the virtual host level retry policy entirely * (e.g.: policies are not merged, most internal one becomes the enforced policy). */ - 'retry_policy'?: (_envoy_config_route_v3_RetryPolicy__Output); + 'retry_policy': (_envoy_config_route_v3_RetryPolicy__Output | null); /** * Optionally specifies the :ref:`routing priority `. */ @@ -958,7 +958,7 @@ export interface RouteAction__Output { * * This field is deprecated. Please use :ref:`vh_rate_limits ` */ - 'include_vh_rate_limits'?: (_google_protobuf_BoolValue__Output); + 'include_vh_rate_limits': (_google_protobuf_BoolValue__Output | null); /** * Specifies a list of hash policies to use for ring hash load balancing. Each * hash policy is evaluated individually and the combined result is used to @@ -977,7 +977,7 @@ export interface RouteAction__Output { /** * Indicates that the route has a CORS policy. */ - 'cors'?: (_envoy_config_route_v3_CorsPolicy__Output); + '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. @@ -1005,7 +1005,7 @@ export interface RouteAction__Output { * :ref:`config_http_filters_router_x-envoy-upstream-rq-per-try-timeout-ms`, and the * :ref:`retry overview `. */ - 'max_grpc_timeout'?: (_google_protobuf_Duration__Output); + 'max_grpc_timeout': (_google_protobuf_Duration__Output | null); /** * Specifies the idle timeout for the route. If not specified, there is no per-route idle timeout, * although the connection manager wide :ref:`stream_idle_timeout @@ -1030,7 +1030,7 @@ export interface RouteAction__Output { * is configured, this timeout is scaled according to the value for * :ref:`HTTP_DOWNSTREAM_STREAM_IDLE `. */ - 'idle_timeout'?: (_google_protobuf_Duration__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); /** @@ -1038,7 +1038,7 @@ export interface RouteAction__Output { * it'll take precedence over the virtual host level hedge policy entirely * (e.g.: policies are not merged, most internal one becomes the enforced policy). */ - 'hedge_policy'?: (_envoy_config_route_v3_HedgePolicy__Output); + 'hedge_policy': (_envoy_config_route_v3_HedgePolicy__Output | null); /** * Deprecated by :ref:`grpc_timeout_header_offset `. * If present, Envoy will adjust the timeout provided by the `grpc-timeout` header by subtracting @@ -1049,7 +1049,7 @@ export interface RouteAction__Output { * ensures that the offset will only ever decrease the timeout and never set it to 0 (meaning * infinity). */ - 'grpc_timeout_offset'?: (_google_protobuf_Duration__Output); + 'grpc_timeout_offset': (_google_protobuf_Duration__Output | null); /** * Indicates that during forwarding, the host header will be swapped with the content of given * downstream or :ref:`custom ` header. @@ -1085,7 +1085,7 @@ export interface RouteAction__Output { * * If not specified, at most one redirect will be followed. */ - 'max_internal_redirects'?: (_google_protobuf_UInt32Value__Output); + 'max_internal_redirects': (_google_protobuf_UInt32Value__Output | null); /** * Indicates that during forwarding, portions of the path that match the * pattern should be rewritten, even allowing the substitution of capture @@ -1116,7 +1116,7 @@ export interface RouteAction__Output { * would do a case-insensitive match and transform path ``/aaa/XxX/bbb`` to * ``/aaa/yyy/bbb``. */ - 'regex_rewrite'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute__Output); + 'regex_rewrite': (_envoy_type_matcher_v3_RegexMatchAndSubstitute__Output | null); /** * [#not-implemented-hide:] * Specifies the configuration for retry policy extension. Note that if this is set, it'll take @@ -1124,14 +1124,14 @@ export interface RouteAction__Output { * most internal one becomes the enforced policy). :ref:`Retry policy ` * should not be set if this field is used. */ - 'retry_policy_typed_config'?: (_google_protobuf_Any__Output); + 'retry_policy_typed_config': (_google_protobuf_Any__Output | null); /** * If present, Envoy will try to follow an upstream redirect response instead of proxying the * response back to the downstream. An upstream redirect response is defined * by :ref:`redirect_response_codes * `. */ - 'internal_redirect_policy'?: (_envoy_config_route_v3_InternalRedirectPolicy__Output); + 'internal_redirect_policy': (_envoy_config_route_v3_InternalRedirectPolicy__Output | null); /** * Indicates that during forwarding, the host header will be swapped with * the result of the regex substitution executed on path value with query and fragment removed. @@ -1149,11 +1149,11 @@ export interface RouteAction__Output { * * Would rewrite the host header to `envoyproxy.io` given the path `/envoyproxy.io/some/path`. */ - 'host_rewrite_path_regex'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute__Output); + 'host_rewrite_path_regex'?: (_envoy_type_matcher_v3_RegexMatchAndSubstitute__Output | null); /** * Specifies the maximum stream duration for this route. */ - 'max_stream_duration'?: (_envoy_config_route_v3_RouteAction_MaxStreamDuration__Output); + 'max_stream_duration': (_envoy_config_route_v3_RouteAction_MaxStreamDuration__Output | null); 'cluster_specifier': "cluster"|"cluster_header"|"weighted_clusters"; 'host_rewrite_specifier': "host_rewrite_literal"|"auto_host_rewrite"|"host_rewrite_header"|"host_rewrite_path_regex"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteConfiguration.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteConfiguration.ts index e9ad30257..ebb3c3419 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteConfiguration.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteConfiguration.ts @@ -66,7 +66,7 @@ export interface RouteConfiguration { * option. Users may wish to override the default behavior in certain cases (for example when * using CDS with a static route table). */ - 'validate_clusters'?: (_google_protobuf_BoolValue); + 'validate_clusters'?: (_google_protobuf_BoolValue | null); /** * Specifies a list of HTTP headers that should be removed from each request * routed by the HTTP connection manager. @@ -80,7 +80,7 @@ export interface RouteConfiguration { * generate a routing table for a given RouteConfiguration, with *vhds* derived configuration * taking precedence. */ - 'vhds'?: (_envoy_config_route_v3_Vhds); + 'vhds'?: (_envoy_config_route_v3_Vhds | null); /** * By default, headers that should be added/removed are evaluated from most to least specific: * @@ -106,7 +106,7 @@ export interface RouteConfiguration { * this to be larger than the default 4KB, since the allocated memory for direct response body * is not subject to data plane buffering controls. */ - 'max_direct_response_body_size_bytes'?: (_google_protobuf_UInt32Value); + 'max_direct_response_body_size_bytes'?: (_google_protobuf_UInt32Value | null); } /** @@ -169,7 +169,7 @@ export interface RouteConfiguration__Output { * option. Users may wish to override the default behavior in certain cases (for example when * using CDS with a static route table). */ - 'validate_clusters'?: (_google_protobuf_BoolValue__Output); + 'validate_clusters': (_google_protobuf_BoolValue__Output | null); /** * Specifies a list of HTTP headers that should be removed from each request * routed by the HTTP connection manager. @@ -183,7 +183,7 @@ export interface RouteConfiguration__Output { * generate a routing table for a given RouteConfiguration, with *vhds* derived configuration * taking precedence. */ - 'vhds'?: (_envoy_config_route_v3_Vhds__Output); + 'vhds': (_envoy_config_route_v3_Vhds__Output | null); /** * By default, headers that should be added/removed are evaluated from most to least specific: * @@ -209,5 +209,5 @@ export interface RouteConfiguration__Output { * this to be larger than the default 4KB, since the allocated memory for direct response body * is not subject to data plane buffering controls. */ - 'max_direct_response_body_size_bytes'?: (_google_protobuf_UInt32Value__Output); + 'max_direct_response_body_size_bytes': (_google_protobuf_UInt32Value__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteMatch.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteMatch.ts index d941bcfd1..ddf44da2f 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteMatch.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteMatch.ts @@ -29,12 +29,12 @@ export interface _envoy_config_route_v3_RouteMatch_TlsContextMatchOptions { * If specified, the route will match against whether or not a certificate is presented. * If not specified, certificate presentation status (true or false) will not be considered when route matching. */ - 'presented'?: (_google_protobuf_BoolValue); + 'presented'?: (_google_protobuf_BoolValue | null); /** * If specified, the route will match against whether or not a certificate is validated. * If not specified, certificate validation status (true or false) will not be considered when route matching. */ - 'validated'?: (_google_protobuf_BoolValue); + 'validated'?: (_google_protobuf_BoolValue | null); } export interface _envoy_config_route_v3_RouteMatch_TlsContextMatchOptions__Output { @@ -42,12 +42,12 @@ export interface _envoy_config_route_v3_RouteMatch_TlsContextMatchOptions__Outpu * If specified, the route will match against whether or not a certificate is presented. * If not specified, certificate presentation status (true or false) will not be considered when route matching. */ - 'presented'?: (_google_protobuf_BoolValue__Output); + 'presented': (_google_protobuf_BoolValue__Output | null); /** * If specified, the route will match against whether or not a certificate is validated. * If not specified, certificate validation status (true or false) will not be considered when route matching. */ - 'validated'?: (_google_protobuf_BoolValue__Output); + 'validated': (_google_protobuf_BoolValue__Output | null); } /** @@ -68,7 +68,7 @@ export interface RouteMatch { * Indicates that prefix/path matching should be case sensitive. The default * is true. */ - 'case_sensitive'?: (_google_protobuf_BoolValue); + 'case_sensitive'?: (_google_protobuf_BoolValue | null); /** * Specifies a set of headers that the route should match on. The router will * check the request’s headers against all the specified headers in the route @@ -90,7 +90,7 @@ export interface RouteMatch { * that the content-type header has a application/grpc or one of the various * application/grpc+ values. */ - 'grpc'?: (_envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions); + 'grpc'?: (_envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions | null); /** * Indicates that the route should additionally match on a runtime key. Every time the route * is considered for a match, it must also fall under the percentage of matches indicated by @@ -109,7 +109,7 @@ export interface RouteMatch { * instance, a runtime key lookup returning the value "42" would parse as a FractionalPercent * whose numerator is 42 and denominator is HUNDRED. This preserves legacy semantics. */ - 'runtime_fraction'?: (_envoy_config_core_v3_RuntimeFractionalPercent); + 'runtime_fraction'?: (_envoy_config_core_v3_RuntimeFractionalPercent | null); /** * If specified, the route is a regular expression rule meaning that the * regex must match the *:path* header once the query string is removed. The entire path @@ -124,14 +124,14 @@ export interface RouteMatch { * on :path, etc. The issue with that is it is unclear how to generically deal with query string * stripping. This needs more thought.] */ - 'safe_regex'?: (_envoy_type_matcher_v3_RegexMatcher); + 'safe_regex'?: (_envoy_type_matcher_v3_RegexMatcher | null); /** * If specified, the client tls context will be matched against the defined * match options. * * [#next-major-version: unify with RBAC] */ - 'tls_context'?: (_envoy_config_route_v3_RouteMatch_TlsContextMatchOptions); + 'tls_context'?: (_envoy_config_route_v3_RouteMatch_TlsContextMatchOptions | null); /** * If this is used as the matcher, the matcher will only match CONNECT requests. * Note that this will not match HTTP/2 upgrade-style CONNECT requests @@ -143,7 +143,7 @@ export interface RouteMatch { * Note that CONNECT support is currently considered alpha in Envoy. * [#comment:TODO(htuch): Replace the above comment with an alpha tag. */ - 'connect_matcher'?: (_envoy_config_route_v3_RouteMatch_ConnectMatcher); + 'connect_matcher'?: (_envoy_config_route_v3_RouteMatch_ConnectMatcher | null); 'path_specifier'?: "prefix"|"path"|"safe_regex"|"connect_matcher"; } @@ -165,7 +165,7 @@ export interface RouteMatch__Output { * Indicates that prefix/path matching should be case sensitive. The default * is true. */ - 'case_sensitive'?: (_google_protobuf_BoolValue__Output); + 'case_sensitive': (_google_protobuf_BoolValue__Output | null); /** * Specifies a set of headers that the route should match on. The router will * check the request’s headers against all the specified headers in the route @@ -187,7 +187,7 @@ export interface RouteMatch__Output { * that the content-type header has a application/grpc or one of the various * application/grpc+ values. */ - 'grpc'?: (_envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions__Output); + 'grpc': (_envoy_config_route_v3_RouteMatch_GrpcRouteMatchOptions__Output | null); /** * Indicates that the route should additionally match on a runtime key. Every time the route * is considered for a match, it must also fall under the percentage of matches indicated by @@ -206,7 +206,7 @@ export interface RouteMatch__Output { * instance, a runtime key lookup returning the value "42" would parse as a FractionalPercent * whose numerator is 42 and denominator is HUNDRED. This preserves legacy semantics. */ - 'runtime_fraction'?: (_envoy_config_core_v3_RuntimeFractionalPercent__Output); + 'runtime_fraction': (_envoy_config_core_v3_RuntimeFractionalPercent__Output | null); /** * If specified, the route is a regular expression rule meaning that the * regex must match the *:path* header once the query string is removed. The entire path @@ -221,14 +221,14 @@ export interface RouteMatch__Output { * on :path, etc. The issue with that is it is unclear how to generically deal with query string * stripping. This needs more thought.] */ - 'safe_regex'?: (_envoy_type_matcher_v3_RegexMatcher__Output); + 'safe_regex'?: (_envoy_type_matcher_v3_RegexMatcher__Output | null); /** * If specified, the client tls context will be matched against the defined * match options. * * [#next-major-version: unify with RBAC] */ - 'tls_context'?: (_envoy_config_route_v3_RouteMatch_TlsContextMatchOptions__Output); + 'tls_context': (_envoy_config_route_v3_RouteMatch_TlsContextMatchOptions__Output | null); /** * If this is used as the matcher, the matcher will only match CONNECT requests. * Note that this will not match HTTP/2 upgrade-style CONNECT requests @@ -240,6 +240,6 @@ export interface RouteMatch__Output { * Note that CONNECT support is currently considered alpha in Envoy. * [#comment:TODO(htuch): Replace the above comment with an alpha tag. */ - 'connect_matcher'?: (_envoy_config_route_v3_RouteMatch_ConnectMatcher__Output); + 'connect_matcher'?: (_envoy_config_route_v3_RouteMatch_ConnectMatcher__Output | null); 'path_specifier': "prefix"|"path"|"safe_regex"|"connect_matcher"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/ScopedRouteConfiguration.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/ScopedRouteConfiguration.ts index afbb9886b..74b5fe43d 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/ScopedRouteConfiguration.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/ScopedRouteConfiguration.ts @@ -123,7 +123,7 @@ export interface ScopedRouteConfiguration { /** * The key to match against. */ - 'key'?: (_envoy_config_route_v3_ScopedRouteConfiguration_Key); + 'key'?: (_envoy_config_route_v3_ScopedRouteConfiguration_Key | null); /** * Whether the RouteConfiguration should be loaded on demand. */ @@ -204,7 +204,7 @@ export interface ScopedRouteConfiguration__Output { /** * The key to match against. */ - 'key'?: (_envoy_config_route_v3_ScopedRouteConfiguration_Key__Output); + 'key': (_envoy_config_route_v3_ScopedRouteConfiguration_Key__Output | null); /** * Whether the RouteConfiguration should be loaded on demand. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Tracing.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Tracing.ts index 5be619a5f..e1a9220d7 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Tracing.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Tracing.ts @@ -12,7 +12,7 @@ export interface Tracing { * `. * Default: 100% */ - 'client_sampling'?: (_envoy_type_v3_FractionalPercent); + 'client_sampling'?: (_envoy_type_v3_FractionalPercent | null); /** * Target percentage of requests managed by this HTTP connection manager that will be randomly * selected for trace generation, if not requested by the client or not forced. This field is @@ -20,7 +20,7 @@ export interface Tracing { * :ref:`HTTP Connection Manager `. * Default: 100% */ - 'random_sampling'?: (_envoy_type_v3_FractionalPercent); + 'random_sampling'?: (_envoy_type_v3_FractionalPercent | null); /** * Target percentage of requests managed by this HTTP connection manager that will be traced * after all other sampling checks have been applied (client-directed, force tracing, random @@ -31,7 +31,7 @@ export interface Tracing { * :ref:`HTTP Connection Manager `. * Default: 100% */ - 'overall_sampling'?: (_envoy_type_v3_FractionalPercent); + 'overall_sampling'?: (_envoy_type_v3_FractionalPercent | null); /** * A list of custom tags with unique tag name to create tags for the active span. * It will take effect after merging with the :ref:`corresponding configuration @@ -52,7 +52,7 @@ export interface Tracing__Output { * `. * Default: 100% */ - 'client_sampling'?: (_envoy_type_v3_FractionalPercent__Output); + 'client_sampling': (_envoy_type_v3_FractionalPercent__Output | null); /** * Target percentage of requests managed by this HTTP connection manager that will be randomly * selected for trace generation, if not requested by the client or not forced. This field is @@ -60,7 +60,7 @@ export interface Tracing__Output { * :ref:`HTTP Connection Manager `. * Default: 100% */ - 'random_sampling'?: (_envoy_type_v3_FractionalPercent__Output); + 'random_sampling': (_envoy_type_v3_FractionalPercent__Output | null); /** * Target percentage of requests managed by this HTTP connection manager that will be traced * after all other sampling checks have been applied (client-directed, force tracing, random @@ -71,7 +71,7 @@ export interface Tracing__Output { * :ref:`HTTP Connection Manager `. * Default: 100% */ - 'overall_sampling'?: (_envoy_type_v3_FractionalPercent__Output); + 'overall_sampling': (_envoy_type_v3_FractionalPercent__Output | null); /** * A list of custom tags with unique tag name to create tags for the active span. * It will take effect after merging with the :ref:`corresponding configuration diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Vhds.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Vhds.ts index 2868685b2..b8a37be65 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Vhds.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Vhds.ts @@ -6,12 +6,12 @@ export interface Vhds { /** * Configuration source specifier for VHDS. */ - 'config_source'?: (_envoy_config_core_v3_ConfigSource); + 'config_source'?: (_envoy_config_core_v3_ConfigSource | null); } export interface Vhds__Output { /** * Configuration source specifier for VHDS. */ - 'config_source'?: (_envoy_config_core_v3_ConfigSource__Output); + 'config_source': (_envoy_config_core_v3_ConfigSource__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 86088ded6..1d3fb2309 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 @@ -96,7 +96,7 @@ export interface VirtualHost { /** * Indicates that the virtual host has a CORS policy. */ - 'cors'?: (_envoy_config_route_v3_CorsPolicy); + 'cors'?: (_envoy_config_route_v3_CorsPolicy | null); /** * Specifies a list of HTTP headers that should be added to each response * handled by this virtual host. Headers specified at this level are applied @@ -145,19 +145,19 @@ export interface VirtualHost { * route level entry will take precedence over this config and it'll be treated * independently (e.g.: values are not inherited). */ - 'retry_policy'?: (_envoy_config_route_v3_RetryPolicy); + 'retry_policy'?: (_envoy_config_route_v3_RetryPolicy | null); /** * Indicates the hedge policy for all routes in this virtual host. Note that setting a * route level entry will take precedence over this config and it'll be treated * independently (e.g.: values are not inherited). */ - 'hedge_policy'?: (_envoy_config_route_v3_HedgePolicy); + 'hedge_policy'?: (_envoy_config_route_v3_HedgePolicy | null); /** * The maximum bytes which will be buffered for retries and shadowing. * If set and a route-specific limit is not set, the bytes actually buffered will be the minimum * value of this and the listener per_connection_buffer_limit_bytes. */ - 'per_request_buffer_limit_bytes'?: (_google_protobuf_UInt32Value); + 'per_request_buffer_limit_bytes'?: (_google_protobuf_UInt32Value | null); /** * Decides whether the :ref:`x-envoy-attempt-count * ` header should be included @@ -176,7 +176,7 @@ export interface VirtualHost { * inherited). :ref:`Retry policy ` should not be * set if this field is used. */ - 'retry_policy_typed_config'?: (_google_protobuf_Any); + 'retry_policy_typed_config'?: (_google_protobuf_Any | null); } /** @@ -246,7 +246,7 @@ export interface VirtualHost__Output { /** * Indicates that the virtual host has a CORS policy. */ - 'cors'?: (_envoy_config_route_v3_CorsPolicy__Output); + 'cors': (_envoy_config_route_v3_CorsPolicy__Output | null); /** * Specifies a list of HTTP headers that should be added to each response * handled by this virtual host. Headers specified at this level are applied @@ -289,25 +289,25 @@ export interface VirtualHost__Output { * :ref:`FilterConfig` * message to specify additional options.] */ - 'typed_per_filter_config'?: ({[key: string]: _google_protobuf_Any__Output}); + 'typed_per_filter_config': ({[key: string]: _google_protobuf_Any__Output}); /** * Indicates the retry policy for all routes in this virtual host. Note that setting a * route level entry will take precedence over this config and it'll be treated * independently (e.g.: values are not inherited). */ - 'retry_policy'?: (_envoy_config_route_v3_RetryPolicy__Output); + 'retry_policy': (_envoy_config_route_v3_RetryPolicy__Output | null); /** * Indicates the hedge policy for all routes in this virtual host. Note that setting a * route level entry will take precedence over this config and it'll be treated * independently (e.g.: values are not inherited). */ - 'hedge_policy'?: (_envoy_config_route_v3_HedgePolicy__Output); + 'hedge_policy': (_envoy_config_route_v3_HedgePolicy__Output | null); /** * The maximum bytes which will be buffered for retries and shadowing. * If set and a route-specific limit is not set, the bytes actually buffered will be the minimum * value of this and the listener per_connection_buffer_limit_bytes. */ - 'per_request_buffer_limit_bytes'?: (_google_protobuf_UInt32Value__Output); + 'per_request_buffer_limit_bytes': (_google_protobuf_UInt32Value__Output | null); /** * Decides whether the :ref:`x-envoy-attempt-count * ` header should be included @@ -326,5 +326,5 @@ export interface VirtualHost__Output { * inherited). :ref:`Retry policy ` should not be * set if this field is used. */ - 'retry_policy_typed_config'?: (_google_protobuf_Any__Output); + 'retry_policy_typed_config': (_google_protobuf_Any__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 7974508ea..02edc0243 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 @@ -20,7 +20,7 @@ export interface _envoy_config_route_v3_WeightedCluster_ClusterWeight { * the choice of an upstream cluster is determined by its weight. The sum of weights across all * entries in the clusters array must add up to the total_weight, which defaults to 100. */ - 'weight'?: (_google_protobuf_UInt32Value); + 'weight'?: (_google_protobuf_UInt32Value | null); /** * Optional endpoint metadata match criteria used by the subset load balancer. Only endpoints in * the upstream cluster with metadata matching what is set in this field will be considered for @@ -28,7 +28,7 @@ export interface _envoy_config_route_v3_WeightedCluster_ClusterWeight { * :ref:`RouteAction.metadata_match `, with * values here taking precedence. The filter name should be specified as *envoy.lb*. */ - 'metadata_match'?: (_envoy_config_core_v3_Metadata); + 'metadata_match'?: (_envoy_config_core_v3_Metadata | null); /** * Specifies a list of headers to be added to requests when this cluster is selected * through the enclosing :ref:`envoy_api_msg_config.route.v3.RouteAction`. @@ -87,7 +87,7 @@ export interface _envoy_config_route_v3_WeightedCluster_ClusterWeight__Output { * the choice of an upstream cluster is determined by its weight. The sum of weights across all * entries in the clusters array must add up to the total_weight, which defaults to 100. */ - 'weight'?: (_google_protobuf_UInt32Value__Output); + 'weight': (_google_protobuf_UInt32Value__Output | null); /** * Optional endpoint metadata match criteria used by the subset load balancer. Only endpoints in * the upstream cluster with metadata matching what is set in this field will be considered for @@ -95,7 +95,7 @@ export interface _envoy_config_route_v3_WeightedCluster_ClusterWeight__Output { * :ref:`RouteAction.metadata_match `, with * values here taking precedence. The filter name should be specified as *envoy.lb*. */ - 'metadata_match'?: (_envoy_config_core_v3_Metadata__Output); + 'metadata_match': (_envoy_config_core_v3_Metadata__Output | null); /** * Specifies a list of headers to be added to requests when this cluster is selected * through the enclosing :ref:`envoy_api_msg_config.route.v3.RouteAction`. @@ -136,7 +136,7 @@ export interface _envoy_config_route_v3_WeightedCluster_ClusterWeight__Output { * :ref:`FilterConfig` * message to specify additional options.] */ - 'typed_per_filter_config'?: ({[key: string]: _google_protobuf_Any__Output}); + 'typed_per_filter_config': ({[key: string]: _google_protobuf_Any__Output}); } /** @@ -167,7 +167,7 @@ export interface WeightedCluster { * Specifies the total weight across all clusters. The sum of all cluster weights must equal this * value, which must be greater than 0. Defaults to 100. */ - 'total_weight'?: (_google_protobuf_UInt32Value); + 'total_weight'?: (_google_protobuf_UInt32Value | null); } /** @@ -198,5 +198,5 @@ export interface WeightedCluster__Output { * Specifies the total weight across all clusters. The sum of all cluster weights must equal this * value, which must be greater than 0. Defaults to 100. */ - 'total_weight'?: (_google_protobuf_UInt32Value__Output); + 'total_weight': (_google_protobuf_UInt32Value__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/trace/v3/Tracing.ts b/packages/grpc-js-xds/src/generated/envoy/config/trace/v3/Tracing.ts index 36dfade51..95b161939 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/trace/v3/Tracing.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/trace/v3/Tracing.ts @@ -23,7 +23,7 @@ export interface _envoy_config_trace_v3_Tracing_Http { * - *envoy.tracers.xray* */ 'name'?: (string); - 'typed_config'?: (_google_protobuf_Any); + 'typed_config'?: (_google_protobuf_Any | null); /** * Trace driver specific configuration which depends on the driver being instantiated. * See the trace drivers for examples: @@ -59,7 +59,7 @@ export interface _envoy_config_trace_v3_Tracing_Http__Output { * - *envoy.tracers.xray* */ 'name': (string); - 'typed_config'?: (_google_protobuf_Any__Output); + 'typed_config'?: (_google_protobuf_Any__Output | null); /** * Trace driver specific configuration which depends on the driver being instantiated. * See the trace drivers for examples: @@ -89,7 +89,7 @@ export interface Tracing { /** * Provides configuration for the HTTP tracer. */ - 'http'?: (_envoy_config_trace_v3_Tracing_Http); + 'http'?: (_envoy_config_trace_v3_Tracing_Http | null); } /** @@ -107,5 +107,5 @@ export interface Tracing__Output { /** * Provides configuration for the HTTP tracer. */ - 'http'?: (_envoy_config_trace_v3_Tracing_Http__Output); + 'http': (_envoy_config_trace_v3_Tracing_Http__Output | null); } 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 b68e812ef..4a8912599 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 @@ -132,7 +132,7 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Ht /** * Whether to forward the subject of the client cert. Defaults to false. */ - 'subject'?: (_google_protobuf_BoolValue); + 'subject'?: (_google_protobuf_BoolValue | null); /** * Whether to forward the entire client cert in URL encoded PEM format. This will appear in the * XFCC header comma separated from other values with the value Cert="PEM". @@ -165,7 +165,7 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Ht /** * Whether to forward the subject of the client cert. Defaults to false. */ - 'subject'?: (_google_protobuf_BoolValue__Output); + 'subject': (_google_protobuf_BoolValue__Output | null); /** * Whether to forward the entire client cert in URL encoded PEM format. This will appear in the * XFCC header comma separated from other values with the value Cert="PEM". @@ -203,7 +203,7 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Ht * `. * Default: 100% */ - 'client_sampling'?: (_envoy_type_v3_Percent); + 'client_sampling'?: (_envoy_type_v3_Percent | null); /** * Target percentage of requests managed by this HTTP connection manager that will be randomly * selected for trace generation, if not requested by the client or not forced. This field is @@ -211,7 +211,7 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Ht * :ref:`HTTP Connection Manager `. * Default: 100% */ - 'random_sampling'?: (_envoy_type_v3_Percent); + 'random_sampling'?: (_envoy_type_v3_Percent | null); /** * Target percentage of requests managed by this HTTP connection manager that will be traced * after all other sampling checks have been applied (client-directed, force tracing, random @@ -222,7 +222,7 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Ht * :ref:`HTTP Connection Manager `. * Default: 100% */ - 'overall_sampling'?: (_envoy_type_v3_Percent); + 'overall_sampling'?: (_envoy_type_v3_Percent | null); /** * Whether to annotate spans with additional data. If true, spans will include logs for stream * events. @@ -233,7 +233,7 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Ht * truncate lengthy request paths to meet the needs of a tracing backend. * Default: 256 */ - 'max_path_tag_length'?: (_google_protobuf_UInt32Value); + 'max_path_tag_length'?: (_google_protobuf_UInt32Value | null); /** * A list of custom tags with unique tag name to create tags for the active span. */ @@ -250,7 +250,7 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Ht * Such a constraint is inherent to OpenCensus itself. It cannot be overcome without changes * on OpenCensus side. */ - 'provider'?: (_envoy_config_trace_v3_Tracing_Http); + 'provider'?: (_envoy_config_trace_v3_Tracing_Http | null); } /** @@ -265,7 +265,7 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Ht * `. * Default: 100% */ - 'client_sampling'?: (_envoy_type_v3_Percent__Output); + 'client_sampling': (_envoy_type_v3_Percent__Output | null); /** * Target percentage of requests managed by this HTTP connection manager that will be randomly * selected for trace generation, if not requested by the client or not forced. This field is @@ -273,7 +273,7 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Ht * :ref:`HTTP Connection Manager `. * Default: 100% */ - 'random_sampling'?: (_envoy_type_v3_Percent__Output); + 'random_sampling': (_envoy_type_v3_Percent__Output | null); /** * Target percentage of requests managed by this HTTP connection manager that will be traced * after all other sampling checks have been applied (client-directed, force tracing, random @@ -284,7 +284,7 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Ht * :ref:`HTTP Connection Manager `. * Default: 100% */ - 'overall_sampling'?: (_envoy_type_v3_Percent__Output); + 'overall_sampling': (_envoy_type_v3_Percent__Output | null); /** * Whether to annotate spans with additional data. If true, spans will include logs for stream * events. @@ -295,7 +295,7 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Ht * truncate lengthy request paths to meet the needs of a tracing backend. * Default: 256 */ - 'max_path_tag_length'?: (_google_protobuf_UInt32Value__Output); + 'max_path_tag_length': (_google_protobuf_UInt32Value__Output | null); /** * A list of custom tags with unique tag name to create tags for the active span. */ @@ -312,7 +312,7 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Ht * Such a constraint is inherent to OpenCensus itself. It cannot be overcome without changes * on OpenCensus side. */ - 'provider'?: (_envoy_config_trace_v3_Tracing_Http__Output); + 'provider': (_envoy_config_trace_v3_Tracing_Http__Output | null); } /** @@ -349,7 +349,7 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Ht * ` as documented in the * :ref:`upgrade documentation `. */ - 'enabled'?: (_google_protobuf_BoolValue); + 'enabled'?: (_google_protobuf_BoolValue | null); } /** @@ -386,7 +386,7 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Ht * ` as documented in the * :ref:`upgrade documentation `. */ - 'enabled'?: (_google_protobuf_BoolValue__Output); + 'enabled': (_google_protobuf_BoolValue__Output | null); } /** @@ -406,11 +406,11 @@ export interface HttpConnectionManager { /** * The connection manager’s route table will be dynamically loaded via the RDS API. */ - 'rds'?: (_envoy_extensions_filters_network_http_connection_manager_v3_Rds); + 'rds'?: (_envoy_extensions_filters_network_http_connection_manager_v3_Rds | null); /** * The route table for the connection manager is static and is specified in this property. */ - 'route_config'?: (_envoy_config_route_v3_RouteConfiguration); + 'route_config'?: (_envoy_config_route_v3_RouteConfiguration | null); /** * A list of individual HTTP filters that make up the filter chain for * requests made to the connection manager. :ref:`Order matters ` @@ -422,21 +422,21 @@ export interface HttpConnectionManager { * and :ref:`config_http_conn_man_headers_downstream-service-cluster` headers. See the linked * documentation for more information. Defaults to false. */ - 'add_user_agent'?: (_google_protobuf_BoolValue); + 'add_user_agent'?: (_google_protobuf_BoolValue | null); /** * Presence of the object defines whether the connection manager * emits :ref:`tracing ` data to the :ref:`configured tracing provider * `. */ - 'tracing'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing); + 'tracing'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing | null); /** * Additional HTTP/1 settings that are passed to the HTTP/1 codec. */ - 'http_protocol_options'?: (_envoy_config_core_v3_Http1ProtocolOptions); + 'http_protocol_options'?: (_envoy_config_core_v3_Http1ProtocolOptions | null); /** * Additional HTTP/2 settings that are passed directly to the HTTP/2 codec. */ - 'http2_protocol_options'?: (_envoy_config_core_v3_Http2ProtocolOptions); + 'http2_protocol_options'?: (_envoy_config_core_v3_Http2ProtocolOptions | null); /** * An optional override that the connection manager will write to the server * header in responses. If not set, the default is *envoy*. @@ -453,7 +453,7 @@ export interface HttpConnectionManager { * draining. The default grace period is 5000 milliseconds (5 seconds) if this * option is not specified. */ - 'drain_timeout'?: (_google_protobuf_Duration); + 'drain_timeout'?: (_google_protobuf_Duration | null); /** * Configuration for :ref:`HTTP access logs ` * emitted by the connection manager. @@ -468,14 +468,14 @@ export interface HttpConnectionManager { * :ref:`config_http_conn_man_headers_x-envoy-internal`, and * :ref:`config_http_conn_man_headers_x-envoy-external-address` for more information. */ - 'use_remote_address'?: (_google_protobuf_BoolValue); + 'use_remote_address'?: (_google_protobuf_BoolValue | null); /** * Whether the connection manager will generate the :ref:`x-request-id * ` header if it does not exist. This defaults to * true. Generating a random UUID4 is expensive so in high throughput scenarios where this feature * is not desired it can be disabled. */ - 'generate_request_id'?: (_google_protobuf_BoolValue); + 'generate_request_id'?: (_google_protobuf_BoolValue | null); /** * How to handle the :ref:`config_http_conn_man_headers_x-forwarded-client-cert` (XFCC) HTTP * header. @@ -490,7 +490,7 @@ export interface HttpConnectionManager { * *By* is always set when the client certificate presents the URI type Subject Alternative Name * value. */ - 'set_current_client_cert_details'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails); + 'set_current_client_cert_details'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails | null); /** * If proxy_100_continue is true, Envoy will proxy incoming "Expect: * 100-continue" headers upstream, and forward "100 Continue" responses @@ -580,14 +580,14 @@ export interface HttpConnectionManager { * A value of 0 will completely disable the connection manager stream idle * timeout, although per-route idle timeout overrides will continue to apply. */ - 'stream_idle_timeout'?: (_google_protobuf_Duration); + 'stream_idle_timeout'?: (_google_protobuf_Duration | null); /** * Configures what network addresses are considered internal for stats and header sanitation * purposes. If unspecified, only RFC1918 IP addresses will be considered internal. * See the documentation for :ref:`config_http_conn_man_headers_x-envoy-internal` for more * information about internal/external addresses. */ - 'internal_address_config'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig); + 'internal_address_config'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig | null); /** * The delayed close timeout is for downstream connections managed by the HTTP connection manager. * It is defined as a grace period after connection close processing has been locally initiated @@ -620,14 +620,14 @@ export interface HttpConnectionManager { * connection's socket will be closed immediately after the write flush is completed or will * never close if the write flush does not complete. */ - 'delayed_close_timeout'?: (_google_protobuf_Duration); + 'delayed_close_timeout'?: (_google_protobuf_Duration | null); /** * The amount of time that Envoy will wait for the entire request to be received. * The timer is activated when the request is initiated, and is disarmed when the last byte of the * request is sent upstream (i.e. all decoding filters have processed the request), OR when the * response is initiated. If not specified or set to 0, this timeout is disabled. */ - 'request_timeout'?: (_google_protobuf_Duration); + 'request_timeout'?: (_google_protobuf_Duration | null); /** * The maximum request headers size for incoming connections. * If unconfigured, the default max request headers allowed is 60 KiB. @@ -635,7 +635,7 @@ export interface HttpConnectionManager { * The max configurable limit is 96 KiB, based on current implementation * constraints. */ - 'max_request_headers_kb'?: (_google_protobuf_UInt32Value); + 'max_request_headers_kb'?: (_google_protobuf_UInt32Value | null); /** * Should paths be normalized according to RFC 3986 before any processing of * requests by HTTP filters or routing? This affects the upstream *:path* header @@ -649,13 +649,13 @@ export interface HttpConnectionManager { * Note that Envoy does not perform * `case normalization `_ */ - 'normalize_path'?: (_google_protobuf_BoolValue); + 'normalize_path'?: (_google_protobuf_BoolValue | null); /** * A route table will be dynamically assigned to each request based on request attributes * (e.g., the value of a header). The "routing scopes" (i.e., route tables) and "scope keys" are * specified in this message. */ - 'scoped_routes'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes); + 'scoped_routes'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes | null); /** * Whether the connection manager will keep the :ref:`x-request-id * ` header if passed for a request that is edge @@ -681,7 +681,7 @@ export interface HttpConnectionManager { * Additional settings for HTTP requests handled by the connection manager. These will be * applicable to both HTTP1 and HTTP2 requests. */ - 'common_http_protocol_options'?: (_envoy_config_core_v3_HttpProtocolOptions); + 'common_http_protocol_options'?: (_envoy_config_core_v3_HttpProtocolOptions | null); /** * The configuration of the request ID extension. This includes operations such as * generation, validation, and associated tracing operations. @@ -694,7 +694,7 @@ export interface HttpConnectionManager { * * 3. Tracing decision (sampled, forced, etc) is set in 14th byte of the UUID. */ - 'request_id_extension'?: (_envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension); + 'request_id_extension'?: (_envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension | null); /** * If set, Envoy will always set :ref:`x-request-id ` header in response. * If this is false or not set, the request ID is returned in responses only if tracing is forced using @@ -706,7 +706,7 @@ export interface HttpConnectionManager { * body text and response content type. If not specified, status code and text body are hard * coded in Envoy, the response content type is plain text. */ - 'local_reply_config'?: (_envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig); + 'local_reply_config'?: (_envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig | null); /** * Determines if the port part should be removed from host/authority header before any processing * of request by HTTP filters or routing. The port would be removed only if it is equal to the :ref:`listener's` @@ -735,13 +735,13 @@ export interface HttpConnectionManager { * *not* the deprecated but similarly named :ref:`stream_error_on_invalid_http_messaging * ` */ - 'stream_error_on_invalid_http_message'?: (_google_protobuf_BoolValue); + 'stream_error_on_invalid_http_message'?: (_google_protobuf_BoolValue | null); /** * The amount of time that Envoy will wait for the request headers to be received. The timer is * activated when the first byte of the headers is received, and is disarmed when the last byte of * the headers has been received. If not specified or set to 0, this timeout is disabled. */ - 'request_headers_timeout'?: (_google_protobuf_Duration); + 'request_headers_timeout'?: (_google_protobuf_Duration | null); /** * Determines if the port part should be removed from host/authority header before any processing * of request by HTTP filters or routing. The port would be removed only if request method is not CONNECT. @@ -773,11 +773,11 @@ export interface HttpConnectionManager__Output { /** * The connection manager’s route table will be dynamically loaded via the RDS API. */ - 'rds'?: (_envoy_extensions_filters_network_http_connection_manager_v3_Rds__Output); + 'rds'?: (_envoy_extensions_filters_network_http_connection_manager_v3_Rds__Output | null); /** * The route table for the connection manager is static and is specified in this property. */ - 'route_config'?: (_envoy_config_route_v3_RouteConfiguration__Output); + 'route_config'?: (_envoy_config_route_v3_RouteConfiguration__Output | null); /** * A list of individual HTTP filters that make up the filter chain for * requests made to the connection manager. :ref:`Order matters ` @@ -789,21 +789,21 @@ export interface HttpConnectionManager__Output { * and :ref:`config_http_conn_man_headers_downstream-service-cluster` headers. See the linked * documentation for more information. Defaults to false. */ - 'add_user_agent'?: (_google_protobuf_BoolValue__Output); + 'add_user_agent': (_google_protobuf_BoolValue__Output | null); /** * Presence of the object defines whether the connection manager * emits :ref:`tracing ` data to the :ref:`configured tracing provider * `. */ - 'tracing'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing__Output); + 'tracing': (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing__Output | null); /** * Additional HTTP/1 settings that are passed to the HTTP/1 codec. */ - 'http_protocol_options'?: (_envoy_config_core_v3_Http1ProtocolOptions__Output); + 'http_protocol_options': (_envoy_config_core_v3_Http1ProtocolOptions__Output | null); /** * Additional HTTP/2 settings that are passed directly to the HTTP/2 codec. */ - 'http2_protocol_options'?: (_envoy_config_core_v3_Http2ProtocolOptions__Output); + 'http2_protocol_options': (_envoy_config_core_v3_Http2ProtocolOptions__Output | null); /** * An optional override that the connection manager will write to the server * header in responses. If not set, the default is *envoy*. @@ -820,7 +820,7 @@ export interface HttpConnectionManager__Output { * draining. The default grace period is 5000 milliseconds (5 seconds) if this * option is not specified. */ - 'drain_timeout'?: (_google_protobuf_Duration__Output); + 'drain_timeout': (_google_protobuf_Duration__Output | null); /** * Configuration for :ref:`HTTP access logs ` * emitted by the connection manager. @@ -835,14 +835,14 @@ export interface HttpConnectionManager__Output { * :ref:`config_http_conn_man_headers_x-envoy-internal`, and * :ref:`config_http_conn_man_headers_x-envoy-external-address` for more information. */ - 'use_remote_address'?: (_google_protobuf_BoolValue__Output); + 'use_remote_address': (_google_protobuf_BoolValue__Output | null); /** * Whether the connection manager will generate the :ref:`x-request-id * ` header if it does not exist. This defaults to * true. Generating a random UUID4 is expensive so in high throughput scenarios where this feature * is not desired it can be disabled. */ - 'generate_request_id'?: (_google_protobuf_BoolValue__Output); + 'generate_request_id': (_google_protobuf_BoolValue__Output | null); /** * How to handle the :ref:`config_http_conn_man_headers_x-forwarded-client-cert` (XFCC) HTTP * header. @@ -857,7 +857,7 @@ export interface HttpConnectionManager__Output { * *By* is always set when the client certificate presents the URI type Subject Alternative Name * value. */ - 'set_current_client_cert_details'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails__Output); + 'set_current_client_cert_details': (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_SetCurrentClientCertDetails__Output | null); /** * If proxy_100_continue is true, Envoy will proxy incoming "Expect: * 100-continue" headers upstream, and forward "100 Continue" responses @@ -947,14 +947,14 @@ export interface HttpConnectionManager__Output { * A value of 0 will completely disable the connection manager stream idle * timeout, although per-route idle timeout overrides will continue to apply. */ - 'stream_idle_timeout'?: (_google_protobuf_Duration__Output); + 'stream_idle_timeout': (_google_protobuf_Duration__Output | null); /** * Configures what network addresses are considered internal for stats and header sanitation * purposes. If unspecified, only RFC1918 IP addresses will be considered internal. * See the documentation for :ref:`config_http_conn_man_headers_x-envoy-internal` for more * information about internal/external addresses. */ - 'internal_address_config'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig__Output); + 'internal_address_config': (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_InternalAddressConfig__Output | null); /** * The delayed close timeout is for downstream connections managed by the HTTP connection manager. * It is defined as a grace period after connection close processing has been locally initiated @@ -987,14 +987,14 @@ export interface HttpConnectionManager__Output { * connection's socket will be closed immediately after the write flush is completed or will * never close if the write flush does not complete. */ - 'delayed_close_timeout'?: (_google_protobuf_Duration__Output); + 'delayed_close_timeout': (_google_protobuf_Duration__Output | null); /** * The amount of time that Envoy will wait for the entire request to be received. * The timer is activated when the request is initiated, and is disarmed when the last byte of the * request is sent upstream (i.e. all decoding filters have processed the request), OR when the * response is initiated. If not specified or set to 0, this timeout is disabled. */ - 'request_timeout'?: (_google_protobuf_Duration__Output); + 'request_timeout': (_google_protobuf_Duration__Output | null); /** * The maximum request headers size for incoming connections. * If unconfigured, the default max request headers allowed is 60 KiB. @@ -1002,7 +1002,7 @@ export interface HttpConnectionManager__Output { * The max configurable limit is 96 KiB, based on current implementation * constraints. */ - 'max_request_headers_kb'?: (_google_protobuf_UInt32Value__Output); + 'max_request_headers_kb': (_google_protobuf_UInt32Value__Output | null); /** * Should paths be normalized according to RFC 3986 before any processing of * requests by HTTP filters or routing? This affects the upstream *:path* header @@ -1016,13 +1016,13 @@ export interface HttpConnectionManager__Output { * Note that Envoy does not perform * `case normalization `_ */ - 'normalize_path'?: (_google_protobuf_BoolValue__Output); + 'normalize_path': (_google_protobuf_BoolValue__Output | null); /** * A route table will be dynamically assigned to each request based on request attributes * (e.g., the value of a header). The "routing scopes" (i.e., route tables) and "scope keys" are * specified in this message. */ - 'scoped_routes'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes__Output); + 'scoped_routes'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes__Output | null); /** * Whether the connection manager will keep the :ref:`x-request-id * ` header if passed for a request that is edge @@ -1048,7 +1048,7 @@ export interface HttpConnectionManager__Output { * Additional settings for HTTP requests handled by the connection manager. These will be * applicable to both HTTP1 and HTTP2 requests. */ - 'common_http_protocol_options'?: (_envoy_config_core_v3_HttpProtocolOptions__Output); + 'common_http_protocol_options': (_envoy_config_core_v3_HttpProtocolOptions__Output | null); /** * The configuration of the request ID extension. This includes operations such as * generation, validation, and associated tracing operations. @@ -1061,7 +1061,7 @@ export interface HttpConnectionManager__Output { * * 3. Tracing decision (sampled, forced, etc) is set in 14th byte of the UUID. */ - 'request_id_extension'?: (_envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension__Output); + 'request_id_extension': (_envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension__Output | null); /** * If set, Envoy will always set :ref:`x-request-id ` header in response. * If this is false or not set, the request ID is returned in responses only if tracing is forced using @@ -1073,7 +1073,7 @@ export interface HttpConnectionManager__Output { * body text and response content type. If not specified, status code and text body are hard * coded in Envoy, the response content type is plain text. */ - 'local_reply_config'?: (_envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig__Output); + 'local_reply_config': (_envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig__Output | null); /** * Determines if the port part should be removed from host/authority header before any processing * of request by HTTP filters or routing. The port would be removed only if it is equal to the :ref:`listener's` @@ -1102,13 +1102,13 @@ export interface HttpConnectionManager__Output { * *not* the deprecated but similarly named :ref:`stream_error_on_invalid_http_messaging * ` */ - 'stream_error_on_invalid_http_message'?: (_google_protobuf_BoolValue__Output); + 'stream_error_on_invalid_http_message': (_google_protobuf_BoolValue__Output | null); /** * The amount of time that Envoy will wait for the request headers to be received. The timer is * activated when the first byte of the headers is received, and is disarmed when the last byte of * the headers has been received. If not specified or set to 0, this timeout is disabled. */ - 'request_headers_timeout'?: (_google_protobuf_Duration__Output); + 'request_headers_timeout': (_google_protobuf_Duration__Output | null); /** * Determines if the port part should be removed from host/authority header before any processing * of request by HTTP filters or routing. The port would be removed only if request method is not CONNECT. diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpFilter.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpFilter.ts index 881e2c714..42e4215d0 100644 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpFilter.ts @@ -17,13 +17,13 @@ export interface HttpFilter { * Filter specific configuration which depends on the filter being instantiated. See the supported * filters for further documentation. */ - 'typed_config'?: (_google_protobuf_Any); + 'typed_config'?: (_google_protobuf_Any | null); /** * Configuration source specifier for an extension configuration discovery service. * In case of a failure and without the default configuration, the HTTP listener responds with code 500. * Extension configs delivered through this mechanism are not expected to require warming (see https://github.com/envoyproxy/envoy/issues/12061). */ - 'config_discovery'?: (_envoy_config_core_v3_ExtensionConfigSource); + 'config_discovery'?: (_envoy_config_core_v3_ExtensionConfigSource | null); /** * If true, clients that do not support this filter may ignore the * filter but otherwise accept the config. @@ -48,13 +48,13 @@ export interface HttpFilter__Output { * Filter specific configuration which depends on the filter being instantiated. See the supported * filters for further documentation. */ - 'typed_config'?: (_google_protobuf_Any__Output); + 'typed_config'?: (_google_protobuf_Any__Output | null); /** * Configuration source specifier for an extension configuration discovery service. * In case of a failure and without the default configuration, the HTTP listener responds with code 500. * Extension configs delivered through this mechanism are not expected to require warming (see https://github.com/envoyproxy/envoy/issues/12061). */ - 'config_discovery'?: (_envoy_config_core_v3_ExtensionConfigSource__Output); + 'config_discovery'?: (_envoy_config_core_v3_ExtensionConfigSource__Output | null); /** * If true, clients that do not support this filter may ignore the * filter but otherwise accept the config. diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/LocalReplyConfig.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/LocalReplyConfig.ts index 10bb6e700..04de11fcb 100644 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/LocalReplyConfig.ts +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/LocalReplyConfig.ts @@ -51,7 +51,7 @@ export interface LocalReplyConfig { * "path": "/foo" * } */ - 'body_format'?: (_envoy_config_core_v3_SubstitutionFormatString); + 'body_format'?: (_envoy_config_core_v3_SubstitutionFormatString | null); } /** @@ -102,5 +102,5 @@ export interface LocalReplyConfig__Output { * "path": "/foo" * } */ - 'body_format'?: (_envoy_config_core_v3_SubstitutionFormatString__Output); + 'body_format': (_envoy_config_core_v3_SubstitutionFormatString__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/Rds.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/Rds.ts index 8e06a6d67..b99e2f1bd 100644 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/Rds.ts +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/Rds.ts @@ -6,7 +6,7 @@ export interface Rds { /** * Configuration source specifier for RDS. */ - 'config_source'?: (_envoy_config_core_v3_ConfigSource); + 'config_source'?: (_envoy_config_core_v3_ConfigSource | null); /** * The name of the route configuration. This name will be passed to the RDS * API. This allows an Envoy configuration with multiple HTTP listeners (and @@ -20,7 +20,7 @@ export interface Rds__Output { /** * Configuration source specifier for RDS. */ - 'config_source'?: (_envoy_config_core_v3_ConfigSource__Output); + 'config_source': (_envoy_config_core_v3_ConfigSource__Output | null); /** * The name of the route configuration. This name will be passed to the RDS * API. This allows an Envoy configuration with multiple HTTP listeners (and diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/RequestIDExtension.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/RequestIDExtension.ts index 24e05ccc3..ba1789a80 100644 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/RequestIDExtension.ts +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/RequestIDExtension.ts @@ -6,12 +6,12 @@ export interface RequestIDExtension { /** * Request ID extension specific configuration. */ - 'typed_config'?: (_google_protobuf_Any); + 'typed_config'?: (_google_protobuf_Any | null); } export interface RequestIDExtension__Output { /** * Request ID extension specific configuration. */ - 'typed_config'?: (_google_protobuf_Any__Output); + 'typed_config': (_google_protobuf_Any__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ResponseMapper.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ResponseMapper.ts index 67af3aec4..26d14a07d 100644 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ResponseMapper.ts +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ResponseMapper.ts @@ -14,21 +14,21 @@ export interface ResponseMapper { /** * Filter to determine if this mapper should apply. */ - 'filter'?: (_envoy_config_accesslog_v3_AccessLogFilter); + 'filter'?: (_envoy_config_accesslog_v3_AccessLogFilter | null); /** * The new response status code if specified. */ - 'status_code'?: (_google_protobuf_UInt32Value); + 'status_code'?: (_google_protobuf_UInt32Value | null); /** * The new local reply body text if specified. It will be used in the `%LOCAL_REPLY_BODY%` * command operator in the `body_format`. */ - 'body'?: (_envoy_config_core_v3_DataSource); + 'body'?: (_envoy_config_core_v3_DataSource | null); /** * A per mapper `body_format` to override the :ref:`body_format `. * It will be used when this mapper is matched. */ - 'body_format_override'?: (_envoy_config_core_v3_SubstitutionFormatString); + 'body_format_override'?: (_envoy_config_core_v3_SubstitutionFormatString | null); /** * HTTP headers to add to a local reply. This allows the response mapper to append, to add * or to override headers of any local reply before it is sent to a downstream client. @@ -44,21 +44,21 @@ export interface ResponseMapper__Output { /** * Filter to determine if this mapper should apply. */ - 'filter'?: (_envoy_config_accesslog_v3_AccessLogFilter__Output); + 'filter': (_envoy_config_accesslog_v3_AccessLogFilter__Output | null); /** * The new response status code if specified. */ - 'status_code'?: (_google_protobuf_UInt32Value__Output); + 'status_code': (_google_protobuf_UInt32Value__Output | null); /** * The new local reply body text if specified. It will be used in the `%LOCAL_REPLY_BODY%` * command operator in the `body_format`. */ - 'body'?: (_envoy_config_core_v3_DataSource__Output); + 'body': (_envoy_config_core_v3_DataSource__Output | null); /** * A per mapper `body_format` to override the :ref:`body_format `. * It will be used when this mapper is matched. */ - 'body_format_override'?: (_envoy_config_core_v3_SubstitutionFormatString__Output); + 'body_format_override': (_envoy_config_core_v3_SubstitutionFormatString__Output | null); /** * HTTP headers to add to a local reply. This allows the response mapper to append, to add * or to override headers of any local reply before it is sent to a downstream client. diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRds.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRds.ts index a9995b455..e4565ce80 100644 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRds.ts +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRds.ts @@ -6,12 +6,12 @@ export interface ScopedRds { /** * Configuration source specifier for scoped RDS. */ - 'scoped_rds_config_source'?: (_envoy_config_core_v3_ConfigSource); + 'scoped_rds_config_source'?: (_envoy_config_core_v3_ConfigSource | null); } export interface ScopedRds__Output { /** * Configuration source specifier for scoped RDS. */ - 'scoped_rds_config_source'?: (_envoy_config_core_v3_ConfigSource__Output); + 'scoped_rds_config_source': (_envoy_config_core_v3_ConfigSource__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRoutes.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRoutes.ts index a19e59b2a..8aecd3883 100644 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRoutes.ts +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRoutes.ts @@ -11,7 +11,7 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Sc /** * Specifies how a header field's value should be extracted. */ - 'header_value_extractor'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor); + 'header_value_extractor'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor | null); 'type'?: "header_value_extractor"; } @@ -22,7 +22,7 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Sc /** * Specifies how a header field's value should be extracted. */ - 'header_value_extractor'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor__Output); + 'header_value_extractor'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor__Output | null); 'type': "header_value_extractor"; } @@ -70,7 +70,7 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Sc /** * Specifies the key value pair to extract the value from. */ - 'element'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement); + 'element'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement | null); 'extract_type'?: "index"|"element"; } @@ -118,7 +118,7 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Sc /** * Specifies the key value pair to extract the value from. */ - 'element'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement__Output); + 'element'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder_HeaderValueExtractor_KvElement__Output | null); 'extract_type': "index"|"element"; } @@ -209,13 +209,13 @@ export interface ScopedRoutes { /** * The algorithm to use for constructing a scope key for each request. */ - 'scope_key_builder'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder); + 'scope_key_builder'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder | null); /** * Configuration source specifier for RDS. * This config source is used to subscribe to RouteConfiguration resources specified in * ScopedRouteConfiguration messages. */ - 'rds_config_source'?: (_envoy_config_core_v3_ConfigSource); + 'rds_config_source'?: (_envoy_config_core_v3_ConfigSource | null); /** * The set of routing scopes corresponding to the HCM. A scope is assigned to a request by * matching a key constructed from the request's attributes according to the algorithm specified @@ -223,7 +223,7 @@ export interface ScopedRoutes { * :ref:`ScopeKeyBuilder` * in this message. */ - 'scoped_route_configurations_list'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList); + 'scoped_route_configurations_list'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList | null); /** * The set of routing scopes associated with the HCM will be dynamically loaded via the SRDS * API. A scope is assigned to a request by matching a key constructed from the request's @@ -231,7 +231,7 @@ export interface ScopedRoutes { * :ref:`ScopeKeyBuilder` * in this message. */ - 'scoped_rds'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds); + 'scoped_rds'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds | null); 'config_specifier'?: "scoped_route_configurations_list"|"scoped_rds"; } @@ -246,13 +246,13 @@ export interface ScopedRoutes__Output { /** * The algorithm to use for constructing a scope key for each request. */ - 'scope_key_builder'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder__Output); + 'scope_key_builder': (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder__Output | null); /** * Configuration source specifier for RDS. * This config source is used to subscribe to RouteConfiguration resources specified in * ScopedRouteConfiguration messages. */ - 'rds_config_source'?: (_envoy_config_core_v3_ConfigSource__Output); + 'rds_config_source': (_envoy_config_core_v3_ConfigSource__Output | null); /** * The set of routing scopes corresponding to the HCM. A scope is assigned to a request by * matching a key constructed from the request's attributes according to the algorithm specified @@ -260,7 +260,7 @@ export interface ScopedRoutes__Output { * :ref:`ScopeKeyBuilder` * in this message. */ - 'scoped_route_configurations_list'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList__Output); + 'scoped_route_configurations_list'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList__Output | null); /** * The set of routing scopes associated with the HCM will be dynamically loaded via the SRDS * API. A scope is assigned to a request by matching a key constructed from the request's @@ -268,6 +268,6 @@ export interface ScopedRoutes__Output { * :ref:`ScopeKeyBuilder` * in this message. */ - 'scoped_rds'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds__Output); + 'scoped_rds'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds__Output | null); 'config_specifier': "scoped_route_configurations_list"|"scoped_rds"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v2/AggregatedDiscoveryService.ts b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v2/AggregatedDiscoveryService.ts index ec7641dca..6044118bc 100644 --- a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v2/AggregatedDiscoveryService.ts +++ b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v2/AggregatedDiscoveryService.ts @@ -1,6 +1,7 @@ // Original file: deps/envoy-api/envoy/service/discovery/v2/ads.proto import type * as grpc from '@grpc/grpc-js' +import type { MethodDefinition } from '@grpc/proto-loader' import type { DeltaDiscoveryRequest as _envoy_api_v2_DeltaDiscoveryRequest, DeltaDiscoveryRequest__Output as _envoy_api_v2_DeltaDiscoveryRequest__Output } from '../../../../envoy/api/v2/DeltaDiscoveryRequest'; import type { DeltaDiscoveryResponse as _envoy_api_v2_DeltaDiscoveryResponse, DeltaDiscoveryResponse__Output as _envoy_api_v2_DeltaDiscoveryResponse__Output } from '../../../../envoy/api/v2/DeltaDiscoveryResponse'; import type { DiscoveryRequest as _envoy_api_v2_DiscoveryRequest, DiscoveryRequest__Output as _envoy_api_v2_DiscoveryRequest__Output } from '../../../../envoy/api/v2/DiscoveryRequest'; @@ -50,3 +51,8 @@ export interface AggregatedDiscoveryServiceHandlers extends grpc.UntypedServiceI StreamAggregatedResources: grpc.handleBidiStreamingCall<_envoy_api_v2_DiscoveryRequest__Output, _envoy_api_v2_DiscoveryResponse>; } + +export interface AggregatedDiscoveryServiceDefinition extends grpc.ServiceDefinition { + DeltaAggregatedResources: MethodDefinition<_envoy_api_v2_DeltaDiscoveryRequest, _envoy_api_v2_DeltaDiscoveryResponse, _envoy_api_v2_DeltaDiscoveryRequest__Output, _envoy_api_v2_DeltaDiscoveryResponse__Output> + StreamAggregatedResources: MethodDefinition<_envoy_api_v2_DiscoveryRequest, _envoy_api_v2_DiscoveryResponse, _envoy_api_v2_DiscoveryRequest__Output, _envoy_api_v2_DiscoveryResponse__Output> +} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/AggregatedDiscoveryService.ts b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/AggregatedDiscoveryService.ts index 445057d44..e6498177b 100644 --- a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/AggregatedDiscoveryService.ts +++ b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/AggregatedDiscoveryService.ts @@ -1,6 +1,7 @@ // Original file: deps/envoy-api/envoy/service/discovery/v3/ads.proto import type * as grpc from '@grpc/grpc-js' +import type { MethodDefinition } from '@grpc/proto-loader' import type { DeltaDiscoveryRequest as _envoy_service_discovery_v3_DeltaDiscoveryRequest, DeltaDiscoveryRequest__Output as _envoy_service_discovery_v3_DeltaDiscoveryRequest__Output } from '../../../../envoy/service/discovery/v3/DeltaDiscoveryRequest'; import type { DeltaDiscoveryResponse as _envoy_service_discovery_v3_DeltaDiscoveryResponse, DeltaDiscoveryResponse__Output as _envoy_service_discovery_v3_DeltaDiscoveryResponse__Output } from '../../../../envoy/service/discovery/v3/DeltaDiscoveryResponse'; import type { DiscoveryRequest as _envoy_service_discovery_v3_DiscoveryRequest, DiscoveryRequest__Output as _envoy_service_discovery_v3_DiscoveryRequest__Output } from '../../../../envoy/service/discovery/v3/DiscoveryRequest'; @@ -50,3 +51,8 @@ export interface AggregatedDiscoveryServiceHandlers extends grpc.UntypedServiceI StreamAggregatedResources: grpc.handleBidiStreamingCall<_envoy_service_discovery_v3_DiscoveryRequest__Output, _envoy_service_discovery_v3_DiscoveryResponse>; } + +export interface AggregatedDiscoveryServiceDefinition extends grpc.ServiceDefinition { + DeltaAggregatedResources: MethodDefinition<_envoy_service_discovery_v3_DeltaDiscoveryRequest, _envoy_service_discovery_v3_DeltaDiscoveryResponse, _envoy_service_discovery_v3_DeltaDiscoveryRequest__Output, _envoy_service_discovery_v3_DeltaDiscoveryResponse__Output> + StreamAggregatedResources: MethodDefinition<_envoy_service_discovery_v3_DiscoveryRequest, _envoy_service_discovery_v3_DiscoveryResponse, _envoy_service_discovery_v3_DiscoveryRequest__Output, _envoy_service_discovery_v3_DiscoveryResponse__Output> +} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DeltaDiscoveryRequest.ts b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DeltaDiscoveryRequest.ts index bcf2de4e2..b42470516 100644 --- a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DeltaDiscoveryRequest.ts +++ b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DeltaDiscoveryRequest.ts @@ -42,7 +42,7 @@ export interface DeltaDiscoveryRequest { /** * The node making the request. */ - 'node'?: (_envoy_config_core_v3_Node); + 'node'?: (_envoy_config_core_v3_Node | null); /** * Type of the resource that is being requested, e.g. * "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment". This does not need to be set if @@ -101,7 +101,7 @@ export interface DeltaDiscoveryRequest { * failed to update configuration. The *message* field in *error_details* * provides the Envoy internal exception related to the failure. */ - 'error_detail'?: (_google_rpc_Status); + 'error_detail'?: (_google_rpc_Status | null); } /** @@ -143,7 +143,7 @@ export interface DeltaDiscoveryRequest__Output { /** * The node making the request. */ - 'node'?: (_envoy_config_core_v3_Node__Output); + 'node': (_envoy_config_core_v3_Node__Output | null); /** * Type of the resource that is being requested, e.g. * "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment". This does not need to be set if @@ -202,5 +202,5 @@ export interface DeltaDiscoveryRequest__Output { * failed to update configuration. The *message* field in *error_details* * provides the Envoy internal exception related to the failure. */ - 'error_detail'?: (_google_rpc_Status__Output); + 'error_detail': (_google_rpc_Status__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DeltaDiscoveryResponse.ts b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DeltaDiscoveryResponse.ts index c22690cd9..efbbed85c 100644 --- a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DeltaDiscoveryResponse.ts +++ b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DeltaDiscoveryResponse.ts @@ -35,7 +35,7 @@ export interface DeltaDiscoveryResponse { * [#not-implemented-hide:] * The control plane instance that sent the response. */ - 'control_plane'?: (_envoy_config_core_v3_ControlPlane); + 'control_plane'?: (_envoy_config_core_v3_ControlPlane | null); } /** @@ -70,5 +70,5 @@ export interface DeltaDiscoveryResponse__Output { * [#not-implemented-hide:] * The control plane instance that sent the response. */ - 'control_plane'?: (_envoy_config_core_v3_ControlPlane__Output); + 'control_plane': (_envoy_config_core_v3_ControlPlane__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DiscoveryRequest.ts b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DiscoveryRequest.ts index 2b23ee869..b30930b6f 100644 --- a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DiscoveryRequest.ts +++ b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DiscoveryRequest.ts @@ -22,7 +22,7 @@ export interface DiscoveryRequest { /** * The node making the request. */ - 'node'?: (_envoy_config_core_v3_Node); + 'node'?: (_envoy_config_core_v3_Node | null); /** * List of resources to subscribe to, e.g. list of cluster names or a route * configuration name. If this is empty, all resources for the API are @@ -53,7 +53,7 @@ export interface DiscoveryRequest { * internal exception related to the failure. It is only intended for consumption during manual * debugging, the string provided is not guaranteed to be stable across Envoy versions. */ - 'error_detail'?: (_google_rpc_Status); + 'error_detail'?: (_google_rpc_Status | null); } /** @@ -75,7 +75,7 @@ export interface DiscoveryRequest__Output { /** * The node making the request. */ - 'node'?: (_envoy_config_core_v3_Node__Output); + 'node': (_envoy_config_core_v3_Node__Output | null); /** * List of resources to subscribe to, e.g. list of cluster names or a route * configuration name. If this is empty, all resources for the API are @@ -106,5 +106,5 @@ export interface DiscoveryRequest__Output { * internal exception related to the failure. It is only intended for consumption during manual * debugging, the string provided is not guaranteed to be stable across Envoy versions. */ - 'error_detail'?: (_google_rpc_Status__Output); + 'error_detail': (_google_rpc_Status__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DiscoveryResponse.ts b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DiscoveryResponse.ts index f69944b80..874168317 100644 --- a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DiscoveryResponse.ts +++ b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DiscoveryResponse.ts @@ -51,7 +51,7 @@ export interface DiscoveryResponse { /** * The control plane instance that sent the response. */ - 'control_plane'?: (_envoy_config_core_v3_ControlPlane); + 'control_plane'?: (_envoy_config_core_v3_ControlPlane | null); } /** @@ -102,5 +102,5 @@ export interface DiscoveryResponse__Output { /** * The control plane instance that sent the response. */ - 'control_plane'?: (_envoy_config_core_v3_ControlPlane__Output); + 'control_plane': (_envoy_config_core_v3_ControlPlane__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/Resource.ts b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/Resource.ts index 27a70c97c..0e5897ab4 100644 --- a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/Resource.ts +++ b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/Resource.ts @@ -41,7 +41,7 @@ export interface Resource { /** * The resource being tracked. */ - 'resource'?: (_google_protobuf_Any); + 'resource'?: (_google_protobuf_Any | null); /** * The resource's name, to distinguish it from others of the same type of resource. */ @@ -65,12 +65,12 @@ export interface Resource { * testing where the fault injection should be terminated in the event that Envoy loses contact * with the management server. */ - 'ttl'?: (_google_protobuf_Duration); + 'ttl'?: (_google_protobuf_Duration | null); /** * Cache control properties for the resource. * [#not-implemented-hide:] */ - 'cache_control'?: (_envoy_service_discovery_v3_Resource_CacheControl); + 'cache_control'?: (_envoy_service_discovery_v3_Resource_CacheControl | null); } /** @@ -85,7 +85,7 @@ export interface Resource__Output { /** * The resource being tracked. */ - 'resource'?: (_google_protobuf_Any__Output); + 'resource': (_google_protobuf_Any__Output | null); /** * The resource's name, to distinguish it from others of the same type of resource. */ @@ -109,10 +109,10 @@ export interface Resource__Output { * testing where the fault injection should be terminated in the event that Envoy loses contact * with the management server. */ - 'ttl'?: (_google_protobuf_Duration__Output); + 'ttl': (_google_protobuf_Duration__Output | null); /** * Cache control properties for the resource. * [#not-implemented-hide:] */ - 'cache_control'?: (_envoy_service_discovery_v3_Resource_CacheControl__Output); + 'cache_control': (_envoy_service_discovery_v3_Resource_CacheControl__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadReportingService.ts b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadReportingService.ts index 41e73f0e9..2a95752de 100644 --- a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadReportingService.ts +++ b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadReportingService.ts @@ -1,6 +1,7 @@ // Original file: deps/envoy-api/envoy/service/load_stats/v2/lrs.proto import type * as grpc from '@grpc/grpc-js' +import type { MethodDefinition } from '@grpc/proto-loader' import type { LoadStatsRequest as _envoy_service_load_stats_v2_LoadStatsRequest, LoadStatsRequest__Output as _envoy_service_load_stats_v2_LoadStatsRequest__Output } from '../../../../envoy/service/load_stats/v2/LoadStatsRequest'; import type { LoadStatsResponse as _envoy_service_load_stats_v2_LoadStatsResponse, LoadStatsResponse__Output as _envoy_service_load_stats_v2_LoadStatsResponse__Output } from '../../../../envoy/service/load_stats/v2/LoadStatsResponse'; @@ -106,3 +107,7 @@ export interface LoadReportingServiceHandlers extends grpc.UntypedServiceImpleme StreamLoadStats: grpc.handleBidiStreamingCall<_envoy_service_load_stats_v2_LoadStatsRequest__Output, _envoy_service_load_stats_v2_LoadStatsResponse>; } + +export interface LoadReportingServiceDefinition extends grpc.ServiceDefinition { + StreamLoadStats: MethodDefinition<_envoy_service_load_stats_v2_LoadStatsRequest, _envoy_service_load_stats_v2_LoadStatsResponse, _envoy_service_load_stats_v2_LoadStatsRequest__Output, _envoy_service_load_stats_v2_LoadStatsResponse__Output> +} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadStatsRequest.ts b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadStatsRequest.ts index a7ac6b8e1..3cd5ebc2f 100644 --- a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadStatsRequest.ts +++ b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadStatsRequest.ts @@ -11,7 +11,7 @@ export interface LoadStatsRequest { /** * Node identifier for Envoy instance. */ - 'node'?: (_envoy_api_v2_core_Node); + 'node'?: (_envoy_api_v2_core_Node | null); /** * A list of load stats to report. */ @@ -26,7 +26,7 @@ export interface LoadStatsRequest__Output { /** * Node identifier for Envoy instance. */ - 'node'?: (_envoy_api_v2_core_Node__Output); + 'node': (_envoy_api_v2_core_Node__Output | null); /** * A list of load stats to report. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadStatsResponse.ts b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadStatsResponse.ts index afec8f180..1065fe22f 100644 --- a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadStatsResponse.ts +++ b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadStatsResponse.ts @@ -22,7 +22,7 @@ export interface LoadStatsResponse { * of inobservability that might otherwise exists between the messages. New clusters are not * subject to this consideration. */ - 'load_reporting_interval'?: (_google_protobuf_Duration); + 'load_reporting_interval'?: (_google_protobuf_Duration | null); /** * Set to *true* if the management server supports endpoint granularity * report. @@ -56,7 +56,7 @@ export interface LoadStatsResponse__Output { * of inobservability that might otherwise exists between the messages. New clusters are not * subject to this consideration. */ - 'load_reporting_interval'?: (_google_protobuf_Duration__Output); + 'load_reporting_interval': (_google_protobuf_Duration__Output | null); /** * Set to *true* if the management server supports endpoint granularity * report. diff --git a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadReportingService.ts b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadReportingService.ts index 24a9de55e..32aa4f96e 100644 --- a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadReportingService.ts +++ b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadReportingService.ts @@ -1,6 +1,7 @@ // Original file: deps/envoy-api/envoy/service/load_stats/v3/lrs.proto import type * as grpc from '@grpc/grpc-js' +import type { MethodDefinition } from '@grpc/proto-loader' import type { LoadStatsRequest as _envoy_service_load_stats_v3_LoadStatsRequest, LoadStatsRequest__Output as _envoy_service_load_stats_v3_LoadStatsRequest__Output } from '../../../../envoy/service/load_stats/v3/LoadStatsRequest'; import type { LoadStatsResponse as _envoy_service_load_stats_v3_LoadStatsResponse, LoadStatsResponse__Output as _envoy_service_load_stats_v3_LoadStatsResponse__Output } from '../../../../envoy/service/load_stats/v3/LoadStatsResponse'; @@ -106,3 +107,7 @@ export interface LoadReportingServiceHandlers extends grpc.UntypedServiceImpleme StreamLoadStats: grpc.handleBidiStreamingCall<_envoy_service_load_stats_v3_LoadStatsRequest__Output, _envoy_service_load_stats_v3_LoadStatsResponse>; } + +export interface LoadReportingServiceDefinition extends grpc.ServiceDefinition { + StreamLoadStats: MethodDefinition<_envoy_service_load_stats_v3_LoadStatsRequest, _envoy_service_load_stats_v3_LoadStatsResponse, _envoy_service_load_stats_v3_LoadStatsRequest__Output, _envoy_service_load_stats_v3_LoadStatsResponse__Output> +} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadStatsRequest.ts b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadStatsRequest.ts index 6f0e19525..e430eb270 100644 --- a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadStatsRequest.ts +++ b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadStatsRequest.ts @@ -10,7 +10,7 @@ export interface LoadStatsRequest { /** * Node identifier for Envoy instance. */ - 'node'?: (_envoy_config_core_v3_Node); + 'node'?: (_envoy_config_core_v3_Node | null); /** * A list of load stats to report. */ @@ -24,7 +24,7 @@ export interface LoadStatsRequest__Output { /** * Node identifier for Envoy instance. */ - 'node'?: (_envoy_config_core_v3_Node__Output); + 'node': (_envoy_config_core_v3_Node__Output | null); /** * A list of load stats to report. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadStatsResponse.ts b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadStatsResponse.ts index 51f017474..c39658cde 100644 --- a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadStatsResponse.ts +++ b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadStatsResponse.ts @@ -22,7 +22,7 @@ export interface LoadStatsResponse { * of inobservability that might otherwise exists between the messages. New clusters are not * subject to this consideration. */ - 'load_reporting_interval'?: (_google_protobuf_Duration); + 'load_reporting_interval'?: (_google_protobuf_Duration | null); /** * Set to *true* if the management server supports endpoint granularity * report. @@ -56,7 +56,7 @@ export interface LoadStatsResponse__Output { * of inobservability that might otherwise exists between the messages. New clusters are not * subject to this consideration. */ - 'load_reporting_interval'?: (_google_protobuf_Duration__Output); + 'load_reporting_interval': (_google_protobuf_Duration__Output | null); /** * Set to *true* if the management server supports endpoint granularity * report. diff --git a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/DoubleMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/DoubleMatcher.ts index e91a4898e..0bf3bca79 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/DoubleMatcher.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/DoubleMatcher.ts @@ -10,7 +10,7 @@ export interface DoubleMatcher { * If specified, the input double value must be in the range specified here. * Note: The range is using half-open interval semantics [start, end). */ - 'range'?: (_envoy_type_v3_DoubleRange); + 'range'?: (_envoy_type_v3_DoubleRange | null); /** * If specified, the input double value must be equal to the value specified here. */ @@ -26,7 +26,7 @@ export interface DoubleMatcher__Output { * If specified, the input double value must be in the range specified here. * Note: The range is using half-open interval semantics [start, end). */ - 'range'?: (_envoy_type_v3_DoubleRange__Output); + 'range'?: (_envoy_type_v3_DoubleRange__Output | null); /** * If specified, the input double value must be equal to the value specified here. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/ListMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/ListMatcher.ts index c32b72a39..10bf5567c 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/ListMatcher.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/ListMatcher.ts @@ -9,7 +9,7 @@ export interface ListMatcher { /** * If specified, at least one of the values in the list must match the value specified. */ - 'one_of'?: (_envoy_type_matcher_v3_ValueMatcher); + 'one_of'?: (_envoy_type_matcher_v3_ValueMatcher | null); 'match_pattern'?: "one_of"; } @@ -20,6 +20,6 @@ export interface ListMatcher__Output { /** * If specified, at least one of the values in the list must match the value specified. */ - 'one_of'?: (_envoy_type_matcher_v3_ValueMatcher__Output); + 'one_of'?: (_envoy_type_matcher_v3_ValueMatcher__Output | null); 'match_pattern': "one_of"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/MetadataMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/MetadataMatcher.ts index 8d80408a3..58117faab 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/MetadataMatcher.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/MetadataMatcher.ts @@ -43,7 +43,7 @@ export interface MetadataMatcher { /** * The MetadataMatcher is matched if the value retrieved by path is matched to this value. */ - 'value'?: (_envoy_type_matcher_v3_ValueMatcher); + 'value'?: (_envoy_type_matcher_v3_ValueMatcher | null); } /** @@ -61,5 +61,5 @@ export interface MetadataMatcher__Output { /** * The MetadataMatcher is matched if the value retrieved by path is matched to this value. */ - 'value'?: (_envoy_type_matcher_v3_ValueMatcher__Output); + 'value': (_envoy_type_matcher_v3_ValueMatcher__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/RegexMatchAndSubstitute.ts b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/RegexMatchAndSubstitute.ts index 4abddc655..3796765a7 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/RegexMatchAndSubstitute.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/RegexMatchAndSubstitute.ts @@ -18,7 +18,7 @@ export interface RegexMatchAndSubstitute { * used in the pattern to extract portions of the subject string, and then * referenced in the substitution string. */ - 'pattern'?: (_envoy_type_matcher_v3_RegexMatcher); + 'pattern'?: (_envoy_type_matcher_v3_RegexMatcher | null); /** * The string that should be substituted into matching portions of the * subject string during a substitution operation to produce a new string. @@ -49,7 +49,7 @@ export interface RegexMatchAndSubstitute__Output { * used in the pattern to extract portions of the subject string, and then * referenced in the substitution string. */ - 'pattern'?: (_envoy_type_matcher_v3_RegexMatcher__Output); + 'pattern': (_envoy_type_matcher_v3_RegexMatcher__Output | null); /** * The string that should be substituted into matching portions of the * subject string during a substitution operation to produce a new string. 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 0e8b37f08..1addb1730 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 @@ -27,7 +27,7 @@ export interface _envoy_type_matcher_v3_RegexMatcher_GoogleRE2 { * This field is deprecated; regexp validation should be performed on the management server * instead of being done by each individual client. */ - 'max_program_size'?: (_google_protobuf_UInt32Value); + 'max_program_size'?: (_google_protobuf_UInt32Value | null); } /** @@ -55,7 +55,7 @@ export interface _envoy_type_matcher_v3_RegexMatcher_GoogleRE2__Output { * This field is deprecated; regexp validation should be performed on the management server * instead of being done by each individual client. */ - 'max_program_size'?: (_google_protobuf_UInt32Value__Output); + 'max_program_size': (_google_protobuf_UInt32Value__Output | null); } /** @@ -65,7 +65,7 @@ export interface RegexMatcher { /** * Google's RE2 regex engine. */ - 'google_re2'?: (_envoy_type_matcher_v3_RegexMatcher_GoogleRE2); + 'google_re2'?: (_envoy_type_matcher_v3_RegexMatcher_GoogleRE2 | null); /** * The regex match string. The string must be supported by the configured engine. */ @@ -80,7 +80,7 @@ export interface RegexMatcher__Output { /** * Google's RE2 regex engine. */ - 'google_re2'?: (_envoy_type_matcher_v3_RegexMatcher_GoogleRE2__Output); + 'google_re2'?: (_envoy_type_matcher_v3_RegexMatcher_GoogleRE2__Output | null); /** * The regex match string. The string must be supported by the configured engine. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/StringMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/StringMatcher.ts index 58616dde8..c89190510 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/StringMatcher.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/StringMatcher.ts @@ -36,7 +36,7 @@ export interface StringMatcher { /** * The input string must match the regular expression specified here. */ - 'safe_regex'?: (_envoy_type_matcher_v3_RegexMatcher); + 'safe_regex'?: (_envoy_type_matcher_v3_RegexMatcher | null); /** * If true, indicates the exact/prefix/suffix matching should be case insensitive. This has no * effect for the safe_regex match. @@ -89,7 +89,7 @@ export interface StringMatcher__Output { /** * The input string must match the regular expression specified here. */ - 'safe_regex'?: (_envoy_type_matcher_v3_RegexMatcher__Output); + 'safe_regex'?: (_envoy_type_matcher_v3_RegexMatcher__Output | null); /** * If true, indicates the exact/prefix/suffix matching should be case insensitive. This has no * effect for the safe_regex match. diff --git a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/ValueMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/ValueMatcher.ts index 6c271162a..d01060446 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/ValueMatcher.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/ValueMatcher.ts @@ -25,17 +25,17 @@ export interface ValueMatcher { /** * If specified, a match occurs if and only if the target value is a NullValue. */ - 'null_match'?: (_envoy_type_matcher_v3_ValueMatcher_NullMatch); + 'null_match'?: (_envoy_type_matcher_v3_ValueMatcher_NullMatch | null); /** * If specified, a match occurs if and only if the target value is a double value and is * matched to this field. */ - 'double_match'?: (_envoy_type_matcher_v3_DoubleMatcher); + 'double_match'?: (_envoy_type_matcher_v3_DoubleMatcher | null); /** * If specified, a match occurs if and only if the target value is a string value and is * matched to this field. */ - 'string_match'?: (_envoy_type_matcher_v3_StringMatcher); + 'string_match'?: (_envoy_type_matcher_v3_StringMatcher | null); /** * If specified, a match occurs if and only if the target value is a bool value and is equal * to this field. @@ -51,7 +51,7 @@ export interface ValueMatcher { * If specified, a match occurs if and only if the target value is a list value and * is matched to this field. */ - 'list_match'?: (_envoy_type_matcher_v3_ListMatcher); + 'list_match'?: (_envoy_type_matcher_v3_ListMatcher | null); /** * Specifies how to match a value. */ @@ -67,17 +67,17 @@ export interface ValueMatcher__Output { /** * If specified, a match occurs if and only if the target value is a NullValue. */ - 'null_match'?: (_envoy_type_matcher_v3_ValueMatcher_NullMatch__Output); + 'null_match'?: (_envoy_type_matcher_v3_ValueMatcher_NullMatch__Output | null); /** * If specified, a match occurs if and only if the target value is a double value and is * matched to this field. */ - 'double_match'?: (_envoy_type_matcher_v3_DoubleMatcher__Output); + 'double_match'?: (_envoy_type_matcher_v3_DoubleMatcher__Output | null); /** * If specified, a match occurs if and only if the target value is a string value and is * matched to this field. */ - 'string_match'?: (_envoy_type_matcher_v3_StringMatcher__Output); + 'string_match'?: (_envoy_type_matcher_v3_StringMatcher__Output | null); /** * If specified, a match occurs if and only if the target value is a bool value and is equal * to this field. @@ -93,7 +93,7 @@ export interface ValueMatcher__Output { * If specified, a match occurs if and only if the target value is a list value and * is matched to this field. */ - 'list_match'?: (_envoy_type_matcher_v3_ListMatcher__Output); + 'list_match'?: (_envoy_type_matcher_v3_ListMatcher__Output | null); /** * Specifies how to match a value. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/type/metadata/v3/MetadataKind.ts b/packages/grpc-js-xds/src/generated/envoy/type/metadata/v3/MetadataKind.ts index c231ecf98..2457b3f91 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/metadata/v3/MetadataKind.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/metadata/v3/MetadataKind.ts @@ -58,19 +58,19 @@ export interface MetadataKind { /** * Request kind of metadata. */ - 'request'?: (_envoy_type_metadata_v3_MetadataKind_Request); + 'request'?: (_envoy_type_metadata_v3_MetadataKind_Request | null); /** * Route kind of metadata. */ - 'route'?: (_envoy_type_metadata_v3_MetadataKind_Route); + 'route'?: (_envoy_type_metadata_v3_MetadataKind_Route | null); /** * Cluster kind of metadata. */ - 'cluster'?: (_envoy_type_metadata_v3_MetadataKind_Cluster); + 'cluster'?: (_envoy_type_metadata_v3_MetadataKind_Cluster | null); /** * Host kind of metadata. */ - 'host'?: (_envoy_type_metadata_v3_MetadataKind_Host); + 'host'?: (_envoy_type_metadata_v3_MetadataKind_Host | null); 'kind'?: "request"|"route"|"cluster"|"host"; } @@ -81,18 +81,18 @@ export interface MetadataKind__Output { /** * Request kind of metadata. */ - 'request'?: (_envoy_type_metadata_v3_MetadataKind_Request__Output); + 'request'?: (_envoy_type_metadata_v3_MetadataKind_Request__Output | null); /** * Route kind of metadata. */ - 'route'?: (_envoy_type_metadata_v3_MetadataKind_Route__Output); + 'route'?: (_envoy_type_metadata_v3_MetadataKind_Route__Output | null); /** * Cluster kind of metadata. */ - 'cluster'?: (_envoy_type_metadata_v3_MetadataKind_Cluster__Output); + 'cluster'?: (_envoy_type_metadata_v3_MetadataKind_Cluster__Output | null); /** * Host kind of metadata. */ - 'host'?: (_envoy_type_metadata_v3_MetadataKind_Host__Output); + 'host'?: (_envoy_type_metadata_v3_MetadataKind_Host__Output | null); 'kind': "request"|"route"|"cluster"|"host"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/type/tracing/v3/CustomTag.ts b/packages/grpc-js-xds/src/generated/envoy/type/tracing/v3/CustomTag.ts index ef29c3420..d5fe26ed5 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/tracing/v3/CustomTag.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/tracing/v3/CustomTag.ts @@ -98,11 +98,11 @@ export interface _envoy_type_tracing_v3_CustomTag_Metadata { /** * Specify what kind of metadata to obtain tag value from. */ - 'kind'?: (_envoy_type_metadata_v3_MetadataKind); + 'kind'?: (_envoy_type_metadata_v3_MetadataKind | null); /** * Metadata key to define the path to retrieve the tag value. */ - 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey); + 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey | null); /** * When no valid metadata is found, * the tag value would be populated with this default value if specified, @@ -122,11 +122,11 @@ export interface _envoy_type_tracing_v3_CustomTag_Metadata__Output { /** * Specify what kind of metadata to obtain tag value from. */ - 'kind'?: (_envoy_type_metadata_v3_MetadataKind__Output); + 'kind': (_envoy_type_metadata_v3_MetadataKind__Output | null); /** * Metadata key to define the path to retrieve the tag value. */ - 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey__Output); + 'metadata_key': (_envoy_type_metadata_v3_MetadataKey__Output | null); /** * When no valid metadata is found, * the tag value would be populated with this default value if specified, @@ -147,19 +147,19 @@ export interface CustomTag { /** * A literal custom tag. */ - 'literal'?: (_envoy_type_tracing_v3_CustomTag_Literal); + 'literal'?: (_envoy_type_tracing_v3_CustomTag_Literal | null); /** * An environment custom tag. */ - 'environment'?: (_envoy_type_tracing_v3_CustomTag_Environment); + 'environment'?: (_envoy_type_tracing_v3_CustomTag_Environment | null); /** * A request header custom tag. */ - 'request_header'?: (_envoy_type_tracing_v3_CustomTag_Header); + 'request_header'?: (_envoy_type_tracing_v3_CustomTag_Header | null); /** * A custom tag to obtain tag value from the metadata. */ - 'metadata'?: (_envoy_type_tracing_v3_CustomTag_Metadata); + 'metadata'?: (_envoy_type_tracing_v3_CustomTag_Metadata | null); /** * Used to specify what kind of custom tag. */ @@ -178,19 +178,19 @@ export interface CustomTag__Output { /** * A literal custom tag. */ - 'literal'?: (_envoy_type_tracing_v3_CustomTag_Literal__Output); + 'literal'?: (_envoy_type_tracing_v3_CustomTag_Literal__Output | null); /** * An environment custom tag. */ - 'environment'?: (_envoy_type_tracing_v3_CustomTag_Environment__Output); + 'environment'?: (_envoy_type_tracing_v3_CustomTag_Environment__Output | null); /** * A request header custom tag. */ - 'request_header'?: (_envoy_type_tracing_v3_CustomTag_Header__Output); + 'request_header'?: (_envoy_type_tracing_v3_CustomTag_Header__Output | null); /** * A custom tag to obtain tag value from the metadata. */ - 'metadata'?: (_envoy_type_tracing_v3_CustomTag_Metadata__Output); + 'metadata'?: (_envoy_type_tracing_v3_CustomTag_Metadata__Output | null); /** * Used to specify what kind of custom tag. */ diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/DescriptorProto.ts b/packages/grpc-js-xds/src/generated/google/protobuf/DescriptorProto.ts index 2f6f9f0cc..f729437f4 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/DescriptorProto.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/DescriptorProto.ts @@ -33,7 +33,7 @@ export interface DescriptorProto { 'enumType'?: (_google_protobuf_EnumDescriptorProto)[]; 'extensionRange'?: (_google_protobuf_DescriptorProto_ExtensionRange)[]; 'extension'?: (_google_protobuf_FieldDescriptorProto)[]; - 'options'?: (_google_protobuf_MessageOptions); + 'options'?: (_google_protobuf_MessageOptions | null); 'oneofDecl'?: (_google_protobuf_OneofDescriptorProto)[]; 'reservedRange'?: (_google_protobuf_DescriptorProto_ReservedRange)[]; 'reservedName'?: (string)[]; @@ -46,7 +46,7 @@ export interface DescriptorProto__Output { 'enumType': (_google_protobuf_EnumDescriptorProto__Output)[]; 'extensionRange': (_google_protobuf_DescriptorProto_ExtensionRange__Output)[]; 'extension': (_google_protobuf_FieldDescriptorProto__Output)[]; - 'options'?: (_google_protobuf_MessageOptions__Output); + 'options': (_google_protobuf_MessageOptions__Output | null); 'oneofDecl': (_google_protobuf_OneofDescriptorProto__Output)[]; 'reservedRange': (_google_protobuf_DescriptorProto_ReservedRange__Output)[]; 'reservedName': (string)[]; diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/EnumDescriptorProto.ts b/packages/grpc-js-xds/src/generated/google/protobuf/EnumDescriptorProto.ts index 7aa40ce4d..dc4c9673e 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/EnumDescriptorProto.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/EnumDescriptorProto.ts @@ -6,11 +6,11 @@ import type { EnumOptions as _google_protobuf_EnumOptions, EnumOptions__Output a export interface EnumDescriptorProto { 'name'?: (string); 'value'?: (_google_protobuf_EnumValueDescriptorProto)[]; - 'options'?: (_google_protobuf_EnumOptions); + 'options'?: (_google_protobuf_EnumOptions | null); } export interface EnumDescriptorProto__Output { 'name': (string); 'value': (_google_protobuf_EnumValueDescriptorProto__Output)[]; - 'options'?: (_google_protobuf_EnumOptions__Output); + 'options': (_google_protobuf_EnumOptions__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/EnumOptions.ts b/packages/grpc-js-xds/src/generated/google/protobuf/EnumOptions.ts index b92ade4f9..777901a54 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/EnumOptions.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/EnumOptions.ts @@ -1,15 +1,18 @@ // Original file: null import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; +import type { MigrateAnnotation as _udpa_annotations_MigrateAnnotation, MigrateAnnotation__Output as _udpa_annotations_MigrateAnnotation__Output } from '../../udpa/annotations/MigrateAnnotation'; export interface EnumOptions { 'allowAlias'?: (boolean); 'deprecated'?: (boolean); 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; + '.udpa.annotations.enum_migrate'?: (_udpa_annotations_MigrateAnnotation | null); } export interface EnumOptions__Output { 'allowAlias': (boolean); 'deprecated': (boolean); 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; + '.udpa.annotations.enum_migrate': (_udpa_annotations_MigrateAnnotation__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/EnumValueDescriptorProto.ts b/packages/grpc-js-xds/src/generated/google/protobuf/EnumValueDescriptorProto.ts index 238e7fd01..7f8e57ea5 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/EnumValueDescriptorProto.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/EnumValueDescriptorProto.ts @@ -5,11 +5,11 @@ import type { EnumValueOptions as _google_protobuf_EnumValueOptions, EnumValueOp export interface EnumValueDescriptorProto { 'name'?: (string); 'number'?: (number); - 'options'?: (_google_protobuf_EnumValueOptions); + 'options'?: (_google_protobuf_EnumValueOptions | null); } export interface EnumValueDescriptorProto__Output { 'name': (string); 'number': (number); - 'options'?: (_google_protobuf_EnumValueOptions__Output); + 'options': (_google_protobuf_EnumValueOptions__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/EnumValueOptions.ts b/packages/grpc-js-xds/src/generated/google/protobuf/EnumValueOptions.ts index e60ee6f4c..48fea77be 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/EnumValueOptions.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/EnumValueOptions.ts @@ -1,13 +1,18 @@ // Original file: null import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; +import type { MigrateAnnotation as _udpa_annotations_MigrateAnnotation, MigrateAnnotation__Output as _udpa_annotations_MigrateAnnotation__Output } from '../../udpa/annotations/MigrateAnnotation'; export interface EnumValueOptions { 'deprecated'?: (boolean); 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; + '.envoy.annotations.disallowed_by_default_enum'?: (boolean); + '.udpa.annotations.enum_value_migrate'?: (_udpa_annotations_MigrateAnnotation | null); } export interface EnumValueOptions__Output { 'deprecated': (boolean); 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; + '.envoy.annotations.disallowed_by_default_enum': (boolean); + '.udpa.annotations.enum_value_migrate': (_udpa_annotations_MigrateAnnotation__Output | null); } 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 b59518c4b..c511e2eff 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/FieldDescriptorProto.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/FieldDescriptorProto.ts @@ -41,7 +41,7 @@ export interface FieldDescriptorProto { 'type'?: (_google_protobuf_FieldDescriptorProto_Type | keyof typeof _google_protobuf_FieldDescriptorProto_Type); 'typeName'?: (string); 'defaultValue'?: (string); - 'options'?: (_google_protobuf_FieldOptions); + 'options'?: (_google_protobuf_FieldOptions | null); 'oneofIndex'?: (number); 'jsonName'?: (string); } @@ -54,7 +54,7 @@ export interface FieldDescriptorProto__Output { 'type': (keyof typeof _google_protobuf_FieldDescriptorProto_Type); 'typeName': (string); 'defaultValue': (string); - 'options'?: (_google_protobuf_FieldOptions__Output); + 'options': (_google_protobuf_FieldOptions__Output | null); 'oneofIndex': (number); 'jsonName': (string); } 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 530022afe..028e14b74 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/FieldOptions.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/FieldOptions.ts @@ -2,6 +2,7 @@ import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; import type { FieldRules as _validate_FieldRules, FieldRules__Output as _validate_FieldRules__Output } from '../../validate/FieldRules'; +import type { FieldMigrateAnnotation as _udpa_annotations_FieldMigrateAnnotation, FieldMigrateAnnotation__Output as _udpa_annotations_FieldMigrateAnnotation__Output } from '../../udpa/annotations/FieldMigrateAnnotation'; // Original file: null @@ -27,7 +28,10 @@ export interface FieldOptions { 'jstype'?: (_google_protobuf_FieldOptions_JSType | keyof typeof _google_protobuf_FieldOptions_JSType); 'weak'?: (boolean); 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; - '.validate.rules'?: (_validate_FieldRules); + '.validate.rules'?: (_validate_FieldRules | null); + '.udpa.annotations.sensitive'?: (boolean); + '.udpa.annotations.field_migrate'?: (_udpa_annotations_FieldMigrateAnnotation | null); + '.envoy.annotations.disallowed_by_default'?: (boolean); } export interface FieldOptions__Output { @@ -38,5 +42,8 @@ export interface FieldOptions__Output { 'jstype': (keyof typeof _google_protobuf_FieldOptions_JSType); 'weak': (boolean); 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; - '.validate.rules'?: (_validate_FieldRules__Output); + '.validate.rules': (_validate_FieldRules__Output | null); + '.udpa.annotations.sensitive': (boolean); + '.udpa.annotations.field_migrate': (_udpa_annotations_FieldMigrateAnnotation__Output | null); + '.envoy.annotations.disallowed_by_default': (boolean); } diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/FileDescriptorProto.ts b/packages/grpc-js-xds/src/generated/google/protobuf/FileDescriptorProto.ts index 2954e4208..b723da7c0 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/FileDescriptorProto.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/FileDescriptorProto.ts @@ -15,8 +15,8 @@ export interface FileDescriptorProto { 'enumType'?: (_google_protobuf_EnumDescriptorProto)[]; 'service'?: (_google_protobuf_ServiceDescriptorProto)[]; 'extension'?: (_google_protobuf_FieldDescriptorProto)[]; - 'options'?: (_google_protobuf_FileOptions); - 'sourceCodeInfo'?: (_google_protobuf_SourceCodeInfo); + 'options'?: (_google_protobuf_FileOptions | null); + 'sourceCodeInfo'?: (_google_protobuf_SourceCodeInfo | null); 'publicDependency'?: (number)[]; 'weakDependency'?: (number)[]; 'syntax'?: (string); @@ -30,8 +30,8 @@ export interface FileDescriptorProto__Output { 'enumType': (_google_protobuf_EnumDescriptorProto__Output)[]; 'service': (_google_protobuf_ServiceDescriptorProto__Output)[]; 'extension': (_google_protobuf_FieldDescriptorProto__Output)[]; - 'options'?: (_google_protobuf_FileOptions__Output); - 'sourceCodeInfo'?: (_google_protobuf_SourceCodeInfo__Output); + 'options': (_google_protobuf_FileOptions__Output | null); + 'sourceCodeInfo': (_google_protobuf_SourceCodeInfo__Output | null); 'publicDependency': (number)[]; 'weakDependency': (number)[]; 'syntax': (string); 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 573e847c0..b046c3ad3 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/FileOptions.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/FileOptions.ts @@ -1,6 +1,8 @@ // Original file: null import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; +import type { FileMigrateAnnotation as _udpa_annotations_FileMigrateAnnotation, FileMigrateAnnotation__Output as _udpa_annotations_FileMigrateAnnotation__Output } from '../../udpa/annotations/FileMigrateAnnotation'; +import type { StatusAnnotation as _udpa_annotations_StatusAnnotation, StatusAnnotation__Output as _udpa_annotations_StatusAnnotation__Output } from '../../udpa/annotations/StatusAnnotation'; // Original file: null @@ -26,6 +28,8 @@ export interface FileOptions { 'objcClassPrefix'?: (string); 'csharpNamespace'?: (string); 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; + '.udpa.annotations.file_migrate'?: (_udpa_annotations_FileMigrateAnnotation | null); + '.udpa.annotations.file_status'?: (_udpa_annotations_StatusAnnotation | null); } export interface FileOptions__Output { @@ -44,4 +48,6 @@ export interface FileOptions__Output { 'objcClassPrefix': (string); 'csharpNamespace': (string); 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; + '.udpa.annotations.file_migrate': (_udpa_annotations_FileMigrateAnnotation__Output | null); + '.udpa.annotations.file_status': (_udpa_annotations_StatusAnnotation__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/MessageOptions.ts b/packages/grpc-js-xds/src/generated/google/protobuf/MessageOptions.ts index d3b5a54b8..9dc521214 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/MessageOptions.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/MessageOptions.ts @@ -1,6 +1,8 @@ // Original file: null import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; +import type { VersioningAnnotation as _udpa_annotations_VersioningAnnotation, VersioningAnnotation__Output as _udpa_annotations_VersioningAnnotation__Output } from '../../udpa/annotations/VersioningAnnotation'; +import type { MigrateAnnotation as _udpa_annotations_MigrateAnnotation, MigrateAnnotation__Output as _udpa_annotations_MigrateAnnotation__Output } from '../../udpa/annotations/MigrateAnnotation'; export interface MessageOptions { 'messageSetWireFormat'?: (boolean); @@ -9,6 +11,8 @@ export interface MessageOptions { 'mapEntry'?: (boolean); 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; '.validate.disabled'?: (boolean); + '.udpa.annotations.versioning'?: (_udpa_annotations_VersioningAnnotation | null); + '.udpa.annotations.message_migrate'?: (_udpa_annotations_MigrateAnnotation | null); } export interface MessageOptions__Output { @@ -18,4 +22,6 @@ export interface MessageOptions__Output { 'mapEntry': (boolean); 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; '.validate.disabled': (boolean); + '.udpa.annotations.versioning': (_udpa_annotations_VersioningAnnotation__Output | null); + '.udpa.annotations.message_migrate': (_udpa_annotations_MigrateAnnotation__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/MethodDescriptorProto.ts b/packages/grpc-js-xds/src/generated/google/protobuf/MethodDescriptorProto.ts index bc2f0afb5..c76c0ea23 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/MethodDescriptorProto.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/MethodDescriptorProto.ts @@ -6,7 +6,7 @@ export interface MethodDescriptorProto { 'name'?: (string); 'inputType'?: (string); 'outputType'?: (string); - 'options'?: (_google_protobuf_MethodOptions); + 'options'?: (_google_protobuf_MethodOptions | null); 'clientStreaming'?: (boolean); 'serverStreaming'?: (boolean); } @@ -15,7 +15,7 @@ export interface MethodDescriptorProto__Output { 'name': (string); 'inputType': (string); 'outputType': (string); - 'options'?: (_google_protobuf_MethodOptions__Output); + 'options': (_google_protobuf_MethodOptions__Output | null); 'clientStreaming': (boolean); 'serverStreaming': (boolean); } diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/OneofDescriptorProto.ts b/packages/grpc-js-xds/src/generated/google/protobuf/OneofDescriptorProto.ts index c10ccecd3..636f13ed4 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/OneofDescriptorProto.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/OneofDescriptorProto.ts @@ -4,10 +4,10 @@ import type { OneofOptions as _google_protobuf_OneofOptions, OneofOptions__Outpu export interface OneofDescriptorProto { 'name'?: (string); - 'options'?: (_google_protobuf_OneofOptions); + 'options'?: (_google_protobuf_OneofOptions | null); } export interface OneofDescriptorProto__Output { 'name': (string); - 'options'?: (_google_protobuf_OneofOptions__Output); + 'options': (_google_protobuf_OneofOptions__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/ServiceDescriptorProto.ts b/packages/grpc-js-xds/src/generated/google/protobuf/ServiceDescriptorProto.ts index 695a8775c..40c9263ea 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/ServiceDescriptorProto.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/ServiceDescriptorProto.ts @@ -6,11 +6,11 @@ import type { ServiceOptions as _google_protobuf_ServiceOptions, ServiceOptions_ export interface ServiceDescriptorProto { 'name'?: (string); 'method'?: (_google_protobuf_MethodDescriptorProto)[]; - 'options'?: (_google_protobuf_ServiceOptions); + 'options'?: (_google_protobuf_ServiceOptions | null); } export interface ServiceDescriptorProto__Output { 'name': (string); 'method': (_google_protobuf_MethodDescriptorProto__Output)[]; - 'options'?: (_google_protobuf_ServiceOptions__Output); + 'options': (_google_protobuf_ServiceOptions__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/Struct.ts b/packages/grpc-js-xds/src/generated/google/protobuf/Struct.ts index 9919350e4..41b79eab3 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/Struct.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/Struct.ts @@ -7,5 +7,5 @@ export interface Struct { } export interface Struct__Output { - 'fields'?: ({[key: string]: _google_protobuf_Value__Output}); + 'fields': ({[key: string]: _google_protobuf_Value__Output}); } 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 0860535dc..b1a942a56 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/Value.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/Value.ts @@ -9,8 +9,8 @@ export interface Value { 'numberValue'?: (number | string); 'stringValue'?: (string); 'boolValue'?: (boolean); - 'structValue'?: (_google_protobuf_Struct); - 'listValue'?: (_google_protobuf_ListValue); + 'structValue'?: (_google_protobuf_Struct | null); + 'listValue'?: (_google_protobuf_ListValue | null); 'kind'?: "nullValue"|"numberValue"|"stringValue"|"boolValue"|"structValue"|"listValue"; } @@ -19,7 +19,7 @@ export interface Value__Output { 'numberValue'?: (number); 'stringValue'?: (string); 'boolValue'?: (boolean); - 'structValue'?: (_google_protobuf_Struct__Output); - 'listValue'?: (_google_protobuf_ListValue__Output); + 'structValue'?: (_google_protobuf_Struct__Output | null); + 'listValue'?: (_google_protobuf_ListValue__Output | null); 'kind': "nullValue"|"numberValue"|"stringValue"|"boolValue"|"structValue"|"listValue"; } diff --git a/packages/grpc-js-xds/src/generated/http_connection_manager.ts b/packages/grpc-js-xds/src/generated/http_connection_manager.ts index 9cb81bb0e..bb4e80360 100644 --- a/packages/grpc-js-xds/src/generated/http_connection_manager.ts +++ b/packages/grpc-js-xds/src/generated/http_connection_manager.ts @@ -1,5 +1,5 @@ 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'; type SubtypeConstructor any, Subtype> = { diff --git a/packages/grpc-js-xds/src/generated/listener.ts b/packages/grpc-js-xds/src/generated/listener.ts index 69454efdc..cf7297a5b 100644 --- a/packages/grpc-js-xds/src/generated/listener.ts +++ b/packages/grpc-js-xds/src/generated/listener.ts @@ -1,5 +1,5 @@ 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'; type SubtypeConstructor any, Subtype> = { diff --git a/packages/grpc-js-xds/src/generated/lrs.ts b/packages/grpc-js-xds/src/generated/lrs.ts index 9a2864fcf..929fd6914 100644 --- a/packages/grpc-js-xds/src/generated/lrs.ts +++ b/packages/grpc-js-xds/src/generated/lrs.ts @@ -1,8 +1,8 @@ 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 { LoadReportingServiceClient as _envoy_service_load_stats_v2_LoadReportingServiceClient } from './envoy/service/load_stats/v2/LoadReportingService'; -import type { LoadReportingServiceClient as _envoy_service_load_stats_v3_LoadReportingServiceClient } from './envoy/service/load_stats/v3/LoadReportingService'; +import type { LoadReportingServiceClient as _envoy_service_load_stats_v2_LoadReportingServiceClient, LoadReportingServiceDefinition as _envoy_service_load_stats_v2_LoadReportingServiceDefinition } from './envoy/service/load_stats/v2/LoadReportingService'; +import type { LoadReportingServiceClient as _envoy_service_load_stats_v3_LoadReportingServiceClient, LoadReportingServiceDefinition as _envoy_service_load_stats_v3_LoadReportingServiceDefinition } from './envoy/service/load_stats/v3/LoadReportingService'; type SubtypeConstructor any, Subtype> = { new(...args: ConstructorParameters): Subtype; @@ -102,12 +102,12 @@ export interface ProtoGrpcType { service: { load_stats: { v2: { - LoadReportingService: SubtypeConstructor & { service: ServiceDefinition } + LoadReportingService: SubtypeConstructor & { service: _envoy_service_load_stats_v2_LoadReportingServiceDefinition } LoadStatsRequest: MessageTypeDefinition LoadStatsResponse: MessageTypeDefinition } v3: { - LoadReportingService: SubtypeConstructor & { service: ServiceDefinition } + LoadReportingService: SubtypeConstructor & { service: _envoy_service_load_stats_v3_LoadReportingServiceDefinition } LoadStatsRequest: MessageTypeDefinition LoadStatsResponse: MessageTypeDefinition } diff --git a/packages/grpc-js-xds/src/generated/route.ts b/packages/grpc-js-xds/src/generated/route.ts index a51060779..702395d19 100644 --- a/packages/grpc-js-xds/src/generated/route.ts +++ b/packages/grpc-js-xds/src/generated/route.ts @@ -1,5 +1,5 @@ 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'; type SubtypeConstructor any, Subtype> = { diff --git a/packages/grpc-js-xds/src/generated/typed_struct.ts b/packages/grpc-js-xds/src/generated/typed_struct.ts index 78d781a29..47abe063c 100644 --- a/packages/grpc-js-xds/src/generated/typed_struct.ts +++ b/packages/grpc-js-xds/src/generated/typed_struct.ts @@ -1,5 +1,5 @@ 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'; type SubtypeConstructor any, Subtype> = { diff --git a/packages/grpc-js-xds/src/generated/udpa/type/v1/TypedStruct.ts b/packages/grpc-js-xds/src/generated/udpa/type/v1/TypedStruct.ts index f9d842982..435872808 100644 --- a/packages/grpc-js-xds/src/generated/udpa/type/v1/TypedStruct.ts +++ b/packages/grpc-js-xds/src/generated/udpa/type/v1/TypedStruct.ts @@ -36,7 +36,7 @@ export interface TypedStruct { /** * A JSON representation of the above specified type. */ - 'value'?: (_google_protobuf_Struct); + 'value'?: (_google_protobuf_Struct | null); } /** @@ -73,5 +73,5 @@ export interface TypedStruct__Output { /** * A JSON representation of the above specified type. */ - 'value'?: (_google_protobuf_Struct__Output); + 'value': (_google_protobuf_Struct__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/validate/DurationRules.ts b/packages/grpc-js-xds/src/generated/validate/DurationRules.ts index 86b80a34d..879928e20 100644 --- a/packages/grpc-js-xds/src/generated/validate/DurationRules.ts +++ b/packages/grpc-js-xds/src/generated/validate/DurationRules.ts @@ -14,27 +14,27 @@ export interface DurationRules { /** * Const specifies that this field must be exactly the specified value */ - 'const'?: (_google_protobuf_Duration); + 'const'?: (_google_protobuf_Duration | null); /** * Lt specifies that this field must be less than the specified value, * exclusive */ - 'lt'?: (_google_protobuf_Duration); + 'lt'?: (_google_protobuf_Duration | null); /** * Lt specifies that this field must be less than the specified value, * inclusive */ - 'lte'?: (_google_protobuf_Duration); + 'lte'?: (_google_protobuf_Duration | null); /** * Gt specifies that this field must be greater than the specified value, * exclusive */ - 'gt'?: (_google_protobuf_Duration); + 'gt'?: (_google_protobuf_Duration | null); /** * Gte specifies that this field must be greater than the specified value, * inclusive */ - 'gte'?: (_google_protobuf_Duration); + 'gte'?: (_google_protobuf_Duration | null); /** * In specifies that this field must be equal to one of the specified * values @@ -59,27 +59,27 @@ export interface DurationRules__Output { /** * Const specifies that this field must be exactly the specified value */ - 'const'?: (_google_protobuf_Duration__Output); + 'const': (_google_protobuf_Duration__Output | null); /** * Lt specifies that this field must be less than the specified value, * exclusive */ - 'lt'?: (_google_protobuf_Duration__Output); + 'lt': (_google_protobuf_Duration__Output | null); /** * Lt specifies that this field must be less than the specified value, * inclusive */ - 'lte'?: (_google_protobuf_Duration__Output); + 'lte': (_google_protobuf_Duration__Output | null); /** * Gt specifies that this field must be greater than the specified value, * exclusive */ - 'gt'?: (_google_protobuf_Duration__Output); + 'gt': (_google_protobuf_Duration__Output | null); /** * Gte specifies that this field must be greater than the specified value, * inclusive */ - 'gte'?: (_google_protobuf_Duration__Output); + 'gte': (_google_protobuf_Duration__Output | null); /** * In specifies that this field must be equal to one of the specified * values diff --git a/packages/grpc-js-xds/src/generated/validate/FieldRules.ts b/packages/grpc-js-xds/src/generated/validate/FieldRules.ts index dae124bc1..067125775 100644 --- a/packages/grpc-js-xds/src/generated/validate/FieldRules.ts +++ b/packages/grpc-js-xds/src/generated/validate/FieldRules.ts @@ -32,34 +32,34 @@ export interface FieldRules { /** * Scalar Field Types */ - 'float'?: (_validate_FloatRules); - 'double'?: (_validate_DoubleRules); - 'int32'?: (_validate_Int32Rules); - 'int64'?: (_validate_Int64Rules); - 'uint32'?: (_validate_UInt32Rules); - 'uint64'?: (_validate_UInt64Rules); - 'sint32'?: (_validate_SInt32Rules); - 'sint64'?: (_validate_SInt64Rules); - 'fixed32'?: (_validate_Fixed32Rules); - 'fixed64'?: (_validate_Fixed64Rules); - 'sfixed32'?: (_validate_SFixed32Rules); - 'sfixed64'?: (_validate_SFixed64Rules); - 'bool'?: (_validate_BoolRules); - 'string'?: (_validate_StringRules); - 'bytes'?: (_validate_BytesRules); + 'float'?: (_validate_FloatRules | null); + 'double'?: (_validate_DoubleRules | null); + 'int32'?: (_validate_Int32Rules | null); + 'int64'?: (_validate_Int64Rules | null); + 'uint32'?: (_validate_UInt32Rules | null); + 'uint64'?: (_validate_UInt64Rules | null); + 'sint32'?: (_validate_SInt32Rules | null); + 'sint64'?: (_validate_SInt64Rules | null); + 'fixed32'?: (_validate_Fixed32Rules | null); + 'fixed64'?: (_validate_Fixed64Rules | null); + 'sfixed32'?: (_validate_SFixed32Rules | null); + 'sfixed64'?: (_validate_SFixed64Rules | null); + 'bool'?: (_validate_BoolRules | null); + 'string'?: (_validate_StringRules | null); + 'bytes'?: (_validate_BytesRules | null); /** * Complex Field Types */ - 'enum'?: (_validate_EnumRules); - 'message'?: (_validate_MessageRules); - 'repeated'?: (_validate_RepeatedRules); - 'map'?: (_validate_MapRules); + 'enum'?: (_validate_EnumRules | null); + 'message'?: (_validate_MessageRules | null); + 'repeated'?: (_validate_RepeatedRules | null); + 'map'?: (_validate_MapRules | null); /** * Well-Known Field Types */ - 'any'?: (_validate_AnyRules); - 'duration'?: (_validate_DurationRules); - 'timestamp'?: (_validate_TimestampRules); + 'any'?: (_validate_AnyRules | null); + 'duration'?: (_validate_DurationRules | null); + 'timestamp'?: (_validate_TimestampRules | null); 'type'?: "float"|"double"|"int32"|"int64"|"uint32"|"uint64"|"sint32"|"sint64"|"fixed32"|"fixed64"|"sfixed32"|"sfixed64"|"bool"|"string"|"bytes"|"enum"|"repeated"|"map"|"any"|"duration"|"timestamp"; } @@ -71,33 +71,33 @@ export interface FieldRules__Output { /** * Scalar Field Types */ - 'float'?: (_validate_FloatRules__Output); - 'double'?: (_validate_DoubleRules__Output); - 'int32'?: (_validate_Int32Rules__Output); - 'int64'?: (_validate_Int64Rules__Output); - 'uint32'?: (_validate_UInt32Rules__Output); - 'uint64'?: (_validate_UInt64Rules__Output); - 'sint32'?: (_validate_SInt32Rules__Output); - 'sint64'?: (_validate_SInt64Rules__Output); - 'fixed32'?: (_validate_Fixed32Rules__Output); - 'fixed64'?: (_validate_Fixed64Rules__Output); - 'sfixed32'?: (_validate_SFixed32Rules__Output); - 'sfixed64'?: (_validate_SFixed64Rules__Output); - 'bool'?: (_validate_BoolRules__Output); - 'string'?: (_validate_StringRules__Output); - 'bytes'?: (_validate_BytesRules__Output); + 'float'?: (_validate_FloatRules__Output | null); + 'double'?: (_validate_DoubleRules__Output | null); + 'int32'?: (_validate_Int32Rules__Output | null); + 'int64'?: (_validate_Int64Rules__Output | null); + 'uint32'?: (_validate_UInt32Rules__Output | null); + 'uint64'?: (_validate_UInt64Rules__Output | null); + 'sint32'?: (_validate_SInt32Rules__Output | null); + 'sint64'?: (_validate_SInt64Rules__Output | null); + 'fixed32'?: (_validate_Fixed32Rules__Output | null); + 'fixed64'?: (_validate_Fixed64Rules__Output | null); + 'sfixed32'?: (_validate_SFixed32Rules__Output | null); + 'sfixed64'?: (_validate_SFixed64Rules__Output | null); + 'bool'?: (_validate_BoolRules__Output | null); + 'string'?: (_validate_StringRules__Output | null); + 'bytes'?: (_validate_BytesRules__Output | null); /** * Complex Field Types */ - 'enum'?: (_validate_EnumRules__Output); - 'message'?: (_validate_MessageRules__Output); - 'repeated'?: (_validate_RepeatedRules__Output); - 'map'?: (_validate_MapRules__Output); + 'enum'?: (_validate_EnumRules__Output | null); + 'message': (_validate_MessageRules__Output | null); + 'repeated'?: (_validate_RepeatedRules__Output | null); + 'map'?: (_validate_MapRules__Output | null); /** * Well-Known Field Types */ - 'any'?: (_validate_AnyRules__Output); - 'duration'?: (_validate_DurationRules__Output); - 'timestamp'?: (_validate_TimestampRules__Output); + 'any'?: (_validate_AnyRules__Output | null); + 'duration'?: (_validate_DurationRules__Output | null); + 'timestamp'?: (_validate_TimestampRules__Output | null); 'type': "float"|"double"|"int32"|"int64"|"uint32"|"uint64"|"sint32"|"sint64"|"fixed32"|"fixed64"|"sfixed32"|"sfixed64"|"bool"|"string"|"bytes"|"enum"|"repeated"|"map"|"any"|"duration"|"timestamp"; } diff --git a/packages/grpc-js-xds/src/generated/validate/MapRules.ts b/packages/grpc-js-xds/src/generated/validate/MapRules.ts index 0c89bf2b3..7efe5b390 100644 --- a/packages/grpc-js-xds/src/generated/validate/MapRules.ts +++ b/packages/grpc-js-xds/src/generated/validate/MapRules.ts @@ -25,13 +25,13 @@ export interface MapRules { /** * Keys specifies the constraints to be applied to each key in the field. */ - 'keys'?: (_validate_FieldRules); + 'keys'?: (_validate_FieldRules | null); /** * Values specifies the constraints to be applied to the value of each key * in the field. Message values will still have their validations evaluated * unless skip is specified here. */ - 'values'?: (_validate_FieldRules); + 'values'?: (_validate_FieldRules | null); } /** @@ -56,11 +56,11 @@ export interface MapRules__Output { /** * Keys specifies the constraints to be applied to each key in the field. */ - 'keys'?: (_validate_FieldRules__Output); + 'keys': (_validate_FieldRules__Output | null); /** * Values specifies the constraints to be applied to the value of each key * in the field. Message values will still have their validations evaluated * unless skip is specified here. */ - 'values'?: (_validate_FieldRules__Output); + 'values': (_validate_FieldRules__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/validate/RepeatedRules.ts b/packages/grpc-js-xds/src/generated/validate/RepeatedRules.ts index 1f6d4f0ff..d347b6497 100644 --- a/packages/grpc-js-xds/src/generated/validate/RepeatedRules.ts +++ b/packages/grpc-js-xds/src/generated/validate/RepeatedRules.ts @@ -28,7 +28,7 @@ export interface RepeatedRules { * Repeated message fields will still execute validation against each item * unless skip is specified here. */ - 'items'?: (_validate_FieldRules); + 'items'?: (_validate_FieldRules | null); } /** @@ -56,5 +56,5 @@ export interface RepeatedRules__Output { * Repeated message fields will still execute validation against each item * unless skip is specified here. */ - 'items'?: (_validate_FieldRules__Output); + 'items': (_validate_FieldRules__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/validate/TimestampRules.ts b/packages/grpc-js-xds/src/generated/validate/TimestampRules.ts index 9436cc8ee..69d548126 100644 --- a/packages/grpc-js-xds/src/generated/validate/TimestampRules.ts +++ b/packages/grpc-js-xds/src/generated/validate/TimestampRules.ts @@ -15,27 +15,27 @@ export interface TimestampRules { /** * Const specifies that this field must be exactly the specified value */ - 'const'?: (_google_protobuf_Timestamp); + 'const'?: (_google_protobuf_Timestamp | null); /** * Lt specifies that this field must be less than the specified value, * exclusive */ - 'lt'?: (_google_protobuf_Timestamp); + 'lt'?: (_google_protobuf_Timestamp | null); /** * Lte specifies that this field must be less than the specified value, * inclusive */ - 'lte'?: (_google_protobuf_Timestamp); + 'lte'?: (_google_protobuf_Timestamp | null); /** * Gt specifies that this field must be greater than the specified value, * exclusive */ - 'gt'?: (_google_protobuf_Timestamp); + 'gt'?: (_google_protobuf_Timestamp | null); /** * Gte specifies that this field must be greater than the specified value, * inclusive */ - 'gte'?: (_google_protobuf_Timestamp); + 'gte'?: (_google_protobuf_Timestamp | null); /** * LtNow specifies that this must be less than the current time. LtNow * can only be used with the Within rule. @@ -51,7 +51,7 @@ export interface TimestampRules { * current time. This constraint can be used alone or with the LtNow and * GtNow rules. */ - 'within'?: (_google_protobuf_Duration); + 'within'?: (_google_protobuf_Duration | null); } /** @@ -66,27 +66,27 @@ export interface TimestampRules__Output { /** * Const specifies that this field must be exactly the specified value */ - 'const'?: (_google_protobuf_Timestamp__Output); + 'const': (_google_protobuf_Timestamp__Output | null); /** * Lt specifies that this field must be less than the specified value, * exclusive */ - 'lt'?: (_google_protobuf_Timestamp__Output); + 'lt': (_google_protobuf_Timestamp__Output | null); /** * Lte specifies that this field must be less than the specified value, * inclusive */ - 'lte'?: (_google_protobuf_Timestamp__Output); + 'lte': (_google_protobuf_Timestamp__Output | null); /** * Gt specifies that this field must be greater than the specified value, * exclusive */ - 'gt'?: (_google_protobuf_Timestamp__Output); + 'gt': (_google_protobuf_Timestamp__Output | null); /** * Gte specifies that this field must be greater than the specified value, * inclusive */ - 'gte'?: (_google_protobuf_Timestamp__Output); + 'gte': (_google_protobuf_Timestamp__Output | null); /** * LtNow specifies that this must be less than the current time. LtNow * can only be used with the Within rule. @@ -102,5 +102,5 @@ export interface TimestampRules__Output { * current time. This constraint can be used alone or with the LtNow and * GtNow rules. */ - 'within'?: (_google_protobuf_Duration__Output); + 'within': (_google_protobuf_Duration__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/xds/core/v3/CollectionEntry.ts b/packages/grpc-js-xds/src/generated/xds/core/v3/CollectionEntry.ts index 4a9a45527..8d583d961 100644 --- a/packages/grpc-js-xds/src/generated/xds/core/v3/CollectionEntry.ts +++ b/packages/grpc-js-xds/src/generated/xds/core/v3/CollectionEntry.ts @@ -22,7 +22,7 @@ export interface _xds_core_v3_CollectionEntry_InlineEntry { /** * The resource payload, including type URL. */ - 'resource'?: (_google_protobuf_Any); + 'resource'?: (_google_protobuf_Any | null); } /** @@ -44,7 +44,7 @@ export interface _xds_core_v3_CollectionEntry_InlineEntry__Output { /** * The resource payload, including type URL. */ - 'resource'?: (_google_protobuf_Any__Output); + 'resource': (_google_protobuf_Any__Output | null); } /** @@ -60,11 +60,11 @@ export interface CollectionEntry { /** * A resource locator describing how the member resource is to be located. */ - 'locator'?: (_xds_core_v3_ResourceLocator); + 'locator'?: (_xds_core_v3_ResourceLocator | null); /** * The resource is inlined in the list collection. */ - 'inline_entry'?: (_xds_core_v3_CollectionEntry_InlineEntry); + 'inline_entry'?: (_xds_core_v3_CollectionEntry_InlineEntry | null); 'resource_specifier'?: "locator"|"inline_entry"; } @@ -81,10 +81,10 @@ export interface CollectionEntry__Output { /** * A resource locator describing how the member resource is to be located. */ - 'locator'?: (_xds_core_v3_ResourceLocator__Output); + 'locator'?: (_xds_core_v3_ResourceLocator__Output | null); /** * The resource is inlined in the list collection. */ - 'inline_entry'?: (_xds_core_v3_CollectionEntry_InlineEntry__Output); + 'inline_entry'?: (_xds_core_v3_CollectionEntry_InlineEntry__Output | null); 'resource_specifier': "locator"|"inline_entry"; } 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 f28a31d20..2b314d8bb 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 @@ -37,7 +37,7 @@ export interface _xds_core_v3_ResourceLocator_Directive { * resource, it will fallback to `bar`. Alternative resources do not need * to have equivalent content, but they should be functional substitutes. */ - 'alt'?: (_xds_core_v3_ResourceLocator); + 'alt'?: (_xds_core_v3_ResourceLocator | null); /** * List collections support inlining of resources via the entry field in * Resource. These inlined Resource objects may have an optional name @@ -83,7 +83,7 @@ export interface _xds_core_v3_ResourceLocator_Directive__Output { * resource, it will fallback to `bar`. Alternative resources do not need * to have equivalent content, but they should be functional substitutes. */ - 'alt'?: (_xds_core_v3_ResourceLocator__Output); + 'alt'?: (_xds_core_v3_ResourceLocator__Output | null); /** * List collections support inlining of resources via the entry field in * Resource. These inlined Resource objects may have an optional name @@ -150,7 +150,7 @@ export interface ResourceLocator { * there must be no additional context parameters set on the matched * resource. */ - 'exact_context'?: (_xds_core_v3_ContextParams); + 'exact_context'?: (_xds_core_v3_ContextParams | null); /** * A list of directives that appear in the xDS resource locator #fragment. * @@ -208,7 +208,7 @@ export interface ResourceLocator__Output { * there must be no additional context parameters set on the matched * resource. */ - 'exact_context'?: (_xds_core_v3_ContextParams__Output); + 'exact_context'?: (_xds_core_v3_ContextParams__Output | null); /** * A list of directives that appear in the xDS resource locator #fragment. * From 8718d7d4761efa8c74948ac2a6e52aa735c6ce3e Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 3 Aug 2021 14:59:38 -0700 Subject: [PATCH 056/450] grpc-js-xds: Generate files for fault injection --- .../filters/common/fault/v3/FaultDelay.ts | 81 +++++++ .../filters/common/fault/v3/FaultRateLimit.ts | 78 +++++++ .../filters/http/fault/v3/FaultAbort.ts | 67 ++++++ .../filters/http/fault/v3/HTTPFault.ts | 213 +++++++++++++++++ packages/grpc-js-xds/src/generated/fault.ts | 220 ++++++++++++++++++ 5 files changed, 659 insertions(+) create mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/filters/common/fault/v3/FaultDelay.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/filters/common/fault/v3/FaultRateLimit.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/filters/http/fault/v3/FaultAbort.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/filters/http/fault/v3/HTTPFault.ts create mode 100644 packages/grpc-js-xds/src/generated/fault.ts 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 new file mode 100644 index 000000000..8e2739958 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/common/fault/v3/FaultDelay.ts @@ -0,0 +1,81 @@ +// Original file: deps/envoy-api/envoy/extensions/filters/common/fault/v3/fault.proto + +import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../../../google/protobuf/Duration'; +import type { FractionalPercent as _envoy_type_v3_FractionalPercent, FractionalPercent__Output as _envoy_type_v3_FractionalPercent__Output } from '../../../../../../envoy/type/v3/FractionalPercent'; + +// Original file: deps/envoy-api/envoy/extensions/filters/common/fault/v3/fault.proto + +export enum _envoy_extensions_filters_common_fault_v3_FaultDelay_FaultDelayType { + /** + * Unused and deprecated. + */ + FIXED = 0, +} + +/** + * Fault delays are controlled via an HTTP header (if applicable). See the + * :ref:`HTTP fault filter ` documentation for + * more information. + */ +export interface _envoy_extensions_filters_common_fault_v3_FaultDelay_HeaderDelay { +} + +/** + * Fault delays are controlled via an HTTP header (if applicable). See the + * :ref:`HTTP fault filter ` documentation for + * more information. + */ +export interface _envoy_extensions_filters_common_fault_v3_FaultDelay_HeaderDelay__Output { +} + +/** + * Delay specification is used to inject latency into the + * HTTP/gRPC/Mongo/Redis operation or delay proxying of TCP connections. + * [#next-free-field: 6] + */ +export interface FaultDelay { + /** + * Add a fixed delay before forwarding the operation upstream. See + * https://developers.google.com/protocol-buffers/docs/proto3#json for + * the JSON/YAML Duration mapping. For HTTP/Mongo/Redis, the specified + * delay will be injected before a new request/operation. For TCP + * connections, the proxying of the connection upstream will be delayed + * for the specified period. This is required if type is FIXED. + */ + 'fixed_delay'?: (_google_protobuf_Duration | null); + /** + * The percentage of operations/connections/requests on which the delay will be injected. + */ + 'percentage'?: (_envoy_type_v3_FractionalPercent | null); + /** + * Fault delays are controlled via an HTTP header (if applicable). + */ + 'header_delay'?: (_envoy_extensions_filters_common_fault_v3_FaultDelay_HeaderDelay | null); + 'fault_delay_secifier'?: "fixed_delay"|"header_delay"; +} + +/** + * Delay specification is used to inject latency into the + * HTTP/gRPC/Mongo/Redis operation or delay proxying of TCP connections. + * [#next-free-field: 6] + */ +export interface FaultDelay__Output { + /** + * Add a fixed delay before forwarding the operation upstream. See + * https://developers.google.com/protocol-buffers/docs/proto3#json for + * the JSON/YAML Duration mapping. For HTTP/Mongo/Redis, the specified + * delay will be injected before a new request/operation. For TCP + * connections, the proxying of the connection upstream will be delayed + * for the specified period. This is required if type is FIXED. + */ + 'fixed_delay'?: (_google_protobuf_Duration__Output | null); + /** + * The percentage of operations/connections/requests on which the delay will be injected. + */ + 'percentage': (_envoy_type_v3_FractionalPercent__Output | null); + /** + * Fault delays are controlled via an HTTP header (if applicable). + */ + 'header_delay'?: (_envoy_extensions_filters_common_fault_v3_FaultDelay_HeaderDelay__Output | null); + 'fault_delay_secifier': "fixed_delay"|"header_delay"; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/common/fault/v3/FaultRateLimit.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/common/fault/v3/FaultRateLimit.ts new file mode 100644 index 000000000..4df7395bb --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/common/fault/v3/FaultRateLimit.ts @@ -0,0 +1,78 @@ +// Original file: deps/envoy-api/envoy/extensions/filters/common/fault/v3/fault.proto + +import type { FractionalPercent as _envoy_type_v3_FractionalPercent, FractionalPercent__Output as _envoy_type_v3_FractionalPercent__Output } from '../../../../../../envoy/type/v3/FractionalPercent'; +import type { Long } from '@grpc/proto-loader'; + +/** + * Describes a fixed/constant rate limit. + */ +export interface _envoy_extensions_filters_common_fault_v3_FaultRateLimit_FixedLimit { + /** + * The limit supplied in KiB/s. + */ + 'limit_kbps'?: (number | string | Long); +} + +/** + * Describes a fixed/constant rate limit. + */ +export interface _envoy_extensions_filters_common_fault_v3_FaultRateLimit_FixedLimit__Output { + /** + * The limit supplied in KiB/s. + */ + 'limit_kbps': (string); +} + +/** + * Rate limits are controlled via an HTTP header (if applicable). See the + * :ref:`HTTP fault filter ` documentation for + * more information. + */ +export interface _envoy_extensions_filters_common_fault_v3_FaultRateLimit_HeaderLimit { +} + +/** + * Rate limits are controlled via an HTTP header (if applicable). See the + * :ref:`HTTP fault filter ` documentation for + * more information. + */ +export interface _envoy_extensions_filters_common_fault_v3_FaultRateLimit_HeaderLimit__Output { +} + +/** + * Describes a rate limit to be applied. + */ +export interface FaultRateLimit { + /** + * A fixed rate limit. + */ + 'fixed_limit'?: (_envoy_extensions_filters_common_fault_v3_FaultRateLimit_FixedLimit | null); + /** + * The percentage of operations/connections/requests on which the rate limit will be injected. + */ + 'percentage'?: (_envoy_type_v3_FractionalPercent | null); + /** + * Rate limits are controlled via an HTTP header (if applicable). + */ + 'header_limit'?: (_envoy_extensions_filters_common_fault_v3_FaultRateLimit_HeaderLimit | null); + 'limit_type'?: "fixed_limit"|"header_limit"; +} + +/** + * Describes a rate limit to be applied. + */ +export interface FaultRateLimit__Output { + /** + * A fixed rate limit. + */ + 'fixed_limit'?: (_envoy_extensions_filters_common_fault_v3_FaultRateLimit_FixedLimit__Output | null); + /** + * The percentage of operations/connections/requests on which the rate limit will be injected. + */ + 'percentage': (_envoy_type_v3_FractionalPercent__Output | null); + /** + * Rate limits are controlled via an HTTP header (if applicable). + */ + 'header_limit'?: (_envoy_extensions_filters_common_fault_v3_FaultRateLimit_HeaderLimit__Output | null); + 'limit_type': "fixed_limit"|"header_limit"; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/http/fault/v3/FaultAbort.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/http/fault/v3/FaultAbort.ts new file mode 100644 index 000000000..823706cb7 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/http/fault/v3/FaultAbort.ts @@ -0,0 +1,67 @@ +// Original file: deps/envoy-api/envoy/extensions/filters/http/fault/v3/fault.proto + +import type { FractionalPercent as _envoy_type_v3_FractionalPercent, FractionalPercent__Output as _envoy_type_v3_FractionalPercent__Output } from '../../../../../../envoy/type/v3/FractionalPercent'; + +/** + * Fault aborts are controlled via an HTTP header (if applicable). See the + * :ref:`HTTP fault filter ` documentation for + * more information. + */ +export interface _envoy_extensions_filters_http_fault_v3_FaultAbort_HeaderAbort { +} + +/** + * Fault aborts are controlled via an HTTP header (if applicable). See the + * :ref:`HTTP fault filter ` documentation for + * more information. + */ +export interface _envoy_extensions_filters_http_fault_v3_FaultAbort_HeaderAbort__Output { +} + +/** + * [#next-free-field: 6] + */ +export interface FaultAbort { + /** + * HTTP status code to use to abort the HTTP request. + */ + 'http_status'?: (number); + /** + * The percentage of requests/operations/connections that will be aborted with the error code + * provided. + */ + 'percentage'?: (_envoy_type_v3_FractionalPercent | null); + /** + * Fault aborts are controlled via an HTTP header (if applicable). + */ + 'header_abort'?: (_envoy_extensions_filters_http_fault_v3_FaultAbort_HeaderAbort | null); + /** + * gRPC status code to use to abort the gRPC request. + */ + 'grpc_status'?: (number); + 'error_type'?: "http_status"|"grpc_status"|"header_abort"; +} + +/** + * [#next-free-field: 6] + */ +export interface FaultAbort__Output { + /** + * HTTP status code to use to abort the HTTP request. + */ + 'http_status'?: (number); + /** + * The percentage of requests/operations/connections that will be aborted with the error code + * provided. + */ + 'percentage': (_envoy_type_v3_FractionalPercent__Output | null); + /** + * Fault aborts are controlled via an HTTP header (if applicable). + */ + 'header_abort'?: (_envoy_extensions_filters_http_fault_v3_FaultAbort_HeaderAbort__Output | null); + /** + * gRPC status code to use to abort the gRPC request. + */ + 'grpc_status'?: (number); + 'error_type': "http_status"|"grpc_status"|"header_abort"; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/http/fault/v3/HTTPFault.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/http/fault/v3/HTTPFault.ts new file mode 100644 index 000000000..20c543508 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/http/fault/v3/HTTPFault.ts @@ -0,0 +1,213 @@ +// Original file: deps/envoy-api/envoy/extensions/filters/http/fault/v3/fault.proto + +import type { FaultDelay as _envoy_extensions_filters_common_fault_v3_FaultDelay, FaultDelay__Output as _envoy_extensions_filters_common_fault_v3_FaultDelay__Output } from '../../../../../../envoy/extensions/filters/common/fault/v3/FaultDelay'; +import type { FaultAbort as _envoy_extensions_filters_http_fault_v3_FaultAbort, FaultAbort__Output as _envoy_extensions_filters_http_fault_v3_FaultAbort__Output } from '../../../../../../envoy/extensions/filters/http/fault/v3/FaultAbort'; +import type { HeaderMatcher as _envoy_config_route_v3_HeaderMatcher, HeaderMatcher__Output as _envoy_config_route_v3_HeaderMatcher__Output } from '../../../../../../envoy/config/route/v3/HeaderMatcher'; +import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../../../google/protobuf/UInt32Value'; +import type { FaultRateLimit as _envoy_extensions_filters_common_fault_v3_FaultRateLimit, FaultRateLimit__Output as _envoy_extensions_filters_common_fault_v3_FaultRateLimit__Output } from '../../../../../../envoy/extensions/filters/common/fault/v3/FaultRateLimit'; + +/** + * [#next-free-field: 15] + */ +export interface HTTPFault { + /** + * If specified, the filter will inject delays based on the values in the + * object. + */ + 'delay'?: (_envoy_extensions_filters_common_fault_v3_FaultDelay | null); + /** + * If specified, the filter will abort requests based on the values in + * the object. At least *abort* or *delay* must be specified. + */ + 'abort'?: (_envoy_extensions_filters_http_fault_v3_FaultAbort | null); + /** + * Specifies the name of the (destination) upstream cluster that the + * filter should match on. Fault injection will be restricted to requests + * bound to the specific upstream cluster. + */ + 'upstream_cluster'?: (string); + /** + * Specifies a set of headers that the filter should match on. The fault + * injection filter can be applied selectively to requests that match a set of + * headers specified in the fault filter config. The chances of actual fault + * injection further depend on the value of the :ref:`percentage + * ` field. + * The filter will check the request's headers against all the specified + * headers in the filter config. A match will happen if all the headers in the + * config are present in the request with the same values (or based on + * presence if the *value* field is not in the config). + */ + 'headers'?: (_envoy_config_route_v3_HeaderMatcher)[]; + /** + * Faults are injected for the specified list of downstream hosts. If this + * setting is not set, faults are injected for all downstream nodes. + * Downstream node name is taken from :ref:`the HTTP + * x-envoy-downstream-service-node + * ` header and compared + * against downstream_nodes list. + */ + 'downstream_nodes'?: (string)[]; + /** + * The maximum number of faults that can be active at a single time via the configured fault + * filter. Note that because this setting can be overridden at the route level, it's possible + * for the number of active faults to be greater than this value (if injected via a different + * route). If not specified, defaults to unlimited. This setting can be overridden via + * `runtime ` and any faults that are not injected + * due to overflow will be indicated via the `faults_overflow + * ` stat. + * + * .. attention:: + * Like other :ref:`circuit breakers ` in Envoy, this is a fuzzy + * limit. It's possible for the number of active faults to rise slightly above the configured + * amount due to the implementation details. + */ + 'max_active_faults'?: (_google_protobuf_UInt32Value | null); + /** + * The response rate limit to be applied to the response body of the stream. When configured, + * the percentage can be overridden by the :ref:`fault.http.rate_limit.response_percent + * ` runtime key. + * + * .. attention:: + * This is a per-stream limit versus a connection level limit. This means that concurrent streams + * will each get an independent limit. + */ + 'response_rate_limit'?: (_envoy_extensions_filters_common_fault_v3_FaultRateLimit | null); + /** + * The runtime key to override the :ref:`default ` + * runtime. The default is: fault.http.delay.fixed_delay_percent + */ + 'delay_percent_runtime'?: (string); + /** + * The runtime key to override the :ref:`default ` + * runtime. The default is: fault.http.abort.abort_percent + */ + 'abort_percent_runtime'?: (string); + /** + * The runtime key to override the :ref:`default ` + * runtime. The default is: fault.http.delay.fixed_duration_ms + */ + 'delay_duration_runtime'?: (string); + /** + * The runtime key to override the :ref:`default ` + * runtime. The default is: fault.http.abort.http_status + */ + 'abort_http_status_runtime'?: (string); + /** + * The runtime key to override the :ref:`default ` + * runtime. The default is: fault.http.max_active_faults + */ + 'max_active_faults_runtime'?: (string); + /** + * The runtime key to override the :ref:`default ` + * runtime. The default is: fault.http.rate_limit.response_percent + */ + 'response_rate_limit_percent_runtime'?: (string); + /** + * The runtime key to override the :ref:`default ` + * runtime. The default is: fault.http.abort.grpc_status + */ + 'abort_grpc_status_runtime'?: (string); +} + +/** + * [#next-free-field: 15] + */ +export interface HTTPFault__Output { + /** + * If specified, the filter will inject delays based on the values in the + * object. + */ + 'delay': (_envoy_extensions_filters_common_fault_v3_FaultDelay__Output | null); + /** + * If specified, the filter will abort requests based on the values in + * the object. At least *abort* or *delay* must be specified. + */ + 'abort': (_envoy_extensions_filters_http_fault_v3_FaultAbort__Output | null); + /** + * Specifies the name of the (destination) upstream cluster that the + * filter should match on. Fault injection will be restricted to requests + * bound to the specific upstream cluster. + */ + 'upstream_cluster': (string); + /** + * Specifies a set of headers that the filter should match on. The fault + * injection filter can be applied selectively to requests that match a set of + * headers specified in the fault filter config. The chances of actual fault + * injection further depend on the value of the :ref:`percentage + * ` field. + * The filter will check the request's headers against all the specified + * headers in the filter config. A match will happen if all the headers in the + * config are present in the request with the same values (or based on + * presence if the *value* field is not in the config). + */ + 'headers': (_envoy_config_route_v3_HeaderMatcher__Output)[]; + /** + * Faults are injected for the specified list of downstream hosts. If this + * setting is not set, faults are injected for all downstream nodes. + * Downstream node name is taken from :ref:`the HTTP + * x-envoy-downstream-service-node + * ` header and compared + * against downstream_nodes list. + */ + 'downstream_nodes': (string)[]; + /** + * The maximum number of faults that can be active at a single time via the configured fault + * filter. Note that because this setting can be overridden at the route level, it's possible + * for the number of active faults to be greater than this value (if injected via a different + * route). If not specified, defaults to unlimited. This setting can be overridden via + * `runtime ` and any faults that are not injected + * due to overflow will be indicated via the `faults_overflow + * ` stat. + * + * .. attention:: + * Like other :ref:`circuit breakers ` in Envoy, this is a fuzzy + * limit. It's possible for the number of active faults to rise slightly above the configured + * amount due to the implementation details. + */ + 'max_active_faults': (_google_protobuf_UInt32Value__Output | null); + /** + * The response rate limit to be applied to the response body of the stream. When configured, + * the percentage can be overridden by the :ref:`fault.http.rate_limit.response_percent + * ` runtime key. + * + * .. attention:: + * This is a per-stream limit versus a connection level limit. This means that concurrent streams + * will each get an independent limit. + */ + 'response_rate_limit': (_envoy_extensions_filters_common_fault_v3_FaultRateLimit__Output | null); + /** + * The runtime key to override the :ref:`default ` + * runtime. The default is: fault.http.delay.fixed_delay_percent + */ + 'delay_percent_runtime': (string); + /** + * The runtime key to override the :ref:`default ` + * runtime. The default is: fault.http.abort.abort_percent + */ + 'abort_percent_runtime': (string); + /** + * The runtime key to override the :ref:`default ` + * runtime. The default is: fault.http.delay.fixed_duration_ms + */ + 'delay_duration_runtime': (string); + /** + * The runtime key to override the :ref:`default ` + * runtime. The default is: fault.http.abort.http_status + */ + 'abort_http_status_runtime': (string); + /** + * The runtime key to override the :ref:`default ` + * runtime. The default is: fault.http.max_active_faults + */ + 'max_active_faults_runtime': (string); + /** + * The runtime key to override the :ref:`default ` + * runtime. The default is: fault.http.rate_limit.response_percent + */ + 'response_rate_limit_percent_runtime': (string); + /** + * The runtime key to override the :ref:`default ` + * runtime. The default is: fault.http.abort.grpc_status + */ + 'abort_grpc_status_runtime': (string); +} diff --git a/packages/grpc-js-xds/src/generated/fault.ts b/packages/grpc-js-xds/src/generated/fault.ts new file mode 100644 index 000000000..6eefcdfbd --- /dev/null +++ b/packages/grpc-js-xds/src/generated/fault.ts @@ -0,0 +1,220 @@ +import type * as grpc from '@grpc/grpc-js'; +import type { EnumTypeDefinition, MessageTypeDefinition } from '@grpc/proto-loader'; + + +type SubtypeConstructor any, Subtype> = { + new(...args: ConstructorParameters): Subtype; +}; + +export interface ProtoGrpcType { + envoy: { + annotations: { + } + config: { + core: { + v3: { + Address: MessageTypeDefinition + AggregatedConfigSource: MessageTypeDefinition + ApiConfigSource: MessageTypeDefinition + ApiVersion: EnumTypeDefinition + AsyncDataSource: MessageTypeDefinition + BackoffStrategy: MessageTypeDefinition + BindConfig: MessageTypeDefinition + BuildVersion: MessageTypeDefinition + CidrRange: MessageTypeDefinition + ConfigSource: MessageTypeDefinition + ControlPlane: MessageTypeDefinition + DataSource: MessageTypeDefinition + EnvoyInternalAddress: MessageTypeDefinition + Extension: MessageTypeDefinition + ExtensionConfigSource: MessageTypeDefinition + GrpcService: MessageTypeDefinition + HeaderMap: MessageTypeDefinition + HeaderValue: MessageTypeDefinition + HeaderValueOption: MessageTypeDefinition + HttpUri: MessageTypeDefinition + Locality: MessageTypeDefinition + Metadata: MessageTypeDefinition + Node: MessageTypeDefinition + Pipe: MessageTypeDefinition + ProxyProtocolConfig: MessageTypeDefinition + RateLimitSettings: MessageTypeDefinition + RemoteDataSource: MessageTypeDefinition + RequestMethod: EnumTypeDefinition + RetryPolicy: MessageTypeDefinition + RoutingPriority: EnumTypeDefinition + RuntimeDouble: MessageTypeDefinition + RuntimeFeatureFlag: MessageTypeDefinition + RuntimeFractionalPercent: MessageTypeDefinition + RuntimePercent: MessageTypeDefinition + RuntimeUInt32: MessageTypeDefinition + SelfConfigSource: MessageTypeDefinition + SocketAddress: MessageTypeDefinition + SocketOption: MessageTypeDefinition + TcpKeepalive: MessageTypeDefinition + TrafficDirection: EnumTypeDefinition + TransportSocket: MessageTypeDefinition + TypedExtensionConfig: MessageTypeDefinition + WatchedDirectory: MessageTypeDefinition + } + } + route: { + v3: { + CorsPolicy: MessageTypeDefinition + Decorator: MessageTypeDefinition + DirectResponseAction: MessageTypeDefinition + FilterAction: MessageTypeDefinition + FilterConfig: MessageTypeDefinition + HeaderMatcher: MessageTypeDefinition + HedgePolicy: MessageTypeDefinition + InternalRedirectPolicy: MessageTypeDefinition + QueryParameterMatcher: MessageTypeDefinition + RateLimit: MessageTypeDefinition + RedirectAction: MessageTypeDefinition + RetryPolicy: MessageTypeDefinition + Route: MessageTypeDefinition + RouteAction: MessageTypeDefinition + RouteMatch: MessageTypeDefinition + Tracing: MessageTypeDefinition + VirtualCluster: MessageTypeDefinition + VirtualHost: MessageTypeDefinition + WeightedCluster: MessageTypeDefinition + } + } + } + extensions: { + filters: { + common: { + fault: { + v3: { + FaultDelay: MessageTypeDefinition + FaultRateLimit: MessageTypeDefinition + } + } + } + http: { + fault: { + v3: { + FaultAbort: MessageTypeDefinition + HTTPFault: MessageTypeDefinition + } + } + } + } + } + type: { + matcher: { + v3: { + ListStringMatcher: MessageTypeDefinition + RegexMatchAndSubstitute: MessageTypeDefinition + RegexMatcher: MessageTypeDefinition + StringMatcher: MessageTypeDefinition + } + } + metadata: { + v3: { + MetadataKey: MessageTypeDefinition + MetadataKind: MessageTypeDefinition + } + } + tracing: { + v3: { + CustomTag: MessageTypeDefinition + } + } + v3: { + DoubleRange: MessageTypeDefinition + FractionalPercent: MessageTypeDefinition + Int32Range: MessageTypeDefinition + Int64Range: MessageTypeDefinition + Percent: MessageTypeDefinition + SemanticVersion: MessageTypeDefinition + } + } + } + google: { + protobuf: { + Any: MessageTypeDefinition + BoolValue: MessageTypeDefinition + BytesValue: MessageTypeDefinition + DescriptorProto: MessageTypeDefinition + DoubleValue: MessageTypeDefinition + Duration: MessageTypeDefinition + Empty: MessageTypeDefinition + EnumDescriptorProto: MessageTypeDefinition + EnumOptions: MessageTypeDefinition + EnumValueDescriptorProto: MessageTypeDefinition + EnumValueOptions: MessageTypeDefinition + FieldDescriptorProto: MessageTypeDefinition + FieldOptions: MessageTypeDefinition + FileDescriptorProto: MessageTypeDefinition + FileDescriptorSet: MessageTypeDefinition + FileOptions: MessageTypeDefinition + FloatValue: MessageTypeDefinition + GeneratedCodeInfo: MessageTypeDefinition + Int32Value: MessageTypeDefinition + Int64Value: MessageTypeDefinition + ListValue: MessageTypeDefinition + MessageOptions: MessageTypeDefinition + MethodDescriptorProto: MessageTypeDefinition + MethodOptions: MessageTypeDefinition + NullValue: EnumTypeDefinition + OneofDescriptorProto: MessageTypeDefinition + OneofOptions: MessageTypeDefinition + ServiceDescriptorProto: MessageTypeDefinition + ServiceOptions: MessageTypeDefinition + SourceCodeInfo: MessageTypeDefinition + StringValue: MessageTypeDefinition + Struct: MessageTypeDefinition + Timestamp: MessageTypeDefinition + UInt32Value: MessageTypeDefinition + UInt64Value: MessageTypeDefinition + UninterpretedOption: MessageTypeDefinition + Value: MessageTypeDefinition + } + } + udpa: { + annotations: { + FieldMigrateAnnotation: MessageTypeDefinition + FileMigrateAnnotation: MessageTypeDefinition + MigrateAnnotation: MessageTypeDefinition + PackageVersionStatus: EnumTypeDefinition + StatusAnnotation: MessageTypeDefinition + VersioningAnnotation: MessageTypeDefinition + } + } + validate: { + AnyRules: MessageTypeDefinition + BoolRules: MessageTypeDefinition + BytesRules: MessageTypeDefinition + DoubleRules: MessageTypeDefinition + DurationRules: MessageTypeDefinition + EnumRules: MessageTypeDefinition + FieldRules: MessageTypeDefinition + Fixed32Rules: MessageTypeDefinition + Fixed64Rules: MessageTypeDefinition + FloatRules: MessageTypeDefinition + Int32Rules: MessageTypeDefinition + Int64Rules: MessageTypeDefinition + KnownRegex: EnumTypeDefinition + MapRules: MessageTypeDefinition + MessageRules: MessageTypeDefinition + RepeatedRules: MessageTypeDefinition + SFixed32Rules: MessageTypeDefinition + SFixed64Rules: MessageTypeDefinition + SInt32Rules: MessageTypeDefinition + SInt64Rules: MessageTypeDefinition + StringRules: MessageTypeDefinition + TimestampRules: MessageTypeDefinition + UInt32Rules: MessageTypeDefinition + UInt64Rules: MessageTypeDefinition + } + xds: { + core: { + v3: { + Authority: MessageTypeDefinition + } + } + } +} + From 365b37919317b8db1dc576b4957ebf96049a34b4 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 3 Aug 2021 14:59:59 -0700 Subject: [PATCH 057/450] grpc-js-xds: Factor Fraction out into a separate file --- packages/grpc-js-xds/src/fraction.ts | 39 ++++++++++++++++++++++++ packages/grpc-js-xds/src/matcher.ts | 10 +----- packages/grpc-js-xds/src/resolver-xds.ts | 14 ++------- 3 files changed, 43 insertions(+), 20 deletions(-) create mode 100644 packages/grpc-js-xds/src/fraction.ts diff --git a/packages/grpc-js-xds/src/fraction.ts b/packages/grpc-js-xds/src/fraction.ts new file mode 100644 index 000000000..709af72b2 --- /dev/null +++ b/packages/grpc-js-xds/src/fraction.ts @@ -0,0 +1,39 @@ +/* + * Copyright 2021 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 { FractionalPercent__Output } from "./generated/envoy/type/v3/FractionalPercent"; + +export interface Fraction { + numerator: number; + denominator: number; +} + +export function fractionToString(fraction: Fraction): string { + return `${fraction.numerator}/${fraction.denominator}`; +} + +const RUNTIME_FRACTION_DENOMINATOR_VALUES = { + HUNDRED: 100, + TEN_THOUSAND: 10_000, + MILLION: 1_000_000 +} + +export function envoyFractionToFraction(envoyFraction: FractionalPercent__Output): Fraction { + return { + numerator: envoyFraction.numerator, + denominator: RUNTIME_FRACTION_DENOMINATOR_VALUES[envoyFraction.denominator] + }; +} \ No newline at end of file diff --git a/packages/grpc-js-xds/src/matcher.ts b/packages/grpc-js-xds/src/matcher.ts index 14cb7f672..b173c30e0 100644 --- a/packages/grpc-js-xds/src/matcher.ts +++ b/packages/grpc-js-xds/src/matcher.ts @@ -16,6 +16,7 @@ import { Metadata } from "@grpc/grpc-js"; import { RE2 } from "re2-wasm"; +import { Fraction, fractionToString } from "./fraction"; /** * An object representing a predicate that determines whether a given @@ -210,15 +211,6 @@ export class PathSafeRegexValueMatcher { } } -export interface Fraction { - numerator: number; - denominator: number; -} - -function fractionToString(fraction: Fraction): string { - return `${fraction.numerator}/${fraction.denominator}`; -} - export class FullMatcher implements Matcher { constructor(private pathMatcher: ValueMatcher, private headerMatchers: Matcher[], private fraction: Fraction | null) {} diff --git a/packages/grpc-js-xds/src/resolver-xds.ts b/packages/grpc-js-xds/src/resolver-xds.ts index 3eaabb111..3712ad647 100644 --- a/packages/grpc-js-xds/src/resolver-xds.ts +++ b/packages/grpc-js-xds/src/resolver-xds.ts @@ -37,7 +37,8 @@ import { HeaderMatcher__Output } from './generated/envoy/config/route/v3/HeaderM import ConfigSelector = experimental.ConfigSelector; import LoadBalancingConfig = experimental.LoadBalancingConfig; import { XdsClusterManagerLoadBalancingConfig } from './load-balancer-xds-cluster-manager'; -import { ExactValueMatcher, Fraction, FullMatcher, HeaderMatcher, Matcher, PathExactValueMatcher, PathPrefixValueMatcher, PathSafeRegexValueMatcher, PrefixValueMatcher, PresentValueMatcher, RangeValueMatcher, RejectValueMatcher, SafeRegexValueMatcher, SuffixValueMatcher, ValueMatcher } from './matcher'; +import { ExactValueMatcher, FullMatcher, HeaderMatcher, Matcher, PathExactValueMatcher, PathPrefixValueMatcher, PathSafeRegexValueMatcher, PrefixValueMatcher, PresentValueMatcher, RangeValueMatcher, RejectValueMatcher, SafeRegexValueMatcher, SuffixValueMatcher, ValueMatcher } from './matcher'; +import { envoyFractionToFraction, Fraction } from "./fraction"; import { RouteAction, SingleClusterRouteAction, WeightedCluster, WeightedClusterRouteAction } from './route-action'; import { decodeSingleResource, HTTP_CONNECTION_MANGER_TYPE_URL_V3 } from './resources'; import Duration = experimental.Duration; @@ -158,12 +159,6 @@ function getPredicateForHeaderMatcher(headerMatch: HeaderMatcher__Output): Match return new HeaderMatcher(headerMatch.name, valueChecker, headerMatch.invert_match); } -const RUNTIME_FRACTION_DENOMINATOR_VALUES = { - HUNDRED: 100, - TEN_THOUSAND: 10_000, - MILLION: 1_000_000 -} - function getPredicateForMatcher(routeMatch: RouteMatch__Output): Matcher { let pathMatcher: ValueMatcher; const caseInsensitive = routeMatch.case_sensitive?.value === false; @@ -185,10 +180,7 @@ function getPredicateForMatcher(routeMatch: RouteMatch__Output): Matcher { if (!routeMatch.runtime_fraction?.default_value) { runtimeFraction = null; } else { - runtimeFraction = { - numerator: routeMatch.runtime_fraction.default_value.numerator, - denominator: RUNTIME_FRACTION_DENOMINATOR_VALUES[routeMatch.runtime_fraction.default_value.denominator] - }; + runtimeFraction = envoyFractionToFraction(routeMatch.runtime_fraction.default_value) } return new FullMatcher(pathMatcher, headerMatchers, runtimeFraction); } From f216ecef00f925d46a3796e7ca3c91d9ce547385 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 3 Aug 2021 15:06:47 -0700 Subject: [PATCH 058/450] grpc-js-xds: Add null checks to handle generated code changes --- packages/grpc-js-xds/src/resolver-xds.ts | 2 +- packages/grpc-js-xds/src/xds-stream-state/rds-state.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js-xds/src/resolver-xds.ts b/packages/grpc-js-xds/src/resolver-xds.ts index 3712ad647..f6287ea67 100644 --- a/packages/grpc-js-xds/src/resolver-xds.ts +++ b/packages/grpc-js-xds/src/resolver-xds.ts @@ -228,7 +228,7 @@ class XdsResolver implements Resolver { onValidUpdate: (update: Listener__Output) => { const httpConnectionManager = decodeSingleResource(HTTP_CONNECTION_MANGER_TYPE_URL_V3, update.api_listener!.api_listener!.value); const defaultTimeout = httpConnectionManager.common_http_protocol_options?.idle_timeout; - if (defaultTimeout === undefined) { + if (defaultTimeout === null || defaultTimeout === undefined) { this.latestDefaultTimeout = undefined; } else { this.latestDefaultTimeout = protoDurationToDuration(defaultTimeout); diff --git a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts index f04692859..58f11f0b4 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts @@ -137,7 +137,7 @@ export class RdsState implements XdsStreamState { if (route.action !== 'route') { return false; } - if ((route.route === undefined) || SUPPORTED_CLUSTER_SPECIFIERS.indexOf(route.route.cluster_specifier) < 0) { + if ((route.route === undefined) || (route.route === null) || SUPPORTED_CLUSTER_SPECIFIERS.indexOf(route.route.cluster_specifier) < 0) { return false; } if (EXPERIMENTAL_FAULT_INJECTION) { From e1b0d62e9bcf5f0aba88ac2207459afba43bbec7 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 3 Aug 2021 15:07:42 -0700 Subject: [PATCH 059/450] grpc-js-xds: Add fault injection file to type generator script --- packages/grpc-js-xds/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index eb8e3e03e..6506112c4 100644 --- a/packages/grpc-js-xds/package.json +++ b/packages/grpc-js-xds/package.json @@ -12,7 +12,7 @@ "prepare": "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/udpa/ deps/googleapis/ deps/protoc-gen-validate/ -O src/generated/ --grpcLib @grpc/grpc-js envoy/service/discovery/v2/ads.proto envoy/service/load_stats/v2/lrs.proto 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", + "generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs deps/envoy-api/ deps/udpa/ deps/googleapis/ deps/protoc-gen-validate/ -O src/generated/ --grpcLib @grpc/grpc-js envoy/service/discovery/v2/ads.proto envoy/service/load_stats/v2/lrs.proto 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 envoy/extensions/filters/http/fault/v3/fault.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" }, "repository": { From b5fd5b033ee6e876e4bc0304ff8c31a8bfd0b8a4 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 3 Aug 2021 15:08:10 -0700 Subject: [PATCH 060/450] grpc-js-xds: Add fault injection HTTP filter --- .../src/http-filter/fault-injection-filter.ts | 333 ++++++++++++++++++ packages/grpc-js-xds/src/index.ts | 2 + 2 files changed, 335 insertions(+) create mode 100644 packages/grpc-js-xds/src/http-filter/fault-injection-filter.ts diff --git a/packages/grpc-js-xds/src/http-filter/fault-injection-filter.ts b/packages/grpc-js-xds/src/http-filter/fault-injection-filter.ts new file mode 100644 index 000000000..825b7c058 --- /dev/null +++ b/packages/grpc-js-xds/src/http-filter/fault-injection-filter.ts @@ -0,0 +1,333 @@ +/* + * Copyright 2021 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. + */ + +// This is a non-public, unstable API, but it's very convenient +import { loadProtosWithOptionsSync } from '@grpc/proto-loader/build/src/util'; +import { experimental, Metadata, status } from '@grpc/grpc-js'; +import { Any__Output } from '../generated/google/protobuf/Any'; +import Filter = experimental.Filter; +import FilterFactory = experimental.FilterFactory; +import BaseFilter = experimental.BaseFilter; +import CallStream = experimental.CallStream; +import { HttpFilterConfig, registerHttpFilter } from '../http-filter'; +import { HTTPFault__Output } from '../generated/envoy/extensions/filters/http/fault/v3/HTTPFault'; +import { envoyFractionToFraction, Fraction } from '../fraction'; +import { Duration__Output } from '../generated/google/protobuf/Duration'; + +const resourceRoot = loadProtosWithOptionsSync([ + 'envoy/extendsion/filtesr/http/fault/v3/fault.proto'], { + keepCase: true, + includeDirs: [ + // Paths are relative to src/build + __dirname + '/../../deps/udpa/', + __dirname + '/../../deps/envoy-api/', + __dirname + '/../../deps/protoc-gen-validate/' + ], + } +); + +interface FixedDelayConfig { + kind: 'fixed'; + durationMs: number; + percentage: Fraction; +} + +interface HeaderDelayConfig { + kind: 'header'; + percentage: Fraction; +} + +interface GrpcAbortConfig { + kind: 'grpc'; + code: status; + percentage: Fraction; +} + +interface HeaderAbortConfig { + kind: 'header'; + percentage: Fraction; +} + +interface FaultInjectionConfig { + delay: FixedDelayConfig | HeaderDelayConfig | null; + abort: GrpcAbortConfig | HeaderAbortConfig | null; + maxActiveFaults: number; +} + +interface FaultInjectionFilterConfig extends HttpFilterConfig { + typeUrl: 'type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault'; + config: FaultInjectionConfig; +} + +const FAULT_INJECTION_FILTER_URL = 'type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault'; + +const toObjectOptions = { + longs: String, + enums: String, + defaults: true, + oneofs: true +} + +function parseAnyMessage(message: Any__Output): MessageType | null { + const messageType = resourceRoot.lookup(message.type_url); + if (messageType) { + const decodedMessage = (messageType as any).decode(message.value); + return decodedMessage.$type.toObject(decodedMessage, toObjectOptions) as MessageType; + } else { + return null; + } +} + +function durationToMs(duration: Duration__Output): number { + return Number.parseInt(duration.seconds) * 1000 + duration.nanos / 1_000_000; +} + +function httpCodeToGrpcStatus(code: number): status { + switch (code) { + case 400: return status.INTERNAL; + case 401: return status.UNAUTHENTICATED; + case 403: return status.PERMISSION_DENIED; + case 404: return status.UNIMPLEMENTED; + case 429: return status.UNAVAILABLE; + case 502: return status.UNAVAILABLE; + case 503: return status.UNAVAILABLE; + case 504: return status.UNAVAILABLE; + default: return status.UNKNOWN; + } +} + +function parseHTTPFaultConfig(encodedConfig: Any__Output): FaultInjectionFilterConfig | null { + if (encodedConfig.type_url !== FAULT_INJECTION_FILTER_URL) { + return null; + } + const parsedMessage = parseAnyMessage(encodedConfig); + if (parsedMessage === null) { + return null; + } + const result: FaultInjectionConfig = { + delay: null, + abort: null, + maxActiveFaults: Infinity + }; + // Parse delay field + if (parsedMessage.delay !== null) { + if (parsedMessage.delay.percentage === null) { + return null; + } + const percentage = envoyFractionToFraction(parsedMessage.delay.percentage); + switch (parsedMessage.delay.fault_delay_secifier /* sic */) { + case 'fixed_delay': + result.delay = { + kind: 'fixed', + durationMs: durationToMs(parsedMessage.delay.fixed_delay!), + percentage: percentage + }; + break; + case 'header_delay': + result.delay = { + kind: 'header', + percentage: percentage + }; + break; + default: + // Should not be possible + return null; + } + } + // Parse abort field + if (parsedMessage.abort !== null) { + if (parsedMessage.abort.percentage === null) { + return null; + } + const percentage = envoyFractionToFraction(parsedMessage.abort.percentage); + switch (parsedMessage.abort.error_type) { + case 'http_status': + result.abort = { + kind: 'grpc', + code: httpCodeToGrpcStatus(parsedMessage.abort.http_status!), + percentage: percentage + }; + break; + case 'grpc_status': + result.abort = { + kind: 'grpc', + code: parsedMessage.abort.grpc_status!, + percentage: percentage + } + break; + case 'header_abort': + result.abort = { + kind: 'header', + percentage: percentage + }; + break; + default: + // Should not be possible + return null; + } + } + // Parse max_active_faults field + if (parsedMessage.max_active_faults !== null) { + result.maxActiveFaults = parsedMessage.max_active_faults.value; + } + return { + typeUrl: FAULT_INJECTION_FILTER_URL, + config: result + }; +} + +function asyncTimeout(timeMs: number): Promise { + return new Promise((resolve, reject) => { + setTimeout(() => { + resolve(); + }, timeMs); + }); +} + +/** + * Returns true with probability numerator/denominator. + * @param numerator + * @param denominator + */ +function rollRandomPercentage(numerator: number, denominator: number): boolean { + return Math.random() * denominator < numerator; +} + +const DELAY_DURATION_HEADER_KEY = 'x-envoy-fault-delay-request'; +const DELAY_PERCENTAGE_HEADER_KEY = 'x-envoy-fault-delay-request-percentage'; +const ABORT_GRPC_HEADER_KEY = 'x-envoy-fault-abort-grpc-request'; +const ABORT_HTTP_HEADER_KEY = 'x-envoy-fault-abort-request'; +const ABORT_PERCENTAGE_HEADER_KEY = 'x-envoy-fault-abort-request-percentage'; + +const NUMBER_REGEX = /\d+/; + +let totalActiveFaults = 0; + +class FaultInjectionFilter extends BaseFilter implements Filter { + constructor(private callStream: CallStream, private config: FaultInjectionConfig) { + super(); + } + + async sendMetadata(metadataPromise: Promise): Promise { + const metadata = await metadataPromise; + // Handle delay + if (totalActiveFaults < this.config.maxActiveFaults && this.config.delay) { + let duration = 0; + let numerator = this.config.delay.percentage.numerator; + const denominator = this.config.delay.percentage.denominator; + if (this.config.delay.kind === 'fixed') { + duration = this.config.delay.durationMs; + } else { + const durationHeader = metadata.get(DELAY_DURATION_HEADER_KEY); + for (const value of durationHeader) { + if (typeof value !== 'string') { + continue; + } + if (NUMBER_REGEX.test(value)) { + duration = Number.parseInt(value); + break; + } + } + const percentageHeader = metadata.get(DELAY_PERCENTAGE_HEADER_KEY); + for (const value of percentageHeader) { + if (typeof value !== 'string') { + continue; + } + if (NUMBER_REGEX.test(value)) { + numerator = Math.min(numerator, Number.parseInt(value)); + break; + } + } + } + if (rollRandomPercentage(numerator, denominator)) { + totalActiveFaults++; + await asyncTimeout(duration); + totalActiveFaults--; + } + } + // Handle abort + if (totalActiveFaults < this.config.maxActiveFaults && this.config.abort) { + let abortStatus: status | null = null; + let numerator = this.config.abort.percentage.numerator; + const denominator = this.config.abort.percentage.denominator; + if (this.config.abort.kind === 'grpc') { + abortStatus = this.config.abort.code; + } else { + const grpcStatusHeader = metadata.get(ABORT_GRPC_HEADER_KEY); + for (const value of grpcStatusHeader) { + if (typeof value !== 'string') { + continue; + } + if (NUMBER_REGEX.test(value)) { + abortStatus = Number.parseInt(value); + break; + } + } + /* Fall back to looking for HTTP status header if the gRPC status + * header is not present. */ + if (abortStatus === null) { + const httpStatusHeader = metadata.get(ABORT_HTTP_HEADER_KEY); + for (const value of httpStatusHeader) { + if (typeof value !== 'string') { + continue; + } + if (NUMBER_REGEX.test(value)) { + abortStatus = httpCodeToGrpcStatus(Number.parseInt(value)); + break; + } + } + } + const percentageHeader = metadata.get(ABORT_PERCENTAGE_HEADER_KEY); + for (const value of percentageHeader) { + if (typeof value !== 'string') { + continue; + } + if (NUMBER_REGEX.test(value)) { + numerator = Math.min(numerator, Number.parseInt(value)); + break; + } + } + } + if (abortStatus !== null && rollRandomPercentage(numerator, denominator)) { + this.callStream.cancelWithStatus(abortStatus, 'Fault injected'); + } + } + return metadata; + } +} + +class FaultInjectionFilterFactory implements FilterFactory { + private config: FaultInjectionConfig; + constructor(config: HttpFilterConfig, overrideConfig?: HttpFilterConfig) { + if (overrideConfig?.typeUrl === FAULT_INJECTION_FILTER_URL) { + this.config = overrideConfig.config; + } else { + this.config = config.config; + } + } + + createFilter(callStream: experimental.CallStream): FaultInjectionFilter { + return new FaultInjectionFilter(callStream, this.config); + } +} + +export function setup() { + registerHttpFilter(FAULT_INJECTION_FILTER_URL, { + parseTopLevelFilterConfig: parseHTTPFaultConfig, + parseOverrideFilterConfig: parseHTTPFaultConfig, + httpFilterConstructor: FaultInjectionFilterFactory + }); +} \ No newline at end of file diff --git a/packages/grpc-js-xds/src/index.ts b/packages/grpc-js-xds/src/index.ts index 2fee339d1..7d35bcd1e 100644 --- a/packages/grpc-js-xds/src/index.ts +++ b/packages/grpc-js-xds/src/index.ts @@ -23,6 +23,7 @@ import * as load_balancer_priority from './load-balancer-priority'; import * as load_balancer_weighted_target from './load-balancer-weighted-target'; import * as load_balancer_xds_cluster_manager from './load-balancer-xds-cluster-manager'; import * as router_filter from './http-filter/router-filter'; +import * as fault_injection_filter from './http-filter/fault-injection-filter'; /** * Register the "xds:" name scheme with the @grpc/grpc-js library. @@ -36,4 +37,5 @@ export function register() { load_balancer_weighted_target.setup(); load_balancer_xds_cluster_manager.setup(); router_filter.setup(); + fault_injection_filter.setup(); } \ No newline at end of file From 36c6add3a799cb37a11d9da9cfb8ea017c58cf63 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 3 Aug 2021 15:11:52 -0700 Subject: [PATCH 061/450] grpc-js-xds: Enable fault_injection xDS interop test --- packages/grpc-js-xds/scripts/xds.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/scripts/xds.sh b/packages/grpc-js-xds/scripts/xds.sh index 66fe4d568..f845abfb0 100755 --- a/packages/grpc-js-xds/scripts/xds.sh +++ b/packages/grpc-js-xds/scripts/xds.sh @@ -51,8 +51,9 @@ grpc/tools/run_tests/helper_scripts/prep_xds.sh GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weighted_target,round_robin,resolving_load_balancer,subchannel,keepalive,dns_resolver \ GRPC_NODE_VERBOSITY=DEBUG \ NODE_XDS_INTEROP_VERBOSITY=1 \ + GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION=1 \ python3 grpc/tools/run_tests/run_xds_tests.py \ - --test_case="all,timeout,circuit_breaking" \ + --test_case="all,timeout,circuit_breaking,fault_injection" \ --project_id=grpc-testing \ --source_image=projects/grpc-testing/global/images/xds-test-server-4 \ --path_to_server_binary=/java_server/grpc-java/interop-testing/build/install/grpc-interop-testing/bin/xds-test-server \ From a0baf7c99ab37ed651a576921776a98b91284656 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 4 Aug 2021 11:54:21 -0700 Subject: [PATCH 062/450] Fix bugs and add tracing --- packages/grpc-js-xds/scripts/xds.sh | 2 +- packages/grpc-js-xds/src/http-filter.ts | 30 ++++++++++++++++--- .../src/http-filter/fault-injection-filter.ts | 28 ++++++++++++----- .../src/xds-stream-state/lds-state.ts | 11 +++++-- 4 files changed, 56 insertions(+), 15 deletions(-) diff --git a/packages/grpc-js-xds/scripts/xds.sh b/packages/grpc-js-xds/scripts/xds.sh index f845abfb0..8d94ae195 100755 --- a/packages/grpc-js-xds/scripts/xds.sh +++ b/packages/grpc-js-xds/scripts/xds.sh @@ -48,7 +48,7 @@ git clone -b master --single-branch --depth=1 https://github.com/grpc/grpc.git grpc/tools/run_tests/helper_scripts/prep_xds.sh -GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weighted_target,round_robin,resolving_load_balancer,subchannel,keepalive,dns_resolver \ +GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weighted_target,round_robin,resolving_load_balancer,subchannel,keepalive,dns_resolver,fault_injection,http_filter \ GRPC_NODE_VERBOSITY=DEBUG \ NODE_XDS_INTEROP_VERBOSITY=1 \ GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION=1 \ diff --git a/packages/grpc-js-xds/src/http-filter.ts b/packages/grpc-js-xds/src/http-filter.ts index e7ea32957..a00cde5db 100644 --- a/packages/grpc-js-xds/src/http-filter.ts +++ b/packages/grpc-js-xds/src/http-filter.ts @@ -16,7 +16,7 @@ // This is a non-public, unstable API, but it's very convenient import { loadProtosWithOptionsSync } from '@grpc/proto-loader/build/src/util'; -import { experimental } from '@grpc/grpc-js'; +import { experimental, logVerbosity } from '@grpc/grpc-js'; import { Any__Output } from './generated/google/protobuf/Any'; import Filter = experimental.Filter; import FilterFactory = experimental.FilterFactory; @@ -24,6 +24,12 @@ import { TypedStruct__Output } from './generated/udpa/type/v1/TypedStruct'; import { FilterConfig__Output } from './generated/envoy/config/route/v3/FilterConfig'; import { HttpFilter__Output } from './generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpFilter'; +const TRACER_NAME = 'http_filter'; + +function trace(text: string): void { + experimental.trace(logVerbosity.DEBUG, TRACER_NAME, text); +} + const TYPED_STRUCT_URL = 'type.googleapis.com/udpa.type.v1.TypedStruct'; const TYPED_STRUCT_NAME = 'udpa.type.v1.TypedStruct'; @@ -37,7 +43,8 @@ const resourceRoot = loadProtosWithOptionsSync([ includeDirs: [ // Paths are relative to src/build __dirname + '/../../deps/udpa/', - __dirname + '/../../deps/envoy-api/' + __dirname + '/../../deps/envoy-api/', + __dirname + '/../../deps/protoc-gen-validate/' ], } ); @@ -60,6 +67,7 @@ export interface HttpFilterRegistryEntry { const FILTER_REGISTRY = new Map(); export function registerHttpFilter(typeName: string, entry: HttpFilterRegistryEntry) { + trace('Registered filter with type URL ' + typeName); FILTER_REGISTRY.set(typeName, entry); } @@ -71,7 +79,8 @@ const toObjectOptions = { } function parseAnyMessage(message: Any__Output): MessageType | null { - const messageType = resourceRoot.lookup(message.type_url); + const typeName = message.type_url.substring(message.type_url.lastIndexOf('/') + 1); + const messageType = resourceRoot.lookup(typeName); if (messageType) { const decodedMessage = (messageType as any).decode(message.value); return decodedMessage.$type.toObject(decodedMessage, toObjectOptions) as MessageType; @@ -80,7 +89,7 @@ function parseAnyMessage(message: Any__Output): MessageType | null } } -function getTopLevelFilterUrl(encodedConfig: Any__Output): string { +export function getTopLevelFilterUrl(encodedConfig: Any__Output): string { let typeUrl: string; if (encodedConfig.type_url === TYPED_STRUCT_URL) { const typedStruct = parseAnyMessage(encodedConfig) @@ -96,6 +105,7 @@ function getTopLevelFilterUrl(encodedConfig: Any__Output): string { export function validateTopLevelFilter(httpFilter: HttpFilter__Output): boolean { if (!httpFilter.typed_config) { + trace(httpFilter.name + ' validation failed: typed_config unset'); return false; } const encodedConfig = httpFilter.typed_config; @@ -103,16 +113,21 @@ export function validateTopLevelFilter(httpFilter: HttpFilter__Output): boolean try { typeUrl = getTopLevelFilterUrl(encodedConfig); } catch (e) { + trace(httpFilter.name + ' validation failed with error ' + e.message); return false; } const registryEntry = FILTER_REGISTRY.get(typeUrl); if (registryEntry) { const parsedConfig = registryEntry.parseTopLevelFilterConfig(encodedConfig); + if (parsedConfig === null) { + trace(httpFilter.name + ' validation failed: config parsing failed'); + } return parsedConfig !== null; } else { if (httpFilter.is_optional) { return true; } else { + trace(httpFilter.name + ' validation failed: filter is not optional and registry does not contain type URL ' + typeUrl); return false; } } @@ -129,9 +144,11 @@ export function validateOverrideFilter(encodedConfig: Any__Output): boolean { if (filterConfig.config) { realConfig = filterConfig.config; } else { + trace('Override filter validation failed: FilterConfig config field is empty'); return false; } } else { + trace('Override filter validation failed: failed to parse FilterConfig message'); return false; } } else { @@ -142,6 +159,7 @@ export function validateOverrideFilter(encodedConfig: Any__Output): boolean { if (typedStruct) { typeUrl = typedStruct.type_url; } else { + trace('Override filter validation failed: failed to parse TypedStruct message'); return false; } } else { @@ -150,11 +168,15 @@ export function validateOverrideFilter(encodedConfig: Any__Output): boolean { const registryEntry = FILTER_REGISTRY.get(typeUrl); if (registryEntry) { const parsedConfig = registryEntry.parseOverrideFilterConfig(encodedConfig); + if (parsedConfig === null) { + trace('Override filter validation failed: config parsing failed. Type URL: ' + typeUrl); + } return parsedConfig !== null; } else { if (isOptional) { return true; } else { + trace('Override filter validation failed: filter is not optional and registry does not contain type URL ' + typeUrl); return false; } } diff --git a/packages/grpc-js-xds/src/http-filter/fault-injection-filter.ts b/packages/grpc-js-xds/src/http-filter/fault-injection-filter.ts index 825b7c058..e0ee658c7 100644 --- a/packages/grpc-js-xds/src/http-filter/fault-injection-filter.ts +++ b/packages/grpc-js-xds/src/http-filter/fault-injection-filter.ts @@ -16,7 +16,7 @@ // This is a non-public, unstable API, but it's very convenient import { loadProtosWithOptionsSync } from '@grpc/proto-loader/build/src/util'; -import { experimental, Metadata, status } from '@grpc/grpc-js'; +import { experimental, logVerbosity, Metadata, status } from '@grpc/grpc-js'; import { Any__Output } from '../generated/google/protobuf/Any'; import Filter = experimental.Filter; import FilterFactory = experimental.FilterFactory; @@ -27,14 +27,20 @@ import { HTTPFault__Output } from '../generated/envoy/extensions/filters/http/fa import { envoyFractionToFraction, Fraction } from '../fraction'; import { Duration__Output } from '../generated/google/protobuf/Duration'; +const TRACER_NAME = 'fault_injection'; + +function trace(text: string): void { + experimental.trace(logVerbosity.DEBUG, TRACER_NAME, text); +} + const resourceRoot = loadProtosWithOptionsSync([ - 'envoy/extendsion/filtesr/http/fault/v3/fault.proto'], { + 'envoy/extensions/filters/http/fault/v3/fault.proto'], { keepCase: true, includeDirs: [ - // Paths are relative to src/build - __dirname + '/../../deps/udpa/', - __dirname + '/../../deps/envoy-api/', - __dirname + '/../../deps/protoc-gen-validate/' + // Paths are relative to src/build/http-filter + __dirname + '/../../../deps/udpa/', + __dirname + '/../../../deps/envoy-api/', + __dirname + '/../../../deps/protoc-gen-validate/' ], } ); @@ -82,7 +88,8 @@ const toObjectOptions = { } function parseAnyMessage(message: Any__Output): MessageType | null { - const messageType = resourceRoot.lookup(message.type_url); + const typeName = message.type_url.substring(message.type_url.lastIndexOf('/') + 1); + const messageType = resourceRoot.lookup(typeName); if (messageType) { const decodedMessage = (messageType as any).decode(message.value); return decodedMessage.$type.toObject(decodedMessage, toObjectOptions) as MessageType; @@ -111,12 +118,15 @@ function httpCodeToGrpcStatus(code: number): status { function parseHTTPFaultConfig(encodedConfig: Any__Output): FaultInjectionFilterConfig | null { if (encodedConfig.type_url !== FAULT_INJECTION_FILTER_URL) { + trace('Config parsing failed: unexpected type URL: ' + encodedConfig.type_url); return null; } const parsedMessage = parseAnyMessage(encodedConfig); if (parsedMessage === null) { + trace('Config parsing failed: failed to parse HTTPFault message'); return null; } + trace('Parsing HTTPFault message ' + JSON.stringify(parsedMessage, undefined, 2)); const result: FaultInjectionConfig = { delay: null, abort: null, @@ -125,6 +135,7 @@ function parseHTTPFaultConfig(encodedConfig: Any__Output): FaultInjectionFilterC // Parse delay field if (parsedMessage.delay !== null) { if (parsedMessage.delay.percentage === null) { + trace('Config parsing failed: delay.percentage unset'); return null; } const percentage = envoyFractionToFraction(parsedMessage.delay.percentage); @@ -143,6 +154,7 @@ function parseHTTPFaultConfig(encodedConfig: Any__Output): FaultInjectionFilterC }; break; default: + trace('Config parsing failed: delay.fault_delay_secifier has unexpected value ' + parsedMessage.delay.fault_delay_secifier); // Should not be possible return null; } @@ -150,6 +162,7 @@ function parseHTTPFaultConfig(encodedConfig: Any__Output): FaultInjectionFilterC // Parse abort field if (parsedMessage.abort !== null) { if (parsedMessage.abort.percentage === null) { + trace('Config parsing failed: abort.percentage unset'); return null; } const percentage = envoyFractionToFraction(parsedMessage.abort.percentage); @@ -175,6 +188,7 @@ function parseHTTPFaultConfig(encodedConfig: Any__Output): FaultInjectionFilterC }; break; default: + trace('Config parsing failed: abort.error_type has unexpected value ' + parsedMessage.abort.error_type); // Should not be possible return null; } diff --git a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts index 3efc64b92..8ab6ed9d2 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts @@ -22,7 +22,7 @@ import { RdsState } from "./rds-state"; import { Watcher, XdsStreamState } from "./xds-stream-state"; import { HttpConnectionManager__Output } from '../generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpConnectionManager'; import { decodeSingleResource, HTTP_CONNECTION_MANGER_TYPE_URL_V2, HTTP_CONNECTION_MANGER_TYPE_URL_V3 } from '../resources'; -import { validateTopLevelFilter } from '../http-filter'; +import { getTopLevelFilterUrl, validateTopLevelFilter } from '../http-filter'; import { EXPERIMENTAL_FAULT_INJECTION } from '../environment'; const TRACER_NAME = 'xds_client'; @@ -108,20 +108,25 @@ export class LdsState implements XdsStreamState { const filterNames = new Set(); for (const [index, httpFilter] of httpConnectionManager.http_filters.entries()) { if (filterNames.has(httpFilter.name)) { + trace('LDS response validation failed: duplicate HTTP filter name ' + httpFilter.name); return false; } filterNames.add(httpFilter.name); if (!validateTopLevelFilter(httpFilter)) { + trace('LDS response validation failed: ' + httpFilter.name + ' filter validation failed'); return false; } /* Validate that the last filter, and only the last filter, is the * router filter. */ + const filterUrl = getTopLevelFilterUrl(httpFilter.typed_config!) if (index < httpConnectionManager.http_filters.length - 1) { - if (httpFilter.name === ROUTER_FILTER_URL) { + if (filterUrl === ROUTER_FILTER_URL) { + trace('LDS response validation failed: router filter is before end of list'); return false; } } else { - if (httpFilter.name !== ROUTER_FILTER_URL) { + if (filterUrl !== ROUTER_FILTER_URL) { + trace('LDS response validation failed: final filter is ' + filterUrl); return false; } } From cd50baed558ff8697113d4fadfd4842af3665111 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 10 Aug 2021 09:48:56 -0700 Subject: [PATCH 063/450] Add .gitattributes marking generated code in xDS package --- .gitattributes | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..f0957c311 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +packages/grpc-js-xds/src/generated/** linguist-generated +packages/grpc-js-xds/interop/generated/** linguist-generated From 875f483cf6fd5a6b67cafa96dccbef6f4f24a87b Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 10 Aug 2021 14:20:11 -0700 Subject: [PATCH 064/450] grpc-js: Map ETIMEDOUT errors to UNAVAILABLE --- packages/grpc-js/src/call-stream.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/src/call-stream.ts b/packages/grpc-js/src/call-stream.ts index 5e034433a..c829f4229 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -601,7 +601,7 @@ export class Http2CallStream implements Call { * "Internal server error" message. */ details = `Received RST_STREAM with code ${stream.rstCode} (Internal server error)`; } else { - if (this.internalError.code === 'ECONNRESET') { + if (this.internalError.code === 'ECONNRESET' || this.internalError.code === 'ETIMEDOUT') { code = Status.UNAVAILABLE; details = this.internalError.message; } else { From 64a0b0ad7cd28e73e1e28ecad32437652f1bcc60 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 17 Aug 2021 14:59:22 -0700 Subject: [PATCH 065/450] grpc-js-xds: Distinguish v2 and v3 when handling messages --- packages/grpc-js-xds/src/resolver-xds.ts | 24 ++++++++++--------- packages/grpc-js-xds/src/xds-client.ts | 23 ++++++++++++++---- .../src/xds-stream-state/cds-state.ts | 9 ++++--- .../src/xds-stream-state/eds-state.ts | 9 ++++--- .../src/xds-stream-state/lds-state.ts | 17 +++++++------ .../src/xds-stream-state/rds-state.ts | 19 ++++++++------- .../src/xds-stream-state/xds-stream-state.ts | 9 +++++-- 7 files changed, 72 insertions(+), 38 deletions(-) diff --git a/packages/grpc-js-xds/src/resolver-xds.ts b/packages/grpc-js-xds/src/resolver-xds.ts index f6287ea67..ab036184e 100644 --- a/packages/grpc-js-xds/src/resolver-xds.ts +++ b/packages/grpc-js-xds/src/resolver-xds.ts @@ -212,6 +212,7 @@ class XdsResolver implements Resolver { private latestRouteConfigName: string | null = null; private latestRouteConfig: RouteConfiguration__Output | null = null; + private latestRouteConfigIsV2 = false; private clusterRefcounts = new Map(); @@ -225,7 +226,7 @@ class XdsResolver implements Resolver { private channelOptions: ChannelOptions ) { this.ldsWatcher = { - onValidUpdate: (update: Listener__Output) => { + onValidUpdate: (update: Listener__Output, isV2: boolean) => { const httpConnectionManager = decodeSingleResource(HTTP_CONNECTION_MANGER_TYPE_URL_V3, update.api_listener!.api_listener!.value); const defaultTimeout = httpConnectionManager.common_http_protocol_options?.idle_timeout; if (defaultTimeout === null || defaultTimeout === undefined) { @@ -233,7 +234,7 @@ class XdsResolver implements Resolver { } else { this.latestDefaultTimeout = protoDurationToDuration(defaultTimeout); } - if (EXPERIMENTAL_FAULT_INJECTION) { + if (!isV2 && EXPERIMENTAL_FAULT_INJECTION) { this.ldsHttpFilterConfigs = []; for (const filter of httpConnectionManager.http_filters) { // typed_config must be set here, or validation would have failed @@ -259,7 +260,7 @@ class XdsResolver implements Resolver { if (this.latestRouteConfigName) { getSingletonXdsClient().removeRouteWatcher(this.latestRouteConfigName, this.rdsWatcher); } - this.handleRouteConfig(httpConnectionManager.route_config!); + this.handleRouteConfig(httpConnectionManager.route_config!, isV2); break; default: // This is prevented by the validation rules @@ -279,8 +280,8 @@ class XdsResolver implements Resolver { } }; this.rdsWatcher = { - onValidUpdate: (update: RouteConfiguration__Output) => { - this.handleRouteConfig(update); + onValidUpdate: (update: RouteConfiguration__Output, isV2: boolean) => { + this.handleRouteConfig(update, isV2); }, onTransientError: (error: StatusObject) => { /* A transient error only needs to bubble up as a failure if we have @@ -310,20 +311,21 @@ class XdsResolver implements Resolver { refCount.refCount -= 1; if (!refCount.inLastConfig && refCount.refCount === 0) { this.clusterRefcounts.delete(clusterName); - this.handleRouteConfig(this.latestRouteConfig!); + this.handleRouteConfig(this.latestRouteConfig!, this.latestRouteConfigIsV2); } } } - private handleRouteConfig(routeConfig: RouteConfiguration__Output) { + private handleRouteConfig(routeConfig: RouteConfiguration__Output, isV2: boolean) { this.latestRouteConfig = routeConfig; + this.latestRouteConfigIsV2 = isV2; const virtualHost = findVirtualHostForDomain(routeConfig.virtual_hosts, this.target.path); if (virtualHost === null) { this.reportResolutionError('No matching route found'); return; } const virtualHostHttpFilterOverrides = new Map(); - if (EXPERIMENTAL_FAULT_INJECTION) { + if (!isV2 && EXPERIMENTAL_FAULT_INJECTION) { for (const [name, filter] of Object.entries(virtualHost.typed_per_filter_config ?? {})) { const parsedConfig = parseOverrideFilterConfig(filter); if (parsedConfig) { @@ -352,7 +354,7 @@ class XdsResolver implements Resolver { timeout = undefined; } const routeHttpFilterOverrides = new Map(); - if (EXPERIMENTAL_FAULT_INJECTION) { + if (!isV2 && EXPERIMENTAL_FAULT_INJECTION) { for (const [name, filter] of Object.entries(route.typed_per_filter_config ?? {})) { const parsedConfig = parseOverrideFilterConfig(filter); if (parsedConfig) { @@ -367,7 +369,7 @@ class XdsResolver implements Resolver { const cluster = route.route!.cluster!; allConfigClusters.add(cluster); const extraFilterFactories: FilterFactory[] = []; - if (EXPERIMENTAL_FAULT_INJECTION) { + if (!isV2 && EXPERIMENTAL_FAULT_INJECTION) { for (const filterConfig of this.ldsHttpFilterConfigs) { if (routeHttpFilterOverrides.has(filterConfig.name)) { const filter = createHttpFilter(filterConfig.config, routeHttpFilterOverrides.get(filterConfig.name)!); @@ -396,7 +398,7 @@ class XdsResolver implements Resolver { allConfigClusters.add(clusterWeight.name); const extraFilterFactories: FilterFactory[] = []; const clusterHttpFilterOverrides = new Map(); - if (EXPERIMENTAL_FAULT_INJECTION) { + if (!isV2 && EXPERIMENTAL_FAULT_INJECTION) { for (const [name, filter] of Object.entries(clusterWeight.typed_per_filter_config ?? {})) { const parsedConfig = parseOverrideFilterConfig(filter); if (parsedConfig) { diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index 6828a8a8e..952ae81f4 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -435,32 +435,47 @@ export class XdsClient { private handleAdsResponse(message: DiscoveryResponse__Output) { let errorString: string | null; let serviceKind: AdsServiceKind; + let isV2: boolean; + switch (message.type_url) { + case EDS_TYPE_URL_V2: + case CDS_TYPE_URL_V2: + case RDS_TYPE_URL_V2: + case LDS_TYPE_URL_V2: + isV2 = true; + break; + default: + isV2 = false; + } switch (message.type_url) { case EDS_TYPE_URL_V2: case EDS_TYPE_URL_V3: errorString = this.adsState.eds.handleResponses( - getResponseMessages(EDS_TYPE_URL_V3, [EDS_TYPE_URL_V2, EDS_TYPE_URL_V3], message.resources) + getResponseMessages(EDS_TYPE_URL_V3, [EDS_TYPE_URL_V2, EDS_TYPE_URL_V3], message.resources), + isV2 ); serviceKind = 'eds'; break; case CDS_TYPE_URL_V2: case CDS_TYPE_URL_V3: errorString = this.adsState.cds.handleResponses( - getResponseMessages(CDS_TYPE_URL_V3, [CDS_TYPE_URL_V2, CDS_TYPE_URL_V3], message.resources) + getResponseMessages(CDS_TYPE_URL_V3, [CDS_TYPE_URL_V2, CDS_TYPE_URL_V3], message.resources), + isV2 ); serviceKind = 'cds'; break; case RDS_TYPE_URL_V2: case RDS_TYPE_URL_V3: errorString = this.adsState.rds.handleResponses( - getResponseMessages(RDS_TYPE_URL_V3, [RDS_TYPE_URL_V2, RDS_TYPE_URL_V3], message.resources) + getResponseMessages(RDS_TYPE_URL_V3, [RDS_TYPE_URL_V2, RDS_TYPE_URL_V3], message.resources), + isV2 ); serviceKind = 'rds'; break; case LDS_TYPE_URL_V2: case LDS_TYPE_URL_V3: errorString = this.adsState.lds.handleResponses( - getResponseMessages(LDS_TYPE_URL_V3, [LDS_TYPE_URL_V2, LDS_TYPE_URL_V3], message.resources) + getResponseMessages(LDS_TYPE_URL_V3, [LDS_TYPE_URL_V2, LDS_TYPE_URL_V3], message.resources), + isV2 ); serviceKind = 'lds'; break; diff --git a/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts index a6e89805d..7720c5673 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts @@ -36,6 +36,7 @@ export class CdsState implements XdsStreamState { >(); private latestResponses: Cluster__Output[] = []; + private latestIsV2 = false; constructor( private edsState: EdsState, @@ -61,13 +62,14 @@ export class CdsState implements XdsStreamState { /* If we have already received an update for the requested edsServiceName, * immediately pass that update along to the watcher */ + const isV2 = this.latestIsV2; for (const message of this.latestResponses) { if (message.name === clusterName) { /* These updates normally occur asynchronously, so we ensure that * the same happens here */ process.nextTick(() => { trace('Reporting existing CDS update for new watcher for clusterName ' + clusterName); - watcher.onValidUpdate(message); + watcher.onValidUpdate(message, isV2); }); } } @@ -134,7 +136,7 @@ export class CdsState implements XdsStreamState { } } - handleResponses(responses: Cluster__Output[]): string | null { + handleResponses(responses: Cluster__Output[], isV2: boolean): string | null { for (const message of responses) { if (!this.validateResponse(message)) { trace('CDS validation failed for message ' + JSON.stringify(message)); @@ -142,6 +144,7 @@ export class CdsState implements XdsStreamState { } } this.latestResponses = responses; + this.latestIsV2 = isV2; const allEdsServiceNames: Set = new Set(); const allClusterNames: Set = new Set(); for (const message of responses) { @@ -152,7 +155,7 @@ export class CdsState implements XdsStreamState { ); const watchers = this.watchers.get(message.name) ?? []; for (const watcher of watchers) { - watcher.onValidUpdate(message); + watcher.onValidUpdate(message, isV2); } } trace('Received CDS updates for cluster names ' + Array.from(allClusterNames)); diff --git a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts index a0fb5f4dc..dbf18ef81 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts @@ -36,6 +36,7 @@ export class EdsState implements XdsStreamState { > = new Map[]>(); private latestResponses: ClusterLoadAssignment__Output[] = []; + private latestIsV2 = false; constructor(private updateResourceNames: () => void) {} @@ -61,13 +62,14 @@ export class EdsState implements XdsStreamState { /* If we have already received an update for the requested edsServiceName, * immediately pass that update along to the watcher */ + const isV2 = this.latestIsV2; for (const message of this.latestResponses) { if (message.cluster_name === edsServiceName) { /* These updates normally occur asynchronously, so we ensure that * the same happens here */ process.nextTick(() => { trace('Reporting existing EDS update for new watcher for edsServiceName ' + edsServiceName); - watcher.onValidUpdate(message); + watcher.onValidUpdate(message, isV2); }); } } @@ -143,7 +145,7 @@ export class EdsState implements XdsStreamState { } } - handleResponses(responses: ClusterLoadAssignment__Output[]) { + handleResponses(responses: ClusterLoadAssignment__Output[], isV2: boolean) { for (const message of responses) { if (!this.validateResponse(message)) { trace('EDS validation failed for message ' + JSON.stringify(message)); @@ -151,12 +153,13 @@ export class EdsState implements XdsStreamState { } } this.latestResponses = responses; + this.latestIsV2 = isV2; const allClusterNames: Set = new Set(); for (const message of responses) { allClusterNames.add(message.cluster_name); const watchers = this.watchers.get(message.cluster_name) ?? []; for (const watcher of watchers) { - watcher.onValidUpdate(message); + watcher.onValidUpdate(message, isV2); } } trace('Received EDS updates for cluster names ' + Array.from(allClusterNames)); diff --git a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts index 8ab6ed9d2..7e8ec0456 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts @@ -39,6 +39,7 @@ export class LdsState implements XdsStreamState { private watchers: Map[]> = new Map[]>(); private latestResponses: Listener__Output[] = []; + private latestIsV2 = false; constructor(private rdsState: RdsState, private updateResourceNames: () => void) {} @@ -55,13 +56,14 @@ export class LdsState implements XdsStreamState { /* If we have already received an update for the requested edsServiceName, * immediately pass that update along to the watcher */ + const isV2 = this.latestIsV2; for (const message of this.latestResponses) { if (message.name === targetName) { /* These updates normally occur asynchronously, so we ensure that * the same happens here */ process.nextTick(() => { trace('Reporting existing RDS update for new watcher for targetName ' + targetName); - watcher.onValidUpdate(message); + watcher.onValidUpdate(message, isV2); }); } } @@ -93,7 +95,7 @@ export class LdsState implements XdsStreamState { return Array.from(this.watchers.keys()); } - private validateResponse(message: Listener__Output): boolean { + private validateResponse(message: Listener__Output, isV2: boolean): boolean { if ( !( message.api_listener?.api_listener && @@ -104,7 +106,7 @@ export class LdsState implements XdsStreamState { return false; } const httpConnectionManager = decodeSingleResource(HTTP_CONNECTION_MANGER_TYPE_URL_V3, message.api_listener!.api_listener.value); - if (EXPERIMENTAL_FAULT_INJECTION) { + if (!isV2 && EXPERIMENTAL_FAULT_INJECTION) { const filterNames = new Set(); for (const [index, httpFilter] of httpConnectionManager.http_filters.entries()) { if (filterNames.has(httpFilter.name)) { @@ -136,7 +138,7 @@ export class LdsState implements XdsStreamState { case 'rds': return !!httpConnectionManager.rds?.config_source?.ads; case 'route_config': - return this.rdsState.validateResponse(httpConnectionManager.route_config!); + return this.rdsState.validateResponse(httpConnectionManager.route_config!, isV2); } return false; } @@ -151,20 +153,21 @@ export class LdsState implements XdsStreamState { } } - handleResponses(responses: Listener__Output[]): string | null { + handleResponses(responses: Listener__Output[], isV2: boolean): string | null { for (const message of responses) { - if (!this.validateResponse(message)) { + if (!this.validateResponse(message, isV2)) { trace('LDS validation failed for message ' + JSON.stringify(message)); return 'LDS Error: Route validation failed'; } } this.latestResponses = responses; + this.latestIsV2 = isV2; const allTargetNames = new Set(); for (const message of responses) { allTargetNames.add(message.name); const watchers = this.watchers.get(message.name) ?? []; for (const watcher of watchers) { - watcher.onValidUpdate(message); + watcher.onValidUpdate(message, isV2); } } trace('Received RDS response with route config names ' + Array.from(allTargetNames)); diff --git a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts index 58f11f0b4..9194529d8 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts @@ -45,6 +45,7 @@ export class RdsState implements XdsStreamState { private watchers: Map[]> = new Map[]>(); private latestResponses: RouteConfiguration__Output[] = []; + private latestIsV2 = false; constructor(private updateResourceNames: () => void) {} @@ -61,13 +62,14 @@ export class RdsState implements XdsStreamState { /* If we have already received an update for the requested edsServiceName, * immediately pass that update along to the watcher */ + const isV2 = this.latestIsV2; for (const message of this.latestResponses) { if (message.name === routeConfigName) { /* These updates normally occur asynchronously, so we ensure that * the same happens here */ process.nextTick(() => { trace('Reporting existing RDS update for new watcher for routeConfigName ' + routeConfigName); - watcher.onValidUpdate(message); + watcher.onValidUpdate(message, isV2); }); } } @@ -99,7 +101,7 @@ export class RdsState implements XdsStreamState { return Array.from(this.watchers.keys()); } - validateResponse(message: RouteConfiguration__Output): boolean { + validateResponse(message: RouteConfiguration__Output, isV2: boolean): boolean { // https://github.com/grpc/proposal/blob/master/A28-xds-traffic-splitting-and-routing.md#response-validation for (const virtualHost of message.virtual_hosts) { for (const domainPattern of virtualHost.domains) { @@ -114,7 +116,7 @@ export class RdsState implements XdsStreamState { return false; } } - if (EXPERIMENTAL_FAULT_INJECTION) { + if (!isV2 && EXPERIMENTAL_FAULT_INJECTION) { for (const filterConfig of Object.values(virtualHost.typed_per_filter_config ?? {})) { if (!validateOverrideFilter(filterConfig)) { return false; @@ -140,7 +142,7 @@ export class RdsState implements XdsStreamState { if ((route.route === undefined) || (route.route === null) || SUPPORTED_CLUSTER_SPECIFIERS.indexOf(route.route.cluster_specifier) < 0) { return false; } - if (EXPERIMENTAL_FAULT_INJECTION) { + if (!isV2 && EXPERIMENTAL_FAULT_INJECTION) { for (const [name, filterConfig] of Object.entries(route.typed_per_filter_config ?? {})) { if (!validateOverrideFilter(filterConfig)) { return false; @@ -155,7 +157,7 @@ export class RdsState implements XdsStreamState { if (weightSum !== route.route.weighted_clusters!.total_weight?.value ?? 100) { return false; } - if (EXPERIMENTAL_FAULT_INJECTION) { + if (!isV2 && EXPERIMENTAL_FAULT_INJECTION) { for (const weightedCluster of route.route!.weighted_clusters!.clusters) { for (const filterConfig of Object.values(weightedCluster.typed_per_filter_config ?? {})) { if (!validateOverrideFilter(filterConfig)) { @@ -180,20 +182,21 @@ export class RdsState implements XdsStreamState { } } - handleResponses(responses: RouteConfiguration__Output[]): string | null { + handleResponses(responses: RouteConfiguration__Output[], isV2: boolean): string | null { for (const message of responses) { - if (!this.validateResponse(message)) { + if (!this.validateResponse(message, isV2)) { trace('RDS validation failed for message ' + JSON.stringify(message)); return 'RDS Error: Route validation failed'; } } this.latestResponses = responses; + this.latestIsV2 = isV2; const allRouteConfigNames = new Set(); for (const message of responses) { allRouteConfigNames.add(message.name); const watchers = this.watchers.get(message.name) ?? []; for (const watcher of watchers) { - watcher.onValidUpdate(message); + watcher.onValidUpdate(message, isV2); } } trace('Received RDS response with route config names ' + Array.from(allRouteConfigNames)); diff --git a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts index 83db1781e..14f3d1c76 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts @@ -18,7 +18,12 @@ import { StatusObject } from "@grpc/grpc-js"; export interface Watcher { - onValidUpdate(update: UpdateType): void; + /* Including the isV2 flag here is a bit of a kludge. It would probably be + * better for XdsStreamState#handleResponses to transform the protobuf + * message type into a library-specific configuration object type, to + * remove a lot of duplicate logic, including logic for handling that + * flag. */ + onValidUpdate(update: UpdateType, isV2: boolean): void; onTransientError(error: StatusObject): void; onResourceDoesNotExist(): void; } @@ -32,7 +37,7 @@ export interface XdsStreamState { * or null if it should be acked. * @param responses */ - handleResponses(responses: ResponseType[]): string | null; + handleResponses(responses: ResponseType[], isV2: boolean): string | null; reportStreamError(status: StatusObject): void; } \ No newline at end of file From d4574a28fbaba840454bd62914a5d980661b0f31 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 3 Aug 2021 09:28:32 -0700 Subject: [PATCH 066/450] grpc-js: Add channelz support --- packages/grpc-js/src/call-stream.ts | 14 + packages/grpc-js/src/channel.ts | 43 ++- packages/grpc-js/src/channelz.ts | 345 ++++++++++++++++++ .../src/load-balancer-child-handler.ts | 8 + .../grpc-js/src/load-balancer-pick-first.ts | 5 + .../grpc-js/src/load-balancer-round-robin.ts | 2 + packages/grpc-js/src/load-balancer.ts | 3 + .../grpc-js/src/resolving-load-balancer.ts | 8 +- packages/grpc-js/src/server-call.ts | 11 +- packages/grpc-js/src/server.ts | 233 ++++++++++-- packages/grpc-js/src/subchannel-address.ts | 17 + packages/grpc-js/src/subchannel.ts | 166 ++++++++- packages/grpc-tools/deps/protobuf | 2 +- 13 files changed, 826 insertions(+), 31 deletions(-) create mode 100644 packages/grpc-js/src/channelz.ts diff --git a/packages/grpc-js/src/call-stream.ts b/packages/grpc-js/src/call-stream.ts index 87121154d..e030d9e39 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -249,6 +249,9 @@ export class Http2CallStream implements Call { private configDeadline: Deadline = Infinity; + private statusWatchers: ((status: StatusObject) => void)[] = []; + private streamEndWatchers: ((success: boolean) => void)[] = []; + constructor( private readonly methodName: string, private readonly channel: ChannelImplementation, @@ -283,6 +286,7 @@ export class Http2CallStream implements Call { const filteredStatus = this.filterStack.receiveTrailers( this.finalStatus! ); + this.statusWatchers.forEach(watcher => watcher(filteredStatus)); /* We delay the actual action of bubbling up the status to insulate the * cleanup code in this class from any errors that may be thrown in the * upper layers as a result of bubbling up the status. In particular, @@ -426,6 +430,7 @@ export class Http2CallStream implements Call { } private handleTrailers(headers: http2.IncomingHttpHeaders) { + this.streamEndWatchers.forEach(watcher => watcher(true)); let headersString = ''; for (const header of Object.keys(headers)) { headersString += '\t\t' + header + ': ' + headers[header] + '\n'; @@ -647,6 +652,7 @@ export class Http2CallStream implements Call { ); this.internalError = err; } + this.streamEndWatchers.forEach(watcher => watcher(false)); }); if (!this.pendingRead) { stream.pause(); @@ -736,6 +742,14 @@ export class Http2CallStream implements Call { this.configDeadline = configDeadline; } + addStatusWatcher(watcher: (status: StatusObject) => void) { + this.statusWatchers.push(watcher); + } + + addStreamEndWatcher(watcher: (success: boolean) => void) { + this.streamEndWatchers.push(watcher); + } + startRead() { /* If the stream has ended with an error, we should not emit any more * messages and we should communicate that the stream has ended */ diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 9200043e4..4a6e88147 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -47,6 +47,7 @@ import { GrpcUri, parseUri, uriToString } from './uri-parser'; import { ServerSurfaceCall } from './server-call'; import { SurfaceCall } from './call'; import { ConnectivityState } from './connectivity-state'; +import { ChannelInfo, ChannelRef, ChannelzCallTracker, ChannelzChildrenTracker, ChannelzTrace, registerChannelzChannel, SubchannelRef, unregisterChannelzRef } from './channelz'; /** * See https://nodejs.org/api/timers.html#timers_setinterval_callback_delay_args @@ -160,6 +161,13 @@ export class ChannelImplementation implements Channel { */ private callRefTimer: NodeJS.Timer; private configSelector: ConfigSelector | null = null; + + // Channelz info + private channelzRef: ChannelRef; + private channelzTrace: ChannelzTrace; + private callTracker = new ChannelzCallTracker(); + private childrenTracker = new ChannelzChildrenTracker(); + constructor( target: string, private readonly credentials: ChannelCredentials, @@ -204,6 +212,10 @@ export class ChannelImplementation implements Channel { this.callRefTimer = setInterval(() => {}, MAX_TIMEOUT_TIME); this.callRefTimer.unref?.(); + this.channelzRef = registerChannelzChannel(target, () => this.getChannelzInfo()); + this.channelzTrace = new ChannelzTrace(); + this.channelzTrace.addTrace('CT_INFO', 'Channel created'); + if (this.options['grpc.default_authority']) { this.defaultAuthority = this.options['grpc.default_authority'] as string; } else { @@ -223,12 +235,14 @@ export class ChannelImplementation implements Channel { subchannelAddress: SubchannelAddress, subchannelArgs: ChannelOptions ) => { - return this.subchannelPool.getOrCreateSubchannel( + const subchannel = this.subchannelPool.getOrCreateSubchannel( this.target, subchannelAddress, Object.assign({}, this.options, subchannelArgs), this.credentials ); + this.channelzTrace.addTrace('CT_INFO', 'Created or got existing subchannel', subchannel.getChannelzRef()); + return subchannel; }, updateState: (connectivityState: ConnectivityState, picker: Picker) => { this.currentPicker = picker; @@ -246,12 +260,19 @@ export class ChannelImplementation implements Channel { 'Resolving load balancer should never call requestReresolution' ); }, + addChannelzChild: (child: ChannelRef | SubchannelRef) => { + this.childrenTracker.refChild(child); + }, + removeChannelzChild: (child: ChannelRef | SubchannelRef) => { + this.childrenTracker.unrefChild(child); + } }; this.resolvingLoadBalancer = new ResolvingLoadBalancer( this.target, channelControlHelper, options, (configSelector) => { + this.channelzTrace.addTrace('CT_INFO', 'Address resolution succeeded'); this.configSelector = configSelector; /* We process the queue asynchronously to ensure that the corresponding * load balancer update has completed. */ @@ -266,6 +287,7 @@ export class ChannelImplementation implements Channel { }); }, (status) => { + this.channelzTrace.addTrace('CT_WARNING', 'Address resolution failed with code ' + status.code + ' and details "' + status.details + '"'); if (this.configSelectionQueue.length > 0) { trace( LogVerbosity.DEBUG, @@ -296,6 +318,15 @@ export class ChannelImplementation implements Channel { ]); } + private getChannelzInfo(): ChannelInfo { + return { + state: this.connectivityState, + trace: this.channelzTrace, + callTracker: this.callTracker, + children: this.childrenTracker.getChildLists() + }; + } + private callRefTimerRef() { // If the hasRef function does not exist, always run the code if (!this.callRefTimer.hasRef?.()) { @@ -526,6 +557,7 @@ export class ChannelImplementation implements Channel { ' -> ' + ConnectivityState[newState] ); + this.channelzTrace.addTrace('CT_INFO', ConnectivityState[this.connectivityState] + ' -> ' + ConnectivityState[newState]); this.connectivityState = newState; const watchersCopy = this.connectivityStateWatchers.slice(); for (const watcherObject of watchersCopy) { @@ -590,6 +622,7 @@ export class ChannelImplementation implements Channel { this.resolvingLoadBalancer.destroy(); this.updateState(ConnectivityState.SHUTDOWN); clearInterval(this.callRefTimer); + unregisterChannelzRef(this.channelzRef); this.subchannelPool.unrefUnusedSubchannels(); } @@ -685,6 +718,14 @@ export class ChannelImplementation implements Channel { this.credentials._getCallCredentials(), callNumber ); + this.callTracker.addCallStarted(); + stream.addStatusWatcher(status => { + if (status.code === Status.OK) { + this.callTracker.addCallSucceeded(); + } else { + this.callTracker.addCallFailed(); + } + }); return stream; } } diff --git a/packages/grpc-js/src/channelz.ts b/packages/grpc-js/src/channelz.ts new file mode 100644 index 000000000..3edbd7bba --- /dev/null +++ b/packages/grpc-js/src/channelz.ts @@ -0,0 +1,345 @@ +/* + * Copyright 2021 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 { isIPv4, isIPv6 } from "net"; +import { ConnectivityState } from "./connectivity-state"; +import { SubchannelAddress } from "./subchannel-address"; + +export type TraceSeverity = 'CT_UNKNOWN' | 'CT_INFO' | 'CT_WARNING' | 'CT_ERROR'; + +export interface ChannelRef { + kind: 'channel'; + id: number; + name: string; +} + +export interface SubchannelRef { + kind: 'subchannel'; + id: number; + name: string; +} + +export interface ServerRef { + kind: 'server'; + id: number; +} + +export interface SocketRef { + kind: 'socket'; + id: number; + name: string; +} + +interface TraceEvent { + description: string; + severity: TraceSeverity; + timestamp: Date; + childChannel?: ChannelRef; + childSubchannel?: SubchannelRef; +} + +export class ChannelzTrace { + events: TraceEvent[] = []; + creationTimestamp: Date; + eventsLogged: number = 0; + + constructor() { + this.creationTimestamp = new Date(); + } + + addTrace(severity: TraceSeverity, description: string, child?: ChannelRef | SubchannelRef) { + const timestamp = new Date(); + this.events.push({ + description: description, + severity: severity, + timestamp: timestamp, + childChannel: child?.kind === 'channel' ? child : undefined, + childSubchannel: child?.kind === 'subchannel' ? child : undefined + }); + this.eventsLogged += 1; + } +} + +export class ChannelzChildrenTracker { + private channelChildren: Map = new Map(); + private subchannelChildren: Map = new Map(); + private socketChildren: Map = new Map(); + + refChild(child: ChannelRef | SubchannelRef | SocketRef) { + switch (child.kind) { + case 'channel': { + let trackedChild = this.channelChildren.get(child.id) ?? {ref: child, count: 0}; + trackedChild.count += 1; + this.channelChildren.set(child.id, trackedChild); + break; + } + case 'subchannel':{ + let trackedChild = this.subchannelChildren.get(child.id) ?? {ref: child, count: 0}; + trackedChild.count += 1; + this.subchannelChildren.set(child.id, trackedChild); + break; + } + case 'socket':{ + let trackedChild = this.socketChildren.get(child.id) ?? {ref: child, count: 0}; + trackedChild.count += 1; + this.socketChildren.set(child.id, trackedChild); + break; + } + } + } + + unrefChild(child: ChannelRef | SubchannelRef | SocketRef) { + switch (child.kind) { + case 'channel': { + let 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': { + let 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': { + let 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; + } + } + } + + 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}; + } +} + +export class ChannelzCallTracker { + callsStarted: number = 0; + callsSucceeded: number = 0; + callsFailed: number = 0; + lastCallStartedTimestamp: Date | null = null; + + addCallStarted() { + this.callsStarted += 1; + this.lastCallStartedTimestamp = new Date(); + } + addCallSucceeded() { + this.callsSucceeded += 1; + } + addCallFailed() { + this.callsFailed += 1; + } +} + +export interface ChannelzChildren { + channels: ChannelRef[]; + subchannels: SubchannelRef[]; + sockets: SocketRef[]; +} + +export interface ChannelInfo { + state: ConnectivityState; + trace: ChannelzTrace; + callTracker: ChannelzCallTracker; + children: ChannelzChildren; +} + +export interface SubchannelInfo extends ChannelInfo {} + +export interface ServerInfo { + trace: ChannelzTrace; + callTracker: ChannelzCallTracker; + children: ChannelzChildren; +} + +export interface TlsInfo { + cipherSuiteStandardName: string | null; + cipherSuiteOtherName: string | null; + localCertificate: Buffer | null; + remoteCertificate: Buffer | null; +} + +export interface SocketInfo { + localAddress: SubchannelAddress; + remoteAddress: SubchannelAddress | null; + security: TlsInfo | null; + remoteName: string | null; + streamsStarted: number; + streamsSucceeded: number; + streamsFailed: number; + messagesSent: number; + messagesReceived: number; + keepAlivesSent: number; + lastLocalStreamCreatedTimestamp: Date | null; + lastRemoteStreamCreatedTimestamp: Date | null; + lastMessageSentTimestamp: Date | null; + lastMessageReceivedTimestamp: Date | null; + localFlowControlWindow: number | null; + remoteFlowControlWindow: number | null; +} + +interface ChannelEntry { + ref: ChannelRef; + getInfo(): ChannelInfo; +} + +interface SubchannelEntry { + ref: SubchannelRef; + getInfo(): SubchannelInfo; +} + +interface ServerEntry { + ref: ServerRef; + getInfo(): ServerInfo; +} + +interface 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): ChannelRef { + const id = getNextId(); + const ref: ChannelRef = {id, name, kind: 'channel'}; + channels[id] = { ref, getInfo }; + return ref; +} + +export function registerChannelzSubchannel(name: string, getInfo:() => SubchannelInfo): SubchannelRef { + const id = getNextId(); + const ref: SubchannelRef = {id, name, kind: 'subchannel'}; + subchannels[id] = { ref, getInfo }; + return ref; +} + +export function registerChannelzServer(getInfo: () => ServerInfo): ServerRef { + const id = getNextId(); + const ref: ServerRef = {id, kind: 'server'}; + servers[id] = { ref, getInfo }; + return ref; +} + +export function registerChannelzSocket(name: string, getInfo: () => SocketInfo): SocketRef { + const id = getNextId(); + const ref: SocketRef = {id, name, kind: 'socket'}; + sockets[id] = { ref, getInfo}; + return ref; +} + +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; + } +} + +export interface ChannelzClientView { + updateState(connectivityState: ConnectivityState): void; + addTrace(severity: TraceSeverity, description: string, child?: ChannelRef | SubchannelRef): void; + addCallStarted(): void; + addCallSucceeded(): void; + addCallFailed(): void; + addChild(child: ChannelRef | SubchannelRef): void; + removeChild(child: ChannelRef | SubchannelRef): void; +} + +export interface ChannelzSubchannelView extends ChannelzClientView { + getRef(): SubchannelRef; +} + +/** + * Converts an IPv4 or IPv6 address from string representation to binary + * representation + * @param ipAddress an IP address in standard IPv4 or IPv6 text format + * @returns + */ +function ipAddressStringToBuffer(ipAddress: string): Buffer | null { + if (isIPv4(ipAddress)) { + return Buffer.from(Uint8Array.from(ipAddress.split('.').map(segment => Number.parseInt(segment)))); + } else if (isIPv6(ipAddress)) { + let leftSection: string; + let rightSection: string | null; + const doubleColonIndex = ipAddress.indexOf('::'); + if (doubleColonIndex === -1) { + leftSection = ipAddress; + rightSection = null; + } else { + leftSection = ipAddress.substring(0, doubleColonIndex); + rightSection = ipAddress.substring(doubleColonIndex + 2); + } + const leftBuffer = Uint8Array.from(leftSection.split(':').map(segment => Number.parseInt(segment, 16))); + const rightBuffer = rightSection ? Uint8Array.from(rightSection.split(':').map(segment => Number.parseInt(segment, 16))) : new Uint8Array(); + const middleBuffer = Buffer.alloc(16 - leftBuffer.length - rightBuffer.length, 0); + return Buffer.concat([leftBuffer, middleBuffer, rightBuffer]); + } else { + return null; + } +} \ No newline at end of file diff --git a/packages/grpc-js/src/load-balancer-child-handler.ts b/packages/grpc-js/src/load-balancer-child-handler.ts index 8fae7b8a6..c53914942 100644 --- a/packages/grpc-js/src/load-balancer-child-handler.ts +++ b/packages/grpc-js/src/load-balancer-child-handler.ts @@ -26,6 +26,7 @@ import { SubchannelAddress } from './subchannel-address'; import { ChannelOptions } from './channel-options'; import { ConnectivityState } from './connectivity-state'; import { Picker } from './picker'; +import { ChannelRef, SubchannelRef } from './channelz'; const TYPE_NAME = 'child_load_balancer_helper'; @@ -67,6 +68,13 @@ export class ChildLoadBalancerHandler implements LoadBalancer { setChild(newChild: LoadBalancer) { this.child = newChild; } + addChannelzChild(child: ChannelRef | SubchannelRef) { + this.parent.channelControlHelper.addChannelzChild(child); + } + removeChannelzChild(child: ChannelRef | SubchannelRef) { + this.parent.channelControlHelper.removeChannelzChild(child); + } + private calledByPendingChild(): boolean { return this.child === this.parent.pendingChild; } diff --git a/packages/grpc-js/src/load-balancer-pick-first.ts b/packages/grpc-js/src/load-balancer-pick-first.ts index 65179b163..6cdb7cb91 100644 --- a/packages/grpc-js/src/load-balancer-pick-first.ts +++ b/packages/grpc-js/src/load-balancer-pick-first.ts @@ -229,6 +229,7 @@ export class PickFirstLoadBalancer implements LoadBalancer { subchannel.removeConnectivityStateListener( this.pickedSubchannelStateListener ); + this.channelControlHelper.removeChannelzChild(subchannel.getChannelzRef()); if (this.subchannels.length > 0) { if (this.triedAllSubchannels) { let newLBState: ConnectivityState; @@ -321,6 +322,7 @@ export class PickFirstLoadBalancer implements LoadBalancer { this.updateState(ConnectivityState.READY, new PickFirstPicker(subchannel)); subchannel.addConnectivityStateListener(this.pickedSubchannelStateListener); subchannel.ref(); + this.channelControlHelper.addChannelzChild(subchannel.getChannelzRef()); this.resetSubchannelList(); clearTimeout(this.connectionDelayTimeout); } @@ -339,6 +341,7 @@ export class PickFirstLoadBalancer implements LoadBalancer { for (const subchannel of this.subchannels) { subchannel.removeConnectivityStateListener(this.subchannelStateListener); subchannel.unref(); + this.channelControlHelper.removeChannelzChild(subchannel.getChannelzRef()); } this.currentSubchannelIndex = 0; this.subchannelStateCounts = { @@ -369,6 +372,7 @@ export class PickFirstLoadBalancer implements LoadBalancer { ); for (const subchannel of this.subchannels) { subchannel.ref(); + this.channelControlHelper.addChannelzChild(subchannel.getChannelzRef()); } for (const subchannel of this.subchannels) { subchannel.addConnectivityStateListener(this.subchannelStateListener); @@ -449,6 +453,7 @@ export class PickFirstLoadBalancer implements LoadBalancer { this.currentPick.removeConnectivityStateListener( this.pickedSubchannelStateListener ); + this.channelControlHelper.removeChannelzChild(this.currentPick.getChannelzRef()); } } diff --git a/packages/grpc-js/src/load-balancer-round-robin.ts b/packages/grpc-js/src/load-balancer-round-robin.ts index 56703397f..918afab25 100644 --- a/packages/grpc-js/src/load-balancer-round-robin.ts +++ b/packages/grpc-js/src/load-balancer-round-robin.ts @@ -191,6 +191,7 @@ export class RoundRobinLoadBalancer implements LoadBalancer { for (const subchannel of this.subchannels) { subchannel.removeConnectivityStateListener(this.subchannelStateListener); subchannel.unref(); + this.channelControlHelper.removeChannelzChild(subchannel.getChannelzRef()); } this.subchannelStateCounts = { [ConnectivityState.CONNECTING]: 0, @@ -217,6 +218,7 @@ export class RoundRobinLoadBalancer implements LoadBalancer { for (const subchannel of this.subchannels) { subchannel.ref(); subchannel.addConnectivityStateListener(this.subchannelStateListener); + this.channelControlHelper.addChannelzChild(subchannel.getChannelzRef()); const subchannelState = subchannel.getConnectivityState(); this.subchannelStateCounts[subchannelState] += 1; if ( diff --git a/packages/grpc-js/src/load-balancer.ts b/packages/grpc-js/src/load-balancer.ts index f509f73eb..870fdb30b 100644 --- a/packages/grpc-js/src/load-balancer.ts +++ b/packages/grpc-js/src/load-balancer.ts @@ -20,6 +20,7 @@ import { Subchannel } from './subchannel'; import { SubchannelAddress } from './subchannel-address'; import { ConnectivityState } from './connectivity-state'; import { Picker } from './picker'; +import { ChannelRef, SubchannelRef } from './channelz'; /** * A collection of functions associated with a channel that a load balancer @@ -47,6 +48,8 @@ export interface ChannelControlHelper { * Request new data from the resolver. */ requestReresolution(): void; + addChannelzChild(child: ChannelRef | SubchannelRef): void; + removeChannelzChild(child: ChannelRef | SubchannelRef): void; } /** diff --git a/packages/grpc-js/src/resolving-load-balancer.ts b/packages/grpc-js/src/resolving-load-balancer.ts index 5729937d1..a03991bc7 100644 --- a/packages/grpc-js/src/resolving-load-balancer.ts +++ b/packages/grpc-js/src/resolving-load-balancer.ts @@ -75,7 +75,7 @@ function getDefaultConfigSelector( return { methodConfig: { name: [] }, pickInformation: {}, - status: Status.OK, + status: Status.OK }; }; } @@ -170,6 +170,12 @@ export class ResolvingLoadBalancer implements LoadBalancer { this.latestChildPicker = picker; this.updateState(newState, picker); }, + addChannelzChild: channelControlHelper.addChannelzChild.bind( + channelControlHelper + ), + removeChannelzChild: channelControlHelper.removeChannelzChild.bind( + channelControlHelper + ) }); this.innerResolver = createResolver( target, diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index 4d24cdc86..cde7d9185 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -411,6 +411,8 @@ export class Http2ServerCallStream< ); this.cancelled = true; this.emit('cancelled', 'cancelled'); + this.emit('streamEnd', false); + this.sendStatus({code: Status.CANCELLED, details: 'Cancelled by client', metadata: new Metadata()}); }); this.stream.on('drain', () => { @@ -513,6 +515,7 @@ export class Http2ServerCallStream< resolve(); } + this.emit('receiveMessage'); resolve(this.deserializeMessage(requestBytes)); } catch (err) { err.code = Status.INTERNAL; @@ -567,6 +570,7 @@ export class Http2ServerCallStream< const response = this.serializeMessage(value!); this.write(response); + this.emit('sendMessage'); this.sendStatus({ code: Status.OK, details: 'OK', metadata }); } catch (err) { err.code = Status.INTERNAL; @@ -575,6 +579,8 @@ export class Http2ServerCallStream< } sendStatus(statusObj: StatusObject) { + this.emit('callEnd', statusObj.code); + this.emit('streamEnd', statusObj.code === Status.OK); if (this.checkCancelled()) { return; } @@ -609,9 +615,6 @@ export class Http2ServerCallStream< } sendError(error: ServerErrorResponse | ServerStatusResponse) { - if (this.checkCancelled()) { - return; - } const status: StatusObject = { code: Status.UNKNOWN, details: 'message' in error ? error.message : 'Unknown Error', @@ -653,6 +656,7 @@ export class Http2ServerCallStream< } this.sendMetadata(); + this.emit('sendMessage'); return this.stream.write(chunk); } @@ -688,6 +692,7 @@ export class Http2ServerCallStream< }); return; } + this.emit('receiveMessage'); this.pushOrBufferMessage(readable, message); } }); diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 42b79a3cf..04c24c072 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -56,8 +56,11 @@ import { TcpSubchannelAddress, isTcpSubchannelAddress, subchannelAddressToString, + stringToSubchannelAddress, } from './subchannel-address'; import { parseUri } from './uri-parser'; +import { ChannelzCallTracker, ChannelzChildrenTracker, ChannelzTrace, registerChannelzServer, registerChannelzSocket, ServerInfo, ServerRef, SocketInfo, SocketRef, TlsInfo, unregisterChannelzRef } from './channelz'; +import { CipherNameAndProtocol, TLSSocket } from 'tls'; const TRACER_NAME = 'server'; @@ -125,19 +128,91 @@ function getDefaultHandler(handlerType: HandlerType, methodName: string) { } } +interface ChannelzSessionInfo { + ref: SocketRef; + streamTracker: ChannelzCallTracker; + messagesSent: number; + messagesReceived: number; + lastMessageSentTimestamp: Date | null; + lastMessageReceivedTimestamp: Date | null; +} + +interface ChannelzListenerInfo { + ref: SocketRef; +} + export class Server { - private http2ServerList: (http2.Http2Server | http2.Http2SecureServer)[] = []; + private http2ServerList: { server: (http2.Http2Server | http2.Http2SecureServer), channelzRef: SocketRef }[] = []; private handlers: Map = new Map< string, UntypedHandler >(); - private sessions = new Set(); + private sessions = new Map(); private started = false; private options: ChannelOptions; + // Channelz Info + private channelzRef: ServerRef; + private channelzTrace = new ChannelzTrace(); + private callTracker = new ChannelzCallTracker(); + private childrenTracker = new ChannelzChildrenTracker(); + constructor(options?: ChannelOptions) { this.options = options ?? {}; + this.channelzRef = registerChannelzServer(() => this.getChannelzInfo()); + this.channelzTrace.addTrace('CT_INFO', 'Server created'); + } + + private getChannelzInfo(): ServerInfo { + return { + trace: this.channelzTrace, + callTracker: this.callTracker, + children: this.childrenTracker.getChildLists() + }; + } + + 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 = stringToSubchannelAddress(sessionSocket.localAddress, sessionSocket.localPort); + 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 ? cipherInfo.name: null, + 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: 0, + lastLocalStreamCreatedTimestamp: null, + lastRemoteStreamCreatedTimestamp: sessionInfo.streamTracker.lastCallStartedTimestamp, + lastMessageSentTimestamp: sessionInfo.lastMessageSentTimestamp, + lastMessageReceivedTimestamp: sessionInfo.lastMessageReceivedTimestamp, + localFlowControlWindow: session.state.localWindowSize ?? null, + remoteFlowControlWindow: session.state.remoteWindowSize ?? null + }; + return socketInfo; + }; } addProtoService(): void { @@ -315,14 +390,41 @@ export class Server { http2Server.once('error', onError); http2Server.listen(addr, () => { - trace('Successfully bound ' + subchannelAddressToString(address)); - this.http2ServerList.push(http2Server); const boundAddress = http2Server.address()!; + let boundSubchannelAddress: SubchannelAddress; if (typeof boundAddress === 'string') { - resolve(portNum); + boundSubchannelAddress = { + path: boundAddress + }; } else { - resolve(boundAddress.port); + boundSubchannelAddress = { + host: boundAddress.address, + port: boundAddress.port + } } + const channelzRef = registerChannelzSocket(subchannelAddressToString(boundSubchannelAddress), () => { + return { + localAddress: boundSubchannelAddress, + remoteAddress: null, + security: null, + remoteName: null, + streamsStarted: 0, + streamsSucceeded: 0, + streamsFailed: 0, + messagesSent: 0, + messagesReceived: 0, + keepAlivesSent: 0, + lastLocalStreamCreatedTimestamp: null, + lastRemoteStreamCreatedTimestamp: null, + lastMessageSentTimestamp: null, + lastMessageReceivedTimestamp: null, + localFlowControlWindow: null, + remoteFlowControlWindow: null + }; + }); + this.http2ServerList.push({server: http2Server, channelzRef: channelzRef}); + trace('Successfully bound ' + subchannelAddressToString(boundSubchannelAddress)); + resolve('port' in boundSubchannelAddress ? boundSubchannelAddress.port : portNum); http2Server.removeListener('error', onError); }); }); @@ -362,11 +464,37 @@ export class Server { http2Server.once('error', onError); http2Server.listen(address, () => { - this.http2ServerList.push(http2Server); + const boundAddress = http2Server.address() as AddressInfo; + const boundSubchannelAddress: SubchannelAddress = { + host: boundAddress.address, + port: boundAddress.port + }; + const channelzRef = registerChannelzSocket(subchannelAddressToString(boundSubchannelAddress), () => { + return { + localAddress: boundSubchannelAddress, + remoteAddress: null, + security: null, + remoteName: null, + streamsStarted: 0, + streamsSucceeded: 0, + streamsFailed: 0, + messagesSent: 0, + messagesReceived: 0, + keepAlivesSent: 0, + lastLocalStreamCreatedTimestamp: null, + lastRemoteStreamCreatedTimestamp: null, + lastMessageSentTimestamp: null, + lastMessageReceivedTimestamp: null, + localFlowControlWindow: null, + remoteFlowControlWindow: null + }; + }); + this.http2ServerList.push({server: http2Server, channelzRef: channelzRef}); + trace('Successfully bound ' + subchannelAddressToString(boundSubchannelAddress)); resolve( bindSpecificPort( addressList.slice(1), - (http2Server.address() as AddressInfo).port, + boundAddress.port, 1 ) ); @@ -437,9 +565,12 @@ export class Server { forceShutdown(): void { // Close the server if it is still running. - for (const http2Server of this.http2ServerList) { + for (const {server: http2Server, channelzRef: ref} of this.http2ServerList) { if (http2Server.listening) { - http2Server.close(); + http2Server.close(() => { + this.childrenTracker.unrefChild(ref); + unregisterChannelzRef(ref); + }); } } @@ -447,13 +578,14 @@ export class Server { // Always destroy any available sessions. It's possible that one or more // tryShutdown() calls are in progress. Don't wait on them to finish. - this.sessions.forEach((session) => { + this.sessions.forEach((channelzInfo, session) => { // Cast NGHTTP2_CANCEL to any because TypeScript doesn't seem to // recognize destroy(code) as a valid signature. // eslint-disable-next-line @typescript-eslint/no-explicit-any session.destroy(http2.constants.NGHTTP2_CANCEL as any); }); this.sessions.clear(); + unregisterChannelzRef(this.channelzRef); } register( @@ -485,7 +617,7 @@ export class Server { if ( this.http2ServerList.length === 0 || this.http2ServerList.every( - (http2Server) => http2Server.listening !== true + ({server: http2Server}) => http2Server.listening !== true ) ) { throw new Error('server must be bound in order to start'); @@ -494,39 +626,47 @@ export class Server { if (this.started === true) { throw new Error('server is already started'); } - + this.channelzTrace.addTrace('CT_INFO', 'Starting'); this.started = true; } tryShutdown(callback: (error?: Error) => void): void { + const wrappedCallback = (error?: Error) => { + unregisterChannelzRef(this.channelzRef); + callback(error); + }; let pendingChecks = 0; function maybeCallback(): void { pendingChecks--; if (pendingChecks === 0) { - callback(); + wrappedCallback(); } } // Close the server if necessary. this.started = false; - for (const http2Server of this.http2ServerList) { + for (const {server: http2Server, channelzRef: ref} of this.http2ServerList) { if (http2Server.listening) { pendingChecks++; - http2Server.close(maybeCallback); + http2Server.close(() => { + this.childrenTracker.unrefChild(ref); + unregisterChannelzRef(ref); + maybeCallback(); + }); } } - this.sessions.forEach((session) => { + this.sessions.forEach((channelzInfo, session) => { if (!session.closed) { pendingChecks += 1; session.close(maybeCallback); } }); if (pendingChecks === 0) { - callback(); + wrappedCallback(); } } @@ -544,6 +684,9 @@ export class Server { http2Server.on( 'stream', (stream: http2.ServerHttp2Stream, headers: http2.IncomingHttpHeaders) => { + const channelzSessionInfo = this.sessions.get(stream.session as http2.ServerHttp2Session); + this.callTracker.addCallStarted(); + channelzSessionInfo?.streamTracker.addCallStarted(); const contentType = headers[http2.constants.HTTP2_HEADER_CONTENT_TYPE]; if ( @@ -557,9 +700,13 @@ export class Server { }, { endStream: true } ); + this.callTracker.addCallFailed(); + channelzSessionInfo?.streamTracker.addCallFailed(); return; } + let call: Http2ServerCallStream | null = null; + try { const path = headers[http2.constants.HTTP2_HEADER_PATH] as string; const serverAddress = http2Server.address(); @@ -589,7 +736,31 @@ export class Server { throw getUnimplementedStatusResponse(path); } - const call = new Http2ServerCallStream(stream, handler, this.options); + call = new Http2ServerCallStream(stream, handler, this.options); + call.once('callEnd', (code: Status) => { + if (code === Status.OK) { + this.callTracker.addCallSucceeded(); + } else { + this.callTracker.addCallFailed(); + } + }); + if (channelzSessionInfo) { + call.once('streamEnd', (success: boolean) => { + if (success) { + channelzSessionInfo.streamTracker.addCallSucceeded(); + } else { + channelzSessionInfo.streamTracker.addCallFailed(); + } + }); + call.on('sendMessage', () => { + channelzSessionInfo.messagesSent += 1; + channelzSessionInfo.lastMessageSentTimestamp = new Date(); + }); + call.on('receiveMessage', () => { + channelzSessionInfo.messagesReceived += 1; + channelzSessionInfo.lastMessageReceivedTimestamp = new Date(); + }); + } const metadata: Metadata = call.receiveMetadata(headers) as Metadata; switch (handler.type) { case 'unary': @@ -620,7 +791,11 @@ export class Server { throw new Error(`Unknown handler type: ${handler.type}`); } } catch (err) { - const call = new Http2ServerCallStream(stream, null!, this.options); + if (!call) { + call = new Http2ServerCallStream(stream, null!, this.options); + this.callTracker.addCallFailed(); + channelzSessionInfo?.streamTracker.addCallFailed() + } if (err.code === undefined) { err.code = Status.INTERNAL; @@ -637,9 +812,25 @@ export class Server { return; } - this.sessions.add(session); + const channelzRef = registerChannelzSocket(session.socket.remoteAddress ?? 'unknown', this.getChannelzSessionInfoGetter(session)); + + const channelzSessionInfo: ChannelzSessionInfo = { + ref: channelzRef, + streamTracker: new ChannelzCallTracker(), + messagesSent: 0, + messagesReceived: 0, + lastMessageSentTimestamp: null, + lastMessageReceivedTimestamp: null + }; + this.sessions.set(session, channelzSessionInfo); + const clientAddress = session.socket.remoteAddress; + this.channelzTrace.addTrace('CT_INFO', 'Connection established by client ' + clientAddress); + this.childrenTracker.refChild(channelzRef); session.on('close', () => { + this.channelzTrace.addTrace('CT_INFO', 'Connection dropped by client ' + clientAddress); + this.childrenTracker.unrefChild(channelzRef); + unregisterChannelzRef(channelzRef); this.sessions.delete(session); }); }); diff --git a/packages/grpc-js/src/subchannel-address.ts b/packages/grpc-js/src/subchannel-address.ts index 4b08d8ba1..29022caa5 100644 --- a/packages/grpc-js/src/subchannel-address.ts +++ b/packages/grpc-js/src/subchannel-address.ts @@ -15,6 +15,8 @@ * */ +import { isIP } from "net"; + export interface TcpSubchannelAddress { port: number; host: string; @@ -60,3 +62,18 @@ export function subchannelAddressToString(address: SubchannelAddress): string { return address.path; } } + +const DEFAULT_PORT = 443; + +export function stringToSubchannelAddress(addressString: string, port?: number): SubchannelAddress { + if (isIP(addressString)) { + return { + host: addressString, + port: port ?? DEFAULT_PORT + }; + } else { + return { + path: addressString + }; + } +} \ No newline at end of file diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index ae23feb3d..1caf94ba1 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -18,23 +18,25 @@ import * as http2 from 'http2'; import { ChannelCredentials } from './channel-credentials'; import { Metadata } from './metadata'; -import { Http2CallStream } from './call-stream'; +import { Call, Http2CallStream, WriteObject } from './call-stream'; import { ChannelOptions } from './channel-options'; -import { PeerCertificate, checkServerIdentity } from 'tls'; +import { PeerCertificate, checkServerIdentity, TLSSocket, CipherNameAndProtocol } from 'tls'; import { ConnectivityState } from './connectivity-state'; import { BackoffTimeout, BackoffOptions } from './backoff-timeout'; import { getDefaultAuthority } from './resolver'; import * as logging from './logging'; -import { LogVerbosity } from './constants'; +import { LogVerbosity, Status } from './constants'; import { getProxiedConnection, ProxyConnectionResult } from './http_proxy'; import * as net from 'net'; import { GrpcUri, parseUri, splitHostPort, uriToString } from './uri-parser'; import { ConnectionOptions } from 'tls'; -import { FilterFactory, Filter } from './filter'; +import { FilterFactory, Filter, BaseFilter } from './filter'; import { + stringToSubchannelAddress, SubchannelAddress, subchannelAddressToString, } from './subchannel-address'; +import { SubchannelRef, ChannelzTrace, ChannelzChildrenTracker, SubchannelInfo, registerChannelzSubchannel, ChannelzCallTracker, SocketInfo, SocketRef, unregisterChannelzRef, registerChannelzSocket, TlsInfo } from './channelz'; const clientVersion = require('../../package.json').version; @@ -157,6 +159,53 @@ export class Subchannel { */ private subchannelAddressString: string; + // Channelz info + private channelzRef: SubchannelRef; + private channelzTrace: ChannelzTrace; + private callTracker = new ChannelzCallTracker(); + private childrenTracker = new ChannelzChildrenTracker(); + + // Channelz socket info + private channelzSocketRef: SocketRef | null = null; + /** + * Name of the remote server, if it is not the same as the subchannel + * address, i.e. if connecting through an HTTP CONNECT proxy. + */ + private remoteName: string | null = null; + private streamTracker = new ChannelzCallTracker(); + private keepalivesSent = 0; + private messagesSent = 0; + private messagesReceived = 0; + private lastMessageSentTimestamp: Date | null = null; + private lastMessageReceivedTimestamp: Date | null = null; + private MessageCountFilter = class extends BaseFilter implements Filter { + private session: http2.ClientHttp2Session; + constructor(private parent: Subchannel) { + super(); + this.session = parent.session!; + } + sendMessage(message: Promise): Promise { + if (this.parent.session === this.session) { + this.parent.messagesSent += 1; + this.parent.lastMessageSentTimestamp = new Date(); + } + return message; + } + receiveMessage(message: Promise): Promise { + if (this.parent.session === this.session) { + this.parent.messagesReceived += 1; + this.parent.lastMessageReceivedTimestamp = new Date(); + } + return message; + } + }; + private MessageCountFilterFactory = class implements FilterFactory { + constructor(private parent: Subchannel) {} + createFilter(callStream: Call): Filter { + return new this.parent.MessageCountFilter(this.parent); + } + } + /** * A class representing a connection to a single backend. * @param channelTarget The target string for the channel as a whole @@ -206,6 +255,77 @@ export class Subchannel { this.handleBackoffTimer(); }, backoffOptions); this.subchannelAddressString = subchannelAddressToString(subchannelAddress); + + this.channelzRef = registerChannelzSubchannel(this.subchannelAddressString, () => this.getChannelzInfo()); + this.channelzTrace = new ChannelzTrace(); + this.channelzTrace.addTrace('CT_INFO', 'Subchannel created'); + } + + private getChannelzInfo(): SubchannelInfo { + return { + state: this.connectivityState, + trace: this.channelzTrace, + callTracker: this.callTracker, + children: this.childrenTracker.getChildLists() + }; + } + + private getChannelzSocketInfo(): SocketInfo | null { + if (this.session === null) { + return null; + } + const sessionSocket = this.session.socket; + const remoteAddress = sessionSocket.remoteAddress ? stringToSubchannelAddress(sessionSocket.remoteAddress, sessionSocket.remotePort) : null; + const localAddress = stringToSubchannelAddress(sessionSocket.localAddress, sessionSocket.localPort); + let tlsInfo: TlsInfo | null; + if (this.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 ? cipherInfo.name: null, + 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: this.remoteName, + streamsStarted: this.streamTracker.callsStarted, + streamsSucceeded: this.streamTracker.callsSucceeded, + streamsFailed: this.streamTracker.callsFailed, + messagesSent: this.messagesSent, + messagesReceived: this.messagesReceived, + keepAlivesSent: this.keepalivesSent, + lastLocalStreamCreatedTimestamp: this.streamTracker.lastCallStartedTimestamp, + lastRemoteStreamCreatedTimestamp: null, + lastMessageSentTimestamp: this.lastMessageSentTimestamp, + lastMessageReceivedTimestamp: this.lastMessageReceivedTimestamp, + localFlowControlWindow: this.session.state.localWindowSize ?? null, + remoteFlowControlWindow: this.session.state.remoteWindowSize ?? null + }; + return socketInfo; + } + + private resetChannelzSocketInfo() { + if (this.channelzSocketRef) { + unregisterChannelzRef(this.channelzSocketRef); + this.childrenTracker.unrefChild(this.channelzSocketRef); + this.channelzSocketRef = null; + } + this.remoteName = null; + this.streamTracker = new ChannelzCallTracker(); + this.keepalivesSent = 0; + this.messagesSent = 0; + this.messagesReceived = 0; + this.lastMessageSentTimestamp = null; + this.lastMessageReceivedTimestamp = null; } private handleBackoffTimer() { @@ -235,6 +355,7 @@ export class Subchannel { } private sendPing() { + this.keepalivesSent += 1; logging.trace( LogVerbosity.DEBUG, 'keepalive', @@ -266,6 +387,11 @@ export class Subchannel { } private createSession(proxyConnectionResult: ProxyConnectionResult) { + if (proxyConnectionResult.realTarget) { + this.remoteName = uriToString(proxyConnectionResult.realTarget); + } else { + this.remoteName = null; + } const targetAuthority = getDefaultAuthority( proxyConnectionResult.realTarget ?? this.channelTarget ); @@ -353,6 +479,8 @@ export class Subchannel { connectionOptions ); this.session = session; + this.channelzSocketRef = registerChannelzSocket(this.subchannelAddressString, () => this.getChannelzSocketInfo()!); + this.childrenTracker.refChild(this.channelzSocketRef); session.unref(); /* For all of these events, check if the session at the time of the event * is the same one currently attached to this subchannel, to ensure that @@ -425,6 +553,7 @@ export class Subchannel { (error as Error).message ); }); + registerChannelzSocket(this.subchannelAddressString, () => this.getChannelzSocketInfo()!); } private startConnectingInternal() { @@ -506,6 +635,7 @@ export class Subchannel { ' -> ' + ConnectivityState[newState] ); + this.channelzTrace.addTrace('CT_INFO', ConnectivityState[this.connectivityState] + ' -> ' + ConnectivityState[newState]); const previousState = this.connectivityState; this.connectivityState = newState; switch (newState) { @@ -530,6 +660,7 @@ export class Subchannel { this.session.close(); } this.session = null; + this.resetChannelzSocketInfo(); this.stopKeepalivePings(); /* If the backoff timer has already ended by the time we get to the * TRANSIENT_FAILURE state, we want to immediately transition out of @@ -545,6 +676,7 @@ export class Subchannel { this.session.close(); } this.session = null; + this.resetChannelzSocketInfo(); this.stopKeepalivePings(); break; default: @@ -566,10 +698,12 @@ export class Subchannel { /* If no calls, channels, or subchannel pools have any more references to * this subchannel, we can be sure it will never be used again. */ if (this.callRefcount === 0 && this.refcount === 0) { + this.channelzTrace.addTrace('CT_INFO', 'Shutting down'); this.transitionToState( [ConnectivityState.CONNECTING, ConnectivityState.READY], ConnectivityState.TRANSIENT_FAILURE ); + unregisterChannelzRef(this.channelzRef); } } @@ -694,6 +828,26 @@ export class Subchannel { ' with headers\n' + headersString ); + this.callTracker.addCallStarted(); + callStream.addStatusWatcher(status => { + if (status.code === Status.OK) { + this.callTracker.addCallSucceeded(); + } else { + this.callTracker.addCallFailed(); + } + }); + const streamSession = this.session; + this.streamTracker.addCallStarted(); + callStream.addStreamEndWatcher(success => { + if (streamSession === this.session) { + if (success) { + this.streamTracker.addCallSucceeded(); + } else { + this.streamTracker.addCallFailed(); + } + } + }); + extraFilterFactories.push(new this.MessageCountFilterFactory(this)); callStream.attachHttp2Stream(http2Stream, this, extraFilterFactories); } @@ -773,4 +927,8 @@ export class Subchannel { getAddress(): string { return this.subchannelAddressString; } + + getChannelzRef(): SubchannelRef { + return this.channelzRef; + } } diff --git a/packages/grpc-tools/deps/protobuf b/packages/grpc-tools/deps/protobuf index 6aa539bf0..a6e1cc7e3 160000 --- a/packages/grpc-tools/deps/protobuf +++ b/packages/grpc-tools/deps/protobuf @@ -1 +1 @@ -Subproject commit 6aa539bf0195f188ff86efe6fb8bfa2b676cdd46 +Subproject commit a6e1cc7e328c45a0cb9856c530c8f6cd23314163 From 2efe0918a8724e081309a243c14a9c0fc9968c85 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 31 Aug 2021 11:45:15 -0700 Subject: [PATCH 067/450] grpc-js-xds: Enable fault injection feature by default --- packages/grpc-js-xds/scripts/xds.sh | 1 - packages/grpc-js-xds/src/environment.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/grpc-js-xds/scripts/xds.sh b/packages/grpc-js-xds/scripts/xds.sh index 8d94ae195..131cbd551 100755 --- a/packages/grpc-js-xds/scripts/xds.sh +++ b/packages/grpc-js-xds/scripts/xds.sh @@ -51,7 +51,6 @@ grpc/tools/run_tests/helper_scripts/prep_xds.sh GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weighted_target,round_robin,resolving_load_balancer,subchannel,keepalive,dns_resolver,fault_injection,http_filter \ GRPC_NODE_VERBOSITY=DEBUG \ NODE_XDS_INTEROP_VERBOSITY=1 \ - GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION=1 \ python3 grpc/tools/run_tests/run_xds_tests.py \ --test_case="all,timeout,circuit_breaking,fault_injection" \ --project_id=grpc-testing \ diff --git a/packages/grpc-js-xds/src/environment.ts b/packages/grpc-js-xds/src/environment.ts index 18e9e70bd..e1c2d8158 100644 --- a/packages/grpc-js-xds/src/environment.ts +++ b/packages/grpc-js-xds/src/environment.ts @@ -15,4 +15,4 @@ * */ -export const EXPERIMENTAL_FAULT_INJECTION = process.env.GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION; \ No newline at end of file +export const EXPERIMENTAL_FAULT_INJECTION = (process.env.GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION ?? 'true') === 'true'; \ No newline at end of file From ca5045df8c91d9362aff74be702c4e9244c3083c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 31 Aug 2021 11:53:15 -0700 Subject: [PATCH 068/450] grpc-js-xds: Update readme feature list --- packages/grpc-js-xds/README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/README.md b/packages/grpc-js-xds/README.md index bcea70456..84d291508 100644 --- a/packages/grpc-js-xds/README.md +++ b/packages/grpc-js-xds/README.md @@ -22,4 +22,8 @@ const client = new MyServiceClient('xds:///example.com:123'); ## Supported Features - [xDS-Based Global Load Balancing](https://github.com/grpc/proposal/blob/master/A27-xds-global-load-balancing.md) - - [xDS traffic splitting and routing](https://github.com/grpc/proposal/blob/master/A28-xds-traffic-splitting-and-routing.md) \ No newline at end of file + - [xDS traffic splitting and routing](https://github.com/grpc/proposal/blob/master/A28-xds-traffic-splitting-and-routing.md) + - [xDS v3 API](https://github.com/grpc/proposal/blob/master/A30-xds-v3.md) + - [xDS Timeouts](https://github.com/grpc/proposal/blob/master/A31-xds-timeout-support-and-config-selector.md) + - [xDS Circuit Breaking](https://github.com/grpc/proposal/blob/master/A32-xds-circuit-breaking.md) + - [xDS Client-Side Fault Injection](https://github.com/grpc/proposal/blob/master/A33-Fault-Injection.md) \ No newline at end of file From 7a3dd6eb296f0b892867fcba61a2c640dcf35007 Mon Sep 17 00:00:00 2001 From: Pratyay Banerjee <48355572+Neilblaze@users.noreply.github.com> Date: Thu, 2 Sep 2021 22:54:56 +0530 Subject: [PATCH 069/450] =?UTF-8?q?fix(docs):=20supporst=20=E2=9F=B6=20sup?= =?UTF-8?q?ports?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pratyay Banerjee <48355572+Neilblaze@users.noreply.github.com> --- TROUBLESHOOTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TROUBLESHOOTING.md b/TROUBLESHOOTING.md index dd5bce7af..89903392a 100644 --- a/TROUBLESHOOTING.md +++ b/TROUBLESHOOTING.md @@ -4,7 +4,7 @@ This guide is for troubleshooting the `grpc-js` library for Node.js ## Enabling extra logging and tracing -Extra logging can be very useful for diagnosing problems. `grpc-js` supporst +Extra logging can be very useful for diagnosing problems. `grpc-js` support the `GRPC_VERBOSITY` and `GRPC_TRACE` environment variables that can be used to increase the amount of information that gets printed to stderr. From f9ae440b1cc0b4c78c9a7b8a295c9e4d2cb07ac8 Mon Sep 17 00:00:00 2001 From: Pratyay Banerjee <48355572+Neilblaze@users.noreply.github.com> Date: Thu, 2 Sep 2021 23:00:11 +0530 Subject: [PATCH 070/450] updated with an extra 's' Signed-off-by: Pratyay Banerjee <48355572+Neilblaze@users.noreply.github.com> --- TROUBLESHOOTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TROUBLESHOOTING.md b/TROUBLESHOOTING.md index 89903392a..bfcf94edc 100644 --- a/TROUBLESHOOTING.md +++ b/TROUBLESHOOTING.md @@ -4,7 +4,7 @@ This guide is for troubleshooting the `grpc-js` library for Node.js ## Enabling extra logging and tracing -Extra logging can be very useful for diagnosing problems. `grpc-js` support +Extra logging can be very useful for diagnosing problems. `grpc-js` supports the `GRPC_VERBOSITY` and `GRPC_TRACE` environment variables that can be used to increase the amount of information that gets printed to stderr. From c95219b1ea46c1db2d0e2edb817a3ed4232f1749 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 7 Sep 2021 14:36:40 -0700 Subject: [PATCH 071/450] proto-loader: Avoid generating conflicting method names in service clients --- .../bin/proto-loader-gen-types.ts | 35 +++++++++++++++++++ packages/proto-loader/package.json | 2 +- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index b441d425e..6c9596980 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -454,6 +454,38 @@ function generateEnumInterface(formatter: TextFormatter, enumType: Protobuf.Enum formatter.writeLine('}'); } +/** + * This is a list of methods that are exist in the generic Client class in the + * gRPC libraries. TypeScript has a problem with methods in subclasses with the + * same names as methods in the superclass, but with mismatched APIs. So, we + * avoid generating methods with these names in the service client interfaces. + * We always generate two service client methods per service method: one camel + * cased, and one with the original casing. So we will still generate one + * service client method for any conflicting name. + * + * Technically, at runtime conflicting name in the service client method + * actually shadows the original method, but TypeScript does not have a good + * way to represent that. So this change is not 100% accurate, but it gets the + * generated code to compile. + * + * This is just a list of the methods in the Client class definitions in + * grpc@1.24.11 and @grpc/grpc-js@1.4.0. + */ +const CLIENT_RESERVED_METHOD_NAMES = new Set([ + 'close', + 'getChannel', + 'waitForReady', + 'makeUnaryRequest', + 'makeClientStreamRequest', + 'makeServerStreamRequest', + 'makeBidiStreamRequest', + 'resolveCallInterceptors', + /* These methods are private, but TypeScript is not happy with overriding even + * private methods with mismatched APIs. */ + 'checkOptionalUnaryResponseArguments', + 'checkMetadataAndOptions' +]); + function generateServiceClientInterface(formatter: TextFormatter, serviceType: Protobuf.Service, options: GeneratorOptions) { if (options.includeComments) { formatComment(formatter, serviceType.comment); @@ -463,6 +495,9 @@ function generateServiceClientInterface(formatter: TextFormatter, serviceType: P for (const methodName of Object.keys(serviceType.methods).sort()) { const method = serviceType.methods[methodName]; for (const name of [methodName, camelCase(methodName)]) { + if (CLIENT_RESERVED_METHOD_NAMES.has(name)) { + continue; + } if (options.includeComments) { formatComment(formatter, method.comment); } diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index 824fa6f5e..9418df982 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/proto-loader", - "version": "0.6.4", + "version": "0.6.5", "author": "Google Inc.", "contributors": [ { From bf0df1f94a04c1d41374af588b7c212f299ef56d Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 7 Sep 2021 14:21:48 -0700 Subject: [PATCH 072/450] Add channelz.proto and generated code --- packages/grpc-js/package.json | 5 +- packages/grpc-js/proto/channelz.proto | 564 ++++++++++++++++++ packages/grpc-js/src/generated/channelz.ts | 73 +++ .../src/generated/google/protobuf/Any.ts | 13 + .../generated/google/protobuf/BoolValue.ts | 10 + .../generated/google/protobuf/BytesValue.ts | 10 + .../generated/google/protobuf/DoubleValue.ts | 10 + .../src/generated/google/protobuf/Duration.ts | 13 + .../generated/google/protobuf/FloatValue.ts | 10 + .../generated/google/protobuf/Int32Value.ts | 10 + .../generated/google/protobuf/Int64Value.ts | 11 + .../generated/google/protobuf/StringValue.ts | 10 + .../generated/google/protobuf/Timestamp.ts | 13 + .../generated/google/protobuf/UInt32Value.ts | 10 + .../generated/google/protobuf/UInt64Value.ts | 11 + .../src/generated/grpc/channelz/v1/Address.ts | 89 +++ .../src/generated/grpc/channelz/v1/Channel.ts | 68 +++ .../channelz/v1/ChannelConnectivityState.ts | 29 + .../generated/grpc/channelz/v1/ChannelData.ts | 76 +++ .../generated/grpc/channelz/v1/ChannelRef.ts | 31 + .../grpc/channelz/v1/ChannelTrace.ts | 45 ++ .../grpc/channelz/v1/ChannelTraceEvent.ts | 73 +++ .../generated/grpc/channelz/v1/Channelz.ts | 178 ++++++ .../grpc/channelz/v1/GetChannelRequest.ts | 17 + .../grpc/channelz/v1/GetChannelResponse.ts | 19 + .../grpc/channelz/v1/GetServerRequest.ts | 17 + .../grpc/channelz/v1/GetServerResponse.ts | 19 + .../channelz/v1/GetServerSocketsRequest.ts | 39 ++ .../channelz/v1/GetServerSocketsResponse.ts | 33 + .../grpc/channelz/v1/GetServersRequest.ts | 37 ++ .../grpc/channelz/v1/GetServersResponse.ts | 33 + .../grpc/channelz/v1/GetSocketRequest.ts | 29 + .../grpc/channelz/v1/GetSocketResponse.ts | 19 + .../grpc/channelz/v1/GetSubchannelRequest.ts | 17 + .../grpc/channelz/v1/GetSubchannelResponse.ts | 19 + .../grpc/channelz/v1/GetTopChannelsRequest.ts | 37 ++ .../channelz/v1/GetTopChannelsResponse.ts | 33 + .../generated/grpc/channelz/v1/Security.ts | 87 +++ .../src/generated/grpc/channelz/v1/Server.ts | 45 ++ .../generated/grpc/channelz/v1/ServerData.ts | 57 ++ .../generated/grpc/channelz/v1/ServerRef.ts | 31 + .../src/generated/grpc/channelz/v1/Socket.ts | 70 +++ .../generated/grpc/channelz/v1/SocketData.ts | 150 +++++ .../grpc/channelz/v1/SocketOption.ts | 47 ++ .../grpc/channelz/v1/SocketOptionLinger.ts | 33 + .../grpc/channelz/v1/SocketOptionTcpInfo.ts | 74 +++ .../grpc/channelz/v1/SocketOptionTimeout.ts | 19 + .../generated/grpc/channelz/v1/SocketRef.ts | 31 + .../generated/grpc/channelz/v1/Subchannel.ts | 70 +++ .../grpc/channelz/v1/SubchannelRef.ts | 31 + 50 files changed, 2473 insertions(+), 2 deletions(-) create mode 100644 packages/grpc-js/proto/channelz.proto create mode 100644 packages/grpc-js/src/generated/channelz.ts create mode 100644 packages/grpc-js/src/generated/google/protobuf/Any.ts create mode 100644 packages/grpc-js/src/generated/google/protobuf/BoolValue.ts create mode 100644 packages/grpc-js/src/generated/google/protobuf/BytesValue.ts create mode 100644 packages/grpc-js/src/generated/google/protobuf/DoubleValue.ts create mode 100644 packages/grpc-js/src/generated/google/protobuf/Duration.ts create mode 100644 packages/grpc-js/src/generated/google/protobuf/FloatValue.ts create mode 100644 packages/grpc-js/src/generated/google/protobuf/Int32Value.ts create mode 100644 packages/grpc-js/src/generated/google/protobuf/Int64Value.ts create mode 100644 packages/grpc-js/src/generated/google/protobuf/StringValue.ts create mode 100644 packages/grpc-js/src/generated/google/protobuf/Timestamp.ts create mode 100644 packages/grpc-js/src/generated/google/protobuf/UInt32Value.ts create mode 100644 packages/grpc-js/src/generated/google/protobuf/UInt64Value.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/Address.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/Channel.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/ChannelConnectivityState.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/ChannelData.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/ChannelRef.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/ChannelTrace.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/ChannelTraceEvent.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/Channelz.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/GetChannelRequest.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/GetChannelResponse.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/GetServerRequest.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/GetServerResponse.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/GetServerSocketsRequest.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/GetServerSocketsResponse.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/GetServersRequest.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/GetServersResponse.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/GetSocketRequest.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/GetSocketResponse.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/GetSubchannelRequest.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/GetSubchannelResponse.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/GetTopChannelsRequest.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/GetTopChannelsResponse.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/Security.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/Server.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/ServerData.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/ServerRef.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/Socket.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/SocketData.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/SocketOption.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/SocketOptionLinger.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/SocketOptionTcpInfo.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/SocketOptionTimeout.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/SocketRef.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/Subchannel.ts create mode 100644 packages/grpc-js/src/generated/grpc/channelz/v1/SubchannelRef.ts diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 79df40c52..7d8cd611d 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -15,7 +15,6 @@ "types": "build/src/index.d.ts", "license": "Apache-2.0", "devDependencies": { - "@grpc/proto-loader": "^0.5.5", "@types/gulp": "^4.0.6", "@types/gulp-mocha": "0.0.32", "@types/lodash": "^4.14.108", @@ -54,9 +53,11 @@ "check": "gts check src/**/*.ts", "fix": "gts fix src/*.ts", "pretest": "npm run compile", - "posttest": "npm run check && madge -c ./build/src" + "posttest": "npm run check && madge -c ./build/src", + "generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs proto/ -O src/generated/ --grpcLib ../index channelz.proto" }, "dependencies": { + "@grpc/proto-loader": "^0.6.4", "@types/node": ">=12.12.47" }, "files": [ diff --git a/packages/grpc-js/proto/channelz.proto b/packages/grpc-js/proto/channelz.proto new file mode 100644 index 000000000..446e9794b --- /dev/null +++ b/packages/grpc-js/proto/channelz.proto @@ -0,0 +1,564 @@ +// Copyright 2018 The 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. + +// This file defines an interface for exporting monitoring information +// out of gRPC servers. See the full design at +// https://github.com/grpc/proposal/blob/master/A14-channelz.md +// +// The canonical version of this proto can be found at +// https://github.com/grpc/grpc-proto/blob/master/grpc/channelz/v1/channelz.proto + +syntax = "proto3"; + +package grpc.channelz.v1; + +import "google/protobuf/any.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; +import "google/protobuf/wrappers.proto"; + +option go_package = "google.golang.org/grpc/channelz/grpc_channelz_v1"; +option java_multiple_files = true; +option java_package = "io.grpc.channelz.v1"; +option java_outer_classname = "ChannelzProto"; + +// Channel is a logical grouping of channels, subchannels, and sockets. +message Channel { + // The identifier for this channel. This should bet set. + ChannelRef ref = 1; + // Data specific to this channel. + ChannelData data = 2; + // At most one of 'channel_ref+subchannel_ref' and 'socket' is set. + + // There are no ordering guarantees on the order of channel refs. + // There may not be cycles in the ref graph. + // A channel ref may be present in more than one channel or subchannel. + repeated ChannelRef channel_ref = 3; + + // At most one of 'channel_ref+subchannel_ref' and 'socket' is set. + // There are no ordering guarantees on the order of subchannel refs. + // There may not be cycles in the ref graph. + // A sub channel ref may be present in more than one channel or subchannel. + repeated SubchannelRef subchannel_ref = 4; + + // There are no ordering guarantees on the order of sockets. + repeated SocketRef socket_ref = 5; +} + +// Subchannel is a logical grouping of channels, subchannels, and sockets. +// A subchannel is load balanced over by it's ancestor +message Subchannel { + // The identifier for this channel. + SubchannelRef ref = 1; + // Data specific to this channel. + ChannelData data = 2; + // At most one of 'channel_ref+subchannel_ref' and 'socket' is set. + + // There are no ordering guarantees on the order of channel refs. + // There may not be cycles in the ref graph. + // A channel ref may be present in more than one channel or subchannel. + repeated ChannelRef channel_ref = 3; + + // At most one of 'channel_ref+subchannel_ref' and 'socket' is set. + // There are no ordering guarantees on the order of subchannel refs. + // There may not be cycles in the ref graph. + // A sub channel ref may be present in more than one channel or subchannel. + repeated SubchannelRef subchannel_ref = 4; + + // There are no ordering guarantees on the order of sockets. + repeated SocketRef socket_ref = 5; +} + +// These come from the specified states in this document: +// https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md +message ChannelConnectivityState { + enum State { + UNKNOWN = 0; + IDLE = 1; + CONNECTING = 2; + READY = 3; + TRANSIENT_FAILURE = 4; + SHUTDOWN = 5; + } + State state = 1; +} + +// Channel data is data related to a specific Channel or Subchannel. +message ChannelData { + // The connectivity state of the channel or subchannel. Implementations + // should always set this. + ChannelConnectivityState state = 1; + + // The target this channel originally tried to connect to. May be absent + string target = 2; + + // A trace of recent events on the channel. May be absent. + ChannelTrace trace = 3; + + // The number of calls started on the channel + int64 calls_started = 4; + // The number of calls that have completed with an OK status + int64 calls_succeeded = 5; + // The number of calls that have completed with a non-OK status + int64 calls_failed = 6; + + // The last time a call was started on the channel. + google.protobuf.Timestamp last_call_started_timestamp = 7; +} + +// A trace event is an interesting thing that happened to a channel or +// subchannel, such as creation, address resolution, subchannel creation, etc. +message ChannelTraceEvent { + // High level description of the event. + string description = 1; + // The supported severity levels of trace events. + enum Severity { + CT_UNKNOWN = 0; + CT_INFO = 1; + CT_WARNING = 2; + CT_ERROR = 3; + } + // the severity of the trace event + Severity severity = 2; + // When this event occurred. + google.protobuf.Timestamp timestamp = 3; + // ref of referenced channel or subchannel. + // Optional, only present if this event refers to a child object. For example, + // this field would be filled if this trace event was for a subchannel being + // created. + oneof child_ref { + ChannelRef channel_ref = 4; + SubchannelRef subchannel_ref = 5; + } +} + +// ChannelTrace represents the recent events that have occurred on the channel. +message ChannelTrace { + // Number of events ever logged in this tracing object. This can differ from + // events.size() because events can be overwritten or garbage collected by + // implementations. + int64 num_events_logged = 1; + // Time that this channel was created. + google.protobuf.Timestamp creation_timestamp = 2; + // List of events that have occurred on this channel. + repeated ChannelTraceEvent events = 3; +} + +// ChannelRef is a reference to a Channel. +message ChannelRef { + // The globally unique id for this channel. Must be a positive number. + int64 channel_id = 1; + // An optional name associated with the channel. + string name = 2; + // Intentionally don't use field numbers from other refs. + reserved 3, 4, 5, 6, 7, 8; +} + +// SubchannelRef is a reference to a Subchannel. +message SubchannelRef { + // The globally unique id for this subchannel. Must be a positive number. + int64 subchannel_id = 7; + // An optional name associated with the subchannel. + string name = 8; + // Intentionally don't use field numbers from other refs. + reserved 1, 2, 3, 4, 5, 6; +} + +// SocketRef is a reference to a Socket. +message SocketRef { + // The globally unique id for this socket. Must be a positive number. + int64 socket_id = 3; + // An optional name associated with the socket. + string name = 4; + // Intentionally don't use field numbers from other refs. + reserved 1, 2, 5, 6, 7, 8; +} + +// ServerRef is a reference to a Server. +message ServerRef { + // A globally unique identifier for this server. Must be a positive number. + int64 server_id = 5; + // An optional name associated with the server. + string name = 6; + // Intentionally don't use field numbers from other refs. + reserved 1, 2, 3, 4, 7, 8; +} + +// Server represents a single server. There may be multiple servers in a single +// program. +message Server { + // The identifier for a Server. This should be set. + ServerRef ref = 1; + // The associated data of the Server. + ServerData data = 2; + + // The sockets that the server is listening on. There are no ordering + // guarantees. This may be absent. + repeated SocketRef listen_socket = 3; +} + +// ServerData is data for a specific Server. +message ServerData { + // A trace of recent events on the server. May be absent. + ChannelTrace trace = 1; + + // The number of incoming calls started on the server + int64 calls_started = 2; + // The number of incoming calls that have completed with an OK status + int64 calls_succeeded = 3; + // The number of incoming calls that have a completed with a non-OK status + int64 calls_failed = 4; + + // The last time a call was started on the server. + google.protobuf.Timestamp last_call_started_timestamp = 5; +} + +// Information about an actual connection. Pronounced "sock-ay". +message Socket { + // The identifier for the Socket. + SocketRef ref = 1; + + // Data specific to this Socket. + SocketData data = 2; + // The locally bound address. + Address local = 3; + // The remote bound address. May be absent. + Address remote = 4; + // Security details for this socket. May be absent if not available, or + // there is no security on the socket. + Security security = 5; + + // Optional, represents the name of the remote endpoint, if different than + // the original target name. + string remote_name = 6; +} + +// SocketData is data associated for a specific Socket. The fields present +// are specific to the implementation, so there may be minor differences in +// the semantics. (e.g. flow control windows) +message SocketData { + // The number of streams that have been started. + int64 streams_started = 1; + // The number of streams that have ended successfully: + // On client side, received frame with eos bit set; + // On server side, sent frame with eos bit set. + int64 streams_succeeded = 2; + // The number of streams that have ended unsuccessfully: + // On client side, ended without receiving frame with eos bit set; + // On server side, ended without sending frame with eos bit set. + int64 streams_failed = 3; + // The number of grpc messages successfully sent on this socket. + int64 messages_sent = 4; + // The number of grpc messages received on this socket. + int64 messages_received = 5; + + // The number of keep alives sent. This is typically implemented with HTTP/2 + // ping messages. + int64 keep_alives_sent = 6; + + // The last time a stream was created by this endpoint. Usually unset for + // servers. + google.protobuf.Timestamp last_local_stream_created_timestamp = 7; + // The last time a stream was created by the remote endpoint. Usually unset + // for clients. + google.protobuf.Timestamp last_remote_stream_created_timestamp = 8; + + // The last time a message was sent by this endpoint. + google.protobuf.Timestamp last_message_sent_timestamp = 9; + // The last time a message was received by this endpoint. + google.protobuf.Timestamp last_message_received_timestamp = 10; + + // The amount of window, granted to the local endpoint by the remote endpoint. + // This may be slightly out of date due to network latency. This does NOT + // include stream level or TCP level flow control info. + google.protobuf.Int64Value local_flow_control_window = 11; + + // The amount of window, granted to the remote endpoint by the local endpoint. + // This may be slightly out of date due to network latency. This does NOT + // include stream level or TCP level flow control info. + google.protobuf.Int64Value remote_flow_control_window = 12; + + // Socket options set on this socket. May be absent if 'summary' is set + // on GetSocketRequest. + repeated SocketOption option = 13; +} + +// Address represents the address used to create the socket. +message Address { + message TcpIpAddress { + // Either the IPv4 or IPv6 address in bytes. Will be either 4 bytes or 16 + // bytes in length. + bytes ip_address = 1; + // 0-64k, or -1 if not appropriate. + int32 port = 2; + } + // A Unix Domain Socket address. + message UdsAddress { + string filename = 1; + } + // An address type not included above. + message OtherAddress { + // The human readable version of the value. This value should be set. + string name = 1; + // The actual address message. + google.protobuf.Any value = 2; + } + + oneof address { + TcpIpAddress tcpip_address = 1; + UdsAddress uds_address = 2; + OtherAddress other_address = 3; + } +} + +// Security represents details about how secure the socket is. +message Security { + message Tls { + oneof cipher_suite { + // The cipher suite name in the RFC 4346 format: + // https://tools.ietf.org/html/rfc4346#appendix-C + string standard_name = 1; + // Some other way to describe the cipher suite if + // the RFC 4346 name is not available. + string other_name = 2; + } + // the certificate used by this endpoint. + bytes local_certificate = 3; + // the certificate used by the remote endpoint. + bytes remote_certificate = 4; + } + message OtherSecurity { + // The human readable version of the value. + string name = 1; + // The actual security details message. + google.protobuf.Any value = 2; + } + oneof model { + Tls tls = 1; + OtherSecurity other = 2; + } +} + +// SocketOption represents socket options for a socket. Specifically, these +// are the options returned by getsockopt(). +message SocketOption { + // The full name of the socket option. Typically this will be the upper case + // name, such as "SO_REUSEPORT". + string name = 1; + // The human readable value of this socket option. At least one of value or + // additional will be set. + string value = 2; + // Additional data associated with the socket option. At least one of value + // or additional will be set. + google.protobuf.Any additional = 3; +} + +// For use with SocketOption's additional field. This is primarily used for +// SO_RCVTIMEO and SO_SNDTIMEO +message SocketOptionTimeout { + google.protobuf.Duration duration = 1; +} + +// For use with SocketOption's additional field. This is primarily used for +// SO_LINGER. +message SocketOptionLinger { + // active maps to `struct linger.l_onoff` + bool active = 1; + // duration maps to `struct linger.l_linger` + google.protobuf.Duration duration = 2; +} + +// For use with SocketOption's additional field. Tcp info for +// SOL_TCP and TCP_INFO. +message SocketOptionTcpInfo { + uint32 tcpi_state = 1; + + uint32 tcpi_ca_state = 2; + uint32 tcpi_retransmits = 3; + uint32 tcpi_probes = 4; + uint32 tcpi_backoff = 5; + uint32 tcpi_options = 6; + uint32 tcpi_snd_wscale = 7; + uint32 tcpi_rcv_wscale = 8; + + uint32 tcpi_rto = 9; + uint32 tcpi_ato = 10; + uint32 tcpi_snd_mss = 11; + uint32 tcpi_rcv_mss = 12; + + uint32 tcpi_unacked = 13; + uint32 tcpi_sacked = 14; + uint32 tcpi_lost = 15; + uint32 tcpi_retrans = 16; + uint32 tcpi_fackets = 17; + + uint32 tcpi_last_data_sent = 18; + uint32 tcpi_last_ack_sent = 19; + uint32 tcpi_last_data_recv = 20; + uint32 tcpi_last_ack_recv = 21; + + uint32 tcpi_pmtu = 22; + uint32 tcpi_rcv_ssthresh = 23; + uint32 tcpi_rtt = 24; + uint32 tcpi_rttvar = 25; + uint32 tcpi_snd_ssthresh = 26; + uint32 tcpi_snd_cwnd = 27; + uint32 tcpi_advmss = 28; + uint32 tcpi_reordering = 29; +} + +// Channelz is a service exposed by gRPC servers that provides detailed debug +// information. +service Channelz { + // Gets all root channels (i.e. channels the application has directly + // created). This does not include subchannels nor non-top level channels. + rpc GetTopChannels(GetTopChannelsRequest) returns (GetTopChannelsResponse); + // Gets all servers that exist in the process. + rpc GetServers(GetServersRequest) returns (GetServersResponse); + // Returns a single Server, or else a NOT_FOUND code. + rpc GetServer(GetServerRequest) returns (GetServerResponse); + // Gets all server sockets that exist in the process. + rpc GetServerSockets(GetServerSocketsRequest) returns (GetServerSocketsResponse); + // Returns a single Channel, or else a NOT_FOUND code. + rpc GetChannel(GetChannelRequest) returns (GetChannelResponse); + // Returns a single Subchannel, or else a NOT_FOUND code. + rpc GetSubchannel(GetSubchannelRequest) returns (GetSubchannelResponse); + // Returns a single Socket or else a NOT_FOUND code. + rpc GetSocket(GetSocketRequest) returns (GetSocketResponse); +} + +message GetTopChannelsRequest { + // start_channel_id indicates that only channels at or above this id should be + // included in the results. + // To request the first page, this should be set to 0. To request + // subsequent pages, the client generates this value by adding 1 to + // the highest seen result ID. + int64 start_channel_id = 1; + + // If non-zero, the server will return a page of results containing + // at most this many items. If zero, the server will choose a + // reasonable page size. Must never be negative. + int64 max_results = 2; +} + +message GetTopChannelsResponse { + // list of channels that the connection detail service knows about. Sorted in + // ascending channel_id order. + // Must contain at least 1 result, otherwise 'end' must be true. + repeated Channel channel = 1; + // If set, indicates that the list of channels is the final list. Requesting + // more channels can only return more if they are created after this RPC + // completes. + bool end = 2; +} + +message GetServersRequest { + // start_server_id indicates that only servers at or above this id should be + // included in the results. + // To request the first page, this must be set to 0. To request + // subsequent pages, the client generates this value by adding 1 to + // the highest seen result ID. + int64 start_server_id = 1; + + // If non-zero, the server will return a page of results containing + // at most this many items. If zero, the server will choose a + // reasonable page size. Must never be negative. + int64 max_results = 2; +} + +message GetServersResponse { + // list of servers that the connection detail service knows about. Sorted in + // ascending server_id order. + // Must contain at least 1 result, otherwise 'end' must be true. + repeated Server server = 1; + // If set, indicates that the list of servers is the final list. Requesting + // more servers will only return more if they are created after this RPC + // completes. + bool end = 2; +} + +message GetServerRequest { + // server_id is the identifier of the specific server to get. + int64 server_id = 1; +} + +message GetServerResponse { + // The Server that corresponds to the requested server_id. This field + // should be set. + Server server = 1; +} + +message GetServerSocketsRequest { + int64 server_id = 1; + // start_socket_id indicates that only sockets at or above this id should be + // included in the results. + // To request the first page, this must be set to 0. To request + // subsequent pages, the client generates this value by adding 1 to + // the highest seen result ID. + int64 start_socket_id = 2; + + // If non-zero, the server will return a page of results containing + // at most this many items. If zero, the server will choose a + // reasonable page size. Must never be negative. + int64 max_results = 3; +} + +message GetServerSocketsResponse { + // list of socket refs that the connection detail service knows about. Sorted in + // ascending socket_id order. + // Must contain at least 1 result, otherwise 'end' must be true. + repeated SocketRef socket_ref = 1; + // If set, indicates that the list of sockets is the final list. Requesting + // more sockets will only return more if they are created after this RPC + // completes. + bool end = 2; +} + +message GetChannelRequest { + // channel_id is the identifier of the specific channel to get. + int64 channel_id = 1; +} + +message GetChannelResponse { + // The Channel that corresponds to the requested channel_id. This field + // should be set. + Channel channel = 1; +} + +message GetSubchannelRequest { + // subchannel_id is the identifier of the specific subchannel to get. + int64 subchannel_id = 1; +} + +message GetSubchannelResponse { + // The Subchannel that corresponds to the requested subchannel_id. This + // field should be set. + Subchannel subchannel = 1; +} + +message GetSocketRequest { + // socket_id is the identifier of the specific socket to get. + int64 socket_id = 1; + + // If true, the response will contain only high level information + // that is inexpensive to obtain. Fields thay may be omitted are + // documented. + bool summary = 2; +} + +message GetSocketResponse { + // The Socket that corresponds to the requested socket_id. This field + // should be set. + Socket socket = 1; +} \ No newline at end of file diff --git a/packages/grpc-js/src/generated/channelz.ts b/packages/grpc-js/src/generated/channelz.ts new file mode 100644 index 000000000..367cf27f6 --- /dev/null +++ b/packages/grpc-js/src/generated/channelz.ts @@ -0,0 +1,73 @@ +import type * as grpc from '../index'; +import type { MessageTypeDefinition } from '@grpc/proto-loader'; + +import type { ChannelzClient as _grpc_channelz_v1_ChannelzClient, ChannelzDefinition as _grpc_channelz_v1_ChannelzDefinition } from './grpc/channelz/v1/Channelz'; + +type SubtypeConstructor any, Subtype> = { + new(...args: ConstructorParameters): Subtype; +}; + +export interface ProtoGrpcType { + google: { + protobuf: { + Any: MessageTypeDefinition + BoolValue: MessageTypeDefinition + BytesValue: MessageTypeDefinition + DoubleValue: MessageTypeDefinition + Duration: MessageTypeDefinition + FloatValue: MessageTypeDefinition + Int32Value: MessageTypeDefinition + Int64Value: MessageTypeDefinition + StringValue: MessageTypeDefinition + Timestamp: MessageTypeDefinition + UInt32Value: MessageTypeDefinition + UInt64Value: MessageTypeDefinition + } + } + grpc: { + channelz: { + v1: { + Address: MessageTypeDefinition + Channel: MessageTypeDefinition + ChannelConnectivityState: MessageTypeDefinition + ChannelData: MessageTypeDefinition + ChannelRef: MessageTypeDefinition + ChannelTrace: MessageTypeDefinition + ChannelTraceEvent: MessageTypeDefinition + /** + * Channelz is a service exposed by gRPC servers that provides detailed debug + * information. + */ + Channelz: SubtypeConstructor & { service: _grpc_channelz_v1_ChannelzDefinition } + GetChannelRequest: MessageTypeDefinition + GetChannelResponse: MessageTypeDefinition + GetServerRequest: MessageTypeDefinition + GetServerResponse: MessageTypeDefinition + GetServerSocketsRequest: MessageTypeDefinition + GetServerSocketsResponse: MessageTypeDefinition + GetServersRequest: MessageTypeDefinition + GetServersResponse: MessageTypeDefinition + GetSocketRequest: MessageTypeDefinition + GetSocketResponse: MessageTypeDefinition + GetSubchannelRequest: MessageTypeDefinition + GetSubchannelResponse: MessageTypeDefinition + GetTopChannelsRequest: MessageTypeDefinition + GetTopChannelsResponse: MessageTypeDefinition + Security: MessageTypeDefinition + Server: MessageTypeDefinition + ServerData: MessageTypeDefinition + ServerRef: MessageTypeDefinition + Socket: MessageTypeDefinition + SocketData: MessageTypeDefinition + SocketOption: MessageTypeDefinition + SocketOptionLinger: MessageTypeDefinition + SocketOptionTcpInfo: MessageTypeDefinition + SocketOptionTimeout: MessageTypeDefinition + SocketRef: MessageTypeDefinition + Subchannel: MessageTypeDefinition + SubchannelRef: MessageTypeDefinition + } + } + } +} + diff --git a/packages/grpc-js/src/generated/google/protobuf/Any.ts b/packages/grpc-js/src/generated/google/protobuf/Any.ts new file mode 100644 index 000000000..fcaa6724e --- /dev/null +++ b/packages/grpc-js/src/generated/google/protobuf/Any.ts @@ -0,0 +1,13 @@ +// Original file: null + +import type { AnyExtension } from '@grpc/proto-loader'; + +export type Any = AnyExtension | { + type_url: string; + value: Buffer | Uint8Array | string; +} + +export interface Any__Output { + 'type_url': (string); + 'value': (Buffer); +} diff --git a/packages/grpc-js/src/generated/google/protobuf/BoolValue.ts b/packages/grpc-js/src/generated/google/protobuf/BoolValue.ts new file mode 100644 index 000000000..86507eaf1 --- /dev/null +++ b/packages/grpc-js/src/generated/google/protobuf/BoolValue.ts @@ -0,0 +1,10 @@ +// Original file: null + + +export interface BoolValue { + 'value'?: (boolean); +} + +export interface BoolValue__Output { + 'value': (boolean); +} diff --git a/packages/grpc-js/src/generated/google/protobuf/BytesValue.ts b/packages/grpc-js/src/generated/google/protobuf/BytesValue.ts new file mode 100644 index 000000000..9cec76f71 --- /dev/null +++ b/packages/grpc-js/src/generated/google/protobuf/BytesValue.ts @@ -0,0 +1,10 @@ +// Original file: null + + +export interface BytesValue { + 'value'?: (Buffer | Uint8Array | string); +} + +export interface BytesValue__Output { + 'value': (Buffer); +} diff --git a/packages/grpc-js/src/generated/google/protobuf/DoubleValue.ts b/packages/grpc-js/src/generated/google/protobuf/DoubleValue.ts new file mode 100644 index 000000000..d70b303c2 --- /dev/null +++ b/packages/grpc-js/src/generated/google/protobuf/DoubleValue.ts @@ -0,0 +1,10 @@ +// Original file: null + + +export interface DoubleValue { + 'value'?: (number | string); +} + +export interface DoubleValue__Output { + 'value': (number); +} diff --git a/packages/grpc-js/src/generated/google/protobuf/Duration.ts b/packages/grpc-js/src/generated/google/protobuf/Duration.ts new file mode 100644 index 000000000..8595377a0 --- /dev/null +++ b/packages/grpc-js/src/generated/google/protobuf/Duration.ts @@ -0,0 +1,13 @@ +// Original file: null + +import type { Long } from '@grpc/proto-loader'; + +export interface Duration { + 'seconds'?: (number | string | Long); + 'nanos'?: (number); +} + +export interface Duration__Output { + 'seconds': (string); + 'nanos': (number); +} diff --git a/packages/grpc-js/src/generated/google/protobuf/FloatValue.ts b/packages/grpc-js/src/generated/google/protobuf/FloatValue.ts new file mode 100644 index 000000000..54a655fbb --- /dev/null +++ b/packages/grpc-js/src/generated/google/protobuf/FloatValue.ts @@ -0,0 +1,10 @@ +// Original file: null + + +export interface FloatValue { + 'value'?: (number | string); +} + +export interface FloatValue__Output { + 'value': (number); +} diff --git a/packages/grpc-js/src/generated/google/protobuf/Int32Value.ts b/packages/grpc-js/src/generated/google/protobuf/Int32Value.ts new file mode 100644 index 000000000..ec4eeb7ec --- /dev/null +++ b/packages/grpc-js/src/generated/google/protobuf/Int32Value.ts @@ -0,0 +1,10 @@ +// Original file: null + + +export interface Int32Value { + 'value'?: (number); +} + +export interface Int32Value__Output { + 'value': (number); +} diff --git a/packages/grpc-js/src/generated/google/protobuf/Int64Value.ts b/packages/grpc-js/src/generated/google/protobuf/Int64Value.ts new file mode 100644 index 000000000..f7375196d --- /dev/null +++ b/packages/grpc-js/src/generated/google/protobuf/Int64Value.ts @@ -0,0 +1,11 @@ +// Original file: null + +import type { Long } from '@grpc/proto-loader'; + +export interface Int64Value { + 'value'?: (number | string | Long); +} + +export interface Int64Value__Output { + 'value': (string); +} diff --git a/packages/grpc-js/src/generated/google/protobuf/StringValue.ts b/packages/grpc-js/src/generated/google/protobuf/StringValue.ts new file mode 100644 index 000000000..673090e3f --- /dev/null +++ b/packages/grpc-js/src/generated/google/protobuf/StringValue.ts @@ -0,0 +1,10 @@ +// Original file: null + + +export interface StringValue { + 'value'?: (string); +} + +export interface StringValue__Output { + 'value': (string); +} diff --git a/packages/grpc-js/src/generated/google/protobuf/Timestamp.ts b/packages/grpc-js/src/generated/google/protobuf/Timestamp.ts new file mode 100644 index 000000000..ceaa32b5f --- /dev/null +++ b/packages/grpc-js/src/generated/google/protobuf/Timestamp.ts @@ -0,0 +1,13 @@ +// Original file: null + +import type { Long } from '@grpc/proto-loader'; + +export interface Timestamp { + 'seconds'?: (number | string | Long); + 'nanos'?: (number); +} + +export interface Timestamp__Output { + 'seconds': (string); + 'nanos': (number); +} diff --git a/packages/grpc-js/src/generated/google/protobuf/UInt32Value.ts b/packages/grpc-js/src/generated/google/protobuf/UInt32Value.ts new file mode 100644 index 000000000..973ab34a5 --- /dev/null +++ b/packages/grpc-js/src/generated/google/protobuf/UInt32Value.ts @@ -0,0 +1,10 @@ +// Original file: null + + +export interface UInt32Value { + 'value'?: (number); +} + +export interface UInt32Value__Output { + 'value': (number); +} diff --git a/packages/grpc-js/src/generated/google/protobuf/UInt64Value.ts b/packages/grpc-js/src/generated/google/protobuf/UInt64Value.ts new file mode 100644 index 000000000..7a85c39ce --- /dev/null +++ b/packages/grpc-js/src/generated/google/protobuf/UInt64Value.ts @@ -0,0 +1,11 @@ +// Original file: null + +import type { Long } from '@grpc/proto-loader'; + +export interface UInt64Value { + 'value'?: (number | string | Long); +} + +export interface UInt64Value__Output { + 'value': (string); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/Address.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/Address.ts new file mode 100644 index 000000000..259cfeabe --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/Address.ts @@ -0,0 +1,89 @@ +// Original file: proto/channelz.proto + +import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any'; + +/** + * An address type not included above. + */ +export interface _grpc_channelz_v1_Address_OtherAddress { + /** + * The human readable version of the value. This value should be set. + */ + 'name'?: (string); + /** + * The actual address message. + */ + 'value'?: (_google_protobuf_Any | null); +} + +/** + * An address type not included above. + */ +export interface _grpc_channelz_v1_Address_OtherAddress__Output { + /** + * The human readable version of the value. This value should be set. + */ + 'name': (string); + /** + * The actual address message. + */ + 'value': (_google_protobuf_Any__Output | null); +} + +export interface _grpc_channelz_v1_Address_TcpIpAddress { + /** + * Either the IPv4 or IPv6 address in bytes. Will be either 4 bytes or 16 + * bytes in length. + */ + 'ip_address'?: (Buffer | Uint8Array | string); + /** + * 0-64k, or -1 if not appropriate. + */ + 'port'?: (number); +} + +export interface _grpc_channelz_v1_Address_TcpIpAddress__Output { + /** + * Either the IPv4 or IPv6 address in bytes. Will be either 4 bytes or 16 + * bytes in length. + */ + 'ip_address': (Buffer); + /** + * 0-64k, or -1 if not appropriate. + */ + 'port': (number); +} + +/** + * A Unix Domain Socket address. + */ +export interface _grpc_channelz_v1_Address_UdsAddress { + 'filename'?: (string); +} + +/** + * A Unix Domain Socket address. + */ +export interface _grpc_channelz_v1_Address_UdsAddress__Output { + 'filename': (string); +} + +/** + * Address represents the address used to create the socket. + */ +export interface Address { + 'tcpip_address'?: (_grpc_channelz_v1_Address_TcpIpAddress | null); + 'uds_address'?: (_grpc_channelz_v1_Address_UdsAddress | null); + 'other_address'?: (_grpc_channelz_v1_Address_OtherAddress | null); + 'address'?: "tcpip_address"|"uds_address"|"other_address"; +} + +/** + * Address represents the address used to create the socket. + */ +export interface Address__Output { + 'tcpip_address'?: (_grpc_channelz_v1_Address_TcpIpAddress__Output | null); + 'uds_address'?: (_grpc_channelz_v1_Address_UdsAddress__Output | null); + 'other_address'?: (_grpc_channelz_v1_Address_OtherAddress__Output | null); + 'address': "tcpip_address"|"uds_address"|"other_address"; +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/Channel.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/Channel.ts new file mode 100644 index 000000000..93b4a261d --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/Channel.ts @@ -0,0 +1,68 @@ +// Original file: proto/channelz.proto + +import type { ChannelRef as _grpc_channelz_v1_ChannelRef, ChannelRef__Output as _grpc_channelz_v1_ChannelRef__Output } from '../../../grpc/channelz/v1/ChannelRef'; +import type { ChannelData as _grpc_channelz_v1_ChannelData, ChannelData__Output as _grpc_channelz_v1_ChannelData__Output } from '../../../grpc/channelz/v1/ChannelData'; +import type { SubchannelRef as _grpc_channelz_v1_SubchannelRef, SubchannelRef__Output as _grpc_channelz_v1_SubchannelRef__Output } from '../../../grpc/channelz/v1/SubchannelRef'; +import type { SocketRef as _grpc_channelz_v1_SocketRef, SocketRef__Output as _grpc_channelz_v1_SocketRef__Output } from '../../../grpc/channelz/v1/SocketRef'; + +/** + * Channel is a logical grouping of channels, subchannels, and sockets. + */ +export interface Channel { + /** + * The identifier for this channel. This should bet set. + */ + 'ref'?: (_grpc_channelz_v1_ChannelRef | null); + /** + * Data specific to this channel. + */ + 'data'?: (_grpc_channelz_v1_ChannelData | null); + /** + * There are no ordering guarantees on the order of channel refs. + * There may not be cycles in the ref graph. + * A channel ref may be present in more than one channel or subchannel. + */ + 'channel_ref'?: (_grpc_channelz_v1_ChannelRef)[]; + /** + * At most one of 'channel_ref+subchannel_ref' and 'socket' is set. + * There are no ordering guarantees on the order of subchannel refs. + * There may not be cycles in the ref graph. + * A sub channel ref may be present in more than one channel or subchannel. + */ + 'subchannel_ref'?: (_grpc_channelz_v1_SubchannelRef)[]; + /** + * There are no ordering guarantees on the order of sockets. + */ + 'socket_ref'?: (_grpc_channelz_v1_SocketRef)[]; +} + +/** + * Channel is a logical grouping of channels, subchannels, and sockets. + */ +export interface Channel__Output { + /** + * The identifier for this channel. This should bet set. + */ + 'ref': (_grpc_channelz_v1_ChannelRef__Output | null); + /** + * Data specific to this channel. + */ + 'data': (_grpc_channelz_v1_ChannelData__Output | null); + /** + * There are no ordering guarantees on the order of channel refs. + * There may not be cycles in the ref graph. + * A channel ref may be present in more than one channel or subchannel. + */ + 'channel_ref': (_grpc_channelz_v1_ChannelRef__Output)[]; + /** + * At most one of 'channel_ref+subchannel_ref' and 'socket' is set. + * There are no ordering guarantees on the order of subchannel refs. + * There may not be cycles in the ref graph. + * A sub channel ref may be present in more than one channel or subchannel. + */ + 'subchannel_ref': (_grpc_channelz_v1_SubchannelRef__Output)[]; + /** + * There are no ordering guarantees on the order of sockets. + */ + 'socket_ref': (_grpc_channelz_v1_SocketRef__Output)[]; +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/ChannelConnectivityState.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/ChannelConnectivityState.ts new file mode 100644 index 000000000..be34ab98d --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/ChannelConnectivityState.ts @@ -0,0 +1,29 @@ +// Original file: proto/channelz.proto + + +// Original file: proto/channelz.proto + +export enum _grpc_channelz_v1_ChannelConnectivityState_State { + UNKNOWN = 0, + IDLE = 1, + CONNECTING = 2, + READY = 3, + TRANSIENT_FAILURE = 4, + SHUTDOWN = 5, +} + +/** + * These come from the specified states in this document: + * https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md + */ +export interface ChannelConnectivityState { + 'state'?: (_grpc_channelz_v1_ChannelConnectivityState_State | keyof typeof _grpc_channelz_v1_ChannelConnectivityState_State); +} + +/** + * These come from the specified states in this document: + * https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md + */ +export interface ChannelConnectivityState__Output { + 'state': (keyof typeof _grpc_channelz_v1_ChannelConnectivityState_State); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/ChannelData.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/ChannelData.ts new file mode 100644 index 000000000..6d6824af4 --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/ChannelData.ts @@ -0,0 +1,76 @@ +// Original file: proto/channelz.proto + +import type { ChannelConnectivityState as _grpc_channelz_v1_ChannelConnectivityState, ChannelConnectivityState__Output as _grpc_channelz_v1_ChannelConnectivityState__Output } from '../../../grpc/channelz/v1/ChannelConnectivityState'; +import type { ChannelTrace as _grpc_channelz_v1_ChannelTrace, ChannelTrace__Output as _grpc_channelz_v1_ChannelTrace__Output } from '../../../grpc/channelz/v1/ChannelTrace'; +import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp'; +import type { Long } from '@grpc/proto-loader'; + +/** + * Channel data is data related to a specific Channel or Subchannel. + */ +export interface ChannelData { + /** + * The connectivity state of the channel or subchannel. Implementations + * should always set this. + */ + 'state'?: (_grpc_channelz_v1_ChannelConnectivityState | null); + /** + * The target this channel originally tried to connect to. May be absent + */ + 'target'?: (string); + /** + * A trace of recent events on the channel. May be absent. + */ + 'trace'?: (_grpc_channelz_v1_ChannelTrace | null); + /** + * The number of calls started on the channel + */ + 'calls_started'?: (number | string | Long); + /** + * The number of calls that have completed with an OK status + */ + 'calls_succeeded'?: (number | string | Long); + /** + * The number of calls that have completed with a non-OK status + */ + 'calls_failed'?: (number | string | Long); + /** + * The last time a call was started on the channel. + */ + 'last_call_started_timestamp'?: (_google_protobuf_Timestamp | null); +} + +/** + * Channel data is data related to a specific Channel or Subchannel. + */ +export interface ChannelData__Output { + /** + * The connectivity state of the channel or subchannel. Implementations + * should always set this. + */ + 'state': (_grpc_channelz_v1_ChannelConnectivityState__Output | null); + /** + * The target this channel originally tried to connect to. May be absent + */ + 'target': (string); + /** + * A trace of recent events on the channel. May be absent. + */ + 'trace': (_grpc_channelz_v1_ChannelTrace__Output | null); + /** + * The number of calls started on the channel + */ + 'calls_started': (string); + /** + * The number of calls that have completed with an OK status + */ + 'calls_succeeded': (string); + /** + * The number of calls that have completed with a non-OK status + */ + 'calls_failed': (string); + /** + * The last time a call was started on the channel. + */ + 'last_call_started_timestamp': (_google_protobuf_Timestamp__Output | null); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/ChannelRef.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/ChannelRef.ts new file mode 100644 index 000000000..231d00876 --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/ChannelRef.ts @@ -0,0 +1,31 @@ +// Original file: proto/channelz.proto + +import type { Long } from '@grpc/proto-loader'; + +/** + * ChannelRef is a reference to a Channel. + */ +export interface ChannelRef { + /** + * The globally unique id for this channel. Must be a positive number. + */ + 'channel_id'?: (number | string | Long); + /** + * An optional name associated with the channel. + */ + 'name'?: (string); +} + +/** + * ChannelRef is a reference to a Channel. + */ +export interface ChannelRef__Output { + /** + * The globally unique id for this channel. Must be a positive number. + */ + 'channel_id': (string); + /** + * An optional name associated with the channel. + */ + 'name': (string); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/ChannelTrace.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/ChannelTrace.ts new file mode 100644 index 000000000..7dbc8d924 --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/ChannelTrace.ts @@ -0,0 +1,45 @@ +// Original file: proto/channelz.proto + +import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp'; +import type { ChannelTraceEvent as _grpc_channelz_v1_ChannelTraceEvent, ChannelTraceEvent__Output as _grpc_channelz_v1_ChannelTraceEvent__Output } from '../../../grpc/channelz/v1/ChannelTraceEvent'; +import type { Long } from '@grpc/proto-loader'; + +/** + * ChannelTrace represents the recent events that have occurred on the channel. + */ +export interface ChannelTrace { + /** + * Number of events ever logged in this tracing object. This can differ from + * events.size() because events can be overwritten or garbage collected by + * implementations. + */ + 'num_events_logged'?: (number | string | Long); + /** + * Time that this channel was created. + */ + 'creation_timestamp'?: (_google_protobuf_Timestamp | null); + /** + * List of events that have occurred on this channel. + */ + 'events'?: (_grpc_channelz_v1_ChannelTraceEvent)[]; +} + +/** + * ChannelTrace represents the recent events that have occurred on the channel. + */ +export interface ChannelTrace__Output { + /** + * Number of events ever logged in this tracing object. This can differ from + * events.size() because events can be overwritten or garbage collected by + * implementations. + */ + 'num_events_logged': (string); + /** + * Time that this channel was created. + */ + 'creation_timestamp': (_google_protobuf_Timestamp__Output | null); + /** + * List of events that have occurred on this channel. + */ + 'events': (_grpc_channelz_v1_ChannelTraceEvent__Output)[]; +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/ChannelTraceEvent.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/ChannelTraceEvent.ts new file mode 100644 index 000000000..24b97fbcd --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/ChannelTraceEvent.ts @@ -0,0 +1,73 @@ +// Original file: proto/channelz.proto + +import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp'; +import type { ChannelRef as _grpc_channelz_v1_ChannelRef, ChannelRef__Output as _grpc_channelz_v1_ChannelRef__Output } from '../../../grpc/channelz/v1/ChannelRef'; +import type { SubchannelRef as _grpc_channelz_v1_SubchannelRef, SubchannelRef__Output as _grpc_channelz_v1_SubchannelRef__Output } from '../../../grpc/channelz/v1/SubchannelRef'; + +// Original file: proto/channelz.proto + +/** + * The supported severity levels of trace events. + */ +export enum _grpc_channelz_v1_ChannelTraceEvent_Severity { + CT_UNKNOWN = 0, + CT_INFO = 1, + CT_WARNING = 2, + CT_ERROR = 3, +} + +/** + * A trace event is an interesting thing that happened to a channel or + * subchannel, such as creation, address resolution, subchannel creation, etc. + */ +export interface ChannelTraceEvent { + /** + * High level description of the event. + */ + 'description'?: (string); + /** + * the severity of the trace event + */ + 'severity'?: (_grpc_channelz_v1_ChannelTraceEvent_Severity | keyof typeof _grpc_channelz_v1_ChannelTraceEvent_Severity); + /** + * When this event occurred. + */ + 'timestamp'?: (_google_protobuf_Timestamp | null); + 'channel_ref'?: (_grpc_channelz_v1_ChannelRef | null); + 'subchannel_ref'?: (_grpc_channelz_v1_SubchannelRef | null); + /** + * ref of referenced channel or subchannel. + * Optional, only present if this event refers to a child object. For example, + * this field would be filled if this trace event was for a subchannel being + * created. + */ + 'child_ref'?: "channel_ref"|"subchannel_ref"; +} + +/** + * A trace event is an interesting thing that happened to a channel or + * subchannel, such as creation, address resolution, subchannel creation, etc. + */ +export interface ChannelTraceEvent__Output { + /** + * High level description of the event. + */ + 'description': (string); + /** + * the severity of the trace event + */ + 'severity': (keyof typeof _grpc_channelz_v1_ChannelTraceEvent_Severity); + /** + * When this event occurred. + */ + 'timestamp': (_google_protobuf_Timestamp__Output | null); + 'channel_ref'?: (_grpc_channelz_v1_ChannelRef__Output | null); + 'subchannel_ref'?: (_grpc_channelz_v1_SubchannelRef__Output | null); + /** + * ref of referenced channel or subchannel. + * Optional, only present if this event refers to a child object. For example, + * this field would be filled if this trace event was for a subchannel being + * created. + */ + 'child_ref': "channel_ref"|"subchannel_ref"; +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/Channelz.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/Channelz.ts new file mode 100644 index 000000000..ace712454 --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/Channelz.ts @@ -0,0 +1,178 @@ +// Original file: proto/channelz.proto + +import type * as grpc from '../../../../index' +import type { MethodDefinition } from '@grpc/proto-loader' +import type { GetChannelRequest as _grpc_channelz_v1_GetChannelRequest, GetChannelRequest__Output as _grpc_channelz_v1_GetChannelRequest__Output } from '../../../grpc/channelz/v1/GetChannelRequest'; +import type { GetChannelResponse as _grpc_channelz_v1_GetChannelResponse, GetChannelResponse__Output as _grpc_channelz_v1_GetChannelResponse__Output } from '../../../grpc/channelz/v1/GetChannelResponse'; +import type { GetServerRequest as _grpc_channelz_v1_GetServerRequest, GetServerRequest__Output as _grpc_channelz_v1_GetServerRequest__Output } from '../../../grpc/channelz/v1/GetServerRequest'; +import type { GetServerResponse as _grpc_channelz_v1_GetServerResponse, GetServerResponse__Output as _grpc_channelz_v1_GetServerResponse__Output } from '../../../grpc/channelz/v1/GetServerResponse'; +import type { GetServerSocketsRequest as _grpc_channelz_v1_GetServerSocketsRequest, GetServerSocketsRequest__Output as _grpc_channelz_v1_GetServerSocketsRequest__Output } from '../../../grpc/channelz/v1/GetServerSocketsRequest'; +import type { GetServerSocketsResponse as _grpc_channelz_v1_GetServerSocketsResponse, GetServerSocketsResponse__Output as _grpc_channelz_v1_GetServerSocketsResponse__Output } from '../../../grpc/channelz/v1/GetServerSocketsResponse'; +import type { GetServersRequest as _grpc_channelz_v1_GetServersRequest, GetServersRequest__Output as _grpc_channelz_v1_GetServersRequest__Output } from '../../../grpc/channelz/v1/GetServersRequest'; +import type { GetServersResponse as _grpc_channelz_v1_GetServersResponse, GetServersResponse__Output as _grpc_channelz_v1_GetServersResponse__Output } from '../../../grpc/channelz/v1/GetServersResponse'; +import type { GetSocketRequest as _grpc_channelz_v1_GetSocketRequest, GetSocketRequest__Output as _grpc_channelz_v1_GetSocketRequest__Output } from '../../../grpc/channelz/v1/GetSocketRequest'; +import type { GetSocketResponse as _grpc_channelz_v1_GetSocketResponse, GetSocketResponse__Output as _grpc_channelz_v1_GetSocketResponse__Output } from '../../../grpc/channelz/v1/GetSocketResponse'; +import type { GetSubchannelRequest as _grpc_channelz_v1_GetSubchannelRequest, GetSubchannelRequest__Output as _grpc_channelz_v1_GetSubchannelRequest__Output } from '../../../grpc/channelz/v1/GetSubchannelRequest'; +import type { GetSubchannelResponse as _grpc_channelz_v1_GetSubchannelResponse, GetSubchannelResponse__Output as _grpc_channelz_v1_GetSubchannelResponse__Output } from '../../../grpc/channelz/v1/GetSubchannelResponse'; +import type { GetTopChannelsRequest as _grpc_channelz_v1_GetTopChannelsRequest, GetTopChannelsRequest__Output as _grpc_channelz_v1_GetTopChannelsRequest__Output } from '../../../grpc/channelz/v1/GetTopChannelsRequest'; +import type { GetTopChannelsResponse as _grpc_channelz_v1_GetTopChannelsResponse, GetTopChannelsResponse__Output as _grpc_channelz_v1_GetTopChannelsResponse__Output } from '../../../grpc/channelz/v1/GetTopChannelsResponse'; + +/** + * Channelz is a service exposed by gRPC servers that provides detailed debug + * information. + */ +export interface ChannelzClient extends grpc.Client { + /** + * Returns a single Channel, or else a NOT_FOUND code. + */ + GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetChannelResponse__Output) => void): grpc.ClientUnaryCall; + GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetChannelResponse__Output) => void): grpc.ClientUnaryCall; + GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetChannelResponse__Output) => void): grpc.ClientUnaryCall; + GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetChannelResponse__Output) => void): grpc.ClientUnaryCall; + + /** + * Returns a single Server, or else a NOT_FOUND code. + */ + GetServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; + GetServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; + GetServer(argument: _grpc_channelz_v1_GetServerRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; + GetServer(argument: _grpc_channelz_v1_GetServerRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; + /** + * Returns a single Server, or else a NOT_FOUND code. + */ + getServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; + getServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; + getServer(argument: _grpc_channelz_v1_GetServerRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; + getServer(argument: _grpc_channelz_v1_GetServerRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; + + /** + * Gets all server sockets that exist in the process. + */ + GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; + GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; + GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; + GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; + /** + * Gets all server sockets that exist in the process. + */ + getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; + getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; + getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; + getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; + + /** + * Gets all servers that exist in the process. + */ + GetServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; + GetServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; + GetServers(argument: _grpc_channelz_v1_GetServersRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; + GetServers(argument: _grpc_channelz_v1_GetServersRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; + /** + * Gets all servers that exist in the process. + */ + getServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; + getServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; + getServers(argument: _grpc_channelz_v1_GetServersRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; + getServers(argument: _grpc_channelz_v1_GetServersRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; + + /** + * Returns a single Socket or else a NOT_FOUND code. + */ + GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; + GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; + GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; + GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; + /** + * Returns a single Socket or else a NOT_FOUND code. + */ + getSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; + getSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; + getSocket(argument: _grpc_channelz_v1_GetSocketRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; + getSocket(argument: _grpc_channelz_v1_GetSocketRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; + + /** + * Returns a single Subchannel, or else a NOT_FOUND code. + */ + GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; + GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; + GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; + GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; + /** + * Returns a single Subchannel, or else a NOT_FOUND code. + */ + getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; + getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; + getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; + getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; + + /** + * Gets all root channels (i.e. channels the application has directly + * created). This does not include subchannels nor non-top level channels. + */ + GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; + GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; + GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; + GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; + /** + * Gets all root channels (i.e. channels the application has directly + * created). This does not include subchannels nor non-top level channels. + */ + getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; + getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; + getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; + getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; + +} + +/** + * Channelz is a service exposed by gRPC servers that provides detailed debug + * information. + */ +export interface ChannelzHandlers extends grpc.UntypedServiceImplementation { + /** + * Returns a single Channel, or else a NOT_FOUND code. + */ + GetChannel: grpc.handleUnaryCall<_grpc_channelz_v1_GetChannelRequest__Output, _grpc_channelz_v1_GetChannelResponse>; + + /** + * Returns a single Server, or else a NOT_FOUND code. + */ + GetServer: grpc.handleUnaryCall<_grpc_channelz_v1_GetServerRequest__Output, _grpc_channelz_v1_GetServerResponse>; + + /** + * Gets all server sockets that exist in the process. + */ + GetServerSockets: grpc.handleUnaryCall<_grpc_channelz_v1_GetServerSocketsRequest__Output, _grpc_channelz_v1_GetServerSocketsResponse>; + + /** + * Gets all servers that exist in the process. + */ + GetServers: grpc.handleUnaryCall<_grpc_channelz_v1_GetServersRequest__Output, _grpc_channelz_v1_GetServersResponse>; + + /** + * Returns a single Socket or else a NOT_FOUND code. + */ + GetSocket: grpc.handleUnaryCall<_grpc_channelz_v1_GetSocketRequest__Output, _grpc_channelz_v1_GetSocketResponse>; + + /** + * Returns a single Subchannel, or else a NOT_FOUND code. + */ + GetSubchannel: grpc.handleUnaryCall<_grpc_channelz_v1_GetSubchannelRequest__Output, _grpc_channelz_v1_GetSubchannelResponse>; + + /** + * Gets all root channels (i.e. channels the application has directly + * created). This does not include subchannels nor non-top level channels. + */ + GetTopChannels: grpc.handleUnaryCall<_grpc_channelz_v1_GetTopChannelsRequest__Output, _grpc_channelz_v1_GetTopChannelsResponse>; + +} + +export interface ChannelzDefinition extends grpc.ServiceDefinition { + GetChannel: MethodDefinition<_grpc_channelz_v1_GetChannelRequest, _grpc_channelz_v1_GetChannelResponse, _grpc_channelz_v1_GetChannelRequest__Output, _grpc_channelz_v1_GetChannelResponse__Output> + GetServer: MethodDefinition<_grpc_channelz_v1_GetServerRequest, _grpc_channelz_v1_GetServerResponse, _grpc_channelz_v1_GetServerRequest__Output, _grpc_channelz_v1_GetServerResponse__Output> + GetServerSockets: MethodDefinition<_grpc_channelz_v1_GetServerSocketsRequest, _grpc_channelz_v1_GetServerSocketsResponse, _grpc_channelz_v1_GetServerSocketsRequest__Output, _grpc_channelz_v1_GetServerSocketsResponse__Output> + GetServers: MethodDefinition<_grpc_channelz_v1_GetServersRequest, _grpc_channelz_v1_GetServersResponse, _grpc_channelz_v1_GetServersRequest__Output, _grpc_channelz_v1_GetServersResponse__Output> + GetSocket: MethodDefinition<_grpc_channelz_v1_GetSocketRequest, _grpc_channelz_v1_GetSocketResponse, _grpc_channelz_v1_GetSocketRequest__Output, _grpc_channelz_v1_GetSocketResponse__Output> + GetSubchannel: MethodDefinition<_grpc_channelz_v1_GetSubchannelRequest, _grpc_channelz_v1_GetSubchannelResponse, _grpc_channelz_v1_GetSubchannelRequest__Output, _grpc_channelz_v1_GetSubchannelResponse__Output> + GetTopChannels: MethodDefinition<_grpc_channelz_v1_GetTopChannelsRequest, _grpc_channelz_v1_GetTopChannelsResponse, _grpc_channelz_v1_GetTopChannelsRequest__Output, _grpc_channelz_v1_GetTopChannelsResponse__Output> +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/GetChannelRequest.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/GetChannelRequest.ts new file mode 100644 index 000000000..437e2d60a --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/GetChannelRequest.ts @@ -0,0 +1,17 @@ +// Original file: proto/channelz.proto + +import type { Long } from '@grpc/proto-loader'; + +export interface GetChannelRequest { + /** + * channel_id is the identifier of the specific channel to get. + */ + 'channel_id'?: (number | string | Long); +} + +export interface GetChannelRequest__Output { + /** + * channel_id is the identifier of the specific channel to get. + */ + 'channel_id': (string); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/GetChannelResponse.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/GetChannelResponse.ts new file mode 100644 index 000000000..2e967a458 --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/GetChannelResponse.ts @@ -0,0 +1,19 @@ +// Original file: proto/channelz.proto + +import type { Channel as _grpc_channelz_v1_Channel, Channel__Output as _grpc_channelz_v1_Channel__Output } from '../../../grpc/channelz/v1/Channel'; + +export interface GetChannelResponse { + /** + * The Channel that corresponds to the requested channel_id. This field + * should be set. + */ + 'channel'?: (_grpc_channelz_v1_Channel | null); +} + +export interface GetChannelResponse__Output { + /** + * The Channel that corresponds to the requested channel_id. This field + * should be set. + */ + 'channel': (_grpc_channelz_v1_Channel__Output | null); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/GetServerRequest.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/GetServerRequest.ts new file mode 100644 index 000000000..f5d4a298f --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/GetServerRequest.ts @@ -0,0 +1,17 @@ +// Original file: proto/channelz.proto + +import type { Long } from '@grpc/proto-loader'; + +export interface GetServerRequest { + /** + * server_id is the identifier of the specific server to get. + */ + 'server_id'?: (number | string | Long); +} + +export interface GetServerRequest__Output { + /** + * server_id is the identifier of the specific server to get. + */ + 'server_id': (string); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/GetServerResponse.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/GetServerResponse.ts new file mode 100644 index 000000000..fe0078209 --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/GetServerResponse.ts @@ -0,0 +1,19 @@ +// Original file: proto/channelz.proto + +import type { Server as _grpc_channelz_v1_Server, Server__Output as _grpc_channelz_v1_Server__Output } from '../../../grpc/channelz/v1/Server'; + +export interface GetServerResponse { + /** + * The Server that corresponds to the requested server_id. This field + * should be set. + */ + 'server'?: (_grpc_channelz_v1_Server | null); +} + +export interface GetServerResponse__Output { + /** + * The Server that corresponds to the requested server_id. This field + * should be set. + */ + 'server': (_grpc_channelz_v1_Server__Output | null); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/GetServerSocketsRequest.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/GetServerSocketsRequest.ts new file mode 100644 index 000000000..c33056edc --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/GetServerSocketsRequest.ts @@ -0,0 +1,39 @@ +// Original file: proto/channelz.proto + +import type { Long } from '@grpc/proto-loader'; + +export interface GetServerSocketsRequest { + 'server_id'?: (number | string | Long); + /** + * start_socket_id indicates that only sockets at or above this id should be + * included in the results. + * To request the first page, this must be set to 0. To request + * subsequent pages, the client generates this value by adding 1 to + * the highest seen result ID. + */ + 'start_socket_id'?: (number | string | Long); + /** + * If non-zero, the server will return a page of results containing + * at most this many items. If zero, the server will choose a + * reasonable page size. Must never be negative. + */ + 'max_results'?: (number | string | Long); +} + +export interface GetServerSocketsRequest__Output { + 'server_id': (string); + /** + * start_socket_id indicates that only sockets at or above this id should be + * included in the results. + * To request the first page, this must be set to 0. To request + * subsequent pages, the client generates this value by adding 1 to + * the highest seen result ID. + */ + 'start_socket_id': (string); + /** + * If non-zero, the server will return a page of results containing + * at most this many items. If zero, the server will choose a + * reasonable page size. Must never be negative. + */ + 'max_results': (string); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/GetServerSocketsResponse.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/GetServerSocketsResponse.ts new file mode 100644 index 000000000..112f277e3 --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/GetServerSocketsResponse.ts @@ -0,0 +1,33 @@ +// Original file: proto/channelz.proto + +import type { SocketRef as _grpc_channelz_v1_SocketRef, SocketRef__Output as _grpc_channelz_v1_SocketRef__Output } from '../../../grpc/channelz/v1/SocketRef'; + +export interface GetServerSocketsResponse { + /** + * list of socket refs that the connection detail service knows about. Sorted in + * ascending socket_id order. + * Must contain at least 1 result, otherwise 'end' must be true. + */ + 'socket_ref'?: (_grpc_channelz_v1_SocketRef)[]; + /** + * If set, indicates that the list of sockets is the final list. Requesting + * more sockets will only return more if they are created after this RPC + * completes. + */ + 'end'?: (boolean); +} + +export interface GetServerSocketsResponse__Output { + /** + * list of socket refs that the connection detail service knows about. Sorted in + * ascending socket_id order. + * Must contain at least 1 result, otherwise 'end' must be true. + */ + 'socket_ref': (_grpc_channelz_v1_SocketRef__Output)[]; + /** + * If set, indicates that the list of sockets is the final list. Requesting + * more sockets will only return more if they are created after this RPC + * completes. + */ + 'end': (boolean); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/GetServersRequest.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/GetServersRequest.ts new file mode 100644 index 000000000..2defea62d --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/GetServersRequest.ts @@ -0,0 +1,37 @@ +// Original file: proto/channelz.proto + +import type { Long } from '@grpc/proto-loader'; + +export interface GetServersRequest { + /** + * start_server_id indicates that only servers at or above this id should be + * included in the results. + * To request the first page, this must be set to 0. To request + * subsequent pages, the client generates this value by adding 1 to + * the highest seen result ID. + */ + 'start_server_id'?: (number | string | Long); + /** + * If non-zero, the server will return a page of results containing + * at most this many items. If zero, the server will choose a + * reasonable page size. Must never be negative. + */ + 'max_results'?: (number | string | Long); +} + +export interface GetServersRequest__Output { + /** + * start_server_id indicates that only servers at or above this id should be + * included in the results. + * To request the first page, this must be set to 0. To request + * subsequent pages, the client generates this value by adding 1 to + * the highest seen result ID. + */ + 'start_server_id': (string); + /** + * If non-zero, the server will return a page of results containing + * at most this many items. If zero, the server will choose a + * reasonable page size. Must never be negative. + */ + 'max_results': (string); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/GetServersResponse.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/GetServersResponse.ts new file mode 100644 index 000000000..b07893b8c --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/GetServersResponse.ts @@ -0,0 +1,33 @@ +// Original file: proto/channelz.proto + +import type { Server as _grpc_channelz_v1_Server, Server__Output as _grpc_channelz_v1_Server__Output } from '../../../grpc/channelz/v1/Server'; + +export interface GetServersResponse { + /** + * list of servers that the connection detail service knows about. Sorted in + * ascending server_id order. + * Must contain at least 1 result, otherwise 'end' must be true. + */ + 'server'?: (_grpc_channelz_v1_Server)[]; + /** + * If set, indicates that the list of servers is the final list. Requesting + * more servers will only return more if they are created after this RPC + * completes. + */ + 'end'?: (boolean); +} + +export interface GetServersResponse__Output { + /** + * list of servers that the connection detail service knows about. Sorted in + * ascending server_id order. + * Must contain at least 1 result, otherwise 'end' must be true. + */ + 'server': (_grpc_channelz_v1_Server__Output)[]; + /** + * If set, indicates that the list of servers is the final list. Requesting + * more servers will only return more if they are created after this RPC + * completes. + */ + 'end': (boolean); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/GetSocketRequest.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/GetSocketRequest.ts new file mode 100644 index 000000000..b3dc1608e --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/GetSocketRequest.ts @@ -0,0 +1,29 @@ +// Original file: proto/channelz.proto + +import type { Long } from '@grpc/proto-loader'; + +export interface GetSocketRequest { + /** + * socket_id is the identifier of the specific socket to get. + */ + 'socket_id'?: (number | string | Long); + /** + * If true, the response will contain only high level information + * that is inexpensive to obtain. Fields thay may be omitted are + * documented. + */ + 'summary'?: (boolean); +} + +export interface GetSocketRequest__Output { + /** + * socket_id is the identifier of the specific socket to get. + */ + 'socket_id': (string); + /** + * If true, the response will contain only high level information + * that is inexpensive to obtain. Fields thay may be omitted are + * documented. + */ + 'summary': (boolean); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/GetSocketResponse.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/GetSocketResponse.ts new file mode 100644 index 000000000..b6304b7f0 --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/GetSocketResponse.ts @@ -0,0 +1,19 @@ +// Original file: proto/channelz.proto + +import type { Socket as _grpc_channelz_v1_Socket, Socket__Output as _grpc_channelz_v1_Socket__Output } from '../../../grpc/channelz/v1/Socket'; + +export interface GetSocketResponse { + /** + * The Socket that corresponds to the requested socket_id. This field + * should be set. + */ + 'socket'?: (_grpc_channelz_v1_Socket | null); +} + +export interface GetSocketResponse__Output { + /** + * The Socket that corresponds to the requested socket_id. This field + * should be set. + */ + 'socket': (_grpc_channelz_v1_Socket__Output | null); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/GetSubchannelRequest.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/GetSubchannelRequest.ts new file mode 100644 index 000000000..f481a81d2 --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/GetSubchannelRequest.ts @@ -0,0 +1,17 @@ +// Original file: proto/channelz.proto + +import type { Long } from '@grpc/proto-loader'; + +export interface GetSubchannelRequest { + /** + * subchannel_id is the identifier of the specific subchannel to get. + */ + 'subchannel_id'?: (number | string | Long); +} + +export interface GetSubchannelRequest__Output { + /** + * subchannel_id is the identifier of the specific subchannel to get. + */ + 'subchannel_id': (string); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/GetSubchannelResponse.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/GetSubchannelResponse.ts new file mode 100644 index 000000000..57d2bf2dc --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/GetSubchannelResponse.ts @@ -0,0 +1,19 @@ +// Original file: proto/channelz.proto + +import type { Subchannel as _grpc_channelz_v1_Subchannel, Subchannel__Output as _grpc_channelz_v1_Subchannel__Output } from '../../../grpc/channelz/v1/Subchannel'; + +export interface GetSubchannelResponse { + /** + * The Subchannel that corresponds to the requested subchannel_id. This + * field should be set. + */ + 'subchannel'?: (_grpc_channelz_v1_Subchannel | null); +} + +export interface GetSubchannelResponse__Output { + /** + * The Subchannel that corresponds to the requested subchannel_id. This + * field should be set. + */ + 'subchannel': (_grpc_channelz_v1_Subchannel__Output | null); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/GetTopChannelsRequest.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/GetTopChannelsRequest.ts new file mode 100644 index 000000000..a122d7a85 --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/GetTopChannelsRequest.ts @@ -0,0 +1,37 @@ +// Original file: proto/channelz.proto + +import type { Long } from '@grpc/proto-loader'; + +export interface GetTopChannelsRequest { + /** + * start_channel_id indicates that only channels at or above this id should be + * included in the results. + * To request the first page, this should be set to 0. To request + * subsequent pages, the client generates this value by adding 1 to + * the highest seen result ID. + */ + 'start_channel_id'?: (number | string | Long); + /** + * If non-zero, the server will return a page of results containing + * at most this many items. If zero, the server will choose a + * reasonable page size. Must never be negative. + */ + 'max_results'?: (number | string | Long); +} + +export interface GetTopChannelsRequest__Output { + /** + * start_channel_id indicates that only channels at or above this id should be + * included in the results. + * To request the first page, this should be set to 0. To request + * subsequent pages, the client generates this value by adding 1 to + * the highest seen result ID. + */ + 'start_channel_id': (string); + /** + * If non-zero, the server will return a page of results containing + * at most this many items. If zero, the server will choose a + * reasonable page size. Must never be negative. + */ + 'max_results': (string); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/GetTopChannelsResponse.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/GetTopChannelsResponse.ts new file mode 100644 index 000000000..d96e63673 --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/GetTopChannelsResponse.ts @@ -0,0 +1,33 @@ +// Original file: proto/channelz.proto + +import type { Channel as _grpc_channelz_v1_Channel, Channel__Output as _grpc_channelz_v1_Channel__Output } from '../../../grpc/channelz/v1/Channel'; + +export interface GetTopChannelsResponse { + /** + * list of channels that the connection detail service knows about. Sorted in + * ascending channel_id order. + * Must contain at least 1 result, otherwise 'end' must be true. + */ + 'channel'?: (_grpc_channelz_v1_Channel)[]; + /** + * If set, indicates that the list of channels is the final list. Requesting + * more channels can only return more if they are created after this RPC + * completes. + */ + 'end'?: (boolean); +} + +export interface GetTopChannelsResponse__Output { + /** + * list of channels that the connection detail service knows about. Sorted in + * ascending channel_id order. + * Must contain at least 1 result, otherwise 'end' must be true. + */ + 'channel': (_grpc_channelz_v1_Channel__Output)[]; + /** + * If set, indicates that the list of channels is the final list. Requesting + * more channels can only return more if they are created after this RPC + * completes. + */ + 'end': (boolean); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/Security.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/Security.ts new file mode 100644 index 000000000..e555d698e --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/Security.ts @@ -0,0 +1,87 @@ +// Original file: proto/channelz.proto + +import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any'; + +export interface _grpc_channelz_v1_Security_OtherSecurity { + /** + * The human readable version of the value. + */ + 'name'?: (string); + /** + * The actual security details message. + */ + 'value'?: (_google_protobuf_Any | null); +} + +export interface _grpc_channelz_v1_Security_OtherSecurity__Output { + /** + * The human readable version of the value. + */ + 'name': (string); + /** + * The actual security details message. + */ + 'value': (_google_protobuf_Any__Output | null); +} + +export interface _grpc_channelz_v1_Security_Tls { + /** + * The cipher suite name in the RFC 4346 format: + * https://tools.ietf.org/html/rfc4346#appendix-C + */ + 'standard_name'?: (string); + /** + * Some other way to describe the cipher suite if + * the RFC 4346 name is not available. + */ + 'other_name'?: (string); + /** + * the certificate used by this endpoint. + */ + 'local_certificate'?: (Buffer | Uint8Array | string); + /** + * the certificate used by the remote endpoint. + */ + 'remote_certificate'?: (Buffer | Uint8Array | string); + 'cipher_suite'?: "standard_name"|"other_name"; +} + +export interface _grpc_channelz_v1_Security_Tls__Output { + /** + * The cipher suite name in the RFC 4346 format: + * https://tools.ietf.org/html/rfc4346#appendix-C + */ + 'standard_name'?: (string); + /** + * Some other way to describe the cipher suite if + * the RFC 4346 name is not available. + */ + 'other_name'?: (string); + /** + * the certificate used by this endpoint. + */ + 'local_certificate': (Buffer); + /** + * the certificate used by the remote endpoint. + */ + 'remote_certificate': (Buffer); + 'cipher_suite': "standard_name"|"other_name"; +} + +/** + * Security represents details about how secure the socket is. + */ +export interface Security { + 'tls'?: (_grpc_channelz_v1_Security_Tls | null); + 'other'?: (_grpc_channelz_v1_Security_OtherSecurity | null); + 'model'?: "tls"|"other"; +} + +/** + * Security represents details about how secure the socket is. + */ +export interface Security__Output { + 'tls'?: (_grpc_channelz_v1_Security_Tls__Output | null); + 'other'?: (_grpc_channelz_v1_Security_OtherSecurity__Output | null); + 'model': "tls"|"other"; +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/Server.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/Server.ts new file mode 100644 index 000000000..958343358 --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/Server.ts @@ -0,0 +1,45 @@ +// Original file: proto/channelz.proto + +import type { ServerRef as _grpc_channelz_v1_ServerRef, ServerRef__Output as _grpc_channelz_v1_ServerRef__Output } from '../../../grpc/channelz/v1/ServerRef'; +import type { ServerData as _grpc_channelz_v1_ServerData, ServerData__Output as _grpc_channelz_v1_ServerData__Output } from '../../../grpc/channelz/v1/ServerData'; +import type { SocketRef as _grpc_channelz_v1_SocketRef, SocketRef__Output as _grpc_channelz_v1_SocketRef__Output } from '../../../grpc/channelz/v1/SocketRef'; + +/** + * Server represents a single server. There may be multiple servers in a single + * program. + */ +export interface Server { + /** + * The identifier for a Server. This should be set. + */ + 'ref'?: (_grpc_channelz_v1_ServerRef | null); + /** + * The associated data of the Server. + */ + 'data'?: (_grpc_channelz_v1_ServerData | null); + /** + * The sockets that the server is listening on. There are no ordering + * guarantees. This may be absent. + */ + 'listen_socket'?: (_grpc_channelz_v1_SocketRef)[]; +} + +/** + * Server represents a single server. There may be multiple servers in a single + * program. + */ +export interface Server__Output { + /** + * The identifier for a Server. This should be set. + */ + 'ref': (_grpc_channelz_v1_ServerRef__Output | null); + /** + * The associated data of the Server. + */ + 'data': (_grpc_channelz_v1_ServerData__Output | null); + /** + * The sockets that the server is listening on. There are no ordering + * guarantees. This may be absent. + */ + 'listen_socket': (_grpc_channelz_v1_SocketRef__Output)[]; +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/ServerData.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/ServerData.ts new file mode 100644 index 000000000..ce48e36f5 --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/ServerData.ts @@ -0,0 +1,57 @@ +// Original file: proto/channelz.proto + +import type { ChannelTrace as _grpc_channelz_v1_ChannelTrace, ChannelTrace__Output as _grpc_channelz_v1_ChannelTrace__Output } from '../../../grpc/channelz/v1/ChannelTrace'; +import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp'; +import type { Long } from '@grpc/proto-loader'; + +/** + * ServerData is data for a specific Server. + */ +export interface ServerData { + /** + * A trace of recent events on the server. May be absent. + */ + 'trace'?: (_grpc_channelz_v1_ChannelTrace | null); + /** + * The number of incoming calls started on the server + */ + 'calls_started'?: (number | string | Long); + /** + * The number of incoming calls that have completed with an OK status + */ + 'calls_succeeded'?: (number | string | Long); + /** + * The number of incoming calls that have a completed with a non-OK status + */ + 'calls_failed'?: (number | string | Long); + /** + * The last time a call was started on the server. + */ + 'last_call_started_timestamp'?: (_google_protobuf_Timestamp | null); +} + +/** + * ServerData is data for a specific Server. + */ +export interface ServerData__Output { + /** + * A trace of recent events on the server. May be absent. + */ + 'trace': (_grpc_channelz_v1_ChannelTrace__Output | null); + /** + * The number of incoming calls started on the server + */ + 'calls_started': (string); + /** + * The number of incoming calls that have completed with an OK status + */ + 'calls_succeeded': (string); + /** + * The number of incoming calls that have a completed with a non-OK status + */ + 'calls_failed': (string); + /** + * The last time a call was started on the server. + */ + 'last_call_started_timestamp': (_google_protobuf_Timestamp__Output | null); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/ServerRef.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/ServerRef.ts new file mode 100644 index 000000000..389183bdc --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/ServerRef.ts @@ -0,0 +1,31 @@ +// Original file: proto/channelz.proto + +import type { Long } from '@grpc/proto-loader'; + +/** + * ServerRef is a reference to a Server. + */ +export interface ServerRef { + /** + * A globally unique identifier for this server. Must be a positive number. + */ + 'server_id'?: (number | string | Long); + /** + * An optional name associated with the server. + */ + 'name'?: (string); +} + +/** + * ServerRef is a reference to a Server. + */ +export interface ServerRef__Output { + /** + * A globally unique identifier for this server. Must be a positive number. + */ + 'server_id': (string); + /** + * An optional name associated with the server. + */ + 'name': (string); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/Socket.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/Socket.ts new file mode 100644 index 000000000..5829afe98 --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/Socket.ts @@ -0,0 +1,70 @@ +// Original file: proto/channelz.proto + +import type { SocketRef as _grpc_channelz_v1_SocketRef, SocketRef__Output as _grpc_channelz_v1_SocketRef__Output } from '../../../grpc/channelz/v1/SocketRef'; +import type { SocketData as _grpc_channelz_v1_SocketData, SocketData__Output as _grpc_channelz_v1_SocketData__Output } from '../../../grpc/channelz/v1/SocketData'; +import type { Address as _grpc_channelz_v1_Address, Address__Output as _grpc_channelz_v1_Address__Output } from '../../../grpc/channelz/v1/Address'; +import type { Security as _grpc_channelz_v1_Security, Security__Output as _grpc_channelz_v1_Security__Output } from '../../../grpc/channelz/v1/Security'; + +/** + * Information about an actual connection. Pronounced "sock-ay". + */ +export interface Socket { + /** + * The identifier for the Socket. + */ + 'ref'?: (_grpc_channelz_v1_SocketRef | null); + /** + * Data specific to this Socket. + */ + 'data'?: (_grpc_channelz_v1_SocketData | null); + /** + * The locally bound address. + */ + 'local'?: (_grpc_channelz_v1_Address | null); + /** + * The remote bound address. May be absent. + */ + 'remote'?: (_grpc_channelz_v1_Address | null); + /** + * Security details for this socket. May be absent if not available, or + * there is no security on the socket. + */ + 'security'?: (_grpc_channelz_v1_Security | null); + /** + * Optional, represents the name of the remote endpoint, if different than + * the original target name. + */ + 'remote_name'?: (string); +} + +/** + * Information about an actual connection. Pronounced "sock-ay". + */ +export interface Socket__Output { + /** + * The identifier for the Socket. + */ + 'ref': (_grpc_channelz_v1_SocketRef__Output | null); + /** + * Data specific to this Socket. + */ + 'data': (_grpc_channelz_v1_SocketData__Output | null); + /** + * The locally bound address. + */ + 'local': (_grpc_channelz_v1_Address__Output | null); + /** + * The remote bound address. May be absent. + */ + 'remote': (_grpc_channelz_v1_Address__Output | null); + /** + * Security details for this socket. May be absent if not available, or + * there is no security on the socket. + */ + 'security': (_grpc_channelz_v1_Security__Output | null); + /** + * Optional, represents the name of the remote endpoint, if different than + * the original target name. + */ + 'remote_name': (string); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/SocketData.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/SocketData.ts new file mode 100644 index 000000000..c62d4d10c --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/SocketData.ts @@ -0,0 +1,150 @@ +// Original file: proto/channelz.proto + +import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp'; +import type { Int64Value as _google_protobuf_Int64Value, Int64Value__Output as _google_protobuf_Int64Value__Output } from '../../../google/protobuf/Int64Value'; +import type { SocketOption as _grpc_channelz_v1_SocketOption, SocketOption__Output as _grpc_channelz_v1_SocketOption__Output } from '../../../grpc/channelz/v1/SocketOption'; +import type { Long } from '@grpc/proto-loader'; + +/** + * SocketData is data associated for a specific Socket. The fields present + * are specific to the implementation, so there may be minor differences in + * the semantics. (e.g. flow control windows) + */ +export interface SocketData { + /** + * The number of streams that have been started. + */ + 'streams_started'?: (number | string | Long); + /** + * The number of streams that have ended successfully: + * On client side, received frame with eos bit set; + * On server side, sent frame with eos bit set. + */ + 'streams_succeeded'?: (number | string | Long); + /** + * The number of streams that have ended unsuccessfully: + * On client side, ended without receiving frame with eos bit set; + * On server side, ended without sending frame with eos bit set. + */ + 'streams_failed'?: (number | string | Long); + /** + * The number of grpc messages successfully sent on this socket. + */ + 'messages_sent'?: (number | string | Long); + /** + * The number of grpc messages received on this socket. + */ + 'messages_received'?: (number | string | Long); + /** + * The number of keep alives sent. This is typically implemented with HTTP/2 + * ping messages. + */ + 'keep_alives_sent'?: (number | string | Long); + /** + * The last time a stream was created by this endpoint. Usually unset for + * servers. + */ + 'last_local_stream_created_timestamp'?: (_google_protobuf_Timestamp | null); + /** + * The last time a stream was created by the remote endpoint. Usually unset + * for clients. + */ + 'last_remote_stream_created_timestamp'?: (_google_protobuf_Timestamp | null); + /** + * The last time a message was sent by this endpoint. + */ + 'last_message_sent_timestamp'?: (_google_protobuf_Timestamp | null); + /** + * The last time a message was received by this endpoint. + */ + 'last_message_received_timestamp'?: (_google_protobuf_Timestamp | null); + /** + * The amount of window, granted to the local endpoint by the remote endpoint. + * This may be slightly out of date due to network latency. This does NOT + * include stream level or TCP level flow control info. + */ + 'local_flow_control_window'?: (_google_protobuf_Int64Value | null); + /** + * The amount of window, granted to the remote endpoint by the local endpoint. + * This may be slightly out of date due to network latency. This does NOT + * include stream level or TCP level flow control info. + */ + 'remote_flow_control_window'?: (_google_protobuf_Int64Value | null); + /** + * Socket options set on this socket. May be absent if 'summary' is set + * on GetSocketRequest. + */ + 'option'?: (_grpc_channelz_v1_SocketOption)[]; +} + +/** + * SocketData is data associated for a specific Socket. The fields present + * are specific to the implementation, so there may be minor differences in + * the semantics. (e.g. flow control windows) + */ +export interface SocketData__Output { + /** + * The number of streams that have been started. + */ + 'streams_started': (string); + /** + * The number of streams that have ended successfully: + * On client side, received frame with eos bit set; + * On server side, sent frame with eos bit set. + */ + 'streams_succeeded': (string); + /** + * The number of streams that have ended unsuccessfully: + * On client side, ended without receiving frame with eos bit set; + * On server side, ended without sending frame with eos bit set. + */ + 'streams_failed': (string); + /** + * The number of grpc messages successfully sent on this socket. + */ + 'messages_sent': (string); + /** + * The number of grpc messages received on this socket. + */ + 'messages_received': (string); + /** + * The number of keep alives sent. This is typically implemented with HTTP/2 + * ping messages. + */ + 'keep_alives_sent': (string); + /** + * The last time a stream was created by this endpoint. Usually unset for + * servers. + */ + 'last_local_stream_created_timestamp': (_google_protobuf_Timestamp__Output | null); + /** + * The last time a stream was created by the remote endpoint. Usually unset + * for clients. + */ + 'last_remote_stream_created_timestamp': (_google_protobuf_Timestamp__Output | null); + /** + * The last time a message was sent by this endpoint. + */ + 'last_message_sent_timestamp': (_google_protobuf_Timestamp__Output | null); + /** + * The last time a message was received by this endpoint. + */ + 'last_message_received_timestamp': (_google_protobuf_Timestamp__Output | null); + /** + * The amount of window, granted to the local endpoint by the remote endpoint. + * This may be slightly out of date due to network latency. This does NOT + * include stream level or TCP level flow control info. + */ + 'local_flow_control_window': (_google_protobuf_Int64Value__Output | null); + /** + * The amount of window, granted to the remote endpoint by the local endpoint. + * This may be slightly out of date due to network latency. This does NOT + * include stream level or TCP level flow control info. + */ + 'remote_flow_control_window': (_google_protobuf_Int64Value__Output | null); + /** + * Socket options set on this socket. May be absent if 'summary' is set + * on GetSocketRequest. + */ + 'option': (_grpc_channelz_v1_SocketOption__Output)[]; +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/SocketOption.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/SocketOption.ts new file mode 100644 index 000000000..115b36aae --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/SocketOption.ts @@ -0,0 +1,47 @@ +// Original file: proto/channelz.proto + +import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any'; + +/** + * SocketOption represents socket options for a socket. Specifically, these + * are the options returned by getsockopt(). + */ +export interface SocketOption { + /** + * The full name of the socket option. Typically this will be the upper case + * name, such as "SO_REUSEPORT". + */ + 'name'?: (string); + /** + * The human readable value of this socket option. At least one of value or + * additional will be set. + */ + 'value'?: (string); + /** + * Additional data associated with the socket option. At least one of value + * or additional will be set. + */ + 'additional'?: (_google_protobuf_Any | null); +} + +/** + * SocketOption represents socket options for a socket. Specifically, these + * are the options returned by getsockopt(). + */ +export interface SocketOption__Output { + /** + * The full name of the socket option. Typically this will be the upper case + * name, such as "SO_REUSEPORT". + */ + 'name': (string); + /** + * The human readable value of this socket option. At least one of value or + * additional will be set. + */ + 'value': (string); + /** + * Additional data associated with the socket option. At least one of value + * or additional will be set. + */ + 'additional': (_google_protobuf_Any__Output | null); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/SocketOptionLinger.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/SocketOptionLinger.ts new file mode 100644 index 000000000..d83fa3238 --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/SocketOptionLinger.ts @@ -0,0 +1,33 @@ +// Original file: proto/channelz.proto + +import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../google/protobuf/Duration'; + +/** + * For use with SocketOption's additional field. This is primarily used for + * SO_LINGER. + */ +export interface SocketOptionLinger { + /** + * active maps to `struct linger.l_onoff` + */ + 'active'?: (boolean); + /** + * duration maps to `struct linger.l_linger` + */ + 'duration'?: (_google_protobuf_Duration | null); +} + +/** + * For use with SocketOption's additional field. This is primarily used for + * SO_LINGER. + */ +export interface SocketOptionLinger__Output { + /** + * active maps to `struct linger.l_onoff` + */ + 'active': (boolean); + /** + * duration maps to `struct linger.l_linger` + */ + 'duration': (_google_protobuf_Duration__Output | null); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/SocketOptionTcpInfo.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/SocketOptionTcpInfo.ts new file mode 100644 index 000000000..2f8affe80 --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/SocketOptionTcpInfo.ts @@ -0,0 +1,74 @@ +// Original file: proto/channelz.proto + + +/** + * For use with SocketOption's additional field. Tcp info for + * SOL_TCP and TCP_INFO. + */ +export interface SocketOptionTcpInfo { + 'tcpi_state'?: (number); + 'tcpi_ca_state'?: (number); + 'tcpi_retransmits'?: (number); + 'tcpi_probes'?: (number); + 'tcpi_backoff'?: (number); + 'tcpi_options'?: (number); + 'tcpi_snd_wscale'?: (number); + 'tcpi_rcv_wscale'?: (number); + 'tcpi_rto'?: (number); + 'tcpi_ato'?: (number); + 'tcpi_snd_mss'?: (number); + 'tcpi_rcv_mss'?: (number); + 'tcpi_unacked'?: (number); + 'tcpi_sacked'?: (number); + 'tcpi_lost'?: (number); + 'tcpi_retrans'?: (number); + 'tcpi_fackets'?: (number); + 'tcpi_last_data_sent'?: (number); + 'tcpi_last_ack_sent'?: (number); + 'tcpi_last_data_recv'?: (number); + 'tcpi_last_ack_recv'?: (number); + 'tcpi_pmtu'?: (number); + 'tcpi_rcv_ssthresh'?: (number); + 'tcpi_rtt'?: (number); + 'tcpi_rttvar'?: (number); + 'tcpi_snd_ssthresh'?: (number); + 'tcpi_snd_cwnd'?: (number); + 'tcpi_advmss'?: (number); + 'tcpi_reordering'?: (number); +} + +/** + * For use with SocketOption's additional field. Tcp info for + * SOL_TCP and TCP_INFO. + */ +export interface SocketOptionTcpInfo__Output { + 'tcpi_state': (number); + 'tcpi_ca_state': (number); + 'tcpi_retransmits': (number); + 'tcpi_probes': (number); + 'tcpi_backoff': (number); + 'tcpi_options': (number); + 'tcpi_snd_wscale': (number); + 'tcpi_rcv_wscale': (number); + 'tcpi_rto': (number); + 'tcpi_ato': (number); + 'tcpi_snd_mss': (number); + 'tcpi_rcv_mss': (number); + 'tcpi_unacked': (number); + 'tcpi_sacked': (number); + 'tcpi_lost': (number); + 'tcpi_retrans': (number); + 'tcpi_fackets': (number); + 'tcpi_last_data_sent': (number); + 'tcpi_last_ack_sent': (number); + 'tcpi_last_data_recv': (number); + 'tcpi_last_ack_recv': (number); + 'tcpi_pmtu': (number); + 'tcpi_rcv_ssthresh': (number); + 'tcpi_rtt': (number); + 'tcpi_rttvar': (number); + 'tcpi_snd_ssthresh': (number); + 'tcpi_snd_cwnd': (number); + 'tcpi_advmss': (number); + 'tcpi_reordering': (number); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/SocketOptionTimeout.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/SocketOptionTimeout.ts new file mode 100644 index 000000000..185839b2c --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/SocketOptionTimeout.ts @@ -0,0 +1,19 @@ +// Original file: proto/channelz.proto + +import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../google/protobuf/Duration'; + +/** + * For use with SocketOption's additional field. This is primarily used for + * SO_RCVTIMEO and SO_SNDTIMEO + */ +export interface SocketOptionTimeout { + 'duration'?: (_google_protobuf_Duration | null); +} + +/** + * For use with SocketOption's additional field. This is primarily used for + * SO_RCVTIMEO and SO_SNDTIMEO + */ +export interface SocketOptionTimeout__Output { + 'duration': (_google_protobuf_Duration__Output | null); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/SocketRef.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/SocketRef.ts new file mode 100644 index 000000000..52fdb2bd3 --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/SocketRef.ts @@ -0,0 +1,31 @@ +// Original file: proto/channelz.proto + +import type { Long } from '@grpc/proto-loader'; + +/** + * SocketRef is a reference to a Socket. + */ +export interface SocketRef { + /** + * The globally unique id for this socket. Must be a positive number. + */ + 'socket_id'?: (number | string | Long); + /** + * An optional name associated with the socket. + */ + 'name'?: (string); +} + +/** + * SocketRef is a reference to a Socket. + */ +export interface SocketRef__Output { + /** + * The globally unique id for this socket. Must be a positive number. + */ + 'socket_id': (string); + /** + * An optional name associated with the socket. + */ + 'name': (string); +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/Subchannel.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/Subchannel.ts new file mode 100644 index 000000000..7122fac83 --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/Subchannel.ts @@ -0,0 +1,70 @@ +// Original file: proto/channelz.proto + +import type { SubchannelRef as _grpc_channelz_v1_SubchannelRef, SubchannelRef__Output as _grpc_channelz_v1_SubchannelRef__Output } from '../../../grpc/channelz/v1/SubchannelRef'; +import type { ChannelData as _grpc_channelz_v1_ChannelData, ChannelData__Output as _grpc_channelz_v1_ChannelData__Output } from '../../../grpc/channelz/v1/ChannelData'; +import type { ChannelRef as _grpc_channelz_v1_ChannelRef, ChannelRef__Output as _grpc_channelz_v1_ChannelRef__Output } from '../../../grpc/channelz/v1/ChannelRef'; +import type { SocketRef as _grpc_channelz_v1_SocketRef, SocketRef__Output as _grpc_channelz_v1_SocketRef__Output } from '../../../grpc/channelz/v1/SocketRef'; + +/** + * Subchannel is a logical grouping of channels, subchannels, and sockets. + * A subchannel is load balanced over by it's ancestor + */ +export interface Subchannel { + /** + * The identifier for this channel. + */ + 'ref'?: (_grpc_channelz_v1_SubchannelRef | null); + /** + * Data specific to this channel. + */ + 'data'?: (_grpc_channelz_v1_ChannelData | null); + /** + * There are no ordering guarantees on the order of channel refs. + * There may not be cycles in the ref graph. + * A channel ref may be present in more than one channel or subchannel. + */ + 'channel_ref'?: (_grpc_channelz_v1_ChannelRef)[]; + /** + * At most one of 'channel_ref+subchannel_ref' and 'socket' is set. + * There are no ordering guarantees on the order of subchannel refs. + * There may not be cycles in the ref graph. + * A sub channel ref may be present in more than one channel or subchannel. + */ + 'subchannel_ref'?: (_grpc_channelz_v1_SubchannelRef)[]; + /** + * There are no ordering guarantees on the order of sockets. + */ + 'socket_ref'?: (_grpc_channelz_v1_SocketRef)[]; +} + +/** + * Subchannel is a logical grouping of channels, subchannels, and sockets. + * A subchannel is load balanced over by it's ancestor + */ +export interface Subchannel__Output { + /** + * The identifier for this channel. + */ + 'ref': (_grpc_channelz_v1_SubchannelRef__Output | null); + /** + * Data specific to this channel. + */ + 'data': (_grpc_channelz_v1_ChannelData__Output | null); + /** + * There are no ordering guarantees on the order of channel refs. + * There may not be cycles in the ref graph. + * A channel ref may be present in more than one channel or subchannel. + */ + 'channel_ref': (_grpc_channelz_v1_ChannelRef__Output)[]; + /** + * At most one of 'channel_ref+subchannel_ref' and 'socket' is set. + * There are no ordering guarantees on the order of subchannel refs. + * There may not be cycles in the ref graph. + * A sub channel ref may be present in more than one channel or subchannel. + */ + 'subchannel_ref': (_grpc_channelz_v1_SubchannelRef__Output)[]; + /** + * There are no ordering guarantees on the order of sockets. + */ + 'socket_ref': (_grpc_channelz_v1_SocketRef__Output)[]; +} diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/SubchannelRef.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/SubchannelRef.ts new file mode 100644 index 000000000..b6911c773 --- /dev/null +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/SubchannelRef.ts @@ -0,0 +1,31 @@ +// Original file: proto/channelz.proto + +import type { Long } from '@grpc/proto-loader'; + +/** + * SubchannelRef is a reference to a Subchannel. + */ +export interface SubchannelRef { + /** + * The globally unique id for this subchannel. Must be a positive number. + */ + 'subchannel_id'?: (number | string | Long); + /** + * An optional name associated with the subchannel. + */ + 'name'?: (string); +} + +/** + * SubchannelRef is a reference to a Subchannel. + */ +export interface SubchannelRef__Output { + /** + * The globally unique id for this subchannel. Must be a positive number. + */ + 'subchannel_id': (string); + /** + * An optional name associated with the subchannel. + */ + 'name': (string); +} From 74fdd85123acac606659cf07bb1d1bdebf836439 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 13 Sep 2021 10:58:12 -0700 Subject: [PATCH 073/450] Add channelz service implementation --- packages/grpc-js/src/channel.ts | 3 + packages/grpc-js/src/channelz.ts | 375 ++++++++++++++++++++++++++++- packages/grpc-js/src/server.ts | 14 +- packages/grpc-js/src/subchannel.ts | 5 +- 4 files changed, 387 insertions(+), 10 deletions(-) diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 4a6e88147..c5f7352e4 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -163,6 +163,7 @@ export class ChannelImplementation implements Channel { private configSelector: ConfigSelector | null = null; // Channelz info + private originalTarget: string; private channelzRef: ChannelRef; private channelzTrace: ChannelzTrace; private callTracker = new ChannelzCallTracker(); @@ -196,6 +197,7 @@ export class ChannelImplementation implements Channel { ); } } + this.originalTarget = target; const originalTargetUri = parseUri(target); if (originalTargetUri === null) { throw new Error(`Could not parse target name "${target}"`); @@ -320,6 +322,7 @@ export class ChannelImplementation implements Channel { private getChannelzInfo(): ChannelInfo { return { + target: this.originalTarget, state: this.connectivityState, trace: this.channelzTrace, callTracker: this.callTracker, diff --git a/packages/grpc-js/src/channelz.ts b/packages/grpc-js/src/channelz.ts index 3edbd7bba..7965ad3c2 100644 --- a/packages/grpc-js/src/channelz.ts +++ b/packages/grpc-js/src/channelz.ts @@ -17,7 +17,39 @@ import { isIPv4, isIPv6 } from "net"; import { ConnectivityState } from "./connectivity-state"; -import { SubchannelAddress } from "./subchannel-address"; +import { Status } from "./constants"; +import { Timestamp } from "./generated/google/protobuf/Timestamp"; +import { Channel as ChannelMessage } from "./generated/grpc/channelz/v1/Channel"; +import { ChannelConnectivityState__Output } from "./generated/grpc/channelz/v1/ChannelConnectivityState"; +import { ChannelRef as ChannelRefMessage } from "./generated/grpc/channelz/v1/ChannelRef"; +import { ChannelTrace } from "./generated/grpc/channelz/v1/ChannelTrace"; +import { GetChannelRequest__Output } from "./generated/grpc/channelz/v1/GetChannelRequest"; +import { GetChannelResponse } from "./generated/grpc/channelz/v1/GetChannelResponse"; +import { sendUnaryData, ServerUnaryCall } from "./server-call"; +import { ServerRef as ServerRefMessage } from "./generated/grpc/channelz/v1/ServerRef"; +import { SocketRef as SocketRefMessage } from "./generated/grpc/channelz/v1/SocketRef"; +import { isTcpSubchannelAddress, SubchannelAddress } from "./subchannel-address"; +import { SubchannelRef as SubchannelRefMessage } from "./generated/grpc/channelz/v1/SubchannelRef"; +import { GetServerRequest__Output } from "./generated/grpc/channelz/v1/GetServerRequest"; +import { GetServerResponse } from "./generated/grpc/channelz/v1/GetServerResponse"; +import { Server as ServerMessage } from "./generated/grpc/channelz/v1/Server"; +import { GetServersRequest__Output } from "./generated/grpc/channelz/v1/GetServersRequest"; +import { GetServersResponse } from "./generated/grpc/channelz/v1/GetServersResponse"; +import { GetTopChannelsRequest__Output } from "./generated/grpc/channelz/v1/GetTopChannelsRequest"; +import { GetTopChannelsResponse } from "./generated/grpc/channelz/v1/GetTopChannelsResponse"; +import { GetSubchannelRequest__Output } from "./generated/grpc/channelz/v1/GetSubchannelRequest"; +import { GetSubchannelResponse } from "./generated/grpc/channelz/v1/GetSubchannelResponse"; +import { Subchannel as SubchannelMessage } from "./generated/grpc/channelz/v1/Subchannel"; +import { GetSocketRequest__Output } from "./generated/grpc/channelz/v1/GetSocketRequest"; +import { GetSocketResponse } from "./generated/grpc/channelz/v1/GetSocketResponse"; +import { Socket as SocketMessage } from "./generated/grpc/channelz/v1/Socket"; +import { Address } from "./generated/grpc/channelz/v1/Address"; +import { Security } from "./generated/grpc/channelz/v1/Security"; +import { GetServerSocketsRequest__Output } from "./generated/grpc/channelz/v1/GetServerSocketsRequest"; +import { GetServerSocketsResponse } from "./generated/grpc/channelz/v1/GetServerSocketsResponse"; +import { ChannelzDefinition, ChannelzHandlers } from "./generated/grpc/channelz/v1/Channelz"; +import { ProtoGrpcType as ChannelzProtoGrpcType } from "./generated/channelz"; +import type { loadSync } from '@grpc/proto-loader'; export type TraceSeverity = 'CT_UNKNOWN' | 'CT_INFO' | 'CT_WARNING' | 'CT_ERROR'; @@ -44,6 +76,33 @@ export interface SocketRef { name: string; } +function channelRefToMessage(ref: ChannelRef): ChannelRefMessage { + return { + channel_id: ref.id, + name: ref.name + }; +} + +function subchannelRefToMessage(ref: SubchannelRef): SubchannelRefMessage { + return { + subchannel_id: ref.id, + name: ref.name + } +} + +function serverRefToMessage(ref: ServerRef): ServerRefMessage { + return { + server_id: ref.id + } +} + +function socketRefToMessage(ref: SocketRef): SocketRefMessage { + return { + socket_id: ref.id, + name: ref.name + } +} + interface TraceEvent { description: string; severity: TraceSeverity; @@ -72,6 +131,22 @@ export class ChannelzTrace { }); this.eventsLogged += 1; } + + getTraceMessage(): ChannelTrace { + return { + creation_timestamp: dateToProtoTimestamp(this.creationTimestamp), + num_events_logged: this.eventsLogged, + events: this.events.map(event => { + return { + description: event.description, + severity: event.severity, + timestamp: dateToProtoTimestamp(event.timestamp), + channel_ref: event.childChannel ? channelRefToMessage(event.childChannel) : null, + subchannel_ref: event.childSubchannel ? subchannelRefToMessage(event.childSubchannel) : null + } + }) + }; + } } export class ChannelzChildrenTracker { @@ -185,6 +260,7 @@ export interface ChannelzChildren { } export interface ChannelInfo { + target: string; state: ConnectivityState; trace: ChannelzTrace; callTracker: ChannelzCallTracker; @@ -196,7 +272,8 @@ export interface SubchannelInfo extends ChannelInfo {} export interface ServerInfo { trace: ChannelzTrace; callTracker: ChannelzCallTracker; - children: ChannelzChildren; + listenerChildren: ChannelzChildren; + sessionChildren: ChannelzChildren; } export interface TlsInfo { @@ -342,4 +419,298 @@ function ipAddressStringToBuffer(ipAddress: string): Buffer | null { } else { return null; } +} + +function connectivityStateToMessage(state: ConnectivityState): ChannelConnectivityState__Output { + switch (state) { + case ConnectivityState.CONNECTING: + return { + state: 'CONNECTING' + }; + case ConnectivityState.IDLE: + return { + state: 'IDLE' + }; + case ConnectivityState.READY: + return { + state: 'READY' + }; + case ConnectivityState.SHUTDOWN: + return { + state: 'SHUTDOWN' + }; + case ConnectivityState.TRANSIENT_FAILURE: + return { + state: 'TRANSIENT_FAILURE' + }; + default: + return { + state: 'UNKNOWN' + }; + } +} + +function dateToProtoTimestamp(date?: Date | null): Timestamp | null { + if (!date) { + return null; + } + return { + seconds: date.getSeconds(), + nanos: date.getMilliseconds() * 1_000_000 + } +} + +function getChannelMessage(channelEntry: ChannelEntry): ChannelMessage { + const resolvedInfo = channelEntry.getInfo(); + return { + ref: channelRefToMessage(channelEntry.ref), + data: { + target: resolvedInfo.target, + state: connectivityStateToMessage(resolvedInfo.state), + calls_started: resolvedInfo.callTracker.callsStarted, + calls_succeeded: resolvedInfo.callTracker.callsSucceeded, + calls_failed: resolvedInfo.callTracker.callsFailed, + last_call_started_timestamp: dateToProtoTimestamp(resolvedInfo.callTracker.lastCallStartedTimestamp), + trace: resolvedInfo.trace.getTraceMessage() + }, + channel_ref: resolvedInfo.children.channels.map(ref => channelRefToMessage(ref)), + subchannel_ref: resolvedInfo.children.subchannels.map(ref => subchannelRefToMessage(ref)) + }; +} + +function GetChannel(call: ServerUnaryCall, callback: sendUnaryData): void { + const channelId = Number.parseInt(call.request.channel_id); + const channelEntry = channels[channelId]; + if (channelEntry === undefined) { + callback({ + 'code': Status.NOT_FOUND, + 'details': 'No channel data found for id ' + channelId + }); + return; + } + callback(null, {channel: getChannelMessage(channelEntry)}); +} + +function GetTopChannels(call: ServerUnaryCall, callback: sendUnaryData): void { + const maxResults = Number.parseInt(call.request.max_results); + 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; + } + } + callback(null, { + channel: resultList, + end: i >= servers.length + }); +} + +function getServerMessage(serverEntry: ServerEntry): ServerMessage { + const resolvedInfo = serverEntry.getInfo(); + return { + ref: serverRefToMessage(serverEntry.ref), + data: { + calls_started: resolvedInfo.callTracker.callsStarted, + calls_succeeded: resolvedInfo.callTracker.callsSucceeded, + calls_failed: resolvedInfo.callTracker.callsFailed, + last_call_started_timestamp: dateToProtoTimestamp(resolvedInfo.callTracker.lastCallStartedTimestamp), + trace: resolvedInfo.trace.getTraceMessage() + }, + listen_socket: resolvedInfo.listenerChildren.sockets.map(ref => socketRefToMessage(ref)) + }; +} + +function GetServer(call: ServerUnaryCall, callback: sendUnaryData): void { + const serverId = Number.parseInt(call.request.server_id); + const serverEntry = servers[serverId]; + if (serverEntry === undefined) { + callback({ + 'code': Status.NOT_FOUND, + 'details': 'No server data found for id ' + serverId + }); + return; + } + callback(null, {server: getServerMessage(serverEntry)}); +} + +function GetServers(call: ServerUnaryCall, callback: sendUnaryData): void { + const maxResults = Number.parseInt(call.request.max_results); + 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; + } + } + callback(null, { + server: resultList, + end: i >= servers.length + }); +} + +function GetSubchannel(call: ServerUnaryCall, callback: sendUnaryData): void { + const subchannelId = Number.parseInt(call.request.subchannel_id); + const subchannelEntry = subchannels[subchannelId]; + if (subchannelEntry === undefined) { + callback({ + 'code': Status.NOT_FOUND, + 'details': 'No subchannel data found for id ' + subchannelId + }); + return; + } + const resolvedInfo = subchannelEntry.getInfo(); + const subchannelMessage: SubchannelMessage = { + ref: subchannelRefToMessage(subchannelEntry.ref), + data: { + target: resolvedInfo.target, + state: connectivityStateToMessage(resolvedInfo.state), + calls_started: resolvedInfo.callTracker.callsStarted, + calls_succeeded: resolvedInfo.callTracker.callsSucceeded, + calls_failed: resolvedInfo.callTracker.callsFailed, + last_call_started_timestamp: dateToProtoTimestamp(resolvedInfo.callTracker.lastCallStartedTimestamp), + trace: resolvedInfo.trace.getTraceMessage() + }, + socket_ref: resolvedInfo.children.sockets.map(ref => socketRefToMessage(ref)) + }; + callback(null, {subchannel: subchannelMessage}); +} + +function subchannelAddressToAddressMessage(subchannelAddress: SubchannelAddress): Address { + if (isTcpSubchannelAddress(subchannelAddress)) { + return { + address: 'tcpip_address', + tcpip_address: { + ip_address: ipAddressStringToBuffer(subchannelAddress.host) ?? undefined, + port: subchannelAddress.port + } + }; + } else { + return { + address: 'uds_address', + uds_address: { + filename: subchannelAddress.path + } + }; + } +} + +function GetSocket(call: ServerUnaryCall, callback: sendUnaryData): void { + const socketId = Number.parseInt(call.request.socket_id); + const socketEntry = sockets[socketId]; + if (socketEntry === undefined) { + callback({ + 'code': Status.NOT_FOUND, + 'details': 'No socket data found for id ' + socketId + }); + return; + } + const resolvedInfo = socketEntry.getInfo(); + const securityMessage: Security | null = resolvedInfo.security ? { + model: 'tls', + tls: { + cipher_suite: resolvedInfo.security.cipherSuiteStandardName ? 'standard_name' : 'other_name', + standard_name: resolvedInfo.security.cipherSuiteStandardName ?? undefined, + other_name: resolvedInfo.security.cipherSuiteOtherName ?? undefined, + local_certificate: resolvedInfo.security.localCertificate ?? undefined, + remote_certificate: resolvedInfo.security.remoteCertificate ?? undefined + } + } : null; + const socketMessage: SocketMessage = { + ref: socketRefToMessage(socketEntry.ref), + local: subchannelAddressToAddressMessage(resolvedInfo.localAddress), + remote: resolvedInfo.remoteAddress ? subchannelAddressToAddressMessage(resolvedInfo.remoteAddress) : null, + remote_name: resolvedInfo.remoteName ?? undefined, + security: securityMessage, + data: { + keep_alives_sent: resolvedInfo.keepAlivesSent, + streams_started: resolvedInfo.streamsStarted, + streams_succeeded: resolvedInfo.streamsSucceeded, + streams_failed: resolvedInfo.streamsFailed, + last_local_stream_created_timestamp: dateToProtoTimestamp(resolvedInfo.lastLocalStreamCreatedTimestamp), + last_remote_stream_created_timestamp: dateToProtoTimestamp(resolvedInfo.lastRemoteStreamCreatedTimestamp), + messages_received: resolvedInfo.messagesReceived, + messages_sent: resolvedInfo.messagesSent, + last_message_received_timestamp: dateToProtoTimestamp(resolvedInfo.lastMessageReceivedTimestamp), + last_message_sent_timestamp: dateToProtoTimestamp(resolvedInfo.lastMessageSentTimestamp), + local_flow_control_window: resolvedInfo.localFlowControlWindow ? { value: resolvedInfo.localFlowControlWindow } : null, + remote_flow_control_window: resolvedInfo.remoteFlowControlWindow ? { value: resolvedInfo.remoteFlowControlWindow } : null, + } + }; + callback(null, {socket: socketMessage}); +} + +function GetServerSockets(call: ServerUnaryCall, callback: sendUnaryData): void { + const serverId = Number.parseInt(call.request.server_id); + const serverEntry = servers[serverId]; + if (serverEntry === undefined) { + callback({ + 'code': Status.NOT_FOUND, + 'details': 'No server data found for id ' + serverId + }); + return; + } + const startId = Number.parseInt(call.request.start_socket_id); + const maxResults = Number.parseInt(call.request.max_results); + const resolvedInfo = serverEntry.getInfo(); + const allSockets = resolvedInfo.listenerChildren.sockets.concat(resolvedInfo.sessionChildren.sockets).sort((ref1, ref2) => ref1.id - ref2.id); + 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; + } + } + } + callback(null, { + socket_ref: resultList, + end: i >= allSockets.length + }); +} + +export function getChannelzHandlers(): ChannelzHandlers { + return { + GetChannel, + GetTopChannels, + GetServer, + GetServers, + GetSubchannel, + GetSocket, + GetServerSockets + }; +} + +let loadedChannelzDefinition: ChannelzDefinition | null = null; + +export function getChannelzServiceDefinition(): ChannelzDefinition { + if (loadedChannelzDefinition) { + return loadedChannelzDefinition; + } + /* The purpose of this complexity is to avoid loading @grpc/proto-loader at + * runtime for users who will not use/enable channelz. */ + const loaderLoadSync = require('@grpc/proto-loader').loadSync as typeof loadSync; + const loadedProto = loaderLoadSync('channelz.proto', { + keepCase: true, + longs: String, + enums: String, + defaults: true, + oneofs: true, + includeDirs: [ + '../../proto' + ] + }) as unknown as ChannelzProtoGrpcType; + loadedChannelzDefinition = loadedProto.grpc.channelz.v1.Channelz.service; + return loadedChannelzDefinition; } \ No newline at end of file diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 04c24c072..ef31dadce 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -156,7 +156,8 @@ export class Server { private channelzRef: ServerRef; private channelzTrace = new ChannelzTrace(); private callTracker = new ChannelzCallTracker(); - private childrenTracker = new ChannelzChildrenTracker(); + private listenerChildrenTracker = new ChannelzChildrenTracker(); + private sessionChildrenTracker = new ChannelzChildrenTracker(); constructor(options?: ChannelOptions) { this.options = options ?? {}; @@ -168,7 +169,8 @@ export class Server { return { trace: this.channelzTrace, callTracker: this.callTracker, - children: this.childrenTracker.getChildLists() + listenerChildren: this.listenerChildrenTracker.getChildLists(), + sessionChildren: this.sessionChildrenTracker.getChildLists() }; } @@ -568,7 +570,7 @@ export class Server { for (const {server: http2Server, channelzRef: ref} of this.http2ServerList) { if (http2Server.listening) { http2Server.close(() => { - this.childrenTracker.unrefChild(ref); + this.listenerChildrenTracker.unrefChild(ref); unregisterChannelzRef(ref); }); } @@ -652,7 +654,7 @@ export class Server { if (http2Server.listening) { pendingChecks++; http2Server.close(() => { - this.childrenTracker.unrefChild(ref); + this.listenerChildrenTracker.unrefChild(ref); unregisterChannelzRef(ref); maybeCallback(); }); @@ -826,10 +828,10 @@ export class Server { this.sessions.set(session, channelzSessionInfo); const clientAddress = session.socket.remoteAddress; this.channelzTrace.addTrace('CT_INFO', 'Connection established by client ' + clientAddress); - this.childrenTracker.refChild(channelzRef); + this.sessionChildrenTracker.refChild(channelzRef); session.on('close', () => { this.channelzTrace.addTrace('CT_INFO', 'Connection dropped by client ' + clientAddress); - this.childrenTracker.unrefChild(channelzRef); + this.sessionChildrenTracker.unrefChild(channelzRef); unregisterChannelzRef(channelzRef); this.sessions.delete(session); }); diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 1caf94ba1..e7e7a9f08 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -266,7 +266,8 @@ export class Subchannel { state: this.connectivityState, trace: this.channelzTrace, callTracker: this.callTracker, - children: this.childrenTracker.getChildLists() + children: this.childrenTracker.getChildLists(), + target: this.subchannelAddressString }; } @@ -285,7 +286,7 @@ export class Subchannel { const peerCertificate = tlsSocket.getPeerCertificate(); tlsInfo = { cipherSuiteStandardName: cipherInfo.standardName ?? null, - cipherSuiteOtherName: cipherInfo.standardName ? cipherInfo.name: null, + cipherSuiteOtherName: cipherInfo.standardName ? null : cipherInfo.name, localCertificate: (certificate && 'raw' in certificate) ? certificate.raw : null, remoteCertificate: (peerCertificate && 'raw' in peerCertificate) ? peerCertificate.raw : null }; From 737dae88db117e090b9b5020c1de9c1717f7f7b4 Mon Sep 17 00:00:00 2001 From: bbesset Date: Wed, 15 Sep 2021 09:03:49 +0200 Subject: [PATCH 074/450] adds sometimes required Host header to proxy connection --- packages/grpc-js/src/http_proxy.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/grpc-js/src/http_proxy.ts b/packages/grpc-js/src/http_proxy.ts index 14e88f068..248949a80 100644 --- a/packages/grpc-js/src/http_proxy.ts +++ b/packages/grpc-js/src/http_proxy.ts @@ -190,6 +190,9 @@ export function getProxiedConnection( method: 'CONNECT', path: parsedTarget.path, }; + const headers: http.OutgoingHttpHeaders = { + Host: parsedTarget.path, + }; // Connect to the subchannel address as a proxy if (isTcpSubchannelAddress(address)) { options.host = address.host; @@ -198,14 +201,13 @@ export function getProxiedConnection( options.socketPath = address.path; } if ('grpc.http_connect_creds' in channelOptions) { - options.headers = { - 'Proxy-Authorization': - 'Basic ' + - Buffer.from( - channelOptions['grpc.http_connect_creds'] as string - ).toString('base64'), - }; + headers['Proxy-Authorization'] = + 'Basic ' + + Buffer.from( + channelOptions['grpc.http_connect_creds'] as string + ).toString('base64'); } + options.headers = headers const proxyAddressString = subchannelAddressToString(address); trace('Using proxy ' + proxyAddressString + ' to connect to ' + options.path); return new Promise((resolve, reject) => { From acd991368746dba1cd616bc190caea6af3b679d3 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 13 Sep 2021 10:58:24 -0700 Subject: [PATCH 075/450] Add admin interface --- packages/grpc-js/src/admin.ts | 39 ++++++++++++++++++++++++++++ packages/grpc-js/src/channelz.ts | 5 ++++ packages/grpc-js/src/experimental.ts | 1 + packages/grpc-js/src/index.ts | 9 +++++++ 4 files changed, 54 insertions(+) create mode 100644 packages/grpc-js/src/admin.ts diff --git a/packages/grpc-js/src/admin.ts b/packages/grpc-js/src/admin.ts new file mode 100644 index 000000000..7745d07d8 --- /dev/null +++ b/packages/grpc-js/src/admin.ts @@ -0,0 +1,39 @@ +/* + * Copyright 2021 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 { ServiceDefinition } from "./make-client"; +import { Server, UntypedServiceImplementation } from "./server"; + +interface GetServiceDefinition { + (): ServiceDefinition; +} + +interface GetHandlers { + (): UntypedServiceImplementation; +} + +const registeredAdminServices: {getServiceDefinition: GetServiceDefinition, getHandlers: GetHandlers}[] = []; + +export function registerAdminService(getServiceDefinition: GetServiceDefinition, getHandlers: GetHandlers) { + registeredAdminServices.push({getServiceDefinition, getHandlers}); +} + +export function addAdminServicesToServer(server: Server): void { + for (const {getServiceDefinition, getHandlers} of registeredAdminServices) { + server.addService(getServiceDefinition(), getHandlers()); + } +} \ No newline at end of file diff --git a/packages/grpc-js/src/channelz.ts b/packages/grpc-js/src/channelz.ts index 7965ad3c2..1e2cbf708 100644 --- a/packages/grpc-js/src/channelz.ts +++ b/packages/grpc-js/src/channelz.ts @@ -50,6 +50,7 @@ import { GetServerSocketsResponse } from "./generated/grpc/channelz/v1/GetServer import { ChannelzDefinition, ChannelzHandlers } from "./generated/grpc/channelz/v1/Channelz"; import { ProtoGrpcType as ChannelzProtoGrpcType } from "./generated/channelz"; import type { loadSync } from '@grpc/proto-loader'; +import { registerAdminService } from "./admin"; export type TraceSeverity = 'CT_UNKNOWN' | 'CT_INFO' | 'CT_WARNING' | 'CT_ERROR'; @@ -713,4 +714,8 @@ export function getChannelzServiceDefinition(): ChannelzDefinition { }) as unknown as ChannelzProtoGrpcType; loadedChannelzDefinition = loadedProto.grpc.channelz.v1.Channelz.service; return loadedChannelzDefinition; +} + +export function setup() { + registerAdminService(getChannelzServiceDefinition, getChannelzHandlers); } \ No newline at end of file diff --git a/packages/grpc-js/src/experimental.ts b/packages/grpc-js/src/experimental.ts index 24b795f06..4d158a53f 100644 --- a/packages/grpc-js/src/experimental.ts +++ b/packages/grpc-js/src/experimental.ts @@ -32,3 +32,4 @@ export { export { Call as CallStream } from './call-stream'; export { Filter, BaseFilter, FilterFactory } from './filter'; export { FilterStackFactory } from './filter-stack'; +export { registerAdminService } from './admin'; diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index 0730a26eb..29941d27e 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -249,6 +249,13 @@ export { GrpcObject } from './make-client'; export { ChannelOptions } from './channel-options'; +export { + getChannelzServiceDefinition, + getChannelzHandlers +} from './channelz'; + +export { addAdminServicesToServer } from './admin'; + import * as experimental from './experimental'; export { experimental }; @@ -257,6 +264,7 @@ import * as resolver_uds from './resolver-uds'; import * as resolver_ip from './resolver-ip'; import * as load_balancer_pick_first from './load-balancer-pick-first'; import * as load_balancer_round_robin from './load-balancer-round-robin'; +import * as channelz from './channelz'; (() => { resolver_dns.setup(); @@ -264,4 +272,5 @@ import * as load_balancer_round_robin from './load-balancer-round-robin'; resolver_ip.setup(); load_balancer_pick_first.setup(); load_balancer_round_robin.setup(); + channelz.setup(); })(); From 305623e2eba833af1432685872f03cad8041cb97 Mon Sep 17 00:00:00 2001 From: bbesset Date: Wed, 15 Sep 2021 09:03:49 +0200 Subject: [PATCH 076/450] adds sometimes required Host header to proxy connection --- packages/grpc-js/src/http_proxy.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/grpc-js/src/http_proxy.ts b/packages/grpc-js/src/http_proxy.ts index 14e88f068..248949a80 100644 --- a/packages/grpc-js/src/http_proxy.ts +++ b/packages/grpc-js/src/http_proxy.ts @@ -190,6 +190,9 @@ export function getProxiedConnection( method: 'CONNECT', path: parsedTarget.path, }; + const headers: http.OutgoingHttpHeaders = { + Host: parsedTarget.path, + }; // Connect to the subchannel address as a proxy if (isTcpSubchannelAddress(address)) { options.host = address.host; @@ -198,14 +201,13 @@ export function getProxiedConnection( options.socketPath = address.path; } if ('grpc.http_connect_creds' in channelOptions) { - options.headers = { - 'Proxy-Authorization': - 'Basic ' + - Buffer.from( - channelOptions['grpc.http_connect_creds'] as string - ).toString('base64'), - }; + headers['Proxy-Authorization'] = + 'Basic ' + + Buffer.from( + channelOptions['grpc.http_connect_creds'] as string + ).toString('base64'); } + options.headers = headers const proxyAddressString = subchannelAddressToString(address); trace('Using proxy ' + proxyAddressString + ' to connect to ' + options.path); return new Promise((resolve, reject) => { From 1ae04af7ba97b59c23da69345d3eb3a1b6c7a4af Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 16 Sep 2021 14:48:06 -0700 Subject: [PATCH 077/450] grpc-js-xds: fix use of splice in interop test code --- packages/grpc-js-xds/interop/xds-interop-client.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js-xds/interop/xds-interop-client.ts b/packages/grpc-js-xds/interop/xds-interop-client.ts index a414ffe7f..6cd3aeb33 100644 --- a/packages/grpc-js-xds/interop/xds-interop-client.ts +++ b/packages/grpc-js-xds/interop/xds-interop-client.ts @@ -130,6 +130,13 @@ class CallStatsTracker { private subscribers: CallSubscriber[] = []; + private removeSubscriber(subscriber: CallSubscriber) { + const index = this.subscribers.indexOf(subscriber); + if (index >= 0) { + this.subscribers.splice(index, 1); + } + } + getCallStats(callCount: number, timeoutSec: number): Promise { return new Promise((resolve, reject) => { let finished = false; @@ -142,7 +149,7 @@ class CallStatsTracker { setTimeout(() => { if (!finished) { finished = true; - this.subscribers.splice(this.subscribers.indexOf(subscriber), 1); + this.removeSubscriber(subscriber); resolve(subscriber.getFinalStats()); } }, timeoutSec * 1000) @@ -155,7 +162,7 @@ class CallStatsTracker { for (const subscriber of callSubscribers) { subscriber.addCallStarted(); if (!subscriber.needsMoreCalls()) { - this.subscribers.splice(this.subscribers.indexOf(subscriber), 1); + this.removeSubscriber(subscriber); } } return { From 7b656758397d4b5a02098980a16abf67061d3994 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 20 Sep 2021 11:20:41 -0700 Subject: [PATCH 078/450] grpc-js-xds: Log loaded bootstrap info in xDS client --- packages/grpc-js-xds/src/xds-client.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index 952ae81f4..de4fba23e 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -340,6 +340,7 @@ export class XdsClient { if (this.hasShutdown) { return; } + trace('Loaded bootstrap info: ' + JSON.stringify(bootstrapInfo, undefined, 2)); if (bootstrapInfo.xdsServers[0].serverFeatures.indexOf('xds_v3') >= 0) { this.apiVersion = XdsApiVersion.V3; } else { From de5eb821d121e27a5c0d0b3a92e054f691381b42 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 20 Sep 2021 11:20:41 -0700 Subject: [PATCH 079/450] grpc-js-xds: Log loaded bootstrap info in xDS client --- packages/grpc-js-xds/src/xds-client.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index 952ae81f4..de4fba23e 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -340,6 +340,7 @@ export class XdsClient { if (this.hasShutdown) { return; } + trace('Loaded bootstrap info: ' + JSON.stringify(bootstrapInfo, undefined, 2)); if (bootstrapInfo.xdsServers[0].serverFeatures.indexOf('xds_v3') >= 0) { this.apiVersion = XdsApiVersion.V3; } else { From 4229b76812f6b85a8c8bec95e319a7d2c59066bf Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 20 Sep 2021 11:40:15 -0700 Subject: [PATCH 080/450] grpc-js-xds: Add Node message logging --- packages/grpc-js-xds/src/xds-client.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index de4fba23e..41bc27147 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -371,6 +371,13 @@ export class XdsClient { ...nodeV3, client_features: ['envoy.lrs.supports_send_all_clusters'], }; + if (this.apiVersion === XdsApiVersion.V2) { + trace('ADS Node: ' + JSON.stringify(this.adsNodeV2, undefined, 2)); + trace('LRS Node: ' + JSON.stringify(this.lrsNodeV2, undefined, 2)); + } else { + trace('ADS Node: ' + JSON.stringify(this.adsNodeV3, undefined, 2)); + trace('LRS Node: ' + JSON.stringify(this.lrsNodeV3, undefined, 2)); + } const credentialsConfigs = bootstrapInfo.xdsServers[0].channelCreds; let channelCreds: ChannelCredentials | null = null; for (const config of credentialsConfigs) { From cfcc491a61057f9d92459fa76828a5e1b125acea Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 20 Sep 2021 11:40:15 -0700 Subject: [PATCH 081/450] grpc-js-xds: Add Node message logging --- packages/grpc-js-xds/src/xds-client.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index de4fba23e..41bc27147 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -371,6 +371,13 @@ export class XdsClient { ...nodeV3, client_features: ['envoy.lrs.supports_send_all_clusters'], }; + if (this.apiVersion === XdsApiVersion.V2) { + trace('ADS Node: ' + JSON.stringify(this.adsNodeV2, undefined, 2)); + trace('LRS Node: ' + JSON.stringify(this.lrsNodeV2, undefined, 2)); + } else { + trace('ADS Node: ' + JSON.stringify(this.adsNodeV3, undefined, 2)); + trace('LRS Node: ' + JSON.stringify(this.lrsNodeV3, undefined, 2)); + } const credentialsConfigs = bootstrapInfo.xdsServers[0].channelCreds; let channelCreds: ChannelCredentials | null = null; for (const config of credentialsConfigs) { From d60c4ea16f599d205fad63e379edb210da1faaad Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 27 Sep 2021 10:12:11 -0700 Subject: [PATCH 082/450] Add channelz tests and fix some bugs --- packages/grpc-js/src/call-stream.ts | 18 +- packages/grpc-js/src/channel.ts | 12 +- packages/grpc-js/src/channelz.ts | 18 +- packages/grpc-js/src/server-call.ts | 1 - packages/grpc-js/src/server.ts | 8 +- packages/grpc-js/src/subchannel.ts | 43 ++-- packages/grpc-js/test/test-channelz.ts | 289 +++++++++++++++++++++++++ test/channelz/channelz_manual_test.js | 73 +++++++ test/interop/interop_server.js | 2 +- 9 files changed, 421 insertions(+), 43 deletions(-) create mode 100644 packages/grpc-js/test/test-channelz.ts create mode 100644 test/channelz/channelz_manual_test.js diff --git a/packages/grpc-js/src/call-stream.ts b/packages/grpc-js/src/call-stream.ts index e030d9e39..f8bca8db7 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -25,7 +25,7 @@ import { FilterStackFactory, FilterStack } from './filter-stack'; import { Metadata } from './metadata'; import { StreamDecoder } from './stream-decoder'; import { ChannelImplementation } from './channel'; -import { Subchannel } from './subchannel'; +import { SubchannelCallStatsTracker, Subchannel } from './subchannel'; import * as logging from './logging'; import { LogVerbosity } from './constants'; import { ServerSurfaceCall } from './server-call'; @@ -252,6 +252,8 @@ export class Http2CallStream implements Call { private statusWatchers: ((status: StatusObject) => void)[] = []; private streamEndWatchers: ((success: boolean) => void)[] = []; + private callStatsTracker: SubchannelCallStatsTracker | null = null; + constructor( private readonly methodName: string, private readonly channel: ChannelImplementation, @@ -468,10 +470,16 @@ export class Http2CallStream implements Call { this.endCall(status); } + private writeMessageToStream(message: Buffer, callback: WriteCallback) { + this.callStatsTracker?.addMessageSent(); + this.http2Stream!.write(message, callback); + } + attachHttp2Stream( stream: http2.ClientHttp2Stream, subchannel: Subchannel, - extraFilters: FilterFactory[] + extraFilters: FilterFactory[], + callStatsTracker: SubchannelCallStatsTracker ): void { this.filterStack.push( extraFilters.map((filterFactory) => filterFactory.createFilter(this)) @@ -484,6 +492,7 @@ export class Http2CallStream implements Call { ); this.http2Stream = stream; this.subchannel = subchannel; + this.callStatsTracker = callStatsTracker; subchannel.addDisconnectListener(this.disconnectListener); subchannel.callRef(); stream.on('response', (headers, flags) => { @@ -549,6 +558,7 @@ export class Http2CallStream implements Call { for (const message of messages) { this.trace('parsed message of length ' + message.length); + this.callStatsTracker!.addMessageReceived(); this.tryPush(message); } }); @@ -666,7 +676,7 @@ export class Http2CallStream implements Call { this.pendingWrite.length + ' (deferred)' ); - stream.write(this.pendingWrite, this.pendingWriteCallback); + this.writeMessageToStream(this.pendingWrite, this.pendingWriteCallback); } this.maybeCloseWrites(); } @@ -802,7 +812,7 @@ export class Http2CallStream implements Call { this.pendingWriteCallback = cb; } else { this.trace('sending data chunk of length ' + message.message.length); - this.http2Stream.write(message.message, cb); + this.writeMessageToStream(message.message, cb); this.maybeCloseWrites(); } }, this.handleFilterError.bind(this)); diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index c5f7352e4..636ebc44b 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -103,6 +103,12 @@ export interface Channel { deadline: Date | number, callback: (error?: Error) => void ): void; + /** + * Get the channelz reference object for this channel. A request to the + * channelz service for the id in this object will provide information + * about this channel. + */ + getChannelzRef(): ChannelRef; /** * Create a call object. Call is an opaque type that is used by the Client * class. This function is called by the gRPC library when starting a @@ -243,7 +249,7 @@ export class ChannelImplementation implements Channel { Object.assign({}, this.options, subchannelArgs), this.credentials ); - this.channelzTrace.addTrace('CT_INFO', 'Created or got existing subchannel', subchannel.getChannelzRef()); + this.channelzTrace.addTrace('CT_INFO', 'Created subchannel or used existing subchannel', subchannel.getChannelzRef()); return subchannel; }, updateState: (connectivityState: ConnectivityState, picker: Picker) => { @@ -677,6 +683,10 @@ export class ChannelImplementation implements Channel { this.connectivityStateWatchers.push(watcherObject); } + getChannelzRef() { + return this.channelzRef; + } + createCall( method: string, deadline: Deadline, diff --git a/packages/grpc-js/src/channelz.ts b/packages/grpc-js/src/channelz.ts index 1e2cbf708..7efe54780 100644 --- a/packages/grpc-js/src/channelz.ts +++ b/packages/grpc-js/src/channelz.ts @@ -51,6 +51,7 @@ import { ChannelzDefinition, ChannelzHandlers } from "./generated/grpc/channelz/ import { ProtoGrpcType as ChannelzProtoGrpcType } from "./generated/channelz"; import type { loadSync } from '@grpc/proto-loader'; import { registerAdminService } from "./admin"; +import { loadPackageDefinition } from "./make-client"; export type TraceSeverity = 'CT_UNKNOWN' | 'CT_INFO' | 'CT_WARNING' | 'CT_ERROR'; @@ -455,9 +456,10 @@ function dateToProtoTimestamp(date?: Date | null): Timestamp | null { if (!date) { return null; } + const millisSinceEpoch = date.getTime(); return { - seconds: date.getSeconds(), - nanos: date.getMilliseconds() * 1_000_000 + seconds: (millisSinceEpoch / 1000) | 0, + nanos: (millisSinceEpoch % 1000) * 1_000_000 } } @@ -664,7 +666,10 @@ function GetServerSockets(call: ServerUnaryCall ref1.id - ref2.id); + // 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 resultList: SocketRefMessage[] = []; let i = 0; for (; i < allSockets.length; i++) { @@ -709,10 +714,11 @@ export function getChannelzServiceDefinition(): ChannelzDefinition { defaults: true, oneofs: true, includeDirs: [ - '../../proto' + `${__dirname}/../../proto` ] - }) as unknown as ChannelzProtoGrpcType; - loadedChannelzDefinition = loadedProto.grpc.channelz.v1.Channelz.service; + }); + const channelzGrpcObject = loadPackageDefinition(loadedProto) as unknown as ChannelzProtoGrpcType; + loadedChannelzDefinition = channelzGrpcObject.grpc.channelz.v1.Channelz.service; return loadedChannelzDefinition; } diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index cde7d9185..1bd56634f 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -570,7 +570,6 @@ export class Http2ServerCallStream< const response = this.serializeMessage(value!); this.write(response); - this.emit('sendMessage'); this.sendStatus({ code: Status.OK, details: 'OK', metadata }); } catch (err) { err.code = Status.INTERNAL; diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index ef31dadce..4a4091038 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -188,7 +188,7 @@ export class Server { const peerCertificate = tlsSocket.getPeerCertificate(); tlsInfo = { cipherSuiteStandardName: cipherInfo.standardName ?? null, - cipherSuiteOtherName: cipherInfo.standardName ? cipherInfo.name: null, + cipherSuiteOtherName: cipherInfo.standardName ? null : cipherInfo.name, localCertificate: (certificate && 'raw' in certificate) ? certificate.raw : null, remoteCertificate: (peerCertificate && 'raw' in peerCertificate) ? peerCertificate.raw : null }; @@ -424,6 +424,7 @@ export class Server { remoteFlowControlWindow: null }; }); + this.listenerChildrenTracker.refChild(channelzRef); this.http2ServerList.push({server: http2Server, channelzRef: channelzRef}); trace('Successfully bound ' + subchannelAddressToString(boundSubchannelAddress)); resolve('port' in boundSubchannelAddress ? boundSubchannelAddress.port : portNum); @@ -491,6 +492,7 @@ export class Server { remoteFlowControlWindow: null }; }); + this.listenerChildrenTracker.refChild(channelzRef); this.http2ServerList.push({server: http2Server, channelzRef: channelzRef}); trace('Successfully bound ' + subchannelAddressToString(boundSubchannelAddress)); resolve( @@ -676,6 +678,10 @@ export class Server { throw new Error('Not yet implemented'); } + getChannelzRef() { + return this.channelzRef; + } + private _setupHandlers( http2Server: http2.Http2Server | http2.Http2SecureServer ): void { diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index e7e7a9f08..c11a752ab 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -68,6 +68,11 @@ export type ConnectivityStateListener = ( newState: ConnectivityState ) => void; +export interface SubchannelCallStatsTracker { + addMessageSent(): void; + addMessageReceived(): void; +} + const { HTTP2_HEADER_AUTHORITY, HTTP2_HEADER_CONTENT_TYPE, @@ -178,33 +183,6 @@ export class Subchannel { private messagesReceived = 0; private lastMessageSentTimestamp: Date | null = null; private lastMessageReceivedTimestamp: Date | null = null; - private MessageCountFilter = class extends BaseFilter implements Filter { - private session: http2.ClientHttp2Session; - constructor(private parent: Subchannel) { - super(); - this.session = parent.session!; - } - sendMessage(message: Promise): Promise { - if (this.parent.session === this.session) { - this.parent.messagesSent += 1; - this.parent.lastMessageSentTimestamp = new Date(); - } - return message; - } - receiveMessage(message: Promise): Promise { - if (this.parent.session === this.session) { - this.parent.messagesReceived += 1; - this.parent.lastMessageReceivedTimestamp = new Date(); - } - return message; - } - }; - private MessageCountFilterFactory = class implements FilterFactory { - constructor(private parent: Subchannel) {} - createFilter(callStream: Call): Filter { - return new this.parent.MessageCountFilter(this.parent); - } - } /** * A class representing a connection to a single backend. @@ -848,8 +826,15 @@ export class Subchannel { } } }); - extraFilterFactories.push(new this.MessageCountFilterFactory(this)); - callStream.attachHttp2Stream(http2Stream, this, extraFilterFactories); + callStream.attachHttp2Stream(http2Stream, this, extraFilterFactories, { + addMessageSent: () => { + this.messagesSent += 1; + this.lastMessageSentTimestamp = new Date(); + }, + addMessageReceived: () => { + this.messagesReceived += 1; + } + }); } /** diff --git a/packages/grpc-js/test/test-channelz.ts b/packages/grpc-js/test/test-channelz.ts new file mode 100644 index 000000000..2cca780e8 --- /dev/null +++ b/packages/grpc-js/test/test-channelz.ts @@ -0,0 +1,289 @@ +/* + * Copyright 2019 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 * as assert from 'assert'; +import * as protoLoader from '@grpc/proto-loader'; +import * as grpc from '../src'; + +import { ProtoGrpcType } from '../src/generated/channelz' +import { ChannelzClient } from '../src/generated/grpc/channelz/v1/Channelz'; +import { Channel__Output } from '../src/generated/grpc/channelz/v1/Channel'; +import { Server__Output } from '../src/generated/grpc/channelz/v1/Server'; +import { ServiceClient, ServiceClientConstructor } from '../src/make-client'; +import { loadProtoFile } from './common'; + +const loadedChannelzProto = protoLoader.loadSync('channelz.proto', { + keepCase: true, + longs: String, + enums: String, + defaults: true, + oneofs: true, + includeDirs: [ + `${__dirname}/../../proto` + ] +}); +const channelzGrpcObject = grpc.loadPackageDefinition(loadedChannelzProto) as unknown as ProtoGrpcType; + +const TestServiceClient = loadProtoFile(`${__dirname}/fixtures/test_service.proto`).TestService as ServiceClientConstructor; + +const testServiceImpl: grpc.UntypedServiceImplementation = { + unary(call: grpc.ServerUnaryCall, callback: grpc.sendUnaryData) { + if (call.request.error) { + setTimeout(() => { + callback({ + code: grpc.status.INVALID_ARGUMENT, + details: call.request.message + }); + }, call.request.errorAfter) + } else { + callback(null, {count: 1}); + } + } +} + +describe('Channelz', () => { + let channelzServer: grpc.Server; + let channelzClient: ChannelzClient; + let testServer: grpc.Server; + let testClient: ServiceClient; + + before((done) => { + channelzServer = new grpc.Server(); + channelzServer.addService(grpc.getChannelzServiceDefinition(), grpc.getChannelzHandlers()); + channelzServer.bindAsync('localhost:0', grpc.ServerCredentials.createInsecure(), (error, port) => { + if (error) { + done(error); + return; + } + channelzServer.start(); + channelzClient = new channelzGrpcObject.grpc.channelz.v1.Channelz(`localhost:${port}`, grpc.credentials.createInsecure()); + done(); + }); + }); + + after(() => { + channelzClient.close(); + channelzServer.forceShutdown(); + }); + + beforeEach((done) => { + testServer = new grpc.Server(); + testServer.addService(TestServiceClient.service, testServiceImpl); + testServer.bindAsync('localhost:0', grpc.ServerCredentials.createInsecure(), (error, port) => { + if (error) { + done(error); + return; + } + testServer.start(); + testClient = new TestServiceClient(`localhost:${port}`, grpc.credentials.createInsecure()); + done(); + }); + }); + + afterEach(() => { + testClient.close(); + testServer.forceShutdown(); + }); + + it('should see a newly created channel', (done) => { + // Test that the specific test client channel info can be retrieved + channelzClient.GetChannel({channel_id: testClient.getChannel().getChannelzRef().id}, (error, result) => { + assert.ifError(error); + assert(result); + assert(result.channel); + assert(result.channel.ref); + assert.strictEqual(+result.channel.ref.channel_id, testClient.getChannel().getChannelzRef().id); + // Test that the channel is in the list of top channels + channelzClient.getTopChannels({start_channel_id: testClient.getChannel().getChannelzRef().id, max_results:1}, (error, result) => { + assert.ifError(error); + assert(result); + assert.strictEqual(result.channel.length, 1); + assert(result.channel[0].ref); + assert.strictEqual(+result.channel[0].ref.channel_id, testClient.getChannel().getChannelzRef().id); + done(); + }); + }); + }); + + it('should see a newly created server', (done) => { + // Test that the specific test server info can be retrieved + channelzClient.getServer({server_id: testServer.getChannelzRef().id}, (error, result) => { + assert.ifError(error); + assert(result); + assert(result.server); + assert(result.server.ref); + assert.strictEqual(+result.server.ref.server_id, testServer.getChannelzRef().id); + // Test that the server is in the list of servers + channelzClient.getServers({start_server_id: testServer.getChannelzRef().id, max_results: 1}, (error, result) => { + assert.ifError(error); + assert(result); + assert.strictEqual(result.server.length, 1); + assert(result.server[0].ref); + assert.strictEqual(+result.server[0].ref.server_id, testServer.getChannelzRef().id); + done(); + }); + }); + }); + + it('should count successful calls', (done) => { + testClient.unary({}, (error: grpc.ServiceError, value: unknown) => { + assert.ifError(error); + // Channel data tests + channelzClient.GetChannel({channel_id: testClient.getChannel().getChannelzRef().id}, (error, channelResult) => { + assert.ifError(error); + assert(channelResult); + assert(channelResult.channel); + assert(channelResult.channel.ref); + assert(channelResult.channel.data); + assert.strictEqual(+channelResult.channel.data.calls_started, 1); + assert.strictEqual(+channelResult.channel.data.calls_succeeded, 1); + assert.strictEqual(+channelResult.channel.data.calls_failed, 0); + assert.strictEqual(channelResult.channel.subchannel_ref.length, 1); + channelzClient.getSubchannel({subchannel_id: channelResult.channel.subchannel_ref[0].subchannel_id}, (error, subchannelResult) => { + assert.ifError(error); + assert(subchannelResult); + assert(subchannelResult.subchannel); + assert(subchannelResult.subchannel.ref); + assert(subchannelResult.subchannel.data); + assert.strictEqual(subchannelResult.subchannel.ref.subchannel_id, channelResult.channel!.subchannel_ref[0].subchannel_id); + assert.strictEqual(+subchannelResult.subchannel.data.calls_started, 1); + assert.strictEqual(+subchannelResult.subchannel.data.calls_succeeded, 1); + assert.strictEqual(+subchannelResult.subchannel.data.calls_failed, 0); + assert.strictEqual(subchannelResult.subchannel.socket_ref.length, 1); + channelzClient.getSocket({socket_id: subchannelResult.subchannel.socket_ref[0].socket_id}, (error, socketResult) => { + assert.ifError(error); + assert(socketResult); + assert(socketResult.socket); + assert(socketResult.socket.ref); + assert(socketResult.socket.data); + assert.strictEqual(socketResult.socket.ref.socket_id, subchannelResult.subchannel!.socket_ref[0].socket_id); + assert.strictEqual(+socketResult.socket.data.streams_started, 1); + assert.strictEqual(+socketResult.socket.data.streams_succeeded, 1); + assert.strictEqual(+socketResult.socket.data.streams_failed, 0); + assert.strictEqual(+socketResult.socket.data.messages_received, 1); + assert.strictEqual(+socketResult.socket.data.messages_sent, 1); + // Server data tests + channelzClient.getServer({server_id: testServer.getChannelzRef().id}, (error, serverResult) => { + assert.ifError(error); + assert(serverResult); + assert(serverResult.server); + assert(serverResult.server.ref); + assert(serverResult.server.data); + assert.strictEqual(+serverResult.server.ref.server_id, testServer.getChannelzRef().id); + assert.strictEqual(+serverResult.server.data.calls_started, 1); + assert.strictEqual(+serverResult.server.data.calls_succeeded, 1); + assert.strictEqual(+serverResult.server.data.calls_failed, 0); + channelzClient.getServerSockets({server_id: testServer.getChannelzRef().id}, (error, socketsResult) => { + assert.ifError(error); + assert(socketsResult); + assert.strictEqual(socketsResult.socket_ref.length, 1); + channelzClient.getSocket({socket_id: socketsResult.socket_ref[0].socket_id}, (error, serverSocketResult) => { + assert.ifError(error); + assert(serverSocketResult); + assert(serverSocketResult.socket); + assert(serverSocketResult.socket.ref); + assert(serverSocketResult.socket.data); + assert.strictEqual(serverSocketResult.socket.ref.socket_id, socketsResult.socket_ref[0].socket_id); + assert.strictEqual(+serverSocketResult.socket.data.streams_started, 1); + assert.strictEqual(+serverSocketResult.socket.data.streams_succeeded, 1); + assert.strictEqual(+serverSocketResult.socket.data.streams_failed, 0); + assert.strictEqual(+serverSocketResult.socket.data.messages_received, 1); + assert.strictEqual(+serverSocketResult.socket.data.messages_sent, 1); + done(); + }); + }); + }); + }); + }); + }); + }); + }); + + it('should count failed calls', (done) => { + testClient.unary({error: true}, (error: grpc.ServiceError, value: unknown) => { + assert(error); + // Channel data tests + channelzClient.GetChannel({channel_id: testClient.getChannel().getChannelzRef().id}, (error, channelResult) => { + assert.ifError(error); + assert(channelResult); + assert(channelResult.channel); + assert(channelResult.channel.ref); + assert(channelResult.channel.data); + assert.strictEqual(+channelResult.channel.data.calls_started, 1); + assert.strictEqual(+channelResult.channel.data.calls_succeeded, 0); + assert.strictEqual(+channelResult.channel.data.calls_failed, 1); + assert.strictEqual(channelResult.channel.subchannel_ref.length, 1); + channelzClient.getSubchannel({subchannel_id: channelResult.channel.subchannel_ref[0].subchannel_id}, (error, subchannelResult) => { + assert.ifError(error); + assert(subchannelResult); + assert(subchannelResult.subchannel); + assert(subchannelResult.subchannel.ref); + assert(subchannelResult.subchannel.data); + assert.strictEqual(subchannelResult.subchannel.ref.subchannel_id, channelResult.channel!.subchannel_ref[0].subchannel_id); + assert.strictEqual(+subchannelResult.subchannel.data.calls_started, 1); + assert.strictEqual(+subchannelResult.subchannel.data.calls_succeeded, 0); + assert.strictEqual(+subchannelResult.subchannel.data.calls_failed, 1); + assert.strictEqual(subchannelResult.subchannel.socket_ref.length, 1); + channelzClient.getSocket({socket_id: subchannelResult.subchannel.socket_ref[0].socket_id}, (error, socketResult) => { + assert.ifError(error); + assert(socketResult); + assert(socketResult.socket); + assert(socketResult.socket.ref); + assert(socketResult.socket.data); + assert.strictEqual(socketResult.socket.ref.socket_id, subchannelResult.subchannel!.socket_ref[0].socket_id); + assert.strictEqual(+socketResult.socket.data.streams_started, 1); + assert.strictEqual(+socketResult.socket.data.streams_succeeded, 1); + assert.strictEqual(+socketResult.socket.data.streams_failed, 0); + assert.strictEqual(+socketResult.socket.data.messages_received, 0); + assert.strictEqual(+socketResult.socket.data.messages_sent, 1); + // Server data tests + channelzClient.getServer({server_id: testServer.getChannelzRef().id}, (error, serverResult) => { + assert.ifError(error); + assert(serverResult); + assert(serverResult.server); + assert(serverResult.server.ref); + assert(serverResult.server.data); + assert.strictEqual(+serverResult.server.ref.server_id, testServer.getChannelzRef().id); + assert.strictEqual(+serverResult.server.data.calls_started, 1); + assert.strictEqual(+serverResult.server.data.calls_succeeded, 0); + assert.strictEqual(+serverResult.server.data.calls_failed, 1); + channelzClient.getServerSockets({server_id: testServer.getChannelzRef().id}, (error, socketsResult) => { + assert.ifError(error); + assert(socketsResult); + assert.strictEqual(socketsResult.socket_ref.length, 1); + channelzClient.getSocket({socket_id: socketsResult.socket_ref[0].socket_id}, (error, serverSocketResult) => { + assert.ifError(error); + assert(serverSocketResult); + assert(serverSocketResult.socket); + assert(serverSocketResult.socket.ref); + assert(serverSocketResult.socket.data); + assert.strictEqual(serverSocketResult.socket.ref.socket_id, socketsResult.socket_ref[0].socket_id); + assert.strictEqual(+serverSocketResult.socket.data.streams_started, 1); + assert.strictEqual(+serverSocketResult.socket.data.streams_succeeded, 0); + assert.strictEqual(+serverSocketResult.socket.data.streams_failed, 1); + assert.strictEqual(+serverSocketResult.socket.data.messages_received, 1); + assert.strictEqual(+serverSocketResult.socket.data.messages_sent, 0); + done(); + }); + }); + }); + }); + }); + }); + }); + }); +}); \ No newline at end of file diff --git a/test/channelz/channelz_manual_test.js b/test/channelz/channelz_manual_test.js new file mode 100644 index 000000000..2f77df3cc --- /dev/null +++ b/test/channelz/channelz_manual_test.js @@ -0,0 +1,73 @@ +/* + * + * Copyright 2021 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. + * + */ + +'use strict'; + +require('../fixtures/js_js'); +const interopClient = require('../interop/interop_client'); +const interopServer = require('../interop/interop_server'); +const serverGrpc = require('../any_grpc').server; + +const hostOverride = 'foo.test.google.fr'; + +const testCases = [ + 'empty_unary', + 'large_unary', + 'client_streaming', + 'server_streaming', + 'ping_pong', + 'empty_stream', + 'cancel_after_begin', + 'cancel_after_first_response', + 'timeout_on_sleeping_server', + 'custom_metadata', + 'status_code_and_message', + 'special_status_message', + 'unimplemented_service', + 'unimplemented_method' +]; + +function getRandomTest() { + return testCases[(Math.random() * testCases.length) | 0]; +} + +let testCompleteCount = 0; + +interopServer.getServer('0', true, (error, result) => { + if (error) { + throw error; + } + const channelzServer = new serverGrpc.Server(); + channelzServer.bindAsync('localhost:0', serverGrpc.ServerCredentials.createInsecure(), (error, port) => { + if (error) { + throw error; + } + console.log(`Serving channelz at port ${port}`); + serverGrpc.addAdminServicesToServer(channelzServer); + channelzServer.start(); + result.server.start(); + setInterval(() => { + interopClient.runTest(`localhost:${result.port}`, hostOverride, getRandomTest(), true, true, () => { + testCompleteCount += 1; + if (testCompleteCount % 100 === 0) { + console.log(`Completed ${testCompleteCount} tests`); + } + }); + }, 100); + }); +}) \ No newline at end of file diff --git a/test/interop/interop_server.js b/test/interop/interop_server.js index cf7ae354e..b67ec5a8a 100644 --- a/test/interop/interop_server.js +++ b/test/interop/interop_server.js @@ -200,7 +200,7 @@ function handleHalfDuplex(call) { * Get a server object bound to the given port * @param {string} port Port to which to bind * @param {boolean} tls Indicates that the bound port should use TLS - * @param {function(Error, {{server: Server, port: number}})} callback Callback + * @param {function(Error, {server: Server, port: number})} callback Callback * to call with result or error * @param {object?} options Optional additional options to use when * constructing the server From 4b6ea2b78113c8e8b0c1caad0e0a010d8ca6f310 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 27 Sep 2021 10:47:22 -0700 Subject: [PATCH 083/450] Add channelz ID to trace logs, add a few trace log lines --- packages/grpc-js/src/channel.ts | 56 ++++++++++++----------------- packages/grpc-js/src/server.ts | 20 ++++++----- packages/grpc-js/src/subchannel.ts | 57 ++++++++++++++---------------- 3 files changed, 59 insertions(+), 74 deletions(-) diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 636ebc44b..1b5ed3cc0 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -297,13 +297,7 @@ export class ChannelImplementation implements Channel { (status) => { this.channelzTrace.addTrace('CT_WARNING', 'Address resolution failed with code ' + status.code + ' and details "' + status.details + '"'); if (this.configSelectionQueue.length > 0) { - trace( - LogVerbosity.DEBUG, - 'channel', - 'Name resolution failed for target ' + - uriToString(this.target) + - ' with calls queued for config selection' - ); + this.trace('Name resolution failed with calls queued for config selection'); } const localQueue = this.configSelectionQueue; this.configSelectionQueue = []; @@ -324,6 +318,7 @@ export class ChannelImplementation implements Channel { new MaxMessageSizeFilterFactory(this.options), new CompressionFilterFactory(this), ]); + this.trace('Constructed channel'); } private getChannelzInfo(): ChannelInfo { @@ -336,12 +331,14 @@ export class ChannelImplementation implements Channel { }; } + private trace(text: string, verbosityOverride?: LogVerbosity) { + trace(verbosityOverride ?? LogVerbosity.DEBUG, 'channel', '(' + this.channelzRef.id + ') ' + uriToString(this.target) + ' ' + text); + } + private callRefTimerRef() { // If the hasRef function does not exist, always run the code if (!this.callRefTimer.hasRef?.()) { - trace( - LogVerbosity.DEBUG, - 'channel', + this.trace( 'callRefTimer.ref | configSelectionQueue.length=' + this.configSelectionQueue.length + ' pickQueue.length=' + @@ -354,9 +351,7 @@ export class ChannelImplementation implements Channel { private callRefTimerUnref() { // If the hasRef function does not exist, always run the code if (!this.callRefTimer.hasRef || this.callRefTimer.hasRef()) { - trace( - LogVerbosity.DEBUG, - 'channel', + this.trace( 'callRefTimer.unref | configSelectionQueue.length=' + this.configSelectionQueue.length + ' pickQueue.length=' + @@ -391,9 +386,7 @@ export class ChannelImplementation implements Channel { metadata: callMetadata, extraPickInfo: callConfig.pickInformation, }); - trace( - LogVerbosity.DEBUG, - 'channel', + this.trace( 'Pick result: ' + PickResultType[pickResult.pickResultType] + ' subchannel: ' + @@ -466,25 +459,23 @@ export class ChannelImplementation implements Channel { * the stream because the correct behavior may be * re-queueing instead, based on the logic in the rest of * tryPick */ - trace( - LogVerbosity.INFO, - 'channel', + this.trace( 'Failed to start call on picked subchannel ' + pickResult.subchannel!.getAddress() + ' with error ' + (error as Error).message + - '. Retrying pick' + '. Retrying pick', + LogVerbosity.INFO ); this.tryPick(callStream, callMetadata, callConfig); } else { - trace( - LogVerbosity.INFO, - 'channel', + this.trace( 'Failed to start call on picked subchanel ' + pickResult.subchannel!.getAddress() + ' with error ' + (error as Error).message + - '. Ending call' + '. Ending call', + LogVerbosity.INFO ); callStream.cancelWithStatus( Status.INTERNAL, @@ -497,14 +488,13 @@ export class ChannelImplementation implements Channel { } else { /* The logic for doing this here is the same as in the catch * block above */ - trace( - LogVerbosity.INFO, - 'channel', + this.trace( 'Picked subchannel ' + pickResult.subchannel!.getAddress() + ' has state ' + ConnectivityState[subchannelState] + - ' after metadata filters. Retrying pick' + ' after metadata filters. Retrying pick', + LogVerbosity.INFO ); this.tryPick(callStream, callMetadata, callConfig); } @@ -560,7 +550,8 @@ export class ChannelImplementation implements Channel { trace( LogVerbosity.DEBUG, 'connectivity_state', - uriToString(this.target) + + '(' + this.channelzRef.id + ') ' + + uriToString(this.target) + ' ' + ConnectivityState[this.connectivityState] + ' -> ' + @@ -706,11 +697,8 @@ export class ChannelImplementation implements Channel { throw new Error('Channel has been shut down'); } const callNumber = getNewCallNumber(); - trace( - LogVerbosity.DEBUG, - 'channel', - uriToString(this.target) + - ' createCall [' + + this.trace( + 'createCall [' + callNumber + '] method="' + method + diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 4a4091038..caaa2fa3d 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -64,10 +64,6 @@ import { CipherNameAndProtocol, TLSSocket } from 'tls'; const TRACER_NAME = 'server'; -function trace(text: string): void { - logging.trace(LogVerbosity.DEBUG, TRACER_NAME, text); -} - interface BindResult { port: number; count: number; @@ -163,6 +159,7 @@ export class Server { this.options = options ?? {}; this.channelzRef = registerChannelzServer(() => this.getChannelzInfo()); this.channelzTrace.addTrace('CT_INFO', 'Server created'); + this.trace('Server constructed'); } private getChannelzInfo(): ServerInfo { @@ -217,6 +214,11 @@ export class Server { }; } + private trace(text: string): void { + logging.trace(LogVerbosity.DEBUG, TRACER_NAME, '(' + this.channelzRef.id + ') ' + text); + } + + addProtoService(): void { throw new Error('Not implemented. Use addService() instead'); } @@ -372,7 +374,7 @@ export class Server { } return Promise.all( addressList.map((address) => { - trace('Attempting to bind ' + subchannelAddressToString(address)); + this.trace('Attempting to bind ' + subchannelAddressToString(address)); let addr: SubchannelAddress; if (isTcpSubchannelAddress(address)) { addr = { @@ -426,7 +428,7 @@ export class Server { }); this.listenerChildrenTracker.refChild(channelzRef); this.http2ServerList.push({server: http2Server, channelzRef: channelzRef}); - trace('Successfully bound ' + subchannelAddressToString(boundSubchannelAddress)); + this.trace('Successfully bound ' + subchannelAddressToString(boundSubchannelAddress)); resolve('port' in boundSubchannelAddress ? boundSubchannelAddress.port : portNum); http2Server.removeListener('error', onError); }); @@ -494,7 +496,7 @@ export class Server { }); this.listenerChildrenTracker.refChild(channelzRef); this.http2ServerList.push({server: http2Server, channelzRef: channelzRef}); - trace('Successfully bound ' + subchannelAddressToString(boundSubchannelAddress)); + this.trace('Successfully bound ' + subchannelAddressToString(boundSubchannelAddress)); resolve( bindSpecificPort( addressList.slice(1), @@ -727,7 +729,7 @@ export class Server { serverAddress.address + ':' + serverAddress.port; } } - trace( + this.trace( 'Received call to method ' + path + ' at address ' + @@ -736,7 +738,7 @@ export class Server { const handler = this.handlers.get(path); if (handler === undefined) { - trace( + this.trace( 'No handler registered for method ' + path + '. Sending UNIMPLEMENTED status.' diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index c11a752ab..25f06b144 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -42,14 +42,6 @@ const clientVersion = require('../../package.json').version; const TRACER_NAME = 'subchannel'; -function trace(text: string): void { - logging.trace(LogVerbosity.DEBUG, TRACER_NAME, text); -} - -function refTrace(text: string): void { - logging.trace(LogVerbosity.DEBUG, 'subchannel_refcount', text); -} - const MIN_CONNECT_TIMEOUT_MS = 20000; const INITIAL_BACKOFF_MS = 1000; const BACKOFF_MULTIPLIER = 1.6; @@ -237,6 +229,7 @@ export class Subchannel { this.channelzRef = registerChannelzSubchannel(this.subchannelAddressString, () => this.getChannelzInfo()); this.channelzTrace = new ChannelzTrace(); this.channelzTrace.addTrace('CT_INFO', 'Subchannel created'); + this.trace('Subchannel constructed'); } private getChannelzInfo(): SubchannelInfo { @@ -307,6 +300,14 @@ export class Subchannel { this.lastMessageReceivedTimestamp = null; } + private trace(text: string): void { + logging.trace(LogVerbosity.DEBUG, TRACER_NAME, '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' ' + text); + } + + private refTrace(text: string): void { + logging.trace(LogVerbosity.DEBUG, 'subchannel_refcount', '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' ' + text); + } + private handleBackoffTimer() { if (this.continueConnecting) { this.transitionToState( @@ -338,7 +339,8 @@ export class Subchannel { logging.trace( LogVerbosity.DEBUG, 'keepalive', - 'Sending ping to ' + this.subchannelAddressString + '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' ' + + 'Sending ping' ); this.keepaliveTimeoutId = setTimeout(() => { this.transitionToState([ConnectivityState.READY], ConnectivityState.IDLE); @@ -511,9 +513,8 @@ export class Subchannel { } ms` ); } - trace( - this.subchannelAddressString + - ' connection closed by GOAWAY with code ' + + this.trace( + 'connection closed by GOAWAY with code ' + errorCode ); this.transitionToState( @@ -526,9 +527,8 @@ export class Subchannel { session.once('error', (error) => { /* Do nothing here. Any error should also trigger a close event, which is * where we want to handle that. */ - trace( - this.subchannelAddressString + - ' connection closed with error ' + + this.trace( + 'connection closed with error ' + (error as Error).message ); }); @@ -607,10 +607,8 @@ export class Subchannel { if (oldStates.indexOf(this.connectivityState) === -1) { return false; } - trace( - this.subchannelAddressString + - ' ' + - ConnectivityState[this.connectivityState] + + this.trace( + ConnectivityState[this.connectivityState] + ' -> ' + ConnectivityState[newState] ); @@ -687,9 +685,8 @@ export class Subchannel { } callRef() { - refTrace( - this.subchannelAddressString + - ' callRefcount ' + + this.refTrace( + 'callRefcount ' + this.callRefcount + ' -> ' + (this.callRefcount + 1) @@ -707,9 +704,8 @@ export class Subchannel { } callUnref() { - refTrace( - this.subchannelAddressString + - ' callRefcount ' + + this.refTrace( + 'callRefcount ' + this.callRefcount + ' -> ' + (this.callRefcount - 1) @@ -728,9 +724,8 @@ export class Subchannel { } ref() { - refTrace( - this.subchannelAddressString + - ' refcount ' + + this.refTrace( + 'refcount ' + this.refcount + ' -> ' + (this.refcount + 1) @@ -739,9 +734,8 @@ export class Subchannel { } unref() { - refTrace( - this.subchannelAddressString + - ' refcount ' + + this.refTrace( + 'refcount ' + this.refcount + ' -> ' + (this.refcount - 1) @@ -803,6 +797,7 @@ export class Subchannel { LogVerbosity.DEBUG, 'call_stream', 'Starting stream on subchannel ' + + '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' with headers\n' + headersString From 8cc5f6cd24490583d204877d1d5cd9772a197f58 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 27 Sep 2021 12:35:21 -0700 Subject: [PATCH 084/450] grpc-js: Loosen requirements on channel option types --- packages/grpc-js/src/channel.ts | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 6dfca312d..ebdac7bce 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -177,18 +177,8 @@ export class ChannelImplementation implements Channel { ); } if (options) { - if ( - typeof options !== 'object' || - !Object.values(options).every( - (value) => - typeof value === 'string' || - typeof value === 'number' || - typeof value === 'undefined' - ) - ) { - throw new TypeError( - 'Channel options must be an object with string or number values' - ); + if (typeof options !== 'object') { + throw new TypeError('Channel options must be an object'); } } const originalTargetUri = parseUri(target); From 157882da451b8be623cc50a139c75b4031c9dab4 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 27 Sep 2021 15:45:22 -0700 Subject: [PATCH 085/450] grpc-js-xds: A few fixes for xDS tests --- packages/grpc-js-xds/scripts/xds.sh | 2 +- packages/grpc-js-xds/src/xds-bootstrap.ts | 2 +- packages/grpc-js-xds/src/xds-client.ts | 13 +++++++++++-- packages/grpc-js/src/server.ts | 2 ++ 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js-xds/scripts/xds.sh b/packages/grpc-js-xds/scripts/xds.sh index 131cbd551..a06cde84b 100755 --- a/packages/grpc-js-xds/scripts/xds.sh +++ b/packages/grpc-js-xds/scripts/xds.sh @@ -59,7 +59,7 @@ GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weigh --gcp_suffix=$(date '+%s') \ --verbose \ ${XDS_V3_OPT-} \ - --client_cmd="$(which node) grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client \ + --client_cmd="$(which node) --enable-source-maps grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client \ --server=xds:///{server_uri} \ --stats_port={stats_port} \ --qps={qps} \ diff --git a/packages/grpc-js-xds/src/xds-bootstrap.ts b/packages/grpc-js-xds/src/xds-bootstrap.ts index 64a7bcb94..876b6d958 100644 --- a/packages/grpc-js-xds/src/xds-bootstrap.ts +++ b/packages/grpc-js-xds/src/xds-bootstrap.ts @@ -109,7 +109,7 @@ function validateXdsServerConfig(obj: any): XdsServerConfig { return { serverUri: obj.server_uri, channelCreds: obj.channel_creds.map(validateChannelCredsConfig), - serverFeatures: obj.server_features + serverFeatures: obj.server_features ?? [] }; } diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index 41bc27147..cfb8b66ac 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -341,6 +341,16 @@ export class XdsClient { return; } trace('Loaded bootstrap info: ' + JSON.stringify(bootstrapInfo, undefined, 2)); + if (bootstrapInfo.xdsServers.length < 1) { + trace('Failed to initialize xDS Client. No servers provided in bootstrap info.'); + // Bubble this error up to any listeners + this.reportStreamError({ + code: status.INTERNAL, + details: 'Failed to initialize xDS Client. No servers provided in bootstrap info.', + metadata: new Metadata(), + }); + return; + } if (bootstrapInfo.xdsServers[0].serverFeatures.indexOf('xds_v3') >= 0) { this.apiVersion = XdsApiVersion.V3; } else { @@ -425,8 +435,7 @@ export class XdsClient { {channelOverride: channel} ); this.maybeStartLrsStream(); - }, - (error) => { + }).catch((error) => { trace('Failed to initialize xDS Client. ' + error.message); // Bubble this error up to any listeners this.reportStreamError({ diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 42b79a3cf..ed4b397d0 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -309,6 +309,7 @@ export class Server { const http2Server = setupServer(); return new Promise((resolve, reject) => { function onError(err: Error): void { + trace('Failed to bind ' + subchannelAddressToString(address) + ' with error ' + err.message); resolve(err); } @@ -356,6 +357,7 @@ export class Server { const http2Server = setupServer(); return new Promise((resolve, reject) => { function onError(err: Error): void { + trace('Failed to bind ' + subchannelAddressToString(address) + ' with error ' + err.message); resolve(bindWildcardPort(addressList.slice(1))); } From 2756a594958f679e6179a6c74ee61e3541e871ea Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 27 Sep 2021 16:12:23 -0700 Subject: [PATCH 086/450] Add a helper for creating ChannelControlHelper children --- packages/grpc-js-xds/src/load-balancer-eds.ts | 11 ++--------- packages/grpc-js-xds/src/load-balancer-lrs.ts | 10 ++-------- .../grpc-js-xds/src/load-balancer-priority.ts | 16 ++-------------- .../src/load-balancer-weighted-target.ts | 12 +++--------- .../src/load-balancer-xds-cluster-manager.ts | 12 +++--------- packages/grpc-js/src/experimental.ts | 1 + packages/grpc-js/src/load-balancer.ts | 18 ++++++++++++++++++ packages/grpc-tools/deps/protobuf | 2 +- 8 files changed, 32 insertions(+), 50 deletions(-) diff --git a/packages/grpc-js-xds/src/load-balancer-eds.ts b/packages/grpc-js-xds/src/load-balancer-eds.ts index efb05eb78..55ad714a9 100644 --- a/packages/grpc-js-xds/src/load-balancer-eds.ts +++ b/packages/grpc-js-xds/src/load-balancer-eds.ts @@ -185,14 +185,7 @@ export class EdsLoadBalancer implements LoadBalancer { private concurrentRequests: number = 0; constructor(private readonly channelControlHelper: ChannelControlHelper) { - this.childBalancer = new ChildLoadBalancerHandler({ - createSubchannel: (subchannelAddress, subchannelArgs) => - this.channelControlHelper.createSubchannel( - subchannelAddress, - subchannelArgs - ), - requestReresolution: () => - this.channelControlHelper.requestReresolution(), + this.childBalancer = new ChildLoadBalancerHandler(experimental.createChildChannelControlHelper(this.channelControlHelper, { updateState: (connectivityState, originalPicker) => { if (this.latestEdsUpdate === null) { return; @@ -243,7 +236,7 @@ export class EdsLoadBalancer implements LoadBalancer { }; this.channelControlHelper.updateState(connectivityState, edsPicker); }, - }); + })); this.watcher = { onValidUpdate: (update) => { trace('Received EDS update for ' + this.edsServiceName + ': ' + JSON.stringify(update, undefined, 2)); diff --git a/packages/grpc-js-xds/src/load-balancer-lrs.ts b/packages/grpc-js-xds/src/load-balancer-lrs.ts index 566aa04c5..145501fe9 100644 --- a/packages/grpc-js-xds/src/load-balancer-lrs.ts +++ b/packages/grpc-js-xds/src/load-balancer-lrs.ts @@ -174,20 +174,14 @@ export class LrsLoadBalancer implements LoadBalancer { private localityStatsReporter: XdsClusterLocalityStats | null = null; constructor(private channelControlHelper: ChannelControlHelper) { - this.childBalancer = new ChildLoadBalancerHandler({ - createSubchannel: (subchannelAddress, subchannelArgs) => - channelControlHelper.createSubchannel( - subchannelAddress, - subchannelArgs - ), - requestReresolution: () => channelControlHelper.requestReresolution(), + this.childBalancer = new ChildLoadBalancerHandler(experimental.createChildChannelControlHelper(channelControlHelper, { updateState: (connectivityState: ConnectivityState, picker: Picker) => { if (this.localityStatsReporter !== null) { picker = new LoadReportingPicker(picker, this.localityStatsReporter); } channelControlHelper.updateState(connectivityState, picker); }, - }); + })); } updateAddressList( diff --git a/packages/grpc-js-xds/src/load-balancer-priority.ts b/packages/grpc-js-xds/src/load-balancer-priority.ts index 872ed7d1b..b05e459a7 100644 --- a/packages/grpc-js-xds/src/load-balancer-priority.ts +++ b/packages/grpc-js-xds/src/load-balancer-priority.ts @@ -139,23 +139,11 @@ export class PriorityLoadBalancer implements LoadBalancer { private failoverTimer: NodeJS.Timer | null = null; private deactivationTimer: NodeJS.Timer | null = null; constructor(private parent: PriorityLoadBalancer, private name: string) { - this.childBalancer = new ChildLoadBalancerHandler({ - createSubchannel: ( - subchannelAddress: SubchannelAddress, - subchannelArgs: ChannelOptions - ) => { - return this.parent.channelControlHelper.createSubchannel( - subchannelAddress, - subchannelArgs - ); - }, + this.childBalancer = new ChildLoadBalancerHandler(experimental.createChildChannelControlHelper(this.parent.channelControlHelper, { updateState: (connectivityState: ConnectivityState, picker: Picker) => { this.updateState(connectivityState, picker); }, - requestReresolution: () => { - this.parent.channelControlHelper.requestReresolution(); - }, - }); + })); this.picker = new QueuePicker(this.childBalancer); } diff --git a/packages/grpc-js-xds/src/load-balancer-weighted-target.ts b/packages/grpc-js-xds/src/load-balancer-weighted-target.ts index 44a6acf11..a7a28c663 100644 --- a/packages/grpc-js-xds/src/load-balancer-weighted-target.ts +++ b/packages/grpc-js-xds/src/load-balancer-weighted-target.ts @@ -168,17 +168,11 @@ export class WeightedTargetLoadBalancer implements LoadBalancer { private weight: number = 0; constructor(private parent: WeightedTargetLoadBalancer, private name: string) { - this.childBalancer = new ChildLoadBalancerHandler({ - createSubchannel: (subchannelAddress, subchannelOptions) => { - return this.parent.channelControlHelper.createSubchannel(subchannelAddress, subchannelOptions); - }, - updateState: (connectivityState, picker) => { + this.childBalancer = new ChildLoadBalancerHandler(experimental.createChildChannelControlHelper(this.parent.channelControlHelper, { + updateState: (connectivityState: ConnectivityState, picker: Picker) => { this.updateState(connectivityState, picker); }, - requestReresolution: () => { - this.parent.channelControlHelper.requestReresolution(); - } - }); + })); this.picker = new QueuePicker(this.childBalancer); } diff --git a/packages/grpc-js-xds/src/load-balancer-xds-cluster-manager.ts b/packages/grpc-js-xds/src/load-balancer-xds-cluster-manager.ts index 7df79e26b..6210ea84a 100644 --- a/packages/grpc-js-xds/src/load-balancer-xds-cluster-manager.ts +++ b/packages/grpc-js-xds/src/load-balancer-xds-cluster-manager.ts @@ -131,17 +131,11 @@ class XdsClusterManager implements LoadBalancer { private childBalancer: ChildLoadBalancerHandler; constructor(private parent: XdsClusterManager, private name: string) { - this.childBalancer = new ChildLoadBalancerHandler({ - createSubchannel: (subchannelAddress, subchannelOptions) => { - return this.parent.channelControlHelper.createSubchannel(subchannelAddress, subchannelOptions); - }, - updateState: (connectivityState, picker) => { + this.childBalancer = new ChildLoadBalancerHandler(experimental.createChildChannelControlHelper(this.parent.channelControlHelper, { + updateState: (connectivityState: ConnectivityState, picker: Picker) => { this.updateState(connectivityState, picker); }, - requestReresolution: () => { - this.parent.channelControlHelper.requestReresolution(); - } - }); + })); this.picker = new QueuePicker(this.childBalancer); } diff --git a/packages/grpc-js/src/experimental.ts b/packages/grpc-js/src/experimental.ts index 4d158a53f..5353f7f59 100644 --- a/packages/grpc-js/src/experimental.ts +++ b/packages/grpc-js/src/experimental.ts @@ -12,6 +12,7 @@ export { LoadBalancer, LoadBalancingConfig, ChannelControlHelper, + createChildChannelControlHelper, registerLoadBalancerType, getFirstUsableConfig, validateLoadBalancingConfig, diff --git a/packages/grpc-js/src/load-balancer.ts b/packages/grpc-js/src/load-balancer.ts index 870fdb30b..19b79764c 100644 --- a/packages/grpc-js/src/load-balancer.ts +++ b/packages/grpc-js/src/load-balancer.ts @@ -52,6 +52,24 @@ export interface ChannelControlHelper { removeChannelzChild(child: ChannelRef | SubchannelRef): void; } +/** + * Create a child ChannelControlHelper that overrides some methods of the + * parent while letting others pass through to the parent unmodified. This + * allows other code to create these children without needing to know about + * all of the methods to be passed through. + * @param parent + * @param overrides + */ +export function createChildChannelControlHelper(parent: ChannelControlHelper, overrides: Partial): ChannelControlHelper { + return { + createSubchannel: overrides.createSubchannel?.bind(overrides) ?? parent.createSubchannel.bind(parent), + updateState: overrides.updateState?.bind(overrides) ?? parent.updateState.bind(parent), + requestReresolution: overrides.requestReresolution?.bind(overrides) ?? parent.requestReresolution.bind(parent), + addChannelzChild: overrides.addChannelzChild?.bind(overrides) ?? parent.addChannelzChild.bind(parent), + removeChannelzChild: overrides.removeChannelzChild?.bind(overrides) ?? parent.removeChannelzChild.bind(parent) + }; +} + /** * Tracks one or more connected subchannels and determines which subchannel * each request should use. diff --git a/packages/grpc-tools/deps/protobuf b/packages/grpc-tools/deps/protobuf index a6e1cc7e3..6aa539bf0 160000 --- a/packages/grpc-tools/deps/protobuf +++ b/packages/grpc-tools/deps/protobuf @@ -1 +1 @@ -Subproject commit a6e1cc7e328c45a0cb9856c530c8f6cd23314163 +Subproject commit 6aa539bf0195f188ff86efe6fb8bfa2b676cdd46 From 1eea4b75bd8744757ac70ab87cae360733fe7f95 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 28 Sep 2021 13:14:14 -0700 Subject: [PATCH 087/450] In server.bindAsync, call callback in process.nextTick --- packages/grpc-js/src/server.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index ed4b397d0..87788158c 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -268,6 +268,10 @@ export class Server { }; } + const deferredCallback = (error: Error | null, port: number) => { + process.nextTick(() => callback(error, port)); + } + const setupServer = (): http2.Http2Server | http2.Http2SecureServer => { let http2Server: http2.Http2Server | http2.Http2SecureServer; if (creds._isSecure()) { @@ -386,7 +390,7 @@ export class Server { // We only want one resolution result. Discard all future results resolverListener.onSuccessfulResolution = () => {}; if (addressList.length === 0) { - callback(new Error(`No addresses resolved for port ${port}`), 0); + deferredCallback(new Error(`No addresses resolved for port ${port}`), 0); return; } let bindResultPromise: Promise; @@ -409,7 +413,7 @@ export class Server { if (bindResult.count === 0) { const errorString = `No address added out of total ${addressList.length} resolved`; logging.log(LogVerbosity.ERROR, errorString); - callback(new Error(errorString), 0); + deferredCallback(new Error(errorString), 0); } else { if (bindResult.count < addressList.length) { logging.log( @@ -417,18 +421,18 @@ export class Server { `WARNING Only ${bindResult.count} addresses added out of total ${addressList.length} resolved` ); } - callback(null, bindResult.port); + deferredCallback(null, bindResult.port); } }, (error) => { const errorString = `No address added out of total ${addressList.length} resolved`; logging.log(LogVerbosity.ERROR, errorString); - callback(new Error(errorString), 0); + deferredCallback(new Error(errorString), 0); } ); }, onError: (error) => { - callback(new Error(error.details), 0); + deferredCallback(new Error(error.details), 0); }, }; From cb6abd7e38bcc29c1731208afed28dc389edc719 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 30 Sep 2021 08:52:04 -0700 Subject: [PATCH 088/450] grpc-js-xds: Handle all ways control-plane streams can end --- packages/grpc-js-xds/src/xds-client.ts | 32 +++++++++++++++----------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index cfb8b66ac..2b8fae44c 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -516,13 +516,15 @@ export class XdsClient { } } - private handleAdsCallError(error: ServiceError) { + private handleAdsCallStatus(streamStatus: StatusObject) { trace( - 'ADS stream ended. code=' + error.code + ' details= ' + error.details + 'ADS stream ended. code=' + streamStatus.code + ' details= ' + streamStatus.details ); this.adsCallV2 = null; this.adsCallV3 = null; - this.reportStreamError(error); + if (streamStatus.code !== status.OK) { + this.reportStreamError(streamStatus); + } /* If the backoff timer is no longer running, we do not need to wait any * more to start the new call. */ if (!this.adsBackoff.isRunning()) { @@ -544,9 +546,10 @@ export class XdsClient { this.adsCallV2.on('data', (message: DiscoveryResponse__Output) => { this.handleAdsResponse(message); }); - this.adsCallV2.on('error', (error: ServiceError) => { - this.handleAdsCallError(error); + this.adsCallV2.on('status', (status: StatusObject) => { + this.handleAdsCallStatus(status); }); + this.adsCallV2.on('error', () => {}); return true; } @@ -564,9 +567,10 @@ export class XdsClient { this.adsCallV3.on('data', (message: DiscoveryResponse__Output) => { this.handleAdsResponse(message); }); - this.adsCallV3.on('error', (error: ServiceError) => { - this.handleAdsCallError(error); + this.adsCallV3.on('status', (status: StatusObject) => { + this.handleAdsCallStatus(status); }); + this.adsCallV3.on('error', () => {}); return true; } @@ -772,9 +776,9 @@ export class XdsClient { this.receivedLrsSettingsForCurrentStream = true; } - private handleLrsCallError(error: ServiceError) { + private handleLrsCallStatus(streamStatus: StatusObject) { trace( - 'LRS stream ended. code=' + error.code + ' details= ' + error.details + 'LRS stream ended. code=' + streamStatus.code + ' details= ' + streamStatus.details ); this.lrsCallV2 = null; this.lrsCallV3 = null; @@ -798,9 +802,10 @@ export class XdsClient { this.lrsCallV2.on('data', (message: LoadStatsResponse__Output) => { this.handleLrsResponse(message); }); - this.lrsCallV2.on('error', (error: ServiceError) => { - this.handleLrsCallError(error); + this.lrsCallV2.on('status', (status: StatusObject) => { + this.handleLrsCallStatus(status); }); + this.lrsCallV2.on('error', () => {}); return true; } @@ -816,9 +821,10 @@ export class XdsClient { this.lrsCallV3.on('data', (message: LoadStatsResponse__Output) => { this.handleLrsResponse(message); }); - this.lrsCallV3.on('error', (error: ServiceError) => { - this.handleLrsCallError(error); + this.lrsCallV3.on('status', (status: StatusObject) => { + this.handleLrsCallStatus(status); }); + this.lrsCallV3.on('error', () => {}); return true; } From c7d9598067918839c35d43594db6b4d72aa51596 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 5 Oct 2021 14:52:26 -0700 Subject: [PATCH 089/450] grpc-js-xds: Fix RDS and EDS missing resource handling --- packages/grpc-js-xds/src/xds-stream-state/eds-state.ts | 1 - packages/grpc-js-xds/src/xds-stream-state/lds-state.ts | 6 ++++++ packages/grpc-js-xds/src/xds-stream-state/rds-state.ts | 3 +-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts index dbf18ef81..3861f4d2a 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts @@ -163,7 +163,6 @@ export class EdsState implements XdsStreamState { } } trace('Received EDS updates for cluster names ' + Array.from(allClusterNames)); - this.handleMissingNames(allClusterNames); return null; } diff --git a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts index 7e8ec0456..10e71babf 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts @@ -163,8 +163,13 @@ export class LdsState implements XdsStreamState { this.latestResponses = responses; this.latestIsV2 = isV2; const allTargetNames = new Set(); + const allRouteConfigNames = new Set(); for (const message of responses) { allTargetNames.add(message.name); + const httpConnectionManager = decodeSingleResource(HTTP_CONNECTION_MANGER_TYPE_URL_V3, message.api_listener!.api_listener!.value); + if (httpConnectionManager.rds) { + allRouteConfigNames.add(httpConnectionManager.rds.route_config_name); + } const watchers = this.watchers.get(message.name) ?? []; for (const watcher of watchers) { watcher.onValidUpdate(message, isV2); @@ -172,6 +177,7 @@ export class LdsState implements XdsStreamState { } trace('Received RDS response with route config names ' + Array.from(allTargetNames)); this.handleMissingNames(allTargetNames); + this.rdsState.handleMissingNames(allRouteConfigNames); return null; } diff --git a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts index 9194529d8..ec7abe55a 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts @@ -172,7 +172,7 @@ export class RdsState implements XdsStreamState { return true; } - private handleMissingNames(allRouteConfigNames: Set) { + handleMissingNames(allRouteConfigNames: Set) { for (const [routeConfigName, watcherList] of this.watchers.entries()) { if (!allRouteConfigNames.has(routeConfigName)) { for (const watcher of watcherList) { @@ -200,7 +200,6 @@ export class RdsState implements XdsStreamState { } } trace('Received RDS response with route config names ' + Array.from(allRouteConfigNames)); - this.handleMissingNames(allRouteConfigNames); return null; } From 16303d9f0bb48e897af3ef79cbca1b50a05f4268 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 6 Oct 2021 14:56:53 -0700 Subject: [PATCH 090/450] grpc-js: Fix server trace function inconsistency --- packages/grpc-js/src/server.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index fb62163b3..aed04adec 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -391,8 +391,8 @@ export class Server { const http2Server = setupServer(); return new Promise((resolve, reject) => { - function onError(err: Error): void { - trace('Failed to bind ' + subchannelAddressToString(address) + ' with error ' + err.message); + const onError = (err: Error) => { + this.trace('Failed to bind ' + subchannelAddressToString(address) + ' with error ' + err.message); resolve(err); } @@ -467,8 +467,8 @@ export class Server { const address = addressList[0]; const http2Server = setupServer(); return new Promise((resolve, reject) => { - function onError(err: Error): void { - trace('Failed to bind ' + subchannelAddressToString(address) + ' with error ' + err.message); + const onError = (err: Error) => { + this.trace('Failed to bind ' + subchannelAddressToString(address) + ' with error ' + err.message); resolve(bindWildcardPort(addressList.slice(1))); } From 590e94e09dd9b0dc2af04f122d7ee2cd45acae96 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 11 Oct 2021 14:23:05 -0700 Subject: [PATCH 091/450] grpc-js: Update package versions for 1.4.0 release --- packages/grpc-js-xds/package.json | 4 ++-- packages/grpc-js/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index 6506112c4..fefc0f33b 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.3.1", + "version": "1.4.0", "description": "Plugin for @grpc/grpc-js. Adds the xds:// URL scheme and associated features.", "main": "build/src/index.js", "scripts": { @@ -47,7 +47,7 @@ "re2-wasm": "^1.0.1" }, "peerDependencies": { - "@grpc/grpc-js": "~1.3.0" + "@grpc/grpc-js": "~1.4.0" }, "engines": { "node": ">=10.10.0" diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 63137c977..856b71471 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.3.7", + "version": "1.4.0", "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 7564f60dcbbc51e0ed3ec8c099bc9c5d7e353b3d Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 12 Oct 2021 12:25:47 -0700 Subject: [PATCH 092/450] grpc-js: Add tracing of channel options in channel and subchannel constructors --- packages/grpc-js/src/channel.ts | 2 +- packages/grpc-js/src/subchannel.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index d25abb05c..f998ecef4 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -311,7 +311,7 @@ export class ChannelImplementation implements Channel { new MaxMessageSizeFilterFactory(this.options), new CompressionFilterFactory(this), ]); - this.trace('Constructed channel'); + this.trace('Channel constructed with options ' + JSON.stringify(options, undefined, 2)); } private getChannelzInfo(): ChannelInfo { diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index be58fe02b..a3b86b283 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -229,7 +229,7 @@ export class Subchannel { this.channelzRef = registerChannelzSubchannel(this.subchannelAddressString, () => this.getChannelzInfo()); this.channelzTrace = new ChannelzTrace(); this.channelzTrace.addTrace('CT_INFO', 'Subchannel created'); - this.trace('Subchannel constructed'); + this.trace('Subchannel constructed with options ' + JSON.stringify(options, undefined, 2)); } private getChannelzInfo(): SubchannelInfo { From 24df9a039b866c74d39cf6afd925859969e51fd8 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 13 Oct 2021 11:10:19 -0700 Subject: [PATCH 093/450] grpc-js: Publish missing channelz proto and type files --- packages/grpc-js/package.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 856b71471..9705383ea 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.4.0", + "version": "1.4.1", "description": "gRPC Library for Node - pure JS implementation", "homepage": "https://grpc.io/", "repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js", @@ -48,11 +48,11 @@ "compile": "tsc -p .", "format": "clang-format -i -style=\"{Language: JavaScript, BasedOnStyle: Google, ColumnLimit: 80}\" src/*.ts test/*.ts", "lint": "npm run check", - "prepare": "npm run compile", + "prepare": "npm run generate-types && npm run compile", "test": "gulp test", "check": "gts check src/**/*.ts", "fix": "gts fix src/*.ts", - "pretest": "npm run compile", + "pretest": "npm run generate-types && npm run compile", "posttest": "npm run check && madge -c ./build/src", "generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs proto/ -O src/generated/ --grpcLib ../index channelz.proto" }, @@ -62,7 +62,8 @@ }, "files": [ "src/**/*.ts", - "build/src/*.{js,d.ts,js.map}", + "build/src/**/*.{js,d.ts,js.map}", + "proto/*.proto", "LICENSE", "deps/envoy-api/envoy/api/v2/**/*.proto", "deps/envoy-api/envoy/config/**/*.proto", From 624a839db9560adeba62e5dea37dec78a7a298ed Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 13 Oct 2021 11:34:32 -0700 Subject: [PATCH 094/450] Drop testing on Node 8, add 14 and 16 --- run-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run-tests.sh b/run-tests.sh index 03fd970b5..e62cbd885 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -28,7 +28,7 @@ cd $ROOT git submodule update --init --recursive if [ ! -n "$node_versions" ] ; then - node_versions="8 10 12" + node_versions="10 12 14 16" fi set +ex From 144c41b366e86fed5cb333ab72014b0ad4ef2556 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 15 Oct 2021 09:48:42 -0700 Subject: [PATCH 095/450] proto-loader: Make serializers reject arrays --- packages/proto-loader/package.json | 2 +- packages/proto-loader/src/index.ts | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index 9418df982..d31220186 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/proto-loader", - "version": "0.6.5", + "version": "0.6.6", "author": "Google Inc.", "contributors": [ { diff --git a/packages/proto-loader/src/index.ts b/packages/proto-loader/src/index.ts index 98ca97b51..24a249400 100644 --- a/packages/proto-loader/src/index.ts +++ b/packages/proto-loader/src/index.ts @@ -212,6 +212,9 @@ function createDeserializer( function createSerializer(cls: Protobuf.Type): Serialize { return function serialize(arg: object): Buffer { + if (Array.isArray(arg)) { + throw new Error(`Failed to serialize message: expected object with ${cls.name} structure, got array instead`); + } const message = cls.fromObject(arg); return cls.encode(message).finish() as Buffer; }; From 5139b107e0f4318b3ee39b2af1daf5446eb05517 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 18 Oct 2021 09:29:43 -0700 Subject: [PATCH 096/450] grpc-js: Limit the number of retained channelz trace events --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/channelz.ts | 26 ++++++++++++-------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 9705383ea..4acf948df 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.4.1", + "version": "1.4.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", diff --git a/packages/grpc-js/src/channelz.ts b/packages/grpc-js/src/channelz.ts index 7efe54780..a1c85eb47 100644 --- a/packages/grpc-js/src/channelz.ts +++ b/packages/grpc-js/src/channelz.ts @@ -113,6 +113,14 @@ interface TraceEvent { childSubchannel?: SubchannelRef; } +/** + * The loose upper bound on the number of events that should be retained in a + * trace. This may be exceeded by up to a factor of 2. Arbitrarily chosen as a + * number that should be large enough to contain the recent relevant + * information, but small enough to not use excessive memory. + */ +const TARGET_RETAINED_TRACES = 32; + export class ChannelzTrace { events: TraceEvent[] = []; creationTimestamp: Date; @@ -131,6 +139,10 @@ export class ChannelzTrace { childChannel: child?.kind === 'channel' ? child : undefined, childSubchannel: child?.kind === 'subchannel' ? child : undefined }); + // Whenever the trace array gets too large, discard the first half + if (this.events.length >= TARGET_RETAINED_TRACES * 2) { + this.events = this.events.slice(TARGET_RETAINED_TRACES); + } this.eventsLogged += 1; } @@ -380,20 +392,6 @@ export function unregisterChannelzRef(ref: ChannelRef | SubchannelRef | ServerRe } } -export interface ChannelzClientView { - updateState(connectivityState: ConnectivityState): void; - addTrace(severity: TraceSeverity, description: string, child?: ChannelRef | SubchannelRef): void; - addCallStarted(): void; - addCallSucceeded(): void; - addCallFailed(): void; - addChild(child: ChannelRef | SubchannelRef): void; - removeChild(child: ChannelRef | SubchannelRef): void; -} - -export interface ChannelzSubchannelView extends ChannelzClientView { - getRef(): SubchannelRef; -} - /** * Converts an IPv4 or IPv6 address from string representation to binary * representation From 891a918c85d717c814d98ee0ce01363970b99007 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 18 Oct 2021 13:31:08 -0700 Subject: [PATCH 097/450] grpc-js: Allow users to disable channelz --- packages/grpc-js/src/channel-options.ts | 2 + packages/grpc-js/src/channel.ts | 69 +++++++++++++----- packages/grpc-js/src/server.ts | 41 ++++++++--- packages/grpc-js/src/subchannel.ts | 94 ++++++++++++++++--------- 4 files changed, 147 insertions(+), 59 deletions(-) diff --git a/packages/grpc-js/src/channel-options.ts b/packages/grpc-js/src/channel-options.ts index 604fd8685..4e2ee6132 100644 --- a/packages/grpc-js/src/channel-options.ts +++ b/packages/grpc-js/src/channel-options.ts @@ -36,6 +36,7 @@ export interface ChannelOptions { 'grpc.enable_http_proxy'?: number; 'grpc.http_connect_target'?: string; 'grpc.http_connect_creds'?: string; + 'grpc.enable_channelz'?: number; 'grpc-node.max_session_memory'?: number; // eslint-disable-next-line @typescript-eslint/no-explicit-any [key: string]: any; @@ -61,6 +62,7 @@ export const recognizedOptions = { 'grpc.max_send_message_length': true, 'grpc.max_receive_message_length': true, 'grpc.enable_http_proxy': true, + 'grpc.enable_channelz': true, 'grpc-node.max_session_memory': true, }; diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index f998ecef4..e442e6e64 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -172,6 +172,7 @@ export class ChannelImplementation implements Channel { private configSelector: ConfigSelector | null = null; // Channelz info + private readonly channelzEnabled: boolean = true; private originalTarget: string; private channelzRef: ChannelRef; private channelzTrace: ChannelzTrace; @@ -213,9 +214,22 @@ export class ChannelImplementation implements Channel { this.callRefTimer = setInterval(() => {}, MAX_TIMEOUT_TIME); this.callRefTimer.unref?.(); - this.channelzRef = registerChannelzChannel(target, () => this.getChannelzInfo()); + if (this.options['grpc.enable_channelz'] === 0) { + this.channelzEnabled = false; + } + this.channelzTrace = new ChannelzTrace(); - this.channelzTrace.addTrace('CT_INFO', 'Channel created'); + if (this.channelzEnabled) { + this.channelzRef = registerChannelzChannel(target, () => this.getChannelzInfo()); + this.channelzTrace.addTrace('CT_INFO', 'Channel created'); + } else { + // Dummy channelz ref that will never be used + this.channelzRef = { + kind: 'channel', + id: -1, + name: '' + }; + } if (this.options['grpc.default_authority']) { this.defaultAuthority = this.options['grpc.default_authority'] as string; @@ -242,7 +256,9 @@ export class ChannelImplementation implements Channel { Object.assign({}, this.options, subchannelArgs), this.credentials ); - this.channelzTrace.addTrace('CT_INFO', 'Created subchannel or used existing subchannel', subchannel.getChannelzRef()); + if (this.channelzEnabled) { + this.channelzTrace.addTrace('CT_INFO', 'Created subchannel or used existing subchannel', subchannel.getChannelzRef()); + } return subchannel; }, updateState: (connectivityState: ConnectivityState, picker: Picker) => { @@ -262,10 +278,14 @@ export class ChannelImplementation implements Channel { ); }, addChannelzChild: (child: ChannelRef | SubchannelRef) => { - this.childrenTracker.refChild(child); + if (this.channelzEnabled) { + this.childrenTracker.refChild(child); + } }, removeChannelzChild: (child: ChannelRef | SubchannelRef) => { - this.childrenTracker.unrefChild(child); + if (this.channelzEnabled) { + this.childrenTracker.unrefChild(child); + } } }; this.resolvingLoadBalancer = new ResolvingLoadBalancer( @@ -273,7 +293,9 @@ export class ChannelImplementation implements Channel { channelControlHelper, options, (configSelector) => { - this.channelzTrace.addTrace('CT_INFO', 'Address resolution succeeded'); + if (this.channelzEnabled) { + this.channelzTrace.addTrace('CT_INFO', 'Address resolution succeeded'); + } this.configSelector = configSelector; /* We process the queue asynchronously to ensure that the corresponding * load balancer update has completed. */ @@ -288,7 +310,9 @@ export class ChannelImplementation implements Channel { }); }, (status) => { - this.channelzTrace.addTrace('CT_WARNING', 'Address resolution failed with code ' + status.code + ' and details "' + status.details + '"'); + if (this.channelzEnabled) { + this.channelzTrace.addTrace('CT_WARNING', 'Address resolution failed with code ' + status.code + ' and details "' + status.details + '"'); + } if (this.configSelectionQueue.length > 0) { this.trace('Name resolution failed with calls queued for config selection'); } @@ -553,7 +577,9 @@ export class ChannelImplementation implements Channel { ' -> ' + ConnectivityState[newState] ); - this.channelzTrace.addTrace('CT_INFO', ConnectivityState[this.connectivityState] + ' -> ' + ConnectivityState[newState]); + if (this.channelzEnabled) { + this.channelzTrace.addTrace('CT_INFO', ConnectivityState[this.connectivityState] + ' -> ' + ConnectivityState[newState]); + } this.connectivityState = newState; const watchersCopy = this.connectivityStateWatchers.slice(); for (const watcherObject of watchersCopy) { @@ -638,7 +664,9 @@ export class ChannelImplementation implements Channel { this.resolvingLoadBalancer.destroy(); this.updateState(ConnectivityState.SHUTDOWN); clearInterval(this.callRefTimer); - unregisterChannelzRef(this.channelzRef); + if (this.channelzEnabled) { + unregisterChannelzRef(this.channelzRef); + } this.subchannelPool.unrefUnusedSubchannels(); } @@ -690,6 +718,11 @@ export class ChannelImplementation implements Channel { this.connectivityStateWatchers.push(watcherObject); } + /** + * Get the channelz reference object for this channel. The returned value is + * garbage if channelz is disabled for this channel. + * @returns + */ getChannelzRef() { return this.channelzRef; } @@ -735,14 +768,16 @@ export class ChannelImplementation implements Channel { this.credentials._getCallCredentials(), callNumber ); - this.callTracker.addCallStarted(); - stream.addStatusWatcher(status => { - if (status.code === Status.OK) { - this.callTracker.addCallSucceeded(); - } else { - this.callTracker.addCallFailed(); - } - }); + if (this.channelzEnabled) { + this.callTracker.addCallStarted(); + stream.addStatusWatcher(status => { + if (status.code === Status.OK) { + this.callTracker.addCallSucceeded(); + } else { + this.callTracker.addCallFailed(); + } + }); + } return stream; } } diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index aed04adec..8bfc2a5bc 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -149,6 +149,7 @@ export class Server { private options: ChannelOptions; // Channelz Info + private readonly channelzEnabled: boolean = true; private channelzRef: ServerRef; private channelzTrace = new ChannelzTrace(); private callTracker = new ChannelzCallTracker(); @@ -157,9 +158,20 @@ export class Server { constructor(options?: ChannelOptions) { this.options = options ?? {}; - this.channelzRef = registerChannelzServer(() => this.getChannelzInfo()); - this.channelzTrace.addTrace('CT_INFO', 'Server created'); - this.trace('Server constructed'); + if (this.options['grpc.enable_channelz'] === 0) { + this.channelzEnabled = false; + } + if (this.channelzEnabled) { + this.channelzRef = registerChannelzServer(() => this.getChannelzInfo()); + this.channelzTrace.addTrace('CT_INFO', 'Server created'); + this.trace('Server constructed'); + } else { + // Dummy channelz ref that will never be used + this.channelzRef = { + kind: 'server', + id: -1 + }; + } } private getChannelzInfo(): ServerInfo { @@ -638,7 +650,9 @@ export class Server { if (this.started === true) { throw new Error('server is already started'); } - this.channelzTrace.addTrace('CT_INFO', 'Starting'); + if (this.channelzEnabled) { + this.channelzTrace.addTrace('CT_INFO', 'Starting'); + } this.started = true; } @@ -686,6 +700,11 @@ export class Server { throw new Error('Not yet implemented'); } + /** + * Get the channelz reference object for this server. The returned value is + * garbage if channelz is disabled for this server. + * @returns + */ getChannelzRef() { return this.channelzRef; } @@ -841,12 +860,16 @@ export class Server { this.sessions.set(session, channelzSessionInfo); const clientAddress = session.socket.remoteAddress; - this.channelzTrace.addTrace('CT_INFO', 'Connection established by client ' + clientAddress); - this.sessionChildrenTracker.refChild(channelzRef); + if (this.channelzEnabled) { + this.channelzTrace.addTrace('CT_INFO', 'Connection established by client ' + clientAddress); + this.sessionChildrenTracker.refChild(channelzRef); + } session.on('close', () => { - this.channelzTrace.addTrace('CT_INFO', 'Connection dropped by client ' + clientAddress); - this.sessionChildrenTracker.unrefChild(channelzRef); - unregisterChannelzRef(channelzRef); + if (this.channelzEnabled) { + this.channelzTrace.addTrace('CT_INFO', 'Connection dropped by client ' + clientAddress); + this.sessionChildrenTracker.unrefChild(channelzRef); + unregisterChannelzRef(channelzRef); + } this.sessions.delete(session); }); }); diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index a3b86b283..edc843a8a 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -157,6 +157,7 @@ export class Subchannel { private subchannelAddressString: string; // Channelz info + private readonly channelzEnabled: boolean = true; private channelzRef: SubchannelRef; private channelzTrace: ChannelzTrace; private callTracker = new ChannelzCallTracker(); @@ -226,9 +227,21 @@ export class Subchannel { }, backoffOptions); this.subchannelAddressString = subchannelAddressToString(subchannelAddress); - this.channelzRef = registerChannelzSubchannel(this.subchannelAddressString, () => this.getChannelzInfo()); + if (options['grpc.enable_channelz'] === 0) { + this.channelzEnabled = false; + } this.channelzTrace = new ChannelzTrace(); - this.channelzTrace.addTrace('CT_INFO', 'Subchannel created'); + if (this.channelzEnabled) { + this.channelzRef = registerChannelzSubchannel(this.subchannelAddressString, () => this.getChannelzInfo()); + this.channelzTrace.addTrace('CT_INFO', 'Subchannel created'); + } else { + // Dummy channelz ref that will never be used + this.channelzRef = { + kind: 'subchannel', + id: -1, + name: '' + }; + } this.trace('Subchannel constructed with options ' + JSON.stringify(options, undefined, 2)); } @@ -286,6 +299,9 @@ export class Subchannel { } private resetChannelzSocketInfo() { + if (!this.channelzEnabled) { + return; + } if (this.channelzSocketRef) { unregisterChannelzRef(this.channelzSocketRef); this.childrenTracker.unrefChild(this.channelzSocketRef); @@ -335,7 +351,9 @@ export class Subchannel { } private sendPing() { - this.keepalivesSent += 1; + if (this.channelzEnabled) { + this.keepalivesSent += 1; + } logging.trace( LogVerbosity.DEBUG, 'keepalive', @@ -462,8 +480,10 @@ export class Subchannel { connectionOptions ); this.session = session; - this.channelzSocketRef = registerChannelzSocket(this.subchannelAddressString, () => this.getChannelzSocketInfo()!); - this.childrenTracker.refChild(this.channelzSocketRef); + if (this.channelzEnabled) { + this.channelzSocketRef = registerChannelzSocket(this.subchannelAddressString, () => this.getChannelzSocketInfo()!); + this.childrenTracker.refChild(this.channelzSocketRef); + } session.unref(); /* For all of these events, check if the session at the time of the event * is the same one currently attached to this subchannel, to ensure that @@ -615,7 +635,9 @@ export class Subchannel { ' -> ' + ConnectivityState[newState] ); - this.channelzTrace.addTrace('CT_INFO', ConnectivityState[this.connectivityState] + ' -> ' + ConnectivityState[newState]); + if (this.channelzEnabled) { + this.channelzTrace.addTrace('CT_INFO', ConnectivityState[this.connectivityState] + ' -> ' + ConnectivityState[newState]); + } const previousState = this.connectivityState; this.connectivityState = newState; switch (newState) { @@ -678,12 +700,16 @@ export class Subchannel { /* If no calls, channels, or subchannel pools have any more references to * this subchannel, we can be sure it will never be used again. */ if (this.callRefcount === 0 && this.refcount === 0) { - this.channelzTrace.addTrace('CT_INFO', 'Shutting down'); + if (this.channelzEnabled) { + this.channelzTrace.addTrace('CT_INFO', 'Shutting down'); + } this.transitionToState( [ConnectivityState.CONNECTING, ConnectivityState.READY], ConnectivityState.TRANSIENT_FAILURE ); - unregisterChannelzRef(this.channelzRef); + if (this.channelzEnabled) { + unregisterChannelzRef(this.channelzRef); + } } } @@ -805,34 +831,36 @@ export class Subchannel { ' with headers\n' + headersString ); - this.callTracker.addCallStarted(); - callStream.addStatusWatcher(status => { - if (status.code === Status.OK) { - this.callTracker.addCallSucceeded(); - } else { - this.callTracker.addCallFailed(); - } - }); const streamSession = this.session; - this.streamTracker.addCallStarted(); - callStream.addStreamEndWatcher(success => { - if (streamSession === this.session) { - if (success) { - this.streamTracker.addCallSucceeded(); + if (this.channelzEnabled) { + this.callTracker.addCallStarted(); + callStream.addStatusWatcher(status => { + if (status.code === Status.OK) { + this.callTracker.addCallSucceeded(); } else { - this.streamTracker.addCallFailed(); + this.callTracker.addCallFailed(); } - } - }); - callStream.attachHttp2Stream(http2Stream, this, extraFilters, { - addMessageSent: () => { - this.messagesSent += 1; - this.lastMessageSentTimestamp = new Date(); - }, - addMessageReceived: () => { - this.messagesReceived += 1; - } - }); + }); + this.streamTracker.addCallStarted(); + callStream.addStreamEndWatcher(success => { + if (streamSession === this.session) { + if (success) { + this.streamTracker.addCallSucceeded(); + } else { + this.streamTracker.addCallFailed(); + } + } + }); + callStream.attachHttp2Stream(http2Stream, this, extraFilters, { + addMessageSent: () => { + this.messagesSent += 1; + this.lastMessageSentTimestamp = new Date(); + }, + addMessageReceived: () => { + this.messagesReceived += 1; + } + }); + } } /** From 9d92bf164fa2ce0445d5acedfcf04034db587a44 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 18 Oct 2021 16:20:39 -0700 Subject: [PATCH 098/450] grpc-js-xds: Improve received resource list logging --- packages/grpc-js-xds/src/xds-stream-state/cds-state.ts | 2 +- packages/grpc-js-xds/src/xds-stream-state/eds-state.ts | 2 +- packages/grpc-js-xds/src/xds-stream-state/lds-state.ts | 2 +- packages/grpc-js-xds/src/xds-stream-state/rds-state.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts index 7720c5673..c3c73e9fb 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts @@ -158,7 +158,7 @@ export class CdsState implements XdsStreamState { watcher.onValidUpdate(message, isV2); } } - trace('Received CDS updates for cluster names ' + Array.from(allClusterNames)); + trace('Received CDS updates for cluster names [' + Array.from(allClusterNames) + ']'); this.handleMissingNames(allClusterNames); this.edsState.handleMissingNames(allEdsServiceNames); return null; diff --git a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts index 3861f4d2a..f816ceea2 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts @@ -162,7 +162,7 @@ export class EdsState implements XdsStreamState { watcher.onValidUpdate(message, isV2); } } - trace('Received EDS updates for cluster names ' + Array.from(allClusterNames)); + trace('Received EDS updates for cluster names [' + Array.from(allClusterNames) + ']'); return null; } diff --git a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts index 10e71babf..7c9105be4 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts @@ -175,7 +175,7 @@ export class LdsState implements XdsStreamState { watcher.onValidUpdate(message, isV2); } } - trace('Received RDS response with route config names ' + Array.from(allTargetNames)); + trace('Received LDS response with listener names [' + Array.from(allTargetNames) + ']'); this.handleMissingNames(allTargetNames); this.rdsState.handleMissingNames(allRouteConfigNames); return null; diff --git a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts index ec7abe55a..04d2bce0d 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts @@ -199,7 +199,7 @@ export class RdsState implements XdsStreamState { watcher.onValidUpdate(message, isV2); } } - trace('Received RDS response with route config names ' + Array.from(allRouteConfigNames)); + trace('Received RDS response with route config names [' + Array.from(allRouteConfigNames) + ']'); return null; } From 647654c7c17cd79dd1f06085d5b8d2c4e40b7e3a Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 19 Oct 2021 08:33:25 -0700 Subject: [PATCH 099/450] grpc-js: Include other causes in ENHANCE_YOUR_CALM translation --- packages/grpc-js/src/call-stream.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/src/call-stream.ts b/packages/grpc-js/src/call-stream.ts index 70a9ac6ee..f705f6caf 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -600,7 +600,7 @@ export class Http2CallStream implements Call { break; case http2.constants.NGHTTP2_ENHANCE_YOUR_CALM: code = Status.RESOURCE_EXHAUSTED; - details = 'Bandwidth exhausted'; + details = 'Bandwidth exhausted or memory limit exceeded'; break; case http2.constants.NGHTTP2_INADEQUATE_SECURITY: code = Status.PERMISSION_DENIED; From 2a45b343d51ae8d3333914659dabdbb1d340334c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 19 Oct 2021 14:20:37 -0700 Subject: [PATCH 100/450] grpc-js-xds: Use valid resources when NACKing messages --- .../grpc-js-xds/src/xds-stream-state/cds-state.ts | 14 +++++++++----- .../grpc-js-xds/src/xds-stream-state/eds-state.ts | 14 +++++++++----- .../grpc-js-xds/src/xds-stream-state/lds-state.ts | 14 +++++++++----- .../grpc-js-xds/src/xds-stream-state/rds-state.ts | 14 +++++++++----- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts index 7720c5673..5dae09fb4 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts @@ -137,17 +137,21 @@ export class CdsState implements XdsStreamState { } handleResponses(responses: Cluster__Output[], isV2: boolean): string | null { + const validResponses: Cluster__Output[] = []; + let errorMessage: string | null = null; for (const message of responses) { - if (!this.validateResponse(message)) { + if (this.validateResponse(message)) { + validResponses.push(message); + } else { trace('CDS validation failed for message ' + JSON.stringify(message)); - return 'CDS Error: Cluster validation failed'; + errorMessage = 'CDS Error: Cluster validation failed'; } } - this.latestResponses = responses; + this.latestResponses = validResponses; this.latestIsV2 = isV2; const allEdsServiceNames: Set = new Set(); const allClusterNames: Set = new Set(); - for (const message of responses) { + for (const message of validResponses) { allClusterNames.add(message.name); const edsServiceName = message.eds_cluster_config?.service_name ?? ''; allEdsServiceNames.add( @@ -161,7 +165,7 @@ export class CdsState implements XdsStreamState { trace('Received CDS updates for cluster names ' + Array.from(allClusterNames)); this.handleMissingNames(allClusterNames); this.edsState.handleMissingNames(allEdsServiceNames); - return null; + return errorMessage; } reportStreamError(status: StatusObject): void { diff --git a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts index 3861f4d2a..7d28ed5ff 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts @@ -146,16 +146,20 @@ export class EdsState implements XdsStreamState { } handleResponses(responses: ClusterLoadAssignment__Output[], isV2: boolean) { + const validResponses: ClusterLoadAssignment__Output[] = []; + let errorMessage: string | null = null; for (const message of responses) { - if (!this.validateResponse(message)) { + if (this.validateResponse(message)) { + validResponses.push(message); + } else { trace('EDS validation failed for message ' + JSON.stringify(message)); - return 'EDS Error: ClusterLoadAssignment validation failed'; + errorMessage = 'EDS Error: ClusterLoadAssignment validation failed'; } } - this.latestResponses = responses; + this.latestResponses = validResponses; this.latestIsV2 = isV2; const allClusterNames: Set = new Set(); - for (const message of responses) { + for (const message of validResponses) { allClusterNames.add(message.cluster_name); const watchers = this.watchers.get(message.cluster_name) ?? []; for (const watcher of watchers) { @@ -163,7 +167,7 @@ export class EdsState implements XdsStreamState { } } trace('Received EDS updates for cluster names ' + Array.from(allClusterNames)); - return null; + return errorMessage; } reportStreamError(status: StatusObject): void { diff --git a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts index 10e71babf..5706e3766 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts @@ -154,17 +154,21 @@ export class LdsState implements XdsStreamState { } handleResponses(responses: Listener__Output[], isV2: boolean): string | null { + const validResponses: Listener__Output[] = []; + let errorMessage: string | null = null; for (const message of responses) { - if (!this.validateResponse(message, isV2)) { + if (this.validateResponse(message, isV2)) { + validResponses.push(message); + } else { trace('LDS validation failed for message ' + JSON.stringify(message)); - return 'LDS Error: Route validation failed'; + errorMessage = 'LDS Error: Route validation failed'; } } - this.latestResponses = responses; + this.latestResponses = validResponses; this.latestIsV2 = isV2; const allTargetNames = new Set(); const allRouteConfigNames = new Set(); - for (const message of responses) { + for (const message of validResponses) { allTargetNames.add(message.name); const httpConnectionManager = decodeSingleResource(HTTP_CONNECTION_MANGER_TYPE_URL_V3, message.api_listener!.api_listener!.value); if (httpConnectionManager.rds) { @@ -178,7 +182,7 @@ export class LdsState implements XdsStreamState { trace('Received RDS response with route config names ' + Array.from(allTargetNames)); this.handleMissingNames(allTargetNames); this.rdsState.handleMissingNames(allRouteConfigNames); - return null; + return errorMessage; } reportStreamError(status: StatusObject): void { diff --git a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts index ec7abe55a..5a3854323 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts @@ -183,16 +183,20 @@ export class RdsState implements XdsStreamState { } handleResponses(responses: RouteConfiguration__Output[], isV2: boolean): string | null { + const validResponses: RouteConfiguration__Output[] = []; + let errorMessage: string | null = null; for (const message of responses) { - if (!this.validateResponse(message, isV2)) { + if (this.validateResponse(message, isV2)) { + validResponses.push(message); + } else { trace('RDS validation failed for message ' + JSON.stringify(message)); - return 'RDS Error: Route validation failed'; + errorMessage = 'RDS Error: Route validation failed'; } } - this.latestResponses = responses; + this.latestResponses = validResponses; this.latestIsV2 = isV2; const allRouteConfigNames = new Set(); - for (const message of responses) { + for (const message of validResponses) { allRouteConfigNames.add(message.name); const watchers = this.watchers.get(message.name) ?? []; for (const watcher of watchers) { @@ -200,7 +204,7 @@ export class RdsState implements XdsStreamState { } } trace('Received RDS response with route config names ' + Array.from(allRouteConfigNames)); - return null; + return errorMessage; } reportStreamError(status: StatusObject): void { From 25e21d1fba1b7f6aa41522309cb1dc773324d5ed Mon Sep 17 00:00:00 2001 From: howyi Date: Sun, 24 Oct 2021 21:14:16 +0900 Subject: [PATCH 101/450] feat(client): export ServiceClientConstructor,ProtobufTypeDefinition type --- packages/grpc-js/src/index.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index 4b7967be9..f3d018953 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -42,7 +42,9 @@ import { loadPackageDefinition, makeClientConstructor, MethodDefinition, + ProtobufTypeDefinition, Serialize, + ServiceClientConstructor, ServiceDefinition, } from './make-client'; import { Metadata, MetadataValue } from './metadata'; @@ -245,7 +247,11 @@ export { InterceptorConfigurationError, } from './client-interceptors'; -export { GrpcObject } from './make-client'; +export { + GrpcObject, + ServiceClientConstructor, + ProtobufTypeDefinition +} from './make-client'; export { ChannelOptions } from './channel-options'; From 7aa5b6200814afc3acf5739d8a758fbaf97dca8b Mon Sep 17 00:00:00 2001 From: Robert Date: Sun, 24 Oct 2021 21:46:23 -0700 Subject: [PATCH 102/450] grpc-js: Allow per-channel request compression from the client and decompression from the server --- packages/grpc-js/package.json | 5 +- packages/grpc-js/proto/test_service.proto | 42 +++ packages/grpc-js/src/channel-options.ts | 1 + packages/grpc-js/src/channel.ts | 3 +- packages/grpc-js/src/compression-filter.ts | 52 +++- packages/grpc-js/src/generated/Request.ts | 14 + packages/grpc-js/src/generated/Response.ts | 10 + packages/grpc-js/src/generated/TestService.ts | 55 ++++ .../grpc-js/src/generated/test_service.ts | 15 + packages/grpc-js/src/server-call.ts | 84 ++++- packages/grpc-js/src/server.ts | 39 ++- packages/grpc-js/test/test-server.ts | 286 ++++++++++++++++++ 12 files changed, 570 insertions(+), 36 deletions(-) create mode 100644 packages/grpc-js/proto/test_service.proto create mode 100644 packages/grpc-js/src/generated/Request.ts create mode 100644 packages/grpc-js/src/generated/Response.ts create mode 100644 packages/grpc-js/src/generated/TestService.ts create mode 100644 packages/grpc-js/src/generated/test_service.ts diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 9705383ea..f430c09d2 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -54,11 +54,12 @@ "fix": "gts fix src/*.ts", "pretest": "npm run generate-types && npm run compile", "posttest": "npm run check && madge -c ./build/src", - "generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs proto/ -O src/generated/ --grpcLib ../index channelz.proto" + "generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs proto/ -O src/generated/ --grpcLib ../index channelz.proto test_service.proto" }, "dependencies": { "@grpc/proto-loader": "^0.6.4", - "@types/node": ">=12.12.47" + "@types/node": "16.10.0", + "@types/semver": "^7.3.9" }, "files": [ "src/**/*.ts", diff --git a/packages/grpc-js/proto/test_service.proto b/packages/grpc-js/proto/test_service.proto new file mode 100644 index 000000000..f99393d14 --- /dev/null +++ b/packages/grpc-js/proto/test_service.proto @@ -0,0 +1,42 @@ +/* + * Copyright 2019 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. + * + */ + +syntax = "proto3"; + +message Request { + bool error = 1; + string message = 2; + int32 errorAfter = 3; +} + +message Response { + int32 count = 1; +} + +service TestService { + rpc Unary (Request) returns (Response) { + } + + rpc ClientStream (stream Request) returns (Response) { + } + + rpc ServerStream (Request) returns (stream Response) { + } + + rpc BidiStream (stream Request) returns (stream Response) { + } +} diff --git a/packages/grpc-js/src/channel-options.ts b/packages/grpc-js/src/channel-options.ts index 604fd8685..f0b37d7a4 100644 --- a/packages/grpc-js/src/channel-options.ts +++ b/packages/grpc-js/src/channel-options.ts @@ -36,6 +36,7 @@ export interface ChannelOptions { 'grpc.enable_http_proxy'?: number; 'grpc.http_connect_target'?: string; 'grpc.http_connect_creds'?: string; + 'grpc.default_compression_algorithm'?: number; 'grpc-node.max_session_memory'?: number; // eslint-disable-next-line @typescript-eslint/no-explicit-any [key: string]: any; diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index f998ecef4..8a2f93a54 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -45,7 +45,6 @@ import { MaxMessageSizeFilterFactory } from './max-message-size-filter'; import { mapProxyName } from './http_proxy'; import { GrpcUri, parseUri, uriToString } from './uri-parser'; import { ServerSurfaceCall } from './server-call'; -import { SurfaceCall } from './call'; import { Filter } from './filter'; import { ConnectivityState } from './connectivity-state'; @@ -309,7 +308,7 @@ export class ChannelImplementation implements Channel { new CallCredentialsFilterFactory(this), new DeadlineFilterFactory(this), new MaxMessageSizeFilterFactory(this.options), - new CompressionFilterFactory(this), + new CompressionFilterFactory(this, this.options), ]); this.trace('Channel constructed with options ' + JSON.stringify(options, undefined, 2)); } diff --git a/packages/grpc-js/src/compression-filter.ts b/packages/grpc-js/src/compression-filter.ts index 330eb675a..4ecdbb6a3 100644 --- a/packages/grpc-js/src/compression-filter.ts +++ b/packages/grpc-js/src/compression-filter.ts @@ -17,10 +17,27 @@ import * as zlib from 'zlib'; -import { Call, WriteFlags, WriteObject } from './call-stream'; +import { Call, WriteObject } from './call-stream'; import { Channel } from './channel'; import { BaseFilter, Filter, FilterFactory } from './filter'; import { Metadata, MetadataValue } from './metadata'; +import { ChannelOptions } from './channel-options'; + +const CompressionAlgorithms = { + '0': 'identity', + '1': 'deflate', + '2': 'gzip', + // Streaming compression is unimplemented + '3': 'stream-gzip' +} as const; + +const CompressionAlgorithKeys = new Set(Object.keys(CompressionAlgorithms)); + +const isCompressionAlgorithmKey = (key: string | undefined): key is keyof typeof CompressionAlgorithms => { + return typeof key === 'string' && CompressionAlgorithKeys.has(key); +} + +type CompressionAlgorithm = (typeof CompressionAlgorithms)[keyof typeof CompressionAlgorithms]; abstract class CompressionHandler { protected abstract compressMessage(message: Buffer): Promise; @@ -167,10 +184,29 @@ function getCompressionHandler(compressionName: string): CompressionHandler { export class CompressionFilter extends BaseFilter implements Filter { private sendCompression: CompressionHandler = new IdentityHandler(); private receiveCompression: CompressionHandler = new IdentityHandler(); + private defaultCompressionAlgorithm: CompressionAlgorithm | undefined; + + constructor(channelOptions: ChannelOptions) { + super(); + + const compressionAlgorithmKey = channelOptions['grpc.default_compression_algorithm']?.toString(); + if (isCompressionAlgorithmKey(compressionAlgorithmKey)) { + this.defaultCompressionAlgorithm = CompressionAlgorithms[compressionAlgorithmKey]; + this.sendCompression = getCompressionHandler(this.defaultCompressionAlgorithm); + } + } + async sendMetadata(metadata: Promise): Promise { const headers: Metadata = await metadata; headers.set('grpc-accept-encoding', 'identity,deflate,gzip'); - headers.set('accept-encoding', 'identity'); + headers.set('accept-encoding', 'identity,deflate,gzip'); + + if (this.defaultCompressionAlgorithm && ['deflate', 'gzip'].includes(this.defaultCompressionAlgorithm)) { + headers.set('grpc-encoding', this.defaultCompressionAlgorithm); + } else { + headers.remove('grpc-encoding'); + } + return headers; } @@ -192,10 +228,10 @@ 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; - const compress = - resolvedMessage.flags === undefined - ? false - : (resolvedMessage.flags & WriteFlags.NoCompress) === 0; + const compress = !(this.sendCompression instanceof IdentityHandler); + // resolvedMessage.flags === undefined + // ? false + // : (resolvedMessage.flags & WriteFlags.NoCompress) === 0; return { message: await this.sendCompression.writeMessage( resolvedMessage.message, @@ -216,8 +252,8 @@ export class CompressionFilter extends BaseFilter implements Filter { export class CompressionFilterFactory implements FilterFactory { - constructor(private readonly channel: Channel) {} + constructor(private readonly channel: Channel, private readonly options: ChannelOptions) {} createFilter(callStream: Call): CompressionFilter { - return new CompressionFilter(); + return new CompressionFilter(this.options); } } diff --git a/packages/grpc-js/src/generated/Request.ts b/packages/grpc-js/src/generated/Request.ts new file mode 100644 index 000000000..93898a701 --- /dev/null +++ b/packages/grpc-js/src/generated/Request.ts @@ -0,0 +1,14 @@ +// Original file: proto/test_service.proto + + +export interface Request { + 'error'?: (boolean); + 'message'?: (string); + 'errorAfter'?: (number); +} + +export interface Request__Output { + 'error': (boolean); + 'message': (string); + 'errorAfter': (number); +} diff --git a/packages/grpc-js/src/generated/Response.ts b/packages/grpc-js/src/generated/Response.ts new file mode 100644 index 000000000..980bfdd18 --- /dev/null +++ b/packages/grpc-js/src/generated/Response.ts @@ -0,0 +1,10 @@ +// Original file: proto/test_service.proto + + +export interface Response { + 'count'?: (number); +} + +export interface Response__Output { + 'count': (number); +} diff --git a/packages/grpc-js/src/generated/TestService.ts b/packages/grpc-js/src/generated/TestService.ts new file mode 100644 index 000000000..dd1d22ab2 --- /dev/null +++ b/packages/grpc-js/src/generated/TestService.ts @@ -0,0 +1,55 @@ +// Original file: proto/test_service.proto + +import type * as grpc from './../index' +import type { MethodDefinition } from '@grpc/proto-loader' +import type { Request as _Request, Request__Output as _Request__Output } from './Request'; +import type { Response as _Response, Response__Output as _Response__Output } from './Response'; + +export interface TestServiceClient extends grpc.Client { + BidiStream(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_Request, _Response__Output>; + BidiStream(options?: grpc.CallOptions): grpc.ClientDuplexStream<_Request, _Response__Output>; + bidiStream(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_Request, _Response__Output>; + bidiStream(options?: grpc.CallOptions): grpc.ClientDuplexStream<_Request, _Response__Output>; + + ClientStream(metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientWritableStream<_Request>; + ClientStream(metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientWritableStream<_Request>; + ClientStream(options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientWritableStream<_Request>; + ClientStream(callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientWritableStream<_Request>; + clientStream(metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientWritableStream<_Request>; + clientStream(metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientWritableStream<_Request>; + clientStream(options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientWritableStream<_Request>; + clientStream(callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientWritableStream<_Request>; + + ServerStream(argument: _Request, metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientReadableStream<_Response__Output>; + ServerStream(argument: _Request, options?: grpc.CallOptions): grpc.ClientReadableStream<_Response__Output>; + serverStream(argument: _Request, metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientReadableStream<_Response__Output>; + serverStream(argument: _Request, options?: grpc.CallOptions): grpc.ClientReadableStream<_Response__Output>; + + Unary(argument: _Request, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientUnaryCall; + Unary(argument: _Request, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientUnaryCall; + Unary(argument: _Request, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientUnaryCall; + Unary(argument: _Request, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientUnaryCall; + unary(argument: _Request, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientUnaryCall; + unary(argument: _Request, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientUnaryCall; + unary(argument: _Request, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientUnaryCall; + unary(argument: _Request, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientUnaryCall; + +} + +export interface TestServiceHandlers extends grpc.UntypedServiceImplementation { + BidiStream: grpc.handleBidiStreamingCall<_Request__Output, _Response>; + + ClientStream: grpc.handleClientStreamingCall<_Request__Output, _Response>; + + ServerStream: grpc.handleServerStreamingCall<_Request__Output, _Response>; + + Unary: grpc.handleUnaryCall<_Request__Output, _Response>; + +} + +export interface TestServiceDefinition extends grpc.ServiceDefinition { + BidiStream: MethodDefinition<_Request, _Response, _Request__Output, _Response__Output> + ClientStream: MethodDefinition<_Request, _Response, _Request__Output, _Response__Output> + ServerStream: MethodDefinition<_Request, _Response, _Request__Output, _Response__Output> + Unary: MethodDefinition<_Request, _Response, _Request__Output, _Response__Output> +} diff --git a/packages/grpc-js/src/generated/test_service.ts b/packages/grpc-js/src/generated/test_service.ts new file mode 100644 index 000000000..2beb88680 --- /dev/null +++ b/packages/grpc-js/src/generated/test_service.ts @@ -0,0 +1,15 @@ +import type * as grpc from '../index'; +import type { MessageTypeDefinition } from '@grpc/proto-loader'; + +import type { TestServiceClient as _TestServiceClient, TestServiceDefinition as _TestServiceDefinition } from './TestService'; + +type SubtypeConstructor any, Subtype> = { + new(...args: ConstructorParameters): Subtype; +}; + +export interface ProtoGrpcType { + Request: MessageTypeDefinition + Response: MessageTypeDefinition + TestService: SubtypeConstructor & { service: _TestServiceDefinition } +} + diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index be4429b0f..8ea488a4d 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -18,6 +18,7 @@ import { EventEmitter } from 'events'; import * as http2 from 'http2'; import { Duplex, Readable, Writable } from 'stream'; +import * as zlib from 'zlib'; import { Deadline, StatusObject } from './call-stream'; import { @@ -32,6 +33,7 @@ import { StreamDecoder } from './stream-decoder'; import { ObjectReadable, ObjectWritable } from './object-stream'; import { ChannelOptions } from './channel-options'; import * as logging from './logging'; +import { MetadataValue } from '.'; const TRACER_NAME = 'server_call'; @@ -60,7 +62,7 @@ const deadlineUnitsToMs: DeadlineUnitIndexSignature = { const defaultResponseHeaders = { // TODO(cjihrig): Remove these encoding headers from the default response // once compression is integrated. - [GRPC_ACCEPT_ENCODING_HEADER]: 'identity', + [GRPC_ACCEPT_ENCODING_HEADER]: 'identity,deflate,gzip', [GRPC_ENCODING_HEADER]: 'identity', [http2.constants.HTTP2_HEADER_STATUS]: http2.constants.HTTP_STATUS_OK, [http2.constants.HTTP2_HEADER_CONTENT_TYPE]: 'application/grpc+proto', @@ -136,12 +138,13 @@ export class ServerReadableStreamImpl constructor( private call: Http2ServerCallStream, public metadata: Metadata, - public deserialize: Deserialize + public deserialize: Deserialize, + encoding?: MetadataValue ) { super({ objectMode: true }); this.cancelled = false; this.call.setupSurfaceCall(this); - this.call.setupReadable(this); + this.call.setupReadable(this, encoding); } _read(size: number) { @@ -250,13 +253,14 @@ export class ServerDuplexStreamImpl private call: Http2ServerCallStream, public metadata: Metadata, public serialize: Serialize, - public deserialize: Deserialize + public deserialize: Deserialize, + encoding?: MetadataValue ) { super({ objectMode: true }); this.cancelled = false; this.trailingMetadata = new Metadata(); this.call.setupSurfaceCall(this); - this.call.setupReadable(this); + this.call.setupReadable(this, encoding); this.on('error', (err) => { this.call.sendError(err); @@ -439,6 +443,47 @@ export class Http2ServerCallStream< return this.cancelled; } + private getDecompressedMessage(message: Buffer, encoding?: MetadataValue) { + switch (encoding) { + case 'deflate': { + return new Promise((resolve, reject) => { + zlib.inflate(message.slice(5), (err, output) => { + if (err) { + this.sendError({ + code: Status.INTERNAL, + details: `Received "grpc-encoding" header "${encoding}" but ${encoding} decompression failed`, + }); + resolve(); + } else { + const joined = Buffer.concat([message.slice(0, 5), output]); + resolve(joined); + } + }); + }); + } + + case 'gzip': { + return new Promise((resolve, reject) => { + zlib.unzip(message.slice(5), (err, output) => { + if (err) { + this.sendError({ + code: Status.INTERNAL, + details: `Received "grpc-encoding" header "${encoding}" but ${encoding} decompression failed`, + }); + resolve(); + } else { + const joined = Buffer.concat([message.slice(0, 5), output]); + resolve(joined); + } + }); + }); + } + + default: + return Promise.resolve(message); + } + } + sendMetadata(customMetadata?: Metadata) { if (this.checkCancelled()) { return; @@ -469,7 +514,7 @@ export class Http2ServerCallStream< const err = new Error('Invalid deadline') as ServerErrorResponse; err.code = Status.OUT_OF_RANGE; this.sendError(err); - return; + return metadata; } const timeout = (+match[1] * deadlineUnitsToMs[match[2]]) | 0; @@ -484,13 +529,12 @@ export class Http2ServerCallStream< metadata.remove(http2.constants.HTTP2_HEADER_ACCEPT_ENCODING); metadata.remove(http2.constants.HTTP2_HEADER_TE); metadata.remove(http2.constants.HTTP2_HEADER_CONTENT_TYPE); - metadata.remove('grpc-encoding'); metadata.remove('grpc-accept-encoding'); return metadata; } - receiveUnaryMessage(): Promise { + receiveUnaryMessage(encoding?: MetadataValue): Promise { return new Promise((resolve, reject) => { const stream = this.stream; const chunks: Buffer[] = []; @@ -516,7 +560,17 @@ export class Http2ServerCallStream< } this.emit('receiveMessage'); - resolve(this.deserializeMessage(requestBytes)); + + const decompressedMessage = await this.getDecompressedMessage(requestBytes, encoding); + + // Encountered an error with decompression; it'll already have been propogated back + // Just return early + if (!decompressedMessage) { + resolve(); + } + else { + resolve(this.deserializeMessage(decompressedMessage)); + } } catch (err) { err.code = Status.INTERNAL; this.sendError(err); @@ -673,7 +727,8 @@ export class Http2ServerCallStream< setupReadable( readable: | ServerReadableStream - | ServerDuplexStream + | ServerDuplexStream, + encoding?: MetadataValue ) { const decoder = new StreamDecoder(); @@ -692,7 +747,14 @@ export class Http2ServerCallStream< return; } this.emit('receiveMessage'); - this.pushOrBufferMessage(readable, message); + + const decompressedMessage = await this.getDecompressedMessage(message, encoding); + + // Encountered an error with decompression; it'll already have been propogated back + // Just return early + if (!decompressedMessage) return; + + this.pushOrBufferMessage(readable, decompressedMessage); } }); diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index aed04adec..552f31b02 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -61,6 +61,7 @@ import { import { parseUri } from './uri-parser'; import { ChannelzCallTracker, ChannelzChildrenTracker, ChannelzTrace, registerChannelzServer, registerChannelzSocket, ServerInfo, ServerRef, SocketInfo, SocketRef, TlsInfo, unregisterChannelzRef } from './channelz'; import { CipherNameAndProtocol, TLSSocket } from 'tls'; +import { MetadataValue } from '.'; const TRACER_NAME = 'server'; @@ -777,30 +778,36 @@ export class Server { channelzSessionInfo.lastMessageReceivedTimestamp = new Date(); }); } - const metadata: Metadata = call.receiveMetadata(headers) as Metadata; + const metadata = call.receiveMetadata(headers); + const encoding: MetadataValue | undefined = metadata.get('grpc-encoding')[0]; + metadata.remove('grpc-encoding'); + switch (handler.type) { case 'unary': - handleUnary(call, handler as UntypedUnaryHandler, metadata); + handleUnary(call, handler as UntypedUnaryHandler, metadata, encoding); break; case 'clientStream': handleClientStreaming( call, handler as UntypedClientStreamingHandler, - metadata + metadata, + encoding ); break; case 'serverStream': handleServerStreaming( call, handler as UntypedServerStreamingHandler, - metadata + metadata, + encoding ); break; case 'bidi': handleBidiStreaming( call, handler as UntypedBidiStreamingHandler, - metadata + metadata, + encoding ); break; default: @@ -856,9 +863,10 @@ export class Server { async function handleUnary( call: Http2ServerCallStream, handler: UnaryHandler, - metadata: Metadata + metadata: Metadata, + encoding?: MetadataValue ): Promise { - const request = await call.receiveUnaryMessage(); + const request = await call.receiveUnaryMessage(encoding); if (request === undefined || call.cancelled) { return; @@ -886,12 +894,14 @@ async function handleUnary( function handleClientStreaming( call: Http2ServerCallStream, handler: ClientStreamingHandler, - metadata: Metadata + metadata: Metadata, + encoding?: MetadataValue ): void { const stream = new ServerReadableStreamImpl( call, metadata, - handler.deserialize + handler.deserialize, + encoding ); function respond( @@ -915,9 +925,10 @@ function handleClientStreaming( async function handleServerStreaming( call: Http2ServerCallStream, handler: ServerStreamingHandler, - metadata: Metadata + metadata: Metadata, + encoding?: MetadataValue ): Promise { - const request = await call.receiveUnaryMessage(); + const request = await call.receiveUnaryMessage(encoding); if (request === undefined || call.cancelled) { return; @@ -936,13 +947,15 @@ async function handleServerStreaming( function handleBidiStreaming( call: Http2ServerCallStream, handler: BidiStreamingHandler, - metadata: Metadata + metadata: Metadata, + encoding?: MetadataValue ): void { const stream = new ServerDuplexStreamImpl( call, metadata, handler.serialize, - handler.deserialize + handler.deserialize, + encoding ); if (call.cancelled) { diff --git a/packages/grpc-js/test/test-server.ts b/packages/grpc-js/test/test-server.ts index 8b2815745..676a2fda2 100644 --- a/packages/grpc-js/test/test-server.ts +++ b/packages/grpc-js/test/test-server.ts @@ -21,6 +21,7 @@ import * as assert from 'assert'; import * as fs from 'fs'; import * as http2 from 'http2'; import * as path from 'path'; +import * as protoLoader from '@grpc/proto-loader'; import * as grpc from '../src'; import { Server, ServerCredentials } from '../src'; @@ -29,6 +30,36 @@ import { ServiceClient, ServiceClientConstructor } from '../src/make-client'; import { sendUnaryData, ServerUnaryCall } from '../src/server-call'; import { loadProtoFile } from './common'; +import { TestServiceClient, TestServiceHandlers } from '../src/generated/TestService'; +import { ProtoGrpcType as ChannelzGrpcType } from '../src/generated/channelz'; +import { ProtoGrpcType as TestServiceGrpcType } from '../src/generated/test_service'; +import { Request__Output } from '../src/generated/Request'; + +const loadedChannelzProto = protoLoader.loadSync('channelz.proto', { + keepCase: true, + longs: String, + enums: String, + defaults: true, + oneofs: true, + includeDirs: [ + `${__dirname}/../../proto` + ] +}); + +const channelzGrpcObject = grpc.loadPackageDefinition(loadedChannelzProto) as unknown as ChannelzGrpcType; + +const loadedTestServiceProto = protoLoader.loadSync('test_service.proto', { + keepCase: true, + longs: String, + enums: String, + defaults: true, + oneofs: true, + includeDirs: [ + `${__dirname}/../../proto` + ] +}); + +const testServiceGrpcObject = grpc.loadPackageDefinition(loadedTestServiceProto) as unknown as TestServiceGrpcType; const ca = fs.readFileSync(path.join(__dirname, 'fixtures', 'ca.pem')); const key = fs.readFileSync(path.join(__dirname, 'fixtures', 'server1.key')); @@ -604,3 +635,258 @@ describe('Generic client and server', () => { }); }); }); + +describe('Compressed requests', () => { + const testServiceHandlers: TestServiceHandlers = { + Unary(call, callback) { + const { metadata, request } = call; + console.log({ metadata, request }); + + callback(null, { count: 500000 }); + }, + + ClientStream(call, callback) { + let timesCalled = 0; + + call.on('data', () => { + timesCalled += 1; + console.log('clientStream received another call', { timesCalled }); + }); + + call.on('end', () => { + console.log('Returning from clientStream: ', { timesCalled }); + callback(null, { count: timesCalled }); + }); + }, + + ServerStream(call) { + const { metadata, request } = call; + console.log({ metadata, request }); + + for (let i = 0; i < 5; i++) { + call.write({ count: request.message.length }); + } + + call.end(); + }, + + BidiStream(call) { + call.on('data', (data: Request__Output) => { + console.log('Bidi stream data received, writing response', { data }); + call.write({ count: data.message.length }); + }); + + call.on('end', () => { + console.log('Server received end event for bidi stream, ending server-side call'); + call.end(); + }); + } + }; + + describe('Test service client and server with deflate', () => { + let client: TestServiceClient; + let server: Server; + let assignedPort: number; + + before(done => { + server = new Server(); + server.addService( + testServiceGrpcObject.TestService.service, + testServiceHandlers + ); + server.bindAsync( + 'localhost:0', + ServerCredentials.createInsecure(), + (err, port) => { + assert.ifError(err); + server.start(); + assignedPort = port; + client = new testServiceGrpcObject.TestService( + `localhost:${assignedPort}`, + grpc.credentials.createInsecure(), + { + 'grpc.default_compression_algorithm': 1 + } + ); + done(); + } + ); + }); + + after(done => { + client.close(); + server.tryShutdown(done); + }); + + it('Should compress and decompress when performing unary call', done => { + client.unary({ message: 'foo' }, (err, response) => { + assert.ifError(err); + done(); + }); + }); + + it('Should compress and decompress when performing client stream', done => { + const clientStream = client.clientStream((err, res) => { + assert.ifError(err); + assert.equal(res?.count, 3); + done(); + }); + + clientStream.write({ message: 'foo' }, () => { + clientStream.write({ message: 'bar' }, () => { + clientStream.write({ message: 'baz' }, () => { + setTimeout(() => clientStream.end(), 10); + }); + }); + }); + }); + + it('Should compress and decompress when performing server stream', done => { + const serverStream = client.serverStream({ message: 'foobar' }); + let timesResponded = 0; + + serverStream.on('data', () => { + timesResponded += 1; + }); + + serverStream.on('error', (err) => { + assert.ifError(err); + done(); + }); + + serverStream.on('end', () => { + assert.equal(timesResponded, 5); + done(); + }); + }); + + it('Should compress and decompress when performing bidi stream', done => { + const bidiStream = client.bidiStream(); + let timesRequested = 0; + let timesResponded = 0; + + bidiStream.on('data', () => { + timesResponded += 1; + }); + + bidiStream.on('error', (err) => { + assert.ifError(err); + done(); + }); + + bidiStream.on('end', () => { + console.log('Client received end event for bidi stream', { timesResponded, timesRequested }); + assert.equal(timesResponded, timesRequested); + done(); + }); + + bidiStream.write({ message: 'foo' }, () => { + timesRequested += 1; + bidiStream.write({ message: 'bar' }, () => { + timesRequested += 1; + bidiStream.write({ message: 'baz' }, () => { + timesRequested += 1; + setTimeout(() => bidiStream.end(), 10); + }) + }) + }); + }); + + it('Should compress and decompress with gzip', done => { + client = new testServiceGrpcObject.TestService( + `localhost:${assignedPort}`, + grpc.credentials.createInsecure(), + { + 'grpc.default_compression_algorithm': 2 + } + ); + + client.unary({ message: 'foo' }, (err, response) => { + assert.ifError(err); + done(); + }); + }); + + it('Should compress and decompress when performing client stream', done => { + const clientStream = client.clientStream((err, res) => { + assert.ifError(err); + assert.equal(res?.count, 3); + done(); + }); + + clientStream.write({ message: 'foo' }, () => { + clientStream.write({ message: 'bar' }, () => { + clientStream.write({ message: 'baz' }, () => { + setTimeout(() => clientStream.end(), 10); + }); + }); + }); + }); + + it('Should compress and decompress when performing server stream', done => { + const serverStream = client.serverStream({ message: 'foobar' }); + let timesResponded = 0; + + serverStream.on('data', () => { + timesResponded += 1; + }); + + serverStream.on('error', (err) => { + assert.ifError(err); + done(); + }); + + serverStream.on('end', () => { + assert.equal(timesResponded, 5); + done(); + }); + }); + + it('Should compress and decompress when performing bidi stream', done => { + const bidiStream = client.bidiStream(); + let timesRequested = 0; + let timesResponded = 0; + + bidiStream.on('data', () => { + timesResponded += 1; + }); + + bidiStream.on('error', (err) => { + assert.ifError(err); + done(); + }); + + bidiStream.on('end', () => { + console.log('Client received end event for bidi stream', { timesResponded, timesRequested }); + assert.equal(timesResponded, timesRequested); + done(); + }); + + bidiStream.write({ message: 'foo' }, () => { + timesRequested += 1; + bidiStream.write({ message: 'bar' }, () => { + timesRequested += 1; + bidiStream.write({ message: 'baz' }, () => { + timesRequested += 1; + setTimeout(() => bidiStream.end(), 10); + }) + }) + }); + }); + + it('Should fail when attempting to use an unsupported compression method', done => { + client = new testServiceGrpcObject.TestService( + `localhost:${assignedPort}`, + grpc.credentials.createInsecure(), + { + 'grpc.default_compression_algorithm': 3 + } + ); + + client.unary({ message: 'foo' }, (err, response) => { + assert.ok(err); + done(); + }); + }); + }); +}); From cec7e64a2be1ba7c2a6bd19d7d234fd0bcff5c29 Mon Sep 17 00:00:00 2001 From: Robert Date: Sun, 24 Oct 2021 22:21:24 -0700 Subject: [PATCH 103/450] cleanup test file --- packages/grpc-js/test/test-server.ts | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/packages/grpc-js/test/test-server.ts b/packages/grpc-js/test/test-server.ts index 676a2fda2..f6a68a02a 100644 --- a/packages/grpc-js/test/test-server.ts +++ b/packages/grpc-js/test/test-server.ts @@ -31,23 +31,9 @@ import { sendUnaryData, ServerUnaryCall } from '../src/server-call'; import { loadProtoFile } from './common'; import { TestServiceClient, TestServiceHandlers } from '../src/generated/TestService'; -import { ProtoGrpcType as ChannelzGrpcType } from '../src/generated/channelz'; import { ProtoGrpcType as TestServiceGrpcType } from '../src/generated/test_service'; import { Request__Output } from '../src/generated/Request'; -const loadedChannelzProto = protoLoader.loadSync('channelz.proto', { - keepCase: true, - longs: String, - enums: String, - defaults: true, - oneofs: true, - includeDirs: [ - `${__dirname}/../../proto` - ] -}); - -const channelzGrpcObject = grpc.loadPackageDefinition(loadedChannelzProto) as unknown as ChannelzGrpcType; - const loadedTestServiceProto = protoLoader.loadSync('test_service.proto', { keepCase: true, longs: String, @@ -639,9 +625,6 @@ describe('Generic client and server', () => { describe('Compressed requests', () => { const testServiceHandlers: TestServiceHandlers = { Unary(call, callback) { - const { metadata, request } = call; - console.log({ metadata, request }); - callback(null, { count: 500000 }); }, @@ -650,18 +633,15 @@ describe('Compressed requests', () => { call.on('data', () => { timesCalled += 1; - console.log('clientStream received another call', { timesCalled }); }); call.on('end', () => { - console.log('Returning from clientStream: ', { timesCalled }); callback(null, { count: timesCalled }); }); }, ServerStream(call) { const { metadata, request } = call; - console.log({ metadata, request }); for (let i = 0; i < 5; i++) { call.write({ count: request.message.length }); @@ -672,12 +652,10 @@ describe('Compressed requests', () => { BidiStream(call) { call.on('data', (data: Request__Output) => { - console.log('Bidi stream data received, writing response', { data }); call.write({ count: data.message.length }); }); call.on('end', () => { - console.log('Server received end event for bidi stream, ending server-side call'); call.end(); }); } @@ -775,7 +753,6 @@ describe('Compressed requests', () => { }); bidiStream.on('end', () => { - console.log('Client received end event for bidi stream', { timesResponded, timesRequested }); assert.equal(timesResponded, timesRequested); done(); }); @@ -857,7 +834,6 @@ describe('Compressed requests', () => { }); bidiStream.on('end', () => { - console.log('Client received end event for bidi stream', { timesResponded, timesRequested }); assert.equal(timesResponded, timesRequested); done(); }); From 8dbeeb1d18cb254bf055c8ebbc966657fd94ed4f Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 25 Oct 2021 13:29:06 -0700 Subject: [PATCH 104/450] grpc-js: Handle undefined socket.localAddress --- packages/grpc-js/src/channelz.ts | 4 ++-- packages/grpc-js/src/server.ts | 2 +- packages/grpc-js/src/subchannel.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js/src/channelz.ts b/packages/grpc-js/src/channelz.ts index 7efe54780..56a015642 100644 --- a/packages/grpc-js/src/channelz.ts +++ b/packages/grpc-js/src/channelz.ts @@ -286,7 +286,7 @@ export interface TlsInfo { } export interface SocketInfo { - localAddress: SubchannelAddress; + localAddress: SubchannelAddress | null; remoteAddress: SubchannelAddress | null; security: TlsInfo | null; remoteName: string | null; @@ -631,7 +631,7 @@ function GetSocket(call: ServerUnaryCall Date: Mon, 25 Oct 2021 18:46:14 -0700 Subject: [PATCH 105/450] revert mistaken accept-encoding client header change --- packages/grpc-js/src/compression-filter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/src/compression-filter.ts b/packages/grpc-js/src/compression-filter.ts index 4ecdbb6a3..4b06fafe6 100644 --- a/packages/grpc-js/src/compression-filter.ts +++ b/packages/grpc-js/src/compression-filter.ts @@ -199,7 +199,7 @@ export class CompressionFilter extends BaseFilter implements Filter { async sendMetadata(metadata: Promise): Promise { const headers: Metadata = await metadata; headers.set('grpc-accept-encoding', 'identity,deflate,gzip'); - headers.set('accept-encoding', 'identity,deflate,gzip'); + headers.set('accept-encoding', 'identity'); if (this.defaultCompressionAlgorithm && ['deflate', 'gzip'].includes(this.defaultCompressionAlgorithm)) { headers.set('grpc-encoding', this.defaultCompressionAlgorithm); From 16f13560506235374775f4fac3005cfdfe9c4559 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 25 Oct 2021 18:54:16 -0700 Subject: [PATCH 106/450] remove unused compression algorithm key value --- packages/grpc-js/src/compression-filter.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/grpc-js/src/compression-filter.ts b/packages/grpc-js/src/compression-filter.ts index 4b06fafe6..6c613612d 100644 --- a/packages/grpc-js/src/compression-filter.ts +++ b/packages/grpc-js/src/compression-filter.ts @@ -26,9 +26,7 @@ import { ChannelOptions } from './channel-options'; const CompressionAlgorithms = { '0': 'identity', '1': 'deflate', - '2': 'gzip', - // Streaming compression is unimplemented - '3': 'stream-gzip' + '2': 'gzip' } as const; const CompressionAlgorithKeys = new Set(Object.keys(CompressionAlgorithms)); From 9d70f39b7e53bb10a578ffd5846e14dd788cc63b Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 25 Oct 2021 19:00:59 -0700 Subject: [PATCH 107/450] remove copied test proto file and modify npm command --- packages/grpc-js/package.json | 2 +- packages/grpc-js/proto/test_service.proto | 42 ------------------- packages/grpc-js/src/generated/Request.ts | 2 +- packages/grpc-js/src/generated/Response.ts | 2 +- packages/grpc-js/src/generated/TestService.ts | 2 +- 5 files changed, 4 insertions(+), 46 deletions(-) delete mode 100644 packages/grpc-js/proto/test_service.proto diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index f430c09d2..76a0902be 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -54,7 +54,7 @@ "fix": "gts fix src/*.ts", "pretest": "npm run generate-types && npm run compile", "posttest": "npm run check && madge -c ./build/src", - "generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs proto/ -O src/generated/ --grpcLib ../index channelz.proto test_service.proto" + "generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs proto/ --include-dirs test/fixtures/ -O src/generated/ --grpcLib ../index channelz.proto test_service.proto" }, "dependencies": { "@grpc/proto-loader": "^0.6.4", diff --git a/packages/grpc-js/proto/test_service.proto b/packages/grpc-js/proto/test_service.proto deleted file mode 100644 index f99393d14..000000000 --- a/packages/grpc-js/proto/test_service.proto +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2019 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. - * - */ - -syntax = "proto3"; - -message Request { - bool error = 1; - string message = 2; - int32 errorAfter = 3; -} - -message Response { - int32 count = 1; -} - -service TestService { - rpc Unary (Request) returns (Response) { - } - - rpc ClientStream (stream Request) returns (Response) { - } - - rpc ServerStream (Request) returns (stream Response) { - } - - rpc BidiStream (stream Request) returns (stream Response) { - } -} diff --git a/packages/grpc-js/src/generated/Request.ts b/packages/grpc-js/src/generated/Request.ts index 93898a701..d64ebb6ea 100644 --- a/packages/grpc-js/src/generated/Request.ts +++ b/packages/grpc-js/src/generated/Request.ts @@ -1,4 +1,4 @@ -// Original file: proto/test_service.proto +// Original file: test/fixtures/test_service.proto export interface Request { diff --git a/packages/grpc-js/src/generated/Response.ts b/packages/grpc-js/src/generated/Response.ts index 980bfdd18..217fc75e8 100644 --- a/packages/grpc-js/src/generated/Response.ts +++ b/packages/grpc-js/src/generated/Response.ts @@ -1,4 +1,4 @@ -// Original file: proto/test_service.proto +// Original file: test/fixtures/test_service.proto export interface Response { diff --git a/packages/grpc-js/src/generated/TestService.ts b/packages/grpc-js/src/generated/TestService.ts index dd1d22ab2..f890c520f 100644 --- a/packages/grpc-js/src/generated/TestService.ts +++ b/packages/grpc-js/src/generated/TestService.ts @@ -1,4 +1,4 @@ -// Original file: proto/test_service.proto +// Original file: test/fixtures/test_service.proto import type * as grpc from './../index' import type { MethodDefinition } from '@grpc/proto-loader' From 959503ec94aa08a6942780d7b7cd80847dbd4be6 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 25 Oct 2021 19:14:01 -0700 Subject: [PATCH 108/450] rewrite CompressionAlgorithms to use numeric keys and export it --- packages/grpc-js/src/compression-filter.ts | 14 +++++++------- packages/grpc-js/src/index.ts | 2 ++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/grpc-js/src/compression-filter.ts b/packages/grpc-js/src/compression-filter.ts index 6c613612d..eabb7a851 100644 --- a/packages/grpc-js/src/compression-filter.ts +++ b/packages/grpc-js/src/compression-filter.ts @@ -23,16 +23,16 @@ import { BaseFilter, Filter, FilterFactory } from './filter'; import { Metadata, MetadataValue } from './metadata'; import { ChannelOptions } from './channel-options'; -const CompressionAlgorithms = { - '0': 'identity', - '1': 'deflate', - '2': 'gzip' +export const CompressionAlgorithms = { + 0: 'identity', + 1: 'deflate', + 2: 'gzip' } as const; const CompressionAlgorithKeys = new Set(Object.keys(CompressionAlgorithms)); -const isCompressionAlgorithmKey = (key: string | undefined): key is keyof typeof CompressionAlgorithms => { - return typeof key === 'string' && CompressionAlgorithKeys.has(key); +const isCompressionAlgorithmKey = (key: number | undefined): key is keyof typeof CompressionAlgorithms => { + return typeof key === 'number' && CompressionAlgorithKeys.has(key.toString()); } type CompressionAlgorithm = (typeof CompressionAlgorithms)[keyof typeof CompressionAlgorithms]; @@ -187,7 +187,7 @@ export class CompressionFilter extends BaseFilter implements Filter { constructor(channelOptions: ChannelOptions) { super(); - const compressionAlgorithmKey = channelOptions['grpc.default_compression_algorithm']?.toString(); + const compressionAlgorithmKey = channelOptions['grpc.default_compression_algorithm']; if (isCompressionAlgorithmKey(compressionAlgorithmKey)) { this.defaultCompressionAlgorithm = CompressionAlgorithms[compressionAlgorithmKey]; this.sendCompression = getCompressionHandler(this.defaultCompressionAlgorithm); diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index 4b7967be9..7e1ed7a50 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -25,6 +25,7 @@ import { import { CallCredentials, OAuth2Client } from './call-credentials'; import { Deadline, StatusObject } from './call-stream'; import { Channel, ChannelImplementation } from './channel'; +import { CompressionAlgorithms } from './compression-filter'; import { ConnectivityState } from './connectivity-state'; import { ChannelCredentials } from './channel-credentials'; import { @@ -124,6 +125,7 @@ export { Status as status, ConnectivityState as connectivityState, Propagate as propagate, + CompressionAlgorithms as compressionAlgorithms // TODO: Other constants as well }; From af010071fe2f4eeab2ebc80b99039942f935423f Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 25 Oct 2021 19:43:40 -0700 Subject: [PATCH 109/450] have client restore default sendCompression if server doesnt support compression, and fix test file generation --- packages/grpc-js/package.json | 5 ++-- packages/grpc-js/src/compression-filter.ts | 12 ++++++++++ .../{src => test}/generated/Request.ts | 0 .../{src => test}/generated/Response.ts | 0 .../{src => test}/generated/TestService.ts | 2 +- .../{src => test}/generated/test_service.ts | 2 +- packages/grpc-js/test/test-server.ts | 23 ++++--------------- 7 files changed, 21 insertions(+), 23 deletions(-) rename packages/grpc-js/{src => test}/generated/Request.ts (100%) rename packages/grpc-js/{src => test}/generated/Response.ts (100%) rename packages/grpc-js/{src => test}/generated/TestService.ts (98%) rename packages/grpc-js/{src => test}/generated/test_service.ts (92%) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 76a0902be..9131d470f 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -52,9 +52,10 @@ "test": "gulp test", "check": "gts check src/**/*.ts", "fix": "gts fix src/*.ts", - "pretest": "npm run generate-types && npm run compile", + "pretest": "npm run generate-types && npm run generate-test-types && npm run compile", "posttest": "npm run check && madge -c ./build/src", - "generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs proto/ --include-dirs test/fixtures/ -O src/generated/ --grpcLib ../index channelz.proto test_service.proto" + "generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs proto/ --include-dirs test/fixtures/ -O src/generated/ --grpcLib ../index channelz.proto", + "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.6.4", diff --git a/packages/grpc-js/src/compression-filter.ts b/packages/grpc-js/src/compression-filter.ts index eabb7a851..b7e5e5d29 100644 --- a/packages/grpc-js/src/compression-filter.ts +++ b/packages/grpc-js/src/compression-filter.ts @@ -217,6 +217,18 @@ export class CompressionFilter extends BaseFilter implements Filter { } } metadata.remove('grpc-encoding'); + + /* Check to see if the compression we're using to send messages is supported by the server + * If not, reset the sendCompression filter and have it use the default IdentityHandler */ + const serverSupportedEncodingsHeader = metadata.get('grpc-accept-encoding')[0] as string | undefined; + if (serverSupportedEncodingsHeader) { + const serverSupportedEncodings = serverSupportedEncodingsHeader.split(','); + + if ((this.sendCompression instanceof DeflateHandler && !serverSupportedEncodings.includes('deflate')) + || (this.sendCompression instanceof GzipHandler && !serverSupportedEncodings.includes('gzip'))) { + this.sendCompression = new IdentityHandler(); + } + } metadata.remove('grpc-accept-encoding'); return metadata; } diff --git a/packages/grpc-js/src/generated/Request.ts b/packages/grpc-js/test/generated/Request.ts similarity index 100% rename from packages/grpc-js/src/generated/Request.ts rename to packages/grpc-js/test/generated/Request.ts diff --git a/packages/grpc-js/src/generated/Response.ts b/packages/grpc-js/test/generated/Response.ts similarity index 100% rename from packages/grpc-js/src/generated/Response.ts rename to packages/grpc-js/test/generated/Response.ts diff --git a/packages/grpc-js/src/generated/TestService.ts b/packages/grpc-js/test/generated/TestService.ts similarity index 98% rename from packages/grpc-js/src/generated/TestService.ts rename to packages/grpc-js/test/generated/TestService.ts index f890c520f..75bff33e4 100644 --- a/packages/grpc-js/src/generated/TestService.ts +++ b/packages/grpc-js/test/generated/TestService.ts @@ -1,6 +1,6 @@ // Original file: test/fixtures/test_service.proto -import type * as grpc from './../index' +import type * as grpc from './../../src/index' import type { MethodDefinition } from '@grpc/proto-loader' import type { Request as _Request, Request__Output as _Request__Output } from './Request'; import type { Response as _Response, Response__Output as _Response__Output } from './Response'; diff --git a/packages/grpc-js/src/generated/test_service.ts b/packages/grpc-js/test/generated/test_service.ts similarity index 92% rename from packages/grpc-js/src/generated/test_service.ts rename to packages/grpc-js/test/generated/test_service.ts index 2beb88680..364acddeb 100644 --- a/packages/grpc-js/src/generated/test_service.ts +++ b/packages/grpc-js/test/generated/test_service.ts @@ -1,4 +1,4 @@ -import type * as grpc from '../index'; +import type * as grpc from '../../src/index'; import type { MessageTypeDefinition } from '@grpc/proto-loader'; import type { TestServiceClient as _TestServiceClient, TestServiceDefinition as _TestServiceDefinition } from './TestService'; diff --git a/packages/grpc-js/test/test-server.ts b/packages/grpc-js/test/test-server.ts index f6a68a02a..c8171e796 100644 --- a/packages/grpc-js/test/test-server.ts +++ b/packages/grpc-js/test/test-server.ts @@ -30,11 +30,11 @@ import { ServiceClient, ServiceClientConstructor } from '../src/make-client'; import { sendUnaryData, ServerUnaryCall } from '../src/server-call'; import { loadProtoFile } from './common'; -import { TestServiceClient, TestServiceHandlers } from '../src/generated/TestService'; -import { ProtoGrpcType as TestServiceGrpcType } from '../src/generated/test_service'; -import { Request__Output } from '../src/generated/Request'; +import { TestServiceClient, TestServiceHandlers } from './generated/TestService'; +import { ProtoGrpcType as TestServiceGrpcType } from './generated/test_service'; +import { Request__Output } from './generated/Request'; -const loadedTestServiceProto = protoLoader.loadSync('test_service.proto', { +const loadedTestServiceProto = protoLoader.loadSync('test/fixtures/test_service.proto', { keepCase: true, longs: String, enums: String, @@ -849,20 +849,5 @@ describe('Compressed requests', () => { }) }); }); - - it('Should fail when attempting to use an unsupported compression method', done => { - client = new testServiceGrpcObject.TestService( - `localhost:${assignedPort}`, - grpc.credentials.createInsecure(), - { - 'grpc.default_compression_algorithm': 3 - } - ); - - client.unary({ message: 'foo' }, (err, response) => { - assert.ok(err); - done(); - }); - }); }); }); From d68d94a5f47582419390e2e8f08a10339a866026 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 25 Oct 2021 20:21:48 -0700 Subject: [PATCH 110/450] re-enable NoCompress flag behavior and check Compressed Flag byte on server --- packages/grpc-js/src/compression-filter.ts | 10 ++++----- packages/grpc-js/src/server-call.ts | 8 +++++-- packages/grpc-js/test/test-server.ts | 26 ++++++++++++++++++++++ 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/packages/grpc-js/src/compression-filter.ts b/packages/grpc-js/src/compression-filter.ts index b7e5e5d29..ae507d333 100644 --- a/packages/grpc-js/src/compression-filter.ts +++ b/packages/grpc-js/src/compression-filter.ts @@ -17,7 +17,7 @@ import * as zlib from 'zlib'; -import { Call, WriteObject } from './call-stream'; +import { Call, WriteObject, WriteFlags } from './call-stream'; import { Channel } from './channel'; import { BaseFilter, Filter, FilterFactory } from './filter'; import { Metadata, MetadataValue } from './metadata'; @@ -238,10 +238,10 @@ 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; - const compress = !(this.sendCompression instanceof IdentityHandler); - // resolvedMessage.flags === undefined - // ? false - // : (resolvedMessage.flags & WriteFlags.NoCompress) === 0; + const compress = + resolvedMessage.flags === undefined + ? !(this.sendCompression instanceof IdentityHandler) + : (resolvedMessage.flags & WriteFlags.NoCompress) === 0; return { message: await this.sendCompression.writeMessage( resolvedMessage.message, diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index 8ea488a4d..f1d3a8abd 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -561,7 +561,9 @@ export class Http2ServerCallStream< this.emit('receiveMessage'); - const decompressedMessage = await this.getDecompressedMessage(requestBytes, encoding); + const compressed = requestBytes.readUInt8(0) === 1; + const compressedMessageEncoding = compressed ? encoding : undefined; + const decompressedMessage = await this.getDecompressedMessage(requestBytes, compressedMessageEncoding); // Encountered an error with decompression; it'll already have been propogated back // Just return early @@ -748,7 +750,9 @@ export class Http2ServerCallStream< } this.emit('receiveMessage'); - const decompressedMessage = await this.getDecompressedMessage(message, encoding); + const compressed = message.readUInt8(0) === 1; + const compressedMessageEncoding = compressed ? encoding : undefined; + const decompressedMessage = await this.getDecompressedMessage(message, compressedMessageEncoding); // Encountered an error with decompression; it'll already have been propogated back // Just return early diff --git a/packages/grpc-js/test/test-server.ts b/packages/grpc-js/test/test-server.ts index c8171e796..b6cffd81c 100644 --- a/packages/grpc-js/test/test-server.ts +++ b/packages/grpc-js/test/test-server.ts @@ -849,5 +849,31 @@ describe('Compressed requests', () => { }) }); }); + + it('Should not compress requests when the NoCompress write flag is used', done => { + const bidiStream = client.bidiStream(); + let timesRequested = 0; + let timesResponded = 0; + + bidiStream.on('data', () => { + timesResponded += 1; + }); + + bidiStream.on('error', (err) => { + assert.ifError(err); + done(); + }); + + bidiStream.on('end', () => { + assert.equal(timesResponded, timesRequested); + done(); + }); + + bidiStream._write({ message: 'foo' }, '2', (err: any) => { + assert.ifError(err); + timesRequested += 1; + setTimeout(() => bidiStream.end(), 10); + }); + }); }); }); From 91ae2b44b165f4d77ed76deab5275df98230776b Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 25 Oct 2021 13:29:06 -0700 Subject: [PATCH 111/450] grpc-js: Handle undefined socket.localAddress --- packages/grpc-js/src/channelz.ts | 4 ++-- packages/grpc-js/src/server.ts | 2 +- packages/grpc-js/src/subchannel.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js/src/channelz.ts b/packages/grpc-js/src/channelz.ts index a1c85eb47..768efaa58 100644 --- a/packages/grpc-js/src/channelz.ts +++ b/packages/grpc-js/src/channelz.ts @@ -298,7 +298,7 @@ export interface TlsInfo { } export interface SocketInfo { - localAddress: SubchannelAddress; + localAddress: SubchannelAddress | null; remoteAddress: SubchannelAddress | null; security: TlsInfo | null; remoteName: string | null; @@ -629,7 +629,7 @@ function GetSocket(call: ServerUnaryCall Date: Tue, 26 Oct 2021 13:44:03 -0700 Subject: [PATCH 112/450] change encoding type from MetadataValue to string --- packages/grpc-js/src/server-call.ts | 11 +++++------ packages/grpc-js/src/server.ts | 11 +++++------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index f1d3a8abd..d3c622b5c 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -33,7 +33,6 @@ import { StreamDecoder } from './stream-decoder'; import { ObjectReadable, ObjectWritable } from './object-stream'; import { ChannelOptions } from './channel-options'; import * as logging from './logging'; -import { MetadataValue } from '.'; const TRACER_NAME = 'server_call'; @@ -139,7 +138,7 @@ export class ServerReadableStreamImpl private call: Http2ServerCallStream, public metadata: Metadata, public deserialize: Deserialize, - encoding?: MetadataValue + encoding?: string ) { super({ objectMode: true }); this.cancelled = false; @@ -254,7 +253,7 @@ export class ServerDuplexStreamImpl public metadata: Metadata, public serialize: Serialize, public deserialize: Deserialize, - encoding?: MetadataValue + encoding?: string ) { super({ objectMode: true }); this.cancelled = false; @@ -443,7 +442,7 @@ export class Http2ServerCallStream< return this.cancelled; } - private getDecompressedMessage(message: Buffer, encoding?: MetadataValue) { + private getDecompressedMessage(message: Buffer, encoding?: string) { switch (encoding) { case 'deflate': { return new Promise((resolve, reject) => { @@ -534,7 +533,7 @@ export class Http2ServerCallStream< return metadata; } - receiveUnaryMessage(encoding?: MetadataValue): Promise { + receiveUnaryMessage(encoding?: string): Promise { return new Promise((resolve, reject) => { const stream = this.stream; const chunks: Buffer[] = []; @@ -730,7 +729,7 @@ export class Http2ServerCallStream< readable: | ServerReadableStream | ServerDuplexStream, - encoding?: MetadataValue + encoding?: string ) { const decoder = new StreamDecoder(); diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 552f31b02..b69a795e9 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -61,7 +61,6 @@ import { import { parseUri } from './uri-parser'; import { ChannelzCallTracker, ChannelzChildrenTracker, ChannelzTrace, registerChannelzServer, registerChannelzSocket, ServerInfo, ServerRef, SocketInfo, SocketRef, TlsInfo, unregisterChannelzRef } from './channelz'; import { CipherNameAndProtocol, TLSSocket } from 'tls'; -import { MetadataValue } from '.'; const TRACER_NAME = 'server'; @@ -779,7 +778,7 @@ export class Server { }); } const metadata = call.receiveMetadata(headers); - const encoding: MetadataValue | undefined = metadata.get('grpc-encoding')[0]; + const encoding = metadata.get('grpc-encoding')[0] as string | undefined; metadata.remove('grpc-encoding'); switch (handler.type) { @@ -864,7 +863,7 @@ async function handleUnary( call: Http2ServerCallStream, handler: UnaryHandler, metadata: Metadata, - encoding?: MetadataValue + encoding?: string ): Promise { const request = await call.receiveUnaryMessage(encoding); @@ -895,7 +894,7 @@ function handleClientStreaming( call: Http2ServerCallStream, handler: ClientStreamingHandler, metadata: Metadata, - encoding?: MetadataValue + encoding?: string ): void { const stream = new ServerReadableStreamImpl( call, @@ -926,7 +925,7 @@ async function handleServerStreaming( call: Http2ServerCallStream, handler: ServerStreamingHandler, metadata: Metadata, - encoding?: MetadataValue + encoding?: string ): Promise { const request = await call.receiveUnaryMessage(encoding); @@ -948,7 +947,7 @@ function handleBidiStreaming( call: Http2ServerCallStream, handler: BidiStreamingHandler, metadata: Metadata, - encoding?: MetadataValue + encoding?: string ): void { const stream = new ServerDuplexStreamImpl( call, From 21b09e25ba9c430389d8c61e674c531757e6f2ae Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 26 Oct 2021 13:51:42 -0700 Subject: [PATCH 113/450] separate compression algorithms to avoid circular dependency --- packages/grpc-js/src/channel-options.ts | 4 +++- .../grpc-js/src/compression-algorithms.ts | 22 +++++++++++++++++++ packages/grpc-js/src/compression-filter.ts | 7 +----- packages/grpc-js/src/index.ts | 2 +- 4 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 packages/grpc-js/src/compression-algorithms.ts diff --git a/packages/grpc-js/src/channel-options.ts b/packages/grpc-js/src/channel-options.ts index f0b37d7a4..b54ae4eda 100644 --- a/packages/grpc-js/src/channel-options.ts +++ b/packages/grpc-js/src/channel-options.ts @@ -15,6 +15,8 @@ * */ +import { CompressionAlgorithms } from './compression-algorithms'; + /** * An interface that contains options used when initializing a Channel instance. */ @@ -36,7 +38,7 @@ export interface ChannelOptions { 'grpc.enable_http_proxy'?: number; 'grpc.http_connect_target'?: string; 'grpc.http_connect_creds'?: string; - 'grpc.default_compression_algorithm'?: number; + 'grpc.default_compression_algorithm'?: keyof typeof CompressionAlgorithms; 'grpc-node.max_session_memory'?: number; // eslint-disable-next-line @typescript-eslint/no-explicit-any [key: string]: any; diff --git a/packages/grpc-js/src/compression-algorithms.ts b/packages/grpc-js/src/compression-algorithms.ts new file mode 100644 index 000000000..8ec283cf6 --- /dev/null +++ b/packages/grpc-js/src/compression-algorithms.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2019 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. + * + */ + +export const CompressionAlgorithms = { + 0: 'identity', + 1: 'deflate', + 2: 'gzip' +} as const; diff --git a/packages/grpc-js/src/compression-filter.ts b/packages/grpc-js/src/compression-filter.ts index ae507d333..69fcf48db 100644 --- a/packages/grpc-js/src/compression-filter.ts +++ b/packages/grpc-js/src/compression-filter.ts @@ -19,16 +19,11 @@ import * as zlib from 'zlib'; import { Call, WriteObject, WriteFlags } from './call-stream'; import { Channel } from './channel'; +import { CompressionAlgorithms } from './compression-algorithms'; import { BaseFilter, Filter, FilterFactory } from './filter'; import { Metadata, MetadataValue } from './metadata'; import { ChannelOptions } from './channel-options'; -export const CompressionAlgorithms = { - 0: 'identity', - 1: 'deflate', - 2: 'gzip' -} as const; - const CompressionAlgorithKeys = new Set(Object.keys(CompressionAlgorithms)); const isCompressionAlgorithmKey = (key: number | undefined): key is keyof typeof CompressionAlgorithms => { diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index 7e1ed7a50..f34c19a1d 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -25,7 +25,7 @@ import { import { CallCredentials, OAuth2Client } from './call-credentials'; import { Deadline, StatusObject } from './call-stream'; import { Channel, ChannelImplementation } from './channel'; -import { CompressionAlgorithms } from './compression-filter'; +import { CompressionAlgorithms } from './compression-algorithms'; import { ConnectivityState } from './connectivity-state'; import { ChannelCredentials } from './channel-credentials'; import { From e03c1159ea650cc4bb931ae7be2ef22188bd635e Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 26 Oct 2021 14:01:37 -0700 Subject: [PATCH 114/450] log a warning when invalid value for grpc.default_compression_algorithm option is provided --- packages/grpc-js/src/compression-filter.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/src/compression-filter.ts b/packages/grpc-js/src/compression-filter.ts index 69fcf48db..26b2836b6 100644 --- a/packages/grpc-js/src/compression-filter.ts +++ b/packages/grpc-js/src/compression-filter.ts @@ -19,10 +19,12 @@ import * as zlib from 'zlib'; import { Call, WriteObject, WriteFlags } from './call-stream'; import { Channel } from './channel'; +import { ChannelOptions } from './channel-options'; import { CompressionAlgorithms } from './compression-algorithms'; +import { LogVerbosity } from './constants'; import { BaseFilter, Filter, FilterFactory } from './filter'; +import * as logging from './logging'; import { Metadata, MetadataValue } from './metadata'; -import { ChannelOptions } from './channel-options'; const CompressionAlgorithKeys = new Set(Object.keys(CompressionAlgorithms)); @@ -186,6 +188,8 @@ export class CompressionFilter extends BaseFilter implements Filter { if (isCompressionAlgorithmKey(compressionAlgorithmKey)) { this.defaultCompressionAlgorithm = CompressionAlgorithms[compressionAlgorithmKey]; this.sendCompression = getCompressionHandler(this.defaultCompressionAlgorithm); + } else { + logging.log(LogVerbosity.ERROR, 'Invalid value provided for grpc.default_compression_algorithm option'); } } From 7a31b4a65a2e2cc08231984602b84c02e336cd9a Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 26 Oct 2021 14:03:14 -0700 Subject: [PATCH 115/450] change test to use write instead of _write --- packages/grpc-js/test/test-server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/test/test-server.ts b/packages/grpc-js/test/test-server.ts index b6cffd81c..c0e7ebf5f 100644 --- a/packages/grpc-js/test/test-server.ts +++ b/packages/grpc-js/test/test-server.ts @@ -869,7 +869,7 @@ describe('Compressed requests', () => { done(); }); - bidiStream._write({ message: 'foo' }, '2', (err: any) => { + bidiStream.write({ message: 'foo' }, '2', (err: any) => { assert.ifError(err); timesRequested += 1; setTimeout(() => bidiStream.end(), 10); From 25a1806e114431bd355abe1264455fac7ed74bde Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 26 Oct 2021 14:09:09 -0700 Subject: [PATCH 116/450] change year in new copyright heade --- packages/grpc-js/src/compression-algorithms.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/src/compression-algorithms.ts b/packages/grpc-js/src/compression-algorithms.ts index 8ec283cf6..ccc38e76b 100644 --- a/packages/grpc-js/src/compression-algorithms.ts +++ b/packages/grpc-js/src/compression-algorithms.ts @@ -1,5 +1,5 @@ /* - * Copyright 2019 gRPC authors. + * Copyright 2021 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From d01ff794fc2f28a7194fc4cb5e996e13b071dd29 Mon Sep 17 00:00:00 2001 From: Robert M Date: Tue, 26 Oct 2021 14:21:58 -0700 Subject: [PATCH 117/450] Update error message for invalid default_compression_algorithm Co-authored-by: Michael Lumish --- packages/grpc-js/src/compression-filter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/src/compression-filter.ts b/packages/grpc-js/src/compression-filter.ts index 26b2836b6..9568b413d 100644 --- a/packages/grpc-js/src/compression-filter.ts +++ b/packages/grpc-js/src/compression-filter.ts @@ -189,7 +189,7 @@ export class CompressionFilter extends BaseFilter implements Filter { this.defaultCompressionAlgorithm = CompressionAlgorithms[compressionAlgorithmKey]; this.sendCompression = getCompressionHandler(this.defaultCompressionAlgorithm); } else { - logging.log(LogVerbosity.ERROR, 'Invalid value provided for grpc.default_compression_algorithm option'); + logging.log(LogVerbosity.ERROR, `Invalid value provided for grpc.default_compression_algorithm option: ${compressionAlgorithmKey}`); } } From 6ba008110b0ba80d0211c05e7fb5e2da712eb4ad Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 26 Oct 2021 14:25:21 -0700 Subject: [PATCH 118/450] only attempt to use custom compression filter when option value is provided --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/compression-filter.ts | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 9131d470f..893070948 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -59,7 +59,7 @@ }, "dependencies": { "@grpc/proto-loader": "^0.6.4", - "@types/node": "16.10.0", + "@types/node": ">=12.12.47", "@types/semver": "^7.3.9" }, "files": [ diff --git a/packages/grpc-js/src/compression-filter.ts b/packages/grpc-js/src/compression-filter.ts index 26b2836b6..ea81ed8cf 100644 --- a/packages/grpc-js/src/compression-filter.ts +++ b/packages/grpc-js/src/compression-filter.ts @@ -185,11 +185,13 @@ export class CompressionFilter extends BaseFilter implements Filter { super(); const compressionAlgorithmKey = channelOptions['grpc.default_compression_algorithm']; - if (isCompressionAlgorithmKey(compressionAlgorithmKey)) { - this.defaultCompressionAlgorithm = CompressionAlgorithms[compressionAlgorithmKey]; - this.sendCompression = getCompressionHandler(this.defaultCompressionAlgorithm); - } else { - logging.log(LogVerbosity.ERROR, 'Invalid value provided for grpc.default_compression_algorithm option'); + if (compressionAlgorithmKey !== undefined) { + if (isCompressionAlgorithmKey(compressionAlgorithmKey)) { + this.defaultCompressionAlgorithm = CompressionAlgorithms[compressionAlgorithmKey]; + this.sendCompression = getCompressionHandler(this.defaultCompressionAlgorithm); + } else { + logging.log(LogVerbosity.ERROR, 'Invalid value provided for grpc.default_compression_algorithm option'); + } } } From c9659b5158d7a26b6046e20127ba6dc3e844486d Mon Sep 17 00:00:00 2001 From: Robert Date: Thu, 28 Oct 2021 20:29:47 -0700 Subject: [PATCH 119/450] persist server supported encoding header across compression filter instances --- packages/grpc-js/src/compression-filter.ts | 25 ++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js/src/compression-filter.ts b/packages/grpc-js/src/compression-filter.ts index 090556381..e5f53334b 100644 --- a/packages/grpc-js/src/compression-filter.ts +++ b/packages/grpc-js/src/compression-filter.ts @@ -34,6 +34,10 @@ const isCompressionAlgorithmKey = (key: number | undefined): key is keyof typeof type CompressionAlgorithm = (typeof CompressionAlgorithms)[keyof typeof CompressionAlgorithms]; +type SharedCompressionFilterConfig = { + serverSupportedEncodingHeader?: string; +}; + abstract class CompressionHandler { protected abstract compressMessage(message: Buffer): Promise; protected abstract decompressMessage(data: Buffer): Promise; @@ -181,14 +185,25 @@ export class CompressionFilter extends BaseFilter implements Filter { private receiveCompression: CompressionHandler = new IdentityHandler(); private defaultCompressionAlgorithm: CompressionAlgorithm | undefined; - constructor(channelOptions: ChannelOptions) { + constructor(channelOptions: ChannelOptions, private sharedFilterConfig: SharedCompressionFilterConfig) { super(); + const serverSupportedEncodings = sharedFilterConfig.serverSupportedEncodingHeader?.split(','); const compressionAlgorithmKey = channelOptions['grpc.default_compression_algorithm']; if (compressionAlgorithmKey !== undefined) { if (isCompressionAlgorithmKey(compressionAlgorithmKey)) { - this.defaultCompressionAlgorithm = CompressionAlgorithms[compressionAlgorithmKey]; - this.sendCompression = getCompressionHandler(this.defaultCompressionAlgorithm); + const clientSelectedEncoding = CompressionAlgorithms[compressionAlgorithmKey]; + /** + * There are two possible situations here: + * 1) We don't have any info yet from the server about what compression it supports + * In that case we should just use what the client tells us to use + * 2) We've previously received a response from the server including a grpc-accept-encoding header + * In that case we only want to use the encoding chosen by the client if the server supports it + */ + if (!serverSupportedEncodings || serverSupportedEncodings.includes(clientSelectedEncoding)) { + this.defaultCompressionAlgorithm = clientSelectedEncoding; + this.sendCompression = getCompressionHandler(this.defaultCompressionAlgorithm); + } } else { logging.log(LogVerbosity.ERROR, `Invalid value provided for grpc.default_compression_algorithm option: ${compressionAlgorithmKey}`); } @@ -223,6 +238,7 @@ export class CompressionFilter extends BaseFilter implements Filter { * If not, reset the sendCompression filter and have it use the default IdentityHandler */ const serverSupportedEncodingsHeader = metadata.get('grpc-accept-encoding')[0] as string | undefined; if (serverSupportedEncodingsHeader) { + this.sharedFilterConfig.serverSupportedEncodingHeader = serverSupportedEncodingsHeader; const serverSupportedEncodings = serverSupportedEncodingsHeader.split(','); if ((this.sendCompression instanceof DeflateHandler && !serverSupportedEncodings.includes('deflate')) @@ -263,8 +279,9 @@ export class CompressionFilter extends BaseFilter implements Filter { export class CompressionFilterFactory implements FilterFactory { + private sharedFilterConfig: SharedCompressionFilterConfig = {}; constructor(private readonly channel: Channel, private readonly options: ChannelOptions) {} createFilter(callStream: Call): CompressionFilter { - return new CompressionFilter(this.options); + return new CompressionFilter(this.options, this.sharedFilterConfig); } } From 47bb8b669e6e28453f84092b6f3ea0c4ff81e64a Mon Sep 17 00:00:00 2001 From: Robert Date: Thu, 28 Oct 2021 20:36:29 -0700 Subject: [PATCH 120/450] move string split down to where it matters --- packages/grpc-js/src/compression-filter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/src/compression-filter.ts b/packages/grpc-js/src/compression-filter.ts index e5f53334b..a6428ce01 100644 --- a/packages/grpc-js/src/compression-filter.ts +++ b/packages/grpc-js/src/compression-filter.ts @@ -188,11 +188,11 @@ export class CompressionFilter extends BaseFilter implements Filter { constructor(channelOptions: ChannelOptions, private sharedFilterConfig: SharedCompressionFilterConfig) { super(); - const serverSupportedEncodings = sharedFilterConfig.serverSupportedEncodingHeader?.split(','); const compressionAlgorithmKey = channelOptions['grpc.default_compression_algorithm']; if (compressionAlgorithmKey !== undefined) { if (isCompressionAlgorithmKey(compressionAlgorithmKey)) { const clientSelectedEncoding = CompressionAlgorithms[compressionAlgorithmKey]; + const serverSupportedEncodings = sharedFilterConfig.serverSupportedEncodingHeader?.split(','); /** * There are two possible situations here: * 1) We don't have any info yet from the server about what compression it supports From 9150bdfd247b5f3215bac8b87097cf4691b262e3 Mon Sep 17 00:00:00 2001 From: Robert Date: Fri, 29 Oct 2021 19:19:09 -0700 Subject: [PATCH 121/450] default to identity header everywhere instead of leaving it undefined --- packages/grpc-js/src/compression-filter.ts | 24 +++++++++++-------- packages/grpc-js/src/server-call.ts | 27 ++++++++++++++-------- packages/grpc-js/src/server.ts | 10 ++++---- 3 files changed, 37 insertions(+), 24 deletions(-) diff --git a/packages/grpc-js/src/compression-filter.ts b/packages/grpc-js/src/compression-filter.ts index a6428ce01..cbdd35104 100644 --- a/packages/grpc-js/src/compression-filter.ts +++ b/packages/grpc-js/src/compression-filter.ts @@ -183,7 +183,7 @@ function getCompressionHandler(compressionName: string): CompressionHandler { export class CompressionFilter extends BaseFilter implements Filter { private sendCompression: CompressionHandler = new IdentityHandler(); private receiveCompression: CompressionHandler = new IdentityHandler(); - private defaultCompressionAlgorithm: CompressionAlgorithm | undefined; + private currentCompressionAlgorithm: CompressionAlgorithm = 'identity'; constructor(channelOptions: ChannelOptions, private sharedFilterConfig: SharedCompressionFilterConfig) { super(); @@ -201,8 +201,8 @@ export class CompressionFilter extends BaseFilter implements Filter { * In that case we only want to use the encoding chosen by the client if the server supports it */ if (!serverSupportedEncodings || serverSupportedEncodings.includes(clientSelectedEncoding)) { - this.defaultCompressionAlgorithm = clientSelectedEncoding; - this.sendCompression = getCompressionHandler(this.defaultCompressionAlgorithm); + this.currentCompressionAlgorithm = clientSelectedEncoding; + this.sendCompression = getCompressionHandler(this.currentCompressionAlgorithm); } } else { logging.log(LogVerbosity.ERROR, `Invalid value provided for grpc.default_compression_algorithm option: ${compressionAlgorithmKey}`); @@ -215,10 +215,11 @@ export class CompressionFilter extends BaseFilter implements Filter { headers.set('grpc-accept-encoding', 'identity,deflate,gzip'); headers.set('accept-encoding', 'identity'); - if (this.defaultCompressionAlgorithm && ['deflate', 'gzip'].includes(this.defaultCompressionAlgorithm)) { - headers.set('grpc-encoding', this.defaultCompressionAlgorithm); - } else { + // No need to send the header if it's "identity" - behavior is identical; save the bandwidth + if (this.currentCompressionAlgorithm === 'identity') { headers.remove('grpc-encoding'); + } else { + headers.set('grpc-encoding', this.currentCompressionAlgorithm); } return headers; @@ -255,10 +256,13 @@ 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; - const compress = - resolvedMessage.flags === undefined - ? !(this.sendCompression instanceof IdentityHandler) - : (resolvedMessage.flags & WriteFlags.NoCompress) === 0; + let compress: boolean; + if (this.sendCompression instanceof IdentityHandler) { + compress = false; + } else { + compress = ((resolvedMessage.flags ?? 0) & WriteFlags.NoCompress) === 0; + } + return { message: await this.sendCompression.writeMessage( resolvedMessage.message, diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index d3c622b5c..b340b3446 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -138,7 +138,7 @@ export class ServerReadableStreamImpl private call: Http2ServerCallStream, public metadata: Metadata, public deserialize: Deserialize, - encoding?: string + encoding: string ) { super({ objectMode: true }); this.cancelled = false; @@ -253,7 +253,7 @@ export class ServerDuplexStreamImpl public metadata: Metadata, public serialize: Serialize, public deserialize: Deserialize, - encoding?: string + encoding: string ) { super({ objectMode: true }); this.cancelled = false; @@ -442,7 +442,7 @@ export class Http2ServerCallStream< return this.cancelled; } - private getDecompressedMessage(message: Buffer, encoding?: string) { + private getDecompressedMessage(message: Buffer, encoding: string) { switch (encoding) { case 'deflate': { return new Promise((resolve, reject) => { @@ -477,9 +477,18 @@ export class Http2ServerCallStream< }); }); } - - default: + + case 'identity': { return Promise.resolve(message); + } + + default: { + this.sendError({ + code: Status.UNIMPLEMENTED, + details: `Received "grpc-encoding" header "${encoding}", which is not supported`, + }); + return Promise.resolve(); + } } } @@ -533,7 +542,7 @@ export class Http2ServerCallStream< return metadata; } - receiveUnaryMessage(encoding?: string): Promise { + receiveUnaryMessage(encoding: string): Promise { return new Promise((resolve, reject) => { const stream = this.stream; const chunks: Buffer[] = []; @@ -561,7 +570,7 @@ export class Http2ServerCallStream< this.emit('receiveMessage'); const compressed = requestBytes.readUInt8(0) === 1; - const compressedMessageEncoding = compressed ? encoding : undefined; + const compressedMessageEncoding = compressed ? encoding : 'identity'; const decompressedMessage = await this.getDecompressedMessage(requestBytes, compressedMessageEncoding); // Encountered an error with decompression; it'll already have been propogated back @@ -729,7 +738,7 @@ export class Http2ServerCallStream< readable: | ServerReadableStream | ServerDuplexStream, - encoding?: string + encoding: string ) { const decoder = new StreamDecoder(); @@ -750,7 +759,7 @@ export class Http2ServerCallStream< this.emit('receiveMessage'); const compressed = message.readUInt8(0) === 1; - const compressedMessageEncoding = compressed ? encoding : undefined; + const compressedMessageEncoding = compressed ? encoding : 'identity'; const decompressedMessage = await this.getDecompressedMessage(message, compressedMessageEncoding); // Encountered an error with decompression; it'll already have been propogated back diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index b69a795e9..a83363674 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -778,7 +778,7 @@ export class Server { }); } const metadata = call.receiveMetadata(headers); - const encoding = metadata.get('grpc-encoding')[0] as string | undefined; + const encoding = (metadata.get('grpc-encoding')[0] as string | undefined) ?? 'identity'; metadata.remove('grpc-encoding'); switch (handler.type) { @@ -863,7 +863,7 @@ async function handleUnary( call: Http2ServerCallStream, handler: UnaryHandler, metadata: Metadata, - encoding?: string + encoding: string ): Promise { const request = await call.receiveUnaryMessage(encoding); @@ -894,7 +894,7 @@ function handleClientStreaming( call: Http2ServerCallStream, handler: ClientStreamingHandler, metadata: Metadata, - encoding?: string + encoding: string ): void { const stream = new ServerReadableStreamImpl( call, @@ -925,7 +925,7 @@ async function handleServerStreaming( call: Http2ServerCallStream, handler: ServerStreamingHandler, metadata: Metadata, - encoding?: string + encoding: string ): Promise { const request = await call.receiveUnaryMessage(encoding); @@ -947,7 +947,7 @@ function handleBidiStreaming( call: Http2ServerCallStream, handler: BidiStreamingHandler, metadata: Metadata, - encoding?: string + encoding: string ): void { const stream = new ServerDuplexStreamImpl( call, From 692ee3c03faab8fcbd3dfaa70bff57e32c739c3d Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 1 Nov 2021 14:23:53 -0700 Subject: [PATCH 122/450] grpc-js-xds: Switch from udpa to xds submodule --- .gitmodules | 6 +- packages/grpc-js-xds/deps/udpa | 1 - packages/grpc-js-xds/deps/xds | 1 + packages/grpc-js-xds/package.json | 2 +- packages/grpc-js-xds/src/generated/cluster.ts | 9 +++ packages/grpc-js-xds/src/generated/fault.ts | 9 +++ .../generated/google/protobuf/FieldOptions.ts | 3 + .../generated/google/protobuf/FileOptions.ts | 3 + .../google/protobuf/MessageOptions.ts | 3 + .../src/generated/http_connection_manager.ts | 9 +++ .../grpc-js-xds/src/generated/listener.ts | 9 +++ packages/grpc-js-xds/src/generated/route.ts | 9 +++ .../grpc-js-xds/src/generated/typed_struct.ts | 7 ++ .../annotations/FieldMigrateAnnotation.ts | 2 +- .../annotations/FieldSecurityAnnotation.ts | 2 +- .../udpa/annotations/FileMigrateAnnotation.ts | 2 +- .../udpa/annotations/MigrateAnnotation.ts | 2 +- .../udpa/annotations/PackageVersionStatus.ts | 2 +- .../udpa/annotations/StatusAnnotation.ts | 2 +- .../udpa/annotations/VersioningAnnotation.ts | 2 +- .../src/generated/udpa/type/v1/TypedStruct.ts | 2 +- .../annotations/v3/FieldStatusAnnotation.ts | 16 ++++ .../annotations/v3/FileStatusAnnotation.ts | 16 ++++ .../annotations/v3/MessageStatusAnnotation.ts | 16 ++++ .../annotations/v3/PackageVersionStatus.ts | 21 +++++ .../xds/annotations/v3/StatusAnnotation.ts | 25 ++++++ .../src/generated/xds/core/v3/Authority.ts | 2 +- .../generated/xds/core/v3/CollectionEntry.ts | 2 +- .../generated/xds/core/v3/ContextParams.ts | 2 +- .../generated/xds/core/v3/ResourceLocator.ts | 4 +- .../src/generated/xds/type/v3/TypedStruct.ts | 77 +++++++++++++++++++ packages/grpc-js-xds/src/http-filter.ts | 17 ++-- .../src/http-filter/fault-injection-filter.ts | 2 +- packages/grpc-js-xds/src/resources.ts | 2 +- packages/grpc-js-xds/src/xds-client.ts | 2 +- 35 files changed, 263 insertions(+), 28 deletions(-) delete mode 160000 packages/grpc-js-xds/deps/udpa create mode 160000 packages/grpc-js-xds/deps/xds create mode 100644 packages/grpc-js-xds/src/generated/xds/annotations/v3/FieldStatusAnnotation.ts create mode 100644 packages/grpc-js-xds/src/generated/xds/annotations/v3/FileStatusAnnotation.ts create mode 100644 packages/grpc-js-xds/src/generated/xds/annotations/v3/MessageStatusAnnotation.ts create mode 100644 packages/grpc-js-xds/src/generated/xds/annotations/v3/PackageVersionStatus.ts create mode 100644 packages/grpc-js-xds/src/generated/xds/annotations/v3/StatusAnnotation.ts create mode 100644 packages/grpc-js-xds/src/generated/xds/type/v3/TypedStruct.ts diff --git a/.gitmodules b/.gitmodules index d3c1ebaf6..f54fa6afc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,12 +10,12 @@ [submodule "packages/grpc-js-xds/deps/envoy-api"] path = packages/grpc-js-xds/deps/envoy-api url = https://github.com/envoyproxy/data-plane-api.git -[submodule "packages/grpc-js-xds/deps/udpa"] - path = packages/grpc-js-xds/deps/udpa - url = https://github.com/cncf/udpa.git [submodule "packages/grpc-js-xds/deps/googleapis"] path = packages/grpc-js-xds/deps/googleapis url = https://github.com/googleapis/googleapis.git [submodule "packages/grpc-js-xds/deps/protoc-gen-validate"] path = packages/grpc-js-xds/deps/protoc-gen-validate url = https://github.com/envoyproxy/protoc-gen-validate.git +[submodule "packages/grpc-js-xds/deps/xds"] + path = packages/grpc-js-xds/deps/xds + url = https://github.com/cncf/xds.git diff --git a/packages/grpc-js-xds/deps/udpa b/packages/grpc-js-xds/deps/udpa deleted file mode 160000 index cc1b757b3..000000000 --- a/packages/grpc-js-xds/deps/udpa +++ /dev/null @@ -1 +0,0 @@ -Subproject commit cc1b757b3eddccaaaf0743cbb107742bb7e3ee4f diff --git a/packages/grpc-js-xds/deps/xds b/packages/grpc-js-xds/deps/xds new file mode 160000 index 000000000..cb28da345 --- /dev/null +++ b/packages/grpc-js-xds/deps/xds @@ -0,0 +1 @@ +Subproject commit cb28da3451f158a947dfc45090fe92b07b243bc1 diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index fefc0f33b..9be41a0a4 100644 --- a/packages/grpc-js-xds/package.json +++ b/packages/grpc-js-xds/package.json @@ -12,7 +12,7 @@ "prepare": "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/udpa/ deps/googleapis/ deps/protoc-gen-validate/ -O src/generated/ --grpcLib @grpc/grpc-js envoy/service/discovery/v2/ads.proto envoy/service/load_stats/v2/lrs.proto 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 envoy/extensions/filters/http/fault/v3/fault.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/v2/ads.proto envoy/service/load_stats/v2/lrs.proto 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", "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" }, "repository": { diff --git a/packages/grpc-js-xds/src/generated/cluster.ts b/packages/grpc-js-xds/src/generated/cluster.ts index bc4465a30..6c2f7aa6f 100644 --- a/packages/grpc-js-xds/src/generated/cluster.ts +++ b/packages/grpc-js-xds/src/generated/cluster.ts @@ -189,6 +189,15 @@ export interface ProtoGrpcType { UInt64Rules: MessageTypeDefinition } xds: { + annotations: { + v3: { + FieldStatusAnnotation: MessageTypeDefinition + FileStatusAnnotation: MessageTypeDefinition + MessageStatusAnnotation: MessageTypeDefinition + PackageVersionStatus: EnumTypeDefinition + StatusAnnotation: MessageTypeDefinition + } + } core: { v3: { Authority: MessageTypeDefinition diff --git a/packages/grpc-js-xds/src/generated/fault.ts b/packages/grpc-js-xds/src/generated/fault.ts index 6eefcdfbd..0f60fc224 100644 --- a/packages/grpc-js-xds/src/generated/fault.ts +++ b/packages/grpc-js-xds/src/generated/fault.ts @@ -210,6 +210,15 @@ export interface ProtoGrpcType { UInt64Rules: MessageTypeDefinition } xds: { + annotations: { + v3: { + FieldStatusAnnotation: MessageTypeDefinition + FileStatusAnnotation: MessageTypeDefinition + MessageStatusAnnotation: MessageTypeDefinition + PackageVersionStatus: EnumTypeDefinition + StatusAnnotation: MessageTypeDefinition + } + } core: { v3: { Authority: MessageTypeDefinition 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 028e14b74..91af8a985 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/FieldOptions.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/FieldOptions.ts @@ -3,6 +3,7 @@ import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; import type { FieldRules as _validate_FieldRules, FieldRules__Output as _validate_FieldRules__Output } from '../../validate/FieldRules'; import type { FieldMigrateAnnotation as _udpa_annotations_FieldMigrateAnnotation, FieldMigrateAnnotation__Output as _udpa_annotations_FieldMigrateAnnotation__Output } from '../../udpa/annotations/FieldMigrateAnnotation'; +import type { FieldStatusAnnotation as _xds_annotations_v3_FieldStatusAnnotation, FieldStatusAnnotation__Output as _xds_annotations_v3_FieldStatusAnnotation__Output } from '../../xds/annotations/v3/FieldStatusAnnotation'; // Original file: null @@ -32,6 +33,7 @@ export interface FieldOptions { '.udpa.annotations.sensitive'?: (boolean); '.udpa.annotations.field_migrate'?: (_udpa_annotations_FieldMigrateAnnotation | null); '.envoy.annotations.disallowed_by_default'?: (boolean); + '.xds.annotations.v3.field_status'?: (_xds_annotations_v3_FieldStatusAnnotation | null); } export interface FieldOptions__Output { @@ -46,4 +48,5 @@ export interface FieldOptions__Output { '.udpa.annotations.sensitive': (boolean); '.udpa.annotations.field_migrate': (_udpa_annotations_FieldMigrateAnnotation__Output | null); '.envoy.annotations.disallowed_by_default': (boolean); + '.xds.annotations.v3.field_status': (_xds_annotations_v3_FieldStatusAnnotation__Output | null); } 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 b046c3ad3..48a376cd0 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/FileOptions.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/FileOptions.ts @@ -3,6 +3,7 @@ import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; import type { FileMigrateAnnotation as _udpa_annotations_FileMigrateAnnotation, FileMigrateAnnotation__Output as _udpa_annotations_FileMigrateAnnotation__Output } from '../../udpa/annotations/FileMigrateAnnotation'; import type { StatusAnnotation as _udpa_annotations_StatusAnnotation, StatusAnnotation__Output as _udpa_annotations_StatusAnnotation__Output } from '../../udpa/annotations/StatusAnnotation'; +import type { FileStatusAnnotation as _xds_annotations_v3_FileStatusAnnotation, FileStatusAnnotation__Output as _xds_annotations_v3_FileStatusAnnotation__Output } from '../../xds/annotations/v3/FileStatusAnnotation'; // Original file: null @@ -30,6 +31,7 @@ export interface FileOptions { 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; '.udpa.annotations.file_migrate'?: (_udpa_annotations_FileMigrateAnnotation | null); '.udpa.annotations.file_status'?: (_udpa_annotations_StatusAnnotation | null); + '.xds.annotations.v3.file_status'?: (_xds_annotations_v3_FileStatusAnnotation | null); } export interface FileOptions__Output { @@ -50,4 +52,5 @@ export interface FileOptions__Output { 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; '.udpa.annotations.file_migrate': (_udpa_annotations_FileMigrateAnnotation__Output | null); '.udpa.annotations.file_status': (_udpa_annotations_StatusAnnotation__Output | null); + '.xds.annotations.v3.file_status': (_xds_annotations_v3_FileStatusAnnotation__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/MessageOptions.ts b/packages/grpc-js-xds/src/generated/google/protobuf/MessageOptions.ts index 9dc521214..71d8c855b 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/MessageOptions.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/MessageOptions.ts @@ -3,6 +3,7 @@ import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; import type { VersioningAnnotation as _udpa_annotations_VersioningAnnotation, VersioningAnnotation__Output as _udpa_annotations_VersioningAnnotation__Output } from '../../udpa/annotations/VersioningAnnotation'; import type { MigrateAnnotation as _udpa_annotations_MigrateAnnotation, MigrateAnnotation__Output as _udpa_annotations_MigrateAnnotation__Output } from '../../udpa/annotations/MigrateAnnotation'; +import type { MessageStatusAnnotation as _xds_annotations_v3_MessageStatusAnnotation, MessageStatusAnnotation__Output as _xds_annotations_v3_MessageStatusAnnotation__Output } from '../../xds/annotations/v3/MessageStatusAnnotation'; export interface MessageOptions { 'messageSetWireFormat'?: (boolean); @@ -13,6 +14,7 @@ export interface MessageOptions { '.validate.disabled'?: (boolean); '.udpa.annotations.versioning'?: (_udpa_annotations_VersioningAnnotation | null); '.udpa.annotations.message_migrate'?: (_udpa_annotations_MigrateAnnotation | null); + '.xds.annotations.v3.message_status'?: (_xds_annotations_v3_MessageStatusAnnotation | null); } export interface MessageOptions__Output { @@ -24,4 +26,5 @@ export interface MessageOptions__Output { '.validate.disabled': (boolean); '.udpa.annotations.versioning': (_udpa_annotations_VersioningAnnotation__Output | null); '.udpa.annotations.message_migrate': (_udpa_annotations_MigrateAnnotation__Output | null); + '.xds.annotations.v3.message_status': (_xds_annotations_v3_MessageStatusAnnotation__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/http_connection_manager.ts b/packages/grpc-js-xds/src/generated/http_connection_manager.ts index bb4e80360..351e65400 100644 --- a/packages/grpc-js-xds/src/generated/http_connection_manager.ts +++ b/packages/grpc-js-xds/src/generated/http_connection_manager.ts @@ -250,6 +250,15 @@ export interface ProtoGrpcType { UInt64Rules: MessageTypeDefinition } xds: { + annotations: { + v3: { + FieldStatusAnnotation: MessageTypeDefinition + FileStatusAnnotation: MessageTypeDefinition + MessageStatusAnnotation: MessageTypeDefinition + PackageVersionStatus: EnumTypeDefinition + StatusAnnotation: MessageTypeDefinition + } + } core: { v3: { Authority: MessageTypeDefinition diff --git a/packages/grpc-js-xds/src/generated/listener.ts b/packages/grpc-js-xds/src/generated/listener.ts index cf7297a5b..aac080a90 100644 --- a/packages/grpc-js-xds/src/generated/listener.ts +++ b/packages/grpc-js-xds/src/generated/listener.ts @@ -228,6 +228,15 @@ export interface ProtoGrpcType { UInt64Rules: MessageTypeDefinition } xds: { + annotations: { + v3: { + FieldStatusAnnotation: MessageTypeDefinition + FileStatusAnnotation: MessageTypeDefinition + MessageStatusAnnotation: MessageTypeDefinition + PackageVersionStatus: EnumTypeDefinition + StatusAnnotation: MessageTypeDefinition + } + } core: { v3: { Authority: MessageTypeDefinition diff --git a/packages/grpc-js-xds/src/generated/route.ts b/packages/grpc-js-xds/src/generated/route.ts index 702395d19..67b9c5ce4 100644 --- a/packages/grpc-js-xds/src/generated/route.ts +++ b/packages/grpc-js-xds/src/generated/route.ts @@ -192,6 +192,15 @@ export interface ProtoGrpcType { UInt64Rules: MessageTypeDefinition } xds: { + annotations: { + v3: { + FieldStatusAnnotation: MessageTypeDefinition + FileStatusAnnotation: MessageTypeDefinition + MessageStatusAnnotation: MessageTypeDefinition + PackageVersionStatus: EnumTypeDefinition + StatusAnnotation: MessageTypeDefinition + } + } core: { v3: { Authority: MessageTypeDefinition diff --git a/packages/grpc-js-xds/src/generated/typed_struct.ts b/packages/grpc-js-xds/src/generated/typed_struct.ts index 47abe063c..e8dca13d5 100644 --- a/packages/grpc-js-xds/src/generated/typed_struct.ts +++ b/packages/grpc-js-xds/src/generated/typed_struct.ts @@ -70,5 +70,12 @@ export interface ProtoGrpcType { UInt32Rules: MessageTypeDefinition UInt64Rules: MessageTypeDefinition } + xds: { + type: { + v3: { + TypedStruct: MessageTypeDefinition + } + } + } } diff --git a/packages/grpc-js-xds/src/generated/udpa/annotations/FieldMigrateAnnotation.ts b/packages/grpc-js-xds/src/generated/udpa/annotations/FieldMigrateAnnotation.ts index 1ad015b25..4cbe9fdcb 100644 --- a/packages/grpc-js-xds/src/generated/udpa/annotations/FieldMigrateAnnotation.ts +++ b/packages/grpc-js-xds/src/generated/udpa/annotations/FieldMigrateAnnotation.ts @@ -1,4 +1,4 @@ -// Original file: deps/udpa/udpa/annotations/migrate.proto +// Original file: deps/xds/udpa/annotations/migrate.proto export interface FieldMigrateAnnotation { diff --git a/packages/grpc-js-xds/src/generated/udpa/annotations/FieldSecurityAnnotation.ts b/packages/grpc-js-xds/src/generated/udpa/annotations/FieldSecurityAnnotation.ts index 13d48b5ce..9c25fb84e 100644 --- a/packages/grpc-js-xds/src/generated/udpa/annotations/FieldSecurityAnnotation.ts +++ b/packages/grpc-js-xds/src/generated/udpa/annotations/FieldSecurityAnnotation.ts @@ -1,4 +1,4 @@ -// Original file: deps/udpa/udpa/annotations/security.proto +// Original file: deps/xds/udpa/annotations/security.proto /** diff --git a/packages/grpc-js-xds/src/generated/udpa/annotations/FileMigrateAnnotation.ts b/packages/grpc-js-xds/src/generated/udpa/annotations/FileMigrateAnnotation.ts index b7ef7c21d..95d29245d 100644 --- a/packages/grpc-js-xds/src/generated/udpa/annotations/FileMigrateAnnotation.ts +++ b/packages/grpc-js-xds/src/generated/udpa/annotations/FileMigrateAnnotation.ts @@ -1,4 +1,4 @@ -// Original file: deps/udpa/udpa/annotations/migrate.proto +// Original file: deps/xds/udpa/annotations/migrate.proto export interface FileMigrateAnnotation { diff --git a/packages/grpc-js-xds/src/generated/udpa/annotations/MigrateAnnotation.ts b/packages/grpc-js-xds/src/generated/udpa/annotations/MigrateAnnotation.ts index e3fdcaa99..16def9f28 100644 --- a/packages/grpc-js-xds/src/generated/udpa/annotations/MigrateAnnotation.ts +++ b/packages/grpc-js-xds/src/generated/udpa/annotations/MigrateAnnotation.ts @@ -1,4 +1,4 @@ -// Original file: deps/udpa/udpa/annotations/migrate.proto +// Original file: deps/xds/udpa/annotations/migrate.proto export interface MigrateAnnotation { 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 c60c3f984..d0e181aa5 100644 --- a/packages/grpc-js-xds/src/generated/udpa/annotations/PackageVersionStatus.ts +++ b/packages/grpc-js-xds/src/generated/udpa/annotations/PackageVersionStatus.ts @@ -1,4 +1,4 @@ -// Original file: deps/udpa/udpa/annotations/status.proto +// Original file: deps/xds/udpa/annotations/status.proto export enum 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 7b33ce9c8..f01b45063 100644 --- a/packages/grpc-js-xds/src/generated/udpa/annotations/StatusAnnotation.ts +++ b/packages/grpc-js-xds/src/generated/udpa/annotations/StatusAnnotation.ts @@ -1,4 +1,4 @@ -// Original file: deps/udpa/udpa/annotations/status.proto +// Original file: deps/xds/udpa/annotations/status.proto import type { PackageVersionStatus as _udpa_annotations_PackageVersionStatus } from '../../udpa/annotations/PackageVersionStatus'; diff --git a/packages/grpc-js-xds/src/generated/udpa/annotations/VersioningAnnotation.ts b/packages/grpc-js-xds/src/generated/udpa/annotations/VersioningAnnotation.ts index 1a3d09dc8..7a517a06c 100644 --- a/packages/grpc-js-xds/src/generated/udpa/annotations/VersioningAnnotation.ts +++ b/packages/grpc-js-xds/src/generated/udpa/annotations/VersioningAnnotation.ts @@ -1,4 +1,4 @@ -// Original file: deps/udpa/udpa/annotations/versioning.proto +// Original file: deps/xds/udpa/annotations/versioning.proto export interface VersioningAnnotation { diff --git a/packages/grpc-js-xds/src/generated/udpa/type/v1/TypedStruct.ts b/packages/grpc-js-xds/src/generated/udpa/type/v1/TypedStruct.ts index 435872808..b080c6348 100644 --- a/packages/grpc-js-xds/src/generated/udpa/type/v1/TypedStruct.ts +++ b/packages/grpc-js-xds/src/generated/udpa/type/v1/TypedStruct.ts @@ -1,4 +1,4 @@ -// Original file: deps/udpa/udpa/type/v1/typed_struct.proto +// Original file: deps/xds/udpa/type/v1/typed_struct.proto import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../google/protobuf/Struct'; diff --git a/packages/grpc-js-xds/src/generated/xds/annotations/v3/FieldStatusAnnotation.ts b/packages/grpc-js-xds/src/generated/xds/annotations/v3/FieldStatusAnnotation.ts new file mode 100644 index 000000000..744e13837 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/xds/annotations/v3/FieldStatusAnnotation.ts @@ -0,0 +1,16 @@ +// Original file: deps/xds/xds/annotations/v3/status.proto + + +export interface FieldStatusAnnotation { + /** + * The entity is work-in-progress and subject to breaking changes. + */ + 'work_in_progress'?: (boolean); +} + +export interface FieldStatusAnnotation__Output { + /** + * The entity is work-in-progress and subject to breaking changes. + */ + 'work_in_progress': (boolean); +} diff --git a/packages/grpc-js-xds/src/generated/xds/annotations/v3/FileStatusAnnotation.ts b/packages/grpc-js-xds/src/generated/xds/annotations/v3/FileStatusAnnotation.ts new file mode 100644 index 000000000..cbc3ab3f9 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/xds/annotations/v3/FileStatusAnnotation.ts @@ -0,0 +1,16 @@ +// Original file: deps/xds/xds/annotations/v3/status.proto + + +export interface FileStatusAnnotation { + /** + * The entity is work-in-progress and subject to breaking changes. + */ + 'work_in_progress'?: (boolean); +} + +export interface FileStatusAnnotation__Output { + /** + * The entity is work-in-progress and subject to breaking changes. + */ + 'work_in_progress': (boolean); +} diff --git a/packages/grpc-js-xds/src/generated/xds/annotations/v3/MessageStatusAnnotation.ts b/packages/grpc-js-xds/src/generated/xds/annotations/v3/MessageStatusAnnotation.ts new file mode 100644 index 000000000..f403f6506 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/xds/annotations/v3/MessageStatusAnnotation.ts @@ -0,0 +1,16 @@ +// Original file: deps/xds/xds/annotations/v3/status.proto + + +export interface MessageStatusAnnotation { + /** + * The entity is work-in-progress and subject to breaking changes. + */ + 'work_in_progress'?: (boolean); +} + +export interface MessageStatusAnnotation__Output { + /** + * The entity is work-in-progress and subject to breaking changes. + */ + 'work_in_progress': (boolean); +} 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 new file mode 100644 index 000000000..e76e2848f --- /dev/null +++ b/packages/grpc-js-xds/src/generated/xds/annotations/v3/PackageVersionStatus.ts @@ -0,0 +1,21 @@ +// Original file: deps/xds/xds/annotations/v3/status.proto + +export enum 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, +} 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 new file mode 100644 index 000000000..58efbd8f7 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/xds/annotations/v3/StatusAnnotation.ts @@ -0,0 +1,25 @@ +// Original file: deps/xds/xds/annotations/v3/status.proto + +import type { PackageVersionStatus as _xds_annotations_v3_PackageVersionStatus } from '../../../xds/annotations/v3/PackageVersionStatus'; + +export interface StatusAnnotation { + /** + * The entity is work-in-progress and subject to breaking changes. + */ + 'work_in_progress'?: (boolean); + /** + * The entity belongs to a package with the given version status. + */ + 'package_version_status'?: (_xds_annotations_v3_PackageVersionStatus | keyof typeof _xds_annotations_v3_PackageVersionStatus); +} + +export interface StatusAnnotation__Output { + /** + * The entity is work-in-progress and subject to breaking changes. + */ + 'work_in_progress': (boolean); + /** + * The entity belongs to a package with the given version status. + */ + 'package_version_status': (keyof typeof _xds_annotations_v3_PackageVersionStatus); +} diff --git a/packages/grpc-js-xds/src/generated/xds/core/v3/Authority.ts b/packages/grpc-js-xds/src/generated/xds/core/v3/Authority.ts index 8e9211838..9505731d7 100644 --- a/packages/grpc-js-xds/src/generated/xds/core/v3/Authority.ts +++ b/packages/grpc-js-xds/src/generated/xds/core/v3/Authority.ts @@ -1,4 +1,4 @@ -// Original file: deps/udpa/xds/core/v3/authority.proto +// Original file: deps/xds/xds/core/v3/authority.proto /** diff --git a/packages/grpc-js-xds/src/generated/xds/core/v3/CollectionEntry.ts b/packages/grpc-js-xds/src/generated/xds/core/v3/CollectionEntry.ts index 8d583d961..5d2ce9721 100644 --- a/packages/grpc-js-xds/src/generated/xds/core/v3/CollectionEntry.ts +++ b/packages/grpc-js-xds/src/generated/xds/core/v3/CollectionEntry.ts @@ -1,4 +1,4 @@ -// Original file: deps/udpa/xds/core/v3/collection_entry.proto +// Original file: deps/xds/xds/core/v3/collection_entry.proto import type { ResourceLocator as _xds_core_v3_ResourceLocator, ResourceLocator__Output as _xds_core_v3_ResourceLocator__Output } from '../../../xds/core/v3/ResourceLocator'; import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any'; diff --git a/packages/grpc-js-xds/src/generated/xds/core/v3/ContextParams.ts b/packages/grpc-js-xds/src/generated/xds/core/v3/ContextParams.ts index f9c57249c..19a8a99bb 100644 --- a/packages/grpc-js-xds/src/generated/xds/core/v3/ContextParams.ts +++ b/packages/grpc-js-xds/src/generated/xds/core/v3/ContextParams.ts @@ -1,4 +1,4 @@ -// Original file: deps/udpa/xds/core/v3/context_params.proto +// Original file: deps/xds/xds/core/v3/context_params.proto /** 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 2b314d8bb..bb1f822b8 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 @@ -1,4 +1,4 @@ -// Original file: deps/udpa/xds/core/v3/resource_locator.proto +// Original file: deps/xds/xds/core/v3/resource_locator.proto import type { ContextParams as _xds_core_v3_ContextParams, ContextParams__Output as _xds_core_v3_ContextParams__Output } from '../../../xds/core/v3/ContextParams'; import type { ResourceLocator as _xds_core_v3_ResourceLocator, ResourceLocator__Output as _xds_core_v3_ResourceLocator__Output } from '../../../xds/core/v3/ResourceLocator'; @@ -95,7 +95,7 @@ export interface _xds_core_v3_ResourceLocator_Directive__Output { 'directive': "alt"|"entry"; } -// Original file: deps/udpa/xds/core/v3/resource_locator.proto +// Original file: deps/xds/xds/core/v3/resource_locator.proto export enum _xds_core_v3_ResourceLocator_Scheme { XDSTP = 0, diff --git a/packages/grpc-js-xds/src/generated/xds/type/v3/TypedStruct.ts b/packages/grpc-js-xds/src/generated/xds/type/v3/TypedStruct.ts new file mode 100644 index 000000000..a0df831d2 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/xds/type/v3/TypedStruct.ts @@ -0,0 +1,77 @@ +// Original file: deps/xds/xds/type/v3/typed_struct.proto + +import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../google/protobuf/Struct'; + +/** + * A TypedStruct contains an arbitrary JSON serialized protocol buffer message with a URL that + * describes the type of the serialized message. This is very similar to google.protobuf.Any, + * instead of having protocol buffer binary, this employs google.protobuf.Struct as value. + * + * This message is intended to be embedded inside Any, so it shouldn't be directly referred + * from other UDPA messages. + * + * When packing an opaque extension config, packing the expected type into Any is preferred + * wherever possible for its efficiency. TypedStruct should be used only if a proto descriptor + * is not available, for example if: + * - A control plane sends opaque message that is originally from external source in human readable + * format such as JSON or YAML. + * - The control plane doesn't have the knowledge of the protocol buffer schema hence it cannot + * serialize the message in protocol buffer binary format. + * - The DPLB doesn't have have the knowledge of the protocol buffer schema its plugin or extension + * uses. This has to be indicated in the DPLB capability negotiation. + * + * When a DPLB receives a TypedStruct in Any, it should: + * - Check if the type_url of the TypedStruct matches the type the extension expects. + * - Convert value to the type described in type_url and perform validation. + * TODO(lizan): Figure out how TypeStruct should be used with DPLB extensions that doesn't link + * protobuf descriptor with DPLB itself, (e.g. gRPC LB Plugin, Envoy WASM extensions). + */ +export interface TypedStruct { + /** + * A URL that uniquely identifies the type of the serialize protocol buffer message. + * This has same semantics and format described in google.protobuf.Any: + * https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto + */ + 'type_url'?: (string); + /** + * A JSON representation of the above specified type. + */ + 'value'?: (_google_protobuf_Struct | null); +} + +/** + * A TypedStruct contains an arbitrary JSON serialized protocol buffer message with a URL that + * describes the type of the serialized message. This is very similar to google.protobuf.Any, + * instead of having protocol buffer binary, this employs google.protobuf.Struct as value. + * + * This message is intended to be embedded inside Any, so it shouldn't be directly referred + * from other UDPA messages. + * + * When packing an opaque extension config, packing the expected type into Any is preferred + * wherever possible for its efficiency. TypedStruct should be used only if a proto descriptor + * is not available, for example if: + * - A control plane sends opaque message that is originally from external source in human readable + * format such as JSON or YAML. + * - The control plane doesn't have the knowledge of the protocol buffer schema hence it cannot + * serialize the message in protocol buffer binary format. + * - The DPLB doesn't have have the knowledge of the protocol buffer schema its plugin or extension + * uses. This has to be indicated in the DPLB capability negotiation. + * + * When a DPLB receives a TypedStruct in Any, it should: + * - Check if the type_url of the TypedStruct matches the type the extension expects. + * - Convert value to the type described in type_url and perform validation. + * TODO(lizan): Figure out how TypeStruct should be used with DPLB extensions that doesn't link + * protobuf descriptor with DPLB itself, (e.g. gRPC LB Plugin, Envoy WASM extensions). + */ +export interface TypedStruct__Output { + /** + * A URL that uniquely identifies the type of the serialize protocol buffer message. + * This has same semantics and format described in google.protobuf.Any: + * https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto + */ + 'type_url': (string); + /** + * A JSON representation of the above specified type. + */ + 'value': (_google_protobuf_Struct__Output | null); +} diff --git a/packages/grpc-js-xds/src/http-filter.ts b/packages/grpc-js-xds/src/http-filter.ts index a00cde5db..29ce5958f 100644 --- a/packages/grpc-js-xds/src/http-filter.ts +++ b/packages/grpc-js-xds/src/http-filter.ts @@ -20,7 +20,7 @@ import { experimental, logVerbosity } from '@grpc/grpc-js'; import { Any__Output } from './generated/google/protobuf/Any'; import Filter = experimental.Filter; import FilterFactory = experimental.FilterFactory; -import { TypedStruct__Output } from './generated/udpa/type/v1/TypedStruct'; +import { TypedStruct__Output as TypedStruct__Output } from './generated/xds/type/v3/TypedStruct'; import { FilterConfig__Output } from './generated/envoy/config/route/v3/FilterConfig'; import { HttpFilter__Output } from './generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpFilter'; @@ -30,19 +30,22 @@ function trace(text: string): void { experimental.trace(logVerbosity.DEBUG, TRACER_NAME, text); } -const TYPED_STRUCT_URL = 'type.googleapis.com/udpa.type.v1.TypedStruct'; -const TYPED_STRUCT_NAME = 'udpa.type.v1.TypedStruct'; +const TYPED_STRUCT_UDPA_URL = 'type.googleapis.com/udpa.type.v1.TypedStruct'; +const TYPED_STRUCT_UDPA_NAME = 'udpa.type.v1.TypedStruct'; +const TYPED_STRUCT_XDS_URL = 'type.googleapis.com/xds.type.v3.TypedStruct'; +const TYPED_STRUCT_XDS_NAME = 'xds.type.v3.TypedStruct'; const FILTER_CONFIG_URL = 'type.googleapis.com/envoy.config.route.v3.FilterConfig'; const FILTER_CONFIG_NAME = 'envoy.config.route.v3.FilterConfig'; const resourceRoot = loadProtosWithOptionsSync([ 'udpa/type/v1/typed_struct.proto', + 'xds/type/v3/typed_struct.proto', 'envoy/config/route/v3/route_components.proto'], { keepCase: true, includeDirs: [ // Paths are relative to src/build - __dirname + '/../../deps/udpa/', + __dirname + '/../../deps/xds/', __dirname + '/../../deps/envoy-api/', __dirname + '/../../deps/protoc-gen-validate/' ], @@ -91,7 +94,7 @@ function parseAnyMessage(message: Any__Output): MessageType | null export function getTopLevelFilterUrl(encodedConfig: Any__Output): string { let typeUrl: string; - if (encodedConfig.type_url === TYPED_STRUCT_URL) { + if (encodedConfig.type_url === TYPED_STRUCT_UDPA_URL || encodedConfig.type_url === TYPED_STRUCT_XDS_URL) { const typedStruct = parseAnyMessage(encodedConfig) if (typedStruct) { return typedStruct.type_url; @@ -154,7 +157,7 @@ export function validateOverrideFilter(encodedConfig: Any__Output): boolean { } else { realConfig = encodedConfig; } - if (realConfig.type_url === TYPED_STRUCT_URL) { + if (realConfig.type_url === TYPED_STRUCT_UDPA_URL || realConfig.type_url === TYPED_STRUCT_XDS_URL) { const typedStruct = parseAnyMessage(encodedConfig); if (typedStruct) { typeUrl = typedStruct.type_url; @@ -215,7 +218,7 @@ export function parseOverrideFilterConfig(encodedConfig: Any__Output) { } else { realConfig = encodedConfig; } - if (realConfig.type_url === TYPED_STRUCT_URL) { + if (realConfig.type_url === TYPED_STRUCT_UDPA_URL || realConfig.type_url === TYPED_STRUCT_XDS_URL) { const typedStruct = parseAnyMessage(encodedConfig); if (typedStruct) { typeUrl = typedStruct.type_url; diff --git a/packages/grpc-js-xds/src/http-filter/fault-injection-filter.ts b/packages/grpc-js-xds/src/http-filter/fault-injection-filter.ts index e0ee658c7..a49ec77d4 100644 --- a/packages/grpc-js-xds/src/http-filter/fault-injection-filter.ts +++ b/packages/grpc-js-xds/src/http-filter/fault-injection-filter.ts @@ -38,7 +38,7 @@ const resourceRoot = loadProtosWithOptionsSync([ keepCase: true, includeDirs: [ // Paths are relative to src/build/http-filter - __dirname + '/../../../deps/udpa/', + __dirname + '/../../../deps/xds/', __dirname + '/../../../deps/envoy-api/', __dirname + '/../../../deps/protoc-gen-validate/' ], diff --git a/packages/grpc-js-xds/src/resources.ts b/packages/grpc-js-xds/src/resources.ts index 516980de8..4a7e22763 100644 --- a/packages/grpc-js-xds/src/resources.ts +++ b/packages/grpc-js-xds/src/resources.ts @@ -70,7 +70,7 @@ const resourceRoot = loadProtosWithOptionsSync([ includeDirs: [ // Paths are relative to src/build __dirname + '/../../deps/envoy-api/', - __dirname + '/../../deps/udpa/', + __dirname + '/../../deps/xds/', __dirname + '/../../deps/googleapis/', __dirname + '/../../deps/protoc-gen-validate/', ], diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index 2b8fae44c..8a08276eb 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -87,7 +87,7 @@ function loadAdsProtos(): Promise< includeDirs: [ // Paths are relative to src/build __dirname + '/../../deps/envoy-api/', - __dirname + '/../../deps/udpa/', + __dirname + '/../../deps/xds/', __dirname + '/../../deps/googleapis/', __dirname + '/../../deps/protoc-gen-validate/', ], From 3c48058d9a2c5c95d5fc88d54f55221a56c7aea5 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 1 Nov 2021 16:09:49 -0700 Subject: [PATCH 123/450] grpc-js-xds: Update files list to account for submodule change --- packages/grpc-js-xds/package.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index 9be41a0a4..fca6ab80d 100644 --- a/packages/grpc-js-xds/package.json +++ b/packages/grpc-js-xds/package.json @@ -63,7 +63,11 @@ "deps/googleapis/google/api/**/*.proto", "deps/googleapis/google/protobuf/**/*.proto", "deps/googleapis/google/rpc/**/*.proto", - "deps/udpa/udpa/annotations/**/*.proto", + "deps/xds/udpa/annotations/**/*.proto", + "deps/xds/udpa/type/**/*.proto", + "deps/xds/xds/annotations/**/*.proto", + "deps/xds/xds/core/**/*.proto", + "deps/xds/xds/type/**/*.proto", "deps/protoc-gen-validate/validate/**/*.proto" ] } From 5c61a6a34e375eebbab1cd399de7a0b805916a4c Mon Sep 17 00:00:00 2001 From: Robert M Date: Mon, 1 Nov 2021 18:38:37 -0700 Subject: [PATCH 124/450] Update packages/grpc-js/src/server-call.ts Co-authored-by: Michael Lumish --- packages/grpc-js/src/server-call.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index b340b3446..24028c073 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -485,7 +485,7 @@ export class Http2ServerCallStream< default: { this.sendError({ code: Status.UNIMPLEMENTED, - details: `Received "grpc-encoding" header "${encoding}", which is not supported`, + details: `Received message compressed with unsupported encoding "${encoding}"`, }); return Promise.resolve(); } From dc9752addcd70785f26f1cde17404c7a4b2ae47f Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 1 Nov 2021 19:04:21 -0700 Subject: [PATCH 125/450] change CompressionAlgorithms to an enum --- packages/grpc-js/src/channel-options.ts | 2 +- packages/grpc-js/src/compression-algorithms.ts | 10 +++++----- packages/grpc-js/src/compression-filter.ts | 10 ++++------ 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/grpc-js/src/channel-options.ts b/packages/grpc-js/src/channel-options.ts index b54ae4eda..e10e92758 100644 --- a/packages/grpc-js/src/channel-options.ts +++ b/packages/grpc-js/src/channel-options.ts @@ -38,7 +38,7 @@ export interface ChannelOptions { 'grpc.enable_http_proxy'?: number; 'grpc.http_connect_target'?: string; 'grpc.http_connect_creds'?: string; - 'grpc.default_compression_algorithm'?: keyof typeof CompressionAlgorithms; + 'grpc.default_compression_algorithm'?: CompressionAlgorithms; 'grpc-node.max_session_memory'?: number; // eslint-disable-next-line @typescript-eslint/no-explicit-any [key: string]: any; diff --git a/packages/grpc-js/src/compression-algorithms.ts b/packages/grpc-js/src/compression-algorithms.ts index ccc38e76b..ca2c7a624 100644 --- a/packages/grpc-js/src/compression-algorithms.ts +++ b/packages/grpc-js/src/compression-algorithms.ts @@ -15,8 +15,8 @@ * */ -export const CompressionAlgorithms = { - 0: 'identity', - 1: 'deflate', - 2: 'gzip' -} as const; +export enum CompressionAlgorithms { + identity = 0, + deflate = 1, + gzip = 2 +}; diff --git a/packages/grpc-js/src/compression-filter.ts b/packages/grpc-js/src/compression-filter.ts index cbdd35104..de35dd44a 100644 --- a/packages/grpc-js/src/compression-filter.ts +++ b/packages/grpc-js/src/compression-filter.ts @@ -26,13 +26,11 @@ import { BaseFilter, Filter, FilterFactory } from './filter'; import * as logging from './logging'; import { Metadata, MetadataValue } from './metadata'; -const CompressionAlgorithKeys = new Set(Object.keys(CompressionAlgorithms)); - -const isCompressionAlgorithmKey = (key: number | undefined): key is keyof typeof CompressionAlgorithms => { - return typeof key === 'number' && CompressionAlgorithKeys.has(key.toString()); +const isCompressionAlgorithmKey = (key: number): key is CompressionAlgorithms => { + return typeof key === 'number' && typeof CompressionAlgorithms[key] === 'string'; } -type CompressionAlgorithm = (typeof CompressionAlgorithms)[keyof typeof CompressionAlgorithms]; +type CompressionAlgorithm = keyof typeof CompressionAlgorithms; type SharedCompressionFilterConfig = { serverSupportedEncodingHeader?: string; @@ -191,7 +189,7 @@ export class CompressionFilter extends BaseFilter implements Filter { const compressionAlgorithmKey = channelOptions['grpc.default_compression_algorithm']; if (compressionAlgorithmKey !== undefined) { if (isCompressionAlgorithmKey(compressionAlgorithmKey)) { - const clientSelectedEncoding = CompressionAlgorithms[compressionAlgorithmKey]; + const clientSelectedEncoding = CompressionAlgorithms[compressionAlgorithmKey] as CompressionAlgorithm; const serverSupportedEncodings = sharedFilterConfig.serverSupportedEncodingHeader?.split(','); /** * There are two possible situations here: From c4d7fab13ea8a18e3bcf6b57bfb3220177ff2006 Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 2 Nov 2021 19:17:44 -0700 Subject: [PATCH 126/450] simplify compression filter handling of server supported encoding headers --- packages/grpc-js/src/compression-filter.ts | 8 ++++---- packages/grpc-js/test/test-server.ts | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/grpc-js/src/compression-filter.ts b/packages/grpc-js/src/compression-filter.ts index de35dd44a..40825467e 100644 --- a/packages/grpc-js/src/compression-filter.ts +++ b/packages/grpc-js/src/compression-filter.ts @@ -240,10 +240,10 @@ export class CompressionFilter extends BaseFilter implements Filter { this.sharedFilterConfig.serverSupportedEncodingHeader = serverSupportedEncodingsHeader; const serverSupportedEncodings = serverSupportedEncodingsHeader.split(','); - if ((this.sendCompression instanceof DeflateHandler && !serverSupportedEncodings.includes('deflate')) - || (this.sendCompression instanceof GzipHandler && !serverSupportedEncodings.includes('gzip'))) { - this.sendCompression = new IdentityHandler(); - } + if (!serverSupportedEncodings.includes(this.currentCompressionAlgorithm)) { + this.sendCompression = new IdentityHandler(); + this.currentCompressionAlgorithm = 'identity'; + } } metadata.remove('grpc-accept-encoding'); return metadata; diff --git a/packages/grpc-js/test/test-server.ts b/packages/grpc-js/test/test-server.ts index c0e7ebf5f..cc20164a4 100644 --- a/packages/grpc-js/test/test-server.ts +++ b/packages/grpc-js/test/test-server.ts @@ -33,6 +33,7 @@ import { loadProtoFile } from './common'; import { TestServiceClient, TestServiceHandlers } from './generated/TestService'; import { ProtoGrpcType as TestServiceGrpcType } from './generated/test_service'; import { Request__Output } from './generated/Request'; +import { CompressionAlgorithms } from '../src/compression-algorithms'; const loadedTestServiceProto = protoLoader.loadSync('test/fixtures/test_service.proto', { keepCase: true, @@ -683,7 +684,7 @@ describe('Compressed requests', () => { `localhost:${assignedPort}`, grpc.credentials.createInsecure(), { - 'grpc.default_compression_algorithm': 1 + 'grpc.default_compression_algorithm': CompressionAlgorithms.deflate } ); done(); @@ -774,7 +775,7 @@ describe('Compressed requests', () => { `localhost:${assignedPort}`, grpc.credentials.createInsecure(), { - 'grpc.default_compression_algorithm': 2 + 'grpc.default_compression_algorithm': CompressionAlgorithms.gzip } ); From 1a60c4f3a92d6c0559422666ec446bdc3b0f70a3 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 4 Nov 2021 14:11:16 -0700 Subject: [PATCH 127/450] grpc-js: channelz: Fix algorithm for representing an IPv6 address in binary --- packages/grpc-js/src/channelz.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/src/channelz.ts b/packages/grpc-js/src/channelz.ts index 768efaa58..94d84d8f2 100644 --- a/packages/grpc-js/src/channelz.ts +++ b/packages/grpc-js/src/channelz.ts @@ -392,6 +392,16 @@ export function unregisterChannelzRef(ref: ChannelRef | SubchannelRef | ServerRe } } +/** + * Parses a single section of an IPv6 address as two bytes + * @param addressSection A hexadecimal string of length up to 4 + * @returns The pair of bytes representing this address section + */ +function parseIPv6Section(addressSection: string): [number, number] { + const numberValue = Number.parseInt(addressSection, 16); + return [numberValue / 256 | 0, numberValue % 256]; +} + /** * Converts an IPv4 or IPv6 address from string representation to binary * representation @@ -412,8 +422,8 @@ function ipAddressStringToBuffer(ipAddress: string): Buffer | null { leftSection = ipAddress.substring(0, doubleColonIndex); rightSection = ipAddress.substring(doubleColonIndex + 2); } - const leftBuffer = Uint8Array.from(leftSection.split(':').map(segment => Number.parseInt(segment, 16))); - const rightBuffer = rightSection ? Uint8Array.from(rightSection.split(':').map(segment => Number.parseInt(segment, 16))) : new Uint8Array(); + const leftBuffer = Buffer.from(leftSection.split(':').map(segment => parseIPv6Section(segment)).flat()); + const rightBuffer = rightSection ? Buffer.from(rightSection.split(':').map(segment => parseIPv6Section(segment)).flat()) : Buffer.alloc(0); const middleBuffer = Buffer.alloc(16 - leftBuffer.length - rightBuffer.length, 0); return Buffer.concat([leftBuffer, middleBuffer, rightBuffer]); } else { From bb26dcfd1ef1019af887e4a76c72262bc26a5378 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 5 Nov 2021 10:11:22 -0700 Subject: [PATCH 128/450] grpc-js: Fix handling of grpc.enable_channelz option --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/subchannel.ts | 11 +++++++-- packages/grpc-js/test/test-channelz.ts | 32 ++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 4acf948df..69d0662b7 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.4.2", + "version": "1.4.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", diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 0b6465b2e..87defa740 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -832,6 +832,7 @@ export class Subchannel { headersString ); const streamSession = this.session; + let statsTracker: SubchannelCallStatsTracker; if (this.channelzEnabled) { this.callTracker.addCallStarted(); callStream.addStatusWatcher(status => { @@ -851,7 +852,7 @@ export class Subchannel { } } }); - callStream.attachHttp2Stream(http2Stream, this, extraFilters, { + statsTracker = { addMessageSent: () => { this.messagesSent += 1; this.lastMessageSentTimestamp = new Date(); @@ -859,8 +860,14 @@ export class Subchannel { addMessageReceived: () => { this.messagesReceived += 1; } - }); + } + } else { + statsTracker = { + addMessageSent: () => {}, + addMessageReceived: () => {} + } } + callStream.attachHttp2Stream(http2Stream, this, extraFilters, statsTracker); } /** diff --git a/packages/grpc-js/test/test-channelz.ts b/packages/grpc-js/test/test-channelz.ts index 2cca780e8..f14145c37 100644 --- a/packages/grpc-js/test/test-channelz.ts +++ b/packages/grpc-js/test/test-channelz.ts @@ -286,4 +286,36 @@ describe('Channelz', () => { }); }); }); +}); + +describe('Disabling channelz', () => { + let testServer: grpc.Server; + let testClient: ServiceClient; + beforeEach((done) => { + testServer = new grpc.Server({'grpc.enable_channelz': 0}); + testServer.addService(TestServiceClient.service, testServiceImpl); + testServer.bindAsync('localhost:0', grpc.ServerCredentials.createInsecure(), (error, port) => { + if (error) { + done(error); + return; + } + testServer.start(); + testClient = new TestServiceClient(`localhost:${port}`, grpc.credentials.createInsecure(), {'grpc.enable_channelz': 0}); + done(); + }); + }); + + afterEach(() => { + testClient.close(); + testServer.forceShutdown(); + }); + + it('Should still work', (done) => { + const deadline = new Date(); + deadline.setSeconds(deadline.getSeconds() + 1); + testClient.unary({}, {deadline}, (error: grpc.ServiceError, value: unknown) => { + assert.ifError(error); + done(); + }); + }); }); \ No newline at end of file From b1be84a0214ed140e3c58d8624c11c5756223376 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 5 Nov 2021 11:54:15 -0700 Subject: [PATCH 129/450] Make IPv6 parsing code compatible with Node 10 --- packages/grpc-js/src/channelz.ts | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/packages/grpc-js/src/channelz.ts b/packages/grpc-js/src/channelz.ts index 94d84d8f2..14c94fd0c 100644 --- a/packages/grpc-js/src/channelz.ts +++ b/packages/grpc-js/src/channelz.ts @@ -393,7 +393,7 @@ export function unregisterChannelzRef(ref: ChannelRef | SubchannelRef | ServerRe } /** - * Parses a single section of an IPv6 address as two bytes + * Parse a single section of an IPv6 address as two bytes * @param addressSection A hexadecimal string of length up to 4 * @returns The pair of bytes representing this address section */ @@ -402,6 +402,21 @@ function parseIPv6Section(addressSection: string): [number, number] { return [numberValue / 256 | 0, numberValue % 256]; } +/** + * Parse a chunk of an IPv6 address string to some number of bytes + * @param addressChunk Some number of segments of up to 4 hexadecimal + * characters each, joined by colons. + * @returns The list of bytes representing this address chunk + */ +function parseIPv6Chunk(addressChunk: string): number[] { + if (addressChunk === '') { + return []; + } + const bytePairs = addressChunk.split(':').map(section => parseIPv6Section(section)); + const result: number[] = []; + return result.concat(...bytePairs); +} + /** * Converts an IPv4 or IPv6 address from string representation to binary * representation @@ -413,17 +428,17 @@ function ipAddressStringToBuffer(ipAddress: string): Buffer | null { return Buffer.from(Uint8Array.from(ipAddress.split('.').map(segment => Number.parseInt(segment)))); } else if (isIPv6(ipAddress)) { let leftSection: string; - let rightSection: string | null; + let rightSection: string; const doubleColonIndex = ipAddress.indexOf('::'); if (doubleColonIndex === -1) { leftSection = ipAddress; - rightSection = null; + rightSection = ''; } else { leftSection = ipAddress.substring(0, doubleColonIndex); rightSection = ipAddress.substring(doubleColonIndex + 2); } - const leftBuffer = Buffer.from(leftSection.split(':').map(segment => parseIPv6Section(segment)).flat()); - const rightBuffer = rightSection ? Buffer.from(rightSection.split(':').map(segment => parseIPv6Section(segment)).flat()) : Buffer.alloc(0); + const leftBuffer = Buffer.from(parseIPv6Chunk(leftSection)); + const rightBuffer = Buffer.from(parseIPv6Chunk(rightSection)); const middleBuffer = Buffer.alloc(16 - leftBuffer.length - rightBuffer.length, 0); return Buffer.concat([leftBuffer, middleBuffer, rightBuffer]); } else { From 96ae102eaf82e2094556a13539faa4f9a9edcabe Mon Sep 17 00:00:00 2001 From: Robert Date: Fri, 5 Nov 2021 19:59:03 -0700 Subject: [PATCH 130/450] fix path for loading test_service proto --- packages/grpc-js/test/test-server.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/grpc-js/test/test-server.ts b/packages/grpc-js/test/test-server.ts index cc20164a4..a5f7ec80b 100644 --- a/packages/grpc-js/test/test-server.ts +++ b/packages/grpc-js/test/test-server.ts @@ -35,15 +35,12 @@ import { ProtoGrpcType as TestServiceGrpcType } from './generated/test_service'; import { Request__Output } from './generated/Request'; import { CompressionAlgorithms } from '../src/compression-algorithms'; -const loadedTestServiceProto = protoLoader.loadSync('test/fixtures/test_service.proto', { +const loadedTestServiceProto = protoLoader.loadSync(path.join(__dirname, 'fixtures/test_service.proto'), { keepCase: true, longs: String, enums: String, defaults: true, - oneofs: true, - includeDirs: [ - `${__dirname}/../../proto` - ] + oneofs: true }); const testServiceGrpcObject = grpc.loadPackageDefinition(loadedTestServiceProto) as unknown as TestServiceGrpcType; From af966f04b864a811c7a38df26ca683af78c1a02f Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 8 Nov 2021 09:44:11 -0800 Subject: [PATCH 131/450] grpc-js: Remove an extra call to registerChannelzSocket --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/subchannel.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 69d0662b7..e14ffa0eb 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.4.3", + "version": "1.4.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.ts b/packages/grpc-js/src/subchannel.ts index 87defa740..6f9471bb9 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -555,7 +555,6 @@ export class Subchannel { (error as Error).message ); }); - registerChannelzSocket(this.subchannelAddressString, () => this.getChannelzSocketInfo()!); } private startConnectingInternal() { From 69428b04457f0e9337e38072bc88932585855768 Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 9 Nov 2021 21:26:54 -0800 Subject: [PATCH 132/450] simplify removal of compression prefix bytes --- packages/grpc-js/src/server-call.ts | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index 24028c073..709d20d41 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -454,8 +454,7 @@ export class Http2ServerCallStream< }); resolve(); } else { - const joined = Buffer.concat([message.slice(0, 5), output]); - resolve(joined); + resolve(output); } }); }); @@ -471,15 +470,14 @@ export class Http2ServerCallStream< }); resolve(); } else { - const joined = Buffer.concat([message.slice(0, 5), output]); - resolve(joined); + resolve(output); } }); }); } case 'identity': { - return Promise.resolve(message); + return Promise.resolve(message.slice(5)); } default: { @@ -603,10 +601,7 @@ export class Http2ServerCallStream< } deserializeMessage(bytes: Buffer) { - // TODO(cjihrig): Call compression aware deserializeMessage(). - const receivedMessage = bytes.slice(5); - - return this.handler.deserialize(receivedMessage); + return this.handler.deserialize(bytes); } async sendUnaryMessage( From 4b20bf3fce00106b975752d6fd5e226b1f227000 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 15 Nov 2021 10:05:10 -0800 Subject: [PATCH 133/450] proto-loader: Fix generated types for callbacks --- .../bin/proto-loader-gen-types.ts | 2 +- .../google/longrunning/Operations.ts | 80 +++++++++---------- .../google/showcase/v1beta1/Echo.ts | 80 +++++++++---------- packages/proto-loader/package.json | 2 +- 4 files changed, 82 insertions(+), 82 deletions(-) diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index 6c9596980..3ecf6dcc4 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -503,7 +503,7 @@ function generateServiceClientInterface(formatter: TextFormatter, serviceType: P } const requestType = getTypeInterfaceName(method.resolvedRequestType!); const responseType = getTypeInterfaceName(method.resolvedResponseType!) + '__Output'; - const callbackType = `(error?: grpc.ServiceError, result?: ${responseType}) => void`; + const callbackType = `grpc.requestCallback<${responseType}>`; if (method.requestStream) { if (method.responseStream) { // Bidi streaming diff --git a/packages/proto-loader/golden-generated/google/longrunning/Operations.ts b/packages/proto-loader/golden-generated/google/longrunning/Operations.ts index 7644f974d..6358cbbfd 100644 --- a/packages/proto-loader/golden-generated/google/longrunning/Operations.ts +++ b/packages/proto-loader/golden-generated/google/longrunning/Operations.ts @@ -35,10 +35,10 @@ export interface OperationsClient extends grpc.Client { * an [Operation.error][google.longrunning.Operation.error] value with a [google.rpc.Status.code][google.rpc.Status.code] of 1, * corresponding to `Code.CANCELLED`. */ - CancelOperation(argument: _google_longrunning_CancelOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; - CancelOperation(argument: _google_longrunning_CancelOperationRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; - CancelOperation(argument: _google_longrunning_CancelOperationRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; - CancelOperation(argument: _google_longrunning_CancelOperationRequest, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; + CancelOperation(argument: _google_longrunning_CancelOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; + CancelOperation(argument: _google_longrunning_CancelOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; + CancelOperation(argument: _google_longrunning_CancelOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; + CancelOperation(argument: _google_longrunning_CancelOperationRequest, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; /** * Starts asynchronous cancellation on a long-running operation. The server * makes a best effort to cancel the operation, but success is not @@ -51,10 +51,10 @@ export interface OperationsClient extends grpc.Client { * an [Operation.error][google.longrunning.Operation.error] value with a [google.rpc.Status.code][google.rpc.Status.code] of 1, * corresponding to `Code.CANCELLED`. */ - cancelOperation(argument: _google_longrunning_CancelOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; - cancelOperation(argument: _google_longrunning_CancelOperationRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; - cancelOperation(argument: _google_longrunning_CancelOperationRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; - cancelOperation(argument: _google_longrunning_CancelOperationRequest, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; + cancelOperation(argument: _google_longrunning_CancelOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; + cancelOperation(argument: _google_longrunning_CancelOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; + cancelOperation(argument: _google_longrunning_CancelOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; + cancelOperation(argument: _google_longrunning_CancelOperationRequest, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; /** * Deletes a long-running operation. This method indicates that the client is @@ -62,39 +62,39 @@ export interface OperationsClient extends grpc.Client { * operation. If the server doesn't support this method, it returns * `google.rpc.Code.UNIMPLEMENTED`. */ - DeleteOperation(argument: _google_longrunning_DeleteOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; - DeleteOperation(argument: _google_longrunning_DeleteOperationRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; - DeleteOperation(argument: _google_longrunning_DeleteOperationRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; - DeleteOperation(argument: _google_longrunning_DeleteOperationRequest, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; + DeleteOperation(argument: _google_longrunning_DeleteOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; + DeleteOperation(argument: _google_longrunning_DeleteOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; + DeleteOperation(argument: _google_longrunning_DeleteOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; + DeleteOperation(argument: _google_longrunning_DeleteOperationRequest, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; /** * Deletes a long-running operation. This method indicates that the client is * no longer interested in the operation result. It does not cancel the * operation. If the server doesn't support this method, it returns * `google.rpc.Code.UNIMPLEMENTED`. */ - deleteOperation(argument: _google_longrunning_DeleteOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; - deleteOperation(argument: _google_longrunning_DeleteOperationRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; - deleteOperation(argument: _google_longrunning_DeleteOperationRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; - deleteOperation(argument: _google_longrunning_DeleteOperationRequest, callback: (error?: grpc.ServiceError, result?: _google_protobuf_Empty__Output) => void): grpc.ClientUnaryCall; + deleteOperation(argument: _google_longrunning_DeleteOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; + deleteOperation(argument: _google_longrunning_DeleteOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; + deleteOperation(argument: _google_longrunning_DeleteOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; + deleteOperation(argument: _google_longrunning_DeleteOperationRequest, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; /** * Gets the latest state of a long-running operation. Clients can use this * method to poll the operation result at intervals as recommended by the API * service. */ - GetOperation(argument: _google_longrunning_GetOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; - GetOperation(argument: _google_longrunning_GetOperationRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; - GetOperation(argument: _google_longrunning_GetOperationRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; - GetOperation(argument: _google_longrunning_GetOperationRequest, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; + GetOperation(argument: _google_longrunning_GetOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + GetOperation(argument: _google_longrunning_GetOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + GetOperation(argument: _google_longrunning_GetOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + GetOperation(argument: _google_longrunning_GetOperationRequest, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; /** * Gets the latest state of a long-running operation. Clients can use this * method to poll the operation result at intervals as recommended by the API * service. */ - getOperation(argument: _google_longrunning_GetOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; - getOperation(argument: _google_longrunning_GetOperationRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; - getOperation(argument: _google_longrunning_GetOperationRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; - getOperation(argument: _google_longrunning_GetOperationRequest, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; + getOperation(argument: _google_longrunning_GetOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + getOperation(argument: _google_longrunning_GetOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + getOperation(argument: _google_longrunning_GetOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + getOperation(argument: _google_longrunning_GetOperationRequest, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; /** * Lists operations that match the specified filter in the request. If the @@ -108,10 +108,10 @@ export interface OperationsClient extends grpc.Client { * collection id, however overriding users must ensure the name binding * is the parent resource, without the operations collection id. */ - ListOperations(argument: _google_longrunning_ListOperationsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_longrunning_ListOperationsResponse__Output) => void): grpc.ClientUnaryCall; - ListOperations(argument: _google_longrunning_ListOperationsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_longrunning_ListOperationsResponse__Output) => void): grpc.ClientUnaryCall; - ListOperations(argument: _google_longrunning_ListOperationsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_longrunning_ListOperationsResponse__Output) => void): grpc.ClientUnaryCall; - ListOperations(argument: _google_longrunning_ListOperationsRequest, callback: (error?: grpc.ServiceError, result?: _google_longrunning_ListOperationsResponse__Output) => void): grpc.ClientUnaryCall; + ListOperations(argument: _google_longrunning_ListOperationsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_ListOperationsResponse__Output>): grpc.ClientUnaryCall; + ListOperations(argument: _google_longrunning_ListOperationsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_longrunning_ListOperationsResponse__Output>): grpc.ClientUnaryCall; + ListOperations(argument: _google_longrunning_ListOperationsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_ListOperationsResponse__Output>): grpc.ClientUnaryCall; + ListOperations(argument: _google_longrunning_ListOperationsRequest, callback: grpc.requestCallback<_google_longrunning_ListOperationsResponse__Output>): grpc.ClientUnaryCall; /** * Lists operations that match the specified filter in the request. If the * server doesn't support this method, it returns `UNIMPLEMENTED`. @@ -124,10 +124,10 @@ export interface OperationsClient extends grpc.Client { * collection id, however overriding users must ensure the name binding * is the parent resource, without the operations collection id. */ - listOperations(argument: _google_longrunning_ListOperationsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_longrunning_ListOperationsResponse__Output) => void): grpc.ClientUnaryCall; - listOperations(argument: _google_longrunning_ListOperationsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_longrunning_ListOperationsResponse__Output) => void): grpc.ClientUnaryCall; - listOperations(argument: _google_longrunning_ListOperationsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_longrunning_ListOperationsResponse__Output) => void): grpc.ClientUnaryCall; - listOperations(argument: _google_longrunning_ListOperationsRequest, callback: (error?: grpc.ServiceError, result?: _google_longrunning_ListOperationsResponse__Output) => void): grpc.ClientUnaryCall; + listOperations(argument: _google_longrunning_ListOperationsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_ListOperationsResponse__Output>): grpc.ClientUnaryCall; + listOperations(argument: _google_longrunning_ListOperationsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_longrunning_ListOperationsResponse__Output>): grpc.ClientUnaryCall; + listOperations(argument: _google_longrunning_ListOperationsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_ListOperationsResponse__Output>): grpc.ClientUnaryCall; + listOperations(argument: _google_longrunning_ListOperationsRequest, callback: grpc.requestCallback<_google_longrunning_ListOperationsResponse__Output>): grpc.ClientUnaryCall; /** * Waits for the specified long-running operation until it is done or reaches @@ -140,10 +140,10 @@ export interface OperationsClient extends grpc.Client { * state before the specified timeout (including immediately), meaning even an * immediate response is no guarantee that the operation is done. */ - WaitOperation(argument: _google_longrunning_WaitOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; - WaitOperation(argument: _google_longrunning_WaitOperationRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; - WaitOperation(argument: _google_longrunning_WaitOperationRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; - WaitOperation(argument: _google_longrunning_WaitOperationRequest, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; + WaitOperation(argument: _google_longrunning_WaitOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + WaitOperation(argument: _google_longrunning_WaitOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + WaitOperation(argument: _google_longrunning_WaitOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + WaitOperation(argument: _google_longrunning_WaitOperationRequest, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; /** * Waits for the specified long-running operation until it is done or reaches * at most a specified timeout, returning the latest state. If the operation @@ -155,10 +155,10 @@ export interface OperationsClient extends grpc.Client { * state before the specified timeout (including immediately), meaning even an * immediate response is no guarantee that the operation is done. */ - waitOperation(argument: _google_longrunning_WaitOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; - waitOperation(argument: _google_longrunning_WaitOperationRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; - waitOperation(argument: _google_longrunning_WaitOperationRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; - waitOperation(argument: _google_longrunning_WaitOperationRequest, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; + waitOperation(argument: _google_longrunning_WaitOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + waitOperation(argument: _google_longrunning_WaitOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + waitOperation(argument: _google_longrunning_WaitOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + waitOperation(argument: _google_longrunning_WaitOperationRequest, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; } diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/Echo.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/Echo.ts index 8e75c6c1a..30ecc8e23 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/Echo.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/Echo.ts @@ -25,19 +25,19 @@ export interface EchoClient extends grpc.Client { * and then return the response or error. * This method showcases how a client handles delays or retries. */ - Block(argument: _google_showcase_v1beta1_BlockRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_BlockResponse__Output) => void): grpc.ClientUnaryCall; - Block(argument: _google_showcase_v1beta1_BlockRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_BlockResponse__Output) => void): grpc.ClientUnaryCall; - Block(argument: _google_showcase_v1beta1_BlockRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_BlockResponse__Output) => void): grpc.ClientUnaryCall; - Block(argument: _google_showcase_v1beta1_BlockRequest, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_BlockResponse__Output) => void): grpc.ClientUnaryCall; + Block(argument: _google_showcase_v1beta1_BlockRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_BlockResponse__Output>): grpc.ClientUnaryCall; + Block(argument: _google_showcase_v1beta1_BlockRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_showcase_v1beta1_BlockResponse__Output>): grpc.ClientUnaryCall; + Block(argument: _google_showcase_v1beta1_BlockRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_BlockResponse__Output>): grpc.ClientUnaryCall; + Block(argument: _google_showcase_v1beta1_BlockRequest, callback: grpc.requestCallback<_google_showcase_v1beta1_BlockResponse__Output>): grpc.ClientUnaryCall; /** * This method will block (wait) for the requested amount of time * and then return the response or error. * This method showcases how a client handles delays or retries. */ - block(argument: _google_showcase_v1beta1_BlockRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_BlockResponse__Output) => void): grpc.ClientUnaryCall; - block(argument: _google_showcase_v1beta1_BlockRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_BlockResponse__Output) => void): grpc.ClientUnaryCall; - block(argument: _google_showcase_v1beta1_BlockRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_BlockResponse__Output) => void): grpc.ClientUnaryCall; - block(argument: _google_showcase_v1beta1_BlockRequest, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_BlockResponse__Output) => void): grpc.ClientUnaryCall; + block(argument: _google_showcase_v1beta1_BlockRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_BlockResponse__Output>): grpc.ClientUnaryCall; + block(argument: _google_showcase_v1beta1_BlockRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_showcase_v1beta1_BlockResponse__Output>): grpc.ClientUnaryCall; + block(argument: _google_showcase_v1beta1_BlockRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_BlockResponse__Output>): grpc.ClientUnaryCall; + block(argument: _google_showcase_v1beta1_BlockRequest, callback: grpc.requestCallback<_google_showcase_v1beta1_BlockResponse__Output>): grpc.ClientUnaryCall; /** * This method, upon receiving a request on the stream, the same content will @@ -59,34 +59,34 @@ export interface EchoClient extends grpc.Client { * by the client, this method will return the a concatenation of the strings * passed to it. This method showcases client-side streaming rpcs. */ - Collect(metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_EchoResponse__Output) => void): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; - Collect(metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_EchoResponse__Output) => void): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; - Collect(options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_EchoResponse__Output) => void): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; - Collect(callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_EchoResponse__Output) => void): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; + Collect(metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; + Collect(metadata: grpc.Metadata, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; + Collect(options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; + Collect(callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; /** * This method will collect the words given to it. When the stream is closed * by the client, this method will return the a concatenation of the strings * passed to it. This method showcases client-side streaming rpcs. */ - collect(metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_EchoResponse__Output) => void): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; - collect(metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_EchoResponse__Output) => void): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; - collect(options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_EchoResponse__Output) => void): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; - collect(callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_EchoResponse__Output) => void): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; + collect(metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; + collect(metadata: grpc.Metadata, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; + collect(options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; + collect(callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; /** * This method simply echos the request. This method is showcases unary rpcs. */ - Echo(argument: _google_showcase_v1beta1_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_EchoResponse__Output) => void): grpc.ClientUnaryCall; - Echo(argument: _google_showcase_v1beta1_EchoRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_EchoResponse__Output) => void): grpc.ClientUnaryCall; - Echo(argument: _google_showcase_v1beta1_EchoRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_EchoResponse__Output) => void): grpc.ClientUnaryCall; - Echo(argument: _google_showcase_v1beta1_EchoRequest, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_EchoResponse__Output) => void): grpc.ClientUnaryCall; + Echo(argument: _google_showcase_v1beta1_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo(argument: _google_showcase_v1beta1_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo(argument: _google_showcase_v1beta1_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo(argument: _google_showcase_v1beta1_EchoRequest, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientUnaryCall; /** * This method simply echos the request. This method is showcases unary rpcs. */ - echo(argument: _google_showcase_v1beta1_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_EchoResponse__Output) => void): grpc.ClientUnaryCall; - echo(argument: _google_showcase_v1beta1_EchoRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_EchoResponse__Output) => void): grpc.ClientUnaryCall; - echo(argument: _google_showcase_v1beta1_EchoRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_EchoResponse__Output) => void): grpc.ClientUnaryCall; - echo(argument: _google_showcase_v1beta1_EchoRequest, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_EchoResponse__Output) => void): grpc.ClientUnaryCall; + echo(argument: _google_showcase_v1beta1_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientUnaryCall; + echo(argument: _google_showcase_v1beta1_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientUnaryCall; + echo(argument: _google_showcase_v1beta1_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientUnaryCall; + echo(argument: _google_showcase_v1beta1_EchoRequest, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientUnaryCall; /** * This method split the given content into words and will pass each word back @@ -105,35 +105,35 @@ export interface EchoClient extends grpc.Client { * This is similar to the Expand method but instead of returning a stream of * expanded words, this method returns a paged list of expanded words. */ - PagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_PagedExpandResponse__Output) => void): grpc.ClientUnaryCall; - PagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_PagedExpandResponse__Output) => void): grpc.ClientUnaryCall; - PagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_PagedExpandResponse__Output) => void): grpc.ClientUnaryCall; - PagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_PagedExpandResponse__Output) => void): grpc.ClientUnaryCall; + PagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_PagedExpandResponse__Output>): grpc.ClientUnaryCall; + PagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_showcase_v1beta1_PagedExpandResponse__Output>): grpc.ClientUnaryCall; + PagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_PagedExpandResponse__Output>): grpc.ClientUnaryCall; + PagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, callback: grpc.requestCallback<_google_showcase_v1beta1_PagedExpandResponse__Output>): grpc.ClientUnaryCall; /** * This is similar to the Expand method but instead of returning a stream of * expanded words, this method returns a paged list of expanded words. */ - pagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_PagedExpandResponse__Output) => void): grpc.ClientUnaryCall; - pagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_PagedExpandResponse__Output) => void): grpc.ClientUnaryCall; - pagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_PagedExpandResponse__Output) => void): grpc.ClientUnaryCall; - pagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, callback: (error?: grpc.ServiceError, result?: _google_showcase_v1beta1_PagedExpandResponse__Output) => void): grpc.ClientUnaryCall; + pagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_PagedExpandResponse__Output>): grpc.ClientUnaryCall; + pagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_showcase_v1beta1_PagedExpandResponse__Output>): grpc.ClientUnaryCall; + pagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_PagedExpandResponse__Output>): grpc.ClientUnaryCall; + pagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, callback: grpc.requestCallback<_google_showcase_v1beta1_PagedExpandResponse__Output>): grpc.ClientUnaryCall; /** * This method will wait the requested amount of and then return. * This method showcases how a client handles a request timing out. */ - Wait(argument: _google_showcase_v1beta1_WaitRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; - Wait(argument: _google_showcase_v1beta1_WaitRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; - Wait(argument: _google_showcase_v1beta1_WaitRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; - Wait(argument: _google_showcase_v1beta1_WaitRequest, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; + Wait(argument: _google_showcase_v1beta1_WaitRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + Wait(argument: _google_showcase_v1beta1_WaitRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + Wait(argument: _google_showcase_v1beta1_WaitRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + Wait(argument: _google_showcase_v1beta1_WaitRequest, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; /** * This method will wait the requested amount of and then return. * This method showcases how a client handles a request timing out. */ - wait(argument: _google_showcase_v1beta1_WaitRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; - wait(argument: _google_showcase_v1beta1_WaitRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; - wait(argument: _google_showcase_v1beta1_WaitRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; - wait(argument: _google_showcase_v1beta1_WaitRequest, callback: (error?: grpc.ServiceError, result?: _google_longrunning_Operation__Output) => void): grpc.ClientUnaryCall; + wait(argument: _google_showcase_v1beta1_WaitRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + wait(argument: _google_showcase_v1beta1_WaitRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + wait(argument: _google_showcase_v1beta1_WaitRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + wait(argument: _google_showcase_v1beta1_WaitRequest, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; } diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index d31220186..cd27743a0 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/proto-loader", - "version": "0.6.6", + "version": "0.6.7", "author": "Google Inc.", "contributors": [ { From 472baec1ff7d17ca8dbea409eb7a23d7820208bb Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 15 Nov 2021 10:53:31 -0800 Subject: [PATCH 134/450] grpc-js: Provide full certificate in checkServerIdentity callback --- packages/grpc-js/src/channel-credentials.ts | 25 +++++---------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/packages/grpc-js/src/channel-credentials.ts b/packages/grpc-js/src/channel-credentials.ts index 675e91628..c501692c9 100644 --- a/packages/grpc-js/src/channel-credentials.ts +++ b/packages/grpc-js/src/channel-credentials.ts @@ -27,16 +27,6 @@ function verifyIsBufferOrNull(obj: any, friendlyName: string): void { } } -/** - * A certificate as received by the checkServerIdentity callback. - */ -export interface Certificate { - /** - * The raw certificate in DER form. - */ - raw: Buffer; -} - /** * A callback that will receive the expected hostname and presented peer * certificate as parameters. The callback should return an error to @@ -45,7 +35,7 @@ export interface Certificate { */ export type CheckServerIdentityCallback = ( hostname: string, - cert: Certificate + cert: PeerCertificate ) => Error | undefined; function bufferOrNullEqual(buf1: Buffer | null, buf2: Buffer | null) { @@ -192,15 +182,10 @@ class SecureChannelCredentialsImpl extends ChannelCredentials { cert: certChain || undefined, ciphers: CIPHER_SUITES, }); - this.connectionOptions = { secureContext }; - if (verifyOptions && verifyOptions.checkServerIdentity) { - this.connectionOptions.checkServerIdentity = ( - host: string, - cert: PeerCertificate - ) => { - return verifyOptions.checkServerIdentity!(host, { raw: cert.raw }); - }; - } + this.connectionOptions = { + secureContext, + checkServerIdentity: verifyOptions?.checkServerIdentity + }; } compose(callCredentials: CallCredentials): ChannelCredentials { From 3106057f5ad8f79a71d2ae411e116ad308a2e835 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 17 Nov 2021 12:36:38 -0800 Subject: [PATCH 135/450] grpc-js: Don't pass undefined checkServerIdentity --- packages/grpc-js/src/channel-credentials.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/src/channel-credentials.ts b/packages/grpc-js/src/channel-credentials.ts index c501692c9..02c9c309b 100644 --- a/packages/grpc-js/src/channel-credentials.ts +++ b/packages/grpc-js/src/channel-credentials.ts @@ -183,9 +183,12 @@ class SecureChannelCredentialsImpl extends ChannelCredentials { ciphers: CIPHER_SUITES, }); this.connectionOptions = { - secureContext, - checkServerIdentity: verifyOptions?.checkServerIdentity + secureContext }; + // Node asserts that this option is a function, so we cannot pass undefined + if (verifyOptions?.checkServerIdentity) { + this.connectionOptions.checkServerIdentity = verifyOptions.checkServerIdentity; + } } compose(callCredentials: CallCredentials): ChannelCredentials { From 8658fd5752cca9338210eb4544c6f76231fdcf51 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 18 Nov 2021 12:48:40 -0800 Subject: [PATCH 136/450] grpc-js-xds: Remove LDS and CDS code for removing RDS and EDS entries --- .../src/xds-stream-state/cds-state.ts | 6 ------ .../src/xds-stream-state/eds-state.ts | 17 ----------------- .../src/xds-stream-state/lds-state.ts | 6 ------ .../src/xds-stream-state/rds-state.ts | 10 ---------- 4 files changed, 39 deletions(-) diff --git a/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts index 5dae09fb4..01e1db135 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts @@ -149,14 +149,9 @@ export class CdsState implements XdsStreamState { } this.latestResponses = validResponses; this.latestIsV2 = isV2; - const allEdsServiceNames: Set = new Set(); const allClusterNames: Set = new Set(); for (const message of validResponses) { allClusterNames.add(message.name); - const edsServiceName = message.eds_cluster_config?.service_name ?? ''; - allEdsServiceNames.add( - edsServiceName === '' ? message.name : edsServiceName - ); const watchers = this.watchers.get(message.name) ?? []; for (const watcher of watchers) { watcher.onValidUpdate(message, isV2); @@ -164,7 +159,6 @@ export class CdsState implements XdsStreamState { } trace('Received CDS updates for cluster names ' + Array.from(allClusterNames)); this.handleMissingNames(allClusterNames); - this.edsState.handleMissingNames(allEdsServiceNames); return errorMessage; } diff --git a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts index 7d28ed5ff..7e57012cb 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts @@ -128,23 +128,6 @@ export class EdsState implements XdsStreamState { return true; } - /** - * Given a list of edsServiceNames (which may actually be the cluster name), - * for each watcher watching a name not on the list, call that watcher's - * onResourceDoesNotExist method. - * @param allClusterNames - */ - handleMissingNames(allEdsServiceNames: Set) { - for (const [edsServiceName, watcherList] of this.watchers.entries()) { - if (!allEdsServiceNames.has(edsServiceName)) { - trace('Reporting EDS resource does not exist for edsServiceName ' + edsServiceName); - for (const watcher of watcherList) { - watcher.onResourceDoesNotExist(); - } - } - } - } - handleResponses(responses: ClusterLoadAssignment__Output[], isV2: boolean) { const validResponses: ClusterLoadAssignment__Output[] = []; let errorMessage: string | null = null; diff --git a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts index 5706e3766..2797bc1a8 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts @@ -167,13 +167,8 @@ export class LdsState implements XdsStreamState { this.latestResponses = validResponses; this.latestIsV2 = isV2; const allTargetNames = new Set(); - const allRouteConfigNames = new Set(); for (const message of validResponses) { allTargetNames.add(message.name); - const httpConnectionManager = decodeSingleResource(HTTP_CONNECTION_MANGER_TYPE_URL_V3, message.api_listener!.api_listener!.value); - if (httpConnectionManager.rds) { - allRouteConfigNames.add(httpConnectionManager.rds.route_config_name); - } const watchers = this.watchers.get(message.name) ?? []; for (const watcher of watchers) { watcher.onValidUpdate(message, isV2); @@ -181,7 +176,6 @@ export class LdsState implements XdsStreamState { } trace('Received RDS response with route config names ' + Array.from(allTargetNames)); this.handleMissingNames(allTargetNames); - this.rdsState.handleMissingNames(allRouteConfigNames); return errorMessage; } diff --git a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts index 5a3854323..4f06bd2dc 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts @@ -172,16 +172,6 @@ export class RdsState implements XdsStreamState { return true; } - handleMissingNames(allRouteConfigNames: Set) { - for (const [routeConfigName, watcherList] of this.watchers.entries()) { - if (!allRouteConfigNames.has(routeConfigName)) { - for (const watcher of watcherList) { - watcher.onResourceDoesNotExist(); - } - } - } - } - handleResponses(responses: RouteConfiguration__Output[], isV2: boolean): string | null { const validResponses: RouteConfiguration__Output[] = []; let errorMessage: string | null = null; From 8b7a4a0d9e5fabe758d21150f99b0961db3dc5db Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 2 Dec 2021 16:14:03 -0500 Subject: [PATCH 137/450] grpc-js-xds: Update envoy submodule, generate CSDS code --- packages/grpc-js-xds/deps/envoy-api | 2 +- packages/grpc-js-xds/package.json | 2 +- packages/grpc-js-xds/src/generated/ads.ts | 19 + packages/grpc-js-xds/src/generated/cluster.ts | 7 + packages/grpc-js-xds/src/generated/csds.ts | 393 ++++++++++ .../grpc-js-xds/src/generated/endpoint.ts | 27 + .../envoy/admin/v3/BootstrapConfigDump.ts | 32 + .../envoy/admin/v3/ClientResourceStatus.ts | 34 + .../envoy/admin/v3/ClustersConfigDump.ts | 164 +++++ .../generated/envoy/admin/v3/ConfigDump.ts | 65 ++ .../envoy/admin/v3/EndpointsConfigDump.ts | 126 ++++ .../envoy/admin/v3/ListenersConfigDump.ts | 198 +++++ .../envoy/admin/v3/RoutesConfigDump.ts | 130 ++++ .../envoy/admin/v3/ScopedRoutesConfigDump.ts | 144 ++++ .../envoy/admin/v3/SecretsConfigDump.ts | 162 +++++ .../envoy/admin/v3/UpdateFailureState.ts | 46 ++ .../generated/envoy/api/v2/core/CidrRange.ts | 4 +- .../envoy/config/accesslog/v3/AccessLog.ts | 40 +- .../config/accesslog/v3/RuntimeFilter.ts | 8 +- .../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 | 20 +- .../envoy/config/cluster/v3/Cluster.ts | 508 +++++++++---- .../envoy/config/cluster/v3/Filter.ts | 6 +- .../config/cluster/v3/LoadBalancingPolicy.ts | 18 +- .../config/cluster/v3/OutlierDetection.ts | 40 +- .../config/core/v3/AggregatedConfigSource.ts | 4 +- .../core/v3/AlternateProtocolsCacheOptions.ts | 72 ++ .../envoy/config/core/v3/BackoffStrategy.ts | 12 +- .../envoy/config/core/v3/BindConfig.ts | 4 +- .../envoy/config/core/v3/CidrRange.ts | 4 +- .../envoy/config/core/v3/ConfigSource.ts | 12 +- .../config/core/v3/DnsResolutionConfig.ts | 42 ++ .../config/core/v3/DnsResolverOptions.ts | 36 + .../config/core/v3/EnvoyInternalAddress.ts | 4 +- .../envoy/config/core/v3/GrpcService.ts | 22 +- .../envoy/config/core/v3/HeaderValueOption.ts | 35 + .../envoy/config/core/v3/HealthCheck.ts | 84 ++- .../config/core/v3/Http1ProtocolOptions.ts | 23 +- .../config/core/v3/Http2ProtocolOptions.ts | 8 + .../config/core/v3/Http3ProtocolOptions.ts | 54 +- .../config/core/v3/HttpProtocolOptions.ts | 44 +- .../envoy/config/core/v3/KeepaliveSettings.ts | 18 + .../envoy/config/core/v3/Locality.ts | 8 +- .../envoy/config/core/v3/Metadata.ts | 27 + .../generated/envoy/config/core/v3/Node.ts | 33 +- .../envoy/config/core/v3/QueryParameter.ts | 30 + .../config/core/v3/QuicProtocolOptions.ts | 69 ++ .../envoy/config/core/v3/RetryPolicy.ts | 4 +- .../core/v3/RuntimeFractionalPercent.ts | 4 +- .../core/v3/SchemeHeaderTransformation.ts | 24 + .../envoy/config/core/v3/SelfConfigSource.ts | 4 +- .../envoy/config/core/v3/SocketAddress.ts | 20 +- .../core/v3/SubstitutionFormatString.ts | 2 + .../envoy/config/core/v3/TransportSocket.ts | 4 +- .../envoy/config/core/v3/UdpSocketConfig.ts | 45 ++ .../core/v3/UpstreamHttpProtocolOptions.ts | 42 +- .../endpoint/v3/ClusterLoadAssignment.ts | 8 +- .../envoy/config/endpoint/v3/ClusterStats.ts | 4 +- .../envoy/config/endpoint/v3/Endpoint.ts | 16 +- .../envoy/config/endpoint/v3/LbEndpoint.ts | 4 +- .../endpoint/v3/LedsClusterLocalityConfig.ts | 35 + .../config/endpoint/v3/LocalityLbEndpoints.ts | 53 +- .../endpoint/v3/UpstreamLocalityStats.ts | 8 +- .../envoy/config/listener/v3/ApiListener.ts | 6 +- .../envoy/config/listener/v3/Filter.ts | 2 + .../envoy/config/listener/v3/FilterChain.ts | 10 +- .../config/listener/v3/FilterChainMatch.ts | 34 +- .../envoy/config/listener/v3/Listener.ts | 237 ++++-- .../config/listener/v3/ListenerFilter.ts | 22 +- .../v3/ListenerFilterChainMatchPredicate.ts | 4 +- .../config/listener/v3/QuicProtocolOptions.ts | 97 +++ .../config/listener/v3/UdpListenerConfig.ts | 49 +- .../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 + .../config/route/v3/ClusterSpecifierPlugin.ts | 23 + .../envoy/config/route/v3/CorsPolicy.ts | 8 +- .../config/route/v3/DirectResponseAction.ts | 8 +- .../envoy/config/route/v3/FilterConfig.ts | 12 +- .../envoy/config/route/v3/HeaderMatcher.ts | 43 +- .../envoy/config/route/v3/HedgePolicy.ts | 4 +- .../config/route/v3/InternalRedirectPolicy.ts | 6 +- .../config/route/v3/NonForwardingAction.ts | 14 + .../envoy/config/route/v3/RateLimit.ts | 32 +- .../envoy/config/route/v3/RedirectAction.ts | 4 +- .../envoy/config/route/v3/RetryPolicy.ts | 85 ++- .../generated/envoy/config/route/v3/Route.ts | 55 +- .../envoy/config/route/v3/RouteAction.ts | 122 ++-- .../config/route/v3/RouteConfiguration.ts | 59 +- .../envoy/config/route/v3/RouteMatch.ts | 43 +- .../route/v3/ScopedRouteConfiguration.ts | 32 +- .../envoy/config/route/v3/Tracing.ts | 4 +- .../envoy/config/route/v3/VirtualHost.ts | 32 +- .../envoy/config/route/v3/WeightedCluster.ts | 108 ++- .../envoy/config/trace/v3/Tracing.ts | 54 +- .../filters/common/fault/v3/FaultDelay.ts | 18 +- .../filters/http/fault/v3/HTTPFault.ts | 22 +- .../v3/EnvoyMobileHttpConnectionManager.ts | 29 + .../v3/HttpConnectionManager.ts | 350 +++++++-- .../http_connection_manager/v3/HttpFilter.ts | 24 +- .../http_connection_manager/v3/ScopedRds.ts | 10 + .../v3/ScopedRoutes.ts | 28 +- .../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 ++ .../discovery/v3/DeltaDiscoveryRequest.ts | 4 +- .../service/discovery/v3/DiscoveryRequest.ts | 4 +- .../load_stats/v3/LoadStatsResponse.ts | 4 +- .../envoy/service/status/v3/ClientConfig.ts | 159 ++++ .../service/status/v3/ClientConfigStatus.ts | 26 + .../status/v3/ClientStatusDiscoveryService.ts | 45 ++ .../service/status/v3/ClientStatusRequest.ts | 34 + .../service/status/v3/ClientStatusResponse.ts | 17 + .../envoy/service/status/v3/ConfigStatus.ts | 30 + .../envoy/service/status/v3/PerXdsConfig.ts | 67 ++ .../envoy/type/http/v3/PathTransformation.ts | 92 +++ .../envoy/type/matcher/v3/MetadataMatcher.ts | 8 + .../envoy/type/matcher/v3/NodeMatcher.ts | 34 + .../envoy/type/matcher/v3/StringMatcher.ts | 8 +- .../envoy/type/matcher/v3/StructMatcher.ts | 153 ++++ .../envoy/type/metadata/v3/MetadataKey.ts | 4 +- .../envoy/type/metadata/v3/MetadataKind.ts | 12 +- .../envoy/type/tracing/v3/CustomTag.ts | 8 +- packages/grpc-js-xds/src/generated/fault.ts | 7 + .../generated/google/api/CustomHttpPattern.ts | 30 + .../src/generated/google/api/Http.ts | 49 ++ .../src/generated/google/api/HttpRule.ts | 680 ++++++++++++++++++ .../google/protobuf/EnumValueOptions.ts | 2 + .../generated/google/protobuf/FieldOptions.ts | 5 + .../google/protobuf/MethodOptions.ts | 3 + .../src/generated/http_connection_manager.ts | 13 + .../grpc-js-xds/src/generated/listener.ts | 15 + packages/grpc-js-xds/src/generated/lrs.ts | 19 + packages/grpc-js-xds/src/generated/route.ts | 8 + packages/grpc-js-xds/src/resolver-xds.ts | 5 + 163 files changed, 8798 insertions(+), 856 deletions(-) create mode 100644 packages/grpc-js-xds/src/generated/csds.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/admin/v3/BootstrapConfigDump.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/admin/v3/ClientResourceStatus.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/admin/v3/ClustersConfigDump.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/admin/v3/ConfigDump.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/admin/v3/EndpointsConfigDump.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/admin/v3/ListenersConfigDump.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/admin/v3/RoutesConfigDump.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/admin/v3/ScopedRoutesConfigDump.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/admin/v3/SecretsConfigDump.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/admin/v3/UpdateFailureState.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Admin.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Bootstrap.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/ClusterManager.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/CustomInlineHeader.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/FatalAction.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/LayeredRuntime.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Runtime.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/RuntimeLayer.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Watchdog.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Watchdogs.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/AlternateProtocolsCacheOptions.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/DnsResolutionConfig.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/DnsResolverOptions.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/QueryParameter.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/QuicProtocolOptions.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/SchemeHeaderTransformation.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/core/v3/UdpSocketConfig.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LedsClusterLocalityConfig.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/listener/v3/QuicProtocolOptions.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/DogStatsdSink.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/HistogramBucketSettings.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/HystrixSink.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsConfig.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsMatcher.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsSink.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsdSink.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/TagSpecifier.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/overload/v3/BufferFactoryConfig.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/overload/v3/OverloadAction.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/overload/v3/OverloadManager.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ResourceMonitor.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ScaleTimersOverloadActionConfig.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ScaledTrigger.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ThresholdTrigger.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/overload/v3/Trigger.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/route/v3/ClusterSpecifierPlugin.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/config/route/v3/NonForwardingAction.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/EnvoyMobileHttpConnectionManager.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/CertificateProviderPluginInstance.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/CertificateValidationContext.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/GenericSecret.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/PrivateKeyProvider.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/SdsSecretConfig.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/Secret.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/TlsCertificate.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/TlsParameters.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/TlsSessionTicketKeys.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientConfig.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientConfigStatus.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientStatusDiscoveryService.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientStatusRequest.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientStatusResponse.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/service/status/v3/ConfigStatus.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/service/status/v3/PerXdsConfig.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/type/http/v3/PathTransformation.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/NodeMatcher.ts create mode 100644 packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/StructMatcher.ts create mode 100644 packages/grpc-js-xds/src/generated/google/api/CustomHttpPattern.ts create mode 100644 packages/grpc-js-xds/src/generated/google/api/Http.ts create mode 100644 packages/grpc-js-xds/src/generated/google/api/HttpRule.ts diff --git a/packages/grpc-js-xds/deps/envoy-api b/packages/grpc-js-xds/deps/envoy-api index 18b54850c..20b1b5fce 160000 --- a/packages/grpc-js-xds/deps/envoy-api +++ b/packages/grpc-js-xds/deps/envoy-api @@ -1 +1 @@ -Subproject commit 18b54850c9b7ba29a4ab67cbd7ed7eab7b0bbdb2 +Subproject commit 20b1b5fcee88a20a08b71051a961181839ec7268 diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index fca6ab80d..2ead8f1e8 100644 --- a/packages/grpc-js-xds/package.json +++ b/packages/grpc-js-xds/package.json @@ -12,7 +12,7 @@ "prepare": "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/v2/ads.proto envoy/service/load_stats/v2/lrs.proto 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", + "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/v2/ads.proto envoy/service/load_stats/v2/lrs.proto 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", "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" }, "repository": { diff --git a/packages/grpc-js-xds/src/generated/ads.ts b/packages/grpc-js-xds/src/generated/ads.ts index f8e336131..e0e46bb25 100644 --- a/packages/grpc-js-xds/src/generated/ads.ts +++ b/packages/grpc-js-xds/src/generated/ads.ts @@ -10,6 +10,8 @@ type SubtypeConstructor any, Subtype> export interface ProtoGrpcType { envoy: { + annotations: { + } api: { v2: { DeltaDiscoveryRequest: MessageTypeDefinition @@ -72,6 +74,7 @@ export interface ProtoGrpcType { Metadata: MessageTypeDefinition Node: MessageTypeDefinition Pipe: MessageTypeDefinition + QueryParameter: MessageTypeDefinition RemoteDataSource: MessageTypeDefinition RequestMethod: EnumTypeDefinition RetryPolicy: MessageTypeDefinition @@ -213,5 +216,21 @@ export interface ProtoGrpcType { UInt32Rules: MessageTypeDefinition UInt64Rules: MessageTypeDefinition } + xds: { + annotations: { + v3: { + FieldStatusAnnotation: MessageTypeDefinition + FileStatusAnnotation: MessageTypeDefinition + MessageStatusAnnotation: MessageTypeDefinition + PackageVersionStatus: EnumTypeDefinition + StatusAnnotation: MessageTypeDefinition + } + } + core: { + v3: { + ContextParams: MessageTypeDefinition + } + } + } } diff --git a/packages/grpc-js-xds/src/generated/cluster.ts b/packages/grpc-js-xds/src/generated/cluster.ts index 6c2f7aa6f..78ac3bbd3 100644 --- a/packages/grpc-js-xds/src/generated/cluster.ts +++ b/packages/grpc-js-xds/src/generated/cluster.ts @@ -28,6 +28,7 @@ export interface ProtoGrpcType { v3: { Address: MessageTypeDefinition AggregatedConfigSource: MessageTypeDefinition + AlternateProtocolsCacheOptions: MessageTypeDefinition ApiConfigSource: MessageTypeDefinition ApiVersion: EnumTypeDefinition AsyncDataSource: MessageTypeDefinition @@ -38,6 +39,8 @@ export interface ProtoGrpcType { ConfigSource: MessageTypeDefinition ControlPlane: MessageTypeDefinition DataSource: MessageTypeDefinition + DnsResolutionConfig: MessageTypeDefinition + DnsResolverOptions: MessageTypeDefinition EnvoyInternalAddress: MessageTypeDefinition EventServiceConfig: MessageTypeDefinition Extension: MessageTypeDefinition @@ -59,6 +62,8 @@ export interface ProtoGrpcType { Metadata: MessageTypeDefinition Node: MessageTypeDefinition Pipe: MessageTypeDefinition + QueryParameter: MessageTypeDefinition + QuicProtocolOptions: MessageTypeDefinition RateLimitSettings: MessageTypeDefinition RemoteDataSource: MessageTypeDefinition RequestMethod: EnumTypeDefinition @@ -69,6 +74,7 @@ export interface ProtoGrpcType { RuntimeFractionalPercent: MessageTypeDefinition RuntimePercent: MessageTypeDefinition RuntimeUInt32: MessageTypeDefinition + SchemeHeaderTransformation: MessageTypeDefinition SelfConfigSource: MessageTypeDefinition SocketAddress: MessageTypeDefinition SocketOption: MessageTypeDefinition @@ -86,6 +92,7 @@ export interface ProtoGrpcType { ClusterLoadAssignment: MessageTypeDefinition Endpoint: MessageTypeDefinition LbEndpoint: MessageTypeDefinition + LedsClusterLocalityConfig: MessageTypeDefinition LocalityLbEndpoints: MessageTypeDefinition } } diff --git a/packages/grpc-js-xds/src/generated/csds.ts b/packages/grpc-js-xds/src/generated/csds.ts new file mode 100644 index 000000000..58e903bc9 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/csds.ts @@ -0,0 +1,393 @@ +import type * as grpc from '@grpc/grpc-js'; +import type { EnumTypeDefinition, MessageTypeDefinition } from '@grpc/proto-loader'; + +import type { ClientStatusDiscoveryServiceClient as _envoy_service_status_v3_ClientStatusDiscoveryServiceClient, ClientStatusDiscoveryServiceDefinition as _envoy_service_status_v3_ClientStatusDiscoveryServiceDefinition } from './envoy/service/status/v3/ClientStatusDiscoveryService'; + +type SubtypeConstructor any, Subtype> = { + new(...args: ConstructorParameters): Subtype; +}; + +export interface ProtoGrpcType { + envoy: { + admin: { + v3: { + BootstrapConfigDump: MessageTypeDefinition + ClientResourceStatus: EnumTypeDefinition + ClustersConfigDump: MessageTypeDefinition + ConfigDump: MessageTypeDefinition + EndpointsConfigDump: MessageTypeDefinition + ListenersConfigDump: MessageTypeDefinition + RoutesConfigDump: MessageTypeDefinition + ScopedRoutesConfigDump: MessageTypeDefinition + SecretsConfigDump: MessageTypeDefinition + UpdateFailureState: MessageTypeDefinition + } + } + annotations: { + } + config: { + accesslog: { + v3: { + AccessLog: MessageTypeDefinition + AccessLogFilter: MessageTypeDefinition + AndFilter: MessageTypeDefinition + ComparisonFilter: MessageTypeDefinition + DurationFilter: MessageTypeDefinition + ExtensionFilter: MessageTypeDefinition + GrpcStatusFilter: MessageTypeDefinition + HeaderFilter: MessageTypeDefinition + MetadataFilter: MessageTypeDefinition + NotHealthCheckFilter: MessageTypeDefinition + OrFilter: MessageTypeDefinition + ResponseFlagFilter: MessageTypeDefinition + RuntimeFilter: MessageTypeDefinition + StatusCodeFilter: MessageTypeDefinition + TraceableFilter: MessageTypeDefinition + } + } + bootstrap: { + v3: { + Admin: MessageTypeDefinition + Bootstrap: MessageTypeDefinition + ClusterManager: MessageTypeDefinition + CustomInlineHeader: MessageTypeDefinition + FatalAction: MessageTypeDefinition + LayeredRuntime: MessageTypeDefinition + Runtime: MessageTypeDefinition + RuntimeLayer: MessageTypeDefinition + Watchdog: MessageTypeDefinition + Watchdogs: MessageTypeDefinition + } + } + cluster: { + v3: { + CircuitBreakers: MessageTypeDefinition + Cluster: MessageTypeDefinition + ClusterCollection: MessageTypeDefinition + Filter: MessageTypeDefinition + LoadBalancingPolicy: MessageTypeDefinition + OutlierDetection: MessageTypeDefinition + TrackClusterStats: MessageTypeDefinition + UpstreamBindConfig: MessageTypeDefinition + UpstreamConnectionOptions: MessageTypeDefinition + } + } + core: { + v3: { + Address: MessageTypeDefinition + AggregatedConfigSource: MessageTypeDefinition + AlternateProtocolsCacheOptions: MessageTypeDefinition + ApiConfigSource: MessageTypeDefinition + ApiVersion: EnumTypeDefinition + AsyncDataSource: MessageTypeDefinition + BackoffStrategy: MessageTypeDefinition + BindConfig: MessageTypeDefinition + BuildVersion: MessageTypeDefinition + CidrRange: MessageTypeDefinition + ConfigSource: MessageTypeDefinition + ControlPlane: MessageTypeDefinition + DataSource: MessageTypeDefinition + DnsResolutionConfig: MessageTypeDefinition + DnsResolverOptions: MessageTypeDefinition + EnvoyInternalAddress: MessageTypeDefinition + EventServiceConfig: MessageTypeDefinition + Extension: MessageTypeDefinition + ExtensionConfigSource: MessageTypeDefinition + GrpcProtocolOptions: MessageTypeDefinition + GrpcService: MessageTypeDefinition + HeaderMap: MessageTypeDefinition + HeaderValue: MessageTypeDefinition + HeaderValueOption: MessageTypeDefinition + HealthCheck: MessageTypeDefinition + HealthStatus: EnumTypeDefinition + Http1ProtocolOptions: MessageTypeDefinition + Http2ProtocolOptions: MessageTypeDefinition + Http3ProtocolOptions: MessageTypeDefinition + HttpProtocolOptions: MessageTypeDefinition + HttpUri: MessageTypeDefinition + KeepaliveSettings: MessageTypeDefinition + Locality: MessageTypeDefinition + Metadata: MessageTypeDefinition + Node: MessageTypeDefinition + Pipe: MessageTypeDefinition + ProxyProtocolConfig: MessageTypeDefinition + QueryParameter: MessageTypeDefinition + QuicProtocolOptions: MessageTypeDefinition + RateLimitSettings: MessageTypeDefinition + RemoteDataSource: MessageTypeDefinition + RequestMethod: EnumTypeDefinition + RetryPolicy: MessageTypeDefinition + RoutingPriority: EnumTypeDefinition + RuntimeDouble: MessageTypeDefinition + RuntimeFeatureFlag: MessageTypeDefinition + RuntimeFractionalPercent: MessageTypeDefinition + RuntimePercent: MessageTypeDefinition + RuntimeUInt32: MessageTypeDefinition + SchemeHeaderTransformation: MessageTypeDefinition + SelfConfigSource: MessageTypeDefinition + SocketAddress: MessageTypeDefinition + SocketOption: MessageTypeDefinition + TcpKeepalive: MessageTypeDefinition + TcpProtocolOptions: MessageTypeDefinition + TrafficDirection: EnumTypeDefinition + TransportSocket: MessageTypeDefinition + TypedExtensionConfig: MessageTypeDefinition + UdpSocketConfig: MessageTypeDefinition + UpstreamHttpProtocolOptions: MessageTypeDefinition + WatchedDirectory: MessageTypeDefinition + } + } + endpoint: { + v3: { + ClusterLoadAssignment: MessageTypeDefinition + Endpoint: MessageTypeDefinition + LbEndpoint: MessageTypeDefinition + LedsClusterLocalityConfig: MessageTypeDefinition + LocalityLbEndpoints: MessageTypeDefinition + } + } + listener: { + v3: { + ActiveRawUdpListenerConfig: MessageTypeDefinition + ApiListener: MessageTypeDefinition + Filter: MessageTypeDefinition + FilterChain: MessageTypeDefinition + FilterChainMatch: MessageTypeDefinition + Listener: MessageTypeDefinition + ListenerCollection: MessageTypeDefinition + ListenerFilter: MessageTypeDefinition + ListenerFilterChainMatchPredicate: MessageTypeDefinition + QuicProtocolOptions: MessageTypeDefinition + UdpListenerConfig: MessageTypeDefinition + } + } + metrics: { + v3: { + DogStatsdSink: MessageTypeDefinition + HistogramBucketSettings: MessageTypeDefinition + HystrixSink: MessageTypeDefinition + StatsConfig: MessageTypeDefinition + StatsMatcher: MessageTypeDefinition + StatsSink: MessageTypeDefinition + StatsdSink: MessageTypeDefinition + TagSpecifier: MessageTypeDefinition + } + } + overload: { + v3: { + BufferFactoryConfig: MessageTypeDefinition + OverloadAction: MessageTypeDefinition + OverloadManager: MessageTypeDefinition + ResourceMonitor: MessageTypeDefinition + ScaleTimersOverloadActionConfig: MessageTypeDefinition + ScaledTrigger: MessageTypeDefinition + ThresholdTrigger: MessageTypeDefinition + Trigger: MessageTypeDefinition + } + } + route: { + v3: { + CorsPolicy: MessageTypeDefinition + Decorator: MessageTypeDefinition + DirectResponseAction: MessageTypeDefinition + FilterAction: MessageTypeDefinition + FilterConfig: MessageTypeDefinition + HeaderMatcher: MessageTypeDefinition + HedgePolicy: MessageTypeDefinition + InternalRedirectPolicy: MessageTypeDefinition + NonForwardingAction: MessageTypeDefinition + QueryParameterMatcher: MessageTypeDefinition + RateLimit: MessageTypeDefinition + RedirectAction: MessageTypeDefinition + RetryPolicy: MessageTypeDefinition + Route: MessageTypeDefinition + RouteAction: MessageTypeDefinition + RouteMatch: MessageTypeDefinition + Tracing: MessageTypeDefinition + VirtualCluster: MessageTypeDefinition + VirtualHost: MessageTypeDefinition + WeightedCluster: MessageTypeDefinition + } + } + trace: { + v3: { + Tracing: MessageTypeDefinition + } + } + } + extensions: { + transport_sockets: { + tls: { + v3: { + CertificateProviderPluginInstance: MessageTypeDefinition + CertificateValidationContext: MessageTypeDefinition + GenericSecret: MessageTypeDefinition + PrivateKeyProvider: MessageTypeDefinition + SdsSecretConfig: MessageTypeDefinition + Secret: MessageTypeDefinition + TlsCertificate: MessageTypeDefinition + TlsParameters: MessageTypeDefinition + TlsSessionTicketKeys: MessageTypeDefinition + } + } + } + } + service: { + status: { + v3: { + ClientConfig: MessageTypeDefinition + ClientConfigStatus: EnumTypeDefinition + /** + * CSDS is Client Status Discovery Service. It can be used to get the status of + * an xDS-compliant client from the management server's point of view. It can + * also be used to get the current xDS states directly from the client. + */ + ClientStatusDiscoveryService: SubtypeConstructor & { service: _envoy_service_status_v3_ClientStatusDiscoveryServiceDefinition } + ClientStatusRequest: MessageTypeDefinition + ClientStatusResponse: MessageTypeDefinition + ConfigStatus: EnumTypeDefinition + PerXdsConfig: MessageTypeDefinition + } + } + } + type: { + matcher: { + v3: { + DoubleMatcher: MessageTypeDefinition + ListMatcher: MessageTypeDefinition + ListStringMatcher: MessageTypeDefinition + MetadataMatcher: MessageTypeDefinition + NodeMatcher: MessageTypeDefinition + RegexMatchAndSubstitute: MessageTypeDefinition + RegexMatcher: MessageTypeDefinition + StringMatcher: MessageTypeDefinition + StructMatcher: MessageTypeDefinition + ValueMatcher: MessageTypeDefinition + } + } + metadata: { + v3: { + MetadataKey: MessageTypeDefinition + MetadataKind: MessageTypeDefinition + } + } + tracing: { + v3: { + CustomTag: MessageTypeDefinition + } + } + v3: { + CodecClientType: EnumTypeDefinition + DoubleRange: MessageTypeDefinition + FractionalPercent: MessageTypeDefinition + Int32Range: MessageTypeDefinition + Int64Range: MessageTypeDefinition + Percent: MessageTypeDefinition + SemanticVersion: MessageTypeDefinition + } + } + } + google: { + api: { + CustomHttpPattern: MessageTypeDefinition + Http: MessageTypeDefinition + HttpRule: MessageTypeDefinition + } + protobuf: { + Any: MessageTypeDefinition + BoolValue: MessageTypeDefinition + BytesValue: MessageTypeDefinition + DescriptorProto: MessageTypeDefinition + DoubleValue: MessageTypeDefinition + Duration: MessageTypeDefinition + Empty: MessageTypeDefinition + EnumDescriptorProto: MessageTypeDefinition + EnumOptions: MessageTypeDefinition + EnumValueDescriptorProto: MessageTypeDefinition + EnumValueOptions: MessageTypeDefinition + FieldDescriptorProto: MessageTypeDefinition + FieldOptions: MessageTypeDefinition + FileDescriptorProto: MessageTypeDefinition + FileDescriptorSet: MessageTypeDefinition + FileOptions: MessageTypeDefinition + FloatValue: MessageTypeDefinition + GeneratedCodeInfo: MessageTypeDefinition + Int32Value: MessageTypeDefinition + Int64Value: MessageTypeDefinition + ListValue: MessageTypeDefinition + MessageOptions: MessageTypeDefinition + MethodDescriptorProto: MessageTypeDefinition + MethodOptions: MessageTypeDefinition + NullValue: EnumTypeDefinition + OneofDescriptorProto: MessageTypeDefinition + OneofOptions: MessageTypeDefinition + ServiceDescriptorProto: MessageTypeDefinition + ServiceOptions: MessageTypeDefinition + SourceCodeInfo: MessageTypeDefinition + StringValue: MessageTypeDefinition + Struct: MessageTypeDefinition + Timestamp: MessageTypeDefinition + UInt32Value: MessageTypeDefinition + UInt64Value: MessageTypeDefinition + UninterpretedOption: MessageTypeDefinition + Value: MessageTypeDefinition + } + } + udpa: { + annotations: { + FieldMigrateAnnotation: MessageTypeDefinition + FieldSecurityAnnotation: MessageTypeDefinition + FileMigrateAnnotation: MessageTypeDefinition + MigrateAnnotation: MessageTypeDefinition + PackageVersionStatus: EnumTypeDefinition + StatusAnnotation: MessageTypeDefinition + VersioningAnnotation: MessageTypeDefinition + } + } + validate: { + AnyRules: MessageTypeDefinition + BoolRules: MessageTypeDefinition + BytesRules: MessageTypeDefinition + DoubleRules: MessageTypeDefinition + DurationRules: MessageTypeDefinition + EnumRules: MessageTypeDefinition + FieldRules: MessageTypeDefinition + Fixed32Rules: MessageTypeDefinition + Fixed64Rules: MessageTypeDefinition + FloatRules: MessageTypeDefinition + Int32Rules: MessageTypeDefinition + Int64Rules: MessageTypeDefinition + KnownRegex: EnumTypeDefinition + MapRules: MessageTypeDefinition + MessageRules: MessageTypeDefinition + RepeatedRules: MessageTypeDefinition + SFixed32Rules: MessageTypeDefinition + SFixed64Rules: MessageTypeDefinition + SInt32Rules: MessageTypeDefinition + SInt64Rules: MessageTypeDefinition + StringRules: MessageTypeDefinition + TimestampRules: MessageTypeDefinition + UInt32Rules: MessageTypeDefinition + UInt64Rules: MessageTypeDefinition + } + xds: { + annotations: { + v3: { + FieldStatusAnnotation: MessageTypeDefinition + FileStatusAnnotation: MessageTypeDefinition + MessageStatusAnnotation: MessageTypeDefinition + PackageVersionStatus: EnumTypeDefinition + StatusAnnotation: MessageTypeDefinition + } + } + core: { + v3: { + Authority: MessageTypeDefinition + CollectionEntry: MessageTypeDefinition + ContextParams: MessageTypeDefinition + ResourceLocator: MessageTypeDefinition + } + } + } +} + diff --git a/packages/grpc-js-xds/src/generated/endpoint.ts b/packages/grpc-js-xds/src/generated/endpoint.ts index 630bdeb62..9a87bc9a5 100644 --- a/packages/grpc-js-xds/src/generated/endpoint.ts +++ b/packages/grpc-js-xds/src/generated/endpoint.ts @@ -8,15 +8,21 @@ type SubtypeConstructor any, Subtype> export interface ProtoGrpcType { envoy: { + annotations: { + } config: { core: { v3: { Address: MessageTypeDefinition + AggregatedConfigSource: MessageTypeDefinition + ApiConfigSource: MessageTypeDefinition + ApiVersion: EnumTypeDefinition AsyncDataSource: MessageTypeDefinition BackoffStrategy: MessageTypeDefinition BindConfig: MessageTypeDefinition BuildVersion: MessageTypeDefinition CidrRange: MessageTypeDefinition + ConfigSource: MessageTypeDefinition ControlPlane: MessageTypeDefinition DataSource: MessageTypeDefinition EnvoyInternalAddress: MessageTypeDefinition @@ -33,6 +39,8 @@ export interface ProtoGrpcType { Metadata: MessageTypeDefinition Node: MessageTypeDefinition Pipe: MessageTypeDefinition + QueryParameter: MessageTypeDefinition + RateLimitSettings: MessageTypeDefinition RemoteDataSource: MessageTypeDefinition RequestMethod: EnumTypeDefinition RetryPolicy: MessageTypeDefinition @@ -42,6 +50,7 @@ export interface ProtoGrpcType { RuntimeFractionalPercent: MessageTypeDefinition RuntimePercent: MessageTypeDefinition RuntimeUInt32: MessageTypeDefinition + SelfConfigSource: MessageTypeDefinition SocketAddress: MessageTypeDefinition SocketOption: MessageTypeDefinition TcpKeepalive: MessageTypeDefinition @@ -55,6 +64,7 @@ export interface ProtoGrpcType { ClusterLoadAssignment: MessageTypeDefinition Endpoint: MessageTypeDefinition LbEndpoint: MessageTypeDefinition + LedsClusterLocalityConfig: MessageTypeDefinition LocalityLbEndpoints: MessageTypeDefinition } } @@ -156,5 +166,22 @@ export interface ProtoGrpcType { UInt32Rules: MessageTypeDefinition UInt64Rules: MessageTypeDefinition } + xds: { + annotations: { + v3: { + FieldStatusAnnotation: MessageTypeDefinition + FileStatusAnnotation: MessageTypeDefinition + MessageStatusAnnotation: MessageTypeDefinition + PackageVersionStatus: EnumTypeDefinition + StatusAnnotation: MessageTypeDefinition + } + } + core: { + v3: { + Authority: MessageTypeDefinition + ContextParams: MessageTypeDefinition + } + } + } } 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 new file mode 100644 index 000000000..d47f00ef3 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/admin/v3/BootstrapConfigDump.ts @@ -0,0 +1,32 @@ +// 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 new file mode 100644 index 000000000..31c3a813a --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/admin/v3/ClientResourceStatus.ts @@ -0,0 +1,34 @@ +// Original file: deps/envoy-api/envoy/admin/v3/config_dump.proto + +/** + * 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 { + /** + * 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, +} 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 new file mode 100644 index 000000000..ab7c528bf --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/admin/v3/ClustersConfigDump.ts @@ -0,0 +1,164 @@ +// 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'; +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'; + +/** + * Describes a dynamically loaded cluster via the CDS API. + * [#next-free-field: 6] + */ +export interface _envoy_admin_v3_ClustersConfigDump_DynamicCluster { + /** + * This is the per-resource version information. This version is currently taken from the + * :ref:`version_info ` field at the time + * that the cluster was loaded. In the future, discrete per-cluster versions may be supported by + * the API. + */ + 'version_info'?: (string); + /** + * The cluster config. + */ + 'cluster'?: (_google_protobuf_Any | null); + /** + * The timestamp when the Cluster was last updated. + */ + 'last_updated'?: (_google_protobuf_Timestamp | 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); +} + +/** + * Describes a dynamically loaded cluster via the CDS API. + * [#next-free-field: 6] + */ +export interface _envoy_admin_v3_ClustersConfigDump_DynamicCluster__Output { + /** + * This is the per-resource version information. This version is currently taken from the + * :ref:`version_info ` field at the time + * that the cluster was loaded. In the future, discrete per-cluster versions may be supported by + * the API. + */ + 'version_info': (string); + /** + * The cluster config. + */ + 'cluster': (_google_protobuf_Any__Output | null); + /** + * The timestamp when the Cluster was last updated. + */ + 'last_updated': (_google_protobuf_Timestamp__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); +} + +/** + * Describes a statically loaded cluster. + */ +export interface _envoy_admin_v3_ClustersConfigDump_StaticCluster { + /** + * The cluster config. + */ + 'cluster'?: (_google_protobuf_Any | null); + /** + * The timestamp when the Cluster was last updated. + */ + 'last_updated'?: (_google_protobuf_Timestamp | null); +} + +/** + * Describes a statically loaded cluster. + */ +export interface _envoy_admin_v3_ClustersConfigDump_StaticCluster__Output { + /** + * The cluster config. + */ + 'cluster': (_google_protobuf_Any__Output | null); + /** + * The timestamp when the Cluster was last updated. + */ + 'last_updated': (_google_protobuf_Timestamp__Output | null); +} + +/** + * Envoy's cluster manager fills this message with all currently known clusters. Cluster + * configuration information can be used to recreate an Envoy configuration by populating all + * clusters as static clusters or by returning them in a CDS response. + */ +export interface ClustersConfigDump { + /** + * This is the :ref:`version_info ` in the + * last processed CDS discovery response. If there are only static bootstrap clusters, this field + * will be "". + */ + 'version_info'?: (string); + /** + * The statically loaded cluster configs. + */ + 'static_clusters'?: (_envoy_admin_v3_ClustersConfigDump_StaticCluster)[]; + /** + * The dynamically loaded active clusters. These are clusters that are available to service + * data plane traffic. + */ + 'dynamic_active_clusters'?: (_envoy_admin_v3_ClustersConfigDump_DynamicCluster)[]; + /** + * The dynamically loaded warming clusters. These are clusters that are currently undergoing + * warming in preparation to service data plane traffic. Note that if attempting to recreate an + * Envoy configuration from a configuration dump, the warming clusters should generally be + * discarded. + */ + 'dynamic_warming_clusters'?: (_envoy_admin_v3_ClustersConfigDump_DynamicCluster)[]; +} + +/** + * Envoy's cluster manager fills this message with all currently known clusters. Cluster + * configuration information can be used to recreate an Envoy configuration by populating all + * clusters as static clusters or by returning them in a CDS response. + */ +export interface ClustersConfigDump__Output { + /** + * This is the :ref:`version_info ` in the + * last processed CDS discovery response. If there are only static bootstrap clusters, this field + * will be "". + */ + 'version_info': (string); + /** + * The statically loaded cluster configs. + */ + 'static_clusters': (_envoy_admin_v3_ClustersConfigDump_StaticCluster__Output)[]; + /** + * The dynamically loaded active clusters. These are clusters that are available to service + * data plane traffic. + */ + 'dynamic_active_clusters': (_envoy_admin_v3_ClustersConfigDump_DynamicCluster__Output)[]; + /** + * The dynamically loaded warming clusters. These are clusters that are currently undergoing + * warming in preparation to service data plane traffic. Note that if attempting to recreate an + * Envoy configuration from a configuration dump, the warming clusters should generally be + * discarded. + */ + 'dynamic_warming_clusters': (_envoy_admin_v3_ClustersConfigDump_DynamicCluster__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 new file mode 100644 index 000000000..8a0ab65c2 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/admin/v3/ConfigDump.ts @@ -0,0 +1,65 @@ +// 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/EndpointsConfigDump.ts b/packages/grpc-js-xds/src/generated/envoy/admin/v3/EndpointsConfigDump.ts new file mode 100644 index 000000000..d68b27e7c --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/admin/v3/EndpointsConfigDump.ts @@ -0,0 +1,126 @@ +// 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'; +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'; + +/** + * [#next-free-field: 6] + */ +export interface _envoy_admin_v3_EndpointsConfigDump_DynamicEndpointConfig { + /** + * [#not-implemented-hide:] This is the per-resource version information. This version is currently taken from the + * :ref:`version_info ` field at the time that + * the endpoint configuration was loaded. + */ + 'version_info'?: (string); + /** + * The endpoint config. + */ + 'endpoint_config'?: (_google_protobuf_Any | null); + /** + * [#not-implemented-hide:] The timestamp when the Endpoint was last updated. + */ + 'last_updated'?: (_google_protobuf_Timestamp | 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); +} + +/** + * [#next-free-field: 6] + */ +export interface _envoy_admin_v3_EndpointsConfigDump_DynamicEndpointConfig__Output { + /** + * [#not-implemented-hide:] This is the per-resource version information. This version is currently taken from the + * :ref:`version_info ` field at the time that + * the endpoint configuration was loaded. + */ + 'version_info': (string); + /** + * The endpoint config. + */ + 'endpoint_config': (_google_protobuf_Any__Output | null); + /** + * [#not-implemented-hide:] The timestamp when the Endpoint was last updated. + */ + 'last_updated': (_google_protobuf_Timestamp__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); +} + +export interface _envoy_admin_v3_EndpointsConfigDump_StaticEndpointConfig { + /** + * The endpoint config. + */ + 'endpoint_config'?: (_google_protobuf_Any | null); + /** + * [#not-implemented-hide:] The timestamp when the Endpoint was last updated. + */ + 'last_updated'?: (_google_protobuf_Timestamp | null); +} + +export interface _envoy_admin_v3_EndpointsConfigDump_StaticEndpointConfig__Output { + /** + * The endpoint config. + */ + 'endpoint_config': (_google_protobuf_Any__Output | null); + /** + * [#not-implemented-hide:] The timestamp when the Endpoint was last updated. + */ + 'last_updated': (_google_protobuf_Timestamp__Output | null); +} + +/** + * Envoy's admin fill this message with all currently known endpoints. Endpoint + * configuration information can be used to recreate an Envoy configuration by populating all + * endpoints as static endpoints or by returning them in an EDS response. + */ +export interface EndpointsConfigDump { + /** + * The statically loaded endpoint configs. + */ + 'static_endpoint_configs'?: (_envoy_admin_v3_EndpointsConfigDump_StaticEndpointConfig)[]; + /** + * The dynamically loaded endpoint configs. + */ + 'dynamic_endpoint_configs'?: (_envoy_admin_v3_EndpointsConfigDump_DynamicEndpointConfig)[]; +} + +/** + * Envoy's admin fill this message with all currently known endpoints. Endpoint + * configuration information can be used to recreate an Envoy configuration by populating all + * endpoints as static endpoints or by returning them in an EDS response. + */ +export interface EndpointsConfigDump__Output { + /** + * The statically loaded endpoint configs. + */ + 'static_endpoint_configs': (_envoy_admin_v3_EndpointsConfigDump_StaticEndpointConfig__Output)[]; + /** + * The dynamically loaded endpoint configs. + */ + 'dynamic_endpoint_configs': (_envoy_admin_v3_EndpointsConfigDump_DynamicEndpointConfig__Output)[]; +} 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 new file mode 100644 index 000000000..745abedae --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/admin/v3/ListenersConfigDump.ts @@ -0,0 +1,198 @@ +// 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'; +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'; + +/** + * Describes a dynamically loaded listener via the LDS API. + * [#next-free-field: 7] + */ +export interface _envoy_admin_v3_ListenersConfigDump_DynamicListener { + /** + * The name or unique id of this listener, pulled from the DynamicListenerState config. + */ + 'name'?: (string); + /** + * The listener state for any active listener by this name. + * These are listeners that are available to service data plane traffic. + */ + 'active_state'?: (_envoy_admin_v3_ListenersConfigDump_DynamicListenerState | null); + /** + * The listener state for any warming listener by this name. + * These are listeners that are currently undergoing warming in preparation to service data + * plane traffic. Note that if attempting to recreate an Envoy configuration from a + * configuration dump, the warming listeners should generally be discarded. + */ + 'warming_state'?: (_envoy_admin_v3_ListenersConfigDump_DynamicListenerState | null); + /** + * The listener state for any draining listener by this name. + * These are listeners that are currently undergoing draining in preparation to stop servicing + * data plane traffic. Note that if attempting to recreate an Envoy configuration from a + * configuration dump, the draining listeners should generally be discarded. + */ + 'draining_state'?: (_envoy_admin_v3_ListenersConfigDump_DynamicListenerState | 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. + */ + '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); +} + +/** + * Describes a dynamically loaded listener via the LDS API. + * [#next-free-field: 7] + */ +export interface _envoy_admin_v3_ListenersConfigDump_DynamicListener__Output { + /** + * The name or unique id of this listener, pulled from the DynamicListenerState config. + */ + 'name': (string); + /** + * The listener state for any active listener by this name. + * These are listeners that are available to service data plane traffic. + */ + 'active_state': (_envoy_admin_v3_ListenersConfigDump_DynamicListenerState__Output | null); + /** + * The listener state for any warming listener by this name. + * These are listeners that are currently undergoing warming in preparation to service data + * plane traffic. Note that if attempting to recreate an Envoy configuration from a + * configuration dump, the warming listeners should generally be discarded. + */ + 'warming_state': (_envoy_admin_v3_ListenersConfigDump_DynamicListenerState__Output | null); + /** + * The listener state for any draining listener by this name. + * These are listeners that are currently undergoing draining in preparation to stop servicing + * data plane traffic. Note that if attempting to recreate an Envoy configuration from a + * configuration dump, the draining listeners should generally be discarded. + */ + 'draining_state': (_envoy_admin_v3_ListenersConfigDump_DynamicListenerState__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. + */ + '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); +} + +export interface _envoy_admin_v3_ListenersConfigDump_DynamicListenerState { + /** + * This is the per-resource version information. This version is currently taken from the + * :ref:`version_info ` field at the time + * that the listener was loaded. In the future, discrete per-listener versions may be supported + * by the API. + */ + 'version_info'?: (string); + /** + * The listener config. + */ + 'listener'?: (_google_protobuf_Any | null); + /** + * The timestamp when the Listener was last successfully updated. + */ + 'last_updated'?: (_google_protobuf_Timestamp | null); +} + +export interface _envoy_admin_v3_ListenersConfigDump_DynamicListenerState__Output { + /** + * This is the per-resource version information. This version is currently taken from the + * :ref:`version_info ` field at the time + * that the listener was loaded. In the future, discrete per-listener versions may be supported + * by the API. + */ + 'version_info': (string); + /** + * The listener config. + */ + 'listener': (_google_protobuf_Any__Output | null); + /** + * The timestamp when the Listener was last successfully updated. + */ + 'last_updated': (_google_protobuf_Timestamp__Output | null); +} + +/** + * Describes a statically loaded listener. + */ +export interface _envoy_admin_v3_ListenersConfigDump_StaticListener { + /** + * The listener config. + */ + 'listener'?: (_google_protobuf_Any | null); + /** + * The timestamp when the Listener was last successfully updated. + */ + 'last_updated'?: (_google_protobuf_Timestamp | null); +} + +/** + * Describes a statically loaded listener. + */ +export interface _envoy_admin_v3_ListenersConfigDump_StaticListener__Output { + /** + * The listener config. + */ + 'listener': (_google_protobuf_Any__Output | null); + /** + * The timestamp when the Listener was last successfully updated. + */ + 'last_updated': (_google_protobuf_Timestamp__Output | null); +} + +/** + * Envoy's listener manager fills this message with all currently known listeners. Listener + * configuration information can be used to recreate an Envoy configuration by populating all + * listeners as static listeners or by returning them in a LDS response. + */ +export interface ListenersConfigDump { + /** + * This is the :ref:`version_info ` in the + * last processed LDS discovery response. If there are only static bootstrap listeners, this field + * will be "". + */ + 'version_info'?: (string); + /** + * The statically loaded listener configs. + */ + 'static_listeners'?: (_envoy_admin_v3_ListenersConfigDump_StaticListener)[]; + /** + * State for any warming, active, or draining listeners. + */ + 'dynamic_listeners'?: (_envoy_admin_v3_ListenersConfigDump_DynamicListener)[]; +} + +/** + * Envoy's listener manager fills this message with all currently known listeners. Listener + * configuration information can be used to recreate an Envoy configuration by populating all + * listeners as static listeners or by returning them in a LDS response. + */ +export interface ListenersConfigDump__Output { + /** + * This is the :ref:`version_info ` in the + * last processed LDS discovery response. If there are only static bootstrap listeners, this field + * will be "". + */ + 'version_info': (string); + /** + * The statically loaded listener configs. + */ + 'static_listeners': (_envoy_admin_v3_ListenersConfigDump_StaticListener__Output)[]; + /** + * State for any warming, active, or draining listeners. + */ + 'dynamic_listeners': (_envoy_admin_v3_ListenersConfigDump_DynamicListener__Output)[]; +} 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 new file mode 100644 index 000000000..2a62e9b74 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/admin/v3/RoutesConfigDump.ts @@ -0,0 +1,130 @@ +// 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'; +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'; + +/** + * [#next-free-field: 6] + */ +export interface _envoy_admin_v3_RoutesConfigDump_DynamicRouteConfig { + /** + * This is the per-resource version information. This version is currently taken from the + * :ref:`version_info ` field at the time that + * the route configuration was loaded. + */ + 'version_info'?: (string); + /** + * The route config. + */ + 'route_config'?: (_google_protobuf_Any | null); + /** + * The timestamp when the Route was last updated. + */ + 'last_updated'?: (_google_protobuf_Timestamp | 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); +} + +/** + * [#next-free-field: 6] + */ +export interface _envoy_admin_v3_RoutesConfigDump_DynamicRouteConfig__Output { + /** + * This is the per-resource version information. This version is currently taken from the + * :ref:`version_info ` field at the time that + * the route configuration was loaded. + */ + 'version_info': (string); + /** + * The route config. + */ + 'route_config': (_google_protobuf_Any__Output | null); + /** + * The timestamp when the Route was last updated. + */ + 'last_updated': (_google_protobuf_Timestamp__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); +} + +export interface _envoy_admin_v3_RoutesConfigDump_StaticRouteConfig { + /** + * The route config. + */ + 'route_config'?: (_google_protobuf_Any | null); + /** + * The timestamp when the Route was last updated. + */ + 'last_updated'?: (_google_protobuf_Timestamp | null); +} + +export interface _envoy_admin_v3_RoutesConfigDump_StaticRouteConfig__Output { + /** + * The route config. + */ + 'route_config': (_google_protobuf_Any__Output | null); + /** + * The timestamp when the Route was last updated. + */ + 'last_updated': (_google_protobuf_Timestamp__Output | null); +} + +/** + * Envoy's RDS implementation fills this message with all currently loaded routes, as described by + * their RouteConfiguration objects. Static routes that are either defined in the bootstrap configuration + * or defined inline while configuring listeners are separated from those configured dynamically via RDS. + * Route configuration information can be used to recreate an Envoy configuration by populating all routes + * as static routes or by returning them in RDS responses. + */ +export interface RoutesConfigDump { + /** + * The statically loaded route configs. + */ + 'static_route_configs'?: (_envoy_admin_v3_RoutesConfigDump_StaticRouteConfig)[]; + /** + * The dynamically loaded route configs. + */ + 'dynamic_route_configs'?: (_envoy_admin_v3_RoutesConfigDump_DynamicRouteConfig)[]; +} + +/** + * Envoy's RDS implementation fills this message with all currently loaded routes, as described by + * their RouteConfiguration objects. Static routes that are either defined in the bootstrap configuration + * or defined inline while configuring listeners are separated from those configured dynamically via RDS. + * Route configuration information can be used to recreate an Envoy configuration by populating all routes + * as static routes or by returning them in RDS responses. + */ +export interface RoutesConfigDump__Output { + /** + * The statically loaded route configs. + */ + 'static_route_configs': (_envoy_admin_v3_RoutesConfigDump_StaticRouteConfig__Output)[]; + /** + * The dynamically loaded route configs. + */ + 'dynamic_route_configs': (_envoy_admin_v3_RoutesConfigDump_DynamicRouteConfig__Output)[]; +} 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 new file mode 100644 index 000000000..f271635bc --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/admin/v3/ScopedRoutesConfigDump.ts @@ -0,0 +1,144 @@ +// 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'; +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'; + +/** + * [#next-free-field: 7] + */ +export interface _envoy_admin_v3_ScopedRoutesConfigDump_DynamicScopedRouteConfigs { + /** + * The name assigned to the scoped route configurations. + */ + 'name'?: (string); + /** + * This is the per-resource version information. This version is currently taken from the + * :ref:`version_info ` field at the time that + * the scoped routes configuration was loaded. + */ + 'version_info'?: (string); + /** + * The scoped route configurations. + */ + 'scoped_route_configs'?: (_google_protobuf_Any)[]; + /** + * The timestamp when the scoped route config set was last updated. + */ + 'last_updated'?: (_google_protobuf_Timestamp | 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); +} + +/** + * [#next-free-field: 7] + */ +export interface _envoy_admin_v3_ScopedRoutesConfigDump_DynamicScopedRouteConfigs__Output { + /** + * The name assigned to the scoped route configurations. + */ + 'name': (string); + /** + * This is the per-resource version information. This version is currently taken from the + * :ref:`version_info ` field at the time that + * the scoped routes configuration was loaded. + */ + 'version_info': (string); + /** + * The scoped route configurations. + */ + 'scoped_route_configs': (_google_protobuf_Any__Output)[]; + /** + * The timestamp when the scoped route config set was last updated. + */ + 'last_updated': (_google_protobuf_Timestamp__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); +} + +export interface _envoy_admin_v3_ScopedRoutesConfigDump_InlineScopedRouteConfigs { + /** + * The name assigned to the scoped route configurations. + */ + 'name'?: (string); + /** + * The scoped route configurations. + */ + 'scoped_route_configs'?: (_google_protobuf_Any)[]; + /** + * The timestamp when the scoped route config set was last updated. + */ + 'last_updated'?: (_google_protobuf_Timestamp | null); +} + +export interface _envoy_admin_v3_ScopedRoutesConfigDump_InlineScopedRouteConfigs__Output { + /** + * The name assigned to the scoped route configurations. + */ + 'name': (string); + /** + * The scoped route configurations. + */ + 'scoped_route_configs': (_google_protobuf_Any__Output)[]; + /** + * The timestamp when the scoped route config set was last updated. + */ + 'last_updated': (_google_protobuf_Timestamp__Output | null); +} + +/** + * Envoy's scoped RDS implementation fills this message with all currently loaded route + * configuration scopes (defined via ScopedRouteConfigurationsSet protos). This message lists both + * the scopes defined inline with the higher order object (i.e., the HttpConnectionManager) and the + * dynamically obtained scopes via the SRDS API. + */ +export interface ScopedRoutesConfigDump { + /** + * The statically loaded scoped route configs. + */ + 'inline_scoped_route_configs'?: (_envoy_admin_v3_ScopedRoutesConfigDump_InlineScopedRouteConfigs)[]; + /** + * The dynamically loaded scoped route configs. + */ + 'dynamic_scoped_route_configs'?: (_envoy_admin_v3_ScopedRoutesConfigDump_DynamicScopedRouteConfigs)[]; +} + +/** + * Envoy's scoped RDS implementation fills this message with all currently loaded route + * configuration scopes (defined via ScopedRouteConfigurationsSet protos). This message lists both + * the scopes defined inline with the higher order object (i.e., the HttpConnectionManager) and the + * dynamically obtained scopes via the SRDS API. + */ +export interface ScopedRoutesConfigDump__Output { + /** + * The statically loaded scoped route configs. + */ + 'inline_scoped_route_configs': (_envoy_admin_v3_ScopedRoutesConfigDump_InlineScopedRouteConfigs__Output)[]; + /** + * The dynamically loaded scoped route configs. + */ + 'dynamic_scoped_route_configs': (_envoy_admin_v3_ScopedRoutesConfigDump_DynamicScopedRouteConfigs__Output)[]; +} 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 new file mode 100644 index 000000000..21921edec --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/admin/v3/SecretsConfigDump.ts @@ -0,0 +1,162 @@ +// 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/admin/v3/UpdateFailureState.ts b/packages/grpc-js-xds/src/generated/envoy/admin/v3/UpdateFailureState.ts new file mode 100644 index 000000000..b98e8cd4d --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/admin/v3/UpdateFailureState.ts @@ -0,0 +1,46 @@ +// 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'; +import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp'; + +export interface UpdateFailureState { + /** + * What the component configuration would have been if the update had succeeded. + * This field may not be populated by xDS clients due to storage overhead. + */ + 'failed_configuration'?: (_google_protobuf_Any | null); + /** + * Time of the latest failed update attempt. + */ + 'last_update_attempt'?: (_google_protobuf_Timestamp | null); + /** + * Details about the last failed update attempt. + */ + 'details'?: (string); + /** + * This is the version of the rejected resource. + * [#not-implemented-hide:] + */ + 'version_info'?: (string); +} + +export interface UpdateFailureState__Output { + /** + * What the component configuration would have been if the update had succeeded. + * This field may not be populated by xDS clients due to storage overhead. + */ + 'failed_configuration': (_google_protobuf_Any__Output | null); + /** + * Time of the latest failed update attempt. + */ + 'last_update_attempt': (_google_protobuf_Timestamp__Output | null); + /** + * Details about the last failed update attempt. + */ + 'details': (string); + /** + * This is the version of the rejected resource. + * [#not-implemented-hide:] + */ + 'version_info': (string); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/CidrRange.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/CidrRange.ts index cca1bc2d8..5e1df8a13 100644 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/CidrRange.ts +++ b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/CidrRange.ts @@ -12,7 +12,7 @@ export interface CidrRange { */ 'address_prefix'?: (string); /** - * Length of prefix, e.g. 0, 32. + * Length of prefix, e.g. 0, 32. Defaults to 0 when unset. */ 'prefix_len'?: (_google_protobuf_UInt32Value | null); } @@ -27,7 +27,7 @@ export interface CidrRange__Output { */ 'address_prefix': (string); /** - * Length of prefix, e.g. 0, 32. + * Length of prefix, e.g. 0, 32. Defaults to 0 when unset. */ 'prefix_len': (_google_protobuf_UInt32Value__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AccessLog.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AccessLog.ts index 369f36bc2..367d8f302 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AccessLog.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/AccessLog.ts @@ -5,12 +5,9 @@ import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__ export interface AccessLog { /** - * The name of the access log implementation to instantiate. The name must - * match a statically registered access log. Current built-in loggers include: - * - * #. "envoy.access_loggers.file" - * #. "envoy.access_loggers.http_grpc" - * #. "envoy.access_loggers.tcp_grpc" + * The name of the access log extension to instantiate. + * The name must match one of the compiled in loggers. + * See the :ref:`extensions listed in typed_config below ` for the default list of available loggers. */ 'name'?: (string); /** @@ -19,27 +16,17 @@ export interface AccessLog { 'filter'?: (_envoy_config_accesslog_v3_AccessLogFilter | null); 'typed_config'?: (_google_protobuf_Any | null); /** - * Custom configuration that depends on the access log being instantiated. - * Built-in configurations include: - * - * #. "envoy.access_loggers.file": :ref:`FileAccessLog - * ` - * #. "envoy.access_loggers.http_grpc": :ref:`HttpGrpcAccessLogConfig - * ` - * #. "envoy.access_loggers.tcp_grpc": :ref:`TcpGrpcAccessLogConfig - * ` + * Custom configuration that must be set according to the access logger extension being instantiated. + * [#extension-category: envoy.access_loggers] */ 'config_type'?: "typed_config"; } export interface AccessLog__Output { /** - * The name of the access log implementation to instantiate. The name must - * match a statically registered access log. Current built-in loggers include: - * - * #. "envoy.access_loggers.file" - * #. "envoy.access_loggers.http_grpc" - * #. "envoy.access_loggers.tcp_grpc" + * The name of the access log extension to instantiate. + * The name must match one of the compiled in loggers. + * See the :ref:`extensions listed in typed_config below ` for the default list of available loggers. */ 'name': (string); /** @@ -48,15 +35,8 @@ export interface AccessLog__Output { 'filter': (_envoy_config_accesslog_v3_AccessLogFilter__Output | null); 'typed_config'?: (_google_protobuf_Any__Output | null); /** - * Custom configuration that depends on the access log being instantiated. - * Built-in configurations include: - * - * #. "envoy.access_loggers.file": :ref:`FileAccessLog - * ` - * #. "envoy.access_loggers.http_grpc": :ref:`HttpGrpcAccessLogConfig - * ` - * #. "envoy.access_loggers.tcp_grpc": :ref:`TcpGrpcAccessLogConfig - * ` + * Custom configuration that must be set according to the access logger extension being instantiated. + * [#extension-category: envoy.access_loggers] */ 'config_type': "typed_config"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/RuntimeFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/RuntimeFilter.ts index e605fa1a4..83b075388 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/RuntimeFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/accesslog/v3/RuntimeFilter.ts @@ -28,8 +28,8 @@ export interface RuntimeFilter { * randomly sample based on the runtime key value alone. * *use_independent_randomness* can be used for logging kill switches within * complex nested :ref:`AndFilter - * ` and :ref:`OrFilter - * ` blocks that are easier to + * ` and :ref:`OrFilter + * ` blocks that are easier to * reason about from a probability perspective (i.e., setting to true will * cause the filter to behave like an independent random variable when * composed within logical operator filters). @@ -63,8 +63,8 @@ export interface RuntimeFilter__Output { * randomly sample based on the runtime key value alone. * *use_independent_randomness* can be used for logging kill switches within * complex nested :ref:`AndFilter - * ` and :ref:`OrFilter - * ` blocks that are easier to + * ` and :ref:`OrFilter + * ` blocks that are easier to * reason about from a probability perspective (i.e., setting to true will * cause the filter to behave like an independent random variable when * composed within logical operator filters). 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 new file mode 100644 index 000000000..a7f3826a1 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Admin.ts @@ -0,0 +1,75 @@ +// 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 new file mode 100644 index 000000000..797148675 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Bootstrap.ts @@ -0,0 +1,642 @@ +// 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 new file mode 100644 index 000000000..571b96fb7 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/ClusterManager.ts @@ -0,0 +1,99 @@ +// 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 new file mode 100644 index 000000000..f0e2d29aa --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/CustomInlineHeader.ts @@ -0,0 +1,85 @@ +// 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 new file mode 100644 index 000000000..236afded5 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/FatalAction.ts @@ -0,0 +1,39 @@ +// 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 new file mode 100644 index 000000000..3514d3140 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/LayeredRuntime.ts @@ -0,0 +1,25 @@ +// 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 new file mode 100644 index 000000000..4f7713bcf --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Runtime.ts @@ -0,0 +1,77 @@ +// 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 new file mode 100644 index 000000000..b072bfa7d --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/RuntimeLayer.ts @@ -0,0 +1,142 @@ +// 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 new file mode 100644 index 000000000..8cd743b56 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Watchdog.ts @@ -0,0 +1,141 @@ +// 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 new file mode 100644 index 000000000..b478615ea --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/bootstrap/v3/Watchdogs.ts @@ -0,0 +1,35 @@ +// 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 e64afb780..12731b056 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 @@ -42,12 +42,12 @@ export interface _envoy_config_cluster_v3_CircuitBreakers_Thresholds_RetryBudget /** * A Thresholds defines CircuitBreaker settings for a - * :ref:`RoutingPriority`. + * :ref:`RoutingPriority`. * [#next-free-field: 9] */ export interface _envoy_config_cluster_v3_CircuitBreakers_Thresholds { /** - * The :ref:`RoutingPriority` + * The :ref:`RoutingPriority` * the specified CircuitBreaker settings apply to. */ 'priority'?: (_envoy_config_core_v3_RoutingPriority | keyof typeof _envoy_config_core_v3_RoutingPriority); @@ -104,12 +104,12 @@ export interface _envoy_config_cluster_v3_CircuitBreakers_Thresholds { /** * A Thresholds defines CircuitBreaker settings for a - * :ref:`RoutingPriority`. + * :ref:`RoutingPriority`. * [#next-free-field: 9] */ export interface _envoy_config_cluster_v3_CircuitBreakers_Thresholds__Output { /** - * The :ref:`RoutingPriority` + * The :ref:`RoutingPriority` * the specified CircuitBreaker settings apply to. */ 'priority': (keyof typeof _envoy_config_core_v3_RoutingPriority); @@ -170,10 +170,10 @@ export interface _envoy_config_cluster_v3_CircuitBreakers_Thresholds__Output { */ export interface CircuitBreakers { /** - * If multiple :ref:`Thresholds` - * are defined with the same :ref:`RoutingPriority`, + * If multiple :ref:`Thresholds` + * are defined with the same :ref:`RoutingPriority`, * the first one in the list is used. If no Thresholds is defined for a given - * :ref:`RoutingPriority`, the default values + * :ref:`RoutingPriority`, the default values * are used. */ 'thresholds'?: (_envoy_config_cluster_v3_CircuitBreakers_Thresholds)[]; @@ -185,10 +185,10 @@ export interface CircuitBreakers { */ export interface CircuitBreakers__Output { /** - * If multiple :ref:`Thresholds` - * are defined with the same :ref:`RoutingPriority`, + * If multiple :ref:`Thresholds` + * are defined with the same :ref:`RoutingPriority`, * the first one in the list is used. If no Thresholds is defined for a given - * :ref:`RoutingPriority`, the default values + * :ref:`RoutingPriority`, the default values * are used. */ 'thresholds': (_envoy_config_cluster_v3_CircuitBreakers_Thresholds__Output)[]; 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 c20440704..12ec7b633 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 @@ -21,6 +21,8 @@ import type { ConfigSource as _envoy_config_core_v3_ConfigSource, ConfigSource__ import type { UpstreamHttpProtocolOptions as _envoy_config_core_v3_UpstreamHttpProtocolOptions, UpstreamHttpProtocolOptions__Output as _envoy_config_core_v3_UpstreamHttpProtocolOptions__Output } from '../../../../envoy/config/core/v3/UpstreamHttpProtocolOptions'; 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 { TrackClusterStats as _envoy_config_cluster_v3_TrackClusterStats, TrackClusterStats__Output as _envoy_config_cluster_v3_TrackClusterStats__Output } from '../../../../envoy/config/cluster/v3/TrackClusterStats'; +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 { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; import type { RuntimeDouble as _envoy_config_core_v3_RuntimeDouble, RuntimeDouble__Output as _envoy_config_core_v3_RuntimeDouble__Output } from '../../../../envoy/config/core/v3/RuntimeDouble'; import type { UInt64Value as _google_protobuf_UInt64Value, UInt64Value__Output as _google_protobuf_UInt64Value__Output } from '../../../../google/protobuf/UInt64Value'; @@ -33,7 +35,7 @@ import type { Long } from '@grpc/proto-loader'; export enum _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 + * If :ref:`http2_protocol_options ` are * present, HTTP2 will be used, otherwise HTTP1.1 will be used. */ USE_CONFIGURED_PROTOCOL = 0, @@ -220,6 +222,7 @@ export interface _envoy_config_cluster_v3_Cluster_CustomClusterType { /** * Cluster specific configuration which depends on the cluster being instantiated. * See the supported cluster for further documentation. + * [#extension-category: envoy.clusters] */ 'typed_config'?: (_google_protobuf_Any | null); } @@ -235,6 +238,7 @@ export interface _envoy_config_cluster_v3_Cluster_CustomClusterType__Output { /** * Cluster specific configuration which depends on the cluster being instantiated. * See the supported cluster for further documentation. + * [#extension-category: envoy.clusters] */ 'typed_config': (_google_protobuf_Any__Output | null); } @@ -284,16 +288,24 @@ export enum _envoy_config_cluster_v3_Cluster_DiscoveryType { * 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. * For cluster types other than - * :ref:`STRICT_DNS` and - * :ref:`LOGICAL_DNS`, + * :ref:`STRICT_DNS` and + * :ref:`LOGICAL_DNS`, * this setting is * 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, } /** @@ -389,8 +401,8 @@ export enum _envoy_config_cluster_v3_Cluster_LbPolicy { */ CLUSTER_PROVIDED = 6, /** - * [#not-implemented-hide:] Use the new :ref:`load_balancing_policy - * ` field to determine the LB policy. + * Use the new :ref:`load_balancing_policy + * ` field to determine the LB policy. * [#next-major-version: In the v3 API, we should consider deprecating the lb_policy field * and instead using the new load_balancing_policy field as the one and only mechanism for * configuring this.] @@ -407,18 +419,18 @@ export interface _envoy_config_cluster_v3_Cluster_LbSubsetConfig { /** * The behavior used when no endpoint subset matches the selected route's * metadata. The value defaults to - * :ref:`NO_FALLBACK`. + * :ref:`NO_FALLBACK`. */ 'fallback_policy'?: (_envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy | keyof typeof _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy); /** * Specifies the default subset of endpoints used during fallback if * fallback_policy is - * :ref:`DEFAULT_SUBSET`. + * :ref:`DEFAULT_SUBSET`. * Each field in default_subset is * compared to the matching LbEndpoint.Metadata under the *envoy.lb* * namespace. It is valid for no hosts to match, in which case the behavior * is the same as a fallback_policy of - * :ref:`NO_FALLBACK`. + * :ref:`NO_FALLBACK`. */ 'default_subset'?: (_google_protobuf_Struct | null); /** @@ -484,18 +496,18 @@ export interface _envoy_config_cluster_v3_Cluster_LbSubsetConfig__Output { /** * The behavior used when no endpoint subset matches the selected route's * metadata. The value defaults to - * :ref:`NO_FALLBACK`. + * :ref:`NO_FALLBACK`. */ 'fallback_policy': (keyof typeof _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetFallbackPolicy); /** * Specifies the default subset of endpoints used during fallback if * fallback_policy is - * :ref:`DEFAULT_SUBSET`. + * :ref:`DEFAULT_SUBSET`. * Each field in default_subset is * compared to the matching LbEndpoint.Metadata under the *envoy.lb* * namespace. It is valid for no hosts to match, in which case the behavior * is the same as a fallback_policy of - * :ref:`NO_FALLBACK`. + * :ref:`NO_FALLBACK`. */ 'default_subset': (_google_protobuf_Struct__Output | null); /** @@ -597,13 +609,13 @@ export interface _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelecto 'fallback_policy'?: (_envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy | keyof typeof _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy); /** * Subset of - * :ref:`keys` used by - * :ref:`KEYS_SUBSET` + * :ref:`keys` used by + * :ref:`KEYS_SUBSET` * fallback policy. * It has to be a non empty list if KEYS_SUBSET fallback policy is selected. * For any other fallback policy the parameter is not used and should not be set. * Only values also present in - * :ref:`keys` are allowed, but + * :ref:`keys` are allowed, but * `fallback_keys_subset` cannot be equal to `keys`. */ 'fallback_keys_subset'?: (string)[]; @@ -639,13 +651,13 @@ export interface _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelecto 'fallback_policy': (keyof typeof _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_LbSubsetSelectorFallbackPolicy); /** * Subset of - * :ref:`keys` used by - * :ref:`KEYS_SUBSET` + * :ref:`keys` used by + * :ref:`KEYS_SUBSET` * fallback policy. * It has to be a non empty list if KEYS_SUBSET fallback policy is selected. * For any other fallback policy the parameter is not used and should not be set. * Only values also present in - * :ref:`keys` are allowed, but + * :ref:`keys` are allowed, but * `fallback_keys_subset` cannot be equal to `keys`. */ 'fallback_keys_subset': (string)[]; @@ -678,7 +690,7 @@ export enum _envoy_config_cluster_v3_Cluster_LbSubsetConfig_LbSubsetSelector_LbS /** * If KEYS_SUBSET is selected, subset selector matching is performed again with metadata * keys reduced to - * :ref:`fallback_keys_subset`. + * :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. */ @@ -720,6 +732,11 @@ export interface _envoy_config_cluster_v3_Cluster_LeastRequestLbConfig { * This setting only takes effect if all host weights are not equal. */ 'active_request_bias'?: (_envoy_config_core_v3_RuntimeDouble | null); + /** + * Configuration for slow start mode. + * If this configuration is not set, slow start will not be not enabled. + */ + 'slow_start_config'?: (_envoy_config_cluster_v3_Cluster_SlowStartConfig | null); } /** @@ -757,6 +774,11 @@ export interface _envoy_config_cluster_v3_Cluster_LeastRequestLbConfig__Output { * This setting only takes effect if all host weights are not equal. */ 'active_request_bias': (_envoy_config_core_v3_RuntimeDouble__Output | null); + /** + * Configuration for slow start mode. + * If this configuration is not set, slow start will not be not enabled. + */ + 'slow_start_config': (_envoy_config_cluster_v3_Cluster_SlowStartConfig__Output | null); } /** @@ -782,7 +804,7 @@ export interface _envoy_config_cluster_v3_Cluster_MaglevLbConfig { * The table size for Maglev hashing. The Maglev aims for ‘minimal disruption’ rather than an absolute guarantee. * Minimal disruption means that when the set of upstreams changes, a connection will likely be sent to the same * upstream as it was before. Increasing the table size reduces the amount of disruption. - * The table size must be prime number. If it is not specified, the default is 65537. + * The table size must be prime number limited to 5000011. If it is not specified, the default is 65537. */ 'table_size'?: (_google_protobuf_UInt64Value | null); } @@ -796,7 +818,7 @@ export interface _envoy_config_cluster_v3_Cluster_MaglevLbConfig__Output { * The table size for Maglev hashing. The Maglev aims for ‘minimal disruption’ rather than an absolute guarantee. * Minimal disruption means that when the set of upstreams changes, a connection will likely be sent to the same * upstream as it was before. Increasing the table size reduces the amount of disruption. - * The table size must be prime number. If it is not specified, the default is 65537. + * The table size must be prime number limited to 5000011. If it is not specified, the default is 65537. */ 'table_size': (_google_protobuf_UInt64Value__Output | null); } @@ -963,14 +985,14 @@ export interface _envoy_config_cluster_v3_Cluster_RefreshRate { /** * Specifies the base interval between refreshes. This parameter is required and must be greater * than zero and less than - * :ref:`max_interval `. + * :ref:`max_interval `. */ 'base_interval'?: (_google_protobuf_Duration | null); /** * Specifies the maximum interval between refreshes. This parameter is optional, but must be * greater than or equal to the - * :ref:`base_interval ` if set. The default - * is 10 times the :ref:`base_interval `. + * :ref:`base_interval ` if set. The default + * is 10 times the :ref:`base_interval `. */ 'max_interval'?: (_google_protobuf_Duration | null); } @@ -979,14 +1001,14 @@ export interface _envoy_config_cluster_v3_Cluster_RefreshRate__Output { /** * Specifies the base interval between refreshes. This parameter is required and must be greater * than zero and less than - * :ref:`max_interval `. + * :ref:`max_interval `. */ 'base_interval': (_google_protobuf_Duration__Output | null); /** * Specifies the maximum interval between refreshes. This parameter is optional, but must be * greater than or equal to the - * :ref:`base_interval ` if set. The default - * is 10 times the :ref:`base_interval `. + * :ref:`base_interval ` if set. The default + * is 10 times the :ref:`base_interval `. */ 'max_interval': (_google_protobuf_Duration__Output | null); } @@ -1000,18 +1022,18 @@ export interface _envoy_config_cluster_v3_Cluster_RingHashLbConfig { * 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 * to 1024 entries, and limited to 8M entries. See also - * :ref:`maximum_ring_size`. + * :ref:`maximum_ring_size`. */ 'minimum_ring_size'?: (_google_protobuf_UInt64Value | null); /** * The hash function used to hash hosts onto the ketama ring. The value defaults to - * :ref:`XX_HASH`. + * :ref:`XX_HASH`. */ 'hash_function'?: (_envoy_config_cluster_v3_Cluster_RingHashLbConfig_HashFunction | keyof typeof _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 - * :ref:`minimum_ring_size`. + * :ref:`minimum_ring_size`. */ 'maximum_ring_size'?: (_google_protobuf_UInt64Value | null); } @@ -1025,22 +1047,98 @@ export interface _envoy_config_cluster_v3_Cluster_RingHashLbConfig__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 * to 1024 entries, and limited to 8M entries. See also - * :ref:`maximum_ring_size`. + * :ref:`maximum_ring_size`. */ 'minimum_ring_size': (_google_protobuf_UInt64Value__Output | null); /** * The hash function used to hash hosts onto the ketama ring. The value defaults to - * :ref:`XX_HASH`. + * :ref:`XX_HASH`. */ 'hash_function': (keyof typeof _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 - * :ref:`minimum_ring_size`. + * :ref:`minimum_ring_size`. */ 'maximum_ring_size': (_google_protobuf_UInt64Value__Output | null); } +/** + * Specific configuration for the RoundRobin load balancing policy. + */ +export interface _envoy_config_cluster_v3_Cluster_RoundRobinLbConfig { + /** + * Configuration for slow start mode. + * If this configuration is not set, slow start will not be not enabled. + */ + 'slow_start_config'?: (_envoy_config_cluster_v3_Cluster_SlowStartConfig | null); +} + +/** + * Specific configuration for the RoundRobin load balancing policy. + */ +export interface _envoy_config_cluster_v3_Cluster_RoundRobinLbConfig__Output { + /** + * Configuration for slow start mode. + * If this configuration is not set, slow start will not be not enabled. + */ + 'slow_start_config': (_envoy_config_cluster_v3_Cluster_SlowStartConfig__Output | null); +} + +/** + * Configuration for :ref:`slow start mode `. + */ +export interface _envoy_config_cluster_v3_Cluster_SlowStartConfig { + /** + * Represents the size of slow start window. + * If set, the newly created host remains in slow start mode starting from its creation time + * for the duration of slow start window. + */ + 'slow_start_window'?: (_google_protobuf_Duration | null); + /** + * This parameter controls the speed of traffic increase over the slow start window. Defaults to 1.0, + * so that endpoint would get linearly increasing amount of traffic. + * When increasing the value for this parameter, the speed of traffic ramp-up increases non-linearly. + * The value of aggression parameter should be greater than 0.0. + * By tuning the parameter, is possible to achieve polynomial or exponential shape of ramp-up curve. + * + * During slow start window, effective weight of an endpoint would be scaled with time factor and aggression: + * `new_weight = weight * time_factor ^ (1 / aggression)`, + * where `time_factor=(time_since_start_seconds / slow_start_time_seconds)`. + * + * As time progresses, more and more traffic would be sent to endpoint, which is in slow start window. + * Once host exits slow start, time_factor and aggression no longer affect its weight. + */ + 'aggression'?: (_envoy_config_core_v3_RuntimeDouble | null); +} + +/** + * Configuration for :ref:`slow start mode `. + */ +export interface _envoy_config_cluster_v3_Cluster_SlowStartConfig__Output { + /** + * Represents the size of slow start window. + * If set, the newly created host remains in slow start mode starting from its creation time + * for the duration of slow start window. + */ + 'slow_start_window': (_google_protobuf_Duration__Output | null); + /** + * This parameter controls the speed of traffic increase over the slow start window. Defaults to 1.0, + * so that endpoint would get linearly increasing amount of traffic. + * When increasing the value for this parameter, the speed of traffic ramp-up increases non-linearly. + * The value of aggression parameter should be greater than 0.0. + * By tuning the parameter, is possible to achieve polynomial or exponential shape of ramp-up curve. + * + * During slow start window, effective weight of an endpoint would be scaled with time factor and aggression: + * `new_weight = weight * time_factor ^ (1 / aggression)`, + * where `time_factor=(time_since_start_seconds / slow_start_time_seconds)`. + * + * As time progresses, more and more traffic would be sent to endpoint, which is in slow start window. + * Once host exits slow start, time_factor and aggression no longer affect its weight. + */ + 'aggression': (_envoy_config_core_v3_RuntimeDouble__Output | null); +} + /** * TransportSocketMatch specifies what transport socket config will be used * when the match conditions are satisfied. @@ -1060,6 +1158,7 @@ export interface _envoy_config_cluster_v3_Cluster_TransportSocketMatch { 'match'?: (_google_protobuf_Struct | null); /** * The configuration of the transport socket. + * [#extension-category: envoy.transport_sockets.upstream] */ 'transport_socket'?: (_envoy_config_core_v3_TransportSocket | null); } @@ -1083,6 +1182,7 @@ export interface _envoy_config_cluster_v3_Cluster_TransportSocketMatch__Output { 'match': (_google_protobuf_Struct__Output | null); /** * The configuration of the transport socket. + * [#extension-category: envoy.transport_sockets.upstream] */ 'transport_socket': (_envoy_config_core_v3_TransportSocket__Output | null); } @@ -1147,14 +1247,14 @@ export interface _envoy_config_cluster_v3_Cluster_CommonLbConfig_ZoneAwareLbConf /** * Configuration for a single upstream cluster. - * [#next-free-field: 53] + * [#next-free-field: 57] */ export interface Cluster { /** * Supplies the name of the cluster which must be unique across all clusters. * The cluster name is used when emitting * :ref:`statistics ` if :ref:`alt_stat_name - * ` is not provided. + * ` is not provided. * Any ``:`` in the cluster name will be converted to ``_`` when emitting statistics. */ 'name'?: (string); @@ -1169,6 +1269,7 @@ export interface Cluster { 'eds_cluster_config'?: (_envoy_config_cluster_v3_Cluster_EdsClusterConfig | null); /** * The timeout for new network connections to hosts in the cluster. + * If not set, a default value of 5s will be used. */ 'connect_timeout'?: (_google_protobuf_Duration | null); /** @@ -1179,7 +1280,6 @@ export interface Cluster { /** * The :ref:`load balancer type ` to use * when picking a host in the cluster. - * [#comment:TODO: Remove enum constraint :ref:`LOAD_BALANCING_POLICY_CONFIG` when implemented.] */ 'lb_policy'?: (_envoy_config_cluster_v3_Cluster_LbPolicy | keyof typeof _envoy_config_cluster_v3_Cluster_LbPolicy); /** @@ -1194,6 +1294,9 @@ export interface Cluster { * is respected by both the HTTP/1.1 and HTTP/2 connection pool * implementations. If not specified, there is no limit. Setting this * parameter to 1 will effectively disable keep alive. + * + * .. attention:: + * This field has been deprecated in favor of the :ref:`max_requests_per_connection ` field. */ 'max_requests_per_connection'?: (_google_protobuf_UInt32Value | null); /** @@ -1202,12 +1305,12 @@ export interface Cluster { 'circuit_breakers'?: (_envoy_config_cluster_v3_CircuitBreakers | null); /** * Additional options when handling HTTP1 requests. - * This has been deprecated in favor of http_protocol_options fields in the in the - * :ref:`http_protocol_options ` message. + * This has been deprecated in favor of http_protocol_options fields in the + * :ref:`http_protocol_options ` message. * http_protocol_options can be set via the cluster's - * :ref:`extension_protocol_options`. - * See ref:`upstream_http_protocol_options - * ` + * :ref:`extension_protocol_options`. + * See :ref:`upstream_http_protocol_options + * ` * for example usage. */ 'http_protocol_options'?: (_envoy_config_core_v3_Http1ProtocolOptions | null); @@ -1218,47 +1321,49 @@ export interface Cluster { * supports prior knowledge for upstream connections. Even if TLS is used * with ALPN, `http2_protocol_options` must be specified. As an aside this allows HTTP/2 * connections to happen over plain text. - * This has been deprecated in favor of http2_protocol_options fields in the in the - * :ref:`http_protocol_options ` + * This has been deprecated in favor of http2_protocol_options fields in the + * :ref:`http_protocol_options ` * message. http2_protocol_options can be set via the cluster's - * :ref:`extension_protocol_options`. - * See ref:`upstream_http_protocol_options - * ` + * :ref:`extension_protocol_options`. + * See :ref:`upstream_http_protocol_options + * ` * for example usage. */ 'http2_protocol_options'?: (_envoy_config_core_v3_Http2ProtocolOptions | null); /** * If the DNS refresh rate is specified and the cluster type is either - * :ref:`STRICT_DNS`, - * or :ref:`LOGICAL_DNS`, + * :ref:`STRICT_DNS`, + * or :ref:`LOGICAL_DNS`, * this value is used as the cluster’s DNS refresh * rate. The value configured must be at least 1ms. If this setting is not specified, the * value defaults to 5000ms. For cluster types other than - * :ref:`STRICT_DNS` - * and :ref:`LOGICAL_DNS` + * :ref:`STRICT_DNS` + * and :ref:`LOGICAL_DNS` * this setting is ignored. */ 'dns_refresh_rate'?: (_google_protobuf_Duration | null); /** * The DNS IP address resolution policy. If this setting is not specified, the * value defaults to - * :ref:`AUTO`. + * :ref:`AUTO`. */ 'dns_lookup_family'?: (_envoy_config_cluster_v3_Cluster_DnsLookupFamily | keyof typeof _envoy_config_cluster_v3_Cluster_DnsLookupFamily); /** * If DNS resolvers are specified and the cluster type is either - * :ref:`STRICT_DNS`, - * or :ref:`LOGICAL_DNS`, + * :ref:`STRICT_DNS`, + * or :ref:`LOGICAL_DNS`, * this value is used to specify the cluster’s dns resolvers. * If this setting is not specified, the value defaults to the default * resolver, which uses /etc/resolv.conf for configuration. For cluster types * other than - * :ref:`STRICT_DNS` - * and :ref:`LOGICAL_DNS` + * :ref:`STRICT_DNS` + * and :ref:`LOGICAL_DNS` * this setting is ignored. * Setting this value causes failure if the * ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during * server startup. Apple's API only allows overriding DNS resolvers via system settings. + * This field is deprecated in favor of *dns_resolution_config* + * which aggregates all of the DNS resolver configuration in a single message. */ 'dns_resolvers'?: (_envoy_config_core_v3_Address)[]; /** @@ -1269,7 +1374,7 @@ export interface Cluster { 'outlier_detection'?: (_envoy_config_cluster_v3_OutlierDetection | null); /** * The interval for removing stale hosts from a cluster type - * :ref:`ORIGINAL_DST`. + * :ref:`ORIGINAL_DST`. * Hosts are considered stale if they have not been used * as upstream destinations during this interval. New hosts are added * to original destination clusters on demand as new connections are @@ -1279,7 +1384,7 @@ export interface Cluster { * them remain open, saving the latency that would otherwise be spent * on opening new connections. If this setting is not specified, the * value defaults to 5000ms. For cluster types other than - * :ref:`ORIGINAL_DST` + * :ref:`ORIGINAL_DST` * this setting is ignored. */ 'cleanup_interval'?: (_google_protobuf_Duration | null); @@ -1299,8 +1404,8 @@ export interface Cluster { 'ring_hash_lb_config'?: (_envoy_config_cluster_v3_Cluster_RingHashLbConfig | null); /** * Optional custom transport socket implementation to use for upstream connections. - * To setup TLS, set a transport socket with name `tls` and - * :ref:`UpstreamTlsContexts ` in the `typed_config`. + * To setup TLS, set a transport socket with name `envoy.transport_sockets.tls` and + * :ref:`UpstreamTlsContexts ` in the `typed_config`. * If no transport socket configuration is specified, new connections * will be set up with plaintext. */ @@ -1317,9 +1422,9 @@ export interface Cluster { * Determines how Envoy selects the protocol used to speak to upstream hosts. * This has been deprecated in favor of setting explicit protocol selection * in the :ref:`http_protocol_options - * ` message. + * ` message. * http_protocol_options can be set via the cluster's - * :ref:`extension_protocol_options`. + * :ref:`extension_protocol_options`. */ 'protocol_selection'?: (_envoy_config_cluster_v3_Cluster_ClusterProtocolSelection | keyof typeof _envoy_config_cluster_v3_Cluster_ClusterProtocolSelection); /** @@ -1327,22 +1432,27 @@ export interface Cluster { */ 'common_lb_config'?: (_envoy_config_cluster_v3_Cluster_CommonLbConfig | null); /** - * An optional alternative to the cluster name to be used while emitting stats. - * Any ``:`` in the name will be converted to ``_`` when emitting statistics. This should not be - * confused with :ref:`Router Filter Header - * `. + * An optional alternative to the cluster name to be used for observability. This name is used + * emitting stats for the cluster and access logging the cluster name. This will appear as + * additional information in configuration dumps of a cluster's current status as + * :ref:`observability_name ` + * and as an additional tag "upstream_cluster.name" while tracing. Note: access logging using + * this field is presently enabled with runtime feature + * `envoy.reloadable_features.use_observable_cluster_name`. Any ``:`` in the name will be + * converted to ``_`` when emitting statistics. This should not be confused with :ref:`Router + * Filter Header `. */ 'alt_stat_name'?: (string); /** * Additional options when handling HTTP requests upstream. These options will be applicable to * both HTTP1 and HTTP2 requests. * This has been deprecated in favor of - * :ref:`common_http_protocol_options ` - * in the :ref:`http_protocol_options ` message. + * :ref:`common_http_protocol_options ` + * in the :ref:`http_protocol_options ` message. * common_http_protocol_options can be set via the cluster's - * :ref:`extension_protocol_options`. - * See ref:`upstream_http_protocol_options - * ` + * :ref:`extension_protocol_options`. + * See :ref:`upstream_http_protocol_options + * ` * for example usage. */ 'common_http_protocol_options'?: (_envoy_config_core_v3_HttpProtocolOptions | null); @@ -1374,15 +1484,15 @@ export interface Cluster { 'ignore_health_on_host_removal'?: (boolean); /** * Setting this is required for specifying members of - * :ref:`STATIC`, - * :ref:`STRICT_DNS` - * or :ref:`LOGICAL_DNS` clusters. + * :ref:`STATIC`, + * :ref:`STRICT_DNS` + * or :ref:`LOGICAL_DNS` clusters. * This field supersedes the *hosts* field in the v2 API. * * .. attention:: * * Setting this allows non-EDS cluster types to contain embedded EDS equivalent - * :ref:`endpoint assignments`. + * :ref:`endpoint assignments`. */ 'load_assignment'?: (_envoy_config_endpoint_v3_ClusterLoadAssignment | null); /** @@ -1418,9 +1528,9 @@ export interface Cluster { */ 'filters'?: (_envoy_config_cluster_v3_Filter)[]; /** - * [#not-implemented-hide:] New mechanism for LB policy configuration. Used only if the - * :ref:`lb_policy` field has the value - * :ref:`LOAD_BALANCING_POLICY_CONFIG`. + * New mechanism for LB policy configuration. Used only if the + * :ref:`lb_policy` field has the value + * :ref:`LOAD_BALANCING_POLICY_CONFIG`. */ 'load_balancing_policy'?: (_envoy_config_cluster_v3_LoadBalancingPolicy | null); /** @@ -1443,9 +1553,9 @@ export interface Cluster { /** * Configuration to use different transport sockets for different endpoints. * The entry of *envoy.transport_socket_match* in the - * :ref:`LbEndpoint.Metadata ` + * :ref:`LbEndpoint.Metadata ` * is used to match against the transport sockets as they appear in the list. The first - * :ref:`match ` is used. + * :ref:`match ` is used. * For example, with the following match * * .. code-block:: yaml @@ -1465,7 +1575,7 @@ export interface Cluster { * Connections to the endpoints whose metadata value under *envoy.transport_socket_match* * having "acceptMTLS"/"true" key/value pair use the "enableMTLS" socket configuration. * - * If a :ref:`socket match ` with empty match + * If a :ref:`socket match ` with empty match * criteria is provided, that always match any endpoint. For example, the "defaultToPlaintext" * socket match in case above. * @@ -1487,40 +1597,41 @@ export interface Cluster { * * This field can be used to specify custom transport socket configurations for health * checks by adding matching key/value pairs in a health check's - * :ref:`transport socket match criteria ` field. + * :ref:`transport socket match criteria ` field. * * [#comment:TODO(incfly): add a detailed architecture doc on intended usage.] */ 'transport_socket_matches'?: (_envoy_config_cluster_v3_Cluster_TransportSocketMatch)[]; /** * If the DNS failure refresh rate is specified and the cluster type is either - * :ref:`STRICT_DNS`, - * or :ref:`LOGICAL_DNS`, + * :ref:`STRICT_DNS`, + * or :ref:`LOGICAL_DNS`, * this is used as the cluster’s DNS refresh rate when requests are failing. If this setting is * not specified, the failure refresh rate defaults to the DNS refresh rate. For cluster types - * other than :ref:`STRICT_DNS` and - * :ref:`LOGICAL_DNS` this setting is + * other than :ref:`STRICT_DNS` and + * :ref:`LOGICAL_DNS` this setting is * ignored. */ 'dns_failure_refresh_rate'?: (_envoy_config_cluster_v3_Cluster_RefreshRate | null); /** - * [#next-major-version: Reconcile DNS options in a single message.] * Always use TCP queries instead of UDP queries for DNS lookups. * 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); /** * HTTP protocol options that are applied only to upstream HTTP connections. * These options apply to all HTTP versions. * This has been deprecated in favor of - * :ref:`upstream_http_protocol_options ` - * in the :ref:`http_protocol_options ` message. + * :ref:`upstream_http_protocol_options ` + * in the :ref:`http_protocol_options ` message. * upstream_http_protocol_options can be set via the cluster's - * :ref:`extension_protocol_options`. - * See ref:`upstream_http_protocol_options - * ` + * :ref:`extension_protocol_options`. + * See :ref:`upstream_http_protocol_options + * ` * for example usage. */ 'upstream_http_protocol_options'?: (_envoy_config_core_v3_UpstreamHttpProtocolOptions | null); @@ -1534,7 +1645,7 @@ export interface Cluster { * .. attention:: * * This field has been deprecated in favor of `timeout_budgets`, part of - * :ref:`track_cluster_stats `. + * :ref:`track_cluster_stats `. */ 'track_timeout_budgets'?: (boolean); /** @@ -1555,6 +1666,7 @@ export interface Cluster { * If users desire custom connection pool or upstream behavior, for example terminating * CONNECT only if a custom filter indicates it is appropriate, the custom factories * can be registered and configured here. + * [#extension-category: envoy.upstreams] */ 'upstream_config'?: (_envoy_config_core_v3_TypedExtensionConfig | null); /** @@ -1574,30 +1686,64 @@ export interface Cluster { * Optional configuration for the Maglev load balancing policy. */ 'maglev_lb_config'?: (_envoy_config_cluster_v3_Cluster_MaglevLbConfig | null); + /** + * DNS resolution configuration which includes the underlying dns resolver addresses and options. + * *dns_resolution_config* will be deprecated once + * :ref:'typed_dns_resolver_config ' + * is fully supported. + */ + 'dns_resolution_config'?: (_envoy_config_core_v3_DnsResolutionConfig | null); + /** + * Optional configuration for having cluster readiness block on warm-up. Currently, only applicable for + * :ref:`STRICT_DNS`, + * or :ref:`LOGICAL_DNS`. + * If true, cluster readiness blocks on warm-up. If false, the cluster will complete + * initialization whether or not warm-up has completed. Defaults to true. + */ + 'wait_for_warm_on_init'?: (_google_protobuf_BoolValue | 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); + /** + * Optional configuration for the RoundRobin load balancing policy. + */ + 'round_robin_lb_config'?: (_envoy_config_cluster_v3_Cluster_RoundRobinLbConfig | null); 'cluster_discovery_type'?: "type"|"cluster_type"; /** * Optional configuration for the load balancing algorithm selected by * LbPolicy. Currently only - * :ref:`RING_HASH`, - * :ref:`MAGLEV` and - * :ref:`LEAST_REQUEST` + * :ref:`RING_HASH`, + * :ref:`MAGLEV` and + * :ref:`LEAST_REQUEST` * has additional configuration options. * Specifying ring_hash_lb_config or maglev_lb_config or least_request_lb_config without setting the corresponding * LbPolicy will generate an error at runtime. */ - 'lb_config'?: "ring_hash_lb_config"|"maglev_lb_config"|"original_dst_lb_config"|"least_request_lb_config"; + 'lb_config'?: "ring_hash_lb_config"|"maglev_lb_config"|"original_dst_lb_config"|"least_request_lb_config"|"round_robin_lb_config"; } /** * Configuration for a single upstream cluster. - * [#next-free-field: 53] + * [#next-free-field: 57] */ export interface Cluster__Output { /** * Supplies the name of the cluster which must be unique across all clusters. * The cluster name is used when emitting * :ref:`statistics ` if :ref:`alt_stat_name - * ` is not provided. + * ` is not provided. * Any ``:`` in the cluster name will be converted to ``_`` when emitting statistics. */ 'name': (string); @@ -1612,6 +1758,7 @@ export interface Cluster__Output { 'eds_cluster_config': (_envoy_config_cluster_v3_Cluster_EdsClusterConfig__Output | null); /** * The timeout for new network connections to hosts in the cluster. + * If not set, a default value of 5s will be used. */ 'connect_timeout': (_google_protobuf_Duration__Output | null); /** @@ -1622,7 +1769,6 @@ export interface Cluster__Output { /** * The :ref:`load balancer type ` to use * when picking a host in the cluster. - * [#comment:TODO: Remove enum constraint :ref:`LOAD_BALANCING_POLICY_CONFIG` when implemented.] */ 'lb_policy': (keyof typeof _envoy_config_cluster_v3_Cluster_LbPolicy); /** @@ -1637,6 +1783,9 @@ export interface Cluster__Output { * is respected by both the HTTP/1.1 and HTTP/2 connection pool * implementations. If not specified, there is no limit. Setting this * parameter to 1 will effectively disable keep alive. + * + * .. attention:: + * This field has been deprecated in favor of the :ref:`max_requests_per_connection ` field. */ 'max_requests_per_connection': (_google_protobuf_UInt32Value__Output | null); /** @@ -1645,12 +1794,12 @@ export interface Cluster__Output { 'circuit_breakers': (_envoy_config_cluster_v3_CircuitBreakers__Output | null); /** * Additional options when handling HTTP1 requests. - * This has been deprecated in favor of http_protocol_options fields in the in the - * :ref:`http_protocol_options ` message. + * This has been deprecated in favor of http_protocol_options fields in the + * :ref:`http_protocol_options ` message. * http_protocol_options can be set via the cluster's - * :ref:`extension_protocol_options`. - * See ref:`upstream_http_protocol_options - * ` + * :ref:`extension_protocol_options`. + * See :ref:`upstream_http_protocol_options + * ` * for example usage. */ 'http_protocol_options': (_envoy_config_core_v3_Http1ProtocolOptions__Output | null); @@ -1661,47 +1810,49 @@ export interface Cluster__Output { * supports prior knowledge for upstream connections. Even if TLS is used * with ALPN, `http2_protocol_options` must be specified. As an aside this allows HTTP/2 * connections to happen over plain text. - * This has been deprecated in favor of http2_protocol_options fields in the in the - * :ref:`http_protocol_options ` + * This has been deprecated in favor of http2_protocol_options fields in the + * :ref:`http_protocol_options ` * message. http2_protocol_options can be set via the cluster's - * :ref:`extension_protocol_options`. - * See ref:`upstream_http_protocol_options - * ` + * :ref:`extension_protocol_options`. + * See :ref:`upstream_http_protocol_options + * ` * for example usage. */ 'http2_protocol_options': (_envoy_config_core_v3_Http2ProtocolOptions__Output | null); /** * If the DNS refresh rate is specified and the cluster type is either - * :ref:`STRICT_DNS`, - * or :ref:`LOGICAL_DNS`, + * :ref:`STRICT_DNS`, + * or :ref:`LOGICAL_DNS`, * this value is used as the cluster’s DNS refresh * rate. The value configured must be at least 1ms. If this setting is not specified, the * value defaults to 5000ms. For cluster types other than - * :ref:`STRICT_DNS` - * and :ref:`LOGICAL_DNS` + * :ref:`STRICT_DNS` + * and :ref:`LOGICAL_DNS` * this setting is ignored. */ 'dns_refresh_rate': (_google_protobuf_Duration__Output | null); /** * The DNS IP address resolution policy. If this setting is not specified, the * value defaults to - * :ref:`AUTO`. + * :ref:`AUTO`. */ 'dns_lookup_family': (keyof typeof _envoy_config_cluster_v3_Cluster_DnsLookupFamily); /** * If DNS resolvers are specified and the cluster type is either - * :ref:`STRICT_DNS`, - * or :ref:`LOGICAL_DNS`, + * :ref:`STRICT_DNS`, + * or :ref:`LOGICAL_DNS`, * this value is used to specify the cluster’s dns resolvers. * If this setting is not specified, the value defaults to the default * resolver, which uses /etc/resolv.conf for configuration. For cluster types * other than - * :ref:`STRICT_DNS` - * and :ref:`LOGICAL_DNS` + * :ref:`STRICT_DNS` + * and :ref:`LOGICAL_DNS` * this setting is ignored. * Setting this value causes failure if the * ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during * server startup. Apple's API only allows overriding DNS resolvers via system settings. + * This field is deprecated in favor of *dns_resolution_config* + * which aggregates all of the DNS resolver configuration in a single message. */ 'dns_resolvers': (_envoy_config_core_v3_Address__Output)[]; /** @@ -1712,7 +1863,7 @@ export interface Cluster__Output { 'outlier_detection': (_envoy_config_cluster_v3_OutlierDetection__Output | null); /** * The interval for removing stale hosts from a cluster type - * :ref:`ORIGINAL_DST`. + * :ref:`ORIGINAL_DST`. * Hosts are considered stale if they have not been used * as upstream destinations during this interval. New hosts are added * to original destination clusters on demand as new connections are @@ -1722,7 +1873,7 @@ export interface Cluster__Output { * them remain open, saving the latency that would otherwise be spent * on opening new connections. If this setting is not specified, the * value defaults to 5000ms. For cluster types other than - * :ref:`ORIGINAL_DST` + * :ref:`ORIGINAL_DST` * this setting is ignored. */ 'cleanup_interval': (_google_protobuf_Duration__Output | null); @@ -1742,8 +1893,8 @@ export interface Cluster__Output { 'ring_hash_lb_config'?: (_envoy_config_cluster_v3_Cluster_RingHashLbConfig__Output | null); /** * Optional custom transport socket implementation to use for upstream connections. - * To setup TLS, set a transport socket with name `tls` and - * :ref:`UpstreamTlsContexts ` in the `typed_config`. + * To setup TLS, set a transport socket with name `envoy.transport_sockets.tls` and + * :ref:`UpstreamTlsContexts ` in the `typed_config`. * If no transport socket configuration is specified, new connections * will be set up with plaintext. */ @@ -1760,9 +1911,9 @@ export interface Cluster__Output { * Determines how Envoy selects the protocol used to speak to upstream hosts. * This has been deprecated in favor of setting explicit protocol selection * in the :ref:`http_protocol_options - * ` message. + * ` message. * http_protocol_options can be set via the cluster's - * :ref:`extension_protocol_options`. + * :ref:`extension_protocol_options`. */ 'protocol_selection': (keyof typeof _envoy_config_cluster_v3_Cluster_ClusterProtocolSelection); /** @@ -1770,22 +1921,27 @@ export interface Cluster__Output { */ 'common_lb_config': (_envoy_config_cluster_v3_Cluster_CommonLbConfig__Output | null); /** - * An optional alternative to the cluster name to be used while emitting stats. - * Any ``:`` in the name will be converted to ``_`` when emitting statistics. This should not be - * confused with :ref:`Router Filter Header - * `. + * An optional alternative to the cluster name to be used for observability. This name is used + * emitting stats for the cluster and access logging the cluster name. This will appear as + * additional information in configuration dumps of a cluster's current status as + * :ref:`observability_name ` + * and as an additional tag "upstream_cluster.name" while tracing. Note: access logging using + * this field is presently enabled with runtime feature + * `envoy.reloadable_features.use_observable_cluster_name`. Any ``:`` in the name will be + * converted to ``_`` when emitting statistics. This should not be confused with :ref:`Router + * Filter Header `. */ 'alt_stat_name': (string); /** * Additional options when handling HTTP requests upstream. These options will be applicable to * both HTTP1 and HTTP2 requests. * This has been deprecated in favor of - * :ref:`common_http_protocol_options ` - * in the :ref:`http_protocol_options ` message. + * :ref:`common_http_protocol_options ` + * in the :ref:`http_protocol_options ` message. * common_http_protocol_options can be set via the cluster's - * :ref:`extension_protocol_options`. - * See ref:`upstream_http_protocol_options - * ` + * :ref:`extension_protocol_options`. + * See :ref:`upstream_http_protocol_options + * ` * for example usage. */ 'common_http_protocol_options': (_envoy_config_core_v3_HttpProtocolOptions__Output | null); @@ -1817,15 +1973,15 @@ export interface Cluster__Output { 'ignore_health_on_host_removal': (boolean); /** * Setting this is required for specifying members of - * :ref:`STATIC`, - * :ref:`STRICT_DNS` - * or :ref:`LOGICAL_DNS` clusters. + * :ref:`STATIC`, + * :ref:`STRICT_DNS` + * or :ref:`LOGICAL_DNS` clusters. * This field supersedes the *hosts* field in the v2 API. * * .. attention:: * * Setting this allows non-EDS cluster types to contain embedded EDS equivalent - * :ref:`endpoint assignments`. + * :ref:`endpoint assignments`. */ 'load_assignment': (_envoy_config_endpoint_v3_ClusterLoadAssignment__Output | null); /** @@ -1861,9 +2017,9 @@ export interface Cluster__Output { */ 'filters': (_envoy_config_cluster_v3_Filter__Output)[]; /** - * [#not-implemented-hide:] New mechanism for LB policy configuration. Used only if the - * :ref:`lb_policy` field has the value - * :ref:`LOAD_BALANCING_POLICY_CONFIG`. + * New mechanism for LB policy configuration. Used only if the + * :ref:`lb_policy` field has the value + * :ref:`LOAD_BALANCING_POLICY_CONFIG`. */ 'load_balancing_policy': (_envoy_config_cluster_v3_LoadBalancingPolicy__Output | null); /** @@ -1886,9 +2042,9 @@ export interface Cluster__Output { /** * Configuration to use different transport sockets for different endpoints. * The entry of *envoy.transport_socket_match* in the - * :ref:`LbEndpoint.Metadata ` + * :ref:`LbEndpoint.Metadata ` * is used to match against the transport sockets as they appear in the list. The first - * :ref:`match ` is used. + * :ref:`match ` is used. * For example, with the following match * * .. code-block:: yaml @@ -1908,7 +2064,7 @@ export interface Cluster__Output { * Connections to the endpoints whose metadata value under *envoy.transport_socket_match* * having "acceptMTLS"/"true" key/value pair use the "enableMTLS" socket configuration. * - * If a :ref:`socket match ` with empty match + * If a :ref:`socket match ` with empty match * criteria is provided, that always match any endpoint. For example, the "defaultToPlaintext" * socket match in case above. * @@ -1930,40 +2086,41 @@ export interface Cluster__Output { * * This field can be used to specify custom transport socket configurations for health * checks by adding matching key/value pairs in a health check's - * :ref:`transport socket match criteria ` field. + * :ref:`transport socket match criteria ` field. * * [#comment:TODO(incfly): add a detailed architecture doc on intended usage.] */ 'transport_socket_matches': (_envoy_config_cluster_v3_Cluster_TransportSocketMatch__Output)[]; /** * If the DNS failure refresh rate is specified and the cluster type is either - * :ref:`STRICT_DNS`, - * or :ref:`LOGICAL_DNS`, + * :ref:`STRICT_DNS`, + * or :ref:`LOGICAL_DNS`, * this is used as the cluster’s DNS refresh rate when requests are failing. If this setting is * not specified, the failure refresh rate defaults to the DNS refresh rate. For cluster types - * other than :ref:`STRICT_DNS` and - * :ref:`LOGICAL_DNS` this setting is + * other than :ref:`STRICT_DNS` and + * :ref:`LOGICAL_DNS` this setting is * ignored. */ 'dns_failure_refresh_rate': (_envoy_config_cluster_v3_Cluster_RefreshRate__Output | null); /** - * [#next-major-version: Reconcile DNS options in a single message.] * Always use TCP queries instead of UDP queries for DNS lookups. * 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); /** * HTTP protocol options that are applied only to upstream HTTP connections. * These options apply to all HTTP versions. * This has been deprecated in favor of - * :ref:`upstream_http_protocol_options ` - * in the :ref:`http_protocol_options ` message. + * :ref:`upstream_http_protocol_options ` + * in the :ref:`http_protocol_options ` message. * upstream_http_protocol_options can be set via the cluster's - * :ref:`extension_protocol_options`. - * See ref:`upstream_http_protocol_options - * ` + * :ref:`extension_protocol_options`. + * See :ref:`upstream_http_protocol_options + * ` * for example usage. */ 'upstream_http_protocol_options': (_envoy_config_core_v3_UpstreamHttpProtocolOptions__Output | null); @@ -1977,7 +2134,7 @@ export interface Cluster__Output { * .. attention:: * * This field has been deprecated in favor of `timeout_budgets`, part of - * :ref:`track_cluster_stats `. + * :ref:`track_cluster_stats `. */ 'track_timeout_budgets': (boolean); /** @@ -1998,6 +2155,7 @@ export interface Cluster__Output { * If users desire custom connection pool or upstream behavior, for example terminating * CONNECT only if a custom filter indicates it is appropriate, the custom factories * can be registered and configured here. + * [#extension-category: envoy.upstreams] */ 'upstream_config': (_envoy_config_core_v3_TypedExtensionConfig__Output | null); /** @@ -2017,16 +2175,50 @@ export interface Cluster__Output { * Optional configuration for the Maglev load balancing policy. */ 'maglev_lb_config'?: (_envoy_config_cluster_v3_Cluster_MaglevLbConfig__Output | null); + /** + * DNS resolution configuration which includes the underlying dns resolver addresses and options. + * *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); + /** + * Optional configuration for having cluster readiness block on warm-up. Currently, only applicable for + * :ref:`STRICT_DNS`, + * or :ref:`LOGICAL_DNS`. + * If true, cluster readiness blocks on warm-up. If false, the cluster will complete + * initialization whether or not warm-up has completed. Defaults to true. + */ + 'wait_for_warm_on_init': (_google_protobuf_BoolValue__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); + /** + * Optional configuration for the RoundRobin load balancing policy. + */ + 'round_robin_lb_config'?: (_envoy_config_cluster_v3_Cluster_RoundRobinLbConfig__Output | null); 'cluster_discovery_type': "type"|"cluster_type"; /** * Optional configuration for the load balancing algorithm selected by * LbPolicy. Currently only - * :ref:`RING_HASH`, - * :ref:`MAGLEV` and - * :ref:`LEAST_REQUEST` + * :ref:`RING_HASH`, + * :ref:`MAGLEV` and + * :ref:`LEAST_REQUEST` * has additional configuration options. * Specifying ring_hash_lb_config or maglev_lb_config or least_request_lb_config without setting the corresponding * LbPolicy will generate an error at runtime. */ - 'lb_config': "ring_hash_lb_config"|"maglev_lb_config"|"original_dst_lb_config"|"least_request_lb_config"; + 'lb_config': "ring_hash_lb_config"|"maglev_lb_config"|"original_dst_lb_config"|"least_request_lb_config"|"round_robin_lb_config"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/Filter.ts b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/Filter.ts index b2ccda5e4..9d9031b68 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/Filter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/Filter.ts @@ -5,7 +5,8 @@ import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__ export interface Filter { /** * The name of the filter to instantiate. The name must match a - * :ref:`supported filter `. + * supported upstream filter. Note that Envoy's :ref:`downstream network + * filters ` are not valid upstream filters. */ 'name'?: (string); /** @@ -18,7 +19,8 @@ export interface Filter { export interface Filter__Output { /** * The name of the filter to instantiate. The name must match a - * :ref:`supported filter `. + * supported upstream filter. Note that Envoy's :ref:`downstream network + * filters ` are not valid upstream filters. */ 'name': (string); /** diff --git a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/LoadBalancingPolicy.ts b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/LoadBalancingPolicy.ts index 128a6458a..78d4a6bfd 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/LoadBalancingPolicy.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/LoadBalancingPolicy.ts @@ -1,25 +1,17 @@ // Original file: deps/envoy-api/envoy/config/cluster/v3/cluster.proto -import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; +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_cluster_v3_LoadBalancingPolicy_Policy { - /** - * Required. The name of the LB policy. - */ - 'name'?: (string); - 'typed_config'?: (_google_protobuf_Any | null); + 'typed_extension_config'?: (_envoy_config_core_v3_TypedExtensionConfig | null); } export interface _envoy_config_cluster_v3_LoadBalancingPolicy_Policy__Output { - /** - * Required. The name of the LB policy. - */ - 'name': (string); - 'typed_config': (_google_protobuf_Any__Output | null); + 'typed_extension_config': (_envoy_config_core_v3_TypedExtensionConfig__Output | null); } /** - * [#not-implemented-hide:] Extensible load balancing policy configuration. + * Extensible load balancing policy configuration. * * Every LB policy defined via this mechanism will be identified via a unique name using reverse * DNS notation. If the policy needs configuration parameters, it must define a message for its @@ -49,7 +41,7 @@ export interface LoadBalancingPolicy { } /** - * [#not-implemented-hide:] Extensible load balancing policy configuration. + * Extensible load balancing policy configuration. * * Every LB policy defined via this mechanism will be identified via a unique name using reverse * DNS notation. If the policy needs configuration parameters, it must define a message for its diff --git a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/OutlierDetection.ts b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/OutlierDetection.ts index abae2e270..789004ad4 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/OutlierDetection.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/cluster/v3/OutlierDetection.ts @@ -24,7 +24,7 @@ export interface OutlierDetection { /** * The base time that a host is ejected for. The real time is equal to the * base time multiplied by the number of times the host has been ejected and is - * capped by :ref:`max_ejection_time`. + * capped by :ref:`max_ejection_time`. * Defaults to 30000ms or 30s. */ 'base_ejection_time'?: (_google_protobuf_Duration | null); @@ -84,17 +84,17 @@ export interface OutlierDetection { /** * Determines whether to distinguish local origin failures from external errors. If set to true * the following configuration parameters are taken into account: - * :ref:`consecutive_local_origin_failure`, - * :ref:`enforcing_consecutive_local_origin_failure` + * :ref:`consecutive_local_origin_failure`, + * :ref:`enforcing_consecutive_local_origin_failure` * and - * :ref:`enforcing_local_origin_success_rate`. + * :ref:`enforcing_local_origin_success_rate`. * Defaults to false. */ 'split_external_local_origin_errors'?: (boolean); /** * The number of consecutive locally originated failures before ejection * occurs. Defaults to 5. Parameter takes effect only when - * :ref:`split_external_local_origin_errors` + * :ref:`split_external_local_origin_errors` * is set to true. */ 'consecutive_local_origin_failure'?: (_google_protobuf_UInt32Value | null); @@ -103,7 +103,7 @@ export interface OutlierDetection { * is detected through consecutive locally originated failures. This setting can be * used to disable ejection or to ramp it up slowly. Defaults to 100. * Parameter takes effect only when - * :ref:`split_external_local_origin_errors` + * :ref:`split_external_local_origin_errors` * is set to true. */ 'enforcing_consecutive_local_origin_failure'?: (_google_protobuf_UInt32Value | null); @@ -112,7 +112,7 @@ export interface OutlierDetection { * is detected through success rate statistics for locally originated errors. * This setting can be used to disable ejection or to ramp it up slowly. Defaults to 100. * Parameter takes effect only when - * :ref:`split_external_local_origin_errors` + * :ref:`split_external_local_origin_errors` * is set to true. */ 'enforcing_local_origin_success_rate'?: (_google_protobuf_UInt32Value | null); @@ -151,9 +151,9 @@ export interface OutlierDetection { */ 'failure_percentage_request_volume'?: (_google_protobuf_UInt32Value | null); /** - * The maximum time that a host is ejected for. See :ref:`base_ejection_time` - * for more information. - * Defaults to 300000ms or 300s. + * The maximum time that a host is ejected for. See :ref:`base_ejection_time` + * for more information. If not specified, the default value (300000ms or 300s) or + * :ref:`base_ejection_time` value is applied, whatever is larger. */ 'max_ejection_time'?: (_google_protobuf_Duration | null); } @@ -179,7 +179,7 @@ export interface OutlierDetection__Output { /** * The base time that a host is ejected for. The real time is equal to the * base time multiplied by the number of times the host has been ejected and is - * capped by :ref:`max_ejection_time`. + * capped by :ref:`max_ejection_time`. * Defaults to 30000ms or 30s. */ 'base_ejection_time': (_google_protobuf_Duration__Output | null); @@ -239,17 +239,17 @@ export interface OutlierDetection__Output { /** * Determines whether to distinguish local origin failures from external errors. If set to true * the following configuration parameters are taken into account: - * :ref:`consecutive_local_origin_failure`, - * :ref:`enforcing_consecutive_local_origin_failure` + * :ref:`consecutive_local_origin_failure`, + * :ref:`enforcing_consecutive_local_origin_failure` * and - * :ref:`enforcing_local_origin_success_rate`. + * :ref:`enforcing_local_origin_success_rate`. * Defaults to false. */ 'split_external_local_origin_errors': (boolean); /** * The number of consecutive locally originated failures before ejection * occurs. Defaults to 5. Parameter takes effect only when - * :ref:`split_external_local_origin_errors` + * :ref:`split_external_local_origin_errors` * is set to true. */ 'consecutive_local_origin_failure': (_google_protobuf_UInt32Value__Output | null); @@ -258,7 +258,7 @@ export interface OutlierDetection__Output { * is detected through consecutive locally originated failures. This setting can be * used to disable ejection or to ramp it up slowly. Defaults to 100. * Parameter takes effect only when - * :ref:`split_external_local_origin_errors` + * :ref:`split_external_local_origin_errors` * is set to true. */ 'enforcing_consecutive_local_origin_failure': (_google_protobuf_UInt32Value__Output | null); @@ -267,7 +267,7 @@ export interface OutlierDetection__Output { * is detected through success rate statistics for locally originated errors. * This setting can be used to disable ejection or to ramp it up slowly. Defaults to 100. * Parameter takes effect only when - * :ref:`split_external_local_origin_errors` + * :ref:`split_external_local_origin_errors` * is set to true. */ 'enforcing_local_origin_success_rate': (_google_protobuf_UInt32Value__Output | null); @@ -306,9 +306,9 @@ export interface OutlierDetection__Output { */ 'failure_percentage_request_volume': (_google_protobuf_UInt32Value__Output | null); /** - * The maximum time that a host is ejected for. See :ref:`base_ejection_time` - * for more information. - * Defaults to 300000ms or 300s. + * The maximum time that a host is ejected for. See :ref:`base_ejection_time` + * for more information. If not specified, the default value (300000ms or 300s) or + * :ref:`base_ejection_time` value is applied, whatever is larger. */ 'max_ejection_time': (_google_protobuf_Duration__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/AggregatedConfigSource.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/AggregatedConfigSource.ts index 824ef93c8..428ab4b56 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/AggregatedConfigSource.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/AggregatedConfigSource.ts @@ -3,7 +3,7 @@ /** * Aggregated Discovery Service (ADS) options. This is currently empty, but when - * set in :ref:`ConfigSource ` can be used to + * set in :ref:`ConfigSource ` can be used to * specify that ADS is to be used. */ export interface AggregatedConfigSource { @@ -11,7 +11,7 @@ export interface AggregatedConfigSource { /** * Aggregated Discovery Service (ADS) options. This is currently empty, but when - * set in :ref:`ConfigSource ` can be used to + * set in :ref:`ConfigSource ` can be used to * specify that ADS is to be used. */ export interface AggregatedConfigSource__Output { diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/AlternateProtocolsCacheOptions.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/AlternateProtocolsCacheOptions.ts new file mode 100644 index 000000000..6fb167174 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/AlternateProtocolsCacheOptions.ts @@ -0,0 +1,72 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/protocol.proto + +import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; +import type { TypedExtensionConfig as _envoy_config_core_v3_TypedExtensionConfig, TypedExtensionConfig__Output as _envoy_config_core_v3_TypedExtensionConfig__Output } from '../../../../envoy/config/core/v3/TypedExtensionConfig'; + +/** + * Configures the alternate protocols cache which tracks alternate protocols that can be used to + * make an HTTP connection to an origin server. See https://tools.ietf.org/html/rfc7838 for + * HTTP Alternative Services and https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-04 + * for the "HTTPS" DNS resource record. + */ +export interface AlternateProtocolsCacheOptions { + /** + * The name of the cache. Multiple named caches allow independent alternate protocols cache + * configurations to operate within a single Envoy process using different configurations. All + * alternate protocols cache options with the same name *must* be equal in all fields when + * referenced from different configuration components. Configuration will fail to load if this is + * not the case. + */ + 'name'?: (string); + /** + * The maximum number of entries that the cache will hold. If not specified defaults to 1024. + * + * .. note: + * + * The implementation is approximate and enforced independently on each worker thread, thus + * it is possible for the maximum entries in the cache to go slightly above the configured + * value depending on timing. This is similar to how other circuit breakers work. + */ + 'max_entries'?: (_google_protobuf_UInt32Value | null); + /** + * Allows configuring a persistent + * :ref:`key value store ` to flush + * alternate protocols entries to disk. + * This function is currently only supported if concurrency is 1 + */ + 'key_value_store_config'?: (_envoy_config_core_v3_TypedExtensionConfig | null); +} + +/** + * Configures the alternate protocols cache which tracks alternate protocols that can be used to + * make an HTTP connection to an origin server. See https://tools.ietf.org/html/rfc7838 for + * HTTP Alternative Services and https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-04 + * for the "HTTPS" DNS resource record. + */ +export interface AlternateProtocolsCacheOptions__Output { + /** + * The name of the cache. Multiple named caches allow independent alternate protocols cache + * configurations to operate within a single Envoy process using different configurations. All + * alternate protocols cache options with the same name *must* be equal in all fields when + * referenced from different configuration components. Configuration will fail to load if this is + * not the case. + */ + 'name': (string); + /** + * The maximum number of entries that the cache will hold. If not specified defaults to 1024. + * + * .. note: + * + * The implementation is approximate and enforced independently on each worker thread, thus + * it is possible for the maximum entries in the cache to go slightly above the configured + * value depending on timing. This is similar to how other circuit breakers work. + */ + 'max_entries': (_google_protobuf_UInt32Value__Output | null); + /** + * Allows configuring a persistent + * :ref:`key value store ` to flush + * alternate protocols entries to disk. + * This function is currently only supported if concurrency is 1 + */ + 'key_value_store_config': (_envoy_config_core_v3_TypedExtensionConfig__Output | null); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BackoffStrategy.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BackoffStrategy.ts index b85b8d5de..1049dec0c 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BackoffStrategy.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/BackoffStrategy.ts @@ -9,15 +9,15 @@ export interface BackoffStrategy { /** * The base interval to be used for the next back off computation. It should * be greater than zero and less than or equal to :ref:`max_interval - * `. + * `. */ 'base_interval'?: (_google_protobuf_Duration | null); /** * Specifies the maximum interval between retries. This parameter is optional, * but must be greater than or equal to the :ref:`base_interval - * ` if set. The default + * ` if set. The default * is 10 times the :ref:`base_interval - * `. + * `. */ 'max_interval'?: (_google_protobuf_Duration | null); } @@ -29,15 +29,15 @@ export interface BackoffStrategy__Output { /** * The base interval to be used for the next back off computation. It should * be greater than zero and less than or equal to :ref:`max_interval - * `. + * `. */ 'base_interval': (_google_protobuf_Duration__Output | null); /** * Specifies the maximum interval between retries. This parameter is optional, * but must be greater than or equal to the :ref:`base_interval - * ` if set. The default + * ` if set. The default * is 10 times the :ref:`base_interval - * `. + * `. */ 'max_interval': (_google_protobuf_Duration__Output | null); } 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 db6b1f654..d3b2cc584 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 @@ -12,7 +12,7 @@ export interface BindConfig { /** * Whether to set the *IP_FREEBIND* option when creating the socket. When this * flag is set to true, allows the :ref:`source_address - * ` to be an IP address + * ` to be an IP address * that is not configured on the system running Envoy. When this flag is set * to false, the option *IP_FREEBIND* is disabled on the socket. When this * flag is not set (default), the socket is not modified, i.e. the option is @@ -34,7 +34,7 @@ export interface BindConfig__Output { /** * Whether to set the *IP_FREEBIND* option when creating the socket. When this * flag is set to true, allows the :ref:`source_address - * ` to be an IP address + * ` to be an IP address * that is not configured on the system running Envoy. When this flag is set * to false, the option *IP_FREEBIND* is disabled on the socket. When this * flag is not set (default), the socket is not modified, i.e. the option is diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/CidrRange.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/CidrRange.ts index df4ff39ff..4e01fa354 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/CidrRange.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/CidrRange.ts @@ -12,7 +12,7 @@ export interface CidrRange { */ 'address_prefix'?: (string); /** - * Length of prefix, e.g. 0, 32. + * Length of prefix, e.g. 0, 32. Defaults to 0 when unset. */ 'prefix_len'?: (_google_protobuf_UInt32Value | null); } @@ -27,7 +27,7 @@ export interface CidrRange__Output { */ 'address_prefix': (string); /** - * Length of prefix, e.g. 0, 32. + * Length of prefix, e.g. 0, 32. Defaults to 0 when unset. */ 'prefix_len': (_google_protobuf_UInt32Value__Output | null); } 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 aaf4d9564..a39c0f077 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 @@ -10,7 +10,7 @@ import type { Authority as _xds_core_v3_Authority, Authority__Output as _xds_cor /** * Configuration for :ref:`listeners `, :ref:`clusters * `, :ref:`routes - * `, :ref:`endpoints + * `, :ref:`endpoints * ` etc. may either be sourced from the * filesystem or from an xDS API source. Filesystem configs are watched with * inotify for updates. @@ -19,7 +19,7 @@ import type { Authority as _xds_core_v3_Authority, Authority__Output as _xds_cor export interface ConfigSource { /** * Path on the filesystem to source and watch for configuration updates. - * When sourcing configuration for :ref:`secret `, + * When sourcing configuration for :ref:`secret `, * the certificate and key files are also watched for updates. * * .. note:: @@ -56,7 +56,7 @@ export interface ConfigSource { * [#not-implemented-hide:] * When set, the client will access the resources from the same server it got the * ConfigSource from, although not necessarily from the same stream. This is similar to the - * :ref:`ads` field, except that the client may use a + * :ref:`ads` field, except that the client may use a * different stream to the same server. As a result, this field can be used for things * like LRS that cannot be sent on an ADS stream. It can also be used to link from (e.g.) * LDS to RDS on the same server without requiring the management server to know its name @@ -85,7 +85,7 @@ export interface ConfigSource { /** * Configuration for :ref:`listeners `, :ref:`clusters * `, :ref:`routes - * `, :ref:`endpoints + * `, :ref:`endpoints * ` etc. may either be sourced from the * filesystem or from an xDS API source. Filesystem configs are watched with * inotify for updates. @@ -94,7 +94,7 @@ export interface ConfigSource { export interface ConfigSource__Output { /** * Path on the filesystem to source and watch for configuration updates. - * When sourcing configuration for :ref:`secret `, + * When sourcing configuration for :ref:`secret `, * the certificate and key files are also watched for updates. * * .. note:: @@ -131,7 +131,7 @@ export interface ConfigSource__Output { * [#not-implemented-hide:] * When set, the client will access the resources from the same server it got the * ConfigSource from, although not necessarily from the same stream. This is similar to the - * :ref:`ads` field, except that the client may use a + * :ref:`ads` field, except that the client may use a * different stream to the same server. As a result, this field can be used for things * like LRS that cannot be sent on an ADS stream. It can also be used to link from (e.g.) * LDS to RDS on the same server without requiring the management server to know its name diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/DnsResolutionConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/DnsResolutionConfig.ts new file mode 100644 index 000000000..c87be12e2 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/DnsResolutionConfig.ts @@ -0,0 +1,42 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/resolver.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 { DnsResolverOptions as _envoy_config_core_v3_DnsResolverOptions, DnsResolverOptions__Output as _envoy_config_core_v3_DnsResolverOptions__Output } from '../../../../envoy/config/core/v3/DnsResolverOptions'; + +/** + * DNS resolution configuration which includes the underlying dns resolver addresses and options. + */ +export interface DnsResolutionConfig { + /** + * A list of dns resolver addresses. If specified, the DNS client library will perform resolution + * via the underlying DNS resolvers. Otherwise, the default system resolvers + * (e.g., /etc/resolv.conf) will be used. + * Setting this value causes failure if the + * ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during + * server startup. Apple's API only allows overriding DNS resolvers via system settings. + */ + 'resolvers'?: (_envoy_config_core_v3_Address)[]; + /** + * Configuration of DNS resolver option flags which control the behavior of the DNS resolver. + */ + 'dns_resolver_options'?: (_envoy_config_core_v3_DnsResolverOptions | null); +} + +/** + * DNS resolution configuration which includes the underlying dns resolver addresses and options. + */ +export interface DnsResolutionConfig__Output { + /** + * A list of dns resolver addresses. If specified, the DNS client library will perform resolution + * via the underlying DNS resolvers. Otherwise, the default system resolvers + * (e.g., /etc/resolv.conf) will be used. + * Setting this value causes failure if the + * ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during + * server startup. Apple's API only allows overriding DNS resolvers via system settings. + */ + 'resolvers': (_envoy_config_core_v3_Address__Output)[]; + /** + * Configuration of DNS resolver option flags which control the behavior of the DNS resolver. + */ + 'dns_resolver_options': (_envoy_config_core_v3_DnsResolverOptions__Output | null); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/DnsResolverOptions.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/DnsResolverOptions.ts new file mode 100644 index 000000000..11b68b150 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/DnsResolverOptions.ts @@ -0,0 +1,36 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/resolver.proto + + +/** + * Configuration of DNS resolver option flags which control the behavior of the DNS resolver. + */ +export interface DnsResolverOptions { + /** + * Use TCP for all DNS queries instead of the default protocol UDP. + * Setting this value causes failure if the + * ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during + * server startup. Apple's API only uses UDP for DNS resolution. + */ + 'use_tcp_for_dns_lookups'?: (boolean); + /** + * Do not use the default search domains; only query hostnames as-is or as aliases. + */ + 'no_default_search_domain'?: (boolean); +} + +/** + * Configuration of DNS resolver option flags which control the behavior of the DNS resolver. + */ +export interface DnsResolverOptions__Output { + /** + * Use TCP for all DNS queries instead of the default protocol UDP. + * Setting this value causes failure if the + * ``envoy.restart_features.use_apple_api_for_dns_lookups`` runtime value is true during + * server startup. Apple's API only uses UDP for DNS resolution. + */ + 'use_tcp_for_dns_lookups': (boolean); + /** + * Do not use the default search domains; only query hostnames as-is or as aliases. + */ + 'no_default_search_domain': (boolean); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/EnvoyInternalAddress.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/EnvoyInternalAddress.ts index dfe6a52b4..936e433db 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/EnvoyInternalAddress.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/EnvoyInternalAddress.ts @@ -8,7 +8,7 @@ */ export interface EnvoyInternalAddress { /** - * [#not-implemented-hide:] The :ref:`listener name ` of the destination internal listener. + * [#not-implemented-hide:] The :ref:`listener name ` of the destination internal listener. */ 'server_listener_name'?: (string); 'address_name_specifier'?: "server_listener_name"; @@ -21,7 +21,7 @@ export interface EnvoyInternalAddress { */ export interface EnvoyInternalAddress__Output { /** - * [#not-implemented-hide:] The :ref:`listener name ` of the destination internal listener. + * [#not-implemented-hide:] The :ref:`listener name ` of the destination internal listener. */ 'server_listener_name'?: (string); 'address_name_specifier': "server_listener_name"; diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/GrpcService.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/GrpcService.ts index 0e55d018b..0d81f7340 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/GrpcService.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/GrpcService.ts @@ -148,8 +148,8 @@ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials export interface _envoy_config_core_v3_GrpcService_EnvoyGrpc { /** * The name of the upstream gRPC cluster. SSL credentials will be supplied - * in the :ref:`Cluster ` :ref:`transport_socket - * `. + * in the :ref:`Cluster ` :ref:`transport_socket + * `. */ 'cluster_name'?: (string); /** @@ -162,8 +162,8 @@ export interface _envoy_config_core_v3_GrpcService_EnvoyGrpc { export interface _envoy_config_core_v3_GrpcService_EnvoyGrpc__Output { /** * The name of the upstream gRPC cluster. SSL credentials will be supplied - * in the :ref:`Cluster ` :ref:`transport_socket - * `. + * in the :ref:`Cluster ` :ref:`transport_socket + * `. */ 'cluster_name': (string); /** @@ -180,7 +180,7 @@ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc { /** * The target URI when using the `Google C++ gRPC client * `_. SSL credentials will be supplied in - * :ref:`channel_credentials `. + * :ref:`channel_credentials `. */ 'target_uri'?: (string); 'channel_credentials'?: (_envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials | null); @@ -230,7 +230,7 @@ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc__Output { /** * The target URI when using the `Google C++ gRPC client * `_. SSL credentials will be supplied in - * :ref:`channel_credentials `. + * :ref:`channel_credentials `. */ 'target_uri': (string); 'channel_credentials': (_envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelCredentials__Output | null); @@ -300,12 +300,18 @@ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_GoogleLocalCredent export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin { 'name'?: (string); 'typed_config'?: (_google_protobuf_Any | null); + /** + * [#extension-category: envoy.grpc_credentials] + */ 'config_type'?: "typed_config"; } export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_CallCredentials_MetadataCredentialsFromPlugin__Output { 'name': (string); 'typed_config'?: (_google_protobuf_Any__Output | null); + /** + * [#extension-category: envoy.grpc_credentials] + */ 'config_type': "typed_config"; } @@ -485,7 +491,7 @@ export interface _envoy_config_core_v3_GrpcService_GoogleGrpc_ChannelArgs_Value_ /** * gRPC service configuration. This is used by :ref:`ApiConfigSource - * ` and filter configurations. + * ` and filter configurations. * [#next-free-field: 6] */ export interface GrpcService { @@ -519,7 +525,7 @@ export interface GrpcService { /** * gRPC service configuration. This is used by :ref:`ApiConfigSource - * ` and filter configurations. + * ` and filter configurations. * [#next-free-field: 6] */ export interface GrpcService__Output { 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 29f9d6695..7ba7e9d8d 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 @@ -3,6 +3,31 @@ import type { HeaderValue as _envoy_config_core_v3_HeaderValue, HeaderValue__Output as _envoy_config_core_v3_HeaderValue__Output } from '../../../../envoy/config/core/v3/HeaderValue'; import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + +/** + * Describes the supported actions types for header append action. + */ +export enum _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, +} + /** * Header name/value pair plus option to control append behavior. */ @@ -16,6 +41,11 @@ export interface HeaderValueOption { * existing values. Otherwise it replaces any existing values. */ 'append'?: (_google_protobuf_BoolValue | null); + /** + * [#not-implemented-hide:] Describes the action taken to append/overwrite the given value for an existing header + * or to only add this header if it's absent. 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); } /** @@ -31,4 +61,9 @@ export interface HeaderValueOption__Output { * existing values. Otherwise it replaces any existing values. */ 'append': (_google_protobuf_BoolValue__Output | null); + /** + * [#not-implemented-hide:] Describes the action taken to append/overwrite the given value for an existing header + * or to only add this header if it's absent. Value defaults to :ref:`APPEND_IF_EXISTS_OR_ADD`. + */ + 'append_action': (keyof typeof _envoy_config_core_v3_HeaderValueOption_HeaderAppendAction); } 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 6dbbf6f4d..8882de614 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 @@ -24,6 +24,7 @@ export interface _envoy_config_core_v3_HealthCheck_CustomHealthCheck { /** * A custom health checker specific configuration which depends on the custom health checker * being instantiated. See :api:`envoy/config/health_checker` for reference. + * [#extension-category: envoy.health_checkers] */ 'config_type'?: "typed_config"; } @@ -40,6 +41,7 @@ export interface _envoy_config_core_v3_HealthCheck_CustomHealthCheck__Output { /** * A custom health checker specific configuration which depends on the custom health checker * being instantiated. See :api:`envoy/config/health_checker` for reference. + * [#extension-category: envoy.health_checkers] */ 'config_type': "typed_config"; } @@ -63,7 +65,7 @@ export interface _envoy_config_core_v3_HealthCheck_GrpcHealthCheck { * The value of the :authority header in the gRPC health check request. If * left empty (default value), the name of the cluster this health check is associated * with will be used. The authority header can be customized for a specific endpoint by setting - * the :ref:`hostname ` field. + * the :ref:`hostname ` field. */ 'authority'?: (string); } @@ -87,20 +89,20 @@ export interface _envoy_config_core_v3_HealthCheck_GrpcHealthCheck__Output { * The value of the :authority header in the gRPC health check request. If * left empty (default value), the name of the cluster this health check is associated * with will be used. The authority header can be customized for a specific endpoint by setting - * the :ref:`hostname ` field. + * the :ref:`hostname ` field. */ 'authority': (string); } /** - * [#next-free-field: 12] + * [#next-free-field: 13] */ export interface _envoy_config_core_v3_HealthCheck_HttpHealthCheck { /** * The value of the host header in the HTTP health check request. If * left empty (default value), the name of the cluster this health check is associated * with will be used. The host header can be customized for a specific endpoint by setting the - * :ref:`hostname ` field. + * :ref:`hostname ` field. */ 'host'?: (string); /** @@ -131,10 +133,23 @@ export interface _envoy_config_core_v3_HealthCheck_HttpHealthCheck { /** * Specifies a list of HTTP response statuses considered healthy. If provided, replaces default * 200-only policy - 200 must be included explicitly as needed. Ranges follow half-open - * semantics of :ref:`Int64Range `. The start and end of each + * semantics of :ref:`Int64Range `. The start and end of each * range are required. Only statuses in the range [100, 600) are allowed. */ 'expected_statuses'?: (_envoy_type_v3_Int64Range)[]; + /** + * Specifies a list of HTTP response statuses considered retriable. If provided, responses in this range + * will count towards the configured :ref:`unhealthy_threshold `, + * but will not result in the host being considered immediately unhealthy. Ranges follow half-open semantics of + * :ref:`Int64Range `. The start and end of each range are required. + * Only statuses in the range [100, 600) are allowed. The :ref:`expected_statuses ` + * field takes precedence for any range overlaps with this field i.e. if status code 200 is both retriable and expected, a 200 response will + * be considered a successful health check. By default all responses not in + * :ref:`expected_statuses ` will result in + * the host being considered immediately unhealthy i.e. if status code 200 is expected and there are no configured retriable statuses, any + * non-200 response will result in the host being marked unhealthy. + */ + 'retriable_statuses'?: (_envoy_type_v3_Int64Range)[]; /** * Use specified application protocol for health checks. */ @@ -142,21 +157,21 @@ export interface _envoy_config_core_v3_HealthCheck_HttpHealthCheck { /** * An optional service name parameter which is used to validate the identity of * the health checked cluster using a :ref:`StringMatcher - * `. See the :ref:`architecture overview + * `. See the :ref:`architecture overview * ` for more information. */ 'service_name_matcher'?: (_envoy_type_matcher_v3_StringMatcher | null); } /** - * [#next-free-field: 12] + * [#next-free-field: 13] */ export interface _envoy_config_core_v3_HealthCheck_HttpHealthCheck__Output { /** * The value of the host header in the HTTP health check request. If * left empty (default value), the name of the cluster this health check is associated * with will be used. The host header can be customized for a specific endpoint by setting the - * :ref:`hostname ` field. + * :ref:`hostname ` field. */ 'host': (string); /** @@ -187,10 +202,23 @@ export interface _envoy_config_core_v3_HealthCheck_HttpHealthCheck__Output { /** * Specifies a list of HTTP response statuses considered healthy. If provided, replaces default * 200-only policy - 200 must be included explicitly as needed. Ranges follow half-open - * semantics of :ref:`Int64Range `. The start and end of each + * semantics of :ref:`Int64Range `. The start and end of each * range are required. Only statuses in the range [100, 600) are allowed. */ 'expected_statuses': (_envoy_type_v3_Int64Range__Output)[]; + /** + * Specifies a list of HTTP response statuses considered retriable. If provided, responses in this range + * will count towards the configured :ref:`unhealthy_threshold `, + * but will not result in the host being considered immediately unhealthy. Ranges follow half-open semantics of + * :ref:`Int64Range `. The start and end of each range are required. + * Only statuses in the range [100, 600) are allowed. The :ref:`expected_statuses ` + * field takes precedence for any range overlaps with this field i.e. if status code 200 is both retriable and expected, a 200 response will + * be considered a successful health check. By default all responses not in + * :ref:`expected_statuses ` will result in + * the host being considered immediately unhealthy i.e. if status code 200 is expected and there are no configured retriable statuses, any + * non-200 response will result in the host being marked unhealthy. + */ + 'retriable_statuses': (_envoy_type_v3_Int64Range__Output)[]; /** * Use specified application protocol for health checks. */ @@ -198,7 +226,7 @@ export interface _envoy_config_core_v3_HealthCheck_HttpHealthCheck__Output { /** * An optional service name parameter which is used to validate the identity of * the health checked cluster using a :ref:`StringMatcher - * `. See the :ref:`architecture overview + * `. See the :ref:`architecture overview * ` for more information. */ 'service_name_matcher': (_envoy_type_matcher_v3_StringMatcher__Output | null); @@ -290,7 +318,7 @@ export interface _envoy_config_core_v3_HealthCheck_TlsOptions { /** * Specifies the ALPN protocols for health check connections. This is useful if the * corresponding upstream is using ALPN-based :ref:`FilterChainMatch - * ` along with different protocols for health checks + * ` along with different protocols for health checks * versus data connections. If empty, no ALPN protocols will be set on health check connections. */ 'alpn_protocols'?: (string)[]; @@ -306,7 +334,7 @@ export interface _envoy_config_core_v3_HealthCheck_TlsOptions__Output { /** * Specifies the ALPN protocols for health check connections. This is useful if the * corresponding upstream is using ALPN-based :ref:`FilterChainMatch - * ` along with different protocols for health checks + * ` along with different protocols for health checks * versus data connections. If empty, no ALPN protocols will be set on health check connections. */ 'alpn_protocols': (string)[]; @@ -332,8 +360,10 @@ export interface HealthCheck { 'interval_jitter'?: (_google_protobuf_Duration | null); /** * The number of unhealthy health checks required before a host is marked - * unhealthy. Note that for *http* health checking if a host responds with 503 - * this threshold is ignored and the host is considered unhealthy immediately. + * unhealthy. Note that for *http* health checking if a host responds with a code not in + * :ref:`expected_statuses ` + * or :ref:`retriable_statuses `, + * this threshold is ignored and the host is considered immediately unhealthy. */ 'unhealthy_threshold'?: (_google_protobuf_UInt32Value | null); /** @@ -440,7 +470,7 @@ export interface HealthCheck { 'event_service'?: (_envoy_config_core_v3_EventServiceConfig | null); /** * Optional key/value pairs that will be used to match a transport socket from those specified in the cluster's - * :ref:`tranport socket matches `. + * :ref:`tranport socket matches `. * For example, the following match criteria * * .. code-block:: yaml @@ -448,7 +478,7 @@ export interface HealthCheck { * transport_socket_match_criteria: * useMTLS: true * - * Will match the following :ref:`cluster socket match ` + * Will match the following :ref:`cluster socket match ` * * .. code-block:: yaml * @@ -461,13 +491,13 @@ export interface HealthCheck { * config: { ... } # tls socket configuration * * If this field is set, then for health checks it will supersede an entry of *envoy.transport_socket* in the - * :ref:`LbEndpoint.Metadata `. + * :ref:`LbEndpoint.Metadata `. * This allows using different transport socket capabilities for health checking versus proxying to the * endpoint. * * If the key/values pairs specified do not match any - * :ref:`transport socket matches `, - * the cluster's :ref:`transport socket ` + * :ref:`transport socket matches `, + * the cluster's :ref:`transport socket ` * will be used for health check socket configuration. */ 'transport_socket_match_criteria'?: (_google_protobuf_Struct | null); @@ -510,8 +540,10 @@ export interface HealthCheck__Output { 'interval_jitter': (_google_protobuf_Duration__Output | null); /** * The number of unhealthy health checks required before a host is marked - * unhealthy. Note that for *http* health checking if a host responds with 503 - * this threshold is ignored and the host is considered unhealthy immediately. + * unhealthy. Note that for *http* health checking if a host responds with a code not in + * :ref:`expected_statuses ` + * or :ref:`retriable_statuses `, + * this threshold is ignored and the host is considered immediately unhealthy. */ 'unhealthy_threshold': (_google_protobuf_UInt32Value__Output | null); /** @@ -618,7 +650,7 @@ export interface HealthCheck__Output { 'event_service': (_envoy_config_core_v3_EventServiceConfig__Output | null); /** * Optional key/value pairs that will be used to match a transport socket from those specified in the cluster's - * :ref:`tranport socket matches `. + * :ref:`tranport socket matches `. * For example, the following match criteria * * .. code-block:: yaml @@ -626,7 +658,7 @@ export interface HealthCheck__Output { * transport_socket_match_criteria: * useMTLS: true * - * Will match the following :ref:`cluster socket match ` + * Will match the following :ref:`cluster socket match ` * * .. code-block:: yaml * @@ -639,13 +671,13 @@ export interface HealthCheck__Output { * config: { ... } # tls socket configuration * * If this field is set, then for health checks it will supersede an entry of *envoy.transport_socket* in the - * :ref:`LbEndpoint.Metadata `. + * :ref:`LbEndpoint.Metadata `. * This allows using different transport socket capabilities for health checking versus proxying to the * endpoint. * * If the key/values pairs specified do not match any - * :ref:`transport socket matches `, - * the cluster's :ref:`transport socket ` + * :ref:`transport socket matches `, + * the cluster's :ref:`transport socket ` * will be used for health check socket configuration. */ 'transport_socket_match_criteria': (_google_protobuf_Struct__Output | null); diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http1ProtocolOptions.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http1ProtocolOptions.ts index 89889d390..40b7408f6 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http1ProtocolOptions.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http1ProtocolOptions.ts @@ -1,7 +1,11 @@ // Original file: deps/envoy-api/envoy/config/core/v3/protocol.proto import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; +import type { TypedExtensionConfig as _envoy_config_core_v3_TypedExtensionConfig, TypedExtensionConfig__Output as _envoy_config_core_v3_TypedExtensionConfig__Output } from '../../../../envoy/config/core/v3/TypedExtensionConfig'; +/** + * [#next-free-field: 9] + */ export interface _envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat { /** * Formats the header by proper casing words: the first character and any character following @@ -11,9 +15,18 @@ export interface _envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat { * are not covered. For example, the "TE" header will be formatted as "Te". */ 'proper_case_words'?: (_envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords | null); - 'header_format'?: "proper_case_words"; + /** + * Configuration for stateful formatter extensions that allow using received headers to + * affect the output of encoding headers. E.g., preserving case during proxying. + * [#extension-category: envoy.http.stateful_header_formatters] + */ + 'stateful_formatter'?: (_envoy_config_core_v3_TypedExtensionConfig | null); + 'header_format'?: "proper_case_words"|"stateful_formatter"; } +/** + * [#next-free-field: 9] + */ export interface _envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat__Output { /** * Formats the header by proper casing words: the first character and any character following @@ -23,7 +36,13 @@ export interface _envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat__Out * are not covered. For example, the "TE" header will be formatted as "Te". */ 'proper_case_words'?: (_envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords__Output | null); - 'header_format': "proper_case_words"; + /** + * Configuration for stateful formatter extensions that allow using received headers to + * affect the output of encoding headers. E.g., preserving case during proxying. + * [#extension-category: envoy.http.stateful_header_formatters] + */ + 'stateful_formatter'?: (_envoy_config_core_v3_TypedExtensionConfig__Output | null); + 'header_format': "proper_case_words"|"stateful_formatter"; } export interface _envoy_config_core_v3_Http1ProtocolOptions_HeaderKeyFormat_ProperCaseWords { 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 52908c961..786e2a00d 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 @@ -53,6 +53,10 @@ export interface Http2ProtocolOptions { * For upstream connections, this also limits how many streams Envoy will initiate concurrently * on a single connection. If the limit is reached, Envoy may queue requests or establish * additional connections (as allowed per circuit breaker limits). + * + * This acts as an upper bound: Envoy will lower the max concurrent streams allowed on a given + * connection based on upstream settings. Config dumps will reflect the configured upper bound, + * not the per-connection negotiated limits. */ 'max_concurrent_streams'?: (_google_protobuf_UInt32Value | null); /** @@ -233,6 +237,10 @@ export interface Http2ProtocolOptions__Output { * For upstream connections, this also limits how many streams Envoy will initiate concurrently * on a single connection. If the limit is reached, Envoy may queue requests or establish * additional connections (as allowed per circuit breaker limits). + * + * This acts as an upper bound: Envoy will lower the max concurrent streams allowed on a given + * connection based on upstream settings. Config dumps will reflect the configured upper bound, + * not the per-connection negotiated limits. */ 'max_concurrent_streams': (_google_protobuf_UInt32Value__Output | null); /** diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http3ProtocolOptions.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http3ProtocolOptions.ts index 320285d87..51b31b8e7 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http3ProtocolOptions.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Http3ProtocolOptions.ts @@ -1,22 +1,56 @@ // Original file: deps/envoy-api/envoy/config/core/v3/protocol.proto +import type { QuicProtocolOptions as _envoy_config_core_v3_QuicProtocolOptions, QuicProtocolOptions__Output as _envoy_config_core_v3_QuicProtocolOptions__Output } from '../../../../envoy/config/core/v3/QuicProtocolOptions'; +import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; /** - * [#not-implemented-hide:] - * - * A message which allows using HTTP/3 as an upstream protocol. - * - * Eventually this will include configuration for tuning HTTP/3. + * A message which allows using HTTP/3. + * [#next-free-field: 6] */ export interface Http3ProtocolOptions { + 'quic_protocol_options'?: (_envoy_config_core_v3_QuicProtocolOptions | null); + /** + * Allows invalid HTTP messaging and headers. When this option is disabled (default), then + * the whole HTTP/3 connection is terminated upon receiving invalid HEADERS frame. However, + * when this option is enabled, only the offending stream is terminated. + * + * If set, this overrides any HCM :ref:`stream_error_on_invalid_http_messaging + * `. + */ + 'override_stream_error_on_invalid_http_message'?: (_google_protobuf_BoolValue | null); + /** + * Allows proxying Websocket and other upgrades over HTTP/3 CONNECT using + * the header mechanisms from the `HTTP/2 extended connect RFC + * `_ + * and settings `proposed for HTTP/3 + * `_ + * Note that HTTP/3 CONNECT is not yet an RFC. + */ + 'allow_extended_connect'?: (boolean); } /** - * [#not-implemented-hide:] - * - * A message which allows using HTTP/3 as an upstream protocol. - * - * Eventually this will include configuration for tuning HTTP/3. + * A message which allows using HTTP/3. + * [#next-free-field: 6] */ export interface Http3ProtocolOptions__Output { + 'quic_protocol_options': (_envoy_config_core_v3_QuicProtocolOptions__Output | null); + /** + * Allows invalid HTTP messaging and headers. When this option is disabled (default), then + * the whole HTTP/3 connection is terminated upon receiving invalid HEADERS frame. However, + * when this option is enabled, only the offending stream is terminated. + * + * If set, this overrides any HCM :ref:`stream_error_on_invalid_http_messaging + * `. + */ + 'override_stream_error_on_invalid_http_message': (_google_protobuf_BoolValue__Output | null); + /** + * Allows proxying Websocket and other upgrades over HTTP/3 CONNECT using + * the header mechanisms from the `HTTP/2 extended connect RFC + * `_ + * and settings `proposed for HTTP/3 + * `_ + * Note that HTTP/3 CONNECT is not yet an RFC. + */ + 'allow_extended_connect': (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 f689ba802..34a4053dd 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 @@ -32,7 +32,7 @@ export enum _envoy_config_core_v3_HttpProtocolOptions_HeadersWithUnderscoresActi } /** - * [#next-free-field: 6] + * [#next-free-field: 7] */ export interface HttpProtocolOptions { /** @@ -41,7 +41,7 @@ export interface HttpProtocolOptions { * idle timeout is reached the connection will be closed. If the connection is an HTTP/2 * downstream connection a drain sequence will occur prior to closing the connection, see * :ref:`drain_timeout - * `. + * `. * Note that request based timeouts mean that HTTP/2 PINGs will not keep the connection alive. * If not specified, this defaults to 1 hour. To disable idle timeouts explicitly set this to 0. * @@ -51,7 +51,7 @@ export interface HttpProtocolOptions { * * If the :ref:`overload action ` "envoy.overload_actions.reduce_timeouts" * is configured, this timeout is scaled for downstream connections according to the value for - * :ref:`HTTP_DOWNSTREAM_CONNECTION_IDLE `. + * :ref:`HTTP_DOWNSTREAM_CONNECTION_IDLE `. */ 'idle_timeout'?: (_google_protobuf_Duration | null); /** @@ -63,10 +63,11 @@ export interface HttpProtocolOptions { /** * The maximum duration of a connection. The duration is defined as a period since a connection * was established. If not set, there is no max duration. When max_connection_duration is reached - * the connection will be closed. Drain sequence will occur prior to closing the connection if - * if's applicable. See :ref:`drain_timeout - * `. - * Note: not implemented for upstream connections. + * and if there are no active streams, the connection will be closed. If there are any active streams, + * the drain sequence will kick-in, and the connection will be force-closed after the drain period. + * See :ref:`drain_timeout + * `. + * Note: This feature is not yet implemented for the upstream connections. */ 'max_connection_duration'?: (_google_protobuf_Duration | null); /** @@ -80,10 +81,17 @@ export interface HttpProtocolOptions { * Note: upstream responses are not affected by this setting. */ 'headers_with_underscores_action'?: (_envoy_config_core_v3_HttpProtocolOptions_HeadersWithUnderscoresAction | keyof typeof _envoy_config_core_v3_HttpProtocolOptions_HeadersWithUnderscoresAction); + /** + * Optional maximum requests for both upstream and downstream connections. + * If not specified, there is no limit. + * Setting this parameter to 1 will effectively disable keep alive. + * For HTTP/2 and HTTP/3, due to concurrent stream processing, the limit is approximate. + */ + 'max_requests_per_connection'?: (_google_protobuf_UInt32Value | null); } /** - * [#next-free-field: 6] + * [#next-free-field: 7] */ export interface HttpProtocolOptions__Output { /** @@ -92,7 +100,7 @@ export interface HttpProtocolOptions__Output { * idle timeout is reached the connection will be closed. If the connection is an HTTP/2 * downstream connection a drain sequence will occur prior to closing the connection, see * :ref:`drain_timeout - * `. + * `. * Note that request based timeouts mean that HTTP/2 PINGs will not keep the connection alive. * If not specified, this defaults to 1 hour. To disable idle timeouts explicitly set this to 0. * @@ -102,7 +110,7 @@ export interface HttpProtocolOptions__Output { * * If the :ref:`overload action ` "envoy.overload_actions.reduce_timeouts" * is configured, this timeout is scaled for downstream connections according to the value for - * :ref:`HTTP_DOWNSTREAM_CONNECTION_IDLE `. + * :ref:`HTTP_DOWNSTREAM_CONNECTION_IDLE `. */ 'idle_timeout': (_google_protobuf_Duration__Output | null); /** @@ -114,10 +122,11 @@ export interface HttpProtocolOptions__Output { /** * The maximum duration of a connection. The duration is defined as a period since a connection * was established. If not set, there is no max duration. When max_connection_duration is reached - * the connection will be closed. Drain sequence will occur prior to closing the connection if - * if's applicable. See :ref:`drain_timeout - * `. - * Note: not implemented for upstream connections. + * and if there are no active streams, the connection will be closed. If there are any active streams, + * the drain sequence will kick-in, and the connection will be force-closed after the drain period. + * See :ref:`drain_timeout + * `. + * Note: This feature is not yet implemented for the upstream connections. */ 'max_connection_duration': (_google_protobuf_Duration__Output | null); /** @@ -131,4 +140,11 @@ export interface HttpProtocolOptions__Output { * Note: upstream responses are not affected by this setting. */ 'headers_with_underscores_action': (keyof typeof _envoy_config_core_v3_HttpProtocolOptions_HeadersWithUnderscoresAction); + /** + * Optional maximum requests for both upstream and downstream connections. + * If not specified, there is no limit. + * Setting this parameter to 1 will effectively disable keep alive. + * For HTTP/2 and HTTP/3, due to concurrent stream processing, the limit is approximate. + */ + 'max_requests_per_connection': (_google_protobuf_UInt32Value__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/KeepaliveSettings.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/KeepaliveSettings.ts index 81344f864..2c274c6e1 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/KeepaliveSettings.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/KeepaliveSettings.ts @@ -6,6 +6,7 @@ import type { Percent as _envoy_type_v3_Percent, Percent__Output as _envoy_type_ export interface KeepaliveSettings { /** * Send HTTP/2 PING frames at this period, in order to test that the connection is still alive. + * If this is zero, interval PINGs will not be sent. */ 'interval'?: (_google_protobuf_Duration | null); /** @@ -19,11 +20,20 @@ export interface KeepaliveSettings { * The default value is 15%. */ 'interval_jitter'?: (_envoy_type_v3_Percent | null); + /** + * If the connection has been idle for this duration, send a HTTP/2 ping ahead + * of new stream creation, to quickly detect dead connections. + * If this is zero, this type of PING will not be sent. + * If an interval ping is outstanding, a second ping will not be sent as the + * interval ping will determine if the connection is dead. + */ + 'connection_idle_interval'?: (_google_protobuf_Duration | null); } export interface KeepaliveSettings__Output { /** * Send HTTP/2 PING frames at this period, in order to test that the connection is still alive. + * If this is zero, interval PINGs will not be sent. */ 'interval': (_google_protobuf_Duration__Output | null); /** @@ -37,4 +47,12 @@ export interface KeepaliveSettings__Output { * The default value is 15%. */ 'interval_jitter': (_envoy_type_v3_Percent__Output | null); + /** + * If the connection has been idle for this duration, send a HTTP/2 ping ahead + * of new stream creation, to quickly detect dead connections. + * If this is zero, this type of PING will not be sent. + * If an interval ping is outstanding, a second ping will not be sent as the + * interval ping will determine if the connection is dead. + */ + 'connection_idle_interval': (_google_protobuf_Duration__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Locality.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Locality.ts index 2b4b42a75..b15b53832 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Locality.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Locality.ts @@ -6,13 +6,13 @@ */ export interface Locality { /** - * Region this :ref:`zone ` belongs to. + * Region this :ref:`zone ` belongs to. */ 'region'?: (string); /** * Defines the local service zone where Envoy is running. Though optional, it * should be set if discovery service routing is used and the discovery - * service exposes :ref:`zone data `, + * service exposes :ref:`zone data `, * either in this message or via :option:`--service-zone`. The meaning of zone * is context dependent, e.g. `Availability Zone (AZ) * `_ @@ -33,13 +33,13 @@ export interface Locality { */ export interface Locality__Output { /** - * Region this :ref:`zone ` belongs to. + * Region this :ref:`zone ` belongs to. */ 'region': (string); /** * Defines the local service zone where Envoy is running. Though optional, it * should be set if discovery service routing is used and the discovery - * service exposes :ref:`zone data `, + * service exposes :ref:`zone data `, * either in this message or via :option:`--service-zone`. The meaning of zone * is context dependent, e.g. `Availability Zone (AZ) * `_ diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Metadata.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Metadata.ts index 8d1811c67..fb603c2ba 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Metadata.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/Metadata.ts @@ -1,6 +1,7 @@ // Original file: deps/envoy-api/envoy/config/core/v3/base.proto import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; +import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; /** * Metadata provides additional inputs to filters based on matched listeners, @@ -30,8 +31,21 @@ export interface Metadata { /** * Key is the reverse DNS filter name, e.g. com.acme.widget. The envoy.* * namespace is reserved for Envoy's built-in filters. + * If both *filter_metadata* and + * :ref:`typed_filter_metadata ` + * fields are present in the metadata with same keys, + * only *typed_filter_metadata* field will be parsed. */ 'filter_metadata'?: ({[key: string]: _google_protobuf_Struct}); + /** + * Key is the reverse DNS filter name, e.g. com.acme.widget. The envoy.* + * namespace is reserved for Envoy's built-in filters. + * The value is encoded as google.protobuf.Any. + * If both :ref:`filter_metadata ` + * and *typed_filter_metadata* fields are present in the metadata with same keys, + * only *typed_filter_metadata* field will be parsed. + */ + 'typed_filter_metadata'?: ({[key: string]: _google_protobuf_Any}); } /** @@ -62,6 +76,19 @@ export interface Metadata__Output { /** * Key is the reverse DNS filter name, e.g. com.acme.widget. The envoy.* * namespace is reserved for Envoy's built-in filters. + * If both *filter_metadata* and + * :ref:`typed_filter_metadata ` + * fields are present in the metadata with same keys, + * only *typed_filter_metadata* field will be parsed. */ 'filter_metadata': ({[key: string]: _google_protobuf_Struct__Output}); + /** + * Key is the reverse DNS filter name, e.g. com.acme.widget. The envoy.* + * namespace is reserved for Envoy's built-in filters. + * The value is encoded as google.protobuf.Any. + * If both :ref:`filter_metadata ` + * and *typed_filter_metadata* fields are present in the metadata with same keys, + * only *typed_filter_metadata* field will be parsed. + */ + 'typed_filter_metadata': ({[key: string]: _google_protobuf_Any__Output}); } 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 7218b802e..addd47a68 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 @@ -5,12 +5,13 @@ import type { Locality as _envoy_config_core_v3_Locality, Locality__Output as _e import type { BuildVersion as _envoy_config_core_v3_BuildVersion, BuildVersion__Output as _envoy_config_core_v3_BuildVersion__Output } from '../../../../envoy/config/core/v3/BuildVersion'; import type { Extension as _envoy_config_core_v3_Extension, Extension__Output as _envoy_config_core_v3_Extension__Output } from '../../../../envoy/config/core/v3/Extension'; 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 { ContextParams as _xds_core_v3_ContextParams, ContextParams__Output as _xds_core_v3_ContextParams__Output } from '../../../../xds/core/v3/ContextParams'; /** * Identifies a specific Envoy instance. The node identifier is presented to the * management server, which may use this identifier to distinguish per Envoy * configuration for serving. - * [#next-free-field: 12] + * [#next-free-field: 13] */ export interface Node { /** @@ -27,10 +28,10 @@ export interface Node { * optional, it should be set if any of the following features are used: * :ref:`statsd `, :ref:`health check cluster * verification - * `, - * :ref:`runtime override directory `, + * `, + * :ref:`runtime override directory `, * :ref:`user agent addition - * `, + * `, * :ref:`HTTP global rate limiting `, * :ref:`CDS `, and :ref:`HTTP tracing * `, either in this message or via @@ -79,6 +80,14 @@ export interface Node { * SocketAddress `(0.0.0.0,80)`. The field is optional and just a hint. */ 'listening_addresses'?: (_envoy_config_core_v3_Address)[]; + /** + * Map from xDS resource type URL to dynamic context parameters. These may vary at runtime (unlike + * other fields in this message). For example, the xDS client may have a shard identifier that + * changes during the lifetime of the xDS client. In Envoy, this would be achieved by updating the + * dynamic context on the Server::Instance's LocalInfo context provider. The shard ID dynamic + * parameter then appears in this field during future discovery requests. + */ + 'dynamic_parameters'?: ({[key: string]: _xds_core_v3_ContextParams}); 'user_agent_version_type'?: "user_agent_version"|"user_agent_build_version"; } @@ -86,7 +95,7 @@ export interface Node { * Identifies a specific Envoy instance. The node identifier is presented to the * management server, which may use this identifier to distinguish per Envoy * configuration for serving. - * [#next-free-field: 12] + * [#next-free-field: 13] */ export interface Node__Output { /** @@ -103,10 +112,10 @@ export interface Node__Output { * optional, it should be set if any of the following features are used: * :ref:`statsd `, :ref:`health check cluster * verification - * `, - * :ref:`runtime override directory `, + * `, + * :ref:`runtime override directory `, * :ref:`user agent addition - * `, + * `, * :ref:`HTTP global rate limiting `, * :ref:`CDS `, and :ref:`HTTP tracing * `, either in this message or via @@ -155,5 +164,13 @@ export interface Node__Output { * SocketAddress `(0.0.0.0,80)`. The field is optional and just a hint. */ 'listening_addresses': (_envoy_config_core_v3_Address__Output)[]; + /** + * Map from xDS resource type URL to dynamic context parameters. These may vary at runtime (unlike + * other fields in this message). For example, the xDS client may have a shard identifier that + * changes during the lifetime of the xDS client. In Envoy, this would be achieved by updating the + * dynamic context on the Server::Instance's LocalInfo context provider. The shard ID dynamic + * parameter then appears in this field during future discovery requests. + */ + 'dynamic_parameters': ({[key: string]: _xds_core_v3_ContextParams__Output}); 'user_agent_version_type': "user_agent_version"|"user_agent_build_version"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/QueryParameter.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/QueryParameter.ts new file mode 100644 index 000000000..4cf7952fb --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/QueryParameter.ts @@ -0,0 +1,30 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/base.proto + + +/** + * Query parameter name/value pair. + */ +export interface QueryParameter { + /** + * The key of the query parameter. Case sensitive. + */ + 'key'?: (string); + /** + * The value of the query parameter. + */ + 'value'?: (string); +} + +/** + * Query parameter name/value pair. + */ +export interface QueryParameter__Output { + /** + * The key of the query parameter. Case sensitive. + */ + 'key': (string); + /** + * The value of the query parameter. + */ + 'value': (string); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/QuicProtocolOptions.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/QuicProtocolOptions.ts new file mode 100644 index 000000000..6a653b54d --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/QuicProtocolOptions.ts @@ -0,0 +1,69 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/protocol.proto + +import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; + +/** + * QUIC protocol options which apply to both downstream and upstream connections. + */ +export interface QuicProtocolOptions { + /** + * Maximum number of streams that the client can negotiate per connection. 100 + * if not specified. + */ + 'max_concurrent_streams'?: (_google_protobuf_UInt32Value | null); + /** + * `Initial stream-level flow-control receive window + * `_ size. Valid values range from + * 1 to 16777216 (2^24, maximum supported by QUICHE) and defaults to 65536 (2^16). + * + * NOTE: 16384 (2^14) is the minimum window size supported in Google QUIC. If configured smaller than it, we will use 16384 instead. + * QUICHE IETF Quic implementation supports 1 bytes window. We only support increasing the default window size now, so it's also the minimum. + * + * This field also acts as a soft limit on the number of bytes Envoy will buffer per-stream in the + * QUIC stream send and receive buffers. Once the buffer reaches this pointer, watermark callbacks will fire to + * stop the flow of data to the stream buffers. + */ + 'initial_stream_window_size'?: (_google_protobuf_UInt32Value | null); + /** + * Similar to *initial_stream_window_size*, but for connection-level + * flow-control. Valid values rage from 1 to 25165824 (24MB, maximum supported by QUICHE) and defaults to 65536 (2^16). + * window. Currently, this has the same minimum/default as *initial_stream_window_size*. + * + * NOTE: 16384 (2^14) is the minimum window size supported in Google QUIC. We only support increasing the default + * window size now, so it's also the minimum. + */ + 'initial_connection_window_size'?: (_google_protobuf_UInt32Value | null); +} + +/** + * QUIC protocol options which apply to both downstream and upstream connections. + */ +export interface QuicProtocolOptions__Output { + /** + * Maximum number of streams that the client can negotiate per connection. 100 + * if not specified. + */ + 'max_concurrent_streams': (_google_protobuf_UInt32Value__Output | null); + /** + * `Initial stream-level flow-control receive window + * `_ size. Valid values range from + * 1 to 16777216 (2^24, maximum supported by QUICHE) and defaults to 65536 (2^16). + * + * NOTE: 16384 (2^14) is the minimum window size supported in Google QUIC. If configured smaller than it, we will use 16384 instead. + * QUICHE IETF Quic implementation supports 1 bytes window. We only support increasing the default window size now, so it's also the minimum. + * + * This field also acts as a soft limit on the number of bytes Envoy will buffer per-stream in the + * QUIC stream send and receive buffers. Once the buffer reaches this pointer, watermark callbacks will fire to + * stop the flow of data to the stream buffers. + */ + 'initial_stream_window_size': (_google_protobuf_UInt32Value__Output | null); + /** + * Similar to *initial_stream_window_size*, but for connection-level + * flow-control. Valid values rage from 1 to 25165824 (24MB, maximum supported by QUICHE) and defaults to 65536 (2^16). + * window. Currently, this has the same minimum/default as *initial_stream_window_size*. + * + * NOTE: 16384 (2^14) is the minimum window size supported in Google QUIC. We only support increasing the default + * window size now, so it's also the minimum. + */ + 'initial_connection_window_size': (_google_protobuf_UInt32Value__Output | null); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RetryPolicy.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RetryPolicy.ts index def6f7311..6e2af23e6 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RetryPolicy.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RetryPolicy.ts @@ -8,7 +8,7 @@ import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output a */ export interface RetryPolicy { /** - * Specifies parameters that control :ref:`retry backoff strategy `. + * Specifies parameters that control :ref:`retry backoff strategy `. * This parameter is optional, in which case the default base interval is 1000 milliseconds. The * default maximum interval is 10 times the base interval. */ @@ -25,7 +25,7 @@ export interface RetryPolicy { */ export interface RetryPolicy__Output { /** - * Specifies parameters that control :ref:`retry backoff strategy `. + * Specifies parameters that control :ref:`retry backoff strategy `. * This parameter is optional, in which case the default base interval is 1000 milliseconds. The * default maximum interval is 10 times the base interval. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeFractionalPercent.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeFractionalPercent.ts index 619bfd484..3a2073294 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeFractionalPercent.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/RuntimeFractionalPercent.ts @@ -9,7 +9,7 @@ import type { FractionalPercent as _envoy_type_v3_FractionalPercent, FractionalP * .. note:: * * Parsing of the runtime key's data is implemented such that it may be represented as a - * :ref:`FractionalPercent ` proto represented as JSON/YAML + * :ref:`FractionalPercent ` proto represented as JSON/YAML * and may also be represented as an integer with the assumption that the value is an integral * percentage out of 100. For instance, a runtime key lookup returning the value "42" would parse * as a `FractionalPercent` whose numerator is 42 and denominator is HUNDRED. @@ -32,7 +32,7 @@ export interface RuntimeFractionalPercent { * .. note:: * * Parsing of the runtime key's data is implemented such that it may be represented as a - * :ref:`FractionalPercent ` proto represented as JSON/YAML + * :ref:`FractionalPercent ` proto represented as JSON/YAML * and may also be represented as an integer with the assumption that the value is an integral * percentage out of 100. For instance, a runtime key lookup returning the value "42" would parse * as a `FractionalPercent` whose numerator is 42 and denominator is HUNDRED. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SchemeHeaderTransformation.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SchemeHeaderTransformation.ts new file mode 100644 index 000000000..95bb4e400 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/SchemeHeaderTransformation.ts @@ -0,0 +1,24 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/protocol.proto + + +/** + * A message to control transformations to the :scheme header + */ +export interface SchemeHeaderTransformation { + /** + * Overwrite any Scheme header with the contents of this string. + */ + 'scheme_to_overwrite'?: (string); + 'transformation'?: "scheme_to_overwrite"; +} + +/** + * A message to control transformations to the :scheme header + */ +export interface SchemeHeaderTransformation__Output { + /** + * Overwrite any Scheme header with the contents of this string. + */ + 'scheme_to_overwrite'?: (string); + 'transformation': "scheme_to_overwrite"; +} 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 e387adca2..3912fd1cf 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 @@ -5,7 +5,7 @@ import type { ApiVersion as _envoy_config_core_v3_ApiVersion } from '../../../.. /** * [#not-implemented-hide:] * Self-referencing config source options. This is currently empty, but when - * set in :ref:`ConfigSource ` can be used to + * set in :ref:`ConfigSource ` can be used to * specify that other data can be obtained from the same server. */ export interface SelfConfigSource { @@ -19,7 +19,7 @@ export interface SelfConfigSource { /** * [#not-implemented-hide:] * Self-referencing config source options. This is currently empty, but when - * set in :ref:`ConfigSource ` can be used to + * set in :ref:`ConfigSource ` can be used to * specify that other data can be obtained from the same server. */ export interface SelfConfigSource__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 e3f342d16..3966dc04c 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 @@ -18,19 +18,19 @@ export interface SocketAddress { * to the address. An empty address is not allowed. Specify ``0.0.0.0`` or ``::`` * to bind to any address. [#comment:TODO(zuercher) reinstate when implemented: * It is possible to distinguish a Listener address via the prefix/suffix matching - * in :ref:`FilterChainMatch `.] When used - * within an upstream :ref:`BindConfig `, the address + * in :ref:`FilterChainMatch `.] When used + * within an upstream :ref:`BindConfig `, the address * controls the source address of outbound connections. For :ref:`clusters - * `, the cluster type determines whether the + * `, the cluster type determines whether the * address must be an IP (*STATIC* or *EDS* clusters) or a hostname resolved by DNS * (*STRICT_DNS* or *LOGICAL_DNS* clusters). Address resolution can be customized - * via :ref:`resolver_name `. + * via :ref:`resolver_name `. */ 'address'?: (string); 'port_value'?: (number); /** * This is only valid if :ref:`resolver_name - * ` is specified below and the + * ` is specified below and the * named resolver is capable of named port resolution. */ 'named_port'?: (string); @@ -62,19 +62,19 @@ export interface SocketAddress__Output { * to the address. An empty address is not allowed. Specify ``0.0.0.0`` or ``::`` * to bind to any address. [#comment:TODO(zuercher) reinstate when implemented: * It is possible to distinguish a Listener address via the prefix/suffix matching - * in :ref:`FilterChainMatch `.] When used - * within an upstream :ref:`BindConfig `, the address + * in :ref:`FilterChainMatch `.] When used + * within an upstream :ref:`BindConfig `, the address * controls the source address of outbound connections. For :ref:`clusters - * `, the cluster type determines whether the + * `, the cluster type determines whether the * address must be an IP (*STATIC* or *EDS* clusters) or a hostname resolved by DNS * (*STRICT_DNS* or *LOGICAL_DNS* clusters). Address resolution can be customized - * via :ref:`resolver_name `. + * via :ref:`resolver_name `. */ 'address': (string); 'port_value'?: (number); /** * This is only valid if :ref:`resolver_name - * ` is specified below and the + * ` is specified below and the * named resolver is capable of named port resolution. */ 'named_port'?: (string); 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 ae3003189..a935fc1ec 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 @@ -95,6 +95,7 @@ export interface SubstitutionFormatString { /** * Specifies a collection of Formatter plugins that can be called from the access log configuration. * See the formatters extensions documentation for details. + * [#extension-category: envoy.formatter] */ 'formatters'?: (_envoy_config_core_v3_TypedExtensionConfig)[]; 'format'?: "text_format"|"json_format"|"text_format_source"; @@ -191,6 +192,7 @@ export interface SubstitutionFormatString__Output { /** * Specifies a collection of Formatter plugins that can be called from the access log configuration. * See the formatters extensions documentation for details. + * [#extension-category: envoy.formatter] */ 'formatters': (_envoy_config_core_v3_TypedExtensionConfig__Output)[]; 'format': "text_format"|"json_format"|"text_format_source"; diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TransportSocket.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TransportSocket.ts index 0031ad52f..ff05991ad 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TransportSocket.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/TransportSocket.ts @@ -4,7 +4,7 @@ import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__ /** * Configuration for transport socket in :ref:`listeners ` and - * :ref:`clusters `. If the configuration is + * :ref:`clusters `. If the configuration is * empty, a default transport socket implementation and configuration will be * chosen based on the platform and existence of tls_context. */ @@ -24,7 +24,7 @@ export interface TransportSocket { /** * Configuration for transport socket in :ref:`listeners ` and - * :ref:`clusters `. If the configuration is + * :ref:`clusters `. If the configuration is * empty, a default transport socket implementation and configuration will be * chosen based on the platform and existence of tls_context. */ 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 new file mode 100644 index 000000000..fe1b038db --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/UdpSocketConfig.ts @@ -0,0 +1,45 @@ +// Original file: deps/envoy-api/envoy/config/core/v3/udp_socket_config.proto + +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. + */ +export interface UdpSocketConfig { + /** + * The maximum size of received UDP datagrams. Using a larger size will cause Envoy to allocate + * more memory per socket. Received datagrams above this size will be dropped. If not set + * defaults to 1500 bytes. + */ + 'max_rx_datagram_size'?: (_google_protobuf_UInt64Value | null); + /** + * Configures whether Generic Receive Offload (GRO) + * _ is preferred when reading from the + * UDP socket. The default is context dependent and is documented where UdpSocketConfig is used. + * This option affects performance but not functionality. If GRO is not supported by the operating + * system, non-GRO receive will be used. + */ + 'prefer_gro'?: (_google_protobuf_BoolValue | null); +} + +/** + * Generic UDP socket configuration. + */ +export interface UdpSocketConfig__Output { + /** + * The maximum size of received UDP datagrams. Using a larger size will cause Envoy to allocate + * more memory per socket. Received datagrams above this size will be dropped. If not set + * defaults to 1500 bytes. + */ + 'max_rx_datagram_size': (_google_protobuf_UInt64Value__Output | null); + /** + * Configures whether Generic Receive Offload (GRO) + * _ is preferred when reading from the + * UDP socket. The default is context dependent and is documented where UdpSocketConfig is used. + * This option affects performance but not functionality. If GRO is not supported by the operating + * system, non-GRO receive will be used. + */ + 'prefer_gro': (_google_protobuf_BoolValue__Output | null); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/UpstreamHttpProtocolOptions.ts b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/UpstreamHttpProtocolOptions.ts index b765ec5a7..c0da4159f 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/core/v3/UpstreamHttpProtocolOptions.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/core/v3/UpstreamHttpProtocolOptions.ts @@ -4,31 +4,53 @@ export interface UpstreamHttpProtocolOptions { /** * Set transport socket `SNI `_ for new - * upstream connections based on the downstream HTTP host/authority header, as seen by the - * :ref:`router filter `. + * upstream connections based on the downstream HTTP host/authority header or any other arbitrary + * header when :ref:`override_auto_sni_header ` + * is set, as seen by the :ref:`router filter `. */ 'auto_sni'?: (boolean); /** * Automatic validate upstream presented certificate for new upstream connections based on the - * downstream HTTP host/authority header, as seen by the - * :ref:`router filter `. - * This field is intended to set with `auto_sni` field. + * downstream HTTP host/authority header or any other arbitrary header when :ref:`override_auto_sni_header ` + * is set, as seen by the :ref:`router filter `. + * This field is intended to be set with `auto_sni` field. */ 'auto_san_validation'?: (boolean); + /** + * An optional alternative to the host/authority header to be used for setting the SNI value. + * It should be a valid downstream HTTP header, as seen by the + * :ref:`router filter `. + * If unset, host/authority header will be used for populating the SNI. If the specified header + * is not found or the value is empty, host/authority header will be used instead. + * This field is intended to be set with `auto_sni` and/or `auto_san_validation` fields. + * If none of these fields are set then setting this would be a no-op. + */ + 'override_auto_sni_header'?: (string); } export interface UpstreamHttpProtocolOptions__Output { /** * Set transport socket `SNI `_ for new - * upstream connections based on the downstream HTTP host/authority header, as seen by the - * :ref:`router filter `. + * upstream connections based on the downstream HTTP host/authority header or any other arbitrary + * header when :ref:`override_auto_sni_header ` + * is set, as seen by the :ref:`router filter `. */ 'auto_sni': (boolean); /** * Automatic validate upstream presented certificate for new upstream connections based on the - * downstream HTTP host/authority header, as seen by the - * :ref:`router filter `. - * This field is intended to set with `auto_sni` field. + * downstream HTTP host/authority header or any other arbitrary header when :ref:`override_auto_sni_header ` + * is set, as seen by the :ref:`router filter `. + * This field is intended to be set with `auto_sni` field. */ 'auto_san_validation': (boolean); + /** + * An optional alternative to the host/authority header to be used for setting the SNI value. + * It should be a valid downstream HTTP header, as seen by the + * :ref:`router filter `. + * If unset, host/authority header will be used for populating the SNI. If the specified header + * is not found or the value is empty, host/authority header will be used instead. + * This field is intended to be set with `auto_sni` and/or `auto_san_validation` fields. + * If none of these fields are set then setting this would be a no-op. + */ + 'override_auto_sni_header': (string); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterLoadAssignment.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterLoadAssignment.ts index 03ceb570e..91ce2e0c8 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterLoadAssignment.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterLoadAssignment.ts @@ -157,9 +157,9 @@ export interface _envoy_config_endpoint_v3_ClusterLoadAssignment_Policy__Output export interface ClusterLoadAssignment { /** * Name of the cluster. This will be the :ref:`service_name - * ` value if specified + * ` value if specified * in the cluster :ref:`EdsClusterConfig - * `. + * `. */ 'cluster_name'?: (string); /** @@ -192,9 +192,9 @@ export interface ClusterLoadAssignment { export interface ClusterLoadAssignment__Output { /** * Name of the cluster. This will be the :ref:`service_name - * ` value if specified + * ` value if specified * in the cluster :ref:`EdsClusterConfig - * `. + * `. */ 'cluster_name': (string); /** diff --git a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterStats.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterStats.ts index db820b0b3..c160333b2 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterStats.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/ClusterStats.ts @@ -28,7 +28,7 @@ export interface _envoy_config_endpoint_v3_ClusterStats_DroppedRequests__Output /** * Per cluster load stats. Envoy reports these stats a management server in a - * :ref:`LoadStatsRequest` + * :ref:`LoadStatsRequest` * Next ID: 7 * [#next-free-field: 7] */ @@ -72,7 +72,7 @@ export interface ClusterStats { /** * Per cluster load stats. Envoy reports these stats a management server in a - * :ref:`LoadStatsRequest` + * :ref:`LoadStatsRequest` * Next ID: 7 * [#next-free-field: 7] */ diff --git a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/Endpoint.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/Endpoint.ts index c01987cce..31eb09055 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/Endpoint.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/Endpoint.ts @@ -17,8 +17,8 @@ export interface _envoy_config_endpoint_v3_Endpoint_HealthCheckConfig { 'port_value'?: (number); /** * By default, the host header for L7 health checks is controlled by cluster level configuration - * (see: :ref:`host ` and - * :ref:`authority `). Setting this + * (see: :ref:`host ` and + * :ref:`authority `). Setting this * to a non-empty value allows overriding the cluster level configuration for a specific * endpoint. */ @@ -40,8 +40,8 @@ export interface _envoy_config_endpoint_v3_Endpoint_HealthCheckConfig__Output { 'port_value': (number); /** * By default, the host header for L7 health checks is controlled by cluster level configuration - * (see: :ref:`host ` and - * :ref:`authority `). Setting this + * (see: :ref:`host ` and + * :ref:`authority `). Setting this * to a non-empty value allows overriding the cluster level configuration for a specific * endpoint. */ @@ -59,7 +59,7 @@ export interface Endpoint { * * The form of host address depends on the given cluster type. For STATIC or EDS, * it is expected to be a direct IP address (or something resolvable by the - * specified :ref:`resolver ` + * specified :ref:`resolver ` * in the Address). For LOGICAL or STRICT DNS, it is expected to be hostname, * and will be resolved via DNS. */ @@ -78,7 +78,7 @@ export interface Endpoint { * The hostname associated with this endpoint. This hostname is not used for routing or address * resolution. If provided, it will be associated with the endpoint, and can be used for features * that require a hostname, like - * :ref:`auto_host_rewrite `. + * :ref:`auto_host_rewrite `. */ 'hostname'?: (string); } @@ -94,7 +94,7 @@ export interface Endpoint__Output { * * The form of host address depends on the given cluster type. For STATIC or EDS, * it is expected to be a direct IP address (or something resolvable by the - * specified :ref:`resolver ` + * specified :ref:`resolver ` * in the Address). For LOGICAL or STRICT DNS, it is expected to be hostname, * and will be resolved via DNS. */ @@ -113,7 +113,7 @@ export interface Endpoint__Output { * The hostname associated with this endpoint. This hostname is not used for routing or address * resolution. If provided, it will be associated with the endpoint, and can be used for features * that require a hostname, like - * :ref:`auto_host_rewrite `. + * :ref:`auto_host_rewrite `. */ 'hostname': (string); } 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 3952a6928..6025ae3a7 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 @@ -21,7 +21,7 @@ export interface LbEndpoint { * name should be specified as *envoy.lb*. An example boolean key-value pair * is *canary*, providing the optional canary status of the upstream host. * This may be matched against in a route's - * :ref:`RouteAction ` metadata_match field + * :ref:`RouteAction ` metadata_match field * to subset the endpoints considered in cluster load balancing. */ 'metadata'?: (_envoy_config_core_v3_Metadata | null); @@ -63,7 +63,7 @@ export interface LbEndpoint__Output { * name should be specified as *envoy.lb*. An example boolean key-value pair * is *canary*, providing the optional canary status of the upstream host. * This may be matched against in a route's - * :ref:`RouteAction ` metadata_match field + * :ref:`RouteAction ` metadata_match field * to subset the endpoints considered in cluster load balancing. */ 'metadata': (_envoy_config_core_v3_Metadata__Output | null); diff --git a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LedsClusterLocalityConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LedsClusterLocalityConfig.ts new file mode 100644 index 000000000..1229d33a3 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LedsClusterLocalityConfig.ts @@ -0,0 +1,35 @@ +// Original file: deps/envoy-api/envoy/config/endpoint/v3/endpoint_components.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'; + +/** + * [#not-implemented-hide:] + * A configuration for a LEDS collection. + */ +export interface LedsClusterLocalityConfig { + /** + * Configuration for the source of LEDS updates for a Locality. + */ + 'leds_config'?: (_envoy_config_core_v3_ConfigSource | null); + /** + * The xDS transport protocol glob collection resource name. + * The service is only supported in delta xDS (incremental) mode. + */ + 'leds_collection_name'?: (string); +} + +/** + * [#not-implemented-hide:] + * A configuration for a LEDS collection. + */ +export interface LedsClusterLocalityConfig__Output { + /** + * Configuration for the source of LEDS updates for a Locality. + */ + 'leds_config': (_envoy_config_core_v3_ConfigSource__Output | null); + /** + * The xDS transport protocol glob collection resource name. + * The service is only supported in delta xDS (incremental) mode. + */ + 'leds_collection_name': (string); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LocalityLbEndpoints.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LocalityLbEndpoints.ts index 22f053ed0..182e27c9c 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LocalityLbEndpoints.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/LocalityLbEndpoints.ts @@ -3,13 +3,30 @@ import type { Locality as _envoy_config_core_v3_Locality, Locality__Output as _envoy_config_core_v3_Locality__Output } from '../../../../envoy/config/core/v3/Locality'; import type { LbEndpoint as _envoy_config_endpoint_v3_LbEndpoint, LbEndpoint__Output as _envoy_config_endpoint_v3_LbEndpoint__Output } from '../../../../envoy/config/endpoint/v3/LbEndpoint'; import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; +import type { LedsClusterLocalityConfig as _envoy_config_endpoint_v3_LedsClusterLocalityConfig, LedsClusterLocalityConfig__Output as _envoy_config_endpoint_v3_LedsClusterLocalityConfig__Output } from '../../../../envoy/config/endpoint/v3/LedsClusterLocalityConfig'; + +/** + * [#not-implemented-hide:] + * A list of endpoints of a specific locality. + */ +export interface _envoy_config_endpoint_v3_LocalityLbEndpoints_LbEndpointList { + 'lb_endpoints'?: (_envoy_config_endpoint_v3_LbEndpoint)[]; +} + +/** + * [#not-implemented-hide:] + * A list of endpoints of a specific locality. + */ +export interface _envoy_config_endpoint_v3_LocalityLbEndpoints_LbEndpointList__Output { + 'lb_endpoints': (_envoy_config_endpoint_v3_LbEndpoint__Output)[]; +} /** * A group of endpoints belonging to a Locality. * One can have multiple LocalityLbEndpoints for a locality, but this is * generally only done if the different groups need to have different load * balancing weights or different priorities. - * [#next-free-field: 7] + * [#next-free-field: 9] */ export interface LocalityLbEndpoints { /** @@ -18,6 +35,8 @@ export interface LocalityLbEndpoints { 'locality'?: (_envoy_config_core_v3_Locality | null); /** * The group of endpoints belonging to the locality specified. + * [#comment:TODO(adisuissa): Once LEDS is implemented this field needs to be + * deprecated and replaced by *load_balancer_endpoints*.] */ 'lb_endpoints'?: (_envoy_config_endpoint_v3_LbEndpoint)[]; /** @@ -55,6 +74,20 @@ export interface LocalityLbEndpoints { * [#not-implemented-hide:] */ 'proximity'?: (_google_protobuf_UInt32Value | null); + /** + * The group of endpoints belonging to the locality. + * [#comment:TODO(adisuissa): Once LEDS is implemented the *lb_endpoints* field + * needs to be deprecated.] + */ + 'load_balancer_endpoints'?: (_envoy_config_endpoint_v3_LocalityLbEndpoints_LbEndpointList | null); + /** + * LEDS Configuration for the current locality. + */ + 'leds_cluster_locality_config'?: (_envoy_config_endpoint_v3_LedsClusterLocalityConfig | null); + /** + * [#not-implemented-hide:] + */ + 'lb_config'?: "load_balancer_endpoints"|"leds_cluster_locality_config"; } /** @@ -62,7 +95,7 @@ export interface LocalityLbEndpoints { * One can have multiple LocalityLbEndpoints for a locality, but this is * generally only done if the different groups need to have different load * balancing weights or different priorities. - * [#next-free-field: 7] + * [#next-free-field: 9] */ export interface LocalityLbEndpoints__Output { /** @@ -71,6 +104,8 @@ export interface LocalityLbEndpoints__Output { 'locality': (_envoy_config_core_v3_Locality__Output | null); /** * The group of endpoints belonging to the locality specified. + * [#comment:TODO(adisuissa): Once LEDS is implemented this field needs to be + * deprecated and replaced by *load_balancer_endpoints*.] */ 'lb_endpoints': (_envoy_config_endpoint_v3_LbEndpoint__Output)[]; /** @@ -108,4 +143,18 @@ export interface LocalityLbEndpoints__Output { * [#not-implemented-hide:] */ 'proximity': (_google_protobuf_UInt32Value__Output | null); + /** + * The group of endpoints belonging to the locality. + * [#comment:TODO(adisuissa): Once LEDS is implemented the *lb_endpoints* field + * needs to be deprecated.] + */ + 'load_balancer_endpoints'?: (_envoy_config_endpoint_v3_LocalityLbEndpoints_LbEndpointList__Output | null); + /** + * LEDS Configuration for the current locality. + */ + 'leds_cluster_locality_config'?: (_envoy_config_endpoint_v3_LedsClusterLocalityConfig__Output | null); + /** + * [#not-implemented-hide:] + */ + 'lb_config': "load_balancer_endpoints"|"leds_cluster_locality_config"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/UpstreamLocalityStats.ts b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/UpstreamLocalityStats.ts index f00607d00..fbfb05ed6 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/UpstreamLocalityStats.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/endpoint/v3/UpstreamLocalityStats.ts @@ -7,7 +7,7 @@ import type { Long } from '@grpc/proto-loader'; /** * These are stats Envoy reports to the management server at a frequency defined by - * :ref:`LoadStatsResponse.load_reporting_interval`. + * :ref:`LoadStatsResponse.load_reporting_interval`. * Stats per upstream region/zone and optionally per subzone. * [#next-free-field: 9] */ @@ -43,7 +43,7 @@ export interface UpstreamLocalityStats { /** * Endpoint granularity stats information for this locality. This information * is populated if the Server requests it by setting - * :ref:`LoadStatsResponse.report_endpoint_granularity`. + * :ref:`LoadStatsResponse.report_endpoint_granularity`. */ 'upstream_endpoint_stats'?: (_envoy_config_endpoint_v3_UpstreamEndpointStats)[]; /** @@ -56,7 +56,7 @@ export interface UpstreamLocalityStats { /** * These are stats Envoy reports to the management server at a frequency defined by - * :ref:`LoadStatsResponse.load_reporting_interval`. + * :ref:`LoadStatsResponse.load_reporting_interval`. * Stats per upstream region/zone and optionally per subzone. * [#next-free-field: 9] */ @@ -92,7 +92,7 @@ export interface UpstreamLocalityStats__Output { /** * Endpoint granularity stats information for this locality. This information * is populated if the Server requests it by setting - * :ref:`LoadStatsResponse.report_endpoint_granularity`. + * :ref:`LoadStatsResponse.report_endpoint_granularity`. */ 'upstream_endpoint_stats': (_envoy_config_endpoint_v3_UpstreamEndpointStats__Output)[]; /** diff --git a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ApiListener.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ApiListener.ts index 4977911fb..5a8e7f37f 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ApiListener.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ApiListener.ts @@ -10,7 +10,8 @@ export interface ApiListener { /** * The type in this field determines the type of API listener. At present, the following * types are supported: - * envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager (HTTP) + * envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager (HTTP) + * envoy.extensions.filters.network.http_connection_manager.v3.EnvoyMobileHttpConnectionManager (HTTP) * [#next-major-version: In the v3 API, replace this Any field with a oneof containing the * specific config message for each type of API listener. We could not do this in v2 because * it would have caused circular dependencies for go protos: lds.proto depends on this file, @@ -28,7 +29,8 @@ export interface ApiListener__Output { /** * The type in this field determines the type of API listener. At present, the following * types are supported: - * envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager (HTTP) + * envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager (HTTP) + * envoy.extensions.filters.network.http_connection_manager.v3.EnvoyMobileHttpConnectionManager (HTTP) * [#next-major-version: In the v3 API, replace this Any field with a oneof containing the * specific config message for each type of API listener. We could not do this in v2 because * it would have caused circular dependencies for go protos: lds.proto depends on this file, diff --git a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/Filter.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/Filter.ts index 3e38fbc00..66e903b28 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/Filter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/Filter.ts @@ -15,6 +15,7 @@ export interface Filter { /** * Filter specific configuration which depends on the filter being * instantiated. See the supported filters for further documentation. + * [#extension-category: envoy.filters.network] */ 'typed_config'?: (_google_protobuf_Any | null); /** @@ -39,6 +40,7 @@ export interface Filter__Output { /** * Filter specific configuration which depends on the filter being * instantiated. See the supported filters for further documentation. + * [#extension-category: envoy.filters.network] */ 'typed_config'?: (_google_protobuf_Any__Output | null); /** 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 d72fa824c..e65f433c4 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 @@ -81,10 +81,11 @@ export interface FilterChain { 'metadata'?: (_envoy_config_core_v3_Metadata | null); /** * Optional custom transport socket implementation to use for downstream connections. - * To setup TLS, set a transport socket with name `tls` and - * :ref:`DownstreamTlsContext ` in the `typed_config`. + * To setup TLS, set a transport socket with name `envoy.transport_sockets.tls` and + * :ref:`DownstreamTlsContext ` in the `typed_config`. * If no transport socket configuration is specified, new connections * will be set up with plaintext. + * [#extension-category: envoy.transport_sockets.downstream] */ 'transport_socket'?: (_envoy_config_core_v3_TransportSocket | null); /** @@ -143,10 +144,11 @@ export interface FilterChain__Output { 'metadata': (_envoy_config_core_v3_Metadata__Output | null); /** * Optional custom transport socket implementation to use for downstream connections. - * To setup TLS, set a transport socket with name `tls` and - * :ref:`DownstreamTlsContext ` in the `typed_config`. + * To setup TLS, set a transport socket with name `envoy.transport_sockets.tls` and + * :ref:`DownstreamTlsContext ` in the `typed_config`. * If no transport socket configuration is specified, new connections * will be set up with plaintext. + * [#extension-category: envoy.transport_sockets.downstream] */ 'transport_socket': (_envoy_config_core_v3_TransportSocket__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 042df6dea..259888217 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 @@ -35,9 +35,12 @@ export enum _envoy_config_listener_v3_FilterChainMatch_ConnectionSourceType { * 3. Server name (e.g. SNI for TLS protocol), * 4. Transport protocol. * 5. Application protocols (e.g. ALPN for TLS protocol). - * 6. Source type (e.g. any, local or external network). - * 7. Source IP address. - * 8. Source port. + * 6. Directly connected source IP address (this will only be different from the source IP address + * when using a listener filter that overrides the source address, such as the :ref:`Proxy Protocol + * listener filter `). + * 7. Source type (e.g. any, local or external network). + * 8. Source IP address. + * 9. Source port. * * For criteria that allow ranges or wildcards, the most specific value in any * of the configured filter chains that matches the incoming connection is going @@ -61,7 +64,7 @@ export enum _envoy_config_listener_v3_FilterChainMatch_ConnectionSourceType { * listed at the end, because that's how we want to list them in the docs. * * [#comment:TODO(PiotrSikora): Add support for configurable precedence of the rules] - * [#next-free-field: 13] + * [#next-free-field: 14] */ export interface FilterChainMatch { /** @@ -151,6 +154,12 @@ 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); + /** + * 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 + * specified or the list is empty, the directly connected source IP address is ignored. + */ + 'direct_source_prefix_ranges'?: (_envoy_config_core_v3_CidrRange)[]; } /** @@ -168,9 +177,12 @@ export interface FilterChainMatch { * 3. Server name (e.g. SNI for TLS protocol), * 4. Transport protocol. * 5. Application protocols (e.g. ALPN for TLS protocol). - * 6. Source type (e.g. any, local or external network). - * 7. Source IP address. - * 8. Source port. + * 6. Directly connected source IP address (this will only be different from the source IP address + * when using a listener filter that overrides the source address, such as the :ref:`Proxy Protocol + * listener filter `). + * 7. Source type (e.g. any, local or external network). + * 8. Source IP address. + * 9. Source port. * * For criteria that allow ranges or wildcards, the most specific value in any * of the configured filter chains that matches the incoming connection is going @@ -194,7 +206,7 @@ export interface FilterChainMatch { * listed at the end, because that's how we want to list them in the docs. * * [#comment:TODO(PiotrSikora): Add support for configurable precedence of the rules] - * [#next-free-field: 13] + * [#next-free-field: 14] */ export interface FilterChainMatch__Output { /** @@ -284,4 +296,10 @@ 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); + /** + * 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 + * specified or the list is empty, the directly connected source IP address is ignored. + */ + 'direct_source_prefix_ranges': (_envoy_config_core_v3_CidrRange__Output)[]; } 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 8e0fc55f6..3df1006b7 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 @@ -12,7 +12,6 @@ import type { TrafficDirection as _envoy_config_core_v3_TrafficDirection } from 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'; -import type { TypedExtensionConfig as _envoy_config_core_v3_TypedExtensionConfig, TypedExtensionConfig__Output as _envoy_config_core_v3_TypedExtensionConfig__Output } from '../../../../envoy/config/core/v3/TypedExtensionConfig'; /** * Configuration for listener connection balancing. @@ -46,7 +45,7 @@ export interface _envoy_config_listener_v3_Listener_DeprecatedV1 { * set use_original_dst parameter to true. Default is true. * * This is deprecated. Use :ref:`Listener.bind_to_port - * ` + * ` */ 'bind_to_port'?: (_google_protobuf_BoolValue | null); } @@ -61,7 +60,7 @@ export interface _envoy_config_listener_v3_Listener_DeprecatedV1__Output { * set use_original_dst parameter to true. Default is true. * * This is deprecated. Use :ref:`Listener.bind_to_port - * ` + * ` */ 'bind_to_port': (_google_protobuf_BoolValue__Output | null); } @@ -105,7 +104,21 @@ export interface _envoy_config_listener_v3_Listener_ConnectionBalanceConfig_Exac } /** - * [#next-free-field: 27] + * Configuration for envoy internal listener. All the future internal listener features should be added here. + * [#not-implemented-hide:] + */ +export interface _envoy_config_listener_v3_Listener_InternalListenerConfig { +} + +/** + * Configuration for envoy internal listener. All the future internal listener features should be added here. + * [#not-implemented-hide:] + */ +export interface _envoy_config_listener_v3_Listener_InternalListenerConfig__Output { +} + +/** + * [#next-free-field: 30] */ export interface Listener { /** @@ -122,8 +135,8 @@ export interface Listener { 'address'?: (_envoy_config_core_v3_Address | null); /** * A list of filter chains to consider for this listener. The - * :ref:`FilterChain ` with the most specific - * :ref:`FilterChainMatch ` criteria is used on a + * :ref:`FilterChain ` with the most specific + * :ref:`FilterChainMatch ` criteria is used on a * connection. * * Example using SNI for filter chain selection can be found in the @@ -158,12 +171,12 @@ export interface Listener { /** * 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 - * :ref:`filter_chains `. Order matters as the + * :ref:`filter_chains `. Order matters as the * filters are processed sequentially right after a socket has been accepted by the listener, and * before a connection is created. * UDP Listener filters can be specified when the protocol in the listener socket address in - * :ref:`protocol ` is :ref:`UDP - * `. + * :ref:`protocol ` is :ref:`UDP + * `. * UDP listeners currently support a single filter. */ 'listener_filters'?: (_envoy_config_listener_v3_ListenerFilter)[]; @@ -173,7 +186,7 @@ export interface Listener { * *iptables* *TPROXY* target, in which case the original source and destination addresses and * ports are preserved on accepted connections. This flag should be used in combination with * :ref:`an original_dst ` :ref:`listener filter - * ` to mark the connections' local addresses as + * ` to mark the connections' local addresses as * "restored." This can be used to hand off each redirected connection to another listener * associated with the connection's destination address. Direct connections to the socket without * using *TPROXY* cannot be distinguished from connections redirected using *TPROXY* and are @@ -224,6 +237,8 @@ export interface Listener { 'listener_filters_timeout'?: (_google_protobuf_Duration | null); /** * Specifies the intended direction of the traffic relative to the local Envoy. + * 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); /** @@ -238,17 +253,15 @@ export interface Listener { 'continue_on_listener_filters_timeout'?: (boolean); /** * If the protocol in the listener socket address in :ref:`protocol - * ` is :ref:`UDP - * `, this field specifies the actual udp - * listener to create, i.e. :ref:`udp_listener_name - * ` = "raw_udp_listener" for - * creating a packet-oriented UDP listener. If not present, treat it as "raw_udp_listener". + * ` is :ref:`UDP + * `, this field specifies UDP + * listener specific configuration. */ 'udp_listener_config'?: (_envoy_config_listener_v3_UdpListenerConfig | null); /** * Used to represent an API listener, which is used in non-proxy clients. The type of API * exposed to the non-proxy application depends on the type of API listener. - * When this field is set, no other field except for :ref:`name` + * When this field is set, no other field except for :ref:`name` * should be set. * * .. note:: @@ -268,19 +281,16 @@ export interface Listener { * The listener's connection balancer configuration, currently only applicable to TCP listeners. * If no configuration is specified, Envoy will not attempt to balance active connections between * worker threads. + * + * In the scenario that the listener X redirects all the connections to the listeners Y1 and Y2 + * by setting :ref:`use_original_dst ` in X + * and :ref:`bind_to_port ` to false in Y1 and Y2, + * it is recommended to disable the balance config in listener X to avoid the cost of balancing, and + * enable the balance config in Y1 and Y2 to balance the connections among the workers. */ 'connection_balance_config'?: (_envoy_config_listener_v3_Listener_ConnectionBalanceConfig | null); /** - * When this flag is set to true, listeners set the *SO_REUSEPORT* socket option and - * create one socket for each worker thread. This makes inbound connections - * distribute among worker threads roughly evenly in cases where there are a high number - * of connections. When this flag is set to false, all worker threads share one socket. - * - * Before Linux v4.19-rc1, new TCP connections may be rejected during hot restart - * (see `3rd paragraph in 'soreuseport' commit message - * `_). - * This issue was fixed by `tcp: Avoid TCP syncookie rejected by SO_REUSEPORT socket - * `_. + * Deprecated. Use `enable_reuse_port` instead. */ 'reuse_port'?: (boolean); /** @@ -288,17 +298,6 @@ export interface Listener { * emitted by this listener. */ 'access_log'?: (_envoy_config_accesslog_v3_AccessLog)[]; - /** - * If the protocol in the listener socket address in :ref:`protocol - * ` is :ref:`UDP - * `, this field specifies the actual udp - * writer to create, i.e. :ref:`name ` - * = "udp_default_writer" for creating a udp writer with writing in passthrough mode, - * = "udp_gso_batch_writer" for creating a udp writer with writing in batch mode. - * If not present, treat it as "udp_default_writer". - * [#not-implemented-hide:] - */ - 'udp_writer_config'?: (_envoy_config_core_v3_TypedExtensionConfig | null); /** * The maximum length a tcp listener's pending connections queue can grow to. If no value is * provided net.core.somaxconn will be used on Linux and 128 otherwise. @@ -312,14 +311,67 @@ export interface Listener { /** * Whether the listener should bind to the port. A listener that doesn't * bind can only receive connections redirected from other listeners that set - * :ref:`use_original_dst ` + * :ref:`use_original_dst ` * to true. Default is true. */ 'bind_to_port'?: (_google_protobuf_BoolValue | null); + /** + * Used to represent an internal listener which does not listen on OSI L4 address but can be used by the + * :ref:`envoy cluster ` to create a user space connection to. + * The internal listener acts as a tcp listener. It supports listener filters and network filter chains. + * The internal listener require :ref:`address ` has + * field `envoy_internal_address`. + * + * There are some limitations are derived from the implementation. The known limitations include + * + * * :ref:`ConnectionBalanceConfig ` is not + * allowed because both cluster connection and listener connection must be owned by the same dispatcher. + * * :ref:`tcp_backlog_size ` + * * :ref:`freebind ` + * * :ref:`transparent ` + * [#not-implemented-hide:] + */ + 'internal_listener'?: (_envoy_config_listener_v3_Listener_InternalListenerConfig | null); + /** + * Optional prefix to use on listener stats. If empty, the stats will be rooted at + * `listener.
.`. If non-empty, stats will be rooted at + * `listener..`. + */ + 'stat_prefix'?: (string); + /** + * When this flag is set to true, listeners set the *SO_REUSEPORT* socket option and + * create one socket for each worker thread. This makes inbound connections + * distribute among worker threads roughly evenly in cases where there are a high number + * of connections. When this flag is set to false, all worker threads share one socket. This field + * defaults to true. + * + * .. attention:: + * + * Although this field defaults to true, it has different behavior on different platforms. See + * the following text for more information. + * + * * On Linux, reuse_port is respected for both TCP and UDP listeners. It also works correctly + * with hot restart. + * * On macOS, reuse_port for TCP does not do what it does on Linux. Instead of load balancing, + * the last socket wins and receives all connections/packets. For TCP, reuse_port is force + * disabled and the user is warned. For UDP, it is enabled, but only one worker will receive + * packets. For QUIC/H3, SW routing will send packets to other workers. For "raw" UDP, only + * a single worker will currently receive packets. + * * On Windows, reuse_port for TCP has undefined behavior. It is force disabled and the user + * is warned similar to macOS. It is left enabled for UDP with undefined behavior currently. + */ + 'enable_reuse_port'?: (_google_protobuf_BoolValue | null); + /** + * The exclusive listener type and the corresponding config. + * TODO(lambdai): https://github.com/envoyproxy/envoy/issues/15372 + * Will create and add TcpListenerConfig. Will add UdpListenerConfig and ApiListener. + * [#not-implemented-hide:] + */ + 'listener_specifier'?: "internal_listener"; } /** - * [#next-free-field: 27] + * [#next-free-field: 30] */ export interface Listener__Output { /** @@ -336,8 +388,8 @@ export interface Listener__Output { 'address': (_envoy_config_core_v3_Address__Output | null); /** * A list of filter chains to consider for this listener. The - * :ref:`FilterChain ` with the most specific - * :ref:`FilterChainMatch ` criteria is used on a + * :ref:`FilterChain ` with the most specific + * :ref:`FilterChainMatch ` criteria is used on a * connection. * * Example using SNI for filter chain selection can be found in the @@ -372,12 +424,12 @@ export interface Listener__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 - * :ref:`filter_chains `. Order matters as the + * :ref:`filter_chains `. Order matters as the * filters are processed sequentially right after a socket has been accepted by the listener, and * before a connection is created. * UDP Listener filters can be specified when the protocol in the listener socket address in - * :ref:`protocol ` is :ref:`UDP - * `. + * :ref:`protocol ` is :ref:`UDP + * `. * UDP listeners currently support a single filter. */ 'listener_filters': (_envoy_config_listener_v3_ListenerFilter__Output)[]; @@ -387,7 +439,7 @@ export interface Listener__Output { * *iptables* *TPROXY* target, in which case the original source and destination addresses and * ports are preserved on accepted connections. This flag should be used in combination with * :ref:`an original_dst ` :ref:`listener filter - * ` to mark the connections' local addresses as + * ` to mark the connections' local addresses as * "restored." This can be used to hand off each redirected connection to another listener * associated with the connection's destination address. Direct connections to the socket without * using *TPROXY* cannot be distinguished from connections redirected using *TPROXY* and are @@ -438,6 +490,8 @@ export interface Listener__Output { 'listener_filters_timeout': (_google_protobuf_Duration__Output | null); /** * Specifies the intended direction of the traffic relative to the local Envoy. + * 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); /** @@ -452,17 +506,15 @@ export interface Listener__Output { 'continue_on_listener_filters_timeout': (boolean); /** * If the protocol in the listener socket address in :ref:`protocol - * ` is :ref:`UDP - * `, this field specifies the actual udp - * listener to create, i.e. :ref:`udp_listener_name - * ` = "raw_udp_listener" for - * creating a packet-oriented UDP listener. If not present, treat it as "raw_udp_listener". + * ` is :ref:`UDP + * `, this field specifies UDP + * listener specific configuration. */ 'udp_listener_config': (_envoy_config_listener_v3_UdpListenerConfig__Output | null); /** * Used to represent an API listener, which is used in non-proxy clients. The type of API * exposed to the non-proxy application depends on the type of API listener. - * When this field is set, no other field except for :ref:`name` + * When this field is set, no other field except for :ref:`name` * should be set. * * .. note:: @@ -482,19 +534,16 @@ export interface Listener__Output { * The listener's connection balancer configuration, currently only applicable to TCP listeners. * If no configuration is specified, Envoy will not attempt to balance active connections between * worker threads. + * + * In the scenario that the listener X redirects all the connections to the listeners Y1 and Y2 + * by setting :ref:`use_original_dst ` in X + * and :ref:`bind_to_port ` to false in Y1 and Y2, + * it is recommended to disable the balance config in listener X to avoid the cost of balancing, and + * enable the balance config in Y1 and Y2 to balance the connections among the workers. */ 'connection_balance_config': (_envoy_config_listener_v3_Listener_ConnectionBalanceConfig__Output | null); /** - * When this flag is set to true, listeners set the *SO_REUSEPORT* socket option and - * create one socket for each worker thread. This makes inbound connections - * distribute among worker threads roughly evenly in cases where there are a high number - * of connections. When this flag is set to false, all worker threads share one socket. - * - * Before Linux v4.19-rc1, new TCP connections may be rejected during hot restart - * (see `3rd paragraph in 'soreuseport' commit message - * `_). - * This issue was fixed by `tcp: Avoid TCP syncookie rejected by SO_REUSEPORT socket - * `_. + * Deprecated. Use `enable_reuse_port` instead. */ 'reuse_port': (boolean); /** @@ -502,17 +551,6 @@ export interface Listener__Output { * emitted by this listener. */ 'access_log': (_envoy_config_accesslog_v3_AccessLog__Output)[]; - /** - * If the protocol in the listener socket address in :ref:`protocol - * ` is :ref:`UDP - * `, this field specifies the actual udp - * writer to create, i.e. :ref:`name ` - * = "udp_default_writer" for creating a udp writer with writing in passthrough mode, - * = "udp_gso_batch_writer" for creating a udp writer with writing in batch mode. - * If not present, treat it as "udp_default_writer". - * [#not-implemented-hide:] - */ - 'udp_writer_config': (_envoy_config_core_v3_TypedExtensionConfig__Output | null); /** * The maximum length a tcp listener's pending connections queue can grow to. If no value is * provided net.core.somaxconn will be used on Linux and 128 otherwise. @@ -526,8 +564,61 @@ export interface Listener__Output { /** * Whether the listener should bind to the port. A listener that doesn't * bind can only receive connections redirected from other listeners that set - * :ref:`use_original_dst ` + * :ref:`use_original_dst ` * to true. Default is true. */ 'bind_to_port': (_google_protobuf_BoolValue__Output | null); + /** + * Used to represent an internal listener which does not listen on OSI L4 address but can be used by the + * :ref:`envoy cluster ` to create a user space connection to. + * The internal listener acts as a tcp listener. It supports listener filters and network filter chains. + * The internal listener require :ref:`address ` has + * field `envoy_internal_address`. + * + * There are some limitations are derived from the implementation. The known limitations include + * + * * :ref:`ConnectionBalanceConfig ` is not + * allowed because both cluster connection and listener connection must be owned by the same dispatcher. + * * :ref:`tcp_backlog_size ` + * * :ref:`freebind ` + * * :ref:`transparent ` + * [#not-implemented-hide:] + */ + 'internal_listener'?: (_envoy_config_listener_v3_Listener_InternalListenerConfig__Output | null); + /** + * Optional prefix to use on listener stats. If empty, the stats will be rooted at + * `listener.
.`. If non-empty, stats will be rooted at + * `listener..`. + */ + 'stat_prefix': (string); + /** + * When this flag is set to true, listeners set the *SO_REUSEPORT* socket option and + * create one socket for each worker thread. This makes inbound connections + * distribute among worker threads roughly evenly in cases where there are a high number + * of connections. When this flag is set to false, all worker threads share one socket. This field + * defaults to true. + * + * .. attention:: + * + * Although this field defaults to true, it has different behavior on different platforms. See + * the following text for more information. + * + * * On Linux, reuse_port is respected for both TCP and UDP listeners. It also works correctly + * with hot restart. + * * On macOS, reuse_port for TCP does not do what it does on Linux. Instead of load balancing, + * the last socket wins and receives all connections/packets. For TCP, reuse_port is force + * disabled and the user is warned. For UDP, it is enabled, but only one worker will receive + * packets. For QUIC/H3, SW routing will send packets to other workers. For "raw" UDP, only + * a single worker will currently receive packets. + * * On Windows, reuse_port for TCP has undefined behavior. It is force disabled and the user + * is warned similar to macOS. It is left enabled for UDP with undefined behavior currently. + */ + 'enable_reuse_port': (_google_protobuf_BoolValue__Output | null); + /** + * The exclusive listener type and the corresponding config. + * TODO(lambdai): https://github.com/envoyproxy/envoy/issues/15372 + * Will create and add TcpListenerConfig. Will add UdpListenerConfig and ApiListener. + * [#not-implemented-hide:] + */ + 'listener_specifier': "internal_listener"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilter.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilter.ts index beba60dce..be7242849 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilter.ts @@ -9,17 +9,18 @@ export interface ListenerFilter { * :ref:`supported filter `. */ 'name'?: (string); + /** + * Filter specific configuration which depends on the filter being + * instantiated. See the supported filters for further documentation. + * [#extension-category: envoy.filters.listener,envoy.filters.udp_listener] + */ 'typed_config'?: (_google_protobuf_Any | null); /** * Optional match predicate used to disable the filter. The filter is enabled when this field is empty. - * See :ref:`ListenerFilterChainMatchPredicate ` + * See :ref:`ListenerFilterChainMatchPredicate ` * for further examples. */ 'filter_disabled'?: (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate | null); - /** - * Filter specific configuration which depends on the filter being instantiated. - * See the supported filters for further documentation. - */ 'config_type'?: "typed_config"; } @@ -29,16 +30,17 @@ export interface ListenerFilter__Output { * :ref:`supported filter `. */ 'name': (string); + /** + * Filter specific configuration which depends on the filter being + * instantiated. See the supported filters for further documentation. + * [#extension-category: envoy.filters.listener,envoy.filters.udp_listener] + */ 'typed_config'?: (_google_protobuf_Any__Output | null); /** * Optional match predicate used to disable the filter. The filter is enabled when this field is empty. - * See :ref:`ListenerFilterChainMatchPredicate ` + * See :ref:`ListenerFilterChainMatchPredicate ` * for further examples. */ 'filter_disabled': (_envoy_config_listener_v3_ListenerFilterChainMatchPredicate__Output | null); - /** - * Filter specific configuration which depends on the filter being instantiated. - * See the supported filters for further documentation. - */ 'config_type': "typed_config"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilterChainMatchPredicate.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilterChainMatchPredicate.ts index 34f937fa1..bb743a29d 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilterChainMatchPredicate.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/ListenerFilterChainMatchPredicate.ts @@ -45,7 +45,7 @@ export interface _envoy_config_listener_v3_ListenerFilterChainMatchPredicate_Mat * rules: * - destination_port_range: * start: 3306 - * end: 3306 + * end: 3307 * - destination_port_range: * start: 15000 * end: 15001 @@ -101,7 +101,7 @@ export interface ListenerFilterChainMatchPredicate { * rules: * - destination_port_range: * start: 3306 - * end: 3306 + * end: 3307 * - destination_port_range: * start: 15000 * end: 15001 diff --git a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/QuicProtocolOptions.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/QuicProtocolOptions.ts new file mode 100644 index 000000000..5e01a772f --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/QuicProtocolOptions.ts @@ -0,0 +1,97 @@ +// Original file: deps/envoy-api/envoy/config/listener/v3/quic_config.proto + +import type { QuicProtocolOptions as _envoy_config_core_v3_QuicProtocolOptions, QuicProtocolOptions__Output as _envoy_config_core_v3_QuicProtocolOptions__Output } from '../../../../envoy/config/core/v3/QuicProtocolOptions'; +import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; +import type { RuntimeFeatureFlag as _envoy_config_core_v3_RuntimeFeatureFlag, RuntimeFeatureFlag__Output as _envoy_config_core_v3_RuntimeFeatureFlag__Output } from '../../../../envoy/config/core/v3/RuntimeFeatureFlag'; +import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; +import type { TypedExtensionConfig as _envoy_config_core_v3_TypedExtensionConfig, TypedExtensionConfig__Output as _envoy_config_core_v3_TypedExtensionConfig__Output } from '../../../../envoy/config/core/v3/TypedExtensionConfig'; + +/** + * Configuration specific to the UDP QUIC listener. + * [#next-free-field: 8] + */ +export interface QuicProtocolOptions { + 'quic_protocol_options'?: (_envoy_config_core_v3_QuicProtocolOptions | null); + /** + * Maximum number of milliseconds that connection will be alive when there is + * no network activity. 300000ms if not specified. + */ + 'idle_timeout'?: (_google_protobuf_Duration | null); + /** + * Connection timeout in milliseconds before the crypto handshake is finished. + * 20000ms if not specified. + */ + 'crypto_handshake_timeout'?: (_google_protobuf_Duration | null); + /** + * Runtime flag that controls whether the listener is enabled or not. If not specified, defaults + * to enabled. + */ + 'enabled'?: (_envoy_config_core_v3_RuntimeFeatureFlag | null); + /** + * A multiplier to number of connections which is used to determine how many packets to read per + * event loop. A reasonable number should allow the listener to process enough payload but not + * starve TCP and other UDP sockets and also prevent long event loop duration. + * The default value is 32. This means if there are N QUIC connections, the total number of + * packets to read in each read event will be 32 * N. + * The actual number of packets to read in total by the UDP listener is also + * bound by 6000, regardless of this field or how many connections there are. + */ + 'packets_to_read_to_connection_count_ratio'?: (_google_protobuf_UInt32Value | null); + /** + * Configure which implementation of `quic::QuicCryptoClientStreamBase` to be used for this listener. + * If not specified the :ref:`QUICHE default one configured by ` will be used. + * [#extension-category: envoy.quic.server.crypto_stream] + */ + 'crypto_stream_config'?: (_envoy_config_core_v3_TypedExtensionConfig | null); + /** + * Configure which implementation of `quic::ProofSource` to be used for this listener. + * If not specified the :ref:`default one configured by ` will be used. + * [#extension-category: envoy.quic.proof_source] + */ + 'proof_source_config'?: (_envoy_config_core_v3_TypedExtensionConfig | null); +} + +/** + * Configuration specific to the UDP QUIC listener. + * [#next-free-field: 8] + */ +export interface QuicProtocolOptions__Output { + 'quic_protocol_options': (_envoy_config_core_v3_QuicProtocolOptions__Output | null); + /** + * Maximum number of milliseconds that connection will be alive when there is + * no network activity. 300000ms if not specified. + */ + 'idle_timeout': (_google_protobuf_Duration__Output | null); + /** + * Connection timeout in milliseconds before the crypto handshake is finished. + * 20000ms if not specified. + */ + 'crypto_handshake_timeout': (_google_protobuf_Duration__Output | null); + /** + * Runtime flag that controls whether the listener is enabled or not. If not specified, defaults + * to enabled. + */ + 'enabled': (_envoy_config_core_v3_RuntimeFeatureFlag__Output | null); + /** + * A multiplier to number of connections which is used to determine how many packets to read per + * event loop. A reasonable number should allow the listener to process enough payload but not + * starve TCP and other UDP sockets and also prevent long event loop duration. + * The default value is 32. This means if there are N QUIC connections, the total number of + * packets to read in each read event will be 32 * N. + * The actual number of packets to read in total by the UDP listener is also + * bound by 6000, regardless of this field or how many connections there are. + */ + 'packets_to_read_to_connection_count_ratio': (_google_protobuf_UInt32Value__Output | null); + /** + * Configure which implementation of `quic::QuicCryptoClientStreamBase` to be used for this listener. + * If not specified the :ref:`QUICHE default one configured by ` will be used. + * [#extension-category: envoy.quic.server.crypto_stream] + */ + 'crypto_stream_config': (_envoy_config_core_v3_TypedExtensionConfig__Output | null); + /** + * Configure which implementation of `quic::ProofSource` to be used for this listener. + * If not specified the :ref:`default one configured by ` will be used. + * [#extension-category: envoy.quic.proof_source] + */ + 'proof_source_config': (_envoy_config_core_v3_TypedExtensionConfig__Output | null); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/UdpListenerConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/UdpListenerConfig.ts index 2ac4463fb..f4c220e20 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/UdpListenerConfig.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/listener/v3/UdpListenerConfig.ts @@ -1,33 +1,48 @@ // Original file: deps/envoy-api/envoy/config/listener/v3/udp_listener_config.proto -import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; +import type { UdpSocketConfig as _envoy_config_core_v3_UdpSocketConfig, UdpSocketConfig__Output as _envoy_config_core_v3_UdpSocketConfig__Output } from '../../../../envoy/config/core/v3/UdpSocketConfig'; +import type { QuicProtocolOptions as _envoy_config_listener_v3_QuicProtocolOptions, QuicProtocolOptions__Output as _envoy_config_listener_v3_QuicProtocolOptions__Output } from '../../../../envoy/config/listener/v3/QuicProtocolOptions'; +/** + * [#next-free-field: 8] + */ export interface UdpListenerConfig { /** - * Used to look up UDP listener factory, matches "raw_udp_listener" or - * "quic_listener" to create a specific udp listener. - * If not specified, treat as "raw_udp_listener". + * UDP socket configuration for the listener. The default for + * :ref:`prefer_gro ` is false for + * listener sockets. If receiving a large amount of datagrams from a small number of sources, it + * may be worthwhile to enable this option after performance testing. */ - 'udp_listener_name'?: (string); - 'typed_config'?: (_google_protobuf_Any | null); + 'downstream_socket_config'?: (_envoy_config_core_v3_UdpSocketConfig | null); /** - * Used to create a specific listener factory. To some factory, e.g. - * "raw_udp_listener", config is not needed. + * Configuration for QUIC protocol. If empty, QUIC will not be enabled on this listener. Set + * to the default object to enable QUIC without modifying any additional options. + * + * .. warning:: + * QUIC support is currently alpha and should be used with caution. Please + * see :ref:`here ` for details. */ - 'config_type'?: "typed_config"; + 'quic_options'?: (_envoy_config_listener_v3_QuicProtocolOptions | null); } +/** + * [#next-free-field: 8] + */ export interface UdpListenerConfig__Output { /** - * Used to look up UDP listener factory, matches "raw_udp_listener" or - * "quic_listener" to create a specific udp listener. - * If not specified, treat as "raw_udp_listener". + * UDP socket configuration for the listener. The default for + * :ref:`prefer_gro ` is false for + * listener sockets. If receiving a large amount of datagrams from a small number of sources, it + * may be worthwhile to enable this option after performance testing. */ - 'udp_listener_name': (string); - 'typed_config'?: (_google_protobuf_Any__Output | null); + 'downstream_socket_config': (_envoy_config_core_v3_UdpSocketConfig__Output | null); /** - * Used to create a specific listener factory. To some factory, e.g. - * "raw_udp_listener", config is not needed. + * Configuration for QUIC protocol. If empty, QUIC will not be enabled on this listener. Set + * to the default object to enable QUIC without modifying any additional options. + * + * .. warning:: + * QUIC support is currently alpha and should be used with caution. Please + * see :ref:`here ` for details. */ - 'config_type': "typed_config"; + 'quic_options': (_envoy_config_listener_v3_QuicProtocolOptions__Output | null); } 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 new file mode 100644 index 000000000..4cf705f10 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/DogStatsdSink.ts @@ -0,0 +1,65 @@ +// 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 new file mode 100644 index 000000000..036958a49 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/HistogramBucketSettings.ts @@ -0,0 +1,35 @@ +// 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 new file mode 100644 index 000000000..b8fb2ed8e --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/HystrixSink.ts @@ -0,0 +1,61 @@ +// 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 new file mode 100644 index 000000000..df5d7c7e4 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsConfig.ts @@ -0,0 +1,148 @@ +// 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 new file mode 100644 index 000000000..9df9e9529 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsMatcher.ts @@ -0,0 +1,47 @@ +// 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 new file mode 100644 index 000000000..3eb8926fa --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsSink.ts @@ -0,0 +1,43 @@ +// 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 new file mode 100644 index 000000000..69d978920 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/StatsdSink.ts @@ -0,0 +1,103 @@ +// 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 new file mode 100644 index 000000000..9b0bb2467 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/metrics/v3/TagSpecifier.ts @@ -0,0 +1,174 @@ +// 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 new file mode 100644 index 000000000..b3fbe1459 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/BufferFactoryConfig.ts @@ -0,0 +1,50 @@ +// 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 new file mode 100644 index 000000000..84f4db34b --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/OverloadAction.ts @@ -0,0 +1,42 @@ +// 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 new file mode 100644 index 000000000..e7f75b8e9 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/OverloadManager.ts @@ -0,0 +1,44 @@ +// 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 new file mode 100644 index 000000000..02fde2411 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ResourceMonitor.ts @@ -0,0 +1,33 @@ +// 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 new file mode 100644 index 000000000..bb48fe3f6 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ScaleTimersOverloadActionConfig.ts @@ -0,0 +1,89 @@ +// 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 new file mode 100644 index 000000000..8c6574f56 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ScaledTrigger.ts @@ -0,0 +1,28 @@ +// 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 new file mode 100644 index 000000000..b02ddd47d --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/ThresholdTrigger.ts @@ -0,0 +1,18 @@ +// 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 new file mode 100644 index 000000000..38f360ee7 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/overload/v3/Trigger.ts @@ -0,0 +1,24 @@ +// 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/ClusterSpecifierPlugin.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/ClusterSpecifierPlugin.ts new file mode 100644 index 000000000..14724412a --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/ClusterSpecifierPlugin.ts @@ -0,0 +1,23 @@ +// Original file: deps/envoy-api/envoy/config/route/v3/route.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'; + +/** + * Configuration for a cluster specifier plugin. + */ +export interface ClusterSpecifierPlugin { + /** + * The name of the plugin and its opaque configuration. + */ + 'extension'?: (_envoy_config_core_v3_TypedExtensionConfig | null); +} + +/** + * Configuration for a cluster specifier plugin. + */ +export interface ClusterSpecifierPlugin__Output { + /** + * The name of the plugin and its opaque configuration. + */ + 'extension': (_envoy_config_core_v3_TypedExtensionConfig__Output | null); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/CorsPolicy.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/CorsPolicy.ts index 03ec3218d..40634448a 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/CorsPolicy.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/CorsPolicy.ts @@ -34,7 +34,7 @@ export interface CorsPolicy { * If neither ``enabled``, ``filter_enabled``, nor ``shadow_enabled`` are specified, the CORS * filter will be enabled for 100% of the requests. * - * If :ref:`runtime_key ` is + * If :ref:`runtime_key ` is * specified, Envoy will lookup the runtime key to get the percentage of requests to filter. */ 'filter_enabled'?: (_envoy_config_core_v3_RuntimeFractionalPercent | null); @@ -45,7 +45,7 @@ export interface CorsPolicy { * This field is intended to be used when ``filter_enabled`` and ``enabled`` are off. One of those * fields have to explicitly disable the filter in order for this setting to take effect. * - * If :ref:`runtime_key ` is specified, + * If :ref:`runtime_key ` is specified, * Envoy will lookup the runtime key to get the percentage of requests for which it will evaluate * and track the request's *Origin* to determine if it's valid but will not enforce any policies. */ @@ -88,7 +88,7 @@ export interface CorsPolicy__Output { * If neither ``enabled``, ``filter_enabled``, nor ``shadow_enabled`` are specified, the CORS * filter will be enabled for 100% of the requests. * - * If :ref:`runtime_key ` is + * If :ref:`runtime_key ` is * specified, Envoy will lookup the runtime key to get the percentage of requests to filter. */ 'filter_enabled'?: (_envoy_config_core_v3_RuntimeFractionalPercent__Output | null); @@ -99,7 +99,7 @@ export interface CorsPolicy__Output { * This field is intended to be used when ``filter_enabled`` and ``enabled`` are off. One of those * fields have to explicitly disable the filter in order for this setting to take effect. * - * If :ref:`runtime_key ` is specified, + * If :ref:`runtime_key ` is specified, * Envoy will lookup the runtime key to get the percentage of requests for which it will evaluate * and track the request's *Origin* to determine if it's valid but will not enforce any policies. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/DirectResponseAction.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/DirectResponseAction.ts index 7e0c3a1b7..794ae510a 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/DirectResponseAction.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/DirectResponseAction.ts @@ -14,8 +14,8 @@ export interface DirectResponseAction { * .. note:: * * Headers can be specified using *response_headers_to_add* in the enclosing - * :ref:`envoy_api_msg_config.route.v3.Route`, :ref:`envoy_api_msg_config.route.v3.RouteConfiguration` or - * :ref:`envoy_api_msg_config.route.v3.VirtualHost`. + * :ref:`envoy_v3_api_msg_config.route.v3.Route`, :ref:`envoy_v3_api_msg_config.route.v3.RouteConfiguration` or + * :ref:`envoy_v3_api_msg_config.route.v3.VirtualHost`. */ 'body'?: (_envoy_config_core_v3_DataSource | null); } @@ -32,8 +32,8 @@ export interface DirectResponseAction__Output { * .. note:: * * Headers can be specified using *response_headers_to_add* in the enclosing - * :ref:`envoy_api_msg_config.route.v3.Route`, :ref:`envoy_api_msg_config.route.v3.RouteConfiguration` or - * :ref:`envoy_api_msg_config.route.v3.VirtualHost`. + * :ref:`envoy_v3_api_msg_config.route.v3.Route`, :ref:`envoy_v3_api_msg_config.route.v3.RouteConfiguration` or + * :ref:`envoy_v3_api_msg_config.route.v3.VirtualHost`. */ 'body': (_envoy_config_core_v3_DataSource__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/FilterConfig.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/FilterConfig.ts index 9a566c2bb..2c960419c 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/FilterConfig.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/FilterConfig.ts @@ -5,9 +5,9 @@ import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__ /** * A simple wrapper for an HTTP filter config. This is intended to be used as a wrapper for the * map value in - * :ref:`VirtualHost.typed_per_filter_config`, - * :ref:`Route.typed_per_filter_config`, - * or :ref:`WeightedCluster.ClusterWeight.typed_per_filter_config` + * :ref:`VirtualHost.typed_per_filter_config`, + * :ref:`Route.typed_per_filter_config`, + * or :ref:`WeightedCluster.ClusterWeight.typed_per_filter_config` * to add additional flags to the filter. * [#not-implemented-hide:] */ @@ -27,9 +27,9 @@ export interface FilterConfig { /** * A simple wrapper for an HTTP filter config. This is intended to be used as a wrapper for the * map value in - * :ref:`VirtualHost.typed_per_filter_config`, - * :ref:`Route.typed_per_filter_config`, - * or :ref:`WeightedCluster.ClusterWeight.typed_per_filter_config` + * :ref:`VirtualHost.typed_per_filter_config`, + * :ref:`Route.typed_per_filter_config`, + * or :ref:`WeightedCluster.ClusterWeight.typed_per_filter_config` * to add additional flags to the filter. * [#not-implemented-hide:] */ 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 ee03d1fe7..bde8f28cd 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 @@ -2,6 +2,7 @@ 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'; /** @@ -24,12 +25,12 @@ import type { Long } from '@grpc/proto-loader'; * * .. attention:: * In the absence of any header match specifier, match will default to :ref:`present_match - * `. i.e, a request that has the :ref:`name - * ` header will match, regardless of the header's + * `. i.e, a request that has the :ref:`name + * ` header will match, regardless of the header's * value. * * [#next-major-version: HeaderMatcher should be refactored to use StringMatcher.] - * [#next-free-field: 13] + * [#next-free-field: 14] */ export interface HeaderMatcher { /** @@ -38,6 +39,7 @@ export interface HeaderMatcher { 'name'?: (string); /** * If specified, header match will be performed based on the value of the header. + * This field is deprecated. Please use :ref:`string_match `. */ 'exact_match'?: (string); /** @@ -55,8 +57,8 @@ export interface HeaderMatcher { */ 'range_match'?: (_envoy_type_v3_Int64Range | null); /** - * If specified, header match will be performed based on whether the header is in the - * request. + * If specified as true, header match will be performed based on whether the header is in the + * request. If specified as false, header match will be performed based on whether the header is absent. */ 'present_match'?: (boolean); /** @@ -71,6 +73,7 @@ export interface HeaderMatcher { /** * If specified, header match will be performed based on the prefix of the header value. * Note: empty prefix is not allowed, please use present_match instead. + * This field is deprecated. Please use :ref:`string_match `. * * Examples: * @@ -80,6 +83,7 @@ export interface HeaderMatcher { /** * If specified, header match will be performed based on the suffix of the header value. * Note: empty suffix is not allowed, please use present_match instead. + * This field is deprecated. Please use :ref:`string_match `. * * Examples: * @@ -90,22 +94,28 @@ export interface HeaderMatcher { * If specified, this regex string is a regular expression rule which implies the entire request * 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 `. */ 'safe_regex_match'?: (_envoy_type_matcher_v3_RegexMatcher | null); /** * If specified, header match will be performed based on whether the header value contains * the given value or not. * Note: empty contains match is not allowed, please use present_match instead. + * This field is deprecated. Please use :ref:`string_match `. * * Examples: * * * The value *abcd* matches the value *xyzabcdpqr*, but not for *xyzbcdpqr*. */ 'contains_match'?: (string); + /** + * If specified, header match will be performed based on the string match of the header value. + */ + 'string_match'?: (_envoy_type_matcher_v3_StringMatcher | null); /** * Specifies how the header match will be performed to route the request. */ - 'header_match_specifier'?: "exact_match"|"safe_regex_match"|"range_match"|"present_match"|"prefix_match"|"suffix_match"|"contains_match"; + 'header_match_specifier'?: "exact_match"|"safe_regex_match"|"range_match"|"present_match"|"prefix_match"|"suffix_match"|"contains_match"|"string_match"; } /** @@ -128,12 +138,12 @@ export interface HeaderMatcher { * * .. attention:: * In the absence of any header match specifier, match will default to :ref:`present_match - * `. i.e, a request that has the :ref:`name - * ` header will match, regardless of the header's + * `. i.e, a request that has the :ref:`name + * ` header will match, regardless of the header's * value. * * [#next-major-version: HeaderMatcher should be refactored to use StringMatcher.] - * [#next-free-field: 13] + * [#next-free-field: 14] */ export interface HeaderMatcher__Output { /** @@ -142,6 +152,7 @@ export interface HeaderMatcher__Output { 'name': (string); /** * If specified, header match will be performed based on the value of the header. + * This field is deprecated. Please use :ref:`string_match `. */ 'exact_match'?: (string); /** @@ -159,8 +170,8 @@ export interface HeaderMatcher__Output { */ 'range_match'?: (_envoy_type_v3_Int64Range__Output | null); /** - * If specified, header match will be performed based on whether the header is in the - * request. + * If specified as true, header match will be performed based on whether the header is in the + * request. If specified as false, header match will be performed based on whether the header is absent. */ 'present_match'?: (boolean); /** @@ -175,6 +186,7 @@ export interface HeaderMatcher__Output { /** * If specified, header match will be performed based on the prefix of the header value. * Note: empty prefix is not allowed, please use present_match instead. + * This field is deprecated. Please use :ref:`string_match `. * * Examples: * @@ -184,6 +196,7 @@ export interface HeaderMatcher__Output { /** * If specified, header match will be performed based on the suffix of the header value. * Note: empty suffix is not allowed, please use present_match instead. + * This field is deprecated. Please use :ref:`string_match `. * * Examples: * @@ -194,20 +207,26 @@ export interface HeaderMatcher__Output { * If specified, this regex string is a regular expression rule which implies the entire request * 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 `. */ 'safe_regex_match'?: (_envoy_type_matcher_v3_RegexMatcher__Output | null); /** * If specified, header match will be performed based on whether the header value contains * the given value or not. * Note: empty contains match is not allowed, please use present_match instead. + * This field is deprecated. Please use :ref:`string_match `. * * Examples: * * * The value *abcd* matches the value *xyzabcdpqr*, but not for *xyzbcdpqr*. */ 'contains_match'?: (string); + /** + * If specified, header match will be performed based on the string match of the header value. + */ + 'string_match'?: (_envoy_type_matcher_v3_StringMatcher__Output | null); /** * Specifies how the header match will be performed to route the request. */ - 'header_match_specifier': "exact_match"|"safe_regex_match"|"range_match"|"present_match"|"prefix_match"|"suffix_match"|"contains_match"; + 'header_match_specifier': "exact_match"|"safe_regex_match"|"range_match"|"present_match"|"prefix_match"|"suffix_match"|"contains_match"|"string_match"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/HedgePolicy.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/HedgePolicy.ts index 413e93b27..302b6d284 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/HedgePolicy.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/HedgePolicy.ts @@ -31,7 +31,7 @@ export interface HedgePolicy { * if there are no more retries left. * * After per-try timeout, an error response would be discarded, as a retry in the form of a hedged request is already in progress. * - * Note: For this to have effect, you must have a :ref:`RetryPolicy ` that retries at least + * Note: For this to have effect, you must have a :ref:`RetryPolicy ` that retries at least * one error code and specifies a maximum number of retries. * * Defaults to false. @@ -67,7 +67,7 @@ export interface HedgePolicy__Output { * if there are no more retries left. * * After per-try timeout, an error response would be discarded, as a retry in the form of a hedged request is already in progress. * - * Note: For this to have effect, you must have a :ref:`RetryPolicy ` that retries at least + * Note: For this to have effect, you must have a :ref:`RetryPolicy ` that retries at least * one error code and specifies a maximum number of retries. * * Defaults to false. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/InternalRedirectPolicy.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/InternalRedirectPolicy.ts index 93a96c247..ab74df94e 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/InternalRedirectPolicy.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/InternalRedirectPolicy.ts @@ -12,7 +12,7 @@ export interface InternalRedirectPolicy { * downstream request has encountered is lower than this value. * In the case where a downstream request is bounced among multiple routes by internal redirect, * the first route that hits this threshold, or does not set :ref:`internal_redirect_policy - * ` + * ` * will pass the redirect back to downstream. * * If not specified, at most one redirect will be followed. @@ -28,6 +28,7 @@ export interface InternalRedirectPolicy { * Specifies a list of predicates that are queried when an upstream response is deemed * to trigger an internal redirect by all other criteria. Any predicate in the list can reject * the redirect, causing the response to be proxied to downstream. + * [#extension-category: envoy.internal_redirect_predicates] */ 'predicates'?: (_envoy_config_core_v3_TypedExtensionConfig)[]; /** @@ -46,7 +47,7 @@ export interface InternalRedirectPolicy__Output { * downstream request has encountered is lower than this value. * In the case where a downstream request is bounced among multiple routes by internal redirect, * the first route that hits this threshold, or does not set :ref:`internal_redirect_policy - * ` + * ` * will pass the redirect back to downstream. * * If not specified, at most one redirect will be followed. @@ -62,6 +63,7 @@ export interface InternalRedirectPolicy__Output { * Specifies a list of predicates that are queried when an upstream response is deemed * to trigger an internal redirect by all other criteria. Any predicate in the list can reject * the redirect, causing the response to be proxied to downstream. + * [#extension-category: envoy.internal_redirect_predicates] */ 'predicates': (_envoy_config_core_v3_TypedExtensionConfig__Output)[]; /** diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/NonForwardingAction.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/NonForwardingAction.ts new file mode 100644 index 000000000..e9c67d44f --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/NonForwardingAction.ts @@ -0,0 +1,14 @@ +// Original file: deps/envoy-api/envoy/config/route/v3/route_components.proto + + +/** + * [#not-implemented-hide:] + */ +export interface NonForwardingAction { +} + +/** + * [#not-implemented-hide:] + */ +export interface NonForwardingAction__Output { +} 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 484044bdf..f1d49537c 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 @@ -38,7 +38,7 @@ export interface _envoy_config_route_v3_RateLimit_Action { * Rate limit on dynamic metadata. * * .. attention:: - * This field has been deprecated in favor of the :ref:`metadata ` field + * This field has been deprecated in favor of the :ref:`metadata ` field */ 'dynamic_metadata'?: (_envoy_config_route_v3_RateLimit_Action_DynamicMetaData | null); /** @@ -47,6 +47,7 @@ export interface _envoy_config_route_v3_RateLimit_Action { 'metadata'?: (_envoy_config_route_v3_RateLimit_Action_MetaData | null); /** * Rate limit descriptor extension. See the rate limit descriptor extensions documentation. + * [#extension-category: envoy.rate_limit_descriptors] */ 'extension'?: (_envoy_config_core_v3_TypedExtensionConfig | null); 'action_specifier'?: "source_cluster"|"destination_cluster"|"request_headers"|"remote_address"|"generic_key"|"header_value_match"|"dynamic_metadata"|"metadata"|"extension"; @@ -84,7 +85,7 @@ export interface _envoy_config_route_v3_RateLimit_Action__Output { * Rate limit on dynamic metadata. * * .. attention:: - * This field has been deprecated in favor of the :ref:`metadata ` field + * This field has been deprecated in favor of the :ref:`metadata ` field */ 'dynamic_metadata'?: (_envoy_config_route_v3_RateLimit_Action_DynamicMetaData__Output | null); /** @@ -93,6 +94,7 @@ export interface _envoy_config_route_v3_RateLimit_Action__Output { 'metadata'?: (_envoy_config_route_v3_RateLimit_Action_MetaData__Output | null); /** * Rate limit descriptor extension. See the rate limit descriptor extensions documentation. + * [#extension-category: envoy.rate_limit_descriptors] */ 'extension'?: (_envoy_config_core_v3_TypedExtensionConfig__Output | null); 'action_specifier': "source_cluster"|"destination_cluster"|"request_headers"|"remote_address"|"generic_key"|"header_value_match"|"dynamic_metadata"|"metadata"|"extension"; @@ -106,14 +108,14 @@ export interface _envoy_config_route_v3_RateLimit_Action__Output { * ("destination_cluster", "") * * Once a request matches against a route table rule, a routed cluster is determined by one of - * the following :ref:`route table configuration ` + * the following :ref:`route table configuration ` * settings: * - * * :ref:`cluster ` indicates the upstream cluster + * * :ref:`cluster ` indicates the upstream cluster * to route to. - * * :ref:`weighted_clusters ` + * * :ref:`weighted_clusters ` * chooses a cluster randomly from a set of clusters with attributed weight. - * * :ref:`cluster_header ` indicates which + * * :ref:`cluster_header ` indicates which * header in the request contains the target cluster. */ export interface _envoy_config_route_v3_RateLimit_Action_DestinationCluster { @@ -127,14 +129,14 @@ export interface _envoy_config_route_v3_RateLimit_Action_DestinationCluster { * ("destination_cluster", "") * * Once a request matches against a route table rule, a routed cluster is determined by one of - * the following :ref:`route table configuration ` + * the following :ref:`route table configuration ` * settings: * - * * :ref:`cluster ` indicates the upstream cluster + * * :ref:`cluster ` indicates the upstream cluster * to route to. - * * :ref:`weighted_clusters ` + * * :ref:`weighted_clusters ` * chooses a cluster randomly from a set of clusters with attributed weight. - * * :ref:`cluster_header ` indicates which + * * :ref:`cluster_header ` indicates which * header in the request contains the target cluster. */ export interface _envoy_config_route_v3_RateLimit_Action_DestinationCluster__Output { @@ -149,7 +151,7 @@ export interface _envoy_config_route_v3_RateLimit_Action_DestinationCluster__Out * ("", "") * * .. attention:: - * This action has been deprecated in favor of the :ref:`metadata ` action + * This action has been deprecated in favor of the :ref:`metadata ` action */ export interface _envoy_config_route_v3_RateLimit_Action_DynamicMetaData { /** @@ -177,7 +179,7 @@ export interface _envoy_config_route_v3_RateLimit_Action_DynamicMetaData { * ("", "") * * .. attention:: - * This action has been deprecated in favor of the :ref:`metadata ` action + * This action has been deprecated in favor of the :ref:`metadata ` action */ export interface _envoy_config_route_v3_RateLimit_Action_DynamicMetaData__Output { /** @@ -204,7 +206,7 @@ export interface _envoy_config_route_v3_RateLimit_Override_DynamicMetadata { * Metadata struct that defines the key and path to retrieve the struct value. * The value must be a struct containing an integer "requests_per_unit" property * and a "unit" property with a value parseable to :ref:`RateLimitUnit - * enum ` + * enum ` */ 'metadata_key'?: (_envoy_type_metadata_v3_MetadataKey | null); } @@ -217,7 +219,7 @@ export interface _envoy_config_route_v3_RateLimit_Override_DynamicMetadata__Outp * Metadata struct that defines the key and path to retrieve the struct value. * The value must be a struct containing an integer "requests_per_unit" property * and a "unit" property with a value parseable to :ref:`RateLimitUnit - * enum ` + * enum ` */ 'metadata_key': (_envoy_type_metadata_v3_MetadataKey__Output | null); } @@ -474,7 +476,7 @@ export enum _envoy_config_route_v3_RateLimit_Action_MetaData_Source { */ DYNAMIC = 0, /** - * Query :ref:`route entry metadata ` + * Query :ref:`route entry metadata ` */ ROUTE_ENTRY = 1, } 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 750946934..e6d41fd7b 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 @@ -71,7 +71,7 @@ export interface RedirectAction { * .. attention:: * * Pay attention to the use of trailing slashes as mentioned in - * :ref:`RouteAction's prefix_rewrite `. + * :ref:`RouteAction's prefix_rewrite `. */ 'prefix_rewrite'?: (string); /** @@ -168,7 +168,7 @@ export interface RedirectAction__Output { * .. attention:: * * Pay attention to the use of trailing slashes as mentioned in - * :ref:`RouteAction's prefix_rewrite `. + * :ref:`RouteAction's prefix_rewrite `. */ 'prefix_rewrite'?: (string); /** 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 d4712b2df..0d523b52e 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 @@ -3,6 +3,7 @@ import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; import type { HeaderMatcher as _envoy_config_route_v3_HeaderMatcher, HeaderMatcher__Output as _envoy_config_route_v3_HeaderMatcher__Output } from '../../../../envoy/config/route/v3/HeaderMatcher'; +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 { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; import type { Long } from '@grpc/proto-loader'; @@ -202,30 +203,42 @@ export interface _envoy_config_route_v3_RetryPolicy_RetryBackOff__Output { export interface _envoy_config_route_v3_RetryPolicy_RetryHostPredicate { 'name'?: (string); 'typed_config'?: (_google_protobuf_Any | null); + /** + * [#extension-category: envoy.retry_host_predicates] + */ 'config_type'?: "typed_config"; } export interface _envoy_config_route_v3_RetryPolicy_RetryHostPredicate__Output { 'name': (string); 'typed_config'?: (_google_protobuf_Any__Output | null); + /** + * [#extension-category: envoy.retry_host_predicates] + */ 'config_type': "typed_config"; } export interface _envoy_config_route_v3_RetryPolicy_RetryPriority { 'name'?: (string); 'typed_config'?: (_google_protobuf_Any | null); + /** + * [#extension-category: envoy.retry_priorities] + */ 'config_type'?: "typed_config"; } export interface _envoy_config_route_v3_RetryPolicy_RetryPriority__Output { 'name': (string); 'typed_config'?: (_google_protobuf_Any__Output | null); + /** + * [#extension-category: envoy.retry_priorities] + */ 'config_type': "typed_config"; } /** * HTTP retry :ref:`architecture overview `. - * [#next-free-field: 12] + * [#next-free-field: 14] */ export interface RetryPolicy { /** @@ -241,14 +254,14 @@ export interface RetryPolicy { */ 'num_retries'?: (_google_protobuf_UInt32Value | null); /** - * Specifies a non-zero upstream timeout per retry attempt. This parameter is optional. The - * same conditions documented for + * Specifies a non-zero upstream timeout per retry attempt (including the initial attempt). This + * parameter is optional. The same conditions documented for * :ref:`config_http_filters_router_x-envoy-upstream-rq-per-try-timeout-ms` apply. * * .. note:: * * If left unspecified, Envoy will use the global - * :ref:`route timeout ` for the request. + * :ref:`route timeout ` for the request. * Consequently, when using a :ref:`5xx ` based * retry policy, a request that times out will not be retried as the total timeout budget * would have been exhausted. @@ -305,11 +318,39 @@ export interface RetryPolicy { * whenever a response includes the matching headers. */ 'rate_limited_retry_back_off'?: (_envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff | null); + /** + * Retry options predicates that will be applied prior to retrying a request. These predicates + * allow customizing request behavior between retries. + * [#comment: add [#extension-category: envoy.retry_options_predicates] when there are built-in extensions] + */ + 'retry_options_predicates'?: (_envoy_config_core_v3_TypedExtensionConfig)[]; + /** + * Specifies an upstream idle timeout per retry attempt (including the initial attempt). This + * parameter is optional and if absent there is no per try idle timeout. The semantics of the per + * try idle timeout are similar to the + * :ref:`route idle timeout ` and + * :ref:`stream idle timeout + * ` + * both enforced by the HTTP connection manager. The difference is that this idle timeout + * is enforced by the router for each individual attempt and thus after all previous filters have + * run, as opposed to *before* all previous filters run for the other idle timeouts. This timeout + * is useful in cases in which total request timeout is bounded by a number of retries and a + * :ref:`per_try_timeout `, but + * there is a desire to ensure each try is making incremental progress. Note also that similar + * to :ref:`per_try_timeout `, + * this idle timeout does not start until after both the entire request has been received by the + * router *and* a connection pool connection has been obtained. Unlike + * :ref:`per_try_timeout `, + * the idle timer continues once the response starts streaming back to the downstream client. + * This ensures that response data continues to make progress without using one of the HTTP + * connection manager idle timeouts. + */ + 'per_try_idle_timeout'?: (_google_protobuf_Duration | null); } /** * HTTP retry :ref:`architecture overview `. - * [#next-free-field: 12] + * [#next-free-field: 14] */ export interface RetryPolicy__Output { /** @@ -325,14 +366,14 @@ export interface RetryPolicy__Output { */ 'num_retries': (_google_protobuf_UInt32Value__Output | null); /** - * Specifies a non-zero upstream timeout per retry attempt. This parameter is optional. The - * same conditions documented for + * Specifies a non-zero upstream timeout per retry attempt (including the initial attempt). This + * parameter is optional. The same conditions documented for * :ref:`config_http_filters_router_x-envoy-upstream-rq-per-try-timeout-ms` apply. * * .. note:: * * If left unspecified, Envoy will use the global - * :ref:`route timeout ` for the request. + * :ref:`route timeout ` for the request. * Consequently, when using a :ref:`5xx ` based * retry policy, a request that times out will not be retried as the total timeout budget * would have been exhausted. @@ -389,4 +430,32 @@ export interface RetryPolicy__Output { * whenever a response includes the matching headers. */ 'rate_limited_retry_back_off': (_envoy_config_route_v3_RetryPolicy_RateLimitedRetryBackOff__Output | null); + /** + * Retry options predicates that will be applied prior to retrying a request. These predicates + * allow customizing request behavior between retries. + * [#comment: add [#extension-category: envoy.retry_options_predicates] when there are built-in extensions] + */ + 'retry_options_predicates': (_envoy_config_core_v3_TypedExtensionConfig__Output)[]; + /** + * Specifies an upstream idle timeout per retry attempt (including the initial attempt). This + * parameter is optional and if absent there is no per try idle timeout. The semantics of the per + * try idle timeout are similar to the + * :ref:`route idle timeout ` and + * :ref:`stream idle timeout + * ` + * both enforced by the HTTP connection manager. The difference is that this idle timeout + * is enforced by the router for each individual attempt and thus after all previous filters have + * run, as opposed to *before* all previous filters run for the other idle timeouts. This timeout + * is useful in cases in which total request timeout is bounded by a number of retries and a + * :ref:`per_try_timeout `, but + * there is a desire to ensure each try is making incremental progress. Note also that similar + * to :ref:`per_try_timeout `, + * this idle timeout does not start until after both the entire request has been received by the + * router *and* a connection pool connection has been obtained. Unlike + * :ref:`per_try_timeout `, + * the idle timer continues once the response starts streaming back to the downstream client. + * This ensures that response data continues to make progress without using one of the HTTP + * connection manager idle timeouts. + */ + 'per_try_idle_timeout': (_google_protobuf_Duration__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Route.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Route.ts index 7bc223f82..d48b554d0 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Route.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Route.ts @@ -11,6 +11,7 @@ import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__ import type { Tracing as _envoy_config_route_v3_Tracing, Tracing__Output as _envoy_config_route_v3_Tracing__Output } from '../../../../envoy/config/route/v3/Tracing'; import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; import type { FilterAction as _envoy_config_route_v3_FilterAction, FilterAction__Output as _envoy_config_route_v3_FilterAction__Output } from '../../../../envoy/config/route/v3/FilterAction'; +import type { NonForwardingAction as _envoy_config_route_v3_NonForwardingAction, NonForwardingAction__Output as _envoy_config_route_v3_NonForwardingAction__Output } from '../../../../envoy/config/route/v3/NonForwardingAction'; /** * A route is both a specification of how to match a request as well as an indication of what to do @@ -19,8 +20,8 @@ import type { FilterAction as _envoy_config_route_v3_FilterAction, FilterAction_ * .. attention:: * * Envoy supports routing on HTTP method via :ref:`header matching - * `. - * [#next-free-field: 18] + * `. + * [#next-free-field: 19] */ export interface Route { /** @@ -54,8 +55,8 @@ export interface Route { /** * Specifies a set of headers that will be added to requests matching this * route. Headers specified at this level are applied before headers from the - * enclosing :ref:`envoy_api_msg_config.route.v3.VirtualHost` and - * :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including details on + * enclosing :ref:`envoy_v3_api_msg_config.route.v3.VirtualHost` and + * :ref:`envoy_v3_api_msg_config.route.v3.RouteConfiguration`. For more information, including details on * header value syntax, see the documentation on :ref:`custom request headers * `. */ @@ -63,8 +64,8 @@ export interface Route { /** * Specifies a set of headers that will be added to responses to requests * matching this route. Headers specified at this level are applied before - * headers from the enclosing :ref:`envoy_api_msg_config.route.v3.VirtualHost` and - * :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including + * headers from the enclosing :ref:`envoy_v3_api_msg_config.route.v3.VirtualHost` and + * :ref:`envoy_v3_api_msg_config.route.v3.RouteConfiguration`. For more information, including * details on header value syntax, see the documentation on * :ref:`custom request headers `. */ @@ -86,7 +87,7 @@ export interface Route { * specific; see the :ref:`HTTP filter documentation ` for * if and how it is utilized. * [#comment: An entry's value may be wrapped in a - * :ref:`FilterConfig` + * :ref:`FilterConfig` * message to specify additional options.] */ 'typed_per_filter_config'?: ({[key: string]: _google_protobuf_Any}); @@ -107,13 +108,20 @@ export interface Route { 'per_request_buffer_limit_bytes'?: (_google_protobuf_UInt32Value | null); /** * [#not-implemented-hide:] - * If true, a filter will define the action (e.g., it could dynamically generate the - * RouteAction). + * A filter-defined action (e.g., it could dynamically generate the RouteAction). * [#comment: TODO(samflattery): Remove cleanup in route_fuzz_test.cc when * implemented] */ 'filter_action'?: (_envoy_config_route_v3_FilterAction | null); - 'action'?: "route"|"redirect"|"direct_response"|"filter_action"; + /** + * [#not-implemented-hide:] + * An action used when the route will generate a response directly, + * without forwarding to an upstream host. This will be used in non-proxy + * xDS clients like the gRPC server. It could also be used in the future + * in Envoy for a filter that directly generates responses for requests. + */ + 'non_forwarding_action'?: (_envoy_config_route_v3_NonForwardingAction | null); + 'action'?: "route"|"redirect"|"direct_response"|"filter_action"|"non_forwarding_action"; } /** @@ -123,8 +131,8 @@ export interface Route { * .. attention:: * * Envoy supports routing on HTTP method via :ref:`header matching - * `. - * [#next-free-field: 18] + * `. + * [#next-free-field: 19] */ export interface Route__Output { /** @@ -158,8 +166,8 @@ export interface Route__Output { /** * Specifies a set of headers that will be added to requests matching this * route. Headers specified at this level are applied before headers from the - * enclosing :ref:`envoy_api_msg_config.route.v3.VirtualHost` and - * :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including details on + * enclosing :ref:`envoy_v3_api_msg_config.route.v3.VirtualHost` and + * :ref:`envoy_v3_api_msg_config.route.v3.RouteConfiguration`. For more information, including details on * header value syntax, see the documentation on :ref:`custom request headers * `. */ @@ -167,8 +175,8 @@ export interface Route__Output { /** * Specifies a set of headers that will be added to responses to requests * matching this route. Headers specified at this level are applied before - * headers from the enclosing :ref:`envoy_api_msg_config.route.v3.VirtualHost` and - * :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including + * headers from the enclosing :ref:`envoy_v3_api_msg_config.route.v3.VirtualHost` and + * :ref:`envoy_v3_api_msg_config.route.v3.RouteConfiguration`. For more information, including * details on header value syntax, see the documentation on * :ref:`custom request headers `. */ @@ -190,7 +198,7 @@ export interface Route__Output { * specific; see the :ref:`HTTP filter documentation ` for * if and how it is utilized. * [#comment: An entry's value may be wrapped in a - * :ref:`FilterConfig` + * :ref:`FilterConfig` * message to specify additional options.] */ 'typed_per_filter_config': ({[key: string]: _google_protobuf_Any__Output}); @@ -211,11 +219,18 @@ export interface Route__Output { 'per_request_buffer_limit_bytes': (_google_protobuf_UInt32Value__Output | null); /** * [#not-implemented-hide:] - * If true, a filter will define the action (e.g., it could dynamically generate the - * RouteAction). + * A filter-defined action (e.g., it could dynamically generate the RouteAction). * [#comment: TODO(samflattery): Remove cleanup in route_fuzz_test.cc when * implemented] */ 'filter_action'?: (_envoy_config_route_v3_FilterAction__Output | null); - 'action': "route"|"redirect"|"direct_response"|"filter_action"; + /** + * [#not-implemented-hide:] + * An action used when the route will generate a response directly, + * without forwarding to an upstream host. This will be used in non-proxy + * xDS clients like the gRPC server. It could also be used in the future + * in Envoy for a filter that directly generates responses for requests. + */ + 'non_forwarding_action'?: (_envoy_config_route_v3_NonForwardingAction__Output | null); + 'action': "route"|"redirect"|"direct_response"|"filter_action"|"non_forwarding_action"; } 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 234aa25e0..43bd51723 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 @@ -306,9 +306,9 @@ export interface _envoy_config_route_v3_RouteAction_MaxStreamDuration { /** * Specifies the maximum duration allowed for streams on the route. If not specified, the value * from the :ref:`max_stream_duration - * ` field in + * ` field in * :ref:`HttpConnectionManager.common_http_protocol_options - * ` + * ` * is used. If this field is set explicitly to zero, any * HttpConnectionManager max_stream_duration timeout will be disabled for * this route. @@ -336,9 +336,9 @@ export interface _envoy_config_route_v3_RouteAction_MaxStreamDuration__Output { /** * Specifies the maximum duration allowed for streams on the route. If not specified, the value * from the :ref:`max_stream_duration - * ` field in + * ` field in * :ref:`HttpConnectionManager.common_http_protocol_options - * ` + * ` * is used. If this field is set explicitly to zero, any * HttpConnectionManager max_stream_duration timeout will be disabled for * this route. @@ -457,7 +457,7 @@ export interface _envoy_config_route_v3_RouteAction_RequestMirrorPolicy__Output * This overrides any enabled/disabled upgrade filter chain specified in the * HttpConnectionManager * :ref:`upgrade_configs - * ` + * ` * but does not affect any custom filter chain specified there. */ export interface _envoy_config_route_v3_RouteAction_UpgradeConfig { @@ -475,7 +475,7 @@ export interface _envoy_config_route_v3_RouteAction_UpgradeConfig { * Configuration for sending data upstream as a raw data payload. This is used for * CONNECT requests, when forwarding CONNECT payload as raw TCP. * Note that CONNECT support is currently considered alpha in Envoy. - * [#comment:TODO(htuch): Replace the above comment with an alpha tag. + * [#comment: TODO(htuch): Replace the above comment with an alpha tag.] */ 'connect_config'?: (_envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig | null); } @@ -485,7 +485,7 @@ export interface _envoy_config_route_v3_RouteAction_UpgradeConfig { * This overrides any enabled/disabled upgrade filter chain specified in the * HttpConnectionManager * :ref:`upgrade_configs - * ` + * ` * but does not affect any custom filter chain specified there. */ export interface _envoy_config_route_v3_RouteAction_UpgradeConfig__Output { @@ -503,13 +503,13 @@ export interface _envoy_config_route_v3_RouteAction_UpgradeConfig__Output { * Configuration for sending data upstream as a raw data payload. This is used for * CONNECT requests, when forwarding CONNECT payload as raw TCP. * Note that CONNECT support is currently considered alpha in Envoy. - * [#comment:TODO(htuch): Replace the above comment with an alpha tag. + * [#comment: TODO(htuch): Replace the above comment with an alpha tag.] */ 'connect_config': (_envoy_config_route_v3_RouteAction_UpgradeConfig_ConnectConfig__Output | null); } /** - * [#next-free-field: 37] + * [#next-free-field: 38] */ export interface RouteAction { /** @@ -545,7 +545,7 @@ export interface RouteAction { * Optional endpoint metadata match criteria used by the subset load balancer. Only endpoints * in the upstream cluster with metadata matching what's set in this field will be considered * for load balancing. If using :ref:`weighted_clusters - * `, metadata will be merged, with values + * `, metadata will be merged, with values * provided there taking precedence. The filter name should be specified as *envoy.lb*. */ 'metadata_match'?: (_envoy_config_core_v3_Metadata | null); @@ -557,16 +557,16 @@ export interface RouteAction { * ` header. * * Only one of *prefix_rewrite* or - * :ref:`regex_rewrite ` + * :ref:`regex_rewrite ` * may be specified. * * .. attention:: * * Pay careful attention to the use of trailing slashes in the - * :ref:`route's match ` prefix value. + * :ref:`route's match ` prefix value. * Stripping a prefix from a path requires multiple Routes to handle all cases. For example, * rewriting * /prefix* to * /* and * /prefix/etc* to * /etc* cannot be done in a single - * :ref:`Route `, as shown by the below config entries: + * :ref:`Route `, as shown by the below config entries: * * .. code-block:: yaml * @@ -628,7 +628,7 @@ export interface RouteAction { /** * Specifies if the rate limit filter should include the virtual host rate * limits. By default, if the route configured rate limits, the virtual host - * :ref:`rate_limits ` are not applied to the + * :ref:`rate_limits ` are not applied to the * request. * * This field is deprecated. Please use :ref:`vh_rate_limits ` @@ -659,15 +659,15 @@ export interface RouteAction { */ 'cluster_not_found_response_code'?: (_envoy_config_route_v3_RouteAction_ClusterNotFoundResponseCode | keyof typeof _envoy_config_route_v3_RouteAction_ClusterNotFoundResponseCode); /** - * Deprecated by :ref:`grpc_timeout_header_max ` + * Deprecated by :ref:`grpc_timeout_header_max ` * If present, and the request is a gRPC request, use the * `grpc-timeout header `_, * or its default value (infinity) instead of - * :ref:`timeout `, but limit the applied timeout + * :ref:`timeout `, but limit the applied timeout * to the maximum value specified here. If configured as 0, the maximum allowed timeout for * gRPC requests is infinity. If not configured at all, the `grpc-timeout` header is not used * and gRPC requests time out like any other requests using - * :ref:`timeout ` or its default. + * :ref:`timeout ` or its default. * This can be used to prevent unexpected upstream request timeouts due to potentially long * time gaps between gRPC request and response in gRPC streaming mode. * @@ -684,14 +684,14 @@ export interface RouteAction { /** * Specifies the idle timeout for the route. If not specified, there is no per-route idle timeout, * although the connection manager wide :ref:`stream_idle_timeout - * ` + * ` * will still apply. A value of 0 will completely disable the route's idle timeout, even if a * connection manager stream idle timeout is configured. * * The idle timeout is distinct to :ref:`timeout - * `, which provides an upper bound + * `, which provides an upper bound * on the upstream response time; :ref:`idle_timeout - * ` instead bounds the amount + * ` instead bounds the amount * of time the request's stream may be idle. * * After header decoding, the idle timeout will apply on downstream and @@ -703,7 +703,7 @@ export interface RouteAction { * * If the :ref:`overload action ` "envoy.overload_actions.reduce_timeouts" * is configured, this timeout is scaled according to the value for - * :ref:`HTTP_DOWNSTREAM_STREAM_IDLE `. + * :ref:`HTTP_DOWNSTREAM_STREAM_IDLE `. */ 'idle_timeout'?: (_google_protobuf_Duration | null); 'upgrade_configs'?: (_envoy_config_route_v3_RouteAction_UpgradeConfig)[]; @@ -715,7 +715,7 @@ export interface RouteAction { */ 'hedge_policy'?: (_envoy_config_route_v3_HedgePolicy | null); /** - * Deprecated by :ref:`grpc_timeout_header_offset `. + * Deprecated by :ref:`grpc_timeout_header_offset `. * If present, Envoy will adjust the timeout provided by the `grpc-timeout` header by subtracting * the provided duration from the header. This is useful in allowing Envoy to set its global * timeout to be less than that of the deadline imposed by the calling client, which makes it more @@ -747,15 +747,15 @@ export interface RouteAction { /** * An internal redirect is handled, iff the number of previous internal redirects that a * downstream request has encountered is lower than this value, and - * :ref:`internal_redirect_action ` + * :ref:`internal_redirect_action ` * is set to :ref:`HANDLE_INTERNAL_REDIRECT - * ` + * ` * In the case where a downstream request is bounced among multiple routes by internal redirect, * the first route that hits this threshold, or has - * :ref:`internal_redirect_action ` + * :ref:`internal_redirect_action ` * set to * :ref:`PASS_THROUGH_INTERNAL_REDIRECT - * ` + * ` * will pass the redirect back to downstream. * * If not specified, at most one redirect will be followed. @@ -771,7 +771,7 @@ export interface RouteAction { * before the rewrite into the :ref:`x-envoy-original-path * ` header. * - * Only one of :ref:`prefix_rewrite ` + * Only one of :ref:`prefix_rewrite ` * or *regex_rewrite* may be specified. * * Examples using Google's `RE2 `_ engine: @@ -796,7 +796,7 @@ export interface RouteAction { * [#not-implemented-hide:] * Specifies the configuration for retry policy extension. Note that if this is set, it'll take * precedence over the virtual host level retry policy entirely (e.g.: policies are not merged, - * most internal one becomes the enforced policy). :ref:`Retry policy ` + * most internal one becomes the enforced policy). :ref:`Retry policy ` * should not be set if this field is used. */ 'retry_policy_typed_config'?: (_google_protobuf_Any | null); @@ -804,7 +804,7 @@ export interface RouteAction { * If present, Envoy will try to follow an upstream redirect response instead of proxying the * response back to the downstream. An upstream redirect response is defined * by :ref:`redirect_response_codes - * `. + * `. */ 'internal_redirect_policy'?: (_envoy_config_route_v3_InternalRedirectPolicy | null); /** @@ -829,12 +829,21 @@ export interface RouteAction { * Specifies the maximum stream duration for this route. */ 'max_stream_duration'?: (_envoy_config_route_v3_RouteAction_MaxStreamDuration | null); - 'cluster_specifier'?: "cluster"|"cluster_header"|"weighted_clusters"; + /** + * [#not-implemented-hide:] + * Name of the cluster specifier plugin to use to determine the cluster for + * requests on this route. The plugin name must be defined in the associated + * :ref:`envoy_v3_api_field_config.route.v3.RouteConfiguration.cluster_specifier_plugins` + * in the + * :ref:`envoy_v3_api_field_config.core.v3.TypedExtensionConfig.name` field. + */ + 'cluster_specifier_plugin'?: (string); + 'cluster_specifier'?: "cluster"|"cluster_header"|"weighted_clusters"|"cluster_specifier_plugin"; 'host_rewrite_specifier'?: "host_rewrite_literal"|"auto_host_rewrite"|"host_rewrite_header"|"host_rewrite_path_regex"; } /** - * [#next-free-field: 37] + * [#next-free-field: 38] */ export interface RouteAction__Output { /** @@ -870,7 +879,7 @@ export interface RouteAction__Output { * Optional endpoint metadata match criteria used by the subset load balancer. Only endpoints * in the upstream cluster with metadata matching what's set in this field will be considered * for load balancing. If using :ref:`weighted_clusters - * `, metadata will be merged, with values + * `, metadata will be merged, with values * provided there taking precedence. The filter name should be specified as *envoy.lb*. */ 'metadata_match': (_envoy_config_core_v3_Metadata__Output | null); @@ -882,16 +891,16 @@ export interface RouteAction__Output { * ` header. * * Only one of *prefix_rewrite* or - * :ref:`regex_rewrite ` + * :ref:`regex_rewrite ` * may be specified. * * .. attention:: * * Pay careful attention to the use of trailing slashes in the - * :ref:`route's match ` prefix value. + * :ref:`route's match ` prefix value. * Stripping a prefix from a path requires multiple Routes to handle all cases. For example, * rewriting * /prefix* to * /* and * /prefix/etc* to * /etc* cannot be done in a single - * :ref:`Route `, as shown by the below config entries: + * :ref:`Route `, as shown by the below config entries: * * .. code-block:: yaml * @@ -953,7 +962,7 @@ export interface RouteAction__Output { /** * Specifies if the rate limit filter should include the virtual host rate * limits. By default, if the route configured rate limits, the virtual host - * :ref:`rate_limits ` are not applied to the + * :ref:`rate_limits ` are not applied to the * request. * * This field is deprecated. Please use :ref:`vh_rate_limits ` @@ -984,15 +993,15 @@ export interface RouteAction__Output { */ 'cluster_not_found_response_code': (keyof typeof _envoy_config_route_v3_RouteAction_ClusterNotFoundResponseCode); /** - * Deprecated by :ref:`grpc_timeout_header_max ` + * Deprecated by :ref:`grpc_timeout_header_max ` * If present, and the request is a gRPC request, use the * `grpc-timeout header `_, * or its default value (infinity) instead of - * :ref:`timeout `, but limit the applied timeout + * :ref:`timeout `, but limit the applied timeout * to the maximum value specified here. If configured as 0, the maximum allowed timeout for * gRPC requests is infinity. If not configured at all, the `grpc-timeout` header is not used * and gRPC requests time out like any other requests using - * :ref:`timeout ` or its default. + * :ref:`timeout ` or its default. * This can be used to prevent unexpected upstream request timeouts due to potentially long * time gaps between gRPC request and response in gRPC streaming mode. * @@ -1009,14 +1018,14 @@ export interface RouteAction__Output { /** * Specifies the idle timeout for the route. If not specified, there is no per-route idle timeout, * although the connection manager wide :ref:`stream_idle_timeout - * ` + * ` * will still apply. A value of 0 will completely disable the route's idle timeout, even if a * connection manager stream idle timeout is configured. * * The idle timeout is distinct to :ref:`timeout - * `, which provides an upper bound + * `, which provides an upper bound * on the upstream response time; :ref:`idle_timeout - * ` instead bounds the amount + * ` instead bounds the amount * of time the request's stream may be idle. * * After header decoding, the idle timeout will apply on downstream and @@ -1028,7 +1037,7 @@ export interface RouteAction__Output { * * If the :ref:`overload action ` "envoy.overload_actions.reduce_timeouts" * is configured, this timeout is scaled according to the value for - * :ref:`HTTP_DOWNSTREAM_STREAM_IDLE `. + * :ref:`HTTP_DOWNSTREAM_STREAM_IDLE `. */ 'idle_timeout': (_google_protobuf_Duration__Output | null); 'upgrade_configs': (_envoy_config_route_v3_RouteAction_UpgradeConfig__Output)[]; @@ -1040,7 +1049,7 @@ export interface RouteAction__Output { */ 'hedge_policy': (_envoy_config_route_v3_HedgePolicy__Output | null); /** - * Deprecated by :ref:`grpc_timeout_header_offset `. + * Deprecated by :ref:`grpc_timeout_header_offset `. * If present, Envoy will adjust the timeout provided by the `grpc-timeout` header by subtracting * the provided duration from the header. This is useful in allowing Envoy to set its global * timeout to be less than that of the deadline imposed by the calling client, which makes it more @@ -1072,15 +1081,15 @@ export interface RouteAction__Output { /** * An internal redirect is handled, iff the number of previous internal redirects that a * downstream request has encountered is lower than this value, and - * :ref:`internal_redirect_action ` + * :ref:`internal_redirect_action ` * is set to :ref:`HANDLE_INTERNAL_REDIRECT - * ` + * ` * In the case where a downstream request is bounced among multiple routes by internal redirect, * the first route that hits this threshold, or has - * :ref:`internal_redirect_action ` + * :ref:`internal_redirect_action ` * set to * :ref:`PASS_THROUGH_INTERNAL_REDIRECT - * ` + * ` * will pass the redirect back to downstream. * * If not specified, at most one redirect will be followed. @@ -1096,7 +1105,7 @@ export interface RouteAction__Output { * before the rewrite into the :ref:`x-envoy-original-path * ` header. * - * Only one of :ref:`prefix_rewrite ` + * Only one of :ref:`prefix_rewrite ` * or *regex_rewrite* may be specified. * * Examples using Google's `RE2 `_ engine: @@ -1121,7 +1130,7 @@ export interface RouteAction__Output { * [#not-implemented-hide:] * Specifies the configuration for retry policy extension. Note that if this is set, it'll take * precedence over the virtual host level retry policy entirely (e.g.: policies are not merged, - * most internal one becomes the enforced policy). :ref:`Retry policy ` + * most internal one becomes the enforced policy). :ref:`Retry policy ` * should not be set if this field is used. */ 'retry_policy_typed_config': (_google_protobuf_Any__Output | null); @@ -1129,7 +1138,7 @@ export interface RouteAction__Output { * If present, Envoy will try to follow an upstream redirect response instead of proxying the * response back to the downstream. An upstream redirect response is defined * by :ref:`redirect_response_codes - * `. + * `. */ 'internal_redirect_policy': (_envoy_config_route_v3_InternalRedirectPolicy__Output | null); /** @@ -1154,6 +1163,15 @@ export interface RouteAction__Output { * Specifies the maximum stream duration for this route. */ 'max_stream_duration': (_envoy_config_route_v3_RouteAction_MaxStreamDuration__Output | null); - 'cluster_specifier': "cluster"|"cluster_header"|"weighted_clusters"; + /** + * [#not-implemented-hide:] + * Name of the cluster specifier plugin to use to determine the cluster for + * requests on this route. The plugin name must be defined in the associated + * :ref:`envoy_v3_api_field_config.route.v3.RouteConfiguration.cluster_specifier_plugins` + * in the + * :ref:`envoy_v3_api_field_config.core.v3.TypedExtensionConfig.name` field. + */ + 'cluster_specifier_plugin'?: (string); + 'cluster_specifier': "cluster"|"cluster_header"|"weighted_clusters"|"cluster_specifier_plugin"; 'host_rewrite_specifier': "host_rewrite_literal"|"auto_host_rewrite"|"host_rewrite_header"|"host_rewrite_path_regex"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteConfiguration.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteConfiguration.ts index ebb3c3419..516f4b06b 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteConfiguration.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteConfiguration.ts @@ -5,16 +5,17 @@ import type { HeaderValueOption as _envoy_config_core_v3_HeaderValueOption, Head import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; import type { Vhds as _envoy_config_route_v3_Vhds, Vhds__Output as _envoy_config_route_v3_Vhds__Output } from '../../../../envoy/config/route/v3/Vhds'; import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; +import type { ClusterSpecifierPlugin as _envoy_config_route_v3_ClusterSpecifierPlugin, ClusterSpecifierPlugin__Output as _envoy_config_route_v3_ClusterSpecifierPlugin__Output } from '../../../../envoy/config/route/v3/ClusterSpecifierPlugin'; /** - * [#next-free-field: 12] + * [#next-free-field: 13] */ export interface RouteConfiguration { /** * The name of the route configuration. For example, it might match * :ref:`route_config_name - * ` in - * :ref:`envoy_api_msg_extensions.filters.network.http_connection_manager.v3.Rds`. + * ` in + * :ref:`envoy_v3_api_msg_extensions.filters.network.http_connection_manager.v3.Rds`. */ 'name'?: (string); /** @@ -31,8 +32,8 @@ export interface RouteConfiguration { /** * Specifies a list of HTTP headers that should be added to each response that * the connection manager encodes. Headers specified at this level are applied - * after headers from any enclosed :ref:`envoy_api_msg_config.route.v3.VirtualHost` or - * :ref:`envoy_api_msg_config.route.v3.RouteAction`. For more information, including details on + * after headers from any enclosed :ref:`envoy_v3_api_msg_config.route.v3.VirtualHost` or + * :ref:`envoy_v3_api_msg_config.route.v3.RouteAction`. For more information, including details on * header value syntax, see the documentation on :ref:`custom request headers * `. */ @@ -45,8 +46,8 @@ export interface RouteConfiguration { /** * Specifies a list of HTTP headers that should be added to each request * routed by the HTTP connection manager. Headers specified at this level are - * applied after headers from any enclosed :ref:`envoy_api_msg_config.route.v3.VirtualHost` or - * :ref:`envoy_api_msg_config.route.v3.RouteAction`. For more information, including details on + * applied after headers from any enclosed :ref:`envoy_v3_api_msg_config.route.v3.VirtualHost` or + * :ref:`envoy_v3_api_msg_config.route.v3.RouteAction`. For more information, including details on * header value syntax, see the documentation on :ref:`custom request headers * `. */ @@ -59,10 +60,10 @@ export interface RouteConfiguration { * route table will load and the router filter will return a 404 if the route * is selected at runtime. This setting defaults to true if the route table * is statically defined via the :ref:`route_config - * ` + * ` * option. This setting default to false if the route table is loaded dynamically via the * :ref:`rds - * ` + * ` * option. Users may wish to override the default behavior in certain cases (for example when * using CDS with a static route table). */ @@ -96,28 +97,35 @@ export interface RouteConfiguration { 'most_specific_header_mutations_wins'?: (boolean); /** * The maximum bytes of the response :ref:`direct response body - * ` size. If not specified the default + * ` size. If not specified the default * is 4096. * * .. warning:: * * Envoy currently holds the content of :ref:`direct response body - * ` in memory. Be careful setting + * ` in memory. Be careful setting * this to be larger than the default 4KB, since the allocated memory for direct response body * is not subject to data plane buffering controls. */ 'max_direct_response_body_size_bytes'?: (_google_protobuf_UInt32Value | null); + /** + * [#not-implemented-hide:] + * A list of plugins and their configurations which may be used by a + * :ref:`envoy_v3_api_field_config.route.v3.RouteAction.cluster_specifier_plugin` + * within the route. All *extension.name* fields in this list must be unique. + */ + 'cluster_specifier_plugins'?: (_envoy_config_route_v3_ClusterSpecifierPlugin)[]; } /** - * [#next-free-field: 12] + * [#next-free-field: 13] */ export interface RouteConfiguration__Output { /** * The name of the route configuration. For example, it might match * :ref:`route_config_name - * ` in - * :ref:`envoy_api_msg_extensions.filters.network.http_connection_manager.v3.Rds`. + * ` in + * :ref:`envoy_v3_api_msg_extensions.filters.network.http_connection_manager.v3.Rds`. */ 'name': (string); /** @@ -134,8 +142,8 @@ export interface RouteConfiguration__Output { /** * Specifies a list of HTTP headers that should be added to each response that * the connection manager encodes. Headers specified at this level are applied - * after headers from any enclosed :ref:`envoy_api_msg_config.route.v3.VirtualHost` or - * :ref:`envoy_api_msg_config.route.v3.RouteAction`. For more information, including details on + * after headers from any enclosed :ref:`envoy_v3_api_msg_config.route.v3.VirtualHost` or + * :ref:`envoy_v3_api_msg_config.route.v3.RouteAction`. For more information, including details on * header value syntax, see the documentation on :ref:`custom request headers * `. */ @@ -148,8 +156,8 @@ export interface RouteConfiguration__Output { /** * Specifies a list of HTTP headers that should be added to each request * routed by the HTTP connection manager. Headers specified at this level are - * applied after headers from any enclosed :ref:`envoy_api_msg_config.route.v3.VirtualHost` or - * :ref:`envoy_api_msg_config.route.v3.RouteAction`. For more information, including details on + * applied after headers from any enclosed :ref:`envoy_v3_api_msg_config.route.v3.VirtualHost` or + * :ref:`envoy_v3_api_msg_config.route.v3.RouteAction`. For more information, including details on * header value syntax, see the documentation on :ref:`custom request headers * `. */ @@ -162,10 +170,10 @@ export interface RouteConfiguration__Output { * route table will load and the router filter will return a 404 if the route * is selected at runtime. This setting defaults to true if the route table * is statically defined via the :ref:`route_config - * ` + * ` * option. This setting default to false if the route table is loaded dynamically via the * :ref:`rds - * ` + * ` * option. Users may wish to override the default behavior in certain cases (for example when * using CDS with a static route table). */ @@ -199,15 +207,22 @@ export interface RouteConfiguration__Output { 'most_specific_header_mutations_wins': (boolean); /** * The maximum bytes of the response :ref:`direct response body - * ` size. If not specified the default + * ` size. If not specified the default * is 4096. * * .. warning:: * * Envoy currently holds the content of :ref:`direct response body - * ` in memory. Be careful setting + * ` in memory. Be careful setting * this to be larger than the default 4KB, since the allocated memory for direct response body * is not subject to data plane buffering controls. */ 'max_direct_response_body_size_bytes': (_google_protobuf_UInt32Value__Output | null); + /** + * [#not-implemented-hide:] + * A list of plugins and their configurations which may be used by a + * :ref:`envoy_v3_api_field_config.route.v3.RouteAction.cluster_specifier_plugin` + * within the route. All *extension.name* fields in this list must be unique. + */ + 'cluster_specifier_plugins': (_envoy_config_route_v3_ClusterSpecifierPlugin__Output)[]; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteMatch.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteMatch.ts index ddf44da2f..9d872ed18 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteMatch.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/RouteMatch.ts @@ -5,6 +5,7 @@ import type { HeaderMatcher as _envoy_config_route_v3_HeaderMatcher, HeaderMatch import type { QueryParameterMatcher as _envoy_config_route_v3_QueryParameterMatcher, QueryParameterMatcher__Output as _envoy_config_route_v3_QueryParameterMatcher__Output } from '../../../../envoy/config/route/v3/QueryParameterMatcher'; import type { RuntimeFractionalPercent as _envoy_config_core_v3_RuntimeFractionalPercent, RuntimeFractionalPercent__Output as _envoy_config_core_v3_RuntimeFractionalPercent__Output } from '../../../../envoy/config/core/v3/RuntimeFractionalPercent'; 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 { MetadataMatcher as _envoy_type_matcher_v3_MetadataMatcher, MetadataMatcher__Output as _envoy_type_matcher_v3_MetadataMatcher__Output } from '../../../../envoy/type/matcher/v3/MetadataMatcher'; /** * An extensible message for matching CONNECT requests. @@ -51,7 +52,7 @@ export interface _envoy_config_route_v3_RouteMatch_TlsContextMatchOptions__Outpu } /** - * [#next-free-field: 13] + * [#next-free-field: 14] */ export interface RouteMatch { /** @@ -66,7 +67,7 @@ export interface RouteMatch { 'path'?: (string); /** * Indicates that prefix/path matching should be case sensitive. The default - * is true. + * is true. Ignored for safe_regex matching. */ 'case_sensitive'?: (_google_protobuf_BoolValue | null); /** @@ -83,6 +84,14 @@ export interface RouteMatch { * against all the specified query parameters. If the number of specified * query parameters is nonzero, they all must match the *path* header's * query string for a match to occur. + * + * .. note:: + * + * If query parameters are used to pass request message fields when + * `grpc_json_transcoder `_ + * is used, the transcoded message fields maybe different. The query parameters are + * url encoded, but the message fields are not. For example, if a query + * parameter is "foo%20bar", the message field will be "foo bar". */ 'query_parameters'?: (_envoy_config_route_v3_QueryParameterMatcher)[]; /** @@ -141,14 +150,21 @@ export interface RouteMatch { * where Extended CONNECT requests may have a path, the path matchers will work if * there is a path present. * Note that CONNECT support is currently considered alpha in Envoy. - * [#comment:TODO(htuch): Replace the above comment with an alpha tag. + * [#comment: TODO(htuch): Replace the above comment with an alpha tag.] */ 'connect_matcher'?: (_envoy_config_route_v3_RouteMatch_ConnectMatcher | null); + /** + * Specifies a set of dynamic metadata matchers on which the route should match. + * The router will check the dynamic metadata against all the specified dynamic metadata matchers. + * If the number of specified dynamic metadata matchers is nonzero, they all must match the + * dynamic metadata for a match to occur. + */ + 'dynamic_metadata'?: (_envoy_type_matcher_v3_MetadataMatcher)[]; 'path_specifier'?: "prefix"|"path"|"safe_regex"|"connect_matcher"; } /** - * [#next-free-field: 13] + * [#next-free-field: 14] */ export interface RouteMatch__Output { /** @@ -163,7 +179,7 @@ export interface RouteMatch__Output { 'path'?: (string); /** * Indicates that prefix/path matching should be case sensitive. The default - * is true. + * is true. Ignored for safe_regex matching. */ 'case_sensitive': (_google_protobuf_BoolValue__Output | null); /** @@ -180,6 +196,14 @@ export interface RouteMatch__Output { * against all the specified query parameters. If the number of specified * query parameters is nonzero, they all must match the *path* header's * query string for a match to occur. + * + * .. note:: + * + * If query parameters are used to pass request message fields when + * `grpc_json_transcoder `_ + * is used, the transcoded message fields maybe different. The query parameters are + * url encoded, but the message fields are not. For example, if a query + * parameter is "foo%20bar", the message field will be "foo bar". */ 'query_parameters': (_envoy_config_route_v3_QueryParameterMatcher__Output)[]; /** @@ -238,8 +262,15 @@ export interface RouteMatch__Output { * where Extended CONNECT requests may have a path, the path matchers will work if * there is a path present. * Note that CONNECT support is currently considered alpha in Envoy. - * [#comment:TODO(htuch): Replace the above comment with an alpha tag. + * [#comment: TODO(htuch): Replace the above comment with an alpha tag.] */ 'connect_matcher'?: (_envoy_config_route_v3_RouteMatch_ConnectMatcher__Output | null); + /** + * Specifies a set of dynamic metadata matchers on which the route should match. + * The router will check the dynamic metadata against all the specified dynamic metadata matchers. + * If the number of specified dynamic metadata matchers is nonzero, they all must match the + * dynamic metadata for a match to occur. + */ + 'dynamic_metadata': (_envoy_type_matcher_v3_MetadataMatcher__Output)[]; 'path_specifier': "prefix"|"path"|"safe_regex"|"connect_matcher"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/ScopedRouteConfiguration.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/ScopedRouteConfiguration.ts index 74b5fe43d..5865eadd3 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/ScopedRouteConfiguration.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/ScopedRouteConfiguration.ts @@ -19,7 +19,7 @@ export interface _envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment__O /** * Specifies a key which is matched against the output of the - * :ref:`scope_key_builder` + * :ref:`scope_key_builder` * specified in the HttpConnectionManager. The matching is done per HTTP * request and is dependent on the order of the fragments contained in the * Key. @@ -28,14 +28,14 @@ export interface _envoy_config_route_v3_ScopedRouteConfiguration_Key { /** * The ordered set of fragments to match against. The order must match the * fragments in the corresponding - * :ref:`scope_key_builder`. + * :ref:`scope_key_builder`. */ 'fragments'?: (_envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment)[]; } /** * Specifies a key which is matched against the output of the - * :ref:`scope_key_builder` + * :ref:`scope_key_builder` * specified in the HttpConnectionManager. The matching is done per HTTP * request and is dependent on the order of the fragments contained in the * Key. @@ -44,20 +44,20 @@ export interface _envoy_config_route_v3_ScopedRouteConfiguration_Key__Output { /** * The ordered set of fragments to match against. The order must match the * fragments in the corresponding - * :ref:`scope_key_builder`. + * :ref:`scope_key_builder`. */ 'fragments': (_envoy_config_route_v3_ScopedRouteConfiguration_Key_Fragment__Output)[]; } /** * Specifies a routing scope, which associates a - * :ref:`Key` to a - * :ref:`envoy_api_msg_config.route.v3.RouteConfiguration` (identified by its resource name). + * :ref:`Key` to a + * :ref:`envoy_v3_api_msg_config.route.v3.RouteConfiguration` (identified by its resource name). * * The HTTP connection manager builds up a table consisting of these Key to * RouteConfiguration mappings, and looks up the RouteConfiguration to use per * request according to the algorithm specified in the - * :ref:`scope_key_builder` + * :ref:`scope_key_builder` * assigned to the HttpConnectionManager. * * For example, with the following configurations (in YAML): @@ -79,7 +79,7 @@ export interface _envoy_config_route_v3_ScopedRouteConfiguration_Key__Output { * key: vip * * ScopedRouteConfiguration resources (specified statically via - * :ref:`scoped_route_configurations_list` + * :ref:`scoped_route_configurations_list` * or obtained dynamically via SRDS): * * .. code:: @@ -115,8 +115,8 @@ export interface ScopedRouteConfiguration { */ 'name'?: (string); /** - * The resource name to use for a :ref:`envoy_api_msg_service.discovery.v3.DiscoveryRequest` to an - * RDS server to fetch the :ref:`envoy_api_msg_config.route.v3.RouteConfiguration` associated + * The resource name to use for a :ref:`envoy_v3_api_msg_service.discovery.v3.DiscoveryRequest` to an + * RDS server to fetch the :ref:`envoy_v3_api_msg_config.route.v3.RouteConfiguration` associated * with this scope. */ 'route_configuration_name'?: (string); @@ -132,13 +132,13 @@ export interface ScopedRouteConfiguration { /** * Specifies a routing scope, which associates a - * :ref:`Key` to a - * :ref:`envoy_api_msg_config.route.v3.RouteConfiguration` (identified by its resource name). + * :ref:`Key` to a + * :ref:`envoy_v3_api_msg_config.route.v3.RouteConfiguration` (identified by its resource name). * * The HTTP connection manager builds up a table consisting of these Key to * RouteConfiguration mappings, and looks up the RouteConfiguration to use per * request according to the algorithm specified in the - * :ref:`scope_key_builder` + * :ref:`scope_key_builder` * assigned to the HttpConnectionManager. * * For example, with the following configurations (in YAML): @@ -160,7 +160,7 @@ export interface ScopedRouteConfiguration { * key: vip * * ScopedRouteConfiguration resources (specified statically via - * :ref:`scoped_route_configurations_list` + * :ref:`scoped_route_configurations_list` * or obtained dynamically via SRDS): * * .. code:: @@ -196,8 +196,8 @@ export interface ScopedRouteConfiguration__Output { */ 'name': (string); /** - * The resource name to use for a :ref:`envoy_api_msg_service.discovery.v3.DiscoveryRequest` to an - * RDS server to fetch the :ref:`envoy_api_msg_config.route.v3.RouteConfiguration` associated + * The resource name to use for a :ref:`envoy_v3_api_msg_service.discovery.v3.DiscoveryRequest` to an + * RDS server to fetch the :ref:`envoy_v3_api_msg_config.route.v3.RouteConfiguration` associated * with this scope. */ 'route_configuration_name': (string); diff --git a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Tracing.ts b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Tracing.ts index e1a9220d7..962e9d51a 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Tracing.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/route/v3/Tracing.ts @@ -35,7 +35,7 @@ export interface Tracing { /** * A list of custom tags with unique tag name to create tags for the active span. * It will take effect after merging with the :ref:`corresponding configuration - * ` + * ` * configured in the HTTP connection manager. If two tags with the same name are configured * each in the HTTP connection manager and the route level, the one configured here takes * priority. @@ -75,7 +75,7 @@ export interface Tracing__Output { /** * A list of custom tags with unique tag name to create tags for the active span. * It will take effect after merging with the :ref:`corresponding configuration - * ` + * ` * configured in the HTTP connection manager. If two tags with the same name are configured * each in the HTTP connection manager and the route level, the one configured here takes * priority. 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 1d3fb2309..017900ed9 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 @@ -87,8 +87,8 @@ export interface VirtualHost { /** * Specifies a list of HTTP headers that should be added to each request * handled by this virtual host. Headers specified at this level are applied - * after headers from enclosed :ref:`envoy_api_msg_config.route.v3.Route` and before headers from the - * enclosing :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including + * after headers from enclosed :ref:`envoy_v3_api_msg_config.route.v3.Route` and before headers from the + * enclosing :ref:`envoy_v3_api_msg_config.route.v3.RouteConfiguration`. For more information, including * details on header value syntax, see the documentation on :ref:`custom request headers * `. */ @@ -100,8 +100,8 @@ export interface VirtualHost { /** * Specifies a list of HTTP headers that should be added to each response * handled by this virtual host. Headers specified at this level are applied - * after headers from enclosed :ref:`envoy_api_msg_config.route.v3.Route` and before headers from the - * enclosing :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including + * after headers from enclosed :ref:`envoy_v3_api_msg_config.route.v3.Route` and before headers from the + * enclosing :ref:`envoy_v3_api_msg_config.route.v3.RouteConfiguration`. For more information, including * details on header value syntax, see the documentation on :ref:`custom request headers * `. */ @@ -124,7 +124,7 @@ export interface VirtualHost { * will see the attempt count as perceived by the second Envoy. Defaults to false. * This header is unaffected by the * :ref:`suppress_envoy_headers - * ` flag. + * ` flag. * * [#next-major-version: rename to include_attempt_count_in_request.] */ @@ -136,7 +136,7 @@ export interface VirtualHost { * specific; see the :ref:`HTTP filter documentation ` * for if and how it is utilized. * [#comment: An entry's value may be wrapped in a - * :ref:`FilterConfig` + * :ref:`FilterConfig` * message to specify additional options.] */ 'typed_per_filter_config'?: ({[key: string]: _google_protobuf_Any}); @@ -166,14 +166,14 @@ export interface VirtualHost { * will see the attempt count as perceived by the Envoy closest upstream from itself. Defaults to false. * This header is unaffected by the * :ref:`suppress_envoy_headers - * ` flag. + * ` flag. */ 'include_attempt_count_in_response'?: (boolean); /** * [#not-implemented-hide:] * Specifies the configuration for retry policy extension. Note that setting a route level entry * will take precedence over this config and it'll be treated independently (e.g.: values are not - * inherited). :ref:`Retry policy ` should not be + * inherited). :ref:`Retry policy ` should not be * set if this field is used. */ 'retry_policy_typed_config'?: (_google_protobuf_Any | null); @@ -237,8 +237,8 @@ export interface VirtualHost__Output { /** * Specifies a list of HTTP headers that should be added to each request * handled by this virtual host. Headers specified at this level are applied - * after headers from enclosed :ref:`envoy_api_msg_config.route.v3.Route` and before headers from the - * enclosing :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including + * after headers from enclosed :ref:`envoy_v3_api_msg_config.route.v3.Route` and before headers from the + * enclosing :ref:`envoy_v3_api_msg_config.route.v3.RouteConfiguration`. For more information, including * details on header value syntax, see the documentation on :ref:`custom request headers * `. */ @@ -250,8 +250,8 @@ export interface VirtualHost__Output { /** * Specifies a list of HTTP headers that should be added to each response * handled by this virtual host. Headers specified at this level are applied - * after headers from enclosed :ref:`envoy_api_msg_config.route.v3.Route` and before headers from the - * enclosing :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including + * after headers from enclosed :ref:`envoy_v3_api_msg_config.route.v3.Route` and before headers from the + * enclosing :ref:`envoy_v3_api_msg_config.route.v3.RouteConfiguration`. For more information, including * details on header value syntax, see the documentation on :ref:`custom request headers * `. */ @@ -274,7 +274,7 @@ export interface VirtualHost__Output { * will see the attempt count as perceived by the second Envoy. Defaults to false. * This header is unaffected by the * :ref:`suppress_envoy_headers - * ` flag. + * ` flag. * * [#next-major-version: rename to include_attempt_count_in_request.] */ @@ -286,7 +286,7 @@ export interface VirtualHost__Output { * specific; see the :ref:`HTTP filter documentation ` * for if and how it is utilized. * [#comment: An entry's value may be wrapped in a - * :ref:`FilterConfig` + * :ref:`FilterConfig` * message to specify additional options.] */ 'typed_per_filter_config': ({[key: string]: _google_protobuf_Any__Output}); @@ -316,14 +316,14 @@ export interface VirtualHost__Output { * will see the attempt count as perceived by the Envoy closest upstream from itself. Defaults to false. * This header is unaffected by the * :ref:`suppress_envoy_headers - * ` flag. + * ` flag. */ 'include_attempt_count_in_response': (boolean); /** * [#not-implemented-hide:] * Specifies the configuration for retry policy extension. Note that setting a route level entry * will take precedence over this config and it'll be treated independently (e.g.: values are not - * inherited). :ref:`Retry policy ` should not be + * inherited). :ref:`Retry policy ` should not be * set if this field is used. */ 'retry_policy_typed_config': (_google_protobuf_Any__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 02edc0243..e734073be 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 @@ -6,17 +6,37 @@ import type { HeaderValueOption as _envoy_config_core_v3_HeaderValueOption, Head import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; /** - * [#next-free-field: 11] + * [#next-free-field: 13] */ export interface _envoy_config_route_v3_WeightedCluster_ClusterWeight { /** + * Only one of *name* and *cluster_header* may be specified. + * [#next-major-version: Need to add back the validation rule: (validate.rules).string = {min_len: 1}] * Name of the upstream cluster. The cluster must exist in the * :ref:`cluster manager configuration `. */ 'name'?: (string); + /** + * Only one of *name* and *cluster_header* may be specified. + * [#next-major-version: Need to add back the validation rule: (validate.rules).string = {min_len: 1 }] + * Envoy will determine the cluster to route to by reading the value of the + * HTTP header named by cluster_header from the request headers. If the + * header is not found or the referenced cluster does not exist, Envoy will + * return a 404 response. + * + * .. attention:: + * + * Internally, Envoy always uses the HTTP/2 *:authority* header to represent the HTTP/1 + * *Host* header. Thus, if attempting to match on *Host*, match on *:authority* instead. + * + * .. note:: + * + * If the header appears multiple times only the first value is used. + */ + 'cluster_header'?: (string); /** * An integer between 0 and :ref:`total_weight - * `. When a request matches the route, + * `. When a request matches the route, * the choice of an upstream cluster is determined by its weight. The sum of weights across all * entries in the clusters array must add up to the total_weight, which defaults to 100. */ @@ -25,38 +45,38 @@ export interface _envoy_config_route_v3_WeightedCluster_ClusterWeight { * Optional endpoint metadata match criteria used by the subset load balancer. Only endpoints in * the upstream cluster with metadata matching what is set in this field will be considered for * load balancing. Note that this will be merged with what's provided in - * :ref:`RouteAction.metadata_match `, with + * :ref:`RouteAction.metadata_match `, with * values here taking precedence. The filter name should be specified as *envoy.lb*. */ 'metadata_match'?: (_envoy_config_core_v3_Metadata | null); /** * Specifies a list of headers to be added to requests when this cluster is selected - * through the enclosing :ref:`envoy_api_msg_config.route.v3.RouteAction`. + * through the enclosing :ref:`envoy_v3_api_msg_config.route.v3.RouteAction`. * Headers specified at this level are applied before headers from the enclosing - * :ref:`envoy_api_msg_config.route.v3.Route`, :ref:`envoy_api_msg_config.route.v3.VirtualHost`, and - * :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including details on + * :ref:`envoy_v3_api_msg_config.route.v3.Route`, :ref:`envoy_v3_api_msg_config.route.v3.VirtualHost`, and + * :ref:`envoy_v3_api_msg_config.route.v3.RouteConfiguration`. For more information, including details on * header value syntax, see the documentation on :ref:`custom request headers * `. */ 'request_headers_to_add'?: (_envoy_config_core_v3_HeaderValueOption)[]; /** * Specifies a list of HTTP headers that should be removed from each request when - * this cluster is selected through the enclosing :ref:`envoy_api_msg_config.route.v3.RouteAction`. + * this cluster is selected through the enclosing :ref:`envoy_v3_api_msg_config.route.v3.RouteAction`. */ 'request_headers_to_remove'?: (string)[]; /** * Specifies a list of headers to be added to responses when this cluster is selected - * through the enclosing :ref:`envoy_api_msg_config.route.v3.RouteAction`. + * through the enclosing :ref:`envoy_v3_api_msg_config.route.v3.RouteAction`. * Headers specified at this level are applied before headers from the enclosing - * :ref:`envoy_api_msg_config.route.v3.Route`, :ref:`envoy_api_msg_config.route.v3.VirtualHost`, and - * :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including details on + * :ref:`envoy_v3_api_msg_config.route.v3.Route`, :ref:`envoy_v3_api_msg_config.route.v3.VirtualHost`, and + * :ref:`envoy_v3_api_msg_config.route.v3.RouteConfiguration`. For more information, including details on * header value syntax, see the documentation on :ref:`custom request headers * `. */ 'response_headers_to_add'?: (_envoy_config_core_v3_HeaderValueOption)[]; /** * Specifies a list of headers to be removed from responses when this cluster is selected - * through the enclosing :ref:`envoy_api_msg_config.route.v3.RouteAction`. + * through the enclosing :ref:`envoy_v3_api_msg_config.route.v3.RouteAction`. */ 'response_headers_to_remove'?: (string)[]; /** @@ -66,24 +86,50 @@ export interface _envoy_config_route_v3_WeightedCluster_ClusterWeight { * specific; see the :ref:`HTTP filter documentation ` * for if and how it is utilized. * [#comment: An entry's value may be wrapped in a - * :ref:`FilterConfig` + * :ref:`FilterConfig` * message to specify additional options.] */ 'typed_per_filter_config'?: ({[key: string]: _google_protobuf_Any}); + /** + * Indicates that during forwarding, the host header will be swapped with + * this value. + */ + 'host_rewrite_literal'?: (string); + 'host_rewrite_specifier'?: "host_rewrite_literal"; } /** - * [#next-free-field: 11] + * [#next-free-field: 13] */ export interface _envoy_config_route_v3_WeightedCluster_ClusterWeight__Output { /** + * Only one of *name* and *cluster_header* may be specified. + * [#next-major-version: Need to add back the validation rule: (validate.rules).string = {min_len: 1}] * Name of the upstream cluster. The cluster must exist in the * :ref:`cluster manager configuration `. */ 'name': (string); + /** + * Only one of *name* and *cluster_header* may be specified. + * [#next-major-version: Need to add back the validation rule: (validate.rules).string = {min_len: 1 }] + * Envoy will determine the cluster to route to by reading the value of the + * HTTP header named by cluster_header from the request headers. If the + * header is not found or the referenced cluster does not exist, Envoy will + * return a 404 response. + * + * .. attention:: + * + * Internally, Envoy always uses the HTTP/2 *:authority* header to represent the HTTP/1 + * *Host* header. Thus, if attempting to match on *Host*, match on *:authority* instead. + * + * .. note:: + * + * If the header appears multiple times only the first value is used. + */ + 'cluster_header': (string); /** * An integer between 0 and :ref:`total_weight - * `. When a request matches the route, + * `. When a request matches the route, * the choice of an upstream cluster is determined by its weight. The sum of weights across all * entries in the clusters array must add up to the total_weight, which defaults to 100. */ @@ -92,38 +138,38 @@ export interface _envoy_config_route_v3_WeightedCluster_ClusterWeight__Output { * Optional endpoint metadata match criteria used by the subset load balancer. Only endpoints in * the upstream cluster with metadata matching what is set in this field will be considered for * load balancing. Note that this will be merged with what's provided in - * :ref:`RouteAction.metadata_match `, with + * :ref:`RouteAction.metadata_match `, with * values here taking precedence. The filter name should be specified as *envoy.lb*. */ 'metadata_match': (_envoy_config_core_v3_Metadata__Output | null); /** * Specifies a list of headers to be added to requests when this cluster is selected - * through the enclosing :ref:`envoy_api_msg_config.route.v3.RouteAction`. + * through the enclosing :ref:`envoy_v3_api_msg_config.route.v3.RouteAction`. * Headers specified at this level are applied before headers from the enclosing - * :ref:`envoy_api_msg_config.route.v3.Route`, :ref:`envoy_api_msg_config.route.v3.VirtualHost`, and - * :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including details on + * :ref:`envoy_v3_api_msg_config.route.v3.Route`, :ref:`envoy_v3_api_msg_config.route.v3.VirtualHost`, and + * :ref:`envoy_v3_api_msg_config.route.v3.RouteConfiguration`. For more information, including details on * header value syntax, see the documentation on :ref:`custom request headers * `. */ 'request_headers_to_add': (_envoy_config_core_v3_HeaderValueOption__Output)[]; /** * Specifies a list of HTTP headers that should be removed from each request when - * this cluster is selected through the enclosing :ref:`envoy_api_msg_config.route.v3.RouteAction`. + * this cluster is selected through the enclosing :ref:`envoy_v3_api_msg_config.route.v3.RouteAction`. */ 'request_headers_to_remove': (string)[]; /** * Specifies a list of headers to be added to responses when this cluster is selected - * through the enclosing :ref:`envoy_api_msg_config.route.v3.RouteAction`. + * through the enclosing :ref:`envoy_v3_api_msg_config.route.v3.RouteAction`. * Headers specified at this level are applied before headers from the enclosing - * :ref:`envoy_api_msg_config.route.v3.Route`, :ref:`envoy_api_msg_config.route.v3.VirtualHost`, and - * :ref:`envoy_api_msg_config.route.v3.RouteConfiguration`. For more information, including details on + * :ref:`envoy_v3_api_msg_config.route.v3.Route`, :ref:`envoy_v3_api_msg_config.route.v3.VirtualHost`, and + * :ref:`envoy_v3_api_msg_config.route.v3.RouteConfiguration`. For more information, including details on * header value syntax, see the documentation on :ref:`custom request headers * `. */ 'response_headers_to_add': (_envoy_config_core_v3_HeaderValueOption__Output)[]; /** * Specifies a list of headers to be removed from responses when this cluster is selected - * through the enclosing :ref:`envoy_api_msg_config.route.v3.RouteAction`. + * through the enclosing :ref:`envoy_v3_api_msg_config.route.v3.RouteAction`. */ 'response_headers_to_remove': (string)[]; /** @@ -133,16 +179,22 @@ export interface _envoy_config_route_v3_WeightedCluster_ClusterWeight__Output { * specific; see the :ref:`HTTP filter documentation ` * for if and how it is utilized. * [#comment: An entry's value may be wrapped in a - * :ref:`FilterConfig` + * :ref:`FilterConfig` * message to specify additional options.] */ 'typed_per_filter_config': ({[key: string]: _google_protobuf_Any__Output}); + /** + * Indicates that during forwarding, the host header will be swapped with + * this value. + */ + 'host_rewrite_literal'?: (string); + 'host_rewrite_specifier': "host_rewrite_literal"; } /** - * Compared to the :ref:`cluster ` field that specifies a + * Compared to the :ref:`cluster ` field that specifies a * single upstream cluster as the target of a request, the :ref:`weighted_clusters - * ` option allows for specification of + * ` option allows for specification of * multiple upstream clusters along with weights that indicate the percentage of * traffic to be forwarded to each cluster. The router selects an upstream cluster based on the * weights. @@ -171,9 +223,9 @@ export interface WeightedCluster { } /** - * Compared to the :ref:`cluster ` field that specifies a + * Compared to the :ref:`cluster ` field that specifies a * single upstream cluster as the target of a request, the :ref:`weighted_clusters - * ` option allows for specification of + * ` option allows for specification of * multiple upstream clusters along with weights that indicate the percentage of * traffic to be forwarded to each cluster. The router selects an upstream cluster based on the * weights. diff --git a/packages/grpc-js-xds/src/generated/envoy/config/trace/v3/Tracing.ts b/packages/grpc-js-xds/src/generated/envoy/config/trace/v3/Tracing.ts index 95b161939..9b9859bc5 100644 --- a/packages/grpc-js-xds/src/generated/envoy/config/trace/v3/Tracing.ts +++ b/packages/grpc-js-xds/src/generated/envoy/config/trace/v3/Tracing.ts @@ -6,34 +6,21 @@ import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__ * Configuration for an HTTP tracer provider used by Envoy. * * The configuration is defined by the - * :ref:`HttpConnectionManager.Tracing ` - * :ref:`provider ` + * :ref:`HttpConnectionManager.Tracing ` + * :ref:`provider ` * field. */ export interface _envoy_config_trace_v3_Tracing_Http { /** * The name of the HTTP trace driver to instantiate. The name must match a - * supported HTTP trace driver. Built-in trace drivers: - * - * - *envoy.tracers.lightstep* - * - *envoy.tracers.zipkin* - * - *envoy.tracers.dynamic_ot* - * - *envoy.tracers.datadog* - * - *envoy.tracers.opencensus* - * - *envoy.tracers.xray* + * supported HTTP trace driver. + * See the :ref:`extensions listed in typed_config below ` for the default list of the HTTP trace driver. */ 'name'?: (string); 'typed_config'?: (_google_protobuf_Any | null); /** - * Trace driver specific configuration which depends on the driver being instantiated. - * See the trace drivers for examples: - * - * - :ref:`LightstepConfig ` - * - :ref:`ZipkinConfig ` - * - :ref:`DynamicOtConfig ` - * - :ref:`DatadogConfig ` - * - :ref:`OpenCensusConfig ` - * - :ref:`AWS X-Ray ` + * Trace driver specific configuration which must be set according to the driver being instantiated. + * [#extension-category: envoy.tracers] */ 'config_type'?: "typed_config"; } @@ -42,34 +29,21 @@ export interface _envoy_config_trace_v3_Tracing_Http { * Configuration for an HTTP tracer provider used by Envoy. * * The configuration is defined by the - * :ref:`HttpConnectionManager.Tracing ` - * :ref:`provider ` + * :ref:`HttpConnectionManager.Tracing ` + * :ref:`provider ` * field. */ export interface _envoy_config_trace_v3_Tracing_Http__Output { /** * The name of the HTTP trace driver to instantiate. The name must match a - * supported HTTP trace driver. Built-in trace drivers: - * - * - *envoy.tracers.lightstep* - * - *envoy.tracers.zipkin* - * - *envoy.tracers.dynamic_ot* - * - *envoy.tracers.datadog* - * - *envoy.tracers.opencensus* - * - *envoy.tracers.xray* + * supported HTTP trace driver. + * See the :ref:`extensions listed in typed_config below ` for the default list of the HTTP trace driver. */ 'name': (string); 'typed_config'?: (_google_protobuf_Any__Output | null); /** - * Trace driver specific configuration which depends on the driver being instantiated. - * See the trace drivers for examples: - * - * - :ref:`LightstepConfig ` - * - :ref:`ZipkinConfig ` - * - :ref:`DynamicOtConfig ` - * - :ref:`DatadogConfig ` - * - :ref:`OpenCensusConfig ` - * - :ref:`AWS X-Ray ` + * Trace driver specific configuration which must be set according to the driver being instantiated. + * [#extension-category: envoy.tracers] */ 'config_type': "typed_config"; } @@ -83,7 +57,7 @@ export interface _envoy_config_trace_v3_Tracing_Http__Output { * .. attention:: * * Use of this message type has been deprecated in favor of direct use of - * :ref:`Tracing.Http `. + * :ref:`Tracing.Http `. */ export interface Tracing { /** @@ -101,7 +75,7 @@ export interface Tracing { * .. attention:: * * Use of this message type has been deprecated in favor of direct use of - * :ref:`Tracing.Http `. + * :ref:`Tracing.Http `. */ export interface Tracing__Output { /** 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 8e2739958..bec0403e4 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 @@ -30,17 +30,16 @@ export interface _envoy_extensions_filters_common_fault_v3_FaultDelay_HeaderDela /** * Delay specification is used to inject latency into the - * HTTP/gRPC/Mongo/Redis operation or delay proxying of TCP connections. + * HTTP/Mongo operation. * [#next-free-field: 6] */ export interface FaultDelay { /** * Add a fixed delay before forwarding the operation upstream. See * https://developers.google.com/protocol-buffers/docs/proto3#json for - * the JSON/YAML Duration mapping. For HTTP/Mongo/Redis, the specified - * delay will be injected before a new request/operation. For TCP - * connections, the proxying of the connection upstream will be delayed - * for the specified period. This is required if type is FIXED. + * the JSON/YAML Duration mapping. For HTTP/Mongo, the specified + * delay will be injected before a new request/operation. + * This is required if type is FIXED. */ 'fixed_delay'?: (_google_protobuf_Duration | null); /** @@ -56,17 +55,16 @@ export interface FaultDelay { /** * Delay specification is used to inject latency into the - * HTTP/gRPC/Mongo/Redis operation or delay proxying of TCP connections. + * HTTP/Mongo operation. * [#next-free-field: 6] */ export interface FaultDelay__Output { /** * Add a fixed delay before forwarding the operation upstream. See * https://developers.google.com/protocol-buffers/docs/proto3#json for - * the JSON/YAML Duration mapping. For HTTP/Mongo/Redis, the specified - * delay will be injected before a new request/operation. For TCP - * connections, the proxying of the connection upstream will be delayed - * for the specified period. This is required if type is FIXED. + * the JSON/YAML Duration mapping. For HTTP/Mongo, the specified + * delay will be injected before a new request/operation. + * This is required if type is FIXED. */ 'fixed_delay'?: (_google_protobuf_Duration__Output | null); /** diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/http/fault/v3/HTTPFault.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/http/fault/v3/HTTPFault.ts index 20c543508..d78bd9e4a 100644 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/http/fault/v3/HTTPFault.ts +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/http/fault/v3/HTTPFault.ts @@ -7,7 +7,7 @@ import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output a import type { FaultRateLimit as _envoy_extensions_filters_common_fault_v3_FaultRateLimit, FaultRateLimit__Output as _envoy_extensions_filters_common_fault_v3_FaultRateLimit__Output } from '../../../../../../envoy/extensions/filters/common/fault/v3/FaultRateLimit'; /** - * [#next-free-field: 15] + * [#next-free-field: 16] */ export interface HTTPFault { /** @@ -31,7 +31,7 @@ export interface HTTPFault { * injection filter can be applied selectively to requests that match a set of * headers specified in the fault filter config. The chances of actual fault * injection further depend on the value of the :ref:`percentage - * ` field. + * ` field. * The filter will check the request's headers against all the specified * headers in the filter config. A match will happen if all the headers in the * config are present in the request with the same values (or based on @@ -107,10 +107,17 @@ export interface HTTPFault { * runtime. The default is: fault.http.abort.grpc_status */ 'abort_grpc_status_runtime'?: (string); + /** + * To control whether stats storage is allocated dynamically for each downstream server. + * If set to true, "x-envoy-downstream-service-cluster" field of header will be ignored by this filter. + * If set to false, dynamic stats storage will be allocated for the downstream cluster name. + * Default value is false. + */ + 'disable_downstream_cluster_stats'?: (boolean); } /** - * [#next-free-field: 15] + * [#next-free-field: 16] */ export interface HTTPFault__Output { /** @@ -134,7 +141,7 @@ export interface HTTPFault__Output { * injection filter can be applied selectively to requests that match a set of * headers specified in the fault filter config. The chances of actual fault * injection further depend on the value of the :ref:`percentage - * ` field. + * ` field. * The filter will check the request's headers against all the specified * headers in the filter config. A match will happen if all the headers in the * config are present in the request with the same values (or based on @@ -210,4 +217,11 @@ export interface HTTPFault__Output { * runtime. The default is: fault.http.abort.grpc_status */ 'abort_grpc_status_runtime': (string); + /** + * To control whether stats storage is allocated dynamically for each downstream server. + * If set to true, "x-envoy-downstream-service-cluster" field of header will be ignored by this filter. + * If set to false, dynamic stats storage will be allocated for the downstream cluster name. + * Default value is false. + */ + 'disable_downstream_cluster_stats': (boolean); } diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/EnvoyMobileHttpConnectionManager.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/EnvoyMobileHttpConnectionManager.ts new file mode 100644 index 000000000..eb73721c3 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/EnvoyMobileHttpConnectionManager.ts @@ -0,0 +1,29 @@ +// Original file: deps/envoy-api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto + +import type { HttpConnectionManager as _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager, HttpConnectionManager__Output as _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager__Output } from '../../../../../../envoy/extensions/filters/network/http_connection_manager/v3/HttpConnectionManager'; + +/** + * [#protodoc-title: Envoy Mobile HTTP connection manager] + * HTTP connection manager for use in Envoy mobile. + * [#extension: envoy.filters.network.envoy_mobile_http_connection_manager] + */ +export interface EnvoyMobileHttpConnectionManager { + /** + * The configuration for the underlying HttpConnectionManager which will be + * instantiated for Envoy mobile. + */ + 'config'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager | null); +} + +/** + * [#protodoc-title: Envoy Mobile HTTP connection manager] + * HTTP connection manager for use in Envoy mobile. + * [#extension: envoy.filters.network.envoy_mobile_http_connection_manager] + */ +export interface EnvoyMobileHttpConnectionManager__Output { + /** + * The configuration for the underlying HttpConnectionManager which will be + * instantiated for Envoy mobile. + */ + 'config': (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager__Output | null); +} 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 4a8912599..fdf7084fe 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 @@ -13,9 +13,13 @@ import type { ScopedRoutes as _envoy_extensions_filters_network_http_connection_ import type { HttpProtocolOptions as _envoy_config_core_v3_HttpProtocolOptions, HttpProtocolOptions__Output as _envoy_config_core_v3_HttpProtocolOptions__Output } from '../../../../../../envoy/config/core/v3/HttpProtocolOptions'; import type { RequestIDExtension as _envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension, RequestIDExtension__Output as _envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension__Output } from '../../../../../../envoy/extensions/filters/network/http_connection_manager/v3/RequestIDExtension'; import type { LocalReplyConfig as _envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig, LocalReplyConfig__Output as _envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig__Output } from '../../../../../../envoy/extensions/filters/network/http_connection_manager/v3/LocalReplyConfig'; +import type { Http3ProtocolOptions as _envoy_config_core_v3_Http3ProtocolOptions, Http3ProtocolOptions__Output as _envoy_config_core_v3_Http3ProtocolOptions__Output } from '../../../../../../envoy/config/core/v3/Http3ProtocolOptions'; +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 { SchemeHeaderTransformation as _envoy_config_core_v3_SchemeHeaderTransformation, SchemeHeaderTransformation__Output as _envoy_config_core_v3_SchemeHeaderTransformation__Output } from '../../../../../../envoy/config/core/v3/SchemeHeaderTransformation'; import type { Percent as _envoy_type_v3_Percent, Percent__Output as _envoy_type_v3_Percent__Output } from '../../../../../../envoy/type/v3/Percent'; import type { CustomTag as _envoy_type_tracing_v3_CustomTag, CustomTag__Output as _envoy_type_tracing_v3_CustomTag__Output } from '../../../../../../envoy/type/tracing/v3/CustomTag'; import type { _envoy_config_trace_v3_Tracing_Http, _envoy_config_trace_v3_Tracing_Http__Output } from '../../../../../../envoy/config/trace/v3/Tracing'; +import type { PathTransformation as _envoy_type_http_v3_PathTransformation, PathTransformation__Output as _envoy_type_http_v3_PathTransformation__Output } from '../../../../../../envoy/type/http/v3/PathTransformation'; // Original file: deps/envoy-api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto @@ -106,6 +110,120 @@ export enum _envoy_extensions_filters_network_http_connection_manager_v3_HttpCon EGRESS = 1, } +/** + * [#not-implemented-hide:] Transformations that apply to path headers. Transformations are applied + * before any processing of requests by HTTP filters, routing, and matching. Only the normalized + * path will be visible internally if a transformation is enabled. Any path rewrites that the + * router performs (e.g. :ref:`regex_rewrite + * ` or :ref:`prefix_rewrite + * `) will apply to the *:path* header + * destined for the upstream. + * + * Note: access logging and tracing will show the original *:path* header. + */ +export interface _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_PathNormalizationOptions { + /** + * [#not-implemented-hide:] Normalization applies internally before any processing of requests by + * HTTP filters, routing, and matching *and* will affect the forwarded *:path* header. Defaults + * to :ref:`NormalizePathRFC3986 + * `. When not + * specified, this value may be overridden by the runtime variable + * :ref:`http_connection_manager.normalize_path`. + * Envoy will respond with 400 to paths that are malformed (e.g. for paths that fail RFC 3986 + * normalization due to disallowed characters.) + */ + 'forwarding_transformation'?: (_envoy_type_http_v3_PathTransformation | null); + /** + * [#not-implemented-hide:] Normalization only applies internally before any processing of + * requests by HTTP filters, routing, and matching. These will be applied after full + * transformation is applied. The *:path* header before this transformation will be restored in + * the router filter and sent upstream unless it was mutated by a filter. Defaults to no + * transformations. + * Multiple actions can be applied in the same Transformation, forming a sequential + * pipeline. The transformations will be performed in the order that they appear. Envoy will + * respond with 400 to paths that are malformed (e.g. for paths that fail RFC 3986 + * normalization due to disallowed characters.) + */ + 'http_filter_transformation'?: (_envoy_type_http_v3_PathTransformation | null); +} + +/** + * [#not-implemented-hide:] Transformations that apply to path headers. Transformations are applied + * before any processing of requests by HTTP filters, routing, and matching. Only the normalized + * path will be visible internally if a transformation is enabled. Any path rewrites that the + * router performs (e.g. :ref:`regex_rewrite + * ` or :ref:`prefix_rewrite + * `) will apply to the *:path* header + * destined for the upstream. + * + * Note: access logging and tracing will show the original *:path* header. + */ +export interface _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_PathNormalizationOptions__Output { + /** + * [#not-implemented-hide:] Normalization applies internally before any processing of requests by + * HTTP filters, routing, and matching *and* will affect the forwarded *:path* header. Defaults + * to :ref:`NormalizePathRFC3986 + * `. When not + * specified, this value may be overridden by the runtime variable + * :ref:`http_connection_manager.normalize_path`. + * Envoy will respond with 400 to paths that are malformed (e.g. for paths that fail RFC 3986 + * normalization due to disallowed characters.) + */ + 'forwarding_transformation': (_envoy_type_http_v3_PathTransformation__Output | null); + /** + * [#not-implemented-hide:] Normalization only applies internally before any processing of + * requests by HTTP filters, routing, and matching. These will be applied after full + * transformation is applied. The *:path* header before this transformation will be restored in + * the router filter and sent upstream unless it was mutated by a filter. Defaults to no + * transformations. + * Multiple actions can be applied in the same Transformation, forming a sequential + * pipeline. The transformations will be performed in the order that they appear. Envoy will + * respond with 400 to paths that are malformed (e.g. for paths that fail RFC 3986 + * normalization due to disallowed characters.) + */ + 'http_filter_transformation': (_envoy_type_http_v3_PathTransformation__Output | null); +} + +// Original file: deps/envoy-api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto + +/** + * 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 { + /** + * 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, +} + // 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 { @@ -346,7 +464,7 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Ht /** * Determines if upgrades are enabled or disabled by default. Defaults to true. * This can be overridden on a per-route basis with :ref:`cluster - * ` as documented in the + * ` as documented in the * :ref:`upgrade documentation `. */ 'enabled'?: (_google_protobuf_BoolValue | null); @@ -383,14 +501,14 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Ht /** * Determines if upgrades are enabled or disabled by default. Defaults to true. * This can be overridden on a per-route basis with :ref:`cluster - * ` as documented in the + * ` as documented in the * :ref:`upgrade documentation `. */ 'enabled': (_google_protobuf_BoolValue__Output | null); } /** - * [#next-free-field: 43] + * [#next-free-field: 49] */ export interface HttpConnectionManager { /** @@ -426,7 +544,7 @@ export interface HttpConnectionManager { /** * Presence of the object defines whether the connection manager * emits :ref:`tracing ` data to the :ref:`configured tracing provider - * `. + * `. */ 'tracing'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing | null); /** @@ -483,7 +601,7 @@ export interface HttpConnectionManager { '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); /** * This field is valid only when :ref:`forward_client_cert_details - * ` + * ` * is APPEND_FORWARD or SANITIZE_SET and the client connection is mTLS. It specifies the fields in * the client certificate to be forwarded. Note that in the * :ref:`config_http_conn_man_headers_x-forwarded-client-cert` header, *Hash* is always set, and @@ -509,7 +627,7 @@ export interface HttpConnectionManager { /** * If * :ref:`use_remote_address - * ` + * ` * is true and represent_ipv4_remote_address_as_ipv4_mapped_ipv6 is true and the remote address is * an IPv4 address, the address will be mapped to IPv6 before it is appended to *x-forwarded-for*. * This is useful for testing compatibility of upstream services that parse the header value. For @@ -527,7 +645,7 @@ export interface HttpConnectionManager { * :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP header. This may be used in * conjunction with HTTP filters that explicitly manipulate XFF after the HTTP connection manager * has mutated the request headers. While :ref:`use_remote_address - * ` + * ` * will also suppress XFF addition, it has consequences for logging and other * Envoy uses of the remote address, so *skip_xff_append* should be used * when only an elision of XFF addition is intended. @@ -548,10 +666,10 @@ export interface HttpConnectionManager { * * This idle timeout applies to new streams and is overridable by the * :ref:`route-level idle_timeout - * `. Even on a stream in + * `. Even on a stream in * which the override applies, prior to receipt of the initial request * headers, the :ref:`stream_idle_timeout - * ` + * ` * applies. Each time an encode/decode event for headers or data is processed * for the stream, the timer will be reset. If the timeout fires, the stream * is terminated with a 408 Request Timeout error code if no upstream response @@ -564,12 +682,12 @@ export interface HttpConnectionManager { * data has been proxied within available flow control windows. If the timeout is hit in this * case, the :ref:`tx_flush_timeout ` counter will be * incremented. Note that :ref:`max_stream_duration - * ` does not apply to + * ` does not apply to * this corner case. * * If the :ref:`overload action ` "envoy.overload_actions.reduce_timeouts" * is configured, this timeout is scaled according to the value for - * :ref:`HTTP_DOWNSTREAM_STREAM_IDLE `. + * :ref:`HTTP_DOWNSTREAM_STREAM_IDLE `. * * Note that it is possible to idle timeout even if the wire traffic for a stream is non-idle, due * to the granularity of events presented to the connection manager. For example, while receiving @@ -632,8 +750,6 @@ export interface HttpConnectionManager { * The maximum request headers size for incoming connections. * If unconfigured, the default max request headers allowed is 60 KiB. * Requests that exceed this limit will receive a 431 response. - * The max configurable limit is 96 KiB, based on current implementation - * constraints. */ 'max_request_headers_kb'?: (_google_protobuf_UInt32Value | null); /** @@ -684,15 +800,21 @@ export interface HttpConnectionManager { 'common_http_protocol_options'?: (_envoy_config_core_v3_HttpProtocolOptions | null); /** * The configuration of the request ID extension. This includes operations such as - * generation, validation, and associated tracing operations. - * - * If not set, Envoy uses the default UUID-based behavior: + * generation, validation, and associated tracing operations. If empty, the + * :ref:`UuidRequestIdConfig ` + * default extension is used with default parameters. See the documentation for that extension + * for details on what it does. Customizing the configuration for the default extension can be + * achieved by configuring it explicitly here. For example, to disable trace reason packing, + * the following configuration can be used: * - * 1. Request ID is propagated using *x-request-id* header. + * .. validated-code-block:: yaml + * :type-name: envoy.extensions.filters.network.http_connection_manager.v3.RequestIDExtension * - * 2. Request ID is a universally unique identifier (UUID). + * typed_config: + * "@type": type.googleapis.com/envoy.extensions.request_id.uuid.v3.UuidRequestIdConfig + * pack_trace_reason: false * - * 3. Tracing decision (sampled, forced, etc) is set in 14th byte of the UUID. + * [#extension-category: envoy.request_id] */ 'request_id_extension'?: (_envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension | null); /** @@ -709,10 +831,12 @@ export interface HttpConnectionManager { 'local_reply_config'?: (_envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig | null); /** * Determines if the port part should be removed from host/authority header before any processing - * of request by HTTP filters or routing. The port would be removed only if it is equal to the :ref:`listener's` - * local port and request method is not CONNECT. This affects the upstream host header as well. + * of request by HTTP filters or routing. The port would be removed only if it is equal to the :ref:`listener's` + * local port. This affects the upstream host header unless the method is + * CONNECT in which case if no filter adds a port the original port will be restored before headers are + * sent upstream. * Without setting this option, incoming requests with host `example:443` will not match against - * route with :ref:`domains` match set to `example`. Defaults to `false`. Note that port removal is not part + * route with :ref:`domains` match set to `example`. Defaults to `false`. Note that port removal is not part * of `HTTP spec `_ and is provided for convenience. * Only one of `strip_matching_host_port` or `strip_any_host_port` can be set. */ @@ -744,20 +868,82 @@ export interface HttpConnectionManager { 'request_headers_timeout'?: (_google_protobuf_Duration | null); /** * Determines if the port part should be removed from host/authority header before any processing - * of request by HTTP filters or routing. The port would be removed only if request method is not CONNECT. - * This affects the upstream host header as well. + * of request by HTTP filters or routing. + * This affects the upstream host header unless the method is CONNECT in + * which case if no filter adds a port the original port will be restored before headers are sent upstream. * Without setting this option, incoming requests with host `example:443` will not match against - * route with :ref:`domains` match set to `example`. Defaults to `false`. Note that port removal is not part + * route with :ref:`domains` match set to `example`. Defaults to `false`. Note that port removal is not part * of `HTTP spec `_ and is provided for convenience. * Only one of `strip_matching_host_port` or `strip_any_host_port` can be set. */ 'strip_any_host_port'?: (boolean); + /** + * [#not-implemented-hide:] Path normalization configuration. This includes + * configurations for transformations (e.g. RFC 3986 normalization or merge + * adjacent slashes) and the policy to apply them. The policy determines + * whether transformations affect the forwarded *:path* header. RFC 3986 path + * normalization is enabled by default and the default policy is that the + * normalized header will be forwarded. See :ref:`PathNormalizationOptions + * ` + * for details. + */ + 'path_normalization_options'?: (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_PathNormalizationOptions | null); + /** + * Additional HTTP/3 settings that are passed directly to the HTTP/3 codec. + * [#not-implemented-hide:] + */ + 'http3_protocol_options'?: (_envoy_config_core_v3_Http3ProtocolOptions | null); + /** + * Action to take when request URL path contains escaped slash sequences (%2F, %2f, %5C and %5c). + * The default value can be overridden by the :ref:`http_connection_manager.path_with_escaped_slashes_action` + * runtime variable. + * The :ref:`http_connection_manager.path_with_escaped_slashes_action_sampling` runtime + * variable can be used to apply the action to a portion of all requests. + */ + '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); + /** + * The configuration for the original IP detection extensions. + * + * When configured the extensions will be called along with the request headers + * and information about the downstream connection, such as the directly connected address. + * Each extension will then use these parameters to decide the request's effective remote address. + * If an extension fails to detect the original IP address and isn't configured to reject + * the request, the HCM will try the remaining extensions until one succeeds or rejects + * the request. If the request isn't rejected nor any extension succeeds, the HCM will + * fallback to using the remote address. + * + * .. WARNING:: + * Extensions cannot be used in conjunction with :ref:`use_remote_address + * ` + * nor :ref:`xff_num_trusted_hops + * `. + * + * [#extension-category: envoy.http.original_ip_detection] + */ + 'original_ip_detection_extensions'?: (_envoy_config_core_v3_TypedExtensionConfig)[]; + /** + * Determines if trailing dot of the host should be removed from host/authority header before any + * processing of request by HTTP filters or routing. + * This affects the upstream host header. + * Without setting this option, incoming requests with host `example.com.` will not match against + * route with :ref:`domains` match set to `example.com`. Defaults to `false`. + * When the incoming request contains a host/authority header that includes a port number, + * setting this option will strip a trailing dot, if present, from the host section, + * leaving the port as is (e.g. host value `example.com.:443` will be updated to `example.com:443`). + */ + 'strip_trailing_host_dot'?: (boolean); + /** + * Allows for explicit transformation of the :scheme header on the request path. + * If not set, Envoy's default :ref:`scheme ` + * handling applies. + */ + 'scheme_header_transformation'?: (_envoy_config_core_v3_SchemeHeaderTransformation | null); 'route_specifier'?: "rds"|"route_config"|"scoped_routes"; 'strip_port_mode'?: "strip_any_host_port"; } /** - * [#next-free-field: 43] + * [#next-free-field: 49] */ export interface HttpConnectionManager__Output { /** @@ -793,7 +979,7 @@ export interface HttpConnectionManager__Output { /** * Presence of the object defines whether the connection manager * emits :ref:`tracing ` data to the :ref:`configured tracing provider - * `. + * `. */ 'tracing': (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_Tracing__Output | null); /** @@ -850,7 +1036,7 @@ export interface HttpConnectionManager__Output { 'forward_client_cert_details': (keyof typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_ForwardClientCertDetails); /** * This field is valid only when :ref:`forward_client_cert_details - * ` + * ` * is APPEND_FORWARD or SANITIZE_SET and the client connection is mTLS. It specifies the fields in * the client certificate to be forwarded. Note that in the * :ref:`config_http_conn_man_headers_x-forwarded-client-cert` header, *Hash* is always set, and @@ -876,7 +1062,7 @@ export interface HttpConnectionManager__Output { /** * If * :ref:`use_remote_address - * ` + * ` * is true and represent_ipv4_remote_address_as_ipv4_mapped_ipv6 is true and the remote address is * an IPv4 address, the address will be mapped to IPv6 before it is appended to *x-forwarded-for*. * This is useful for testing compatibility of upstream services that parse the header value. For @@ -894,7 +1080,7 @@ export interface HttpConnectionManager__Output { * :ref:`config_http_conn_man_headers_x-forwarded-for` HTTP header. This may be used in * conjunction with HTTP filters that explicitly manipulate XFF after the HTTP connection manager * has mutated the request headers. While :ref:`use_remote_address - * ` + * ` * will also suppress XFF addition, it has consequences for logging and other * Envoy uses of the remote address, so *skip_xff_append* should be used * when only an elision of XFF addition is intended. @@ -915,10 +1101,10 @@ export interface HttpConnectionManager__Output { * * This idle timeout applies to new streams and is overridable by the * :ref:`route-level idle_timeout - * `. Even on a stream in + * `. Even on a stream in * which the override applies, prior to receipt of the initial request * headers, the :ref:`stream_idle_timeout - * ` + * ` * applies. Each time an encode/decode event for headers or data is processed * for the stream, the timer will be reset. If the timeout fires, the stream * is terminated with a 408 Request Timeout error code if no upstream response @@ -931,12 +1117,12 @@ export interface HttpConnectionManager__Output { * data has been proxied within available flow control windows. If the timeout is hit in this * case, the :ref:`tx_flush_timeout ` counter will be * incremented. Note that :ref:`max_stream_duration - * ` does not apply to + * ` does not apply to * this corner case. * * If the :ref:`overload action ` "envoy.overload_actions.reduce_timeouts" * is configured, this timeout is scaled according to the value for - * :ref:`HTTP_DOWNSTREAM_STREAM_IDLE `. + * :ref:`HTTP_DOWNSTREAM_STREAM_IDLE `. * * Note that it is possible to idle timeout even if the wire traffic for a stream is non-idle, due * to the granularity of events presented to the connection manager. For example, while receiving @@ -999,8 +1185,6 @@ export interface HttpConnectionManager__Output { * The maximum request headers size for incoming connections. * If unconfigured, the default max request headers allowed is 60 KiB. * Requests that exceed this limit will receive a 431 response. - * The max configurable limit is 96 KiB, based on current implementation - * constraints. */ 'max_request_headers_kb': (_google_protobuf_UInt32Value__Output | null); /** @@ -1051,15 +1235,21 @@ export interface HttpConnectionManager__Output { 'common_http_protocol_options': (_envoy_config_core_v3_HttpProtocolOptions__Output | null); /** * The configuration of the request ID extension. This includes operations such as - * generation, validation, and associated tracing operations. + * generation, validation, and associated tracing operations. If empty, the + * :ref:`UuidRequestIdConfig ` + * default extension is used with default parameters. See the documentation for that extension + * for details on what it does. Customizing the configuration for the default extension can be + * achieved by configuring it explicitly here. For example, to disable trace reason packing, + * the following configuration can be used: * - * If not set, Envoy uses the default UUID-based behavior: + * .. validated-code-block:: yaml + * :type-name: envoy.extensions.filters.network.http_connection_manager.v3.RequestIDExtension * - * 1. Request ID is propagated using *x-request-id* header. + * typed_config: + * "@type": type.googleapis.com/envoy.extensions.request_id.uuid.v3.UuidRequestIdConfig + * pack_trace_reason: false * - * 2. Request ID is a universally unique identifier (UUID). - * - * 3. Tracing decision (sampled, forced, etc) is set in 14th byte of the UUID. + * [#extension-category: envoy.request_id] */ 'request_id_extension': (_envoy_extensions_filters_network_http_connection_manager_v3_RequestIDExtension__Output | null); /** @@ -1076,10 +1266,12 @@ export interface HttpConnectionManager__Output { 'local_reply_config': (_envoy_extensions_filters_network_http_connection_manager_v3_LocalReplyConfig__Output | null); /** * Determines if the port part should be removed from host/authority header before any processing - * of request by HTTP filters or routing. The port would be removed only if it is equal to the :ref:`listener's` - * local port and request method is not CONNECT. This affects the upstream host header as well. + * of request by HTTP filters or routing. The port would be removed only if it is equal to the :ref:`listener's` + * local port. This affects the upstream host header unless the method is + * CONNECT in which case if no filter adds a port the original port will be restored before headers are + * sent upstream. * Without setting this option, incoming requests with host `example:443` will not match against - * route with :ref:`domains` match set to `example`. Defaults to `false`. Note that port removal is not part + * route with :ref:`domains` match set to `example`. Defaults to `false`. Note that port removal is not part * of `HTTP spec `_ and is provided for convenience. * Only one of `strip_matching_host_port` or `strip_any_host_port` can be set. */ @@ -1111,14 +1303,76 @@ export interface HttpConnectionManager__Output { 'request_headers_timeout': (_google_protobuf_Duration__Output | null); /** * Determines if the port part should be removed from host/authority header before any processing - * of request by HTTP filters or routing. The port would be removed only if request method is not CONNECT. - * This affects the upstream host header as well. + * of request by HTTP filters or routing. + * This affects the upstream host header unless the method is CONNECT in + * which case if no filter adds a port the original port will be restored before headers are sent upstream. * Without setting this option, incoming requests with host `example:443` will not match against - * route with :ref:`domains` match set to `example`. Defaults to `false`. Note that port removal is not part + * route with :ref:`domains` match set to `example`. Defaults to `false`. Note that port removal is not part * of `HTTP spec `_ and is provided for convenience. * Only one of `strip_matching_host_port` or `strip_any_host_port` can be set. */ 'strip_any_host_port'?: (boolean); + /** + * [#not-implemented-hide:] Path normalization configuration. This includes + * configurations for transformations (e.g. RFC 3986 normalization or merge + * adjacent slashes) and the policy to apply them. The policy determines + * whether transformations affect the forwarded *:path* header. RFC 3986 path + * normalization is enabled by default and the default policy is that the + * normalized header will be forwarded. See :ref:`PathNormalizationOptions + * ` + * for details. + */ + 'path_normalization_options': (_envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_PathNormalizationOptions__Output | null); + /** + * Additional HTTP/3 settings that are passed directly to the HTTP/3 codec. + * [#not-implemented-hide:] + */ + 'http3_protocol_options': (_envoy_config_core_v3_Http3ProtocolOptions__Output | null); + /** + * Action to take when request URL path contains escaped slash sequences (%2F, %2f, %5C and %5c). + * The default value can be overridden by the :ref:`http_connection_manager.path_with_escaped_slashes_action` + * runtime variable. + * The :ref:`http_connection_manager.path_with_escaped_slashes_action_sampling` runtime + * variable can be used to apply the action to a portion of all requests. + */ + 'path_with_escaped_slashes_action': (keyof typeof _envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_PathWithEscapedSlashesAction); + /** + * The configuration for the original IP detection extensions. + * + * When configured the extensions will be called along with the request headers + * and information about the downstream connection, such as the directly connected address. + * Each extension will then use these parameters to decide the request's effective remote address. + * If an extension fails to detect the original IP address and isn't configured to reject + * the request, the HCM will try the remaining extensions until one succeeds or rejects + * the request. If the request isn't rejected nor any extension succeeds, the HCM will + * fallback to using the remote address. + * + * .. WARNING:: + * Extensions cannot be used in conjunction with :ref:`use_remote_address + * ` + * nor :ref:`xff_num_trusted_hops + * `. + * + * [#extension-category: envoy.http.original_ip_detection] + */ + 'original_ip_detection_extensions': (_envoy_config_core_v3_TypedExtensionConfig__Output)[]; + /** + * Determines if trailing dot of the host should be removed from host/authority header before any + * processing of request by HTTP filters or routing. + * This affects the upstream host header. + * Without setting this option, incoming requests with host `example.com.` will not match against + * route with :ref:`domains` match set to `example.com`. Defaults to `false`. + * When the incoming request contains a host/authority header that includes a port number, + * setting this option will strip a trailing dot, if present, from the host section, + * leaving the port as is (e.g. host value `example.com.:443` will be updated to `example.com:443`). + */ + 'strip_trailing_host_dot': (boolean); + /** + * Allows for explicit transformation of the :scheme header on the request path. + * If not set, Envoy's default :ref:`scheme ` + * handling applies. + */ + 'scheme_header_transformation': (_envoy_config_core_v3_SchemeHeaderTransformation__Output | null); 'route_specifier': "rds"|"route_config"|"scoped_routes"; 'strip_port_mode': "strip_any_host_port"; } diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpFilter.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpFilter.ts index 42e4215d0..d1c1cbc06 100644 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpFilter.ts +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpFilter.ts @@ -16,19 +16,29 @@ export interface HttpFilter { /** * Filter specific configuration which depends on the filter being instantiated. See the supported * filters for further documentation. + * + * To support configuring a :ref:`match tree `, use an + * :ref:`ExtensionWithMatcher ` + * with the desired HTTP filter. + * [#extension-category: envoy.filters.http] */ 'typed_config'?: (_google_protobuf_Any | null); /** * Configuration source specifier for an extension configuration discovery service. * In case of a failure and without the default configuration, the HTTP listener responds with code 500. * Extension configs delivered through this mechanism are not expected to require warming (see https://github.com/envoyproxy/envoy/issues/12061). + * + * To support configuring a :ref:`match tree `, use an + * :ref:`ExtensionWithMatcher ` + * with the desired HTTP filter. This works for both the default filter configuration as well + * as for filters provided via the API. */ 'config_discovery'?: (_envoy_config_core_v3_ExtensionConfigSource | null); /** * If true, clients that do not support this filter may ignore the * filter but otherwise accept the config. * Otherwise, clients that do not support this filter must reject the config. - * [#not-implemented-hide:] + * This is also same with typed per filter config. */ 'is_optional'?: (boolean); 'config_type'?: "typed_config"|"config_discovery"; @@ -47,19 +57,29 @@ export interface HttpFilter__Output { /** * Filter specific configuration which depends on the filter being instantiated. See the supported * filters for further documentation. + * + * To support configuring a :ref:`match tree `, use an + * :ref:`ExtensionWithMatcher ` + * with the desired HTTP filter. + * [#extension-category: envoy.filters.http] */ 'typed_config'?: (_google_protobuf_Any__Output | null); /** * Configuration source specifier for an extension configuration discovery service. * In case of a failure and without the default configuration, the HTTP listener responds with code 500. * Extension configs delivered through this mechanism are not expected to require warming (see https://github.com/envoyproxy/envoy/issues/12061). + * + * To support configuring a :ref:`match tree `, use an + * :ref:`ExtensionWithMatcher ` + * with the desired HTTP filter. This works for both the default filter configuration as well + * as for filters provided via the API. */ 'config_discovery'?: (_envoy_config_core_v3_ExtensionConfigSource__Output | null); /** * If true, clients that do not support this filter may ignore the * filter but otherwise accept the config. * Otherwise, clients that do not support this filter must reject the config. - * [#not-implemented-hide:] + * This is also same with typed per filter config. */ 'is_optional': (boolean); 'config_type': "typed_config"|"config_discovery"; diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRds.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRds.ts index e4565ce80..5f7d2b6fe 100644 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRds.ts +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRds.ts @@ -7,6 +7,11 @@ export interface ScopedRds { * Configuration source specifier for scoped RDS. */ 'scoped_rds_config_source'?: (_envoy_config_core_v3_ConfigSource | null); + /** + * xdstp:// resource locator for scoped RDS collection. + * [#not-implemented-hide:] + */ + 'srds_resources_locator'?: (string); } export interface ScopedRds__Output { @@ -14,4 +19,9 @@ export interface ScopedRds__Output { * Configuration source specifier for scoped RDS. */ 'scoped_rds_config_source': (_envoy_config_core_v3_ConfigSource__Output | null); + /** + * xdstp:// resource locator for scoped RDS collection. + * [#not-implemented-hide:] + */ + 'srds_resources_locator': (string); } diff --git a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRoutes.ts b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRoutes.ts index 8aecd3883..041af534b 100644 --- a/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRoutes.ts +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/filters/network/http_connection_manager/v3/ScopedRoutes.ts @@ -160,19 +160,19 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Sc /** * Specifies the mechanism for constructing "scope keys" based on HTTP request attributes. These - * keys are matched against a set of :ref:`Key` - * objects assembled from :ref:`ScopedRouteConfiguration` + * keys are matched against a set of :ref:`Key` + * objects assembled from :ref:`ScopedRouteConfiguration` * messages distributed via SRDS (the Scoped Route Discovery Service) or assigned statically via - * :ref:`scoped_route_configurations_list`. + * :ref:`scoped_route_configurations_list`. * * Upon receiving a request's headers, the Router will build a key using the algorithm specified * by this message. This key will be used to look up the routing table (i.e., the - * :ref:`RouteConfiguration`) to use for the request. + * :ref:`RouteConfiguration`) to use for the request. */ export interface _envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder { /** * The final(built) scope key consists of the ordered union of these fragments, which are compared in order with the - * fragments of a :ref:`ScopedRouteConfiguration`. + * fragments of a :ref:`ScopedRouteConfiguration`. * A missing fragment during comparison will make the key invalid, i.e., the computed key doesn't match any key. */ 'fragments'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder)[]; @@ -180,19 +180,19 @@ export interface _envoy_extensions_filters_network_http_connection_manager_v3_Sc /** * Specifies the mechanism for constructing "scope keys" based on HTTP request attributes. These - * keys are matched against a set of :ref:`Key` - * objects assembled from :ref:`ScopedRouteConfiguration` + * keys are matched against a set of :ref:`Key` + * objects assembled from :ref:`ScopedRouteConfiguration` * messages distributed via SRDS (the Scoped Route Discovery Service) or assigned statically via - * :ref:`scoped_route_configurations_list`. + * :ref:`scoped_route_configurations_list`. * * Upon receiving a request's headers, the Router will build a key using the algorithm specified * by this message. This key will be used to look up the routing table (i.e., the - * :ref:`RouteConfiguration`) to use for the request. + * :ref:`RouteConfiguration`) to use for the request. */ export interface _envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder__Output { /** * The final(built) scope key consists of the ordered union of these fragments, which are compared in order with the - * fragments of a :ref:`ScopedRouteConfiguration`. + * fragments of a :ref:`ScopedRouteConfiguration`. * A missing fragment during comparison will make the key invalid, i.e., the computed key doesn't match any key. */ 'fragments': (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRoutes_ScopeKeyBuilder_FragmentBuilder__Output)[]; @@ -220,7 +220,7 @@ export interface ScopedRoutes { * The set of routing scopes corresponding to the HCM. A scope is assigned to a request by * matching a key constructed from the request's attributes according to the algorithm specified * by the - * :ref:`ScopeKeyBuilder` + * :ref:`ScopeKeyBuilder` * in this message. */ 'scoped_route_configurations_list'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList | null); @@ -228,7 +228,7 @@ export interface ScopedRoutes { * The set of routing scopes associated with the HCM will be dynamically loaded via the SRDS * API. A scope is assigned to a request by matching a key constructed from the request's * attributes according to the algorithm specified by the - * :ref:`ScopeKeyBuilder` + * :ref:`ScopeKeyBuilder` * in this message. */ 'scoped_rds'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds | null); @@ -257,7 +257,7 @@ export interface ScopedRoutes__Output { * The set of routing scopes corresponding to the HCM. A scope is assigned to a request by * matching a key constructed from the request's attributes according to the algorithm specified * by the - * :ref:`ScopeKeyBuilder` + * :ref:`ScopeKeyBuilder` * in this message. */ 'scoped_route_configurations_list'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRouteConfigurationsList__Output | null); @@ -265,7 +265,7 @@ export interface ScopedRoutes__Output { * The set of routing scopes associated with the HCM will be dynamically loaded via the SRDS * API. A scope is assigned to a request by matching a key constructed from the request's * attributes according to the algorithm specified by the - * :ref:`ScopeKeyBuilder` + * :ref:`ScopeKeyBuilder` * in this message. */ 'scoped_rds'?: (_envoy_extensions_filters_network_http_connection_manager_v3_ScopedRds__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 new file mode 100644 index 000000000..3a3100f55 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/CertificateProviderPluginInstance.ts @@ -0,0 +1,52 @@ +// 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 new file mode 100644 index 000000000..379320086 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/CertificateValidationContext.ts @@ -0,0 +1,372 @@ +// 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 new file mode 100644 index 000000000..b206fb13a --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/GenericSecret.ts @@ -0,0 +1,17 @@ +// 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 new file mode 100644 index 000000000..b4a2ad933 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/PrivateKeyProvider.ts @@ -0,0 +1,39 @@ +// 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 new file mode 100644 index 000000000..38b850c50 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/SdsSecretConfig.ts @@ -0,0 +1,23 @@ +// 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 new file mode 100644 index 000000000..c86957da5 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/Secret.ts @@ -0,0 +1,36 @@ +// 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 new file mode 100644 index 000000000..ce8046e95 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/TlsCertificate.ts @@ -0,0 +1,127 @@ +// 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 new file mode 100644 index 000000000..e68464c8b --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/TlsParameters.ts @@ -0,0 +1,211 @@ +// 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 new file mode 100644 index 000000000..152bccac7 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/extensions/transport_sockets/tls/v3/TlsSessionTicketKeys.ts @@ -0,0 +1,61 @@ +// 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/discovery/v3/DeltaDiscoveryRequest.ts b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DeltaDiscoveryRequest.ts index b42470516..6e900970a 100644 --- a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DeltaDiscoveryRequest.ts +++ b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DeltaDiscoveryRequest.ts @@ -97,7 +97,7 @@ export interface DeltaDiscoveryRequest { */ 'response_nonce'?: (string); /** - * This is populated when the previous :ref:`DiscoveryResponse ` + * This is populated when the previous :ref:`DiscoveryResponse ` * failed to update configuration. The *message* field in *error_details* * provides the Envoy internal exception related to the failure. */ @@ -198,7 +198,7 @@ export interface DeltaDiscoveryRequest__Output { */ 'response_nonce': (string); /** - * This is populated when the previous :ref:`DiscoveryResponse ` + * This is populated when the previous :ref:`DiscoveryResponse ` * failed to update configuration. The *message* field in *error_details* * provides the Envoy internal exception related to the failure. */ diff --git a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DiscoveryRequest.ts b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DiscoveryRequest.ts index b30930b6f..f392ab8ae 100644 --- a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DiscoveryRequest.ts +++ b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v3/DiscoveryRequest.ts @@ -48,7 +48,7 @@ export interface DiscoveryRequest { */ 'response_nonce'?: (string); /** - * This is populated when the previous :ref:`DiscoveryResponse ` + * This is populated when the previous :ref:`DiscoveryResponse ` * failed to update configuration. The *message* field in *error_details* provides the Envoy * internal exception related to the failure. It is only intended for consumption during manual * debugging, the string provided is not guaranteed to be stable across Envoy versions. @@ -101,7 +101,7 @@ export interface DiscoveryRequest__Output { */ 'response_nonce': (string); /** - * This is populated when the previous :ref:`DiscoveryResponse ` + * This is populated when the previous :ref:`DiscoveryResponse ` * failed to update configuration. The *message* field in *error_details* provides the Envoy * internal exception related to the failure. It is only intended for consumption during manual * debugging, the string provided is not guaranteed to be stable across Envoy versions. diff --git a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadStatsResponse.ts b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadStatsResponse.ts index c39658cde..40f561870 100644 --- a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadStatsResponse.ts +++ b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v3/LoadStatsResponse.ts @@ -31,7 +31,7 @@ export interface LoadStatsResponse { /** * If true, the client should send all clusters it knows about. * Only clients that advertise the "envoy.lrs.supports_send_all_clusters" capability in their - * :ref:`client_features` field will honor this field. + * :ref:`client_features` field will honor this field. */ 'send_all_clusters'?: (boolean); } @@ -65,7 +65,7 @@ export interface LoadStatsResponse__Output { /** * If true, the client should send all clusters it knows about. * Only clients that advertise the "envoy.lrs.supports_send_all_clusters" capability in their - * :ref:`client_features` field will honor this field. + * :ref:`client_features` field will honor this field. */ 'send_all_clusters': (boolean); } 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 new file mode 100644 index 000000000..ba6b25b4c --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientConfig.ts @@ -0,0 +1,159 @@ +// Original file: deps/envoy-api/envoy/service/status/v3/csds.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 { 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 { UpdateFailureState as _envoy_admin_v3_UpdateFailureState, UpdateFailureState__Output as _envoy_admin_v3_UpdateFailureState__Output } from '../../../../envoy/admin/v3/UpdateFailureState'; + +/** + * GenericXdsConfig is used to specify the config status and the dump + * of any xDS resource identified by their type URL. It is the generalized + * version of the now deprecated ListenersConfigDump, ClustersConfigDump etc + * [#next-free-field: 10] + */ +export interface _envoy_service_status_v3_ClientConfig_GenericXdsConfig { + /** + * Type_url represents the fully qualified name of xDS resource type + * like envoy.v3.Cluster, envoy.v3.ClusterLoadAssignment etc. + */ + 'type_url'?: (string); + /** + * Name of the xDS resource + */ + 'name'?: (string); + /** + * This is the :ref:`version_info ` + * in the last processed xDS discovery response. If there are only + * static bootstrap listeners, this field will be "" + */ + 'version_info'?: (string); + /** + * The xDS resource config. Actual content depends on the type + */ + 'xds_config'?: (_google_protobuf_Any | null); + /** + * Timestamp when the xDS resource was last updated + */ + 'last_updated'?: (_google_protobuf_Timestamp | null); + /** + * 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); + /** + * Per xDS resource status from the view of a xDS client + */ + 'client_status'?: (_envoy_admin_v3_ClientResourceStatus | keyof typeof _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 + * 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); + /** + * Is static resource is true if it is specified in the config supplied + * through the file at the startup. + */ + 'is_static_resource'?: (boolean); +} + +/** + * GenericXdsConfig is used to specify the config status and the dump + * of any xDS resource identified by their type URL. It is the generalized + * version of the now deprecated ListenersConfigDump, ClustersConfigDump etc + * [#next-free-field: 10] + */ +export interface _envoy_service_status_v3_ClientConfig_GenericXdsConfig__Output { + /** + * Type_url represents the fully qualified name of xDS resource type + * like envoy.v3.Cluster, envoy.v3.ClusterLoadAssignment etc. + */ + 'type_url': (string); + /** + * Name of the xDS resource + */ + 'name': (string); + /** + * This is the :ref:`version_info ` + * in the last processed xDS discovery response. If there are only + * static bootstrap listeners, this field will be "" + */ + 'version_info': (string); + /** + * The xDS resource config. Actual content depends on the type + */ + 'xds_config': (_google_protobuf_Any__Output | null); + /** + * Timestamp when the xDS resource was last updated + */ + 'last_updated': (_google_protobuf_Timestamp__Output | null); + /** + * 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); + /** + * Per xDS resource status from the view of a xDS client + */ + 'client_status': (keyof typeof _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 + * 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); + /** + * Is static resource is true if it is specified in the config supplied + * through the file at the startup. + */ + 'is_static_resource': (boolean); +} + +/** + * All xds configs for a particular client. + */ +export interface ClientConfig { + /** + * Node for a particular client. + */ + 'node'?: (_envoy_config_core_v3_Node | null); + /** + * This field is deprecated in favor of generic_xds_configs which is + * much simpler and uniform in structure. + */ + 'xds_config'?: (_envoy_service_status_v3_PerXdsConfig)[]; + /** + * Represents generic xDS config and the exact config structure depends on + * the type URL (like Cluster if it is CDS) + */ + 'generic_xds_configs'?: (_envoy_service_status_v3_ClientConfig_GenericXdsConfig)[]; +} + +/** + * All xds configs for a particular client. + */ +export interface ClientConfig__Output { + /** + * Node for a particular client. + */ + 'node': (_envoy_config_core_v3_Node__Output | null); + /** + * This field is deprecated in favor of generic_xds_configs which is + * much simpler and uniform in structure. + */ + 'xds_config': (_envoy_service_status_v3_PerXdsConfig__Output)[]; + /** + * Represents generic xDS config and the exact config structure depends on + * the type URL (like Cluster if it is CDS) + */ + 'generic_xds_configs': (_envoy_service_status_v3_ClientConfig_GenericXdsConfig__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 new file mode 100644 index 000000000..104445a3f --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientConfigStatus.ts @@ -0,0 +1,26 @@ +// Original file: deps/envoy-api/envoy/service/status/v3/csds.proto + +/** + * Config status from a client-side view. + */ +export enum 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, +} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientStatusDiscoveryService.ts b/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientStatusDiscoveryService.ts new file mode 100644 index 000000000..7402fb69b --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientStatusDiscoveryService.ts @@ -0,0 +1,45 @@ +// Original file: deps/envoy-api/envoy/service/status/v3/csds.proto + +import type * as grpc from '@grpc/grpc-js' +import type { MethodDefinition } from '@grpc/proto-loader' +import type { ClientStatusRequest as _envoy_service_status_v3_ClientStatusRequest, ClientStatusRequest__Output as _envoy_service_status_v3_ClientStatusRequest__Output } from '../../../../envoy/service/status/v3/ClientStatusRequest'; +import type { ClientStatusResponse as _envoy_service_status_v3_ClientStatusResponse, ClientStatusResponse__Output as _envoy_service_status_v3_ClientStatusResponse__Output } from '../../../../envoy/service/status/v3/ClientStatusResponse'; + +/** + * CSDS is Client Status Discovery Service. It can be used to get the status of + * an xDS-compliant client from the management server's point of view. It can + * also be used to get the current xDS states directly from the client. + */ +export interface ClientStatusDiscoveryServiceClient extends grpc.Client { + FetchClientStatus(argument: _envoy_service_status_v3_ClientStatusRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_envoy_service_status_v3_ClientStatusResponse__Output>): grpc.ClientUnaryCall; + FetchClientStatus(argument: _envoy_service_status_v3_ClientStatusRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_envoy_service_status_v3_ClientStatusResponse__Output>): grpc.ClientUnaryCall; + FetchClientStatus(argument: _envoy_service_status_v3_ClientStatusRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_envoy_service_status_v3_ClientStatusResponse__Output>): grpc.ClientUnaryCall; + FetchClientStatus(argument: _envoy_service_status_v3_ClientStatusRequest, callback: grpc.requestCallback<_envoy_service_status_v3_ClientStatusResponse__Output>): grpc.ClientUnaryCall; + fetchClientStatus(argument: _envoy_service_status_v3_ClientStatusRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_envoy_service_status_v3_ClientStatusResponse__Output>): grpc.ClientUnaryCall; + fetchClientStatus(argument: _envoy_service_status_v3_ClientStatusRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_envoy_service_status_v3_ClientStatusResponse__Output>): grpc.ClientUnaryCall; + fetchClientStatus(argument: _envoy_service_status_v3_ClientStatusRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_envoy_service_status_v3_ClientStatusResponse__Output>): grpc.ClientUnaryCall; + fetchClientStatus(argument: _envoy_service_status_v3_ClientStatusRequest, callback: grpc.requestCallback<_envoy_service_status_v3_ClientStatusResponse__Output>): grpc.ClientUnaryCall; + + StreamClientStatus(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_service_status_v3_ClientStatusRequest, _envoy_service_status_v3_ClientStatusResponse__Output>; + StreamClientStatus(options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_service_status_v3_ClientStatusRequest, _envoy_service_status_v3_ClientStatusResponse__Output>; + streamClientStatus(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_service_status_v3_ClientStatusRequest, _envoy_service_status_v3_ClientStatusResponse__Output>; + streamClientStatus(options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_service_status_v3_ClientStatusRequest, _envoy_service_status_v3_ClientStatusResponse__Output>; + +} + +/** + * CSDS is Client Status Discovery Service. It can be used to get the status of + * an xDS-compliant client from the management server's point of view. It can + * also be used to get the current xDS states directly from the client. + */ +export interface ClientStatusDiscoveryServiceHandlers extends grpc.UntypedServiceImplementation { + FetchClientStatus: grpc.handleUnaryCall<_envoy_service_status_v3_ClientStatusRequest__Output, _envoy_service_status_v3_ClientStatusResponse>; + + StreamClientStatus: grpc.handleBidiStreamingCall<_envoy_service_status_v3_ClientStatusRequest__Output, _envoy_service_status_v3_ClientStatusResponse>; + +} + +export interface ClientStatusDiscoveryServiceDefinition extends grpc.ServiceDefinition { + FetchClientStatus: MethodDefinition<_envoy_service_status_v3_ClientStatusRequest, _envoy_service_status_v3_ClientStatusResponse, _envoy_service_status_v3_ClientStatusRequest__Output, _envoy_service_status_v3_ClientStatusResponse__Output> + StreamClientStatus: MethodDefinition<_envoy_service_status_v3_ClientStatusRequest, _envoy_service_status_v3_ClientStatusResponse, _envoy_service_status_v3_ClientStatusRequest__Output, _envoy_service_status_v3_ClientStatusResponse__Output> +} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientStatusRequest.ts b/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientStatusRequest.ts new file mode 100644 index 000000000..91adddacc --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientStatusRequest.ts @@ -0,0 +1,34 @@ +// Original file: deps/envoy-api/envoy/service/status/v3/csds.proto + +import type { NodeMatcher as _envoy_type_matcher_v3_NodeMatcher, NodeMatcher__Output as _envoy_type_matcher_v3_NodeMatcher__Output } from '../../../../envoy/type/matcher/v3/NodeMatcher'; +import type { Node as _envoy_config_core_v3_Node, Node__Output as _envoy_config_core_v3_Node__Output } from '../../../../envoy/config/core/v3/Node'; + +/** + * Request for client status of clients identified by a list of NodeMatchers. + */ +export interface ClientStatusRequest { + /** + * Management server can use these match criteria to identify clients. + * The match follows OR semantics. + */ + 'node_matchers'?: (_envoy_type_matcher_v3_NodeMatcher)[]; + /** + * The node making the csds request. + */ + 'node'?: (_envoy_config_core_v3_Node | null); +} + +/** + * Request for client status of clients identified by a list of NodeMatchers. + */ +export interface ClientStatusRequest__Output { + /** + * Management server can use these match criteria to identify clients. + * The match follows OR semantics. + */ + 'node_matchers': (_envoy_type_matcher_v3_NodeMatcher__Output)[]; + /** + * The node making the csds request. + */ + 'node': (_envoy_config_core_v3_Node__Output | null); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientStatusResponse.ts b/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientStatusResponse.ts new file mode 100644 index 000000000..3611016ec --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ClientStatusResponse.ts @@ -0,0 +1,17 @@ +// Original file: deps/envoy-api/envoy/service/status/v3/csds.proto + +import type { ClientConfig as _envoy_service_status_v3_ClientConfig, ClientConfig__Output as _envoy_service_status_v3_ClientConfig__Output } from '../../../../envoy/service/status/v3/ClientConfig'; + +export interface ClientStatusResponse { + /** + * Client configs for the clients specified in the ClientStatusRequest. + */ + 'config'?: (_envoy_service_status_v3_ClientConfig)[]; +} + +export interface ClientStatusResponse__Output { + /** + * Client configs for the clients specified in the ClientStatusRequest. + */ + 'config': (_envoy_service_status_v3_ClientConfig__Output)[]; +} 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 new file mode 100644 index 000000000..71db302c3 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/service/status/v3/ConfigStatus.ts @@ -0,0 +1,30 @@ +// Original file: deps/envoy-api/envoy/service/status/v3/csds.proto + +/** + * Status of a config from a management server view. + */ +export enum 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, +} 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 new file mode 100644 index 000000000..947f1c81a --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/service/status/v3/PerXdsConfig.ts @@ -0,0 +1,67 @@ +// 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 { 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'; + +/** + * Detailed config (per xDS) with status. + * [#next-free-field: 8] + */ +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); + 'listener_config'?: (_envoy_admin_v3_ListenersConfigDump | null); + 'cluster_config'?: (_envoy_admin_v3_ClustersConfigDump | null); + 'route_config'?: (_envoy_admin_v3_RoutesConfigDump | null); + 'scoped_route_config'?: (_envoy_admin_v3_ScopedRoutesConfigDump | null); + 'endpoint_config'?: (_envoy_admin_v3_EndpointsConfigDump | null); + /** + * Client config status is populated by xDS clients. Will not be present if + * the CSDS server is an xDS server. No matter what the client config status + * is, xDS clients should always dump the most recent accepted xDS config. + * + * .. attention:: + * This field is deprecated. Use :ref:`ClientResourceStatus + * ` for per-resource + * config status instead. + */ + 'client_status'?: (_envoy_service_status_v3_ClientConfigStatus | keyof typeof _envoy_service_status_v3_ClientConfigStatus); + 'per_xds_config'?: "listener_config"|"cluster_config"|"route_config"|"scoped_route_config"|"endpoint_config"; +} + +/** + * Detailed config (per xDS) with status. + * [#next-free-field: 8] + */ +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); + 'listener_config'?: (_envoy_admin_v3_ListenersConfigDump__Output | null); + 'cluster_config'?: (_envoy_admin_v3_ClustersConfigDump__Output | null); + 'route_config'?: (_envoy_admin_v3_RoutesConfigDump__Output | null); + 'scoped_route_config'?: (_envoy_admin_v3_ScopedRoutesConfigDump__Output | null); + 'endpoint_config'?: (_envoy_admin_v3_EndpointsConfigDump__Output | null); + /** + * Client config status is populated by xDS clients. Will not be present if + * the CSDS server is an xDS server. No matter what the client config status + * is, xDS clients should always dump the most recent accepted xDS config. + * + * .. attention:: + * This field is deprecated. Use :ref:`ClientResourceStatus + * ` for per-resource + * config status instead. + */ + 'client_status': (keyof typeof _envoy_service_status_v3_ClientConfigStatus); + '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/http/v3/PathTransformation.ts b/packages/grpc-js-xds/src/generated/envoy/type/http/v3/PathTransformation.ts new file mode 100644 index 000000000..4dc10efcb --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/type/http/v3/PathTransformation.ts @@ -0,0 +1,92 @@ +// Original file: deps/envoy-api/envoy/type/http/v3/path_transformation.proto + + +/** + * Determines if adjacent slashes are merged into one. A common use case is for a request path + * header. Using this option in `:ref: PathNormalizationOptions + * ` + * will allow incoming requests with path `//dir///file` to match against route with `prefix` + * match set to `/dir`. When using for header transformations, note that slash merging is not + * part of `HTTP spec `_ and is provided for convenience. + */ +export interface _envoy_type_http_v3_PathTransformation_Operation_MergeSlashes { +} + +/** + * Determines if adjacent slashes are merged into one. A common use case is for a request path + * header. Using this option in `:ref: PathNormalizationOptions + * ` + * will allow incoming requests with path `//dir///file` to match against route with `prefix` + * match set to `/dir`. When using for header transformations, note that slash merging is not + * part of `HTTP spec `_ and is provided for convenience. + */ +export interface _envoy_type_http_v3_PathTransformation_Operation_MergeSlashes__Output { +} + +/** + * Should text be normalized according to RFC 3986? This typically is used for path headers + * before any processing of requests by HTTP filters or routing. This applies percent-encoded + * normalization and path segment normalization. Fails on characters disallowed in URLs + * (e.g. NULLs). See `Normalization and Comparison + * `_ for details of normalization. Note that + * this options does not perform `case normalization + * `_ + */ +export interface _envoy_type_http_v3_PathTransformation_Operation_NormalizePathRFC3986 { +} + +/** + * Should text be normalized according to RFC 3986? This typically is used for path headers + * before any processing of requests by HTTP filters or routing. This applies percent-encoded + * normalization and path segment normalization. Fails on characters disallowed in URLs + * (e.g. NULLs). See `Normalization and Comparison + * `_ for details of normalization. Note that + * this options does not perform `case normalization + * `_ + */ +export interface _envoy_type_http_v3_PathTransformation_Operation_NormalizePathRFC3986__Output { +} + +/** + * A type of operation to alter text. + */ +export interface _envoy_type_http_v3_PathTransformation_Operation { + /** + * Enable path normalization per RFC 3986. + */ + 'normalize_path_rfc_3986'?: (_envoy_type_http_v3_PathTransformation_Operation_NormalizePathRFC3986 | null); + /** + * Enable merging adjacent slashes. + */ + 'merge_slashes'?: (_envoy_type_http_v3_PathTransformation_Operation_MergeSlashes | null); + 'operation_specifier'?: "normalize_path_rfc_3986"|"merge_slashes"; +} + +/** + * A type of operation to alter text. + */ +export interface _envoy_type_http_v3_PathTransformation_Operation__Output { + /** + * Enable path normalization per RFC 3986. + */ + 'normalize_path_rfc_3986'?: (_envoy_type_http_v3_PathTransformation_Operation_NormalizePathRFC3986__Output | null); + /** + * Enable merging adjacent slashes. + */ + 'merge_slashes'?: (_envoy_type_http_v3_PathTransformation_Operation_MergeSlashes__Output | null); + 'operation_specifier': "normalize_path_rfc_3986"|"merge_slashes"; +} + +export interface PathTransformation { + /** + * A list of operations to apply. Transformations will be performed in the order that they appear. + */ + 'operations'?: (_envoy_type_http_v3_PathTransformation_Operation)[]; +} + +export interface PathTransformation__Output { + /** + * A list of operations to apply. Transformations will be performed in the order that they appear. + */ + 'operations': (_envoy_type_http_v3_PathTransformation_Operation__Output)[]; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/MetadataMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/MetadataMatcher.ts index 58117faab..78d4f03da 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/MetadataMatcher.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/MetadataMatcher.ts @@ -44,6 +44,10 @@ export interface MetadataMatcher { * The MetadataMatcher is matched if the value retrieved by path is matched to this value. */ 'value'?: (_envoy_type_matcher_v3_ValueMatcher | null); + /** + * If true, the match result will be inverted. + */ + 'invert'?: (boolean); } /** @@ -62,4 +66,8 @@ export interface MetadataMatcher__Output { * The MetadataMatcher is matched if the value retrieved by path is matched to this value. */ 'value': (_envoy_type_matcher_v3_ValueMatcher__Output | null); + /** + * If true, the match result will be inverted. + */ + 'invert': (boolean); } diff --git a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/NodeMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/NodeMatcher.ts new file mode 100644 index 000000000..7e31b9753 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/NodeMatcher.ts @@ -0,0 +1,34 @@ +// Original file: deps/envoy-api/envoy/type/matcher/v3/node.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'; +import type { StructMatcher as _envoy_type_matcher_v3_StructMatcher, StructMatcher__Output as _envoy_type_matcher_v3_StructMatcher__Output } from '../../../../envoy/type/matcher/v3/StructMatcher'; + +/** + * Specifies the way to match a Node. + * The match follows AND semantics. + */ +export interface NodeMatcher { + /** + * Specifies match criteria on the node id. + */ + 'node_id'?: (_envoy_type_matcher_v3_StringMatcher | null); + /** + * Specifies match criteria on the node metadata. + */ + 'node_metadatas'?: (_envoy_type_matcher_v3_StructMatcher)[]; +} + +/** + * Specifies the way to match a Node. + * The match follows AND semantics. + */ +export interface NodeMatcher__Output { + /** + * Specifies match criteria on the node id. + */ + 'node_id': (_envoy_type_matcher_v3_StringMatcher__Output | null); + /** + * Specifies match criteria on the node metadata. + */ + 'node_metadatas': (_envoy_type_matcher_v3_StructMatcher__Output)[]; +} diff --git a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/StringMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/StringMatcher.ts index c89190510..7440746f1 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/StringMatcher.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/StringMatcher.ts @@ -38,8 +38,8 @@ export interface StringMatcher { */ 'safe_regex'?: (_envoy_type_matcher_v3_RegexMatcher | null); /** - * If true, indicates the exact/prefix/suffix matching should be case insensitive. This has no - * effect for the safe_regex match. + * If true, indicates the exact/prefix/suffix/contains matching should be case insensitive. This + * has no effect for the safe_regex match. * For example, the matcher *data* will match both input string *Data* and *data* if set to true. */ 'ignore_case'?: (boolean); @@ -91,8 +91,8 @@ export interface StringMatcher__Output { */ 'safe_regex'?: (_envoy_type_matcher_v3_RegexMatcher__Output | null); /** - * If true, indicates the exact/prefix/suffix matching should be case insensitive. This has no - * effect for the safe_regex match. + * If true, indicates the exact/prefix/suffix/contains matching should be case insensitive. This + * has no effect for the safe_regex match. * For example, the matcher *data* will match both input string *Data* and *data* if set to true. */ 'ignore_case': (boolean); diff --git a/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/StructMatcher.ts b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/StructMatcher.ts new file mode 100644 index 000000000..141806489 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/envoy/type/matcher/v3/StructMatcher.ts @@ -0,0 +1,153 @@ +// Original file: deps/envoy-api/envoy/type/matcher/v3/struct.proto + +import type { ValueMatcher as _envoy_type_matcher_v3_ValueMatcher, ValueMatcher__Output as _envoy_type_matcher_v3_ValueMatcher__Output } from '../../../../envoy/type/matcher/v3/ValueMatcher'; + +/** + * Specifies the segment in a path to retrieve value from Struct. + */ +export interface _envoy_type_matcher_v3_StructMatcher_PathSegment { + /** + * If specified, use the key to retrieve the value in a Struct. + */ + 'key'?: (string); + 'segment'?: "key"; +} + +/** + * Specifies the segment in a path to retrieve value from Struct. + */ +export interface _envoy_type_matcher_v3_StructMatcher_PathSegment__Output { + /** + * If specified, use the key to retrieve the value in a Struct. + */ + 'key'?: (string); + 'segment': "key"; +} + +/** + * StructMatcher provides a general interface to check if a given value is matched in + * google.protobuf.Struct. It uses `path` to retrieve the value + * from the struct and then check if it's matched to the specified value. + * + * For example, for the following Struct: + * + * .. code-block:: yaml + * + * fields: + * a: + * struct_value: + * fields: + * b: + * struct_value: + * fields: + * c: + * string_value: pro + * t: + * list_value: + * values: + * - string_value: m + * - string_value: n + * + * The following MetadataMatcher is matched as the path [a, b, c] will retrieve a string value "pro" + * from the Metadata which is matched to the specified prefix match. + * + * .. code-block:: yaml + * + * path: + * - key: a + * - key: b + * - key: c + * value: + * string_match: + * prefix: pr + * + * The following StructMatcher is matched as the code will match one of the string values in the + * list at the path [a, t]. + * + * .. code-block:: yaml + * + * path: + * - key: a + * - key: t + * value: + * list_match: + * one_of: + * string_match: + * exact: m + * + * An example use of StructMatcher is to match metadata in envoy.v*.core.Node. + */ +export interface StructMatcher { + /** + * The path to retrieve the Value from the Struct. + */ + 'path'?: (_envoy_type_matcher_v3_StructMatcher_PathSegment)[]; + /** + * The StructMatcher is matched if the value retrieved by path is matched to this value. + */ + 'value'?: (_envoy_type_matcher_v3_ValueMatcher | null); +} + +/** + * StructMatcher provides a general interface to check if a given value is matched in + * google.protobuf.Struct. It uses `path` to retrieve the value + * from the struct and then check if it's matched to the specified value. + * + * For example, for the following Struct: + * + * .. code-block:: yaml + * + * fields: + * a: + * struct_value: + * fields: + * b: + * struct_value: + * fields: + * c: + * string_value: pro + * t: + * list_value: + * values: + * - string_value: m + * - string_value: n + * + * The following MetadataMatcher is matched as the path [a, b, c] will retrieve a string value "pro" + * from the Metadata which is matched to the specified prefix match. + * + * .. code-block:: yaml + * + * path: + * - key: a + * - key: b + * - key: c + * value: + * string_match: + * prefix: pr + * + * The following StructMatcher is matched as the code will match one of the string values in the + * list at the path [a, t]. + * + * .. code-block:: yaml + * + * path: + * - key: a + * - key: t + * value: + * list_match: + * one_of: + * string_match: + * exact: m + * + * An example use of StructMatcher is to match metadata in envoy.v*.core.Node. + */ +export interface StructMatcher__Output { + /** + * The path to retrieve the Value from the Struct. + */ + 'path': (_envoy_type_matcher_v3_StructMatcher_PathSegment__Output)[]; + /** + * The StructMatcher is matched if the value retrieved by path is matched to this value. + */ + 'value': (_envoy_type_matcher_v3_ValueMatcher__Output | null); +} diff --git a/packages/grpc-js-xds/src/generated/envoy/type/metadata/v3/MetadataKey.ts b/packages/grpc-js-xds/src/generated/envoy/type/metadata/v3/MetadataKey.ts index fcc43b07b..50b6690d3 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/metadata/v3/MetadataKey.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/metadata/v3/MetadataKey.ts @@ -27,7 +27,7 @@ export interface _envoy_type_metadata_v3_MetadataKey_PathSegment__Output { /** * MetadataKey provides a general interface using `key` and `path` to retrieve value from - * :ref:`Metadata `. + * :ref:`Metadata `. * * For example, for the following Metadata: * @@ -68,7 +68,7 @@ export interface MetadataKey { /** * MetadataKey provides a general interface using `key` and `path` to retrieve value from - * :ref:`Metadata `. + * :ref:`Metadata `. * * For example, for the following Metadata: * diff --git a/packages/grpc-js-xds/src/generated/envoy/type/metadata/v3/MetadataKind.ts b/packages/grpc-js-xds/src/generated/envoy/type/metadata/v3/MetadataKind.ts index 2457b3f91..3ca368ccb 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/metadata/v3/MetadataKind.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/metadata/v3/MetadataKind.ts @@ -2,27 +2,27 @@ /** - * Represents metadata from :ref:`the upstream cluster`. + * Represents metadata from :ref:`the upstream cluster`. */ export interface _envoy_type_metadata_v3_MetadataKind_Cluster { } /** - * Represents metadata from :ref:`the upstream cluster`. + * Represents metadata from :ref:`the upstream cluster`. */ export interface _envoy_type_metadata_v3_MetadataKind_Cluster__Output { } /** * Represents metadata from :ref:`the upstream - * host`. + * host`. */ export interface _envoy_type_metadata_v3_MetadataKind_Host { } /** * Represents metadata from :ref:`the upstream - * host`. + * host`. */ export interface _envoy_type_metadata_v3_MetadataKind_Host__Output { } @@ -40,13 +40,13 @@ export interface _envoy_type_metadata_v3_MetadataKind_Request__Output { } /** - * Represents metadata from :ref:`the route`. + * Represents metadata from :ref:`the route`. */ export interface _envoy_type_metadata_v3_MetadataKind_Route { } /** - * Represents metadata from :ref:`the route`. + * Represents metadata from :ref:`the route`. */ export interface _envoy_type_metadata_v3_MetadataKind_Route__Output { } diff --git a/packages/grpc-js-xds/src/generated/envoy/type/tracing/v3/CustomTag.ts b/packages/grpc-js-xds/src/generated/envoy/type/tracing/v3/CustomTag.ts index d5fe26ed5..34ac26f8c 100644 --- a/packages/grpc-js-xds/src/generated/envoy/type/tracing/v3/CustomTag.ts +++ b/packages/grpc-js-xds/src/generated/envoy/type/tracing/v3/CustomTag.ts @@ -89,8 +89,8 @@ export interface _envoy_type_tracing_v3_CustomTag_Literal__Output { /** * Metadata type custom tag using - * :ref:`MetadataKey ` to retrieve the protobuf value - * from :ref:`Metadata `, and populate the tag value with + * :ref:`MetadataKey ` to retrieve the protobuf value + * from :ref:`Metadata `, and populate the tag value with * `the canonical JSON `_ * representation of it. */ @@ -113,8 +113,8 @@ export interface _envoy_type_tracing_v3_CustomTag_Metadata { /** * Metadata type custom tag using - * :ref:`MetadataKey ` to retrieve the protobuf value - * from :ref:`Metadata `, and populate the tag value with + * :ref:`MetadataKey ` to retrieve the protobuf value + * from :ref:`Metadata `, and populate the tag value with * `the canonical JSON `_ * representation of it. */ diff --git a/packages/grpc-js-xds/src/generated/fault.ts b/packages/grpc-js-xds/src/generated/fault.ts index 0f60fc224..896382e50 100644 --- a/packages/grpc-js-xds/src/generated/fault.ts +++ b/packages/grpc-js-xds/src/generated/fault.ts @@ -38,6 +38,7 @@ export interface ProtoGrpcType { Node: MessageTypeDefinition Pipe: MessageTypeDefinition ProxyProtocolConfig: MessageTypeDefinition + QueryParameter: MessageTypeDefinition RateLimitSettings: MessageTypeDefinition RemoteDataSource: MessageTypeDefinition RequestMethod: EnumTypeDefinition @@ -68,6 +69,7 @@ export interface ProtoGrpcType { HeaderMatcher: MessageTypeDefinition HedgePolicy: MessageTypeDefinition InternalRedirectPolicy: MessageTypeDefinition + NonForwardingAction: MessageTypeDefinition QueryParameterMatcher: MessageTypeDefinition RateLimit: MessageTypeDefinition RedirectAction: MessageTypeDefinition @@ -105,10 +107,14 @@ export interface ProtoGrpcType { type: { matcher: { v3: { + DoubleMatcher: MessageTypeDefinition + ListMatcher: MessageTypeDefinition ListStringMatcher: MessageTypeDefinition + MetadataMatcher: MessageTypeDefinition RegexMatchAndSubstitute: MessageTypeDefinition RegexMatcher: MessageTypeDefinition StringMatcher: MessageTypeDefinition + ValueMatcher: MessageTypeDefinition } } metadata: { @@ -222,6 +228,7 @@ export interface ProtoGrpcType { core: { v3: { Authority: MessageTypeDefinition + ContextParams: MessageTypeDefinition } } } diff --git a/packages/grpc-js-xds/src/generated/google/api/CustomHttpPattern.ts b/packages/grpc-js-xds/src/generated/google/api/CustomHttpPattern.ts new file mode 100644 index 000000000..2b6490be6 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/google/api/CustomHttpPattern.ts @@ -0,0 +1,30 @@ +// Original file: deps/googleapis/google/api/http.proto + + +/** + * A custom pattern is used for defining custom HTTP verb. + */ +export interface CustomHttpPattern { + /** + * The name of this custom HTTP verb. + */ + 'kind'?: (string); + /** + * The path matched by this custom verb. + */ + 'path'?: (string); +} + +/** + * A custom pattern is used for defining custom HTTP verb. + */ +export interface CustomHttpPattern__Output { + /** + * The name of this custom HTTP verb. + */ + 'kind': (string); + /** + * The path matched by this custom verb. + */ + 'path': (string); +} diff --git a/packages/grpc-js-xds/src/generated/google/api/Http.ts b/packages/grpc-js-xds/src/generated/google/api/Http.ts new file mode 100644 index 000000000..e9b3cb309 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/google/api/Http.ts @@ -0,0 +1,49 @@ +// Original file: deps/googleapis/google/api/http.proto + +import type { HttpRule as _google_api_HttpRule, HttpRule__Output as _google_api_HttpRule__Output } from '../../google/api/HttpRule'; + +/** + * Defines the HTTP configuration for an API service. It contains a list of + * [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method + * to one or more HTTP REST API methods. + */ +export interface Http { + /** + * A list of HTTP configuration rules that apply to individual API methods. + * + * **NOTE:** All service configuration rules follow "last one wins" order. + */ + 'rules'?: (_google_api_HttpRule)[]; + /** + * When set to true, URL path parameters will be fully URI-decoded except in + * cases of single segment matches in reserved expansion, where "%2F" will be + * left encoded. + * + * The default behavior is to not decode RFC 6570 reserved characters in multi + * segment matches. + */ + 'fully_decode_reserved_expansion'?: (boolean); +} + +/** + * Defines the HTTP configuration for an API service. It contains a list of + * [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method + * to one or more HTTP REST API methods. + */ +export interface Http__Output { + /** + * A list of HTTP configuration rules that apply to individual API methods. + * + * **NOTE:** All service configuration rules follow "last one wins" order. + */ + 'rules': (_google_api_HttpRule__Output)[]; + /** + * When set to true, URL path parameters will be fully URI-decoded except in + * cases of single segment matches in reserved expansion, where "%2F" will be + * left encoded. + * + * The default behavior is to not decode RFC 6570 reserved characters in multi + * segment matches. + */ + 'fully_decode_reserved_expansion': (boolean); +} diff --git a/packages/grpc-js-xds/src/generated/google/api/HttpRule.ts b/packages/grpc-js-xds/src/generated/google/api/HttpRule.ts new file mode 100644 index 000000000..243a99f80 --- /dev/null +++ b/packages/grpc-js-xds/src/generated/google/api/HttpRule.ts @@ -0,0 +1,680 @@ +// Original file: deps/googleapis/google/api/http.proto + +import type { CustomHttpPattern as _google_api_CustomHttpPattern, CustomHttpPattern__Output as _google_api_CustomHttpPattern__Output } from '../../google/api/CustomHttpPattern'; +import type { HttpRule as _google_api_HttpRule, HttpRule__Output as _google_api_HttpRule__Output } from '../../google/api/HttpRule'; + +/** + * # gRPC Transcoding + * + * gRPC Transcoding is a feature for mapping between a gRPC method and one or + * more HTTP REST endpoints. It allows developers to build a single API service + * that supports both gRPC APIs and REST APIs. Many systems, including [Google + * APIs](https://github.com/googleapis/googleapis), + * [Cloud Endpoints](https://cloud.google.com/endpoints), [gRPC + * Gateway](https://github.com/grpc-ecosystem/grpc-gateway), + * and [Envoy](https://github.com/envoyproxy/envoy) proxy support this feature + * and use it for large scale production services. + * + * `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies + * how different portions of the gRPC request message are mapped to the URL + * path, URL query parameters, and HTTP request body. It also controls how the + * gRPC response message is mapped to the HTTP response body. `HttpRule` is + * typically specified as an `google.api.http` annotation on the gRPC method. + * + * Each mapping specifies a URL path template and an HTTP method. The path + * template may refer to one or more fields in the gRPC request message, as long + * as each field is a non-repeated field with a primitive (non-message) type. + * The path template controls how fields of the request message are mapped to + * the URL path. + * + * Example: + * + * service Messaging { + * rpc GetMessage(GetMessageRequest) returns (Message) { + * option (google.api.http) = { + * get: "/v1/{name=messages/*}" + * }; + * } + * } + * message GetMessageRequest { + * string name = 1; // Mapped to URL path. + * } + * message Message { + * string text = 1; // The resource content. + * } + * + * This enables an HTTP REST to gRPC mapping as below: + * + * HTTP | gRPC + * -----|----- + * `GET /v1/messages/123456` | `GetMessage(name: "messages/123456")` + * + * Any fields in the request message which are not bound by the path template + * automatically become HTTP query parameters if there is no HTTP request body. + * For example: + * + * service Messaging { + * rpc GetMessage(GetMessageRequest) returns (Message) { + * option (google.api.http) = { + * get:"/v1/messages/{message_id}" + * }; + * } + * } + * message GetMessageRequest { + * message SubMessage { + * string subfield = 1; + * } + * string message_id = 1; // Mapped to URL path. + * int64 revision = 2; // Mapped to URL query parameter `revision`. + * SubMessage sub = 3; // Mapped to URL query parameter `sub.subfield`. + * } + * + * This enables a HTTP JSON to RPC mapping as below: + * + * HTTP | gRPC + * -----|----- + * `GET /v1/messages/123456?revision=2&sub.subfield=foo` | + * `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: + * "foo"))` + * + * Note that fields which are mapped to URL query parameters must have a + * primitive type or a repeated primitive type or a non-repeated message type. + * In the case of a repeated type, the parameter can be repeated in the URL + * as `...?param=A¶m=B`. In the case of a message type, each field of the + * message is mapped to a separate parameter, such as + * `...?foo.a=A&foo.b=B&foo.c=C`. + * + * For HTTP methods that allow a request body, the `body` field + * specifies the mapping. Consider a REST update method on the + * message resource collection: + * + * service Messaging { + * rpc UpdateMessage(UpdateMessageRequest) returns (Message) { + * option (google.api.http) = { + * patch: "/v1/messages/{message_id}" + * body: "message" + * }; + * } + * } + * message UpdateMessageRequest { + * string message_id = 1; // mapped to the URL + * Message message = 2; // mapped to the body + * } + * + * The following HTTP JSON to RPC mapping is enabled, where the + * representation of the JSON in the request body is determined by + * protos JSON encoding: + * + * HTTP | gRPC + * -----|----- + * `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: + * "123456" message { text: "Hi!" })` + * + * The special name `*` can be used in the body mapping to define that + * every field not bound by the path template should be mapped to the + * request body. This enables the following alternative definition of + * the update method: + * + * service Messaging { + * rpc UpdateMessage(Message) returns (Message) { + * option (google.api.http) = { + * patch: "/v1/messages/{message_id}" + * body: "*" + * }; + * } + * } + * message Message { + * string message_id = 1; + * string text = 2; + * } + * + * + * The following HTTP JSON to RPC mapping is enabled: + * + * HTTP | gRPC + * -----|----- + * `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: + * "123456" text: "Hi!")` + * + * Note that when using `*` in the body mapping, it is not possible to + * have HTTP parameters, as all fields not bound by the path end in + * the body. This makes this option more rarely used in practice when + * defining REST APIs. The common usage of `*` is in custom methods + * which don't use the URL at all for transferring data. + * + * It is possible to define multiple HTTP methods for one RPC by using + * the `additional_bindings` option. Example: + * + * service Messaging { + * rpc GetMessage(GetMessageRequest) returns (Message) { + * option (google.api.http) = { + * get: "/v1/messages/{message_id}" + * additional_bindings { + * get: "/v1/users/{user_id}/messages/{message_id}" + * } + * }; + * } + * } + * message GetMessageRequest { + * string message_id = 1; + * string user_id = 2; + * } + * + * This enables the following two alternative HTTP JSON to RPC mappings: + * + * HTTP | gRPC + * -----|----- + * `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` + * `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: + * "123456")` + * + * ## Rules for HTTP mapping + * + * 1. Leaf request fields (recursive expansion nested messages in the request + * message) are classified into three categories: + * - Fields referred by the path template. They are passed via the URL path. + * - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They are passed via the HTTP + * request body. + * - All other fields are passed via the URL query parameters, and the + * parameter name is the field path in the request message. A repeated + * field can be represented as multiple query parameters under the same + * name. + * 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL query parameter, all fields + * are passed via URL path and HTTP request body. + * 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP request body, all + * fields are passed via URL path and URL query parameters. + * + * ### Path template syntax + * + * Template = "/" Segments [ Verb ] ; + * Segments = Segment { "/" Segment } ; + * Segment = "*" | "**" | LITERAL | Variable ; + * Variable = "{" FieldPath [ "=" Segments ] "}" ; + * FieldPath = IDENT { "." IDENT } ; + * Verb = ":" LITERAL ; + * + * The syntax `*` matches a single URL path segment. The syntax `**` matches + * zero or more URL path segments, which must be the last part of the URL path + * except the `Verb`. + * + * The syntax `Variable` matches part of the URL path as specified by its + * template. A variable template must not contain other variables. If a variable + * matches a single path segment, its template may be omitted, e.g. `{var}` + * is equivalent to `{var=*}`. + * + * The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL` + * contains any reserved character, such characters should be percent-encoded + * before the matching. + * + * If a variable contains exactly one path segment, such as `"{var}"` or + * `"{var=*}"`, when such a variable is expanded into a URL path on the client + * side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The + * server side does the reverse decoding. Such variables show up in the + * [Discovery + * Document](https://developers.google.com/discovery/v1/reference/apis) as + * `{var}`. + * + * If a variable contains multiple path segments, such as `"{var=foo/*}"` + * or `"{var=**}"`, when such a variable is expanded into a URL path on the + * client side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. + * The server side does the reverse decoding, except "%2F" and "%2f" are left + * unchanged. Such variables show up in the + * [Discovery + * Document](https://developers.google.com/discovery/v1/reference/apis) as + * `{+var}`. + * + * ## Using gRPC API Service Configuration + * + * gRPC API Service Configuration (service config) is a configuration language + * for configuring a gRPC service to become a user-facing product. The + * service config is simply the YAML representation of the `google.api.Service` + * proto message. + * + * As an alternative to annotating your proto file, you can configure gRPC + * transcoding in your service config YAML files. You do this by specifying a + * `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same + * effect as the proto annotation. This can be particularly useful if you + * have a proto that is reused in multiple services. Note that any transcoding + * specified in the service config will override any matching transcoding + * configuration in the proto. + * + * Example: + * + * http: + * rules: + * # Selects a gRPC method and applies HttpRule to it. + * - selector: example.v1.Messaging.GetMessage + * get: /v1/messages/{message_id}/{sub.subfield} + * + * ## Special notes + * + * When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the + * proto to JSON conversion must follow the [proto3 + * specification](https://developers.google.com/protocol-buffers/docs/proto3#json). + * + * While the single segment variable follows the semantics of + * [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String + * Expansion, the multi segment variable **does not** follow RFC 6570 Section + * 3.2.3 Reserved Expansion. The reason is that the Reserved Expansion + * does not expand special characters like `?` and `#`, which would lead + * to invalid URLs. As the result, gRPC Transcoding uses a custom encoding + * for multi segment variables. + * + * The path variables **must not** refer to any repeated or mapped field, + * because client libraries are not capable of handling such variable expansion. + * + * The path variables **must not** capture the leading "/" character. The reason + * is that the most common use case "{var}" does not capture the leading "/" + * character. For consistency, all path variables must share the same behavior. + * + * Repeated message fields must not be mapped to URL query parameters, because + * no client library can support such complicated mapping. + * + * If an API needs to use a JSON array for request or response body, it can map + * the request or response body to a repeated field. However, some gRPC + * Transcoding implementations may not support this feature. + */ +export interface HttpRule { + /** + * Selects a method to which this rule applies. + * + * Refer to [selector][google.api.DocumentationRule.selector] for syntax details. + */ + 'selector'?: (string); + /** + * Maps to HTTP GET. Used for listing and getting information about + * resources. + */ + 'get'?: (string); + /** + * Maps to HTTP PUT. Used for replacing a resource. + */ + 'put'?: (string); + /** + * Maps to HTTP POST. Used for creating a resource or performing an action. + */ + 'post'?: (string); + /** + * Maps to HTTP DELETE. Used for deleting a resource. + */ + 'delete'?: (string); + /** + * Maps to HTTP PATCH. Used for updating a resource. + */ + 'patch'?: (string); + /** + * The name of the request field whose value is mapped to the HTTP request + * body, or `*` for mapping all request fields not captured by the path + * pattern to the HTTP body, or omitted for not having any HTTP request body. + * + * NOTE: the referred field must be present at the top-level of the request + * message type. + */ + 'body'?: (string); + /** + * The custom pattern is used for specifying an HTTP method that is not + * included in the `pattern` field, such as HEAD, or "*" to leave the + * HTTP method unspecified for this rule. The wild-card rule is useful + * for services that provide content to Web (HTML) clients. + */ + 'custom'?: (_google_api_CustomHttpPattern | null); + /** + * Additional HTTP bindings for the selector. Nested bindings must + * not contain an `additional_bindings` field themselves (that is, + * the nesting may only be one level deep). + */ + 'additional_bindings'?: (_google_api_HttpRule)[]; + /** + * Optional. The name of the response field whose value is mapped to the HTTP + * response body. When omitted, the entire response message will be used + * as the HTTP response body. + * + * NOTE: The referred field must be present at the top-level of the response + * message type. + */ + 'response_body'?: (string); + /** + * Determines the URL pattern is matched by this rules. This pattern can be + * used with any of the {get|put|post|delete|patch} methods. A custom method + * can be defined using the 'custom' field. + */ + 'pattern'?: "get"|"put"|"post"|"delete"|"patch"|"custom"; +} + +/** + * # gRPC Transcoding + * + * gRPC Transcoding is a feature for mapping between a gRPC method and one or + * more HTTP REST endpoints. It allows developers to build a single API service + * that supports both gRPC APIs and REST APIs. Many systems, including [Google + * APIs](https://github.com/googleapis/googleapis), + * [Cloud Endpoints](https://cloud.google.com/endpoints), [gRPC + * Gateway](https://github.com/grpc-ecosystem/grpc-gateway), + * and [Envoy](https://github.com/envoyproxy/envoy) proxy support this feature + * and use it for large scale production services. + * + * `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies + * how different portions of the gRPC request message are mapped to the URL + * path, URL query parameters, and HTTP request body. It also controls how the + * gRPC response message is mapped to the HTTP response body. `HttpRule` is + * typically specified as an `google.api.http` annotation on the gRPC method. + * + * Each mapping specifies a URL path template and an HTTP method. The path + * template may refer to one or more fields in the gRPC request message, as long + * as each field is a non-repeated field with a primitive (non-message) type. + * The path template controls how fields of the request message are mapped to + * the URL path. + * + * Example: + * + * service Messaging { + * rpc GetMessage(GetMessageRequest) returns (Message) { + * option (google.api.http) = { + * get: "/v1/{name=messages/*}" + * }; + * } + * } + * message GetMessageRequest { + * string name = 1; // Mapped to URL path. + * } + * message Message { + * string text = 1; // The resource content. + * } + * + * This enables an HTTP REST to gRPC mapping as below: + * + * HTTP | gRPC + * -----|----- + * `GET /v1/messages/123456` | `GetMessage(name: "messages/123456")` + * + * Any fields in the request message which are not bound by the path template + * automatically become HTTP query parameters if there is no HTTP request body. + * For example: + * + * service Messaging { + * rpc GetMessage(GetMessageRequest) returns (Message) { + * option (google.api.http) = { + * get:"/v1/messages/{message_id}" + * }; + * } + * } + * message GetMessageRequest { + * message SubMessage { + * string subfield = 1; + * } + * string message_id = 1; // Mapped to URL path. + * int64 revision = 2; // Mapped to URL query parameter `revision`. + * SubMessage sub = 3; // Mapped to URL query parameter `sub.subfield`. + * } + * + * This enables a HTTP JSON to RPC mapping as below: + * + * HTTP | gRPC + * -----|----- + * `GET /v1/messages/123456?revision=2&sub.subfield=foo` | + * `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: + * "foo"))` + * + * Note that fields which are mapped to URL query parameters must have a + * primitive type or a repeated primitive type or a non-repeated message type. + * In the case of a repeated type, the parameter can be repeated in the URL + * as `...?param=A¶m=B`. In the case of a message type, each field of the + * message is mapped to a separate parameter, such as + * `...?foo.a=A&foo.b=B&foo.c=C`. + * + * For HTTP methods that allow a request body, the `body` field + * specifies the mapping. Consider a REST update method on the + * message resource collection: + * + * service Messaging { + * rpc UpdateMessage(UpdateMessageRequest) returns (Message) { + * option (google.api.http) = { + * patch: "/v1/messages/{message_id}" + * body: "message" + * }; + * } + * } + * message UpdateMessageRequest { + * string message_id = 1; // mapped to the URL + * Message message = 2; // mapped to the body + * } + * + * The following HTTP JSON to RPC mapping is enabled, where the + * representation of the JSON in the request body is determined by + * protos JSON encoding: + * + * HTTP | gRPC + * -----|----- + * `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: + * "123456" message { text: "Hi!" })` + * + * The special name `*` can be used in the body mapping to define that + * every field not bound by the path template should be mapped to the + * request body. This enables the following alternative definition of + * the update method: + * + * service Messaging { + * rpc UpdateMessage(Message) returns (Message) { + * option (google.api.http) = { + * patch: "/v1/messages/{message_id}" + * body: "*" + * }; + * } + * } + * message Message { + * string message_id = 1; + * string text = 2; + * } + * + * + * The following HTTP JSON to RPC mapping is enabled: + * + * HTTP | gRPC + * -----|----- + * `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: + * "123456" text: "Hi!")` + * + * Note that when using `*` in the body mapping, it is not possible to + * have HTTP parameters, as all fields not bound by the path end in + * the body. This makes this option more rarely used in practice when + * defining REST APIs. The common usage of `*` is in custom methods + * which don't use the URL at all for transferring data. + * + * It is possible to define multiple HTTP methods for one RPC by using + * the `additional_bindings` option. Example: + * + * service Messaging { + * rpc GetMessage(GetMessageRequest) returns (Message) { + * option (google.api.http) = { + * get: "/v1/messages/{message_id}" + * additional_bindings { + * get: "/v1/users/{user_id}/messages/{message_id}" + * } + * }; + * } + * } + * message GetMessageRequest { + * string message_id = 1; + * string user_id = 2; + * } + * + * This enables the following two alternative HTTP JSON to RPC mappings: + * + * HTTP | gRPC + * -----|----- + * `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` + * `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: + * "123456")` + * + * ## Rules for HTTP mapping + * + * 1. Leaf request fields (recursive expansion nested messages in the request + * message) are classified into three categories: + * - Fields referred by the path template. They are passed via the URL path. + * - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They are passed via the HTTP + * request body. + * - All other fields are passed via the URL query parameters, and the + * parameter name is the field path in the request message. A repeated + * field can be represented as multiple query parameters under the same + * name. + * 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL query parameter, all fields + * are passed via URL path and HTTP request body. + * 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP request body, all + * fields are passed via URL path and URL query parameters. + * + * ### Path template syntax + * + * Template = "/" Segments [ Verb ] ; + * Segments = Segment { "/" Segment } ; + * Segment = "*" | "**" | LITERAL | Variable ; + * Variable = "{" FieldPath [ "=" Segments ] "}" ; + * FieldPath = IDENT { "." IDENT } ; + * Verb = ":" LITERAL ; + * + * The syntax `*` matches a single URL path segment. The syntax `**` matches + * zero or more URL path segments, which must be the last part of the URL path + * except the `Verb`. + * + * The syntax `Variable` matches part of the URL path as specified by its + * template. A variable template must not contain other variables. If a variable + * matches a single path segment, its template may be omitted, e.g. `{var}` + * is equivalent to `{var=*}`. + * + * The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL` + * contains any reserved character, such characters should be percent-encoded + * before the matching. + * + * If a variable contains exactly one path segment, such as `"{var}"` or + * `"{var=*}"`, when such a variable is expanded into a URL path on the client + * side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The + * server side does the reverse decoding. Such variables show up in the + * [Discovery + * Document](https://developers.google.com/discovery/v1/reference/apis) as + * `{var}`. + * + * If a variable contains multiple path segments, such as `"{var=foo/*}"` + * or `"{var=**}"`, when such a variable is expanded into a URL path on the + * client side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. + * The server side does the reverse decoding, except "%2F" and "%2f" are left + * unchanged. Such variables show up in the + * [Discovery + * Document](https://developers.google.com/discovery/v1/reference/apis) as + * `{+var}`. + * + * ## Using gRPC API Service Configuration + * + * gRPC API Service Configuration (service config) is a configuration language + * for configuring a gRPC service to become a user-facing product. The + * service config is simply the YAML representation of the `google.api.Service` + * proto message. + * + * As an alternative to annotating your proto file, you can configure gRPC + * transcoding in your service config YAML files. You do this by specifying a + * `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same + * effect as the proto annotation. This can be particularly useful if you + * have a proto that is reused in multiple services. Note that any transcoding + * specified in the service config will override any matching transcoding + * configuration in the proto. + * + * Example: + * + * http: + * rules: + * # Selects a gRPC method and applies HttpRule to it. + * - selector: example.v1.Messaging.GetMessage + * get: /v1/messages/{message_id}/{sub.subfield} + * + * ## Special notes + * + * When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the + * proto to JSON conversion must follow the [proto3 + * specification](https://developers.google.com/protocol-buffers/docs/proto3#json). + * + * While the single segment variable follows the semantics of + * [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String + * Expansion, the multi segment variable **does not** follow RFC 6570 Section + * 3.2.3 Reserved Expansion. The reason is that the Reserved Expansion + * does not expand special characters like `?` and `#`, which would lead + * to invalid URLs. As the result, gRPC Transcoding uses a custom encoding + * for multi segment variables. + * + * The path variables **must not** refer to any repeated or mapped field, + * because client libraries are not capable of handling such variable expansion. + * + * The path variables **must not** capture the leading "/" character. The reason + * is that the most common use case "{var}" does not capture the leading "/" + * character. For consistency, all path variables must share the same behavior. + * + * Repeated message fields must not be mapped to URL query parameters, because + * no client library can support such complicated mapping. + * + * If an API needs to use a JSON array for request or response body, it can map + * the request or response body to a repeated field. However, some gRPC + * Transcoding implementations may not support this feature. + */ +export interface HttpRule__Output { + /** + * Selects a method to which this rule applies. + * + * Refer to [selector][google.api.DocumentationRule.selector] for syntax details. + */ + 'selector': (string); + /** + * Maps to HTTP GET. Used for listing and getting information about + * resources. + */ + 'get'?: (string); + /** + * Maps to HTTP PUT. Used for replacing a resource. + */ + 'put'?: (string); + /** + * Maps to HTTP POST. Used for creating a resource or performing an action. + */ + 'post'?: (string); + /** + * Maps to HTTP DELETE. Used for deleting a resource. + */ + 'delete'?: (string); + /** + * Maps to HTTP PATCH. Used for updating a resource. + */ + 'patch'?: (string); + /** + * The name of the request field whose value is mapped to the HTTP request + * body, or `*` for mapping all request fields not captured by the path + * pattern to the HTTP body, or omitted for not having any HTTP request body. + * + * NOTE: the referred field must be present at the top-level of the request + * message type. + */ + 'body': (string); + /** + * The custom pattern is used for specifying an HTTP method that is not + * included in the `pattern` field, such as HEAD, or "*" to leave the + * HTTP method unspecified for this rule. The wild-card rule is useful + * for services that provide content to Web (HTML) clients. + */ + 'custom'?: (_google_api_CustomHttpPattern__Output | null); + /** + * Additional HTTP bindings for the selector. Nested bindings must + * not contain an `additional_bindings` field themselves (that is, + * the nesting may only be one level deep). + */ + 'additional_bindings': (_google_api_HttpRule__Output)[]; + /** + * Optional. The name of the response field whose value is mapped to the HTTP + * response body. When omitted, the entire response message will be used + * as the HTTP response body. + * + * NOTE: The referred field must be present at the top-level of the response + * message type. + */ + 'response_body': (string); + /** + * Determines the URL pattern is matched by this rules. This pattern can be + * used with any of the {get|put|post|delete|patch} methods. A custom method + * can be defined using the 'custom' field. + */ + 'pattern': "get"|"put"|"post"|"delete"|"patch"|"custom"; +} diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/EnumValueOptions.ts b/packages/grpc-js-xds/src/generated/google/protobuf/EnumValueOptions.ts index 48fea77be..9ba51ed60 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/EnumValueOptions.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/EnumValueOptions.ts @@ -8,6 +8,7 @@ export interface EnumValueOptions { 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; '.envoy.annotations.disallowed_by_default_enum'?: (boolean); '.udpa.annotations.enum_value_migrate'?: (_udpa_annotations_MigrateAnnotation | null); + '.envoy.annotations.deprecated_at_minor_version_enum'?: (string); } export interface EnumValueOptions__Output { @@ -15,4 +16,5 @@ export interface EnumValueOptions__Output { 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; '.envoy.annotations.disallowed_by_default_enum': (boolean); '.udpa.annotations.enum_value_migrate': (_udpa_annotations_MigrateAnnotation__Output | null); + '.envoy.annotations.deprecated_at_minor_version_enum': (string); } 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 91af8a985..d62db88d0 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/FieldOptions.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/FieldOptions.ts @@ -2,6 +2,7 @@ import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; import type { FieldRules as _validate_FieldRules, FieldRules__Output as _validate_FieldRules__Output } from '../../validate/FieldRules'; +import type { FieldSecurityAnnotation as _udpa_annotations_FieldSecurityAnnotation, FieldSecurityAnnotation__Output as _udpa_annotations_FieldSecurityAnnotation__Output } from '../../udpa/annotations/FieldSecurityAnnotation'; import type { FieldMigrateAnnotation as _udpa_annotations_FieldMigrateAnnotation, FieldMigrateAnnotation__Output as _udpa_annotations_FieldMigrateAnnotation__Output } from '../../udpa/annotations/FieldMigrateAnnotation'; import type { FieldStatusAnnotation as _xds_annotations_v3_FieldStatusAnnotation, FieldStatusAnnotation__Output as _xds_annotations_v3_FieldStatusAnnotation__Output } from '../../xds/annotations/v3/FieldStatusAnnotation'; @@ -30,7 +31,9 @@ export interface FieldOptions { 'weak'?: (boolean); 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; '.validate.rules'?: (_validate_FieldRules | null); + '.udpa.annotations.security'?: (_udpa_annotations_FieldSecurityAnnotation | null); '.udpa.annotations.sensitive'?: (boolean); + '.envoy.annotations.deprecated_at_minor_version'?: (string); '.udpa.annotations.field_migrate'?: (_udpa_annotations_FieldMigrateAnnotation | null); '.envoy.annotations.disallowed_by_default'?: (boolean); '.xds.annotations.v3.field_status'?: (_xds_annotations_v3_FieldStatusAnnotation | null); @@ -45,7 +48,9 @@ export interface FieldOptions__Output { 'weak': (boolean); 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; '.validate.rules': (_validate_FieldRules__Output | null); + '.udpa.annotations.security': (_udpa_annotations_FieldSecurityAnnotation__Output | null); '.udpa.annotations.sensitive': (boolean); + '.envoy.annotations.deprecated_at_minor_version': (string); '.udpa.annotations.field_migrate': (_udpa_annotations_FieldMigrateAnnotation__Output | null); '.envoy.annotations.disallowed_by_default': (boolean); '.xds.annotations.v3.field_status': (_xds_annotations_v3_FieldStatusAnnotation__Output | null); diff --git a/packages/grpc-js-xds/src/generated/google/protobuf/MethodOptions.ts b/packages/grpc-js-xds/src/generated/google/protobuf/MethodOptions.ts index e47fd756c..5f81f0dd9 100644 --- a/packages/grpc-js-xds/src/generated/google/protobuf/MethodOptions.ts +++ b/packages/grpc-js-xds/src/generated/google/protobuf/MethodOptions.ts @@ -1,13 +1,16 @@ // Original file: null import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; +import type { HttpRule as _google_api_HttpRule, HttpRule__Output as _google_api_HttpRule__Output } from '../../google/api/HttpRule'; export interface MethodOptions { 'deprecated'?: (boolean); 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; + '.google.api.http'?: (_google_api_HttpRule | null); } export interface MethodOptions__Output { 'deprecated': (boolean); 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; + '.google.api.http': (_google_api_HttpRule__Output | null); } diff --git a/packages/grpc-js-xds/src/generated/http_connection_manager.ts b/packages/grpc-js-xds/src/generated/http_connection_manager.ts index 351e65400..137dcd45a 100644 --- a/packages/grpc-js-xds/src/generated/http_connection_manager.ts +++ b/packages/grpc-js-xds/src/generated/http_connection_manager.ts @@ -34,6 +34,7 @@ export interface ProtoGrpcType { v3: { Address: MessageTypeDefinition AggregatedConfigSource: MessageTypeDefinition + AlternateProtocolsCacheOptions: MessageTypeDefinition ApiConfigSource: MessageTypeDefinition ApiVersion: EnumTypeDefinition AsyncDataSource: MessageTypeDefinition @@ -63,6 +64,8 @@ export interface ProtoGrpcType { Node: MessageTypeDefinition Pipe: MessageTypeDefinition ProxyProtocolConfig: MessageTypeDefinition + QueryParameter: MessageTypeDefinition + QuicProtocolOptions: MessageTypeDefinition RateLimitSettings: MessageTypeDefinition RemoteDataSource: MessageTypeDefinition RequestMethod: EnumTypeDefinition @@ -73,6 +76,7 @@ export interface ProtoGrpcType { RuntimeFractionalPercent: MessageTypeDefinition RuntimePercent: MessageTypeDefinition RuntimeUInt32: MessageTypeDefinition + SchemeHeaderTransformation: MessageTypeDefinition SelfConfigSource: MessageTypeDefinition SocketAddress: MessageTypeDefinition SocketOption: MessageTypeDefinition @@ -88,6 +92,7 @@ export interface ProtoGrpcType { } route: { v3: { + ClusterSpecifierPlugin: MessageTypeDefinition CorsPolicy: MessageTypeDefinition Decorator: MessageTypeDefinition DirectResponseAction: MessageTypeDefinition @@ -96,6 +101,7 @@ export interface ProtoGrpcType { HeaderMatcher: MessageTypeDefinition HedgePolicy: MessageTypeDefinition InternalRedirectPolicy: MessageTypeDefinition + NonForwardingAction: MessageTypeDefinition QueryParameterMatcher: MessageTypeDefinition RateLimit: MessageTypeDefinition RedirectAction: MessageTypeDefinition @@ -123,6 +129,7 @@ export interface ProtoGrpcType { network: { http_connection_manager: { v3: { + EnvoyMobileHttpConnectionManager: MessageTypeDefinition HttpConnectionManager: MessageTypeDefinition HttpFilter: MessageTypeDefinition LocalReplyConfig: MessageTypeDefinition @@ -138,6 +145,11 @@ export interface ProtoGrpcType { } } type: { + http: { + v3: { + PathTransformation: MessageTypeDefinition + } + } matcher: { v3: { DoubleMatcher: MessageTypeDefinition @@ -262,6 +274,7 @@ export interface ProtoGrpcType { core: { v3: { Authority: MessageTypeDefinition + ContextParams: MessageTypeDefinition } } } diff --git a/packages/grpc-js-xds/src/generated/listener.ts b/packages/grpc-js-xds/src/generated/listener.ts index aac080a90..b92353ab1 100644 --- a/packages/grpc-js-xds/src/generated/listener.ts +++ b/packages/grpc-js-xds/src/generated/listener.ts @@ -34,6 +34,7 @@ export interface ProtoGrpcType { v3: { Address: MessageTypeDefinition AggregatedConfigSource: MessageTypeDefinition + AlternateProtocolsCacheOptions: MessageTypeDefinition ApiConfigSource: MessageTypeDefinition ApiVersion: EnumTypeDefinition AsyncDataSource: MessageTypeDefinition @@ -47,16 +48,24 @@ export interface ProtoGrpcType { EnvoyInternalAddress: MessageTypeDefinition Extension: MessageTypeDefinition ExtensionConfigSource: MessageTypeDefinition + GrpcProtocolOptions: MessageTypeDefinition GrpcService: MessageTypeDefinition HeaderMap: MessageTypeDefinition HeaderValue: MessageTypeDefinition HeaderValueOption: MessageTypeDefinition + Http1ProtocolOptions: MessageTypeDefinition + Http2ProtocolOptions: MessageTypeDefinition + Http3ProtocolOptions: MessageTypeDefinition + HttpProtocolOptions: MessageTypeDefinition HttpUri: MessageTypeDefinition + KeepaliveSettings: MessageTypeDefinition Locality: MessageTypeDefinition Metadata: MessageTypeDefinition Node: MessageTypeDefinition Pipe: MessageTypeDefinition ProxyProtocolConfig: MessageTypeDefinition + QueryParameter: MessageTypeDefinition + QuicProtocolOptions: MessageTypeDefinition RateLimitSettings: MessageTypeDefinition RemoteDataSource: MessageTypeDefinition RequestMethod: EnumTypeDefinition @@ -67,13 +76,17 @@ export interface ProtoGrpcType { RuntimeFractionalPercent: MessageTypeDefinition RuntimePercent: MessageTypeDefinition RuntimeUInt32: MessageTypeDefinition + SchemeHeaderTransformation: MessageTypeDefinition SelfConfigSource: MessageTypeDefinition SocketAddress: MessageTypeDefinition SocketOption: MessageTypeDefinition TcpKeepalive: MessageTypeDefinition + TcpProtocolOptions: MessageTypeDefinition TrafficDirection: EnumTypeDefinition TransportSocket: MessageTypeDefinition TypedExtensionConfig: MessageTypeDefinition + UdpSocketConfig: MessageTypeDefinition + UpstreamHttpProtocolOptions: MessageTypeDefinition WatchedDirectory: MessageTypeDefinition } } @@ -88,6 +101,7 @@ export interface ProtoGrpcType { ListenerCollection: MessageTypeDefinition ListenerFilter: MessageTypeDefinition ListenerFilterChainMatchPredicate: MessageTypeDefinition + QuicProtocolOptions: MessageTypeDefinition UdpListenerConfig: MessageTypeDefinition } } @@ -101,6 +115,7 @@ export interface ProtoGrpcType { HeaderMatcher: MessageTypeDefinition HedgePolicy: MessageTypeDefinition InternalRedirectPolicy: MessageTypeDefinition + NonForwardingAction: MessageTypeDefinition QueryParameterMatcher: MessageTypeDefinition RateLimit: MessageTypeDefinition RedirectAction: MessageTypeDefinition diff --git a/packages/grpc-js-xds/src/generated/lrs.ts b/packages/grpc-js-xds/src/generated/lrs.ts index 929fd6914..e92f80800 100644 --- a/packages/grpc-js-xds/src/generated/lrs.ts +++ b/packages/grpc-js-xds/src/generated/lrs.ts @@ -10,6 +10,8 @@ type SubtypeConstructor any, Subtype> export interface ProtoGrpcType { envoy: { + annotations: { + } api: { v2: { core: { @@ -73,6 +75,7 @@ export interface ProtoGrpcType { Metadata: MessageTypeDefinition Node: MessageTypeDefinition Pipe: MessageTypeDefinition + QueryParameter: MessageTypeDefinition RemoteDataSource: MessageTypeDefinition RequestMethod: EnumTypeDefinition RetryPolicy: MessageTypeDefinition @@ -200,5 +203,21 @@ export interface ProtoGrpcType { UInt32Rules: MessageTypeDefinition UInt64Rules: MessageTypeDefinition } + xds: { + annotations: { + v3: { + FieldStatusAnnotation: MessageTypeDefinition + FileStatusAnnotation: MessageTypeDefinition + MessageStatusAnnotation: MessageTypeDefinition + PackageVersionStatus: EnumTypeDefinition + StatusAnnotation: MessageTypeDefinition + } + } + core: { + v3: { + ContextParams: MessageTypeDefinition + } + } + } } diff --git a/packages/grpc-js-xds/src/generated/route.ts b/packages/grpc-js-xds/src/generated/route.ts index 67b9c5ce4..d6485bcd7 100644 --- a/packages/grpc-js-xds/src/generated/route.ts +++ b/packages/grpc-js-xds/src/generated/route.ts @@ -38,6 +38,7 @@ export interface ProtoGrpcType { Node: MessageTypeDefinition Pipe: MessageTypeDefinition ProxyProtocolConfig: MessageTypeDefinition + QueryParameter: MessageTypeDefinition RateLimitSettings: MessageTypeDefinition RemoteDataSource: MessageTypeDefinition RequestMethod: EnumTypeDefinition @@ -60,6 +61,7 @@ export interface ProtoGrpcType { } route: { v3: { + ClusterSpecifierPlugin: MessageTypeDefinition CorsPolicy: MessageTypeDefinition Decorator: MessageTypeDefinition DirectResponseAction: MessageTypeDefinition @@ -68,6 +70,7 @@ export interface ProtoGrpcType { HeaderMatcher: MessageTypeDefinition HedgePolicy: MessageTypeDefinition InternalRedirectPolicy: MessageTypeDefinition + NonForwardingAction: MessageTypeDefinition QueryParameterMatcher: MessageTypeDefinition RateLimit: MessageTypeDefinition RedirectAction: MessageTypeDefinition @@ -87,10 +90,14 @@ export interface ProtoGrpcType { type: { matcher: { v3: { + DoubleMatcher: MessageTypeDefinition + ListMatcher: MessageTypeDefinition ListStringMatcher: MessageTypeDefinition + MetadataMatcher: MessageTypeDefinition RegexMatchAndSubstitute: MessageTypeDefinition RegexMatcher: MessageTypeDefinition StringMatcher: MessageTypeDefinition + ValueMatcher: MessageTypeDefinition } } metadata: { @@ -204,6 +211,7 @@ export interface ProtoGrpcType { core: { v3: { Authority: MessageTypeDefinition + ContextParams: MessageTypeDefinition } } } diff --git a/packages/grpc-js-xds/src/resolver-xds.ts b/packages/grpc-js-xds/src/resolver-xds.ts index ab036184e..f6e2ad402 100644 --- a/packages/grpc-js-xds/src/resolver-xds.ts +++ b/packages/grpc-js-xds/src/resolver-xds.ts @@ -432,7 +432,12 @@ class XdsResolver implements Resolver { weightedClusters.push({name: clusterWeight.name, weight: clusterWeight.weight?.value ?? 0, dynamicFilterFactories: extraFilterFactories}); } routeAction = new WeightedClusterRouteAction(weightedClusters, route.route!.weighted_clusters!.total_weight?.value ?? 100, timeout); + break; } + default: + /* The validation logic should prevent us from reaching this point. + * This is just for the type checker. */ + continue; } const routeMatcher = getPredicateForMatcher(route.match!); matchList.push({matcher: routeMatcher, action: routeAction}); From dca36701fc15b85cfe28f727658496d084fd3339 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 2 Dec 2021 16:14:40 -0500 Subject: [PATCH 138/450] grpc-js-xds: Add details to ADS response handling result --- packages/grpc-js-xds/src/xds-client.ts | 128 ++++++++++-------- .../src/xds-stream-state/cds-state.ts | 37 +++-- .../src/xds-stream-state/eds-state.ts | 30 ++-- .../src/xds-stream-state/lds-state.ts | 38 ++++-- .../src/xds-stream-state/rds-state.ts | 30 ++-- .../src/xds-stream-state/xds-stream-state.ts | 25 +++- 6 files changed, 193 insertions(+), 95 deletions(-) diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index 8a08276eb..6c8bcb67f 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -45,7 +45,7 @@ import { EdsState } from './xds-stream-state/eds-state'; import { CdsState } from './xds-stream-state/cds-state'; import { RdsState } from './xds-stream-state/rds-state'; import { LdsState } from './xds-stream-state/lds-state'; -import { Watcher } from './xds-stream-state/xds-stream-state'; +import { HandleResponseResult, ResourcePair, Watcher } from './xds-stream-state/xds-stream-state'; import { ClusterLoadAssignment__Output } from './generated/envoy/config/endpoint/v3/ClusterLoadAssignment'; import { Cluster__Output } from './generated/envoy/config/cluster/v3/Cluster'; import { RouteConfiguration__Output } from './generated/envoy/config/route/v3/RouteConfiguration'; @@ -242,11 +242,14 @@ function getResponseMessages( targetTypeUrl: T, allowedTypeUrls: string[], resources: Any__Output[] -): AdsOutputType[] { - const result: AdsOutputType[] = []; +): ResourcePair>[] { + const result: ResourcePair>[] = []; for (const resource of resources) { if (allowedTypeUrls.includes(resource.type_url)) { - result.push(decodeSingleResource(targetTypeUrl, resource.value)); + result.push({ + resource: decodeSingleResource(targetTypeUrl, resource.value), + raw: resource + }); } else { throw new Error( `ADS Error: Invalid resource type ${resource.type_url}, expected ${allowedTypeUrls}` @@ -450,8 +453,10 @@ export class XdsClient { } private handleAdsResponse(message: DiscoveryResponse__Output) { - let errorString: string | null; - let serviceKind: AdsServiceKind; + let handleResponseResult: { + result: HandleResponseResult; + serviceKind: AdsServiceKind; + } | null = null; let isV2: boolean; switch (message.type_url) { case EDS_TYPE_URL_V2: @@ -463,56 +468,71 @@ export class XdsClient { default: isV2 = false; } - switch (message.type_url) { - case EDS_TYPE_URL_V2: - case EDS_TYPE_URL_V3: - errorString = this.adsState.eds.handleResponses( - getResponseMessages(EDS_TYPE_URL_V3, [EDS_TYPE_URL_V2, EDS_TYPE_URL_V3], message.resources), - isV2 - ); - serviceKind = 'eds'; - break; - case CDS_TYPE_URL_V2: - case CDS_TYPE_URL_V3: - errorString = this.adsState.cds.handleResponses( - getResponseMessages(CDS_TYPE_URL_V3, [CDS_TYPE_URL_V2, CDS_TYPE_URL_V3], message.resources), - isV2 - ); - serviceKind = 'cds'; - break; - case RDS_TYPE_URL_V2: - case RDS_TYPE_URL_V3: - errorString = this.adsState.rds.handleResponses( - getResponseMessages(RDS_TYPE_URL_V3, [RDS_TYPE_URL_V2, RDS_TYPE_URL_V3], message.resources), - isV2 - ); - serviceKind = 'rds'; - break; - case LDS_TYPE_URL_V2: - case LDS_TYPE_URL_V3: - errorString = this.adsState.lds.handleResponses( - getResponseMessages(LDS_TYPE_URL_V3, [LDS_TYPE_URL_V2, LDS_TYPE_URL_V3], message.resources), - isV2 - ); - serviceKind = 'lds'; - break; - default: - errorString = `Unknown type_url ${message.type_url}`; - // This is not used in this branch, but setting it makes the types easier to handle - serviceKind = 'eds'; + try { + switch (message.type_url) { + case EDS_TYPE_URL_V2: + case EDS_TYPE_URL_V3: + handleResponseResult = { + result: this.adsState.eds.handleResponses( + getResponseMessages(EDS_TYPE_URL_V3, [EDS_TYPE_URL_V2, EDS_TYPE_URL_V3], message.resources), + isV2 + ), + serviceKind: 'eds' + }; + break; + case CDS_TYPE_URL_V2: + case CDS_TYPE_URL_V3: + handleResponseResult = { + result: this.adsState.cds.handleResponses( + getResponseMessages(CDS_TYPE_URL_V3, [CDS_TYPE_URL_V2, CDS_TYPE_URL_V3], message.resources), + isV2 + ), + serviceKind: 'cds' + }; + break; + case RDS_TYPE_URL_V2: + case RDS_TYPE_URL_V3: + handleResponseResult = { + result: this.adsState.rds.handleResponses( + getResponseMessages(RDS_TYPE_URL_V3, [RDS_TYPE_URL_V2, RDS_TYPE_URL_V3], message.resources), + isV2 + ), + serviceKind: 'rds' + }; + break; + case LDS_TYPE_URL_V2: + case LDS_TYPE_URL_V3: + handleResponseResult = { + result: this.adsState.lds.handleResponses( + getResponseMessages(LDS_TYPE_URL_V3, [LDS_TYPE_URL_V2, LDS_TYPE_URL_V3], message.resources), + isV2 + ), + serviceKind: 'lds' + } + break; + } + } catch (e) { + trace('Nacking message with protobuf parsing error: ' + e.message); + this.nack(message.type_url, e.message); } - if (errorString === null) { - trace('Acking message with type URL ' + message.type_url); - /* errorString can only be null in one of the first 4 cases, which - * implies that message.type_url is one of the 4 known type URLs, which - * means that this type assertion is valid. */ - const typeUrl = message.type_url as AdsTypeUrl; - this.adsState[serviceKind].nonce = message.nonce; - this.adsState[serviceKind].versionInfo = message.version_info; - this.ack(serviceKind); + if (handleResponseResult === null) { + // Null handleResponseResult means that the type_url was unrecognized + trace('Nacking message with unknown type URL ' + message.type_url); + this.nack(message.type_url, `Unknown type_url ${message.type_url}`); } else { - trace('Nacking message with type URL ' + message.type_url + ': "' + errorString + '"'); - this.nack(message.type_url, errorString); + if (handleResponseResult.result.rejected.length > 0) { + // rejected.length > 0 means that at least one message validation failed + const errorString = `${handleResponseResult.serviceKind.toUpperCase()} Error: ${handleResponseResult.result.rejected[0].error}`; + trace('Nacking message with type URL ' + message.type_url + ': ' + errorString); + this.nack(message.type_url, errorString); + } else { + // If we get here, all message validation succeeded + trace('Acking message with type URL ' + message.type_url); + const serviceKind = handleResponseResult.serviceKind; + this.adsState[serviceKind].nonce = message.nonce; + this.adsState[serviceKind].versionInfo = message.version_info; + this.ack(serviceKind); + } } } diff --git a/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts index 05477388d..ce0434b8b 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts @@ -17,8 +17,9 @@ import { experimental, logVerbosity, StatusObject } from "@grpc/grpc-js"; import { Cluster__Output } from "../generated/envoy/config/cluster/v3/Cluster"; +import { Any__Output } from "../generated/google/protobuf/Any"; import { EdsState } from "./eds-state"; -import { Watcher, XdsStreamState } from "./xds-stream-state"; +import { HandleResponseResult, RejectedResourceEntry, ResourcePair, Watcher, XdsStreamState } from "./xds-stream-state"; const TRACER_NAME = 'xds_client'; @@ -125,26 +126,40 @@ export class CdsState implements XdsStreamState { * onResourceDoesNotExist method. * @param allClusterNames */ - private handleMissingNames(allClusterNames: Set) { + private handleMissingNames(allClusterNames: Set): string[] { + const missingNames: string[] = []; for (const [clusterName, watcherList] of this.watchers.entries()) { if (!allClusterNames.has(clusterName)) { trace('Reporting CDS resource does not exist for clusterName ' + clusterName); + missingNames.push(clusterName); for (const watcher of watcherList) { watcher.onResourceDoesNotExist(); } } } + return missingNames; } - handleResponses(responses: Cluster__Output[], isV2: boolean): string | null { + handleResponses(responses: ResourcePair[], isV2: boolean): HandleResponseResult { const validResponses: Cluster__Output[] = []; - let errorMessage: string | null = null; - for (const message of responses) { - if (this.validateResponse(message)) { - validResponses.push(message); + const result: HandleResponseResult = { + accepted: [], + rejected: [], + missing: [] + } + for (const {resource, raw} of responses) { + if (this.validateResponse(resource)) { + validResponses.push(resource); + result.accepted.push({ + name: resource.name, + raw: raw}); } else { - trace('CDS validation failed for message ' + JSON.stringify(message)); - errorMessage = 'CDS Error: Cluster validation failed'; + trace('CDS validation failed for message ' + JSON.stringify(resource)); + result.rejected.push({ + name: resource.name, + raw: raw, + error: `Cluster validation failed for resource ${resource.name}` + }); } } this.latestResponses = validResponses; @@ -163,9 +178,9 @@ export class CdsState implements XdsStreamState { } } trace('Received CDS updates for cluster names [' + Array.from(allClusterNames) + ']'); - this.handleMissingNames(allClusterNames); + result.missing = this.handleMissingNames(allClusterNames); this.edsState.handleMissingNames(allEdsServiceNames); - return errorMessage; + return result; } reportStreamError(status: StatusObject): void { diff --git a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts index f5a8b774f..5360400c5 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts @@ -18,7 +18,8 @@ import { experimental, logVerbosity, StatusObject } from "@grpc/grpc-js"; import { isIPv4, isIPv6 } from "net"; import { ClusterLoadAssignment__Output } from "../generated/envoy/config/endpoint/v3/ClusterLoadAssignment"; -import { Watcher, XdsStreamState } from "./xds-stream-state"; +import { Any__Output } from "../generated/google/protobuf/Any"; +import { HandleResponseResult, RejectedResourceEntry, ResourcePair, Watcher, XdsStreamState } from "./xds-stream-state"; const TRACER_NAME = 'xds_client'; @@ -145,15 +146,26 @@ export class EdsState implements XdsStreamState { } } - handleResponses(responses: ClusterLoadAssignment__Output[], isV2: boolean) { + handleResponses(responses: ResourcePair[], isV2: boolean): HandleResponseResult { const validResponses: ClusterLoadAssignment__Output[] = []; - let errorMessage: string | null = null; - for (const message of responses) { - if (this.validateResponse(message)) { - validResponses.push(message); + let result: HandleResponseResult = { + accepted: [], + rejected: [], + missing: [] + } + for (const {resource, raw} of responses) { + if (this.validateResponse(resource)) { + validResponses.push(resource); + result.accepted.push({ + name: resource.cluster_name, + raw: raw}); } else { - trace('EDS validation failed for message ' + JSON.stringify(message)); - errorMessage = 'EDS Error: ClusterLoadAssignment validation failed'; + trace('EDS validation failed for message ' + JSON.stringify(resource)); + result.rejected.push({ + name: resource.cluster_name, + raw: raw, + error: `ClusterLoadAssignment validation failed for resource ${resource.cluster_name}` + }); } } this.latestResponses = validResponses; @@ -167,7 +179,7 @@ export class EdsState implements XdsStreamState { } } trace('Received EDS updates for cluster names [' + Array.from(allClusterNames) + ']'); - return errorMessage; + return result; } reportStreamError(status: StatusObject): void { diff --git a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts index 7318b3b8a..0c4fdc516 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts @@ -19,11 +19,12 @@ import * as protoLoader from '@grpc/proto-loader'; import { experimental, logVerbosity, StatusObject } from "@grpc/grpc-js"; import { Listener__Output } from '../generated/envoy/config/listener/v3/Listener'; import { RdsState } from "./rds-state"; -import { Watcher, XdsStreamState } from "./xds-stream-state"; +import { HandleResponseResult, RejectedResourceEntry, ResourcePair, Watcher, XdsStreamState } from "./xds-stream-state"; import { HttpConnectionManager__Output } from '../generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpConnectionManager'; import { decodeSingleResource, HTTP_CONNECTION_MANGER_TYPE_URL_V2, HTTP_CONNECTION_MANGER_TYPE_URL_V3 } from '../resources'; import { getTopLevelFilterUrl, validateTopLevelFilter } from '../http-filter'; import { EXPERIMENTAL_FAULT_INJECTION } from '../environment'; +import { Any__Output } from '../generated/google/protobuf/Any'; const TRACER_NAME = 'xds_client'; @@ -143,25 +144,40 @@ export class LdsState implements XdsStreamState { return false; } - private handleMissingNames(allTargetNames: Set) { + private handleMissingNames(allTargetNames: Set): string[] { + const missingNames: string[] = []; for (const [targetName, watcherList] of this.watchers.entries()) { if (!allTargetNames.has(targetName)) { + missingNames.push(targetName); for (const watcher of watcherList) { watcher.onResourceDoesNotExist(); } } } + return missingNames; } - handleResponses(responses: Listener__Output[], isV2: boolean): string | null { + handleResponses(responses: ResourcePair[], isV2: boolean): HandleResponseResult { const validResponses: Listener__Output[] = []; - let errorMessage: string | null = null; - for (const message of responses) { - if (this.validateResponse(message, isV2)) { - validResponses.push(message); + let result: HandleResponseResult = { + accepted: [], + rejected: [], + missing: [] + } + for (const {resource, raw} of responses) { + if (this.validateResponse(resource, isV2)) { + validResponses.push(resource); + result.accepted.push({ + name: resource.name, + raw: raw + }); } else { - trace('LDS validation failed for message ' + JSON.stringify(message)); - errorMessage = 'LDS Error: Route validation failed'; + trace('LDS validation failed for message ' + JSON.stringify(resource)); + result.rejected.push({ + name: resource.name, + raw: raw, + error: `Listener validation failed for resource ${resource.name}` + }); } } this.latestResponses = validResponses; @@ -180,9 +196,9 @@ export class LdsState implements XdsStreamState { } } trace('Received LDS response with listener names [' + Array.from(allTargetNames) + ']'); - this.handleMissingNames(allTargetNames); + result.missing = this.handleMissingNames(allTargetNames); this.rdsState.handleMissingNames(allRouteConfigNames); - return errorMessage; + return result; } reportStreamError(status: StatusObject): void { diff --git a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts index bb7e0bc51..0ff4c2aae 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts @@ -18,9 +18,10 @@ import { experimental, logVerbosity, StatusObject } from "@grpc/grpc-js"; import { EXPERIMENTAL_FAULT_INJECTION } from "../environment"; import { RouteConfiguration__Output } from "../generated/envoy/config/route/v3/RouteConfiguration"; +import { Any__Output } from "../generated/google/protobuf/Any"; import { validateOverrideFilter } from "../http-filter"; import { CdsLoadBalancingConfig } from "../load-balancer-cds"; -import { Watcher, XdsStreamState } from "./xds-stream-state"; +import { HandleResponseResult, RejectedResourceEntry, ResourcePair, Watcher, XdsStreamState } from "./xds-stream-state"; import ServiceConfig = experimental.ServiceConfig; const TRACER_NAME = 'xds_client'; @@ -182,15 +183,26 @@ export class RdsState implements XdsStreamState { } } - handleResponses(responses: RouteConfiguration__Output[], isV2: boolean): string | null { + handleResponses(responses: ResourcePair[], isV2: boolean): HandleResponseResult { const validResponses: RouteConfiguration__Output[] = []; - let errorMessage: string | null = null; - for (const message of responses) { - if (this.validateResponse(message, isV2)) { - validResponses.push(message); + let result: HandleResponseResult = { + accepted: [], + rejected: [], + missing: [] + } + for (const {resource, raw} of responses) { + if (this.validateResponse(resource, isV2)) { + validResponses.push(resource); + result.accepted.push({ + name: resource.name, + raw: raw}); } else { - trace('RDS validation failed for message ' + JSON.stringify(message)); - errorMessage = 'RDS Error: Route validation failed'; + trace('RDS validation failed for message ' + JSON.stringify(resource)); + result.rejected.push({ + name: resource.name, + raw: raw, + error: `Route validation failed for resource ${resource.name}` + }); } } this.latestResponses = validResponses; @@ -204,7 +216,7 @@ export class RdsState implements XdsStreamState { } } trace('Received RDS response with route config names [' + Array.from(allRouteConfigNames) + ']'); - return errorMessage; + return result; } reportStreamError(status: StatusObject): void { diff --git a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts index 14f3d1c76..c8cbc41cf 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts @@ -16,6 +16,7 @@ */ import { StatusObject } from "@grpc/grpc-js"; +import { Any__Output } from "../generated/google/protobuf/Any"; export interface Watcher { /* Including the isV2 flag here is a bit of a kludge. It would probably be @@ -28,6 +29,28 @@ export interface Watcher { onResourceDoesNotExist(): void; } +export interface ResourcePair { + resource: ResourceType; + raw: Any__Output; +} + +export interface AcceptedResourceEntry { + name: string; + raw: Any__Output; +} + +export interface RejectedResourceEntry { + name: string; + raw: Any__Output; + error: string; +} + +export interface HandleResponseResult { + accepted: AcceptedResourceEntry[]; + rejected: RejectedResourceEntry[]; + missing: string[]; +} + export interface XdsStreamState { versionInfo: string; nonce: string; @@ -37,7 +60,7 @@ export interface XdsStreamState { * or null if it should be acked. * @param responses */ - handleResponses(responses: ResponseType[], isV2: boolean): string | null; + handleResponses(responses: ResourcePair[], isV2: boolean): HandleResponseResult; reportStreamError(status: StatusObject): void; } \ No newline at end of file From 858d1b66ad57fa0eed03877c8b5deae08f3fd653 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 2 Dec 2021 16:15:09 -0500 Subject: [PATCH 139/450] grpc-js-xds: Implement CSDS --- packages/grpc-js-xds/src/csds.ts | 204 ++++++++++++++++++++++++++++++ packages/grpc-js-xds/src/index.ts | 2 + 2 files changed, 206 insertions(+) create mode 100644 packages/grpc-js-xds/src/csds.ts diff --git a/packages/grpc-js-xds/src/csds.ts b/packages/grpc-js-xds/src/csds.ts new file mode 100644 index 000000000..19f1e9660 --- /dev/null +++ b/packages/grpc-js-xds/src/csds.ts @@ -0,0 +1,204 @@ +/* + * Copyright 2021 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 { Node } from "./generated/envoy/config/core/v3/Node"; +import { ClientConfig, _envoy_service_status_v3_ClientConfig_GenericXdsConfig as GenericXdsConfig } from "./generated/envoy/service/status/v3/ClientConfig"; +import { ClientStatusDiscoveryServiceHandlers } from "./generated/envoy/service/status/v3/ClientStatusDiscoveryService"; +import { ClientStatusRequest__Output } from "./generated/envoy/service/status/v3/ClientStatusRequest"; +import { ClientStatusResponse } from "./generated/envoy/service/status/v3/ClientStatusResponse"; +import { Timestamp } from "./generated/google/protobuf/Timestamp"; +import { AdsTypeUrl, CDS_TYPE_URL_V2, CDS_TYPE_URL_V3, EDS_TYPE_URL_V2, EDS_TYPE_URL_V3, LDS_TYPE_URL_V2, LDS_TYPE_URL_V3, RDS_TYPE_URL_V2, RDS_TYPE_URL_V3 } from "./resources"; +import { HandleResponseResult } from "./xds-stream-state/xds-stream-state"; +import { sendUnaryData, ServerDuplexStream, ServerUnaryCall, status, experimental, loadPackageDefinition } from '@grpc/grpc-js'; +import { loadSync } from "@grpc/proto-loader"; +import { ProtoGrpcType as CsdsProtoGrpcType } from "./generated/csds"; + +import registerAdminService = experimental.registerAdminService; + + +function dateToProtoTimestamp(date?: Date | null): Timestamp | null { + if (!date) { + return null; + } + const millisSinceEpoch = date.getTime(); + return { + seconds: (millisSinceEpoch / 1000) | 0, + nanos: (millisSinceEpoch % 1000) * 1_000_000 + } +} + +let clientNode: Node | null = null; + +const configStatus = { + [EDS_TYPE_URL_V2]: new Map(), + [EDS_TYPE_URL_V3]: new Map(), + [CDS_TYPE_URL_V2]: new Map(), + [CDS_TYPE_URL_V3]: new Map(), + [RDS_TYPE_URL_V2]: new Map(), + [RDS_TYPE_URL_V3]: new Map(), + [LDS_TYPE_URL_V2]: new Map(), + [LDS_TYPE_URL_V3]: new Map() +}; + +/** + * This function only accepts a v3 Node message, because we are only supporting + * v3 CSDS and it only handles v3 Nodes. If the client is actually using v2 xDS + * APIs, it should just provide the equivalent v3 Node message. + * @param node The Node message for the client that is requesting resources + */ +export function setCsdsClientNode(node: Node) { + clientNode = node; +} + +/** + * Update the config status maps from the list of names of requested resources + * for a specific type URL. These lists are the source of truth for determining + * what resources will be listed in the CSDS response. Any resource that is not + * in this list will never actually be applied anywhere. + * @param typeUrl The resource type URL + * @param names The list of resource names that are being requested + */ +export function updateRequestedNameList(typeUrl: AdsTypeUrl, names: string[]) { + const currentTime = dateToProtoTimestamp(new Date()); + const configMap = configStatus[typeUrl]; + for (const name of names) { + if (!configMap.has(name)) { + configMap.set(name, { + type_url: typeUrl, + name: name, + last_updated: currentTime, + client_status: 'REQUESTED' + }); + } + } + for (const name of configMap.keys()) { + if (!names.includes(name)) { + configMap.delete(name); + } + } +} + +/** + * Update the config status maps from the result of parsing a single ADS + * response. All resources that validated are considered "ACKED", and all + * resources that failed validation are considered "NACKED". + * @param typeUrl The type URL of resources in this response + * @param versionInfo The version info field from this response + * @param updates The lists of resources that passed and failed validation + */ +export function updateResourceResponse(typeUrl: AdsTypeUrl, versionInfo: string, updates: HandleResponseResult) { + const currentTime = dateToProtoTimestamp(new Date()); + const configMap = configStatus[typeUrl]; + for (const {name, raw} of updates.accepted) { + const mapEntry = configMap.get(name); + if (mapEntry) { + mapEntry.client_status = 'ACKED'; + mapEntry.version_info = versionInfo; + mapEntry.xds_config = raw; + mapEntry.error_state = null; + mapEntry.last_updated = currentTime; + } + } + for (const {name, error, raw} of updates.rejected) { + const mapEntry = configMap.get(name); + if (mapEntry) { + mapEntry.client_status = 'NACKED'; + mapEntry.error_state = { + failed_configuration: raw, + last_update_attempt: currentTime, + details: error, + version_info: versionInfo + }; + } + } + for (const name of updates.missing) { + const mapEntry = configMap.get(name); + if (mapEntry) { + mapEntry.client_status = 'DOES_NOT_EXIST'; + mapEntry.version_info = versionInfo; + mapEntry.xds_config = null; + mapEntry.error_state = null; + mapEntry.last_updated = currentTime; + } + } +} + +function getCurrentConfig(): ClientConfig { + const genericConfigList: GenericXdsConfig[] = []; + for (const configMap of Object.values(configStatus)) { + for (const configValue of configMap.values()) { + genericConfigList.push(configValue); + } + } + return { + node: clientNode, + generic_xds_configs: genericConfigList + }; +} + +const csdsImplementation: ClientStatusDiscoveryServiceHandlers = { + FetchClientStatus(call: ServerUnaryCall, callback: sendUnaryData) { + const request = call.request; + if (request.node_matchers !== null) { + callback({ + code: status.INVALID_ARGUMENT, + details: 'Node matchers not supported' + }); + return; + } + callback(null, { + config: [getCurrentConfig()] + }); + }, + StreamClientStatus(call: ServerDuplexStream) { + call.on('data', (request: ClientStatusRequest__Output) => { + if (request.node_matchers !== null) { + call.emit('error', { + code: status.INVALID_ARGUMENT, + details: 'Node matchers not supported' + }); + return; + } + call.write({ + config: [getCurrentConfig()] + }); + }); + call.on('end', () => { + call.end(); + }); + } +} + +const loadedProto = loadSync('envoy/service/status/v3/csds.proto', { + keepCase: true, + longs: String, + enums: String, + defaults: true, + oneofs: true, + includeDirs: [ + // Paths are relative to src/build + __dirname + '/../../deps/envoy-api/', + __dirname + '/../../deps/xds/', + ], +}); + +const csdsGrpcObject = loadPackageDefinition(loadedProto) as unknown as CsdsProtoGrpcType; +const csdsServiceDefinition = csdsGrpcObject.envoy.service.status.v3.ClientStatusDiscoveryService.service; + +export function setup() { + registerAdminService(() => csdsServiceDefinition, () => csdsImplementation); +} \ No newline at end of file diff --git a/packages/grpc-js-xds/src/index.ts b/packages/grpc-js-xds/src/index.ts index 7d35bcd1e..ca1cf72ef 100644 --- a/packages/grpc-js-xds/src/index.ts +++ b/packages/grpc-js-xds/src/index.ts @@ -24,6 +24,7 @@ import * as load_balancer_weighted_target from './load-balancer-weighted-target' import * as load_balancer_xds_cluster_manager from './load-balancer-xds-cluster-manager'; import * as router_filter from './http-filter/router-filter'; import * as fault_injection_filter from './http-filter/fault-injection-filter'; +import * as csds from './csds'; /** * Register the "xds:" name scheme with the @grpc/grpc-js library. @@ -38,4 +39,5 @@ export function register() { load_balancer_xds_cluster_manager.setup(); router_filter.setup(); fault_injection_filter.setup(); + csds.setup(); } \ No newline at end of file From adc25c25f3503c2743a17738e35dc7493c952708 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 2 Dec 2021 16:21:19 -0500 Subject: [PATCH 140/450] grpc-js-xds: Expose admin service in interop client, enable CSDS test --- packages/grpc-js-xds/interop/xds-interop-client.ts | 1 + packages/grpc-js-xds/scripts/xds.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/interop/xds-interop-client.ts b/packages/grpc-js-xds/interop/xds-interop-client.ts index 6cd3aeb33..029525a45 100644 --- a/packages/grpc-js-xds/interop/xds-interop-client.ts +++ b/packages/grpc-js-xds/interop/xds-interop-client.ts @@ -404,6 +404,7 @@ function main() { const server = new grpc.Server(); server.addService(loadedProto.grpc.testing.LoadBalancerStatsService.service, loadBalancerStatsServiceImpl); server.addService(loadedProto.grpc.testing.XdsUpdateClientConfigureService.service, xdsUpdateClientConfigureServiceImpl); + grpc.addAdminServicesToServer(server); server.bindAsync(`0.0.0.0:${argv.stats_port}`, grpc.ServerCredentials.createInsecure(), (error, port) => { if (error) { throw error; diff --git a/packages/grpc-js-xds/scripts/xds.sh b/packages/grpc-js-xds/scripts/xds.sh index a06cde84b..7fc09e2b1 100755 --- a/packages/grpc-js-xds/scripts/xds.sh +++ b/packages/grpc-js-xds/scripts/xds.sh @@ -52,7 +52,7 @@ GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weigh GRPC_NODE_VERBOSITY=DEBUG \ NODE_XDS_INTEROP_VERBOSITY=1 \ python3 grpc/tools/run_tests/run_xds_tests.py \ - --test_case="all,timeout,circuit_breaking,fault_injection" \ + --test_case="all,timeout,circuit_breaking,fault_injection,csds" \ --project_id=grpc-testing \ --source_image=projects/grpc-testing/global/images/xds-test-server-4 \ --path_to_server_binary=/java_server/grpc-java/interop-testing/build/install/grpc-interop-testing/bin/xds-test-server \ From 29711cd526133ab3b4e4d7e728113331e920bacf Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 2 Dec 2021 18:00:07 -0500 Subject: [PATCH 141/450] grpc-js-xds: CSDS: add tracing and fix bugs --- packages/grpc-js-xds/scripts/xds.sh | 2 +- packages/grpc-js-xds/src/csds.ts | 24 ++++++++++++++++++------ packages/grpc-js-xds/src/xds-client.ts | 12 ++++++++++++ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/packages/grpc-js-xds/scripts/xds.sh b/packages/grpc-js-xds/scripts/xds.sh index 7fc09e2b1..c7a9adb6e 100755 --- a/packages/grpc-js-xds/scripts/xds.sh +++ b/packages/grpc-js-xds/scripts/xds.sh @@ -48,7 +48,7 @@ git clone -b master --single-branch --depth=1 https://github.com/grpc/grpc.git grpc/tools/run_tests/helper_scripts/prep_xds.sh -GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weighted_target,round_robin,resolving_load_balancer,subchannel,keepalive,dns_resolver,fault_injection,http_filter \ +GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weighted_target,round_robin,resolving_load_balancer,subchannel,keepalive,dns_resolver,fault_injection,http_filter,csds \ GRPC_NODE_VERBOSITY=DEBUG \ NODE_XDS_INTEROP_VERBOSITY=1 \ python3 grpc/tools/run_tests/run_xds_tests.py \ diff --git a/packages/grpc-js-xds/src/csds.ts b/packages/grpc-js-xds/src/csds.ts index 19f1e9660..40ca67f1f 100644 --- a/packages/grpc-js-xds/src/csds.ts +++ b/packages/grpc-js-xds/src/csds.ts @@ -23,12 +23,18 @@ import { ClientStatusResponse } from "./generated/envoy/service/status/v3/Client import { Timestamp } from "./generated/google/protobuf/Timestamp"; import { AdsTypeUrl, CDS_TYPE_URL_V2, CDS_TYPE_URL_V3, EDS_TYPE_URL_V2, EDS_TYPE_URL_V3, LDS_TYPE_URL_V2, LDS_TYPE_URL_V3, RDS_TYPE_URL_V2, RDS_TYPE_URL_V3 } from "./resources"; import { HandleResponseResult } from "./xds-stream-state/xds-stream-state"; -import { sendUnaryData, ServerDuplexStream, ServerUnaryCall, status, experimental, loadPackageDefinition } from '@grpc/grpc-js'; +import { sendUnaryData, ServerDuplexStream, ServerUnaryCall, status, experimental, loadPackageDefinition, logVerbosity } from '@grpc/grpc-js'; import { loadSync } from "@grpc/proto-loader"; import { ProtoGrpcType as CsdsProtoGrpcType } from "./generated/csds"; import registerAdminService = experimental.registerAdminService; +const TRACER_NAME = 'csds'; + +function trace(text: string): void { + experimental.trace(logVerbosity.DEBUG, TRACER_NAME, text); +} + function dateToProtoTimestamp(date?: Date | null): Timestamp | null { if (!date) { @@ -72,7 +78,8 @@ export function setCsdsClientNode(node: Node) { * @param typeUrl The resource type URL * @param names The list of resource names that are being requested */ -export function updateRequestedNameList(typeUrl: AdsTypeUrl, names: string[]) { +export function updateCsdsRequestedNameList(typeUrl: AdsTypeUrl, names: string[]) { + trace('Update type URL ' + typeUrl + ' with names [' + names + ']'); const currentTime = dateToProtoTimestamp(new Date()); const configMap = configStatus[typeUrl]; for (const name of names) { @@ -100,12 +107,13 @@ export function updateRequestedNameList(typeUrl: AdsTypeUrl, names: string[]) { * @param versionInfo The version info field from this response * @param updates The lists of resources that passed and failed validation */ -export function updateResourceResponse(typeUrl: AdsTypeUrl, versionInfo: string, updates: HandleResponseResult) { +export function updateCsdsResourceResponse(typeUrl: AdsTypeUrl, versionInfo: string, updates: HandleResponseResult) { const currentTime = dateToProtoTimestamp(new Date()); const configMap = configStatus[typeUrl]; for (const {name, raw} of updates.accepted) { const mapEntry = configMap.get(name); if (mapEntry) { + trace('Updated ' + typeUrl + ' resource ' + name + ' to state ACKED'); mapEntry.client_status = 'ACKED'; mapEntry.version_info = versionInfo; mapEntry.xds_config = raw; @@ -116,6 +124,7 @@ export function updateResourceResponse(typeUrl: AdsTypeUrl, versionInfo: string, for (const {name, error, raw} of updates.rejected) { const mapEntry = configMap.get(name); if (mapEntry) { + trace('Updated ' + typeUrl + ' resource ' + name + ' to state NACKED'); mapEntry.client_status = 'NACKED'; mapEntry.error_state = { failed_configuration: raw, @@ -128,6 +137,7 @@ export function updateResourceResponse(typeUrl: AdsTypeUrl, versionInfo: string, for (const name of updates.missing) { const mapEntry = configMap.get(name); if (mapEntry) { + trace('Updated ' + typeUrl + ' resource ' + name + ' to state DOES_NOT_EXIST'); mapEntry.client_status = 'DOES_NOT_EXIST'; mapEntry.version_info = versionInfo; mapEntry.xds_config = null; @@ -144,16 +154,18 @@ function getCurrentConfig(): ClientConfig { genericConfigList.push(configValue); } } - return { + const config = { node: clientNode, generic_xds_configs: genericConfigList }; + trace('Sending curent config ' + JSON.stringify(config, undefined, 2)); + return config; } const csdsImplementation: ClientStatusDiscoveryServiceHandlers = { FetchClientStatus(call: ServerUnaryCall, callback: sendUnaryData) { const request = call.request; - if (request.node_matchers !== null) { + if (request.node_matchers.length > 0) { callback({ code: status.INVALID_ARGUMENT, details: 'Node matchers not supported' @@ -166,7 +178,7 @@ const csdsImplementation: ClientStatusDiscoveryServiceHandlers = { }, StreamClientStatus(call: ServerDuplexStream) { call.on('data', (request: ClientStatusRequest__Output) => { - if (request.node_matchers !== null) { + if (request.node_matchers.length > 0) { call.emit('error', { code: status.INVALID_ARGUMENT, details: 'Node matchers not supported' diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index 6c8bcb67f..75a567a54 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -51,6 +51,7 @@ import { Cluster__Output } from './generated/envoy/config/cluster/v3/Cluster'; import { RouteConfiguration__Output } from './generated/envoy/config/route/v3/RouteConfiguration'; import { Duration } from './generated/google/protobuf/Duration'; import { AdsOutputType, AdsTypeUrl, CDS_TYPE_URL_V2, CDS_TYPE_URL_V3, decodeSingleResource, EDS_TYPE_URL_V2, EDS_TYPE_URL_V3, LDS_TYPE_URL_V2, LDS_TYPE_URL_V3, RDS_TYPE_URL_V2, RDS_TYPE_URL_V3 } from './resources'; +import { setCsdsClientNode, updateCsdsRequestedNameList, updateCsdsResourceResponse } from './csds'; const TRACER_NAME = 'xds_client'; @@ -384,6 +385,7 @@ export class XdsClient { ...nodeV3, client_features: ['envoy.lrs.supports_send_all_clusters'], }; + setCsdsClientNode(this.adsNodeV3); if (this.apiVersion === XdsApiVersion.V2) { trace('ADS Node: ' + JSON.stringify(this.adsNodeV2, undefined, 2)); trace('LRS Node: ' + JSON.stringify(this.lrsNodeV2, undefined, 2)); @@ -514,12 +516,14 @@ export class XdsClient { } catch (e) { trace('Nacking message with protobuf parsing error: ' + e.message); this.nack(message.type_url, e.message); + return; } if (handleResponseResult === null) { // Null handleResponseResult means that the type_url was unrecognized trace('Nacking message with unknown type URL ' + message.type_url); this.nack(message.type_url, `Unknown type_url ${message.type_url}`); } else { + updateCsdsResourceResponse(message.type_url as AdsTypeUrl, message.version_info, handleResponseResult.result); if (handleResponseResult.result.rejected.length > 0) { // rejected.length > 0 means that at least one message validation failed const errorString = `${handleResponseResult.serviceKind.toUpperCase()} Error: ${handleResponseResult.result.rejected[0].error}`; @@ -754,8 +758,16 @@ export class XdsClient { } this.maybeStartAdsStream(); this.maybeStartLrsStream(); + if (!this.adsCallV2 && !this.adsCallV3) { + /* If the stream is not set up yet at this point, shortcut the rest + * becuase nothing will actually be sent. This would mainly happen if + * the bootstrap file has not been read yet. In that case, the output + * of getTypeUrl is garbage and everything after that is invalid. */ + return; + } trace('Sending update for ' + serviceKind + ' with names ' + this.adsState[serviceKind].getResourceNames()); const typeUrl = this.getTypeUrl(serviceKind); + updateCsdsRequestedNameList(typeUrl, this.adsState[serviceKind].getResourceNames()); this.maybeSendAdsMessage(typeUrl, this.adsState[serviceKind].getResourceNames(), this.adsState[serviceKind].nonce, this.adsState[serviceKind].versionInfo); } From efa6ea1d3e5575ad4717a337dd188f7154c7c815 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 6 Dec 2021 11:38:00 -0500 Subject: [PATCH 142/450] grpc-js-xds: Include additional paths when loading csds protos --- packages/grpc-js-xds/src/csds.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/grpc-js-xds/src/csds.ts b/packages/grpc-js-xds/src/csds.ts index 40ca67f1f..6454e1ad1 100644 --- a/packages/grpc-js-xds/src/csds.ts +++ b/packages/grpc-js-xds/src/csds.ts @@ -205,6 +205,8 @@ const loadedProto = loadSync('envoy/service/status/v3/csds.proto', { // Paths are relative to src/build __dirname + '/../../deps/envoy-api/', __dirname + '/../../deps/xds/', + __dirname + '/../../deps/protoc-gen-validate/', + __dirname + '/../../deps/googleapis/' ], }); From 575c2004f374817c5272f02889b927d4d7221eca Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 6 Dec 2021 12:02:52 -0500 Subject: [PATCH 143/450] Skip some tests to make the Linux test job green --- packages/grpc-js/test/test-server.ts | 6 +++++- test/gulpfile.ts | 8 ++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/grpc-js/test/test-server.ts b/packages/grpc-js/test/test-server.ts index a5f7ec80b..2513b1fe2 100644 --- a/packages/grpc-js/test/test-server.ts +++ b/packages/grpc-js/test/test-server.ts @@ -848,7 +848,11 @@ describe('Compressed requests', () => { }); }); - it('Should not compress requests when the NoCompress write flag is used', done => { + /* As of Node 16, Writable and Duplex streams validate the encoding + * argument to write, and the flags values we are passing there are not + * valid. We don't currently have an alternative way to pass that flag + * down, so for now this feature is not supported. */ + it.skip('Should not compress requests when the NoCompress write flag is used', done => { const bidiStream = client.bidiStream(); let timesRequested = 0; let timesResponded = 0; diff --git a/test/gulpfile.ts b/test/gulpfile.ts index 2024f02cb..6d43d4472 100644 --- a/test/gulpfile.ts +++ b/test/gulpfile.ts @@ -25,6 +25,10 @@ import * as semver from 'semver'; const testDir = __dirname; const apiTestDir = path.resolve(testDir, 'api'); +/* The native library has some misbehavior in specific tests when running in + * Node 14 and above. */ +const NATIVE_SUPPORT_RANGE = '<14'; + const runInstall = () => { return execa('npm', ['install'], {cwd: testDir, stdio: 'inherit'}); }; @@ -51,11 +55,11 @@ const testJsClientNativeServer = runTestsWithFixture('native', 'js'); const testNativeClientJsServer = runTestsWithFixture('js', 'native'); const testJsClientJsServer = runTestsWithFixture('js', 'js'); -const test = gulp.series( +const test = semver.satisfies(process.version, NATIVE_SUPPORT_RANGE)? gulp.series( testJsClientJsServer, testJsClientNativeServer, testNativeClientJsServer - ); + ) : testJsClientJsServer; export { install, From 40c2f61eba518970210ec857cb067f069b907bf2 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 8 Dec 2021 10:27:21 -0500 Subject: [PATCH 144/450] Fix server decompression sequencing, add tracing --- packages/grpc-js/src/server-call.ts | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index 709d20d41..78cab5a9a 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -737,9 +737,24 @@ export class Http2ServerCallStream< ) { const decoder = new StreamDecoder(); + let readsDone = false; + + let pendingMessageProcessing = false; + + let pushedEnd = false; + + const maybePushEnd = () => { + if (!pushedEnd && readsDone && !pendingMessageProcessing) { + pushedEnd = true; + this.pushOrBufferMessage(readable, null); + } + } + this.stream.on('data', async (data: Buffer) => { const messages = decoder.write(data); + pendingMessageProcessing = true; + this.stream.pause(); for (const message of messages) { if ( this.maxReceiveMessageSize !== -1 && @@ -763,10 +778,14 @@ export class Http2ServerCallStream< this.pushOrBufferMessage(readable, decompressedMessage); } + pendingMessageProcessing = false; + this.stream.resume(); + maybePushEnd(); }); this.stream.once('end', () => { - this.pushOrBufferMessage(readable, null); + readsDone = true; + maybePushEnd(); }); } @@ -810,6 +829,7 @@ export class Http2ServerCallStream< messageBytes: Buffer | null ) { if (messageBytes === null) { + trace('Received end of stream'); if (this.canPush) { readable.push(null); } else { @@ -819,6 +839,8 @@ export class Http2ServerCallStream< return; } + trace('Received message of length ' + messageBytes.length); + this.isPushPending = true; try { From c52cb842af6c4d734686524cfbb30091042cbd3c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 8 Dec 2021 11:07:29 -0500 Subject: [PATCH 145/450] Add detailed assertion output for some resolver tests, skip IPv4+IPv6 test --- packages/grpc-js/test/test-resolver.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js/test/test-resolver.ts b/packages/grpc-js/test/test-resolver.ts index 7addfa232..eb4290fc8 100644 --- a/packages/grpc-js/test/test-resolver.ts +++ b/packages/grpc-js/test/test-resolver.ts @@ -24,7 +24,7 @@ import * as resolver_uds from '../src/resolver-uds'; import * as resolver_ip from '../src/resolver-ip'; import { ServiceConfig } from '../src/service-config'; import { StatusObject } from '../src/call-stream'; -import { SubchannelAddress, isTcpSubchannelAddress } from "../src/subchannel-address"; +import { SubchannelAddress, isTcpSubchannelAddress, subchannelAddressToString } from "../src/subchannel-address"; import { parseUri, GrpcUri } from '../src/uri-parser'; describe('Name Resolver', () => { @@ -223,7 +223,7 @@ describe('Name Resolver', () => { isTcpSubchannelAddress(addr) && addr.host === '127.0.0.1' && addr.port === 443 - ) + ), `None of [${addressList.map(addr => subchannelAddressToString(addr))}] matched '127.0.0.1:443'` ); done(); }, @@ -263,7 +263,10 @@ describe('Name Resolver', () => { const resolver = resolverManager.createResolver(target, listener, {}); resolver.updateResolution(); }); - it('Should resolve a DNS name to IPv4 and IPv6 addresses', done => { + /* This DNS name resolves to only the IPv4 address on Windows, and only the + * IPv6 address on Mac. There is no result that we can consistently test + * for here. */ + it.skip('Should resolve a DNS name to IPv4 and IPv6 addresses', done => { const target = resolverManager.mapUriDefaultScheme(parseUri('loopback46.unittest.grpc.io')!)!; const listener: resolverManager.ResolverListener = { onSuccessfulResolution: ( @@ -279,7 +282,7 @@ describe('Name Resolver', () => { isTcpSubchannelAddress(addr) && addr.host === '127.0.0.1' && addr.port === 443 - ) + ), `None of [${addressList.map(addr => subchannelAddressToString(addr))}] matched '127.0.0.1:443'` ); /* TODO(murgatroid99): check for IPv6 result, once we can get that * consistently */ From 57cbf5c8861a91c3229d88e32fc0c82992338246 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 8 Dec 2021 13:44:46 -0500 Subject: [PATCH 146/450] Increase TLS vesion on Windows tests to fix nvm download --- run-tests.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run-tests.bat b/run-tests.bat index 1eebbd4a6..ae9ca1922 100644 --- a/run-tests.bat +++ b/run-tests.bat @@ -21,7 +21,7 @@ powershell -c "[System.Environment]::OSVersion" powershell -c "Get-WmiObject -Class Win32_ComputerSystem" powershell -c "(Get-WmiObject -Class Win32_ComputerSystem).SystemType" -powershell -c "& { iwr https://raw.githubusercontent.com/grumpycoders/nvm-ps/master/nvm.ps1 | iex }" +powershell -c "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; & { iwr https://raw.githubusercontent.com/grumpycoders/nvm-ps/master/nvm.ps1 | iex }" SET PATH=%APPDATA%\nvm-ps;%APPDATA%\nvm-ps\nodejs;%PATH% SET JOBS=8 From 359014eeedc3de46ae7ac73e6a88a8068d4afcf0 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 8 Dec 2021 14:46:33 -0500 Subject: [PATCH 147/450] Drop Node 8 tests on Windows --- run-tests.bat | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/run-tests.bat b/run-tests.bat index ae9ca1922..ce4480e44 100644 --- a/run-tests.bat +++ b/run-tests.bat @@ -28,8 +28,8 @@ SET JOBS=8 call nvm version -call nvm install 8 -call nvm use 8 +call nvm install 10 +call nvm use 10 SET npm_config_fetch_retries=5 @@ -38,7 +38,7 @@ call npm install || goto :error SET JUNIT_REPORT_STACK=1 SET FAILED=0 -for %%v in (8 10 12) do ( +for %%v in (10 12) do ( call nvm install %%v call nvm use %%v if "%%v"=="4" ( From 20dbaa8e27faad9e41d5ce0bafa40f082a37117c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 8 Dec 2021 14:54:56 -0500 Subject: [PATCH 148/450] Make npm clean scripts platform-agnostic --- packages/grpc-js/package.json | 2 +- packages/proto-loader/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 69d565ad3..ad12fb82e 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -44,7 +44,7 @@ ], "scripts": { "build": "npm run compile", - "clean": "node -e 'require(\"rimraf\")(\"./build\", () => {})'", + "clean": "rimraf ./build", "compile": "tsc -p .", "format": "clang-format -i -style=\"{Language: JavaScript, BasedOnStyle: Google, ColumnLimit: 80}\" src/*.ts test/*.ts", "lint": "npm run check", diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index cd27743a0..db6e4755e 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -14,7 +14,7 @@ "typings": "build/src/index.d.ts", "scripts": { "build": "npm run compile", - "clean": "node -e 'require(\"rimraf\")(\"./build\", () => {})'", + "clean": "rimraf ./build", "compile": "tsc -p .", "format": "clang-format -i -style=\"{Language: JavaScript, BasedOnStyle: Google, ColumnLimit: 80}\" src/*.ts test/*.ts", "lint": "tslint -c node_modules/google-ts-style/tslint.json -p . -t codeFrame --type-check", From d5ce78434845442931bff2baedccc91730e0d3b1 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 8 Dec 2021 14:56:52 -0500 Subject: [PATCH 149/450] Update submodules in Windows test script --- run-tests.bat | 2 ++ 1 file changed, 2 insertions(+) diff --git a/run-tests.bat b/run-tests.bat index ce4480e44..611f28ca4 100644 --- a/run-tests.bat +++ b/run-tests.bat @@ -31,6 +31,8 @@ call nvm version call nvm install 10 call nvm use 10 +git submodule update --init --recursive + SET npm_config_fetch_retries=5 call npm install || goto :error From e41b99dffc4bd4a676b7c6932ea46695c511d629 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 8 Dec 2021 15:23:06 -0500 Subject: [PATCH 150/450] Fix a couple of issues with tests on Windows --- packages/grpc-js/test/test-client.ts | 3 ++- test/api/connectivity_test.js | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/grpc-js/test/test-client.ts b/packages/grpc-js/test/test-client.ts index 51af05416..4a02ff3de 100644 --- a/packages/grpc-js/test/test-client.ts +++ b/packages/grpc-js/test/test-client.ts @@ -79,7 +79,8 @@ describe('Client without a server', () => { after(() => { client.close(); }); - it('should fail multiple calls to the nonexistent server', done => { + it('should fail multiple calls to the nonexistent server', function(done) { + this.timeout(5000); // Regression test for https://github.com/grpc/grpc-node/issues/1411 client.makeUnaryRequest('/service/method', x => x, x => x, Buffer.from([]), (error, value) => { assert(error); diff --git a/test/api/connectivity_test.js b/test/api/connectivity_test.js index b5d31943d..64764d7d4 100644 --- a/test/api/connectivity_test.js +++ b/test/api/connectivity_test.js @@ -61,7 +61,9 @@ const serviceImpl = { describe(`${anyGrpc.clientName} client -> ${anyGrpc.serverName} server`, function() { it('client should not wait for ready by default', function(done) { this.timeout(15000); - const disconnectedClient = new TestServiceClient('foo.test.google.com:50051', clientGrpc.credentials.createInsecure()); + /* TCP port 47 is reserved according to + * https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers */ + const disconnectedClient = new TestServiceClient('localhost:47', clientGrpc.credentials.createInsecure()); const deadline = new Date(); deadline.setSeconds(deadline.getSeconds() + 10); disconnectedClient.unary({}, {deadline: deadline}, (error, value) =>{ @@ -72,7 +74,7 @@ describe(`${anyGrpc.clientName} client -> ${anyGrpc.serverName} server`, functio }); it('client should wait for a connection with waitForReady on', function(done) { this.timeout(15000); - const disconnectedClient = new TestServiceClient('foo.test.google.com:50051', clientGrpc.credentials.createInsecure()); + const disconnectedClient = new TestServiceClient('localhost:47', clientGrpc.credentials.createInsecure()); const metadata = new clientGrpc.Metadata({waitForReady: true}); const deadline = new Date(); deadline.setSeconds(deadline.getSeconds() + 10); From f2e698a810b1924cb8b155ae3fcd5827eda591b6 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 9 Dec 2021 10:47:01 -0500 Subject: [PATCH 151/450] Skip clean step in Windows test runs --- run-tests.bat | 1 - 1 file changed, 1 deletion(-) diff --git a/run-tests.bat b/run-tests.bat index 611f28ca4..3b0aa07d0 100644 --- a/run-tests.bat +++ b/run-tests.bat @@ -55,7 +55,6 @@ for %%v in (10 12) do ( node -e "process.exit(process.version.startsWith('v%%v') ? 0 : -1)" || goto :error - call .\node_modules\.bin\gulp cleanAll || SET FAILED=1 call .\node_modules\.bin\gulp setup || SET FAILED=1 call .\node_modules\.bin\gulp test || SET FAILED=1 cmd.exe /c "SET GRPC_DNS_RESOLVER=ares& call .\node_modules\.bin\gulp nativeTestOnly" || SET FAILED=1 From f706d524e7d4de8f305c3d942d1a74830e831f9a Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 9 Dec 2021 10:47:48 -0500 Subject: [PATCH 152/450] Ignore trailing whitespace in proto-loader golden file test diff --- packages/proto-loader/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index db6e4755e..093bfa5a7 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -25,7 +25,7 @@ "pretest": "npm run compile", "posttest": "npm run check", "generate-golden": "node ./build/bin/proto-loader-gen-types.js --keepCase --longs=String --enums=String --defaults --oneofs --json --includeComments -I deps/gapic-showcase/schema/ deps/googleapis/ -O ./golden-generated --grpcLib @grpc/grpc-js google/showcase/v1beta1/echo.proto", - "validate-golden": "rm -rf ./golden-generated-old && mv ./golden-generated/ ./golden-generated-old && npm run generate-golden && diff -r ./golden-generated ./golden-generated-old" + "validate-golden": "rm -rf ./golden-generated-old && mv ./golden-generated/ ./golden-generated-old && npm run generate-golden && diff -rZ ./golden-generated ./golden-generated-old" }, "repository": { "type": "git", From ba375e73716d921eef9933eba76f3e077ae51fb5 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 9 Dec 2021 10:48:38 -0500 Subject: [PATCH 153/450] Skip a test because it behaves weirdly on Mac --- packages/grpc-js/test/test-resolver.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/test/test-resolver.ts b/packages/grpc-js/test/test-resolver.ts index eb4290fc8..354413ea6 100644 --- a/packages/grpc-js/test/test-resolver.ts +++ b/packages/grpc-js/test/test-resolver.ts @@ -207,7 +207,15 @@ describe('Name Resolver', () => { const resolver = resolverManager.createResolver(target, listener, {}); resolver.updateResolution(); }); - it('Should resolve a name with multiple dots', done => { + /* The DNS entry for loopback4.unittest.grpc.io only has a single A record + * with the address 127.0.0.1, but the Mac DNS resolver appears to use + * NAT64 to create an IPv6 address in that case, so it instead returns + * 64:ff9b::7f00:1. Handling that kind of translation is outside of the + * scope of this test, so we are skipping it. The test primarily exists + * as a regression test for https://github.com/grpc/grpc-node/issues/1044, + * and the test 'Should resolve gRPC interop servers' tests the same thing. + */ + it.skip('Should resolve a name with multiple dots', done => { const target = resolverManager.mapUriDefaultScheme(parseUri('loopback4.unittest.grpc.io')!)!; const listener: resolverManager.ResolverListener = { onSuccessfulResolution: ( @@ -317,6 +325,10 @@ describe('Name Resolver', () => { const resolver = resolverManager.createResolver(target, listener, {}); resolver.updateResolution(); }); + /* This test also serves as a regression test for + * https://github.com/grpc/grpc-node/issues/1044, specifically handling + * hyphens and multiple periods in a DNS name. It should not be skipped + * unless there is another test for the same issue. */ it('Should resolve gRPC interop servers', done => { let completeCount = 0; const target1 = resolverManager.mapUriDefaultScheme(parseUri('grpc-test.sandbox.googleapis.com')!)!; From 8d771044e75e5d6a659458297bc9229d7e1b2846 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 9 Dec 2021 11:14:53 -0500 Subject: [PATCH 154/450] Make diff command work on Mac, make file comment use consistent directory separator --- packages/proto-loader/bin/proto-loader-gen-types.ts | 6 +++--- packages/proto-loader/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index 3ecf6dcc4..b416d3382 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -379,7 +379,7 @@ function generateMessageInterfaces(formatter: TextFormatter, messageType: Protob let usesLong: boolean = false; let seenDeps: Set = new Set(); const childTypes = getChildMessagesAndEnums(messageType); - formatter.writeLine(`// Original file: ${messageType.filename}`); + formatter.writeLine(`// Original file: ${messageType.filename?.replace(/\\/g, '/')}`); formatter.writeLine(''); messageType.fieldsArray.sort((fieldA, fieldB) => fieldA.id - fieldB.id); for (const field of messageType.fieldsArray) { @@ -437,7 +437,7 @@ function generateMessageInterfaces(formatter: TextFormatter, messageType: Protob } function generateEnumInterface(formatter: TextFormatter, enumType: Protobuf.Enum, options: GeneratorOptions, nameOverride?: string) { - formatter.writeLine(`// Original file: ${enumType.filename}`); + formatter.writeLine(`// Original file: ${enumType.filename?.replace(/\\/g, '/')}`); formatter.writeLine(''); if (options.includeComments) { formatComment(formatter, enumType.comment); @@ -590,7 +590,7 @@ function generateServiceDefinitionInterface(formatter: TextFormatter, serviceTyp } function generateServiceInterfaces(formatter: TextFormatter, serviceType: Protobuf.Service, options: GeneratorOptions) { - formatter.writeLine(`// Original file: ${serviceType.filename}`); + formatter.writeLine(`// Original file: ${serviceType.filename?.replace(/\\/g, '/')}`); formatter.writeLine(''); const grpcImportPath = options.grpcLib.startsWith('.') ? getPathToRoot(serviceType) + options.grpcLib : options.grpcLib; formatter.writeLine(`import type * as grpc from '${grpcImportPath}'`); diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index 093bfa5a7..6db5cb721 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -25,7 +25,7 @@ "pretest": "npm run compile", "posttest": "npm run check", "generate-golden": "node ./build/bin/proto-loader-gen-types.js --keepCase --longs=String --enums=String --defaults --oneofs --json --includeComments -I deps/gapic-showcase/schema/ deps/googleapis/ -O ./golden-generated --grpcLib @grpc/grpc-js google/showcase/v1beta1/echo.proto", - "validate-golden": "rm -rf ./golden-generated-old && mv ./golden-generated/ ./golden-generated-old && npm run generate-golden && diff -rZ ./golden-generated ./golden-generated-old" + "validate-golden": "rm -rf ./golden-generated-old && mv ./golden-generated/ ./golden-generated-old && npm run generate-golden && diff -rb ./golden-generated ./golden-generated-old" }, "repository": { "type": "git", From 2af9a05ee4eff892f4cd6b7a8e864c7e0115788c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 9 Dec 2021 13:17:01 -0500 Subject: [PATCH 155/450] Ensure consistent null in missing file names --- packages/proto-loader/bin/proto-loader-gen-types.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index b416d3382..b0a9819b4 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -379,7 +379,7 @@ function generateMessageInterfaces(formatter: TextFormatter, messageType: Protob let usesLong: boolean = false; let seenDeps: Set = new Set(); const childTypes = getChildMessagesAndEnums(messageType); - formatter.writeLine(`// Original file: ${messageType.filename?.replace(/\\/g, '/')}`); + formatter.writeLine(`// Original file: ${(messageType.filename ?? 'null')?.replace(/\\/g, '/')}`); formatter.writeLine(''); messageType.fieldsArray.sort((fieldA, fieldB) => fieldA.id - fieldB.id); for (const field of messageType.fieldsArray) { @@ -437,7 +437,7 @@ function generateMessageInterfaces(formatter: TextFormatter, messageType: Protob } function generateEnumInterface(formatter: TextFormatter, enumType: Protobuf.Enum, options: GeneratorOptions, nameOverride?: string) { - formatter.writeLine(`// Original file: ${enumType.filename?.replace(/\\/g, '/')}`); + formatter.writeLine(`// Original file: ${(enumType.filename ?? 'null')?.replace(/\\/g, '/')}`); formatter.writeLine(''); if (options.includeComments) { formatComment(formatter, enumType.comment); @@ -590,7 +590,7 @@ function generateServiceDefinitionInterface(formatter: TextFormatter, serviceTyp } function generateServiceInterfaces(formatter: TextFormatter, serviceType: Protobuf.Service, options: GeneratorOptions) { - formatter.writeLine(`// Original file: ${serviceType.filename?.replace(/\\/g, '/')}`); + formatter.writeLine(`// Original file: ${(serviceType.filename ?? 'null')?.replace(/\\/g, '/')}`); formatter.writeLine(''); const grpcImportPath = options.grpcLib.startsWith('.') ? getPathToRoot(serviceType) + options.grpcLib : options.grpcLib; formatter.writeLine(`import type * as grpc from '${grpcImportPath}'`); From 7cccc392181050f1e7ed7334f148d35dbe6b7b5f Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 9 Dec 2021 16:14:52 -0500 Subject: [PATCH 156/450] grpc-js: Preserve order of metadata and messages with async interceptors --- packages/grpc-js/src/call-stream.ts | 35 +++++++++++++--- packages/grpc-js/src/client-interceptors.ts | 44 ++++++++++++++++++--- 2 files changed, 68 insertions(+), 11 deletions(-) diff --git a/packages/grpc-js/src/call-stream.ts b/packages/grpc-js/src/call-stream.ts index 70a9ac6ee..915d812fc 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -149,6 +149,9 @@ export function isInterceptingListener( } export class InterceptingListenerImpl implements InterceptingListener { + private processingMetadata = false; + private hasPendingMessage = false; + private pendingMessage: any; private processingMessage = false; private pendingStatus: StatusObject | null = null; constructor( @@ -156,9 +159,27 @@ export class InterceptingListenerImpl implements InterceptingListener { private nextListener: InterceptingListener ) {} + private processPendingMessage() { + if (this.hasPendingMessage) { + this.nextListener.onReceiveMessage(this.pendingMessage); + this.pendingMessage = null; + this.hasPendingMessage = false; + } + } + + private processPendingStatus() { + if (this.pendingStatus) { + this.nextListener.onReceiveStatus(this.pendingStatus); + } + } + onReceiveMetadata(metadata: Metadata): void { + this.processingMetadata = true; this.listener.onReceiveMetadata(metadata, (metadata) => { + this.processingMetadata = false; this.nextListener.onReceiveMetadata(metadata); + this.processPendingMessage(); + this.processPendingStatus(); }); } // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -168,15 +189,18 @@ export class InterceptingListenerImpl implements InterceptingListener { this.processingMessage = true; this.listener.onReceiveMessage(message, (msg) => { this.processingMessage = false; - this.nextListener.onReceiveMessage(msg); - if (this.pendingStatus) { - this.nextListener.onReceiveStatus(this.pendingStatus); + if (this.processingMetadata) { + this.pendingMessage = msg; + this.hasPendingMessage = true; + } else { + this.nextListener.onReceiveMessage(msg); + this.processPendingStatus(); } }); } onReceiveStatus(status: StatusObject): void { this.listener.onReceiveStatus(status, (processedStatus) => { - if (this.processingMessage) { + if (this.processingMetadata || this.processingMessage) { this.pendingStatus = processedStatus; } else { this.nextListener.onReceiveStatus(processedStatus); @@ -283,7 +307,7 @@ export class Http2CallStream implements Call { private outputStatus() { /* Precondition: this.finalStatus !== null */ - if (!this.statusOutput) { + if (this.listener && !this.statusOutput) { this.statusOutput = true; const filteredStatus = this.filterStack.receiveTrailers( this.finalStatus! @@ -692,6 +716,7 @@ export class Http2CallStream implements Call { this.trace('Sending metadata'); this.listener = listener; this.channel._startCallStream(this, metadata); + this.maybeOutputStatus(); } private destroyHttp2Stream() { diff --git a/packages/grpc-js/src/client-interceptors.ts b/packages/grpc-js/src/client-interceptors.ts index 5dfbeba14..ddb296ff1 100644 --- a/packages/grpc-js/src/client-interceptors.ts +++ b/packages/grpc-js/src/client-interceptors.ts @@ -208,8 +208,18 @@ export class InterceptingCall implements InterceptingCallInterface { */ private requester: FullRequester; /** - * Indicates that a message has been passed to the listener's onReceiveMessage - * method it has not been passed to the corresponding next callback + * Indicates that metadata has been passed to the requester's start + * method but it has not been passed to the corresponding next callback + */ + private processingMetadata = false; + /** + * Message context for a pending message that is waiting for + */ + private pendingMessageContext: MessageContext | null = null; + private pendingMessage: any; + /** + * Indicates that a message has been passed to the requester's sendMessage + * method but it has not been passed to the corresponding next callback */ private processingMessage = false; /** @@ -242,6 +252,21 @@ export class InterceptingCall implements InterceptingCallInterface { getPeer() { return this.nextCall.getPeer(); } + + private processPendingMessage() { + if (this.pendingMessageContext) { + this.nextCall.sendMessageWithContext(this.pendingMessageContext, this.pendingMessage); + this.pendingMessageContext = null; + this.pendingMessage = null; + } + } + + private processPendingHalfClose() { + if (this.pendingHalfClose) { + this.nextCall.halfClose(); + } + } + start( metadata: Metadata, interceptingListener?: Partial @@ -257,7 +282,9 @@ export class InterceptingCall implements InterceptingCallInterface { interceptingListener?.onReceiveStatus?.bind(interceptingListener) ?? ((status) => {}), }; + this.processingMetadata = true; this.requester.start(metadata, fullInterceptingListener, (md, listener) => { + this.processingMetadata = false; let finalInterceptingListener: InterceptingListener; if (isInterceptingListener(listener)) { finalInterceptingListener = listener; @@ -276,6 +303,8 @@ export class InterceptingCall implements InterceptingCallInterface { ); } this.nextCall.start(md, finalInterceptingListener); + this.processPendingMessage(); + this.processPendingHalfClose(); }); } // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -283,9 +312,12 @@ export class InterceptingCall implements InterceptingCallInterface { this.processingMessage = true; this.requester.sendMessage(message, (finalMessage) => { this.processingMessage = false; - this.nextCall.sendMessageWithContext(context, finalMessage); - if (this.pendingHalfClose) { - this.nextCall.halfClose(); + if (this.processingMetadata) { + this.pendingMessageContext = context; + this.pendingMessage = message; + } else { + this.nextCall.sendMessageWithContext(context, finalMessage); + this.processPendingHalfClose(); } }); } @@ -298,7 +330,7 @@ export class InterceptingCall implements InterceptingCallInterface { } halfClose(): void { this.requester.halfClose(() => { - if (this.processingMessage) { + if (this.processingMetadata || this.processingMessage) { this.pendingHalfClose = true; } else { this.nextCall.halfClose(); From 86f3ffd96ce7e656acd004caf10c1c6c98ceb84c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 9 Dec 2021 16:31:29 -0500 Subject: [PATCH 157/450] grpc-js: Update version to 1.4.5 --- 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 e14ffa0eb..02400ca90 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.4.4", + "version": "1.4.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", From b12330abfd8ff9207a332e8a47e05703c26697f5 Mon Sep 17 00:00:00 2001 From: Cosmin-Catalin Crisan Date: Fri, 10 Dec 2021 20:20:11 +0200 Subject: [PATCH 158/450] grpc-js: Send backoffOptions to BackoffTimeout --- packages/grpc-js/src/resolving-load-balancer.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/grpc-js/src/resolving-load-balancer.ts b/packages/grpc-js/src/resolving-load-balancer.ts index 235748f70..5bc861283 100644 --- a/packages/grpc-js/src/resolving-load-balancer.ts +++ b/packages/grpc-js/src/resolving-load-balancer.ts @@ -26,7 +26,7 @@ import { ConnectivityState } from './connectivity-state'; import { ConfigSelector, createResolver, Resolver } from './resolver'; import { ServiceError } from './call'; import { Picker, UnavailablePicker, QueuePicker } from './picker'; -import { BackoffTimeout } from './backoff-timeout'; +import { BackoffOptions, BackoffTimeout } from './backoff-timeout'; import { Status } from './constants'; import { StatusObject } from './call-stream'; import { Metadata } from './metadata'; @@ -248,7 +248,10 @@ export class ResolvingLoadBalancer implements LoadBalancer { }, channelOptions ); - + const backoffOptions: BackoffOptions = { + initialDelay: channelOptions['grpc.initial_reconnect_backoff_ms'], + maxDelay: channelOptions['grpc.max_reconnect_backoff_ms'], + }; this.backoffTimeout = new BackoffTimeout(() => { if (this.continueResolving) { this.updateResolution(); @@ -256,7 +259,7 @@ export class ResolvingLoadBalancer implements LoadBalancer { } else { this.updateState(this.latestChildState, this.latestChildPicker); } - }); + }, backoffOptions); this.backoffTimeout.unref(); } From 8e53f034d0ea6e1226b21f29d5249ecf60632b65 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 13 Dec 2021 10:05:37 -0500 Subject: [PATCH 159/450] grpc-js: Add credentials.createFromSecureContext --- packages/grpc-js/src/channel-credentials.ts | 57 +++++++++++---------- packages/grpc-js/src/index.ts | 1 + 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/packages/grpc-js/src/channel-credentials.ts b/packages/grpc-js/src/channel-credentials.ts index 02c9c309b..94b66c1bd 100644 --- a/packages/grpc-js/src/channel-credentials.ts +++ b/packages/grpc-js/src/channel-credentials.ts @@ -15,7 +15,7 @@ * */ -import { ConnectionOptions, createSecureContext, PeerCertificate } from 'tls'; +import { ConnectionOptions, createSecureContext, PeerCertificate, SecureContext } from 'tls'; import { CallCredentials } from './call-credentials'; import { CIPHER_SUITES, getDefaultRootsData } from './tls-helpers'; @@ -110,6 +110,7 @@ export abstract class ChannelCredentials { * @param rootCerts The root certificate data. * @param privateKey The client certificate private key, if available. * @param certChain The client certificate key chain, if available. + * @param verifyOptions Additional options to modify certificate verification */ static createSsl( rootCerts?: Buffer | null, @@ -130,14 +131,35 @@ export abstract class ChannelCredentials { 'Certificate chain must be given with accompanying private key' ); } + const secureContext = createSecureContext({ + ca: rootCerts ?? getDefaultRootsData() ?? undefined, + key: privateKey ?? undefined, + cert: certChain ?? undefined, + ciphers: CIPHER_SUITES, + }); return new SecureChannelCredentialsImpl( - rootCerts || getDefaultRootsData(), - privateKey || null, - certChain || null, - verifyOptions || {} + secureContext, + verifyOptions ?? {} ); } + /** + * Return a new ChannelCredentials instance with credentials created using + * the provided secureContext. The resulting instances can be used to + * construct a Channel that communicates over TLS. gRPC will not override + * anything in the provided secureContext, so the environment variables + * GRPC_SSL_CIPHER_SUITES and GRPC_DEFAULT_SSL_ROOTS_FILE_PATH will + * not be applied. + * @param secureContext The return value of tls.createSecureContext() + * @param verifyOptions Additional options to modify certificate verification + */ + static createFromSecureContext(secureContext: SecureContext, verifyOptions?: VerifyOptions): ChannelCredentials { + return new SecureChannelCredentialsImpl( + secureContext, + verifyOptions ?? {} + ) + } + /** * Return a new ChannelCredentials instance with no credentials. */ @@ -170,18 +192,10 @@ class SecureChannelCredentialsImpl extends ChannelCredentials { connectionOptions: ConnectionOptions; constructor( - private rootCerts: Buffer | null, - private privateKey: Buffer | null, - private certChain: Buffer | null, + private secureContext: SecureContext, private verifyOptions: VerifyOptions ) { super(); - const secureContext = createSecureContext({ - ca: rootCerts || undefined, - key: privateKey || undefined, - cert: certChain || undefined, - ciphers: CIPHER_SUITES, - }); this.connectionOptions = { secureContext }; @@ -210,19 +224,10 @@ class SecureChannelCredentialsImpl extends ChannelCredentials { return true; } if (other instanceof SecureChannelCredentialsImpl) { - if (!bufferOrNullEqual(this.rootCerts, other.rootCerts)) { - return false; - } - if (!bufferOrNullEqual(this.privateKey, other.privateKey)) { - return false; - } - if (!bufferOrNullEqual(this.certChain, other.certChain)) { - return false; - } return ( - this.verifyOptions.checkServerIdentity === - other.verifyOptions.checkServerIdentity - ); + this.secureContext === other.secureContext && + this.verifyOptions.checkServerIdentity === other.verifyOptions.checkServerIdentity + ); } else { return false; } diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index c4c774d93..4bf1d9363 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -109,6 +109,7 @@ export const credentials = { // from channel-credentials.ts createInsecure: ChannelCredentials.createInsecure, createSsl: ChannelCredentials.createSsl, + createFromSecureContext: ChannelCredentials.createFromSecureContext, // from call-credentials.ts createFromMetadataGenerator: CallCredentials.createFromMetadataGenerator, From 33c5abd16353eba7c2347bb8368a941df5a37c49 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 13 Dec 2021 14:18:12 -0500 Subject: [PATCH 160/450] grpc-js: Clean up some dependencies --- packages/grpc-js/package.json | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index ad12fb82e..854000a3d 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -21,7 +21,7 @@ "@types/mocha": "^5.2.6", "@types/ncp": "^2.0.1", "@types/pify": "^3.0.2", - "@types/yargs": "^15.0.5", + "@types/semver": "^7.3.9", "clang-format": "^1.0.55", "execa": "^2.0.3", "gts": "^2.0.0", @@ -33,9 +33,9 @@ "ncp": "^2.0.0", "pify": "^4.0.1", "rimraf": "^3.0.2", + "semver": "^7.3.5", "ts-node": "^8.3.0", - "typescript": "^3.7.2", - "yargs": "^15.4.1" + "typescript": "^3.7.2" }, "contributors": [ { @@ -59,8 +59,7 @@ }, "dependencies": { "@grpc/proto-loader": "^0.6.4", - "@types/node": ">=12.12.47", - "@types/semver": "^7.3.9" + "@types/node": ">=12.12.47" }, "files": [ "src/**/*.ts", From ac893ca89fc1be95f3e62e9923a4c2ba88ddc0d3 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 29 Dec 2021 11:58:32 -0800 Subject: [PATCH 161/450] Use xds-test-server-5 as interop server image --- packages/grpc-js-xds/scripts/xds.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/scripts/xds.sh b/packages/grpc-js-xds/scripts/xds.sh index c7a9adb6e..2df2ae42d 100755 --- a/packages/grpc-js-xds/scripts/xds.sh +++ b/packages/grpc-js-xds/scripts/xds.sh @@ -54,7 +54,7 @@ GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weigh python3 grpc/tools/run_tests/run_xds_tests.py \ --test_case="all,timeout,circuit_breaking,fault_injection,csds" \ --project_id=grpc-testing \ - --source_image=projects/grpc-testing/global/images/xds-test-server-4 \ + --source_image=projects/grpc-testing/global/images/xds-test-server-5 \ --path_to_server_binary=/java_server/grpc-java/interop-testing/build/install/grpc-interop-testing/bin/xds-test-server \ --gcp_suffix=$(date '+%s') \ --verbose \ From a000d67a8869585d23d8e9f0a50195c5b364a240 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 29 Dec 2021 11:58:32 -0800 Subject: [PATCH 162/450] Use xds-test-server-5 as interop server image --- packages/grpc-js-xds/scripts/xds.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/scripts/xds.sh b/packages/grpc-js-xds/scripts/xds.sh index a06cde84b..b584c21c3 100755 --- a/packages/grpc-js-xds/scripts/xds.sh +++ b/packages/grpc-js-xds/scripts/xds.sh @@ -54,7 +54,7 @@ GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weigh python3 grpc/tools/run_tests/run_xds_tests.py \ --test_case="all,timeout,circuit_breaking,fault_injection" \ --project_id=grpc-testing \ - --source_image=projects/grpc-testing/global/images/xds-test-server-4 \ + --source_image=projects/grpc-testing/global/images/xds-test-server-5 \ --path_to_server_binary=/java_server/grpc-java/interop-testing/build/install/grpc-interop-testing/bin/xds-test-server \ --gcp_suffix=$(date '+%s') \ --verbose \ From 9f3001eb9737f282b31a4cbdcadb3c1f9994f667 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 4 Jan 2022 10:08:40 -0800 Subject: [PATCH 163/450] proto-loader: Update yargs to version 17 --- packages/proto-loader/bin/proto-loader-gen-types.ts | 4 ++-- packages/proto-loader/package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index b0a9819b4..30df07bdc 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -767,8 +767,8 @@ async function writeAllFiles(protoFiles: string[], options: GeneratorOptions) { } } -function runScript() { - const argv = yargs +async function runScript() { + const argv = await yargs .parserConfiguration({ 'parse-positional-numbers': false }) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index 6db5cb721..7fb179922 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -49,14 +49,14 @@ "lodash.camelcase": "^4.3.0", "long": "^4.0.0", "protobufjs": "^6.10.0", - "yargs": "^16.1.1" + "yargs": "^17.3.1" }, "devDependencies": { "@types/lodash.camelcase": "^4.3.4", "@types/mkdirp": "^1.0.1", "@types/mocha": "^5.2.7", "@types/node": "^10.17.26", - "@types/yargs": "^15.0.5", + "@types/yargs": "^17.0.8", "clang-format": "^1.2.2", "gts": "^1.1.0", "rimraf": "^3.0.2", From 9f5187fbaaa4a7527973fe70d5655947ed714e8a Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 4 Jan 2022 10:09:17 -0800 Subject: [PATCH 164/450] proto-loader: Increase version to 0.6.8 --- packages/proto-loader/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index 7fb179922..b1d3182f7 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/proto-loader", - "version": "0.6.7", + "version": "0.6.8", "author": "Google Inc.", "contributors": [ { From 311d22e03e5818260feedaaf233f86cc55ed581b Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 4 Jan 2022 12:41:41 -0800 Subject: [PATCH 165/450] grpc-js: Fix compatibility with @types/node 17.0.6 --- packages/grpc-js/src/object-stream.ts | 25 ++++++------------------- packages/grpc-js/src/server-call.ts | 5 ++--- 2 files changed, 8 insertions(+), 22 deletions(-) diff --git a/packages/grpc-js/src/object-stream.ts b/packages/grpc-js/src/object-stream.ts index b17058a7a..042820925 100644 --- a/packages/grpc-js/src/object-stream.ts +++ b/packages/grpc-js/src/object-stream.ts @@ -36,9 +36,9 @@ export interface IntermediateObjectWritable extends Writable { write(chunk: any & T, cb?: WriteCallback): boolean; write(chunk: any & T, encoding?: any, cb?: WriteCallback): boolean; setDefaultEncoding(encoding: string): this; - end(): void; - end(chunk: any & T, cb?: Function): void; - end(chunk: any & T, encoding?: any, cb?: Function): void; + end(): this; + end(chunk: any & T, cb?: Function): this; + end(chunk: any & T, encoding?: any, cb?: Function): this; } export interface ObjectWritable extends IntermediateObjectWritable { @@ -46,20 +46,7 @@ export interface ObjectWritable extends IntermediateObjectWritable { write(chunk: T, cb?: Function): boolean; write(chunk: T, encoding?: any, cb?: Function): boolean; setDefaultEncoding(encoding: string): this; - end(): void; - end(chunk: T, cb?: Function): void; - end(chunk: T, encoding?: any, cb?: Function): void; + end(): this; + end(chunk: T, cb?: Function): this; + end(chunk: T, encoding?: any, cb?: Function): this; } - -export type ObjectDuplex = { - read(size?: number): U; - - _write(chunk: T, encoding: string, callback: Function): void; - write(chunk: T, cb?: Function): boolean; - write(chunk: T, encoding?: any, cb?: Function): boolean; - end(): void; - end(chunk: T, cb?: Function): void; - end(chunk: T, encoding?: any, cb?: Function): void; -} & Duplex & - ObjectWritable & - ObjectReadable; diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index be4429b0f..a79e401c6 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -236,7 +236,7 @@ export class ServerWritableStreamImpl this.trailingMetadata = metadata; } - super.end(); + return super.end(); } } @@ -282,7 +282,7 @@ export class ServerDuplexStreamImpl this.trailingMetadata = metadata; } - super.end(); + return super.end(); } } @@ -292,7 +292,6 @@ ServerDuplexStreamImpl.prototype._write = ServerWritableStreamImpl.prototype._write; ServerDuplexStreamImpl.prototype._final = ServerWritableStreamImpl.prototype._final; -ServerDuplexStreamImpl.prototype.end = ServerWritableStreamImpl.prototype.end; // Unary response callback signature. export type sendUnaryData = ( From e2dfb8fbcf0c7f0282e7becfaced75fdef20bb8f Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 4 Jan 2022 12:42:05 -0800 Subject: [PATCH 166/450] grpc-js: Increase version to 1.4.6 --- 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 02400ca90..e3c983445 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.4.5", + "version": "1.4.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", From fba2b9498f7ebf59cc1303dc39fcaf14b5cd3471 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 4 Jan 2022 14:00:25 -0800 Subject: [PATCH 167/450] Fix end type again for older @types/node versions --- packages/grpc-js/src/object-stream.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/grpc-js/src/object-stream.ts b/packages/grpc-js/src/object-stream.ts index 042820925..22ab8a41f 100644 --- a/packages/grpc-js/src/object-stream.ts +++ b/packages/grpc-js/src/object-stream.ts @@ -36,9 +36,9 @@ export interface IntermediateObjectWritable extends Writable { write(chunk: any & T, cb?: WriteCallback): boolean; write(chunk: any & T, encoding?: any, cb?: WriteCallback): boolean; setDefaultEncoding(encoding: string): this; - end(): this; - end(chunk: any & T, cb?: Function): this; - end(chunk: any & T, encoding?: any, cb?: Function): this; + end(): ReturnType extends Writable ? this : void; + end(chunk: any & T, cb?: Function): ReturnType extends Writable ? this : void; + end(chunk: any & T, encoding?: any, cb?: Function): ReturnType extends Writable ? this : void; } export interface ObjectWritable extends IntermediateObjectWritable { @@ -46,7 +46,7 @@ export interface ObjectWritable extends IntermediateObjectWritable { write(chunk: T, cb?: Function): boolean; write(chunk: T, encoding?: any, cb?: Function): boolean; setDefaultEncoding(encoding: string): this; - end(): this; - end(chunk: T, cb?: Function): this; - end(chunk: T, encoding?: any, cb?: Function): this; + end(): ReturnType extends Writable ? this : void; + end(chunk: T, cb?: Function): ReturnType extends Writable ? this : void; + end(chunk: T, encoding?: any, cb?: Function): ReturnType extends Writable ? this : void; } From 78631cdad826316e0a5d562fea55b2571484e615 Mon Sep 17 00:00:00 2001 From: Joey Harrington Date: Mon, 27 Dec 2021 12:55:16 -0800 Subject: [PATCH 168/450] Document grpc-js supported channel args in readme This moves the list of supported channel arguments from PACKAGE_COMPARISON.md into the readme, and also adds a link to the package comparison doc. resolves #1982, resolves #1983 --- PACKAGE-COMPARISON.md | 21 ++------------------- packages/grpc-js/README.md | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/PACKAGE-COMPARISON.md b/PACKAGE-COMPARISON.md index fa0ea319e..f0c444195 100644 --- a/PACKAGE-COMPARISON.md +++ b/PACKAGE-COMPARISON.md @@ -28,22 +28,5 @@ Supported Electron Versions | All | >= 3 Supported Platforms | Linux, Windows, MacOS | All Supported Architectures | x86, x86-64, ARM7+ | All -In addition, all channel arguments defined in [this header file](https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/grpc_types.h) are handled by the `grpc` library. Of those, the following are handled by the `@grpc/grpc-js` library: - - - `grpc.ssl_target_name_override` - - `grpc.primary_user_agent` - - `grpc.secondary_user_agent` - - `grpc.default_authority` - - `grpc.keepalive_time_ms` - - `grpc.keepalive_timeout_ms` - - `grpc.keepalive_permit_without_calls` - - `grpc.service_config` - - `grpc.max_concurrent_streams` - - `grpc.initial_reconnect_backoff_ms` - - `grpc.max_reconnect_backoff_ms` - - `grpc.use_local_subchannel_pool` - - `grpc.max_send_message_length` - - `grpc.max_receive_message_length` - - `grpc.enable_http_proxy` - - `channelOverride` - - `channelFactoryOverride` +In addition, all channel arguments defined in [this header file](https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/grpc_types.h) are handled by the `grpc` library. +Of those, a subset are handled by the `@grpc/grpc-js` library. See [the README](https://github.com/grpc/grpc-node/blob/master/packages/grpc-js/README.md#supported-channel-options) for `@grpc/grpc-js` for the list of supported channel options. diff --git a/packages/grpc-js/README.md b/packages/grpc-js/README.md index df44264ce..4799b0f4a 100644 --- a/packages/grpc-js/README.md +++ b/packages/grpc-js/README.md @@ -36,6 +36,28 @@ This library does not directly handle `.proto` files. To use `.proto` files with - If you are currently loading `.proto` files using `grpc.load`, that function is not available in this library. You should instead load your `.proto` files using `@grpc/proto-loader` and load the resulting package definition objects into `@grpc/grpc-js` using `grpc.loadPackageDefinition`. - If you are currently loading packages generated by `grpc-tools`, you should instead generate your files using the `generate_package_definition` option in `grpc-tools`, then load the object exported by the generated file into `@grpc/grpc-js` using `grpc.loadPackageDefinition`. - If you have a server and you are using `Server#bind` to bind ports, you will need to use `Server#bindAsync` instead. +- If you are using any channel options supported in `grpc` but not supported in `@grpc/grpc-js`, you may need to adjust your code to handle the different behavior. Refer to [the list of supported options](#supported-channel-options) below. +- Refer to the [detailed package comparison](https://github.com/grpc/grpc-node/blob/master/PACKAGE-COMPARISON.md) for more details on the differences between `grpc` and `@grpc/grpc-js`. + +## Supported Channel Options +Many channel arguments supported in `grpc` are not supported in `@grpc/grpc-js`. The channel arguments supported by `@grpc/grpc-js` are: + - `grpc.ssl_target_name_override` + - `grpc.primary_user_agent` + - `grpc.secondary_user_agent` + - `grpc.default_authority` + - `grpc.keepalive_time_ms` + - `grpc.keepalive_timeout_ms` + - `grpc.keepalive_permit_without_calls` + - `grpc.service_config` + - `grpc.max_concurrent_streams` + - `grpc.initial_reconnect_backoff_ms` + - `grpc.max_reconnect_backoff_ms` + - `grpc.use_local_subchannel_pool` + - `grpc.max_send_message_length` + - `grpc.max_receive_message_length` + - `grpc.enable_http_proxy` + - `channelOverride` + - `channelFactoryOverride` ## Some Notes on API Guarantees From f049333e488d3446291d791b66383d1f2527cad7 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 5 Jan 2022 10:51:00 -0800 Subject: [PATCH 169/450] proto-loader: Decrease dependency to yargs 16 for compatibility with Node <12 --- packages/proto-loader/bin/proto-loader-gen-types.ts | 2 +- packages/proto-loader/package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index 30df07bdc..a819d12d4 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -768,7 +768,7 @@ async function writeAllFiles(protoFiles: string[], options: GeneratorOptions) { } async function runScript() { - const argv = await yargs + const argv = yargs .parserConfiguration({ 'parse-positional-numbers': false }) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index b1d3182f7..5694cb547 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -49,14 +49,14 @@ "lodash.camelcase": "^4.3.0", "long": "^4.0.0", "protobufjs": "^6.10.0", - "yargs": "^17.3.1" + "yargs": "^16.2.0" }, "devDependencies": { "@types/lodash.camelcase": "^4.3.4", "@types/mkdirp": "^1.0.1", "@types/mocha": "^5.2.7", "@types/node": "^10.17.26", - "@types/yargs": "^17.0.8", + "@types/yargs": "^16.0.4", "clang-format": "^1.2.2", "gts": "^1.1.0", "rimraf": "^3.0.2", From ee9226e3c87bdbf767e6360f0c897019cec9bae1 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 5 Jan 2022 10:51:45 -0800 Subject: [PATCH 170/450] proto-loader: Update version to 0.6.9 --- packages/proto-loader/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index 5694cb547..9b9431dc1 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/proto-loader", - "version": "0.6.8", + "version": "0.6.9", "author": "Google Inc.", "contributors": [ { From ea1a266dec4a87546a48d29666a73d37d4c4d6e6 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 6 Jan 2022 14:36:40 -0800 Subject: [PATCH 171/450] Update grpc-js and grpc-js-xds to version 1.5.0, and update README --- packages/grpc-js-xds/README.md | 3 ++- packages/grpc-js-xds/package.json | 4 ++-- packages/grpc-js/package.json | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js-xds/README.md b/packages/grpc-js-xds/README.md index 84d291508..1ac235c40 100644 --- a/packages/grpc-js-xds/README.md +++ b/packages/grpc-js-xds/README.md @@ -26,4 +26,5 @@ const client = new MyServiceClient('xds:///example.com:123'); - [xDS v3 API](https://github.com/grpc/proposal/blob/master/A30-xds-v3.md) - [xDS Timeouts](https://github.com/grpc/proposal/blob/master/A31-xds-timeout-support-and-config-selector.md) - [xDS Circuit Breaking](https://github.com/grpc/proposal/blob/master/A32-xds-circuit-breaking.md) - - [xDS Client-Side Fault Injection](https://github.com/grpc/proposal/blob/master/A33-Fault-Injection.md) \ No newline at end of file + - [xDS Client-Side Fault Injection](https://github.com/grpc/proposal/blob/master/A33-Fault-Injection.md) + - [Client Status Discovery Service](https://github.com/grpc/proposal/blob/master/A40-csds-support.md) \ No newline at end of file diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index 2ead8f1e8..d3d9ad72f 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.4.0", + "version": "1.5.0", "description": "Plugin for @grpc/grpc-js. Adds the xds:// URL scheme and associated features.", "main": "build/src/index.js", "scripts": { @@ -47,7 +47,7 @@ "re2-wasm": "^1.0.1" }, "peerDependencies": { - "@grpc/grpc-js": "~1.4.0" + "@grpc/grpc-js": "~1.5.0" }, "engines": { "node": ">=10.10.0" diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 510eac614..97b647a86 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.4.6", + "version": "1.5.0", "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 c95357ccd1a246178141ae4c5962e531f2c8466b Mon Sep 17 00:00:00 2001 From: Jason Praful <32552408+jasonpraful@users.noreply.github.com> Date: Fri, 7 Jan 2022 10:51:38 +0000 Subject: [PATCH 172/450] refactor: added max session memory to docs --- packages/grpc-js/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/grpc-js/README.md b/packages/grpc-js/README.md index 4799b0f4a..cda4fec3c 100644 --- a/packages/grpc-js/README.md +++ b/packages/grpc-js/README.md @@ -56,6 +56,7 @@ Many channel arguments supported in `grpc` are not supported in `@grpc/grpc-js`. - `grpc.max_send_message_length` - `grpc.max_receive_message_length` - `grpc.enable_http_proxy` + - `grpc-node.max_session_memory` - `channelOverride` - `channelFactoryOverride` From d1762316e279d9a0dd224ca0a2eafc843f6a8bda Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 7 Jan 2022 12:21:12 -0800 Subject: [PATCH 173/450] grpc-js: Document recently-added channel options --- packages/grpc-js/README.md | 3 +++ packages/grpc-js/src/channel-options.ts | 3 +++ 2 files changed, 6 insertions(+) diff --git a/packages/grpc-js/README.md b/packages/grpc-js/README.md index 4799b0f4a..71ec937ed 100644 --- a/packages/grpc-js/README.md +++ b/packages/grpc-js/README.md @@ -56,6 +56,9 @@ Many channel arguments supported in `grpc` are not supported in `@grpc/grpc-js`. - `grpc.max_send_message_length` - `grpc.max_receive_message_length` - `grpc.enable_http_proxy` + - `grpc.default_compression_algorithm` + - `grpc.enable_channelz` + - `grpc-node.max_session_memory` - `channelOverride` - `channelFactoryOverride` diff --git a/packages/grpc-js/src/channel-options.ts b/packages/grpc-js/src/channel-options.ts index e1c16d127..688317227 100644 --- a/packages/grpc-js/src/channel-options.ts +++ b/packages/grpc-js/src/channel-options.ts @@ -36,6 +36,9 @@ export interface ChannelOptions { 'grpc.max_send_message_length'?: number; 'grpc.max_receive_message_length'?: number; 'grpc.enable_http_proxy'?: number; + /* http_connect_target and http_connect_creds are used for passing data + * around internally, and should not be documented as public-facing options + */ 'grpc.http_connect_target'?: string; 'grpc.http_connect_creds'?: string; 'grpc.default_compression_algorithm'?: CompressionAlgorithms; From f6d8f137a2fc0f43faf25ab3f51f540522b94a97 Mon Sep 17 00:00:00 2001 From: DavyJohnes Date: Mon, 10 Jan 2022 13:54:53 +0300 Subject: [PATCH 174/450] fix(make-client): set provided serviceName to generated class --- packages/grpc-js/src/make-client.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/grpc-js/src/make-client.ts b/packages/grpc-js/src/make-client.ts index b8ddda29f..7d08fee20 100644 --- a/packages/grpc-js/src/make-client.ts +++ b/packages/grpc-js/src/make-client.ts @@ -91,6 +91,7 @@ export interface ServiceClientConstructor { options?: Partial ): ServiceClient; service: ServiceDefinition; + serviceName: string; } /** @@ -127,6 +128,7 @@ export function makeClientConstructor( class ServiceClientImpl extends Client implements ServiceClient { static service: ServiceDefinition; + static serviceName: string; [methodName: string]: Function; } @@ -171,6 +173,7 @@ export function makeClientConstructor( }); ServiceClientImpl.service = methods; + ServiceClientImpl.serviceName = serviceName; return ServiceClientImpl; } From d46d5c0b2972cbbc2da6d17ab3dfab26efcc7df5 Mon Sep 17 00:00:00 2001 From: Seva Orlov Date: Tue, 11 Jan 2022 14:43:45 +0200 Subject: [PATCH 175/450] Add envoy/extensions files --- packages/grpc-js-xds/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index 2ead8f1e8..3f1ddb5e9 100644 --- a/packages/grpc-js-xds/package.json +++ b/packages/grpc-js-xds/package.json @@ -60,6 +60,7 @@ "deps/envoy-api/envoy/service/**/*.proto", "deps/envoy-api/envoy/type/**/*.proto", "deps/envoy-api/envoy/annotations/**/*.proto", + "deps/envoy-api/envoy/extensions/**/*.proto", "deps/googleapis/google/api/**/*.proto", "deps/googleapis/google/protobuf/**/*.proto", "deps/googleapis/google/rpc/**/*.proto", From 7b2cdd0291d5c269a7e3914300794b71702106a1 Mon Sep 17 00:00:00 2001 From: Seva Orlov Date: Tue, 11 Jan 2022 14:43:45 +0200 Subject: [PATCH 176/450] Add envoy/extensions files --- packages/grpc-js-xds/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index d3d9ad72f..6d6cc68ad 100644 --- a/packages/grpc-js-xds/package.json +++ b/packages/grpc-js-xds/package.json @@ -60,6 +60,7 @@ "deps/envoy-api/envoy/service/**/*.proto", "deps/envoy-api/envoy/type/**/*.proto", "deps/envoy-api/envoy/annotations/**/*.proto", + "deps/envoy-api/envoy/extensions/**/*.proto", "deps/googleapis/google/api/**/*.proto", "deps/googleapis/google/protobuf/**/*.proto", "deps/googleapis/google/rpc/**/*.proto", From 9e3bd11d64c7436d296b999bf7e041aebe6bf732 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 11 Jan 2022 11:10:58 -0800 Subject: [PATCH 177/450] grpc-js-xds: Increase version to 1.5.1 --- packages/grpc-js-xds/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index 6d6cc68ad..8af0c1037 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.5.0", + "version": "1.5.1", "description": "Plugin for @grpc/grpc-js. Adds the xds:// URL scheme and associated features.", "main": "build/src/index.js", "scripts": { From 70b7917dda5ef6e971f10fb967b4ef0391be20d7 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 12 Jan 2022 10:30:27 -0800 Subject: [PATCH 178/450] grpc-js-xds: Add more missing files, add distrib test --- packages/grpc-js-xds/package.json | 1 + run-tests.sh | 2 ++ test/distrib/distrib-test.js | 22 +++++++++++++++++++++ test/distrib/run-distrib-test.sh | 33 +++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+) create mode 100644 test/distrib/distrib-test.js create mode 100644 test/distrib/run-distrib-test.sh diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index 8af0c1037..ddc7f7bd2 100644 --- a/packages/grpc-js-xds/package.json +++ b/packages/grpc-js-xds/package.json @@ -55,6 +55,7 @@ "files": [ "src/**/*.ts", "build/src/**/*.{js,d.ts,js.map}", + "deps/envoy-api/envoy/admin/v3/**/*.proto", "deps/envoy-api/envoy/api/v2/**/*.proto", "deps/envoy-api/envoy/config/**/*.proto", "deps/envoy-api/envoy/service/**/*.proto", diff --git a/run-tests.sh b/run-tests.sh index e62cbd885..4bcb388b4 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -75,6 +75,8 @@ do # npm test calls nyc gulp test npm test || FAILED="true" + + ./test/distrib/run-distrib-test.sh || FAILED="true" done set +ex diff --git a/test/distrib/distrib-test.js b/test/distrib/distrib-test.js new file mode 100644 index 000000000..de3cbc7c7 --- /dev/null +++ b/test/distrib/distrib-test.js @@ -0,0 +1,22 @@ +/* + * 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. + * + */ + +const grpcJs = require('@grpc/grpc-js'); + +const grpcJsXds = require('@grpc/grpc-js-xds'); + +const protoLoader = require('@grpc/proto-loader'); \ No newline at end of file diff --git a/test/distrib/run-distrib-test.sh b/test/distrib/run-distrib-test.sh new file mode 100644 index 000000000..e2ed0853c --- /dev/null +++ b/test/distrib/run-distrib-test.sh @@ -0,0 +1,33 @@ +#!/bin/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 -ex + +cd $(dirname $0) +base=$(pwd) + +cd ../../packages/grpc-js +npm pack +cd ../grpc-js-xds +npm pack +cd ../proto-loader +npm pack + +cd $base +npm install ../../packages/grpc-js/grpc-grpc-js-*.tgz +npm install ../../packages/grpc-js-xds/grpc-grpc-js-xds-*.tgz +npm install ../../packages/proto-loader/grpc-proto-loader-*.tgz + +node ./distrib-test.js From aedfcebde5b2c5ffc64d867bd3628f2620a9a75f Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 12 Jan 2022 10:30:52 -0800 Subject: [PATCH 179/450] grpc-js-xds: Increase version to 1.5.2 --- packages/grpc-js-xds/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index ddc7f7bd2..b4e0a49d7 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.5.1", + "version": "1.5.2", "description": "Plugin for @grpc/grpc-js. Adds the xds:// URL scheme and associated features.", "main": "build/src/index.js", "scripts": { From 52a5e08c7525c04170f99d1b43c905c2510ec3e2 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 12 Jan 2022 10:51:01 -0800 Subject: [PATCH 180/450] chmod a+x run-distrib-test.sh --- test/distrib/run-distrib-test.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 test/distrib/run-distrib-test.sh diff --git a/test/distrib/run-distrib-test.sh b/test/distrib/run-distrib-test.sh old mode 100644 new mode 100755 From bc28ee42fd1449113b218c6382d21acc02bf29ff Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 12 Jan 2022 13:05:45 -0800 Subject: [PATCH 181/450] Add newline in distrib-test.js --- test/distrib/distrib-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/distrib/distrib-test.js b/test/distrib/distrib-test.js index de3cbc7c7..708c93eb8 100644 --- a/test/distrib/distrib-test.js +++ b/test/distrib/distrib-test.js @@ -19,4 +19,4 @@ const grpcJs = require('@grpc/grpc-js'); const grpcJsXds = require('@grpc/grpc-js-xds'); -const protoLoader = require('@grpc/proto-loader'); \ No newline at end of file +const protoLoader = require('@grpc/proto-loader'); From c6691c855105e95ac176cfb799069e69613f1993 Mon Sep 17 00:00:00 2001 From: Oskar Nyberg Date: Thu, 13 Jan 2022 16:24:48 +0100 Subject: [PATCH 182/450] grpc-js: Don't use http_proxy for uds connections --- packages/grpc-js/src/http_proxy.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/grpc-js/src/http_proxy.ts b/packages/grpc-js/src/http_proxy.ts index 248949a80..6faa1976d 100644 --- a/packages/grpc-js/src/http_proxy.ts +++ b/packages/grpc-js/src/http_proxy.ts @@ -136,6 +136,9 @@ export function mapProxyName( if ((options['grpc.enable_http_proxy'] ?? 1) === 0) { return noProxyResult; } + if (target.scheme === 'unix') { + return noProxyResult; + } const proxyInfo = getProxyInfo(); if (!proxyInfo.address) { return noProxyResult; From 5a728ffdc545bbd59247d927ba6e7f8f05e70934 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 13 Jan 2022 15:58:23 -0800 Subject: [PATCH 183/450] grpc-js: Add backoff to DNS resolution attempts --- packages/grpc-js/src/resolver-dns.ts | 33 ++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/src/resolver-dns.ts b/packages/grpc-js/src/resolver-dns.ts index 9077228b8..160b3d326 100644 --- a/packages/grpc-js/src/resolver-dns.ts +++ b/packages/grpc-js/src/resolver-dns.ts @@ -32,6 +32,7 @@ import { SubchannelAddress, TcpSubchannelAddress } from './subchannel-address'; import { GrpcUri, uriToString, splitHostPort } from './uri-parser'; import { isIPv6, isIPv4 } from 'net'; import { ChannelOptions } from './channel-options'; +import { BackoffOptions, BackoffTimeout } from './backoff-timeout'; const TRACER_NAME = 'dns_resolver'; @@ -85,6 +86,8 @@ class DnsResolver implements Resolver { private latestServiceConfigError: StatusObject | null = null; private percentage: number; private defaultResolutionError: StatusObject; + private backoff: BackoffTimeout; + private continueResolving = false; constructor( private target: GrpcUri, private listener: ResolverListener, @@ -119,6 +122,18 @@ class DnsResolver implements Resolver { details: `Name resolution failed for target ${uriToString(this.target)}`, metadata: new Metadata(), }; + + const backoffOptions: BackoffOptions = { + initialDelay: channelOptions['grpc.initial_reconnect_backoff_ms'], + maxDelay: channelOptions['grpc.max_reconnect_backoff_ms'], + }; + + this.backoff = new BackoffTimeout(() => { + if (this.continueResolving) { + this.startResolutionWithBackoff(); + } + }, backoffOptions); + this.backoff.unref(); } /** @@ -140,6 +155,7 @@ class DnsResolver implements Resolver { return; } if (this.dnsHostname === null) { + trace('Failed to parse DNS address ' + uriToString(this.target)); setImmediate(() => { this.listener.onError({ code: Status.UNAVAILABLE, @@ -148,6 +164,7 @@ class DnsResolver implements Resolver { }); }); } else { + trace('Looking up DNS hostname ' + this.dnsHostname); /* We clear out latestLookupResult here to ensure that it contains the * latest result since the last time we started resolving. That way, the * TXT resolution handler can use it, but only if it finishes second. We @@ -164,6 +181,7 @@ class DnsResolver implements Resolver { this.pendingLookupPromise.then( (addressList) => { this.pendingLookupPromise = null; + this.backoff.reset(); const ip4Addresses: dns.LookupAddress[] = addressList.filter( (addr) => addr.family === 4 ); @@ -263,10 +281,21 @@ class DnsResolver implements Resolver { } } + private startResolutionWithBackoff() { + this.startResolution(); + this.backoff.runOnce(); + } + updateResolution() { - trace('Resolution update requested for target ' + uriToString(this.target)); + /* If there is a pending lookup, just let it finish. Otherwise, if the + * backoff timer is running, do another lookup when it ends, and if not, + * do another lookup immeidately. */ if (this.pendingLookupPromise === null) { - this.startResolution(); + if (this.backoff.isRunning()) { + this.continueResolving = true; + } else { + this.startResolutionWithBackoff(); + } } } From 80f31bb1c29692939722fd342d3b9ed6b730de7d Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 13 Jan 2022 15:58:37 -0800 Subject: [PATCH 184/450] grpc-js: Increase version to 1.5.1 --- 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 97b647a86..95f157e63 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.5.0", + "version": "1.5.1", "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 500fc2c752a7259665b480b8b1457225d43c8087 Mon Sep 17 00:00:00 2001 From: Oskar Nyberg Date: Thu, 13 Jan 2022 16:24:48 +0100 Subject: [PATCH 185/450] grpc-js: Don't use http_proxy for uds connections --- packages/grpc-js/src/http_proxy.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/grpc-js/src/http_proxy.ts b/packages/grpc-js/src/http_proxy.ts index 248949a80..6faa1976d 100644 --- a/packages/grpc-js/src/http_proxy.ts +++ b/packages/grpc-js/src/http_proxy.ts @@ -136,6 +136,9 @@ export function mapProxyName( if ((options['grpc.enable_http_proxy'] ?? 1) === 0) { return noProxyResult; } + if (target.scheme === 'unix') { + return noProxyResult; + } const proxyInfo = getProxyInfo(); if (!proxyInfo.address) { return noProxyResult; From db56e80b2135dc5dfa87aae5e47df8b67fde2f9c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 18 Jan 2022 12:35:22 -0800 Subject: [PATCH 186/450] grpc-js: Add secureConnection error handling in server --- packages/grpc-js/src/server.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 33057defa..9c28a276f 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -371,6 +371,13 @@ export class Server { creds._getSettings()! ); http2Server = http2.createSecureServer(secureServerOptions); + http2Server.on('secureConnection', (socket: TLSSocket) => { + /* These errors need to be handled by the user of Http2SecureServer, + * according to https://github.com/nodejs/node/issues/35824 */ + socket.on('error', (e: Error) => { + this.trace('An incoming TLS connection closed with error: ' + e.message); + }); + }); } else { http2Server = http2.createServer(serverOptions); } From b9deb5bc3c75d4d568c4777d3b8328c1f8d8683f Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 18 Jan 2022 12:35:35 -0800 Subject: [PATCH 187/450] grpc-js: Increase version to 1.5.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 95f157e63..e84ae854f 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.5.1", + "version": "1.5.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 4b3c26382b0c4e4cd821b589d948d9ca5abd8b72 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 11 Jan 2022 11:07:19 -0800 Subject: [PATCH 188/450] Add subchannel interface --- packages/grpc-js/src/channel.ts | 3 +- packages/grpc-js/src/experimental.ts | 1 + .../src/load-balancer-child-handler.ts | 4 +- .../grpc-js/src/load-balancer-pick-first.ts | 14 ++-- .../grpc-js/src/load-balancer-round-robin.ts | 10 +-- packages/grpc-js/src/load-balancer.ts | 3 +- packages/grpc-js/src/picker.ts | 5 +- packages/grpc-js/src/subchannel-interface.ts | 82 +++++++++++++++++++ packages/grpc-js/src/subchannel.ts | 11 ++- 9 files changed, 109 insertions(+), 24 deletions(-) create mode 100644 packages/grpc-js/src/subchannel-interface.ts diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 8fa2c592a..8b9275e95 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -49,6 +49,7 @@ import { Filter } from './filter'; import { ConnectivityState } from './connectivity-state'; import { ChannelInfo, ChannelRef, ChannelzCallTracker, ChannelzChildrenTracker, ChannelzTrace, registerChannelzChannel, SubchannelRef, unregisterChannelzRef } from './channelz'; +import { Subchannel } from './subchannel'; /** * See https://nodejs.org/api/timers.html#timers_setinterval_callback_delay_args @@ -451,7 +452,7 @@ export class ChannelImplementation implements Channel { if (subchannelState === ConnectivityState.READY) { try { const pickExtraFilters = pickResult.extraFilterFactories.map(factory => factory.createFilter(callStream)); - pickResult.subchannel!.startCallStream( + pickResult.subchannel?.getRealSubchannel().startCallStream( finalMetadata, callStream, [...dynamicFilters, ...pickExtraFilters] diff --git a/packages/grpc-js/src/experimental.ts b/packages/grpc-js/src/experimental.ts index 5353f7f59..7356cb81a 100644 --- a/packages/grpc-js/src/experimental.ts +++ b/packages/grpc-js/src/experimental.ts @@ -34,3 +34,4 @@ export { Call as CallStream } from './call-stream'; export { Filter, BaseFilter, FilterFactory } from './filter'; export { FilterStackFactory } from './filter-stack'; export { registerAdminService } from './admin'; +export { SubchannelInterface, BaseSubchannelWrapper, ConnectivityStateListener } from './subchannel-interface' diff --git a/packages/grpc-js/src/load-balancer-child-handler.ts b/packages/grpc-js/src/load-balancer-child-handler.ts index c53914942..50708cf90 100644 --- a/packages/grpc-js/src/load-balancer-child-handler.ts +++ b/packages/grpc-js/src/load-balancer-child-handler.ts @@ -21,12 +21,12 @@ import { LoadBalancingConfig, createLoadBalancer, } from './load-balancer'; -import { Subchannel } from './subchannel'; import { SubchannelAddress } from './subchannel-address'; import { ChannelOptions } from './channel-options'; import { ConnectivityState } from './connectivity-state'; import { Picker } from './picker'; import { ChannelRef, SubchannelRef } from './channelz'; +import { SubchannelInterface } from './subchannel-interface'; const TYPE_NAME = 'child_load_balancer_helper'; @@ -40,7 +40,7 @@ export class ChildLoadBalancerHandler implements LoadBalancer { createSubchannel( subchannelAddress: SubchannelAddress, subchannelArgs: ChannelOptions - ): Subchannel { + ): SubchannelInterface { return this.parent.channelControlHelper.createSubchannel( subchannelAddress, subchannelArgs diff --git a/packages/grpc-js/src/load-balancer-pick-first.ts b/packages/grpc-js/src/load-balancer-pick-first.ts index 6cdb7cb91..c7033f589 100644 --- a/packages/grpc-js/src/load-balancer-pick-first.ts +++ b/packages/grpc-js/src/load-balancer-pick-first.ts @@ -31,13 +31,13 @@ import { PickResultType, UnavailablePicker, } from './picker'; -import { Subchannel, ConnectivityStateListener } from './subchannel'; import { SubchannelAddress, subchannelAddressToString, } from './subchannel-address'; import * as logging from './logging'; import { LogVerbosity } from './constants'; +import { SubchannelInterface, ConnectivityStateListener } from './subchannel-interface'; const TRACER_NAME = 'pick_first'; @@ -77,7 +77,7 @@ export class PickFirstLoadBalancingConfig implements LoadBalancingConfig { * picked subchannel. */ class PickFirstPicker implements Picker { - constructor(private subchannel: Subchannel) {} + constructor(private subchannel: SubchannelInterface) {} pick(pickArgs: PickArgs): CompletePickResult { return { @@ -107,7 +107,7 @@ export class PickFirstLoadBalancer implements LoadBalancer { * The list of subchannels this load balancer is currently attempting to * connect to. */ - private subchannels: Subchannel[] = []; + private subchannels: SubchannelInterface[] = []; /** * The current connectivity state of the load balancer. */ @@ -124,7 +124,7 @@ export class PickFirstLoadBalancer implements LoadBalancer { * and only if the load balancer's current state is READY. In that case, * the subchannel's current state is also READY. */ - private currentPick: Subchannel | null = null; + private currentPick: SubchannelInterface | null = null; /** * Listener callback attached to each subchannel in the `subchannels` list * while establishing a connection. @@ -157,7 +157,7 @@ export class PickFirstLoadBalancer implements LoadBalancer { [ConnectivityState.TRANSIENT_FAILURE]: 0, }; this.subchannelStateListener = ( - subchannel: Subchannel, + subchannel: SubchannelInterface, previousState: ConnectivityState, newState: ConnectivityState ) => { @@ -219,7 +219,7 @@ export class PickFirstLoadBalancer implements LoadBalancer { } }; this.pickedSubchannelStateListener = ( - subchannel: Subchannel, + subchannel: SubchannelInterface, previousState: ConnectivityState, newState: ConnectivityState ) => { @@ -310,7 +310,7 @@ export class PickFirstLoadBalancer implements LoadBalancer { }, CONNECTION_DELAY_INTERVAL_MS); } - private pickSubchannel(subchannel: Subchannel) { + private pickSubchannel(subchannel: SubchannelInterface) { trace('Pick subchannel with address ' + subchannel.getAddress()); if (this.currentPick !== null) { this.currentPick.unref(); diff --git a/packages/grpc-js/src/load-balancer-round-robin.ts b/packages/grpc-js/src/load-balancer-round-robin.ts index 918afab25..8a4094a02 100644 --- a/packages/grpc-js/src/load-balancer-round-robin.ts +++ b/packages/grpc-js/src/load-balancer-round-robin.ts @@ -30,13 +30,13 @@ import { PickResultType, UnavailablePicker, } from './picker'; -import { Subchannel, ConnectivityStateListener } from './subchannel'; import { SubchannelAddress, subchannelAddressToString, } from './subchannel-address'; import * as logging from './logging'; import { LogVerbosity } from './constants'; +import { ConnectivityStateListener, SubchannelInterface } from './subchannel-interface'; const TRACER_NAME = 'round_robin'; @@ -67,7 +67,7 @@ class RoundRobinLoadBalancingConfig implements LoadBalancingConfig { class RoundRobinPicker implements Picker { constructor( - private readonly subchannelList: Subchannel[], + private readonly subchannelList: SubchannelInterface[], private nextIndex = 0 ) {} @@ -88,7 +88,7 @@ class RoundRobinPicker implements Picker { * balancer implementation to preserve this part of the picker state if * possible when a subchannel connects or disconnects. */ - peekNextSubchannel(): Subchannel { + peekNextSubchannel(): SubchannelInterface { return this.subchannelList[this.nextIndex]; } } @@ -102,7 +102,7 @@ interface ConnectivityStateCounts { } export class RoundRobinLoadBalancer implements LoadBalancer { - private subchannels: Subchannel[] = []; + private subchannels: SubchannelInterface[] = []; private currentState: ConnectivityState = ConnectivityState.IDLE; @@ -121,7 +121,7 @@ export class RoundRobinLoadBalancer implements LoadBalancer { [ConnectivityState.TRANSIENT_FAILURE]: 0, }; this.subchannelStateListener = ( - subchannel: Subchannel, + subchannel: SubchannelInterface, previousState: ConnectivityState, newState: ConnectivityState ) => { diff --git a/packages/grpc-js/src/load-balancer.ts b/packages/grpc-js/src/load-balancer.ts index 19b79764c..48930c7db 100644 --- a/packages/grpc-js/src/load-balancer.ts +++ b/packages/grpc-js/src/load-balancer.ts @@ -21,6 +21,7 @@ import { SubchannelAddress } from './subchannel-address'; import { ConnectivityState } from './connectivity-state'; import { Picker } from './picker'; import { ChannelRef, SubchannelRef } from './channelz'; +import { SubchannelInterface } from './subchannel-interface'; /** * A collection of functions associated with a channel that a load balancer @@ -35,7 +36,7 @@ export interface ChannelControlHelper { createSubchannel( subchannelAddress: SubchannelAddress, subchannelArgs: ChannelOptions - ): Subchannel; + ): SubchannelInterface; /** * Passes a new subchannel picker up to the channel. This is called if either * the connectivity state changes or if a different picker is needed for any diff --git a/packages/grpc-js/src/picker.ts b/packages/grpc-js/src/picker.ts index 7aeed89b3..f366a6919 100644 --- a/packages/grpc-js/src/picker.ts +++ b/packages/grpc-js/src/picker.ts @@ -21,6 +21,7 @@ import { Metadata } from './metadata'; import { Status } from './constants'; import { LoadBalancer } from './load-balancer'; import { FilterFactory, Filter } from './filter'; +import { SubchannelInterface } from './subchannel-interface'; export enum PickResultType { COMPLETE, @@ -36,7 +37,7 @@ export interface PickResult { * `pickResultType` is COMPLETE. If null, indicates that the call should be * dropped. */ - subchannel: Subchannel | null; + subchannel: SubchannelInterface | null; /** * The status object to end the call with. Populated if and only if * `pickResultType` is TRANSIENT_FAILURE. @@ -53,7 +54,7 @@ export interface PickResult { export interface CompletePickResult extends PickResult { pickResultType: PickResultType.COMPLETE; - subchannel: Subchannel | null; + subchannel: SubchannelInterface | null; status: null; extraFilterFactories: FilterFactory[]; onCallStarted: (() => void) | null; diff --git a/packages/grpc-js/src/subchannel-interface.ts b/packages/grpc-js/src/subchannel-interface.ts new file mode 100644 index 000000000..cdf99176d --- /dev/null +++ b/packages/grpc-js/src/subchannel-interface.ts @@ -0,0 +1,82 @@ +/* + * 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. + * + */ + +import { SubchannelRef } from "./channelz"; +import { ConnectivityState } from "./connectivity-state"; +import { Subchannel } from "./subchannel"; + +export type ConnectivityStateListener = ( + subchannel: SubchannelInterface, + previousState: ConnectivityState, + newState: ConnectivityState +) => void; + +/** + * This is an interface for load balancing policies to use to interact with + * subchannels. This allows load balancing policies to wrap and unwrap + * subchannels. + * + * Any load balancing policy that wraps subchannels must unwrap the subchannel + * in the picker, so that other load balancing policies consistently have + * access to their own wrapper objects. + */ +export interface SubchannelInterface { + getConnectivityState(): ConnectivityState; + addConnectivityStateListener(listener: ConnectivityStateListener): void; + removeConnectivityStateListener(listener: ConnectivityStateListener): void; + startConnecting(): void; + getAddress(): string; + ref(): void; + unref(): void; + getChannelzRef(): SubchannelRef; + /** + * If this is a wrapper, return the wrapped subchannel, otherwise return this + */ + getRealSubchannel(): Subchannel; +} + +export abstract class BaseSubchannelWrapper implements SubchannelInterface { + constructor(private child: SubchannelInterface) {} + + getConnectivityState(): ConnectivityState { + return this.child.getConnectivityState(); + } + addConnectivityStateListener(listener: ConnectivityStateListener): void { + this.child.addConnectivityStateListener(listener); + } + removeConnectivityStateListener(listener: ConnectivityStateListener): void { + this.child.removeConnectivityStateListener(listener); + } + startConnecting(): void { + this.child.startConnecting(); + } + getAddress(): string { + return this.child.getAddress(); + } + ref(): void { + this.child.ref(); + } + unref(): void { + this.child.unref(); + } + getChannelzRef(): SubchannelRef { + return this.child.getChannelzRef(); + } + getRealSubchannel(): Subchannel { + return this.child.getRealSubchannel(); + } +} \ No newline at end of file diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 6f9471bb9..3a1f70487 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -37,6 +37,7 @@ import { subchannelAddressToString, } from './subchannel-address'; import { SubchannelRef, ChannelzTrace, ChannelzChildrenTracker, SubchannelInfo, registerChannelzSubchannel, ChannelzCallTracker, SocketInfo, SocketRef, unregisterChannelzRef, registerChannelzSocket, TlsInfo } from './channelz'; +import { ConnectivityStateListener } from './subchannel-interface'; const clientVersion = require('../../package.json').version; @@ -54,12 +55,6 @@ const BACKOFF_JITTER = 0.2; const KEEPALIVE_MAX_TIME_MS = ~(1 << 31); const KEEPALIVE_TIMEOUT_MS = 20000; -export type ConnectivityStateListener = ( - subchannel: Subchannel, - previousState: ConnectivityState, - newState: ConnectivityState -) => void; - export interface SubchannelCallStatsTracker { addMessageSent(): void; addMessageReceived(): void; @@ -949,4 +944,8 @@ export class Subchannel { getChannelzRef(): SubchannelRef { return this.channelzRef; } + + getRealSubchannel(): this { + return this; + } } From 0a5a2321b4ea1c6442627b843c80e2bb101a280f Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 20 Jan 2022 09:31:09 -0800 Subject: [PATCH 189/450] grpc-js: Fix pick first shutdown reference handling --- .../grpc-js/src/load-balancer-pick-first.ts | 10 ++- .../test/test-local-subchannel-pool.ts | 73 +++++++++++++++++++ 2 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 packages/grpc-js/test/test-local-subchannel-pool.ts diff --git a/packages/grpc-js/src/load-balancer-pick-first.ts b/packages/grpc-js/src/load-balancer-pick-first.ts index 6cdb7cb91..2f638ae68 100644 --- a/packages/grpc-js/src/load-balancer-pick-first.ts +++ b/packages/grpc-js/src/load-balancer-pick-first.ts @@ -449,11 +449,15 @@ export class PickFirstLoadBalancer implements LoadBalancer { destroy() { this.resetSubchannelList(); if (this.currentPick !== null) { - this.currentPick.unref(); - this.currentPick.removeConnectivityStateListener( + /* Unref can cause a state change, which can cause a change in the value + * of this.currentPick, so we hold a local reference to make sure that + * does not impact this function. */ + const currentPick = this.currentPick; + currentPick.unref(); + currentPick.removeConnectivityStateListener( this.pickedSubchannelStateListener ); - this.channelControlHelper.removeChannelzChild(this.currentPick.getChannelzRef()); + this.channelControlHelper.removeChannelzChild(currentPick.getChannelzRef()); } } diff --git a/packages/grpc-js/test/test-local-subchannel-pool.ts b/packages/grpc-js/test/test-local-subchannel-pool.ts new file mode 100644 index 000000000..081b2d3dc --- /dev/null +++ b/packages/grpc-js/test/test-local-subchannel-pool.ts @@ -0,0 +1,73 @@ +/* + * 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. + * + */ + +import * as assert from 'assert'; +import * as path from 'path'; +import * as grpc from '../src'; +import { sendUnaryData, Server, ServerCredentials, ServerUnaryCall, ServiceClientConstructor, ServiceError } from "../src"; +import { loadProtoFile } from './common'; + +const protoFile = path.join(__dirname, 'fixtures', 'echo_service.proto'); +const echoService = loadProtoFile(protoFile) + .EchoService as ServiceClientConstructor; + +describe('Local subchannel pool', () => { + let server: Server; + let serverPort: number; + + before(done => { + + server = new Server(); + server.addService(echoService.service, { + echo(call: ServerUnaryCall, callback: sendUnaryData) { + callback(null, call.request); + }, + }); + + server.bindAsync( + 'localhost:0', + ServerCredentials.createInsecure(), + (err, port) => { + assert.ifError(err); + serverPort = port; + server.start(); + done(); + } + ); + }); + + after(done => { + server.tryShutdown(done); + }); + + it('should complete the client lifecycle without error', done => { + const client = new echoService( + `localhost:${serverPort}`, + grpc.credentials.createInsecure(), + {'grpc.use_local_subchannel_pool': 1} + ); + client.echo( + { value: 'test value', value2: 3 }, + (error: ServiceError, response: any) => { + assert.ifError(error); + assert.deepStrictEqual(response, { value: 'test value', value2: 3 }); + client.close(); + done(); + } + ); + }); +}); \ No newline at end of file From 27bae2009dc22e0fb39fbd61a57201c80f2e705b Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 20 Jan 2022 09:36:44 -0800 Subject: [PATCH 190/450] grpc-js: Increase version to 1.5.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 e84ae854f..3b62aa5ed 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.5.2", + "version": "1.5.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 ba70f7168b41c8533bdaed0bde2cbf573cbdcf1e Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 31 Jan 2022 13:54:40 -0800 Subject: [PATCH 191/450] grpc-js: Fix exitIdle propagation and DNS IP result backoff --- packages/grpc-js/src/load-balancer-child-handler.ts | 4 ++-- packages/grpc-js/src/resolver-dns.ts | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/src/load-balancer-child-handler.ts b/packages/grpc-js/src/load-balancer-child-handler.ts index c53914942..3379ec8a7 100644 --- a/packages/grpc-js/src/load-balancer-child-handler.ts +++ b/packages/grpc-js/src/load-balancer-child-handler.ts @@ -125,9 +125,9 @@ export class ChildLoadBalancerHandler implements LoadBalancer { } exitIdle(): void { if (this.currentChild) { - this.currentChild.resetBackoff(); + this.currentChild.exitIdle(); if (this.pendingChild) { - this.pendingChild.resetBackoff(); + this.pendingChild.exitIdle(); } } } diff --git a/packages/grpc-js/src/resolver-dns.ts b/packages/grpc-js/src/resolver-dns.ts index 160b3d326..8ad24ed05 100644 --- a/packages/grpc-js/src/resolver-dns.ts +++ b/packages/grpc-js/src/resolver-dns.ts @@ -144,6 +144,7 @@ class DnsResolver implements Resolver { if (this.ipResult !== null) { trace('Returning IP address for target ' + uriToString(this.target)); setImmediate(() => { + this.backoff.reset(); this.listener.onSuccessfulResolution( this.ipResult!, null, From f49ed624766d1c40d1b9f215781bf84231688563 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 31 Jan 2022 13:55:07 -0800 Subject: [PATCH 192/450] grpc-js: Increase version to 1.5.4 --- 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 3b62aa5ed..8c65b9365 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.5.3", + "version": "1.5.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", From 2334ca9dfa24915e50304c7c8a472d8e9f34c1ea Mon Sep 17 00:00:00 2001 From: Yuri Golobokov Date: Mon, 7 Feb 2022 16:47:56 -0800 Subject: [PATCH 193/450] Add isTracerEnabled to logging --- packages/grpc-js/src/logging.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js/src/logging.ts b/packages/grpc-js/src/logging.ts index 549cd860e..ec845c1a5 100644 --- a/packages/grpc-js/src/logging.ts +++ b/packages/grpc-js/src/logging.ts @@ -108,10 +108,12 @@ export function trace( tracer: string, text: string ): void { - if ( - !disabledTracers.has(tracer) && - (allEnabled || enabledTracers.has(tracer)) - ) { + if (isTracerEnabled(tracer)) { log(severity, new Date().toISOString() + ' | ' + tracer + ' | ' + text); } } + +export function isTracerEnabled(tracer: string): boolean { + return !disabledTracers.has(tracer) && + (allEnabled || enabledTracers.has(tracer)); +} From ae2a2ac7d0880433b6b8fc584885a14e2ec4fd97 Mon Sep 17 00:00:00 2001 From: Yuri Golobokov Date: Mon, 7 Feb 2022 17:21:14 -0800 Subject: [PATCH 194/450] Add HTTP/2 settings frame tracing. This adds HTTP/2 settings frame information to debug logs. HTTP/2 settings frame contains important information like max_concurrent_streams and initial_window_size useful for debugging concurrency, latency, and throughput issues. --- packages/grpc-js/src/subchannel.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 6f9471bb9..9945b9881 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -555,6 +555,24 @@ export class Subchannel { (error as Error).message ); }); + if (logging.isTracerEnabled(TRACER_NAME)) { + session.on('remoteSettings', (settings: http2.Settings) => { + this.trace( + 'new settings received' + + (this.session !== session ? ' on the old connection' : '') + + ': ' + + JSON.stringify(settings) + ); + }); + session.on('localSettings', (settings: http2.Settings) => { + this.trace( + 'local settings acknowledged by remote' + + (this.session !== session ? ' on the old connection' : '') + + ': ' + + JSON.stringify(settings) + ); + }); + } } private startConnectingInternal() { From da66707d3bb9f5cf253b732888294a589c4dbc88 Mon Sep 17 00:00:00 2001 From: Yuri Golobokov Date: Tue, 8 Feb 2022 15:53:34 -0800 Subject: [PATCH 195/450] HTTP/2 flow control tracing subchannel_flowctrl tracer, if enabled, logs local and remote window sizes of subchannel's HTTP2 session to debug log on the start of every call. --- doc/environment_variables.md | 1 + packages/grpc-js/src/subchannel.ts | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/doc/environment_variables.md b/doc/environment_variables.md index f2a32294c..f4310e625 100644 --- a/doc/environment_variables.md +++ b/doc/environment_variables.md @@ -37,6 +37,7 @@ can be set. - `server_call` - Traces server handling of individual requests - `subchannel` - Traces subchannel connectivity state and errors - `subchannel_refcount` - Traces subchannel refcount changes + - `subchannel_flowctrl` - Traces HTTP/2 flow control The following tracers are added by the `@grpc/grpc-js-xds` library: - `cds_balancer` - Traces the CDS load balancing policy diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 9945b9881..faa68c145 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -41,6 +41,7 @@ import { SubchannelRef, ChannelzTrace, ChannelzChildrenTracker, SubchannelInfo, const clientVersion = require('../../package.json').version; const TRACER_NAME = 'subchannel'; +const FLOW_CONTROL_TRACER_NAME = 'subchannel_flowctrl'; const MIN_CONNECT_TIMEOUT_MS = 20000; const INITIAL_BACKOFF_MS = 1000; @@ -324,6 +325,10 @@ export class Subchannel { logging.trace(LogVerbosity.DEBUG, 'subchannel_refcount', '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' ' + text); } + private flowControlTrace(text: string): void { + logging.trace(LogVerbosity.DEBUG, FLOW_CONTROL_TRACER_NAME, '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' ' + text); + } + private handleBackoffTimer() { if (this.continueConnecting) { this.transitionToState( @@ -848,6 +853,12 @@ export class Subchannel { ' with headers\n' + headersString ); + this.flowControlTrace( + 'local window size: ' + + this.session!.state.localWindowSize + + ' remote window size: ' + + this.session!.state.remoteWindowSize + ); const streamSession = this.session; let statsTracker: SubchannelCallStatsTracker; if (this.channelzEnabled) { From 5bb11e02a0eded5696eaec06f9bbdab6c9234f72 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 10 Feb 2022 10:12:36 -0800 Subject: [PATCH 196/450] grpc-js: Increase version to 1.5.5 --- 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 8c65b9365..faad0991d 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.5.4", + "version": "1.5.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", From d51dfffcfeab1ac448b0ac51eebd3560623ccc7d Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 23 Feb 2022 09:50:11 -0800 Subject: [PATCH 197/450] grpc-js: Add session state logging at call start --- doc/environment_variables.md | 5 +++-- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/subchannel.ts | 11 +++++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/doc/environment_variables.md b/doc/environment_variables.md index f4310e625..2eb429f92 100644 --- a/doc/environment_variables.md +++ b/doc/environment_variables.md @@ -36,8 +36,9 @@ can be set. - `server` - Traces high-level server events - `server_call` - Traces server handling of individual requests - `subchannel` - Traces subchannel connectivity state and errors - - `subchannel_refcount` - Traces subchannel refcount changes - - `subchannel_flowctrl` - Traces HTTP/2 flow control + - `subchannel_refcount` - Traces subchannel refcount changes. Includes per-call logs. + - `subchannel_flowctrl` - Traces HTTP/2 flow control. Includes per-call logs. + - `subchannel_internals` - Traces HTTP/2 session state. Includes per-call logs. The following tracers are added by the `@grpc/grpc-js-xds` library: - `cds_balancer` - Traces the CDS load balancing policy diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index faad0991d..d7708194e 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.5.5", + "version": "1.5.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/subchannel.ts b/packages/grpc-js/src/subchannel.ts index faa68c145..524e36316 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -329,6 +329,10 @@ export class Subchannel { logging.trace(LogVerbosity.DEBUG, FLOW_CONTROL_TRACER_NAME, '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' ' + text); } + private internalsTrace(text: string): void { + logging.trace(LogVerbosity.DEBUG, 'subchannel_internals', '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' ' + text); + } + private handleBackoffTimer() { if (this.continueConnecting) { this.transitionToState( @@ -860,6 +864,13 @@ export class Subchannel { this.session!.state.remoteWindowSize ); const streamSession = this.session; + this.internalsTrace( + 'session.closed=' + + streamSession!.closed + + ' session.destroyed=' + + streamSession!.destroyed + + ' session.socket.destroyed=' + + streamSession!.socket.destroyed); let statsTracker: SubchannelCallStatsTracker; if (this.channelzEnabled) { this.callTracker.addCallStarted(); From 55087d21c4d4752731c7812d6649eb75dccb275b Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 24 Feb 2022 09:09:54 -0800 Subject: [PATCH 198/450] grpc-js: Transition subchannel to TRANSIENT_FAILURE when the socket closes --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/subchannel.ts | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index d7708194e..f41de376d 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.5.6", + "version": "1.5.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.ts b/packages/grpc-js/src/subchannel.ts index 524e36316..24f02144d 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -669,9 +669,15 @@ export class Subchannel { switch (newState) { case ConnectivityState.READY: this.stopBackoff(); - this.session!.socket.once('close', () => { - for (const listener of this.disconnectListeners) { - listener(); + const session = this.session!; + session.socket.once('close', () => { + if (this.session === session) { + this.transitionToState( + [ConnectivityState.READY], + ConnectivityState.TRANSIENT_FAILURE); + for (const listener of this.disconnectListeners) { + listener(); + } } }); if (this.keepaliveWithoutCalls) { From a3ecb4513232557dc9132b81aea9d67ef9544c15 Mon Sep 17 00:00:00 2001 From: Dacio Romero Date: Tue, 1 Mar 2022 14:48:25 -0800 Subject: [PATCH 199/450] grpc-js: Return never from functions that always throw --- packages/grpc-js/src/channel-credentials.ts | 2 +- packages/grpc-js/src/index.ts | 4 ++-- packages/grpc-js/src/resolving-load-balancer.ts | 2 +- packages/grpc-js/src/server.ts | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/grpc-js/src/channel-credentials.ts b/packages/grpc-js/src/channel-credentials.ts index 94b66c1bd..fd9d7b571 100644 --- a/packages/grpc-js/src/channel-credentials.ts +++ b/packages/grpc-js/src/channel-credentials.ts @@ -173,7 +173,7 @@ class InsecureChannelCredentialsImpl extends ChannelCredentials { super(callCredentials); } - compose(callCredentials: CallCredentials): ChannelCredentials { + compose(callCredentials: CallCredentials): never { throw new Error('Cannot compose insecure credentials'); } diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index 4bf1d9363..fa782aaa4 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -207,13 +207,13 @@ export type Call = /* eslint-disable @typescript-eslint/no-explicit-any */ -export const loadObject = (value: any, options: any) => { +export const loadObject = (value: any, options: any): never => { throw new Error( 'Not available in this library. Use @grpc/proto-loader and loadPackageDefinition instead' ); }; -export const load = (filename: any, format: any, options: any) => { +export const load = (filename: any, format: any, options: any): never => { throw new Error( 'Not available in this library. Use @grpc/proto-loader and loadPackageDefinition instead' ); diff --git a/packages/grpc-js/src/resolving-load-balancer.ts b/packages/grpc-js/src/resolving-load-balancer.ts index 5bc861283..907067dfc 100644 --- a/packages/grpc-js/src/resolving-load-balancer.ts +++ b/packages/grpc-js/src/resolving-load-balancer.ts @@ -312,7 +312,7 @@ export class ResolvingLoadBalancer implements LoadBalancer { updateAddressList( addressList: SubchannelAddress[], lbConfig: LoadBalancingConfig | null - ) { + ): never { throw new Error('updateAddressList not supported on ResolvingLoadBalancer'); } diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 33057defa..e0074807e 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -231,7 +231,7 @@ export class Server { } - addProtoService(): void { + addProtoService(): never { throw new Error('Not implemented. Use addService() instead'); } @@ -311,7 +311,7 @@ export class Server { }); } - bind(port: string, creds: ServerCredentials): void { + bind(port: string, creds: ServerCredentials): never { throw new Error('Not implemented. Use bindAsync() instead'); } @@ -696,7 +696,7 @@ export class Server { } } - addHttp2Port(): void { + addHttp2Port(): never { throw new Error('Not yet implemented'); } From 2062062a5cb6741818d31fa3d9c516741389d236 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 19 Jan 2022 10:17:51 -0800 Subject: [PATCH 200/450] grpc-js: Add outlier detection LB policy --- packages/grpc-js/gulpfile.ts | 1 + packages/grpc-js/src/duration.ts | 36 ++ packages/grpc-js/src/experimental.ts | 3 +- packages/grpc-js/src/index.ts | 2 + .../src/load-balancer-outlier-detection.ts | 569 ++++++++++++++++++ packages/grpc-js/src/service-config.ts | 6 +- packages/grpc-js/src/subchannel-interface.ts | 2 +- .../grpc-js/test/test-outlier-detection.ts | 121 ++++ 8 files changed, 733 insertions(+), 7 deletions(-) create mode 100644 packages/grpc-js/src/duration.ts create mode 100644 packages/grpc-js/src/load-balancer-outlier-detection.ts create mode 100644 packages/grpc-js/test/test-outlier-detection.ts diff --git a/packages/grpc-js/gulpfile.ts b/packages/grpc-js/gulpfile.ts index 6d8d20943..d85900364 100644 --- a/packages/grpc-js/gulpfile.ts +++ b/packages/grpc-js/gulpfile.ts @@ -67,6 +67,7 @@ const compile = checkTask(() => execNpmCommand('compile')); 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']})); diff --git a/packages/grpc-js/src/duration.ts b/packages/grpc-js/src/duration.ts new file mode 100644 index 000000000..278c9ae54 --- /dev/null +++ b/packages/grpc-js/src/duration.ts @@ -0,0 +1,36 @@ +/* + * 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. + * + */ + +export interface Duration { + seconds: number; + nanos: number; +} + +export function msToDuration(millis: number): Duration { + return { + seconds: (millis / 1000) | 0, + nanos: (millis % 1000) * 1_000_000 | 0 + }; +} + +export function durationToMs(duration: Duration): number { + return (duration.seconds * 1000 + duration.nanos / 1_000_000) | 0; +} + +export function isDuration(value: any): value is Duration { + return (typeof value.seconds === 'number') && (typeof value.nanos === 'number'); +} \ No newline at end of file diff --git a/packages/grpc-js/src/experimental.ts b/packages/grpc-js/src/experimental.ts index 7356cb81a..a9d76406b 100644 --- a/packages/grpc-js/src/experimental.ts +++ b/packages/grpc-js/src/experimental.ts @@ -6,7 +6,8 @@ export { ConfigSelector, } from './resolver'; export { GrpcUri, uriToString } from './uri-parser'; -export { ServiceConfig, Duration } from './service-config'; +export { Duration } from './duration'; +export { ServiceConfig } from './service-config'; export { BackoffTimeout } from './backoff-timeout'; export { LoadBalancer, diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index 4bf1d9363..b7771be29 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -273,6 +273,7 @@ import * as resolver_uds from './resolver-uds'; import * as resolver_ip from './resolver-ip'; import * as load_balancer_pick_first from './load-balancer-pick-first'; import * as load_balancer_round_robin from './load-balancer-round-robin'; +import * as load_balancer_outlier_detection from './load-balancer-outlier-detection'; import * as channelz from './channelz'; const clientVersion = require('../../package.json').version; @@ -284,5 +285,6 @@ const clientVersion = require('../../package.json').version; resolver_ip.setup(); load_balancer_pick_first.setup(); load_balancer_round_robin.setup(); + load_balancer_outlier_detection.setup(); channelz.setup(); })(); diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts new file mode 100644 index 000000000..ffca1c68e --- /dev/null +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -0,0 +1,569 @@ +/* + * 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. + * + */ + +import { ChannelOptions, connectivityState, StatusObject } from "."; +import { Call } from "./call-stream"; +import { ConnectivityState } from "./connectivity-state"; +import { Status } from "./constants"; +import { durationToMs, isDuration, msToDuration } from "./duration"; +import { ChannelControlHelper, createChildChannelControlHelper, registerLoadBalancerType } from "./experimental"; +import { BaseFilter, Filter, FilterFactory } from "./filter"; +import { getFirstUsableConfig, LoadBalancer, LoadBalancingConfig, validateLoadBalancingConfig } from "./load-balancer"; +import { ChildLoadBalancerHandler } from "./load-balancer-child-handler"; +import { PickArgs, Picker, PickResult, PickResultType, QueuePicker, UnavailablePicker } from "./picker"; +import { Subchannel } from "./subchannel"; +import { SubchannelAddress, subchannelAddressToString } from "./subchannel-address"; +import { BaseSubchannelWrapper, ConnectivityStateListener, SubchannelInterface } from "./subchannel-interface"; + + +const TYPE_NAME = 'outlier_detection'; + +const OUTLIER_DETECTION_ENABLED = process.env.GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION === 'true'; + +interface SuccessRateEjectionConfig { + readonly stdev_factor: number; + readonly enforcement_percentage: number; + readonly minimum_hosts: number; + readonly request_volume: number; +} + +interface FailurePercentageEjectionConfig { + readonly threshold: number; + readonly enforcement_percentage: number; + readonly minimum_hosts: number; + readonly request_volume: number; +} + +const defaultSuccessRateEjectionConfig: SuccessRateEjectionConfig = { + stdev_factor: 1900, + enforcement_percentage: 100, + minimum_hosts: 5, + request_volume: 100 +}; + +const defaultFailurePercentageEjectionConfig: FailurePercentageEjectionConfig = { + threshold: 85, + enforcement_percentage: 100, + minimum_hosts: 5, + request_volume: 50 +} + +type TypeofValues = 'object' | 'boolean' | 'function' | 'number' | 'string' | 'undefined'; + +function validateFieldType(obj: any, fieldName: string, expectedType: TypeofValues, objectName?: string) { + if (fieldName in obj && typeof obj[fieldName] !== expectedType) { + const fullFieldName = objectName ? `${objectName}.${fieldName}` : fieldName; + throw new Error(`outlier detection config ${fullFieldName} parse error: expected ${expectedType}, got ${typeof obj[fieldName]}`); + } +} + +function validatePositiveDuration(obj: any, fieldName: string, objectName?: string) { + const fullFieldName = objectName ? `${objectName}.${fieldName}` : fieldName; + if (fieldName in obj) { + if (!isDuration(obj[fieldName])) { + throw new Error(`outlier detection config ${fullFieldName} parse error: expected Duration, got ${typeof obj[fieldName]}`); + } + if (!(obj[fieldName].seconds >= 0 && obj[fieldName].seconds <= 315_576_000_000 && obj[fieldName].nanos >= 0 && obj[fieldName].nanos <= 999_999_999)) { + throw new Error(`outlier detection config ${fullFieldName} parse error: values out of range for non-negative Duaration`); + } + } +} + +function validatePercentage(obj: any, fieldName: string, objectName?: string) { + const fullFieldName = objectName ? `${objectName}.${fieldName}` : fieldName; + validateFieldType(obj, fieldName, 'number', objectName); + if (fieldName in obj && !(obj[fieldName] >= 0 && obj[fieldName] <= 100)) { + throw new Error(`outlier detection config ${fullFieldName} parse error: value out of range for percentage (0-100)`); + } +} + +export class OutlierDetectionLoadBalancingConfig implements LoadBalancingConfig { + constructor( + private readonly intervalMs: number, + private readonly baseEjectionTimeMs: number, + private readonly maxEjectionTimeMs: number, + private readonly maxEjectionPercent: number, + private readonly successRateEjection: SuccessRateEjectionConfig | null, + private readonly failurePercentageEjection: FailurePercentageEjectionConfig | null, + private readonly childPolicy: LoadBalancingConfig[] + ) {} + getLoadBalancerName(): string { + return TYPE_NAME; + } + toJsonObject(): object { + return { + interval: msToDuration(this.intervalMs), + base_ejection_time: msToDuration(this.baseEjectionTimeMs), + max_ejection_time: msToDuration(this.maxEjectionTimeMs), + max_ejection_percent: this.maxEjectionPercent, + success_rate_ejection: this.successRateEjection, + failure_percentage_ejection: this.failurePercentageEjection, + child_policy: this.childPolicy.map(policy => policy.toJsonObject()) + }; + } + + getIntervalMs(): number { + return this.intervalMs; + } + getBaseEjectionTimeMs(): number { + return this.baseEjectionTimeMs; + } + getMaxEjectionTimeMs(): number { + return this.maxEjectionTimeMs; + } + getMaxEjectionPercent(): number { + return this.maxEjectionPercent; + } + getSuccessRateEjectionConfig(): SuccessRateEjectionConfig | null { + return this.successRateEjection; + } + getFailurePercentageEjectionConfig(): FailurePercentageEjectionConfig | null { + return this.failurePercentageEjection; + } + getChildPolicy(): LoadBalancingConfig[] { + return this.childPolicy; + } + static createFromJson(obj: any): OutlierDetectionLoadBalancingConfig { + validatePositiveDuration(obj, 'interval'); + validatePositiveDuration(obj, 'base_ejection_time'); + validatePositiveDuration(obj, 'max_ejection_time'); + validatePercentage(obj, 'max_ejection_percent'); + if ('success_rate_ejection' in obj) { + if (typeof obj.success_rate_ejection !== 'object') { + throw new Error('outlier detection config success_rate_ejection must be an object'); + } + validateFieldType(obj.success_rate_ejection, 'stdev_factor', 'number', 'success_rate_ejection'); + validatePercentage(obj.success_rate_ejection, 'enforcement_percentage', 'success_rate_ejection'); + validateFieldType(obj.success_rate_ejection, 'minimum_hosts', 'number', 'success_rate_ejection'); + validateFieldType(obj.success_rate_ejection, 'request_volume', 'number', 'success_rate_ejection'); + } + if ('failure_percentage_ejection' in obj) { + if (typeof obj.failure_percentage_ejection !== 'object') { + throw new Error('outlier detection config failure_percentage_ejection must be an object'); + } + validatePercentage(obj.failure_percentage_ejection, 'threshold', 'failure_percentage_ejection'); + validatePercentage(obj.failure_percentage_ejection, 'enforcement_percentage', 'failure_percentage_ejection'); + validateFieldType(obj.failure_percentage_ejection, 'minimum_hosts', 'number', 'failure_percentage_ejection'); + validateFieldType(obj.failure_percentage_ejection, 'request_volume', 'number', 'failure_percentage_ejection'); + } + + return new OutlierDetectionLoadBalancingConfig( + obj.interval ? durationToMs(obj.interval) : 10_000, + obj.base_ejection_time ? durationToMs(obj.base_ejection_time) : 30_000, + obj.max_ejection_time ? durationToMs(obj.max_ejection_time) : 300_000, + obj.max_ejection_percent ?? 10, + obj.success_rate_ejection ? {...defaultSuccessRateEjectionConfig, ...obj.success_rate_ejection} : null, + obj.failure_percentage_ejection ? {...defaultFailurePercentageEjectionConfig, ...obj.failure_percentage_ejection} : null, + obj.child_policy.map(validateLoadBalancingConfig) + ); + } +} + +class OutlierDetectionSubchannelWrapper extends BaseSubchannelWrapper implements SubchannelInterface { + private childSubchannelState: ConnectivityState = ConnectivityState.IDLE; + private stateListeners: ConnectivityStateListener[] = []; + private ejected: boolean = false; + private refCount: number = 0; + constructor(childSubchannel: SubchannelInterface, private mapEntry?: MapEntry) { + super(childSubchannel); + childSubchannel.addConnectivityStateListener((subchannel, previousState, newState) => { + this.childSubchannelState = newState; + if (!this.ejected) { + for (const listener of this.stateListeners) { + listener(this, previousState, newState); + } + } + }); + } + + /** + * Add a listener function to be called whenever the wrapper's + * connectivity state changes. + * @param listener + */ + addConnectivityStateListener(listener: ConnectivityStateListener) { + this.stateListeners.push(listener); + } + + /** + * Remove a listener previously added with `addConnectivityStateListener` + * @param listener A reference to a function previously passed to + * `addConnectivityStateListener` + */ + removeConnectivityStateListener(listener: ConnectivityStateListener) { + const listenerIndex = this.stateListeners.indexOf(listener); + if (listenerIndex > -1) { + this.stateListeners.splice(listenerIndex, 1); + } + } + + ref() { + this.child.ref(); + this.refCount += 1; + } + + unref() { + this.child.unref(); + this.refCount -= 1; + if (this.refCount <= 0) { + if (this.mapEntry) { + const index = this.mapEntry.subchannelWrappers.indexOf(this); + if (index >= 0) { + this.mapEntry.subchannelWrappers.splice(index, 1); + } + } + } + } + + eject() { + this.ejected = true; + for (const listener of this.stateListeners) { + listener(this, this.childSubchannelState, ConnectivityState.TRANSIENT_FAILURE); + } + } + + uneject() { + this.ejected = false; + for (const listener of this.stateListeners) { + listener(this, ConnectivityState.TRANSIENT_FAILURE, this.childSubchannelState); + } + } + + getMapEntry(): MapEntry | undefined { + return this.mapEntry; + } + + getWrappedSubchannel(): SubchannelInterface { + return this.child; + } +} + +interface CallCountBucket { + success: number; + failure: number; +} + +function createEmptyBucket(): CallCountBucket { + return { + success: 0, + failure: 0 + } +} + +class CallCounter { + private activeBucket: CallCountBucket = createEmptyBucket(); + private inactiveBucket: CallCountBucket = createEmptyBucket(); + addSuccess() { + this.activeBucket.success += 1; + } + addFailure() { + this.activeBucket.failure += 1; + } + switchBuckets() { + this.inactiveBucket = this.activeBucket; + this.activeBucket = createEmptyBucket(); + } + getLastSuccesses() { + return this.inactiveBucket.success; + } + getLastFailures() { + return this.inactiveBucket.failure; + } +} + +interface MapEntry { + counter: CallCounter; + currentEjectionTimestamp: Date | null; + ejectionTimeMultiplier: number; + subchannelWrappers: OutlierDetectionSubchannelWrapper[]; +} + +class OutlierDetectionCounterFilter extends BaseFilter implements Filter { + constructor(private callCounter: CallCounter) { + super(); + } + receiveTrailers(status: StatusObject): StatusObject { + if (status.code === Status.OK) { + this.callCounter.addSuccess(); + } else { + this.callCounter.addFailure(); + } + return status; + } +} + +class OutlierDetectionCounterFilterFactory implements FilterFactory { + constructor(private callCounter: CallCounter) {} + createFilter(callStream: Call): OutlierDetectionCounterFilter { + return new OutlierDetectionCounterFilter(this.callCounter); + } + +} + +class OutlierDetectionPicker implements Picker { + constructor(private wrappedPicker: Picker) {} + pick(pickArgs: PickArgs): PickResult { + const wrappedPick = this.wrappedPicker.pick(pickArgs); + if (wrappedPick.pickResultType === PickResultType.COMPLETE) { + const subchannelWrapper = wrappedPick.subchannel as OutlierDetectionSubchannelWrapper; + const mapEntry = subchannelWrapper.getMapEntry(); + if (mapEntry) { + return { + ...wrappedPick, + subchannel: subchannelWrapper.getWrappedSubchannel(), + extraFilterFactories: [...wrappedPick.extraFilterFactories, new OutlierDetectionCounterFilterFactory(mapEntry.counter)] + }; + } else { + return wrappedPick; + } + } else { + return wrappedPick; + } + } + +} + +export class OutlierDetectionLoadBalancer implements LoadBalancer { + private childBalancer: ChildLoadBalancerHandler; + private addressMap: Map = new Map(); + private latestConfig: OutlierDetectionLoadBalancingConfig | null = null; + private ejectionTimer: NodeJS.Timer; + + constructor(channelControlHelper: ChannelControlHelper) { + this.childBalancer = new ChildLoadBalancerHandler(createChildChannelControlHelper(channelControlHelper, { + createSubchannel: (subchannelAddress: SubchannelAddress, subchannelArgs: ChannelOptions) => { + const originalSubchannel = channelControlHelper.createSubchannel(subchannelAddress, subchannelArgs); + const mapEntry = this.addressMap.get(subchannelAddressToString(subchannelAddress)); + const subchannelWrapper = new OutlierDetectionSubchannelWrapper(originalSubchannel, mapEntry); + mapEntry?.subchannelWrappers.push(subchannelWrapper); + return subchannelWrapper; + }, + updateState: (connectivityState: ConnectivityState, picker: Picker) => { + if (connectivityState === ConnectivityState.READY) { + channelControlHelper.updateState(connectivityState, new OutlierDetectionPicker(picker)); + } else { + channelControlHelper.updateState(connectivityState, picker); + } + } + })); + this.ejectionTimer = setInterval(() => {}, 0); + clearInterval(this.ejectionTimer); + } + + private getCurrentEjectionPercent() { + let ejectionCount = 0; + for (const mapEntry of this.addressMap.values()) { + if (mapEntry.currentEjectionTimestamp !== null) { + ejectionCount += 1; + } + } + return (ejectionCount * 100) / this.addressMap.size; + } + + private runSuccessRateCheck(ejectionTimestamp: Date) { + if (!this.latestConfig) { + return; + } + const successRateConfig = this.latestConfig.getSuccessRateEjectionConfig(); + if (!successRateConfig) { + return; + } + // Step 1 + const targetRequestVolume = successRateConfig.request_volume; + let addresesWithTargetVolume = 0; + const successRates: number[] = [] + for (const mapEntry of this.addressMap.values()) { + const successes = mapEntry.counter.getLastSuccesses(); + const failures = mapEntry.counter.getLastFailures(); + if (successes + failures >= targetRequestVolume) { + addresesWithTargetVolume += 1; + successRates.push(successes/(successes + failures)); + } + } + if (addresesWithTargetVolume < successRateConfig.minimum_hosts) { + return; + } + + // Step 2 + const successRateMean = successRates.reduce((a, b) => a + b); + let successRateVariance = 0; + for (const rate of successRates) { + const deviation = rate - successRateMean; + successRateVariance += deviation * deviation; + } + const successRateStdev = Math.sqrt(successRateVariance); + const ejectionThreshold = successRateMean - successRateStdev * (successRateConfig.stdev_factor / 1000); + + // Step 3 + for (const mapEntry of this.addressMap.values()) { + // Step 3.i + if (this.getCurrentEjectionPercent() > this.latestConfig.getMaxEjectionPercent()) { + break; + } + // Step 3.ii + const successes = mapEntry.counter.getLastSuccesses(); + const failures = mapEntry.counter.getLastFailures(); + if (successes + failures < targetRequestVolume) { + continue; + } + // Step 3.iii + const successRate = successes / (successes + failures); + if (successRate < ejectionThreshold) { + const randomNumber = Math.random() * 100; + if (randomNumber < successRateConfig.enforcement_percentage) { + this.eject(mapEntry, ejectionTimestamp); + } + } + } + } + + private runFailurePercentageCheck(ejectionTimestamp: Date) { + if (!this.latestConfig) { + return; + } + const failurePercentageConfig = this.latestConfig.getFailurePercentageEjectionConfig() + if (!failurePercentageConfig) { + return; + } + // Step 1 + if (this.addressMap.size < failurePercentageConfig.minimum_hosts) { + return; + } + + // Step 2 + for (const mapEntry of this.addressMap.values()) { + // Step 2.i + if (this.getCurrentEjectionPercent() > this.latestConfig.getMaxEjectionPercent()) { + break; + } + // Step 2.ii + const successes = mapEntry.counter.getLastSuccesses(); + const failures = mapEntry.counter.getLastFailures(); + if (successes + failures < failurePercentageConfig.request_volume) { + continue; + } + // Step 2.iii + const failurePercentage = (failures * 100) / (failures + successes); + if (failurePercentage > failurePercentageConfig.threshold) { + const randomNumber = Math.random() * 100; + if (randomNumber < failurePercentageConfig.enforcement_percentage) { + this.eject(mapEntry, ejectionTimestamp); + } + } + } + } + + private eject(mapEntry: MapEntry, ejectionTimestamp: Date) { + mapEntry.currentEjectionTimestamp = new Date(); + mapEntry.ejectionTimeMultiplier += 1; + for (const subchannelWrapper of mapEntry.subchannelWrappers) { + subchannelWrapper.eject(); + } + } + + private uneject(mapEntry: MapEntry) { + mapEntry.currentEjectionTimestamp = null; + for (const subchannelWrapper of mapEntry.subchannelWrappers) { + subchannelWrapper.uneject(); + } + } + + private runChecks() { + const ejectionTimestamp = new Date(); + + for (const mapEntry of this.addressMap.values()) { + mapEntry.counter.switchBuckets(); + } + + if (!this.latestConfig) { + return; + } + + this.runSuccessRateCheck(ejectionTimestamp); + this.runFailurePercentageCheck(ejectionTimestamp); + + for (const mapEntry of this.addressMap.values()) { + if (mapEntry.currentEjectionTimestamp === null) { + if (mapEntry.ejectionTimeMultiplier > 0) { + mapEntry.ejectionTimeMultiplier -= 1; + } + } else { + const baseEjectionTimeMs = this.latestConfig.getBaseEjectionTimeMs(); + const maxEjectionTimeMs = this.latestConfig.getMaxEjectionTimeMs(); + const returnTime = new Date(mapEntry.currentEjectionTimestamp.getTime()); + returnTime.setMilliseconds(returnTime.getMilliseconds() + Math.min(baseEjectionTimeMs * mapEntry.ejectionTimeMultiplier, Math.max(baseEjectionTimeMs, maxEjectionTimeMs))); + if (returnTime < new Date()) { + this.uneject(mapEntry); + } + } + } + } + + updateAddressList(addressList: SubchannelAddress[], lbConfig: LoadBalancingConfig, attributes: { [key: string]: unknown; }): void { + if (!(lbConfig instanceof OutlierDetectionLoadBalancingConfig)) { + return; + } + const subchannelAddresses = new Set(); + for (const address of addressList) { + subchannelAddresses.add(subchannelAddressToString(address)); + } + for (const address of subchannelAddresses) { + if (!this.addressMap.has(address)) { + this.addressMap.set(address, { + counter: new CallCounter(), + currentEjectionTimestamp: null, + ejectionTimeMultiplier: 0, + subchannelWrappers: [] + }); + } + } + for (const key of this.addressMap.keys()) { + if (!subchannelAddresses.has(key)) { + this.addressMap.delete(key); + } + } + const childPolicy: LoadBalancingConfig = getFirstUsableConfig( + lbConfig.getChildPolicy(), + true + ); + this.childBalancer.updateAddressList(addressList, childPolicy, attributes); + + if (this.latestConfig === null || this.latestConfig.getIntervalMs() !== lbConfig.getIntervalMs()) { + clearInterval(this.ejectionTimer); + this.ejectionTimer = setInterval(() => this.runChecks(), lbConfig.getIntervalMs()); + } + this.latestConfig = lbConfig; + } + exitIdle(): void { + this.childBalancer.exitIdle(); + } + resetBackoff(): void { + this.childBalancer.resetBackoff(); + } + destroy(): void { + this.childBalancer.destroy(); + } + getTypeName(): string { + return TYPE_NAME; + } +} + +export function setup() { + if (OUTLIER_DETECTION_ENABLED) { + registerLoadBalancerType(TYPE_NAME, OutlierDetectionLoadBalancer, OutlierDetectionLoadBalancingConfig); + } +} \ No newline at end of file diff --git a/packages/grpc-js/src/service-config.ts b/packages/grpc-js/src/service-config.ts index 3f0a00868..f310597e9 100644 --- a/packages/grpc-js/src/service-config.ts +++ b/packages/grpc-js/src/service-config.ts @@ -27,6 +27,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import * as os from 'os'; +import { Duration } from './duration'; import { LoadBalancingConfig, validateLoadBalancingConfig, @@ -37,11 +38,6 @@ export interface MethodConfigName { method?: string; } -export interface Duration { - seconds: number; - nanos: number; -} - export interface MethodConfig { name: MethodConfigName[]; waitForReady?: boolean; diff --git a/packages/grpc-js/src/subchannel-interface.ts b/packages/grpc-js/src/subchannel-interface.ts index cdf99176d..082a8b3c0 100644 --- a/packages/grpc-js/src/subchannel-interface.ts +++ b/packages/grpc-js/src/subchannel-interface.ts @@ -50,7 +50,7 @@ export interface SubchannelInterface { } export abstract class BaseSubchannelWrapper implements SubchannelInterface { - constructor(private child: SubchannelInterface) {} + constructor(protected child: SubchannelInterface) {} getConnectivityState(): ConnectivityState { return this.child.getConnectivityState(); diff --git a/packages/grpc-js/test/test-outlier-detection.ts b/packages/grpc-js/test/test-outlier-detection.ts new file mode 100644 index 000000000..977a3058f --- /dev/null +++ b/packages/grpc-js/test/test-outlier-detection.ts @@ -0,0 +1,121 @@ +/* + * 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. + * + */ + +import * as assert from 'assert'; +import * as path from 'path'; +import * as grpc from '../src'; +import { loadProtoFile } from './common'; + +function multiDone(done: Mocha.Done, target: number) { + let count = 0; + return (error?: any) => { + if (error) { + done(error); + } + count++; + if (count >= target) { + done(); + } + } +} + +const defaultOutlierDetectionServiceConfig = { + methodConfig: [], + loadBalancingConfig: [ + { + outlier_detection: { + success_rate_ejection: {}, + failure_percentage_ejection: {}, + child_policy: [{round_robin: {}}] + } + } + ] +}; + +const defaultOutlierDetectionServiceConfigString = JSON.stringify(defaultOutlierDetectionServiceConfig); + +const goodService = { + echo: (call: grpc.ServerUnaryCall, callback: grpc.sendUnaryData) => { + callback(null, call.request) + } +}; + +const badService = { + echo: (call: grpc.ServerUnaryCall, callback: grpc.sendUnaryData) => { + callback({ + code: grpc.status.PERMISSION_DENIED, + details: 'Permission denied' + }) + } +} + +const protoFile = path.join(__dirname, 'fixtures', 'echo_service.proto'); +const EchoService = loadProtoFile(protoFile) + .EchoService as grpc.ServiceClientConstructor; + +describe('Outlier detection', () => { + const GOOD_PORTS = 4; + let goodServer: grpc.Server; + let badServer: grpc.Server; + const goodPorts: number[] = []; + let badPort: number; + before(done => { + const eachDone = multiDone(() => { + goodServer.start(); + badServer.start(); + done(); + }, GOOD_PORTS + 1); + goodServer = new grpc.Server(); + goodServer.addService(EchoService.service, goodService); + for (let i = 0; i < GOOD_PORTS; i++) { + goodServer.bindAsync('localhost:0', grpc.ServerCredentials.createInsecure(), (error, port) => { + if (error) { + eachDone(error); + return; + } + goodPorts.push(port); + eachDone(); + }); + } + badServer = new grpc.Server(); + badServer.addService(EchoService.service, badService); + badServer.bindAsync('localhost:0', grpc.ServerCredentials.createInsecure(), (error, port) => { + if (error) { + eachDone(error); + return; + } + badPort = port; + eachDone(); + }); + }); + after(() => { + goodServer.forceShutdown(); + badServer.forceShutdown(); + }); + + it('Should allow normal operation with one server', done => { + const client = new EchoService(`localhost:${goodPorts[0]}`, grpc.credentials.createInsecure(), {'grpc.service_config': defaultOutlierDetectionServiceConfigString}); + client.echo( + { value: 'test value', value2: 3 }, + (error: grpc.ServiceError, response: any) => { + assert.ifError(error); + assert.deepStrictEqual(response, { value: 'test value', value2: 3 }); + done(); + } + ); + }); +}); \ No newline at end of file From 5a601b0f78dd124fc0a9056f43d2e4d85d5c1246 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 14 Mar 2022 11:55:38 -0700 Subject: [PATCH 201/450] grpc-js: Consistently log subchannel and call IDs in traces --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/call-stream.ts | 4 ++++ packages/grpc-js/src/channel.ts | 17 +++++++++++------ packages/grpc-js/src/subchannel.ts | 2 +- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index f41de376d..f617223bc 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.5.7", + "version": "1.5.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/call-stream.ts b/packages/grpc-js/src/call-stream.ts index f2e045aef..601218886 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -795,6 +795,10 @@ export class Http2CallStream implements Call { this.filterStack.push(extraFilters); } + getCallNumber() { + return this.callNumber; + } + startRead() { /* If the stream has ended with an error, we should not emit any more * messages and we should communicate that the stream has ended */ diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 8fa2c592a..9d73c5df8 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -404,11 +404,16 @@ export class ChannelImplementation implements Channel { metadata: callMetadata, extraPickInfo: callConfig.pickInformation, }); + const subchannelString = pickResult.subchannel ? + '(' + pickResult.subchannel.getChannelzRef().id + ') ' + pickResult.subchannel.getAddress() : + '' + pickResult.subchannel; this.trace( - 'Pick result: ' + + 'Pick result for call [' + + callStream.getCallNumber() + + ']: ' + PickResultType[pickResult.pickResultType] + ' subchannel: ' + - pickResult.subchannel?.getAddress() + + subchannelString + ' status: ' + pickResult.status?.code + ' ' + @@ -433,7 +438,7 @@ export class ChannelImplementation implements Channel { log( LogVerbosity.ERROR, 'Error: COMPLETE pick result subchannel ' + - pickResult.subchannel!.getAddress() + + subchannelString + ' has state ' + ConnectivityState[pickResult.subchannel!.getConnectivityState()] ); @@ -480,7 +485,7 @@ export class ChannelImplementation implements Channel { * tryPick */ this.trace( 'Failed to start call on picked subchannel ' + - pickResult.subchannel!.getAddress() + + subchannelString + ' with error ' + (error as Error).message + '. Retrying pick', @@ -490,7 +495,7 @@ export class ChannelImplementation implements Channel { } else { this.trace( 'Failed to start call on picked subchanel ' + - pickResult.subchannel!.getAddress() + + subchannelString + ' with error ' + (error as Error).message + '. Ending call', @@ -509,7 +514,7 @@ export class ChannelImplementation implements Channel { * block above */ this.trace( 'Picked subchannel ' + - pickResult.subchannel!.getAddress() + + subchannelString + ' has state ' + ConnectivityState[subchannelState] + ' after metadata filters. Retrying pick', diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 24f02144d..22c243fed 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -857,7 +857,7 @@ export class Subchannel { logging.trace( LogVerbosity.DEBUG, 'call_stream', - 'Starting stream on subchannel ' + + 'Starting stream [' + callStream.getCallNumber() + '] on subchannel ' + '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' with headers\n' + From 109020ef02a443a76ad109a9cd520b49fca3e8af Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 15 Mar 2022 12:07:11 -0700 Subject: [PATCH 202/450] Add credentials scope in oauth2_auth_token interop test --- test/interop/interop_client.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/interop/interop_client.js b/test/interop/interop_client.js index d7df128da..57f4f1846 100644 --- a/test/interop/interop_client.js +++ b/test/interop/interop_client.js @@ -484,7 +484,7 @@ function getApplicationCreds(scope, callback) { } function getOauth2Creds(scope, callback) { - (new GoogleAuth()).getAccessToken().then((token) => { + (new GoogleAuth({scopes: scope})).getAccessToken().then((token) => { var updateMd = function(service_url, callback) { var metadata = new grpc.Metadata(); metadata.add('authorization', 'Bearer ' + token); From 97584dcf3193662388802abba1ffb224953bd1fa Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 16 Mar 2022 11:27:05 -0700 Subject: [PATCH 203/450] grpc-js: Add channel construction stacktrace traces --- doc/environment_variables.md | 1 + packages/grpc-js/src/channel.ts | 2 ++ 2 files changed, 3 insertions(+) diff --git a/doc/environment_variables.md b/doc/environment_variables.md index 2eb429f92..0237dff7e 100644 --- a/doc/environment_variables.md +++ b/doc/environment_variables.md @@ -39,6 +39,7 @@ can be set. - `subchannel_refcount` - Traces subchannel refcount changes. Includes per-call logs. - `subchannel_flowctrl` - Traces HTTP/2 flow control. Includes per-call logs. - `subchannel_internals` - Traces HTTP/2 session state. Includes per-call logs. + - `channel_stacktrace` - Traces channel construction events with stack traces. The following tracers are added by the `@grpc/grpc-js-xds` library: - `cds_balancer` - Traces the CDS load balancing policy diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 9d73c5df8..d1c9bd028 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -335,6 +335,8 @@ export class ChannelImplementation implements Channel { new CompressionFilterFactory(this, this.options), ]); this.trace('Channel constructed with options ' + JSON.stringify(options, undefined, 2)); + const error = new Error(); + trace(LogVerbosity.DEBUG, 'channel_stacktrace', '(' + this.channelzRef.id + ') ' + 'Channel constructed \n' + error.stack?.substring(error.stack.indexOf('\n')+1)); } private getChannelzInfo(): ChannelInfo { From 39f027e284c9c23591fad25eb2f4d6b80ab26e2e Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 16 Mar 2022 11:34:33 -0700 Subject: [PATCH 204/450] grpc-js: Trace call end when actually ending the call --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/call-stream.ts | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index f617223bc..c15678c83 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.5.8", + "version": "1.5.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", diff --git a/packages/grpc-js/src/call-stream.ts b/packages/grpc-js/src/call-stream.ts index 601218886..4eff39eb8 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -312,6 +312,13 @@ export class Http2CallStream implements Call { const filteredStatus = this.filterStack.receiveTrailers( this.finalStatus! ); + this.trace( + 'ended with status: code=' + + filteredStatus.code + + ' details="' + + filteredStatus.details + + '"' + ); this.statusWatchers.forEach(watcher => watcher(filteredStatus)); /* We delay the actual action of bubbling up the status to insulate the * cleanup code in this class from any errors that may be thrown in the @@ -346,13 +353,6 @@ export class Http2CallStream implements Call { /* If the status is OK and a new status comes in (e.g. from a * deserialization failure), that new status takes priority */ if (this.finalStatus === null || this.finalStatus.code === Status.OK) { - this.trace( - 'ended with status: code=' + - status.code + - ' details="' + - status.details + - '"' - ); this.finalStatus = status; this.maybeOutputStatus(); } From 81e08e84df4cfda5e5479f8455a86bd3d27964e7 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 16 Mar 2022 12:39:36 -0700 Subject: [PATCH 205/450] grpc-js: Transparently retry session destroyed error --- packages/grpc-js/src/channel.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 9d73c5df8..8ca11dd58 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -466,9 +466,9 @@ export class ChannelImplementation implements Channel { callConfig.onCommitted?.(); pickResult.onCallStarted?.(); } catch (error) { - if ( - (error as NodeJS.ErrnoException).code === - 'ERR_HTTP2_GOAWAY_SESSION' + const errorCode = (error as NodeJS.ErrnoException).code; + if (errorCode === 'ERR_HTTP2_GOAWAY_SESSION' || + errorCode === 'ERR_HTTP2_INVALID_SESSION' ) { /* An error here indicates that something went wrong with * the picked subchannel's http2 stream right before we From b5b0703bcd7006eef554f977070827e881863d08 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 18 Mar 2022 12:40:30 -0700 Subject: [PATCH 206/450] grpc-js-xds: Add outlier detection configuration handling --- packages/grpc-js-xds/src/environment.ts | 3 +- packages/grpc-js-xds/src/load-balancer-cds.ts | 62 ++++++++++++++++++- packages/grpc-js-xds/src/load-balancer-eds.ts | 34 ++++++++-- .../src/xds-stream-state/cds-state.ts | 48 ++++++++++++++ packages/grpc-js/src/experimental.ts | 5 +- .../src/load-balancer-outlier-detection.ts | 49 ++++++++++----- 6 files changed, 177 insertions(+), 24 deletions(-) diff --git a/packages/grpc-js-xds/src/environment.ts b/packages/grpc-js-xds/src/environment.ts index e1c2d8158..b8b518da4 100644 --- a/packages/grpc-js-xds/src/environment.ts +++ b/packages/grpc-js-xds/src/environment.ts @@ -15,4 +15,5 @@ * */ -export const EXPERIMENTAL_FAULT_INJECTION = (process.env.GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION ?? 'true') === 'true'; \ No newline at end of file +export const EXPERIMENTAL_FAULT_INJECTION = (process.env.GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION ?? 'true') === 'true'; +export const EXPERIMENTAL_OUTLIER_DETECTION = process.env.GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION === 'true'; \ No newline at end of file diff --git a/packages/grpc-js-xds/src/load-balancer-cds.ts b/packages/grpc-js-xds/src/load-balancer-cds.ts index 4829edd44..a6dbf42f0 100644 --- a/packages/grpc-js-xds/src/load-balancer-cds.ts +++ b/packages/grpc-js-xds/src/load-balancer-cds.ts @@ -25,8 +25,14 @@ import LoadBalancer = experimental.LoadBalancer; import ChannelControlHelper = experimental.ChannelControlHelper; import registerLoadBalancerType = experimental.registerLoadBalancerType; import LoadBalancingConfig = experimental.LoadBalancingConfig; +import OutlierDetectionLoadBalancingConfig = experimental.OutlierDetectionLoadBalancingConfig; +import SuccessRateEjectionConfig = experimental.SuccessRateEjectionConfig; +import FailurePercentageEjectionConfig = experimental.FailurePercentageEjectionConfig; import { EdsLoadBalancingConfig } from './load-balancer-eds'; import { Watcher } from './xds-stream-state/xds-stream-state'; +import { OutlierDetection__Output } from './generated/envoy/config/cluster/v3/OutlierDetection'; +import { Duration__Output } from './generated/google/protobuf/Duration'; +import { EXPERIMENTAL_OUTLIER_DETECTION } from './environment'; const TRACER_NAME = 'cds_balancer'; @@ -64,6 +70,52 @@ export class CdsLoadBalancingConfig implements LoadBalancingConfig { } } +function durationToMs(duration: Duration__Output): number { + return (Number(duration.seconds) * 1_000 + duration.nanos / 1_000_000) | 0; +} + +function translateOutlierDetectionConfig(outlierDetection: OutlierDetection__Output | null): OutlierDetectionLoadBalancingConfig | undefined { + if (!EXPERIMENTAL_OUTLIER_DETECTION) { + return undefined; + } + if (!outlierDetection) { + /* No-op outlier detection config, with max possible interval and no + * ejection criteria configured. */ + return new OutlierDetectionLoadBalancingConfig(~(1<<31), null, null, null, null, null, []); + } + let successRateConfig: Partial | null = null; + /* Success rate ejection is enabled by default, so we only disable it if + * enforcing_success_rate is set and it has the value 0 */ + if (!outlierDetection.enforcing_success_rate || outlierDetection.enforcing_success_rate.value > 0) { + successRateConfig = { + enforcement_percentage: outlierDetection.enforcing_success_rate?.value, + minimum_hosts: outlierDetection.success_rate_minimum_hosts?.value, + request_volume: outlierDetection.success_rate_request_volume?.value, + stdev_factor: outlierDetection.success_rate_stdev_factor?.value + }; + } + let failurePercentageConfig: Partial | null = null; + /* Failure percentage ejection is disabled by default, so we only enable it + * if enforcing_failure_percentage is set and it has a value greater than 0 */ + if (outlierDetection.enforcing_failure_percentage && outlierDetection.enforcing_failure_percentage.value > 0) { + failurePercentageConfig = { + enforcement_percentage: outlierDetection.enforcing_failure_percentage.value, + minimum_hosts: outlierDetection.failure_percentage_minimum_hosts?.value, + request_volume: outlierDetection.failure_percentage_request_volume?.value, + threshold: outlierDetection.failure_percentage_threshold?.value + } + } + return new OutlierDetectionLoadBalancingConfig( + outlierDetection.interval ? durationToMs(outlierDetection.interval) : null, + outlierDetection.base_ejection_time ? durationToMs(outlierDetection.base_ejection_time) : null, + outlierDetection.max_ejection_time ? durationToMs(outlierDetection.max_ejection_time) : null, + outlierDetection.max_ejection_percent?.value ?? null, + successRateConfig, + failurePercentageConfig, + [] + ); +} + export class CdsLoadBalancer implements LoadBalancer { private childBalancer: ChildLoadBalancerHandler; private watcher: Watcher; @@ -90,7 +142,15 @@ export class CdsLoadBalancer implements LoadBalancer { * used for load reporting as for other xDS operations. Setting * lrsLoadReportingServerName to the empty string sets that behavior. * Otherwise, if the field is omitted, load reporting is disabled. */ - const edsConfig: EdsLoadBalancingConfig = new EdsLoadBalancingConfig(update.name, [], [], update.eds_cluster_config!.service_name === '' ? undefined : update.eds_cluster_config!.service_name, update.lrs_server?.self ? '' : undefined, maxConcurrentRequests); + const edsConfig: EdsLoadBalancingConfig = new EdsLoadBalancingConfig( + /* cluster= */ update.name, + /* localityPickingPolicy= */ [], + /* endpointPickingPolicy= */ [], + /* edsServiceName= */ update.eds_cluster_config!.service_name === '' ? undefined : update.eds_cluster_config!.service_name, + /* lrsLoadReportingServerName= */update.lrs_server?.self ? '' : undefined, + /* maxConcurrentRequests= */ maxConcurrentRequests, + /* outlierDetection= */ translateOutlierDetectionConfig(update.outlier_detection) + ); trace('Child update EDS config: ' + JSON.stringify(edsConfig)); this.childBalancer.updateAddressList( [], diff --git a/packages/grpc-js-xds/src/load-balancer-eds.ts b/packages/grpc-js-xds/src/load-balancer-eds.ts index 55ad714a9..e7aac0571 100644 --- a/packages/grpc-js-xds/src/load-balancer-eds.ts +++ b/packages/grpc-js-xds/src/load-balancer-eds.ts @@ -38,6 +38,8 @@ import Filter = experimental.Filter; import BaseFilter = experimental.BaseFilter; import FilterFactory = experimental.FilterFactory; import CallStream = experimental.CallStream; +import OutlierDetectionLoadBalancingConfig = experimental.OutlierDetectionLoadBalancingConfig; +import { EXPERIMENTAL_OUTLIER_DETECTION } from './environment'; const TRACER_NAME = 'eds_balancer'; @@ -71,12 +73,15 @@ export class EdsLoadBalancingConfig implements LoadBalancingConfig { if (this.lrsLoadReportingServerName !== undefined) { jsonObj.lrs_load_reporting_server_name = this.lrsLoadReportingServerName; } + if (this.outlierDetection !== undefined) { + jsonObj.outlier_detection = this.outlierDetection.toJsonObject(); + } return { [TYPE_NAME]: jsonObj }; } - constructor(private cluster: string, private localityPickingPolicy: LoadBalancingConfig[], private endpointPickingPolicy: LoadBalancingConfig[], private edsServiceName?: string, private lrsLoadReportingServerName?: string, maxConcurrentRequests?: number) { + constructor(private cluster: string, private localityPickingPolicy: LoadBalancingConfig[], private endpointPickingPolicy: LoadBalancingConfig[], private edsServiceName?: string, private lrsLoadReportingServerName?: string, maxConcurrentRequests?: number, private outlierDetection?: OutlierDetectionLoadBalancingConfig) { this.maxConcurrentRequests = maxConcurrentRequests ?? DEFAULT_MAX_CONCURRENT_REQUESTS; } @@ -104,6 +109,10 @@ export class EdsLoadBalancingConfig implements LoadBalancingConfig { return this.maxConcurrentRequests; } + getOutlierDetection() { + return this.outlierDetection; + } + static createFromJson(obj: any): EdsLoadBalancingConfig { if (!('cluster' in obj && typeof obj.cluster === 'string')) { throw new Error('eds config must have a string field cluster'); @@ -123,7 +132,17 @@ export class EdsLoadBalancingConfig implements LoadBalancingConfig { if ('max_concurrent_requests' in obj && (!obj.max_concurrent_requests === undefined || typeof obj.max_concurrent_requests === 'number')) { throw new Error('eds config max_concurrent_requests must be a number if provided'); } - return new EdsLoadBalancingConfig(obj.cluster, obj.locality_picking_policy.map(validateLoadBalancingConfig), obj.endpoint_picking_policy.map(validateLoadBalancingConfig), obj.eds_service_name, obj.lrs_load_reporting_server_name, obj.max_concurrent_requests); + let validatedOutlierDetectionConfig: OutlierDetectionLoadBalancingConfig | undefined = undefined; + if (EXPERIMENTAL_OUTLIER_DETECTION) { + if ('outlier_detection' in obj) { + const outlierDetectionConfig = validateLoadBalancingConfig(obj.outlier_detection); + if (!(outlierDetectionConfig instanceof OutlierDetectionLoadBalancingConfig)) { + throw new Error('eds config outlier_detection must be a valid outlier detection config if provided'); + } + validatedOutlierDetectionConfig = outlierDetectionConfig; + } + } + return new EdsLoadBalancingConfig(obj.cluster, obj.locality_picking_policy.map(validateLoadBalancingConfig), obj.endpoint_picking_policy.map(validateLoadBalancingConfig), obj.eds_service_name, obj.lrs_load_reporting_server_name, obj.max_concurrent_requests, validatedOutlierDetectionConfig); } } @@ -449,10 +468,15 @@ export class EdsLoadBalancer implements LoadBalancer { } } + const weightedTargetConfig = new WeightedTargetLoadBalancingConfig(childTargets); + let outlierDetectionConfig: OutlierDetectionLoadBalancingConfig | undefined; + if (EXPERIMENTAL_OUTLIER_DETECTION) { + outlierDetectionConfig = this.lastestConfig.getOutlierDetection()?.copyWithChildPolicy([weightedTargetConfig]); + } + const priorityChildConfig = outlierDetectionConfig ?? weightedTargetConfig; + priorityChildren.set(newPriorityName, { - config: [ - new WeightedTargetLoadBalancingConfig(childTargets), - ], + config: [priorityChildConfig], }); } /* Contract the priority names array if it is sparse. This config only diff --git a/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts index 7737dc961..8c3c4d739 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts @@ -16,8 +16,11 @@ */ import { experimental, logVerbosity, StatusObject } from "@grpc/grpc-js"; +import { EXPERIMENTAL_OUTLIER_DETECTION } from "../environment"; import { Cluster__Output } from "../generated/envoy/config/cluster/v3/Cluster"; import { Any__Output } from "../generated/google/protobuf/Any"; +import { Duration__Output } from "../generated/google/protobuf/Duration"; +import { UInt32Value__Output } from "../generated/google/protobuf/UInt32Value"; import { EdsState } from "./eds-state"; import { HandleResponseResult, RejectedResourceEntry, ResourcePair, Watcher, XdsStreamState } from "./xds-stream-state"; @@ -102,6 +105,26 @@ export class CdsState implements XdsStreamState { return Array.from(this.watchers.keys()); } + private validateNonnegativeDuration(duration: Duration__Output | null): boolean { + if (!duration) { + return true; + } + /* The maximum values here come from the official Protobuf documentation: + * https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Duration + */ + return Number(duration.seconds) >= 0 && + Number(duration.seconds) <= 315_576_000_000 && + duration.nanos >= 0 && + duration.nanos <= 999_999_999; + } + + private validatePercentage(percentage: UInt32Value__Output | null): boolean { + if (!percentage) { + return true; + } + return percentage.value >=0 && percentage.value <= 100; + } + private validateResponse(message: Cluster__Output): boolean { if (message.type !== 'EDS') { return false; @@ -117,6 +140,31 @@ export class CdsState implements XdsStreamState { return false; } } + if (EXPERIMENTAL_OUTLIER_DETECTION) { + if (message.outlier_detection) { + if (!this.validateNonnegativeDuration(message.outlier_detection.interval)) { + return false; + } + if (!this.validateNonnegativeDuration(message.outlier_detection.base_ejection_time)) { + return false; + } + if (!this.validateNonnegativeDuration(message.outlier_detection.max_ejection_time)) { + return false; + } + if (!this.validatePercentage(message.outlier_detection.max_ejection_percent)) { + return false; + } + if (!this.validatePercentage(message.outlier_detection.enforcing_success_rate)) { + return false; + } + if (!this.validatePercentage(message.outlier_detection.failure_percentage_threshold)) { + return false; + } + if (!this.validatePercentage(message.outlier_detection.enforcing_failure_percentage)) { + return false; + } + } + } return true; } diff --git a/packages/grpc-js/src/experimental.ts b/packages/grpc-js/src/experimental.ts index a9d76406b..fcafbeb01 100644 --- a/packages/grpc-js/src/experimental.ts +++ b/packages/grpc-js/src/experimental.ts @@ -6,7 +6,7 @@ export { ConfigSelector, } from './resolver'; export { GrpcUri, uriToString } from './uri-parser'; -export { Duration } from './duration'; +export { Duration, durationToMs } from './duration'; export { ServiceConfig } from './service-config'; export { BackoffTimeout } from './backoff-timeout'; export { @@ -35,4 +35,5 @@ export { Call as CallStream } from './call-stream'; export { Filter, BaseFilter, FilterFactory } from './filter'; export { FilterStackFactory } from './filter-stack'; export { registerAdminService } from './admin'; -export { SubchannelInterface, BaseSubchannelWrapper, ConnectivityStateListener } from './subchannel-interface' +export { SubchannelInterface, BaseSubchannelWrapper, ConnectivityStateListener } from './subchannel-interface'; +export { OutlierDetectionLoadBalancingConfig, SuccessRateEjectionConfig, FailurePercentageEjectionConfig } from './load-balancer-outlier-detection'; diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index ffca1c68e..e69e2ef99 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -34,14 +34,14 @@ const TYPE_NAME = 'outlier_detection'; const OUTLIER_DETECTION_ENABLED = process.env.GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION === 'true'; -interface SuccessRateEjectionConfig { +export interface SuccessRateEjectionConfig { readonly stdev_factor: number; readonly enforcement_percentage: number; readonly minimum_hosts: number; readonly request_volume: number; } -interface FailurePercentageEjectionConfig { +export interface FailurePercentageEjectionConfig { readonly threshold: number; readonly enforcement_percentage: number; readonly minimum_hosts: number; @@ -92,15 +92,29 @@ function validatePercentage(obj: any, fieldName: string, objectName?: string) { } export class OutlierDetectionLoadBalancingConfig implements LoadBalancingConfig { + private readonly intervalMs: number; + private readonly baseEjectionTimeMs: number; + private readonly maxEjectionTimeMs: number; + private readonly maxEjectionPercent: number; + private readonly successRateEjection: SuccessRateEjectionConfig | null; + private readonly failurePercentageEjection: FailurePercentageEjectionConfig | null; + constructor( - private readonly intervalMs: number, - private readonly baseEjectionTimeMs: number, - private readonly maxEjectionTimeMs: number, - private readonly maxEjectionPercent: number, - private readonly successRateEjection: SuccessRateEjectionConfig | null, - private readonly failurePercentageEjection: FailurePercentageEjectionConfig | null, + intervalMs: number | null, + baseEjectionTimeMs: number | null, + maxEjectionTimeMs: number | null, + maxEjectionPercent: number | null, + successRateEjection: Partial | null, + failurePercentageEjection: Partial | null, private readonly childPolicy: LoadBalancingConfig[] - ) {} + ) { + this.intervalMs = intervalMs ?? 10_000; + this.baseEjectionTimeMs = baseEjectionTimeMs ?? 30_000; + this.maxEjectionTimeMs = maxEjectionTimeMs ?? 300_000; + this.maxEjectionPercent = maxEjectionPercent ?? 10; + this.successRateEjection = successRateEjection ? {...defaultSuccessRateEjectionConfig, ...successRateEjection} : null; + this.failurePercentageEjection = failurePercentageEjection ? {...defaultFailurePercentageEjectionConfig, ...failurePercentageEjection}: null; + } getLoadBalancerName(): string { return TYPE_NAME; } @@ -137,6 +151,11 @@ export class OutlierDetectionLoadBalancingConfig implements LoadBalancingConfig getChildPolicy(): LoadBalancingConfig[] { return this.childPolicy; } + + copyWithChildPolicy(childPolicy: LoadBalancingConfig[]): OutlierDetectionLoadBalancingConfig { + return new OutlierDetectionLoadBalancingConfig(this.intervalMs, this.baseEjectionTimeMs, this.maxEjectionTimeMs, this.maxEjectionPercent, this.successRateEjection, this.failurePercentageEjection, childPolicy); + } + static createFromJson(obj: any): OutlierDetectionLoadBalancingConfig { validatePositiveDuration(obj, 'interval'); validatePositiveDuration(obj, 'base_ejection_time'); @@ -162,12 +181,12 @@ export class OutlierDetectionLoadBalancingConfig implements LoadBalancingConfig } return new OutlierDetectionLoadBalancingConfig( - obj.interval ? durationToMs(obj.interval) : 10_000, - obj.base_ejection_time ? durationToMs(obj.base_ejection_time) : 30_000, - obj.max_ejection_time ? durationToMs(obj.max_ejection_time) : 300_000, - obj.max_ejection_percent ?? 10, - obj.success_rate_ejection ? {...defaultSuccessRateEjectionConfig, ...obj.success_rate_ejection} : null, - obj.failure_percentage_ejection ? {...defaultFailurePercentageEjectionConfig, ...obj.failure_percentage_ejection} : null, + obj.interval ? durationToMs(obj.interval) : null, + obj.base_ejection_time ? durationToMs(obj.base_ejection_time) : null, + obj.max_ejection_time ? durationToMs(obj.max_ejection_time) : null, + obj.max_ejection_percent ?? null, + obj.success_rate_ejection, + obj.failure_percentage_ejection, obj.child_policy.map(validateLoadBalancingConfig) ); } From 680ff7cc08e12d2bdf57687079fa06ceeafe80c4 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 24 Mar 2022 12:45:28 -0700 Subject: [PATCH 207/450] grpc-js: Improve coverage of channelzEnabled checks in server code --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/server.ts | 147 +++++++++++++++++++++------------ 2 files changed, 95 insertions(+), 54 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index c15678c83..50896e963 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.5.9", + "version": "1.5.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", diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 9c28a276f..85f492ff3 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -430,27 +430,36 @@ export class Server { port: boundAddress.port } } - const channelzRef = registerChannelzSocket(subchannelAddressToString(boundSubchannelAddress), () => { - return { - localAddress: boundSubchannelAddress, - remoteAddress: null, - security: null, - remoteName: null, - streamsStarted: 0, - streamsSucceeded: 0, - streamsFailed: 0, - messagesSent: 0, - messagesReceived: 0, - keepAlivesSent: 0, - lastLocalStreamCreatedTimestamp: null, - lastRemoteStreamCreatedTimestamp: null, - lastMessageSentTimestamp: null, - lastMessageReceivedTimestamp: null, - localFlowControlWindow: null, - remoteFlowControlWindow: null + let channelzRef: SocketRef; + if (this.channelzEnabled) { + channelzRef = registerChannelzSocket(subchannelAddressToString(boundSubchannelAddress), () => { + return { + localAddress: boundSubchannelAddress, + remoteAddress: null, + security: null, + remoteName: null, + streamsStarted: 0, + streamsSucceeded: 0, + streamsFailed: 0, + messagesSent: 0, + messagesReceived: 0, + keepAlivesSent: 0, + lastLocalStreamCreatedTimestamp: null, + lastRemoteStreamCreatedTimestamp: null, + lastMessageSentTimestamp: null, + lastMessageReceivedTimestamp: null, + localFlowControlWindow: null, + remoteFlowControlWindow: null + }; + }); + this.listenerChildrenTracker.refChild(channelzRef); + } else { + channelzRef = { + kind: 'socket', + id: -1, + name: '' }; - }); - this.listenerChildrenTracker.refChild(channelzRef); + } this.http2ServerList.push({server: http2Server, channelzRef: channelzRef}); this.trace('Successfully bound ' + subchannelAddressToString(boundSubchannelAddress)); resolve('port' in boundSubchannelAddress ? boundSubchannelAddress.port : portNum); @@ -499,27 +508,36 @@ export class Server { host: boundAddress.address, port: boundAddress.port }; - const channelzRef = registerChannelzSocket(subchannelAddressToString(boundSubchannelAddress), () => { - return { - localAddress: boundSubchannelAddress, - remoteAddress: null, - security: null, - remoteName: null, - streamsStarted: 0, - streamsSucceeded: 0, - streamsFailed: 0, - messagesSent: 0, - messagesReceived: 0, - keepAlivesSent: 0, - lastLocalStreamCreatedTimestamp: null, - lastRemoteStreamCreatedTimestamp: null, - lastMessageSentTimestamp: null, - lastMessageReceivedTimestamp: null, - localFlowControlWindow: null, - remoteFlowControlWindow: null + let channelzRef: SocketRef; + if (this.channelzEnabled) { + channelzRef = registerChannelzSocket(subchannelAddressToString(boundSubchannelAddress), () => { + return { + localAddress: boundSubchannelAddress, + remoteAddress: null, + security: null, + remoteName: null, + streamsStarted: 0, + streamsSucceeded: 0, + streamsFailed: 0, + messagesSent: 0, + messagesReceived: 0, + keepAlivesSent: 0, + lastLocalStreamCreatedTimestamp: null, + lastRemoteStreamCreatedTimestamp: null, + lastMessageSentTimestamp: null, + lastMessageReceivedTimestamp: null, + localFlowControlWindow: null, + remoteFlowControlWindow: null + }; + }); + this.listenerChildrenTracker.refChild(channelzRef); + } else { + channelzRef = { + kind: 'socket', + id: -1, + name: '' }; - }); - this.listenerChildrenTracker.refChild(channelzRef); + } this.http2ServerList.push({server: http2Server, channelzRef: channelzRef}); this.trace('Successfully bound ' + subchannelAddressToString(boundSubchannelAddress)); resolve( @@ -599,8 +617,10 @@ export class Server { for (const {server: http2Server, channelzRef: ref} of this.http2ServerList) { if (http2Server.listening) { http2Server.close(() => { - this.listenerChildrenTracker.unrefChild(ref); - unregisterChannelzRef(ref); + if (this.channelzEnabled) { + this.listenerChildrenTracker.unrefChild(ref); + unregisterChannelzRef(ref); + } }); } } @@ -616,7 +636,9 @@ export class Server { session.destroy(http2.constants.NGHTTP2_CANCEL as any); }); this.sessions.clear(); - unregisterChannelzRef(this.channelzRef); + if (this.channelzEnabled) { + unregisterChannelzRef(this.channelzRef); + } } register( @@ -665,7 +687,9 @@ export class Server { tryShutdown(callback: (error?: Error) => void): void { const wrappedCallback = (error?: Error) => { - unregisterChannelzRef(this.channelzRef); + if (this.channelzEnabled) { + unregisterChannelzRef(this.channelzRef); + } callback(error); }; let pendingChecks = 0; @@ -685,8 +709,10 @@ export class Server { if (http2Server.listening) { pendingChecks++; http2Server.close(() => { - this.listenerChildrenTracker.unrefChild(ref); - unregisterChannelzRef(ref); + if (this.channelzEnabled) { + this.listenerChildrenTracker.unrefChild(ref); + unregisterChannelzRef(ref); + } maybeCallback(); }); } @@ -727,8 +753,10 @@ export class Server { 'stream', (stream: http2.ServerHttp2Stream, headers: http2.IncomingHttpHeaders) => { const channelzSessionInfo = this.sessions.get(stream.session as http2.ServerHttp2Session); - this.callTracker.addCallStarted(); - channelzSessionInfo?.streamTracker.addCallStarted(); + if (this.channelzEnabled) { + this.callTracker.addCallStarted(); + channelzSessionInfo?.streamTracker.addCallStarted(); + } const contentType = headers[http2.constants.HTTP2_HEADER_CONTENT_TYPE]; if ( @@ -743,7 +771,9 @@ export class Server { { endStream: true } ); this.callTracker.addCallFailed(); - channelzSessionInfo?.streamTracker.addCallFailed(); + if (this.channelzEnabled) { + channelzSessionInfo?.streamTracker.addCallFailed(); + } return; } @@ -786,7 +816,7 @@ export class Server { this.callTracker.addCallFailed(); } }); - if (channelzSessionInfo) { + if (this.channelzEnabled && channelzSessionInfo) { call.once('streamEnd', (success: boolean) => { if (success) { channelzSessionInfo.streamTracker.addCallSucceeded(); @@ -841,8 +871,10 @@ export class Server { } catch (err) { if (!call) { call = new Http2ServerCallStream(stream, null!, this.options); - this.callTracker.addCallFailed(); - channelzSessionInfo?.streamTracker.addCallFailed() + if (this.channelzEnabled) { + this.callTracker.addCallFailed(); + channelzSessionInfo?.streamTracker.addCallFailed() + } } if (err.code === undefined) { @@ -860,7 +892,16 @@ export class Server { return; } - const channelzRef = registerChannelzSocket(session.socket.remoteAddress ?? 'unknown', this.getChannelzSessionInfoGetter(session)); + let channelzRef: SocketRef; + if (this.channelzEnabled) { + channelzRef = registerChannelzSocket(session.socket.remoteAddress ?? 'unknown', this.getChannelzSessionInfoGetter(session)); + } else { + channelzRef = { + kind: 'socket', + id: -1, + name: '' + } + } const channelzSessionInfo: ChannelzSessionInfo = { ref: channelzRef, From 260aee93dac27bad97172fe38ce2f61ce5886af4 Mon Sep 17 00:00:00 2001 From: Kamil Skalski Date: Fri, 25 Mar 2022 09:22:23 -0500 Subject: [PATCH 208/450] Expose MetadataOptions interface in grpc-js. --- packages/grpc-js/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index ed452547e..2e6fcb5bf 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -48,7 +48,7 @@ import { ServiceClientConstructor, ServiceDefinition, } from './make-client'; -import { Metadata, MetadataValue } from './metadata'; +import { Metadata, MetadataOptions, MetadataValue } from './metadata'; import { Server, UntypedHandleCall, From 8d7d3f3d23e3690b732fb4f8ab3e7666ac72be41 Mon Sep 17 00:00:00 2001 From: Kamil Skalski Date: Fri, 25 Mar 2022 09:22:23 -0500 Subject: [PATCH 209/450] Expose MetadataOptions interface in grpc-js. --- packages/grpc-js/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index 2e6fcb5bf..b4855fb59 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -119,7 +119,7 @@ export const credentials = { /**** Metadata ****/ -export { Metadata, MetadataValue }; +export { Metadata, MetadataOptions, MetadataValue }; /**** Constants ****/ From 052af317a3cbd0b8888502c2f232ef76f0af1873 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 28 Mar 2022 14:06:04 -0700 Subject: [PATCH 210/450] grpc-js: Avoid surfacing errors without gRPC error codes --- packages/grpc-js/src/call-stream.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/src/call-stream.ts b/packages/grpc-js/src/call-stream.ts index 4eff39eb8..e8f312752 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -839,7 +839,16 @@ export class Http2CallStream implements Call { message, flags: context.flags, }; - const cb: WriteCallback = context.callback ?? (() => {}); + const cb: WriteCallback = (error?: Error | null) => { + let code: Status = Status.UNAVAILABLE; + if ((error as NodeJS.ErrnoException)?.code === 'ERR_STREAM_WRITE_AFTER_END') { + code = Status.INTERNAL; + } + if (error) { + this.cancelWithStatus(code, `Write error: ${error.message}`); + } + context.callback?.(); + }; this.isWriteFilterPending = true; this.filterStack.sendMessage(Promise.resolve(writeObj)).then((message) => { this.isWriteFilterPending = false; From 9fcf1659b6f2b36bedb0e337e57d8820be3e835a Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 29 Mar 2022 00:15:49 -0700 Subject: [PATCH 211/450] Update version to 1.6.0 --- packages/grpc-js-xds/README.md | 3 ++- packages/grpc-js-xds/package.json | 4 ++-- packages/grpc-js/package.json | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js-xds/README.md b/packages/grpc-js-xds/README.md index 1ac235c40..20bd924a8 100644 --- a/packages/grpc-js-xds/README.md +++ b/packages/grpc-js-xds/README.md @@ -27,4 +27,5 @@ const client = new MyServiceClient('xds:///example.com:123'); - [xDS Timeouts](https://github.com/grpc/proposal/blob/master/A31-xds-timeout-support-and-config-selector.md) - [xDS Circuit Breaking](https://github.com/grpc/proposal/blob/master/A32-xds-circuit-breaking.md) - [xDS Client-Side Fault Injection](https://github.com/grpc/proposal/blob/master/A33-Fault-Injection.md) - - [Client Status Discovery Service](https://github.com/grpc/proposal/blob/master/A40-csds-support.md) \ No newline at end of file + - [Client Status Discovery Service](https://github.com/grpc/proposal/blob/master/A40-csds-support.md) + - [Outlier Detection](https://github.com/grpc/proposal/blob/master/A50-xds-outlier-detection.md) (experimental, disabled by default, enabled by setting the environment variable `GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION=true`) \ No newline at end of file diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index b4e0a49d7..c797f63f2 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.5.2", + "version": "1.6.0", "description": "Plugin for @grpc/grpc-js. Adds the xds:// URL scheme and associated features.", "main": "build/src/index.js", "scripts": { @@ -47,7 +47,7 @@ "re2-wasm": "^1.0.1" }, "peerDependencies": { - "@grpc/grpc-js": "~1.5.0" + "@grpc/grpc-js": "~1.6.0" }, "engines": { "node": ">=10.10.0" diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 50896e963..928260be6 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.5.10", + "version": "1.6.0", "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 e58371033f6cd086fcf9406526a4eb7f30ccc494 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 1 Apr 2022 10:46:39 -0700 Subject: [PATCH 212/450] grpc-js-xds: Don't stop backoff timers for ADS streams --- packages/grpc-js-xds/package.json | 2 +- packages/grpc-js-xds/src/xds-client.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index c797f63f2..9062403cd 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.6.0", + "version": "1.6.1", "description": "Plugin for @grpc/grpc-js. Adds the xds:// URL scheme and associated features.", "main": "build/src/index.js", "scripts": { diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index 75a567a54..7a12af1f6 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -688,7 +688,6 @@ export class XdsClient { ack(serviceKind: AdsServiceKind) { /* An ack is the best indication of a successful interaction between the * client and the server, so we can reset the backoff timer here. */ - this.adsBackoff.stop(); this.adsBackoff.reset(); this.updateNames(serviceKind); From 8a503031f3db9d83f45a887b78db15d14fd275c2 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 1 Apr 2022 10:01:47 -0700 Subject: [PATCH 213/450] grpc-js: Add support for grpc.dns_min_time_between_resolutions_ms channel arg --- packages/grpc-js/README.md | 1 + packages/grpc-js/package.json | 2 +- packages/grpc-js/src/channel-options.ts | 2 ++ packages/grpc-js/src/resolver-dns.ts | 45 +++++++++++++++++++++---- 4 files changed, 43 insertions(+), 7 deletions(-) diff --git a/packages/grpc-js/README.md b/packages/grpc-js/README.md index 71ec937ed..11a8ca9aa 100644 --- a/packages/grpc-js/README.md +++ b/packages/grpc-js/README.md @@ -58,6 +58,7 @@ Many channel arguments supported in `grpc` are not supported in `@grpc/grpc-js`. - `grpc.enable_http_proxy` - `grpc.default_compression_algorithm` - `grpc.enable_channelz` + - `grpc.dns_min_time_between_resolutions_ms` - `grpc-node.max_session_memory` - `channelOverride` - `channelFactoryOverride` diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 928260be6..ecc3e30cd 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.6.0", + "version": "1.6.1", "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/channel-options.ts b/packages/grpc-js/src/channel-options.ts index 688317227..b7fc92fa9 100644 --- a/packages/grpc-js/src/channel-options.ts +++ b/packages/grpc-js/src/channel-options.ts @@ -43,6 +43,7 @@ export interface ChannelOptions { 'grpc.http_connect_creds'?: string; 'grpc.default_compression_algorithm'?: CompressionAlgorithms; 'grpc.enable_channelz'?: number; + 'grpc.dns_min_time_between_resolutions_ms'?: number; 'grpc-node.max_session_memory'?: number; // eslint-disable-next-line @typescript-eslint/no-explicit-any [key: string]: any; @@ -69,6 +70,7 @@ export const recognizedOptions = { 'grpc.max_receive_message_length': true, 'grpc.enable_http_proxy': true, 'grpc.enable_channelz': true, + 'grpc.dns_min_time_between_resolutions_ms': true, 'grpc-node.max_session_memory': true, }; diff --git a/packages/grpc-js/src/resolver-dns.ts b/packages/grpc-js/src/resolver-dns.ts index 8ad24ed05..c4cb64a74 100644 --- a/packages/grpc-js/src/resolver-dns.ts +++ b/packages/grpc-js/src/resolver-dns.ts @@ -45,6 +45,8 @@ function trace(text: string): void { */ const DEFAULT_PORT = 443; +const DEFAULT_MIN_TIME_BETWEEN_RESOLUTIONS_MS = 30_000; + const resolveTxtPromise = util.promisify(dns.resolveTxt); const dnsLookupPromise = util.promisify(dns.lookup); @@ -79,6 +81,12 @@ class DnsResolver implements Resolver { private readonly ipResult: SubchannelAddress[] | null; private readonly dnsHostname: string | null; private readonly port: number | null; + /** + * Minimum time between resolutions, measured as the time between starting + * successive resolution requests. Only applies to successful resolutions. + * Failures are handled by the backoff timer. + */ + private readonly minTimeBetweenResolutionsMs: number; private pendingLookupPromise: Promise | null = null; private pendingTxtPromise: Promise | null = null; private latestLookupResult: TcpSubchannelAddress[] | null = null; @@ -88,6 +96,8 @@ class DnsResolver implements Resolver { private defaultResolutionError: StatusObject; private backoff: BackoffTimeout; private continueResolving = false; + private nextResolutionTimer: NodeJS.Timer; + private isNextResolutionTimerRunning = false; constructor( private target: GrpcUri, private listener: ResolverListener, @@ -134,6 +144,10 @@ class DnsResolver implements Resolver { } }, backoffOptions); this.backoff.unref(); + + this.minTimeBetweenResolutionsMs = channelOptions['grpc.dns_min_time_between_resolutions_ms'] ?? DEFAULT_MIN_TIME_BETWEEN_RESOLUTIONS_MS; + this.nextResolutionTimer = setTimeout(() => {}, 0); + clearTimeout(this.nextResolutionTimer); } /** @@ -183,6 +197,7 @@ class DnsResolver implements Resolver { (addressList) => { this.pendingLookupPromise = null; this.backoff.reset(); + this.backoff.stop(); const ip4Addresses: dns.LookupAddress[] = addressList.filter( (addr) => addr.family === 4 ); @@ -229,6 +244,7 @@ class DnsResolver implements Resolver { (err as Error).message ); this.pendingLookupPromise = null; + this.stopNextResolutionTimer(); this.listener.onError(this.defaultResolutionError); } ); @@ -282,17 +298,34 @@ class DnsResolver implements Resolver { } } + private startNextResolutionTimer() { + this.nextResolutionTimer = setTimeout(() => { + this.stopNextResolutionTimer(); + if (this.continueResolving) { + this.startResolutionWithBackoff(); + } + }, this.minTimeBetweenResolutionsMs).unref?.(); + this.isNextResolutionTimerRunning = true; + } + + private stopNextResolutionTimer() { + clearTimeout(this.nextResolutionTimer); + this.isNextResolutionTimerRunning = false; + } + private startResolutionWithBackoff() { this.startResolution(); this.backoff.runOnce(); + this.startNextResolutionTimer(); } updateResolution() { /* If there is a pending lookup, just let it finish. Otherwise, if the - * backoff timer is running, do another lookup when it ends, and if not, - * do another lookup immeidately. */ + * nextResolutionTimer or backoff timer is running, set the + * continueResolving flag to resolve when whichever of those timers + * fires. Otherwise, start resolving immediately. */ if (this.pendingLookupPromise === null) { - if (this.backoff.isRunning()) { + if (this.isNextResolutionTimerRunning || this.backoff.isRunning()) { this.continueResolving = true; } else { this.startResolutionWithBackoff(); @@ -301,9 +334,9 @@ class DnsResolver implements Resolver { } destroy() { - /* Do nothing. There is not a practical way to cancel in-flight DNS - * requests, and after this function is called we can expect that - * updateResolution will not be called again. */ + this.continueResolving = false; + this.backoff.stop(); + this.stopNextResolutionTimer(); } /** From c106d05ac4cfa17746a2d9d6ee357a8056045d68 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 1 Apr 2022 14:31:24 -0700 Subject: [PATCH 214/450] grpc-js: Make backoff timer reset apply to the currently running timer --- packages/grpc-js/src/backoff-timeout.ts | 83 +++++++++++++++++++++---- 1 file changed, 72 insertions(+), 11 deletions(-) diff --git a/packages/grpc-js/src/backoff-timeout.ts b/packages/grpc-js/src/backoff-timeout.ts index 7f2ab5ebf..dc7be277a 100644 --- a/packages/grpc-js/src/backoff-timeout.ts +++ b/packages/grpc-js/src/backoff-timeout.ts @@ -37,14 +37,47 @@ export interface BackoffOptions { } export class BackoffTimeout { - private initialDelay: number = INITIAL_BACKOFF_MS; - private multiplier: number = BACKOFF_MULTIPLIER; - private maxDelay: number = MAX_BACKOFF_MS; - private jitter: number = BACKOFF_JITTER; + /** + * The delay time at the start, and after each reset. + */ + private readonly initialDelay: number = INITIAL_BACKOFF_MS; + /** + * The exponential backoff multiplier. + */ + private readonly multiplier: number = BACKOFF_MULTIPLIER; + /** + * The maximum delay time + */ + private readonly maxDelay: number = MAX_BACKOFF_MS; + /** + * The maximum fraction by which the delay time can randomly vary after + * applying the multiplier. + */ + private readonly jitter: number = BACKOFF_JITTER; + /** + * The delay time for the next time the timer runs. + */ private nextDelay: number; + /** + * The handle of the underlying timer. If running is false, this value refers + * to an object representing a timer that has ended, but it can still be + * interacted with without error. + */ private timerId: NodeJS.Timer; + /** + * Indicates whether the timer is currently running. + */ private running = false; + /** + * Indicates whether the timer should keep the Node process running if no + * other async operation is doing so. + */ private hasRef = true; + /** + * The time that the currently running timer was started. Only valid if + * running is true. + */ + private startTime: Date = new Date(); constructor(private callback: () => void, options?: BackoffOptions) { if (options) { @@ -66,18 +99,23 @@ export class BackoffTimeout { clearTimeout(this.timerId); } - /** - * Call the callback after the current amount of delay time - */ - runOnce() { - this.running = true; + private runTimer(delay: number) { this.timerId = setTimeout(() => { this.callback(); this.running = false; - }, this.nextDelay); + }, delay); if (!this.hasRef) { this.timerId.unref?.(); } + } + + /** + * Call the callback after the current amount of delay time + */ + runOnce() { + this.running = true; + this.startTime = new Date(); + this.runTimer(this.nextDelay); const nextBackoff = Math.min( this.nextDelay * this.multiplier, this.maxDelay @@ -97,21 +135,44 @@ export class BackoffTimeout { } /** - * Reset the delay time to its initial value. + * Reset the delay time to its initial value. If the timer is still running, + * retroactively apply that reset to the current timer. */ reset() { this.nextDelay = this.initialDelay; + if (this.running) { + const now = new Date(); + const newEndTime = this.startTime; + newEndTime.setMilliseconds(newEndTime.getMilliseconds() + this.nextDelay); + clearTimeout(this.timerId); + if (now < newEndTime) { + this.runTimer(newEndTime.getTime() - now.getTime()); + } else { + this.running = false; + } + } } + /** + * Check whether the timer is currently running. + */ isRunning() { return this.running; } + /** + * Set that while the timer is running, it should keep the Node process + * running. + */ ref() { this.hasRef = true; this.timerId.ref?.(); } + /** + * Set that while the timer is running, it should not keep the Node process + * running. + */ unref() { this.hasRef = false; this.timerId.unref?.(); From f19563d45ce955a343f018e0def877aa8e2b32c1 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 4 Apr 2022 09:37:13 -0700 Subject: [PATCH 215/450] grpc-js: Update to version 1.6.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 ecc3e30cd..bb8adff8f 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.6.1", + "version": "1.6.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 c80b25e2a52f383a7f6eaf2f09548069ab29623a Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 6 Apr 2022 17:15:22 -0700 Subject: [PATCH 216/450] grpc-js: Use real channelz IDs when channelz is disabled --- packages/grpc-js/src/channel.ts | 9 +-- packages/grpc-js/src/channelz.ts | 24 ++++--- packages/grpc-js/src/server.ts | 112 +++++++++++------------------ packages/grpc-js/src/subchannel.ts | 11 +-- 4 files changed, 62 insertions(+), 94 deletions(-) diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 635b52d6f..3d014607e 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -219,16 +219,9 @@ export class ChannelImplementation implements Channel { } this.channelzTrace = new ChannelzTrace(); + this.channelzRef = registerChannelzChannel(target, () => this.getChannelzInfo(), this.channelzEnabled); if (this.channelzEnabled) { - this.channelzRef = registerChannelzChannel(target, () => this.getChannelzInfo()); this.channelzTrace.addTrace('CT_INFO', 'Channel created'); - } else { - // Dummy channelz ref that will never be used - this.channelzRef = { - kind: 'channel', - id: -1, - name: '' - }; } if (this.options['grpc.default_authority']) { diff --git a/packages/grpc-js/src/channelz.ts b/packages/grpc-js/src/channelz.ts index 14c94fd0c..5a7a54760 100644 --- a/packages/grpc-js/src/channelz.ts +++ b/packages/grpc-js/src/channelz.ts @@ -347,31 +347,39 @@ const subchannels: (SubchannelEntry | undefined)[] = []; const servers: (ServerEntry | undefined)[] = []; const sockets: (SocketEntry | undefined)[] = []; -export function registerChannelzChannel(name: string, getInfo: () => ChannelInfo): ChannelRef { +export function registerChannelzChannel(name: string, getInfo: () => ChannelInfo, channelzEnabled: boolean): ChannelRef { const id = getNextId(); const ref: ChannelRef = {id, name, kind: 'channel'}; - channels[id] = { ref, getInfo }; + if (channelzEnabled) { + channels[id] = { ref, getInfo }; + } return ref; } -export function registerChannelzSubchannel(name: string, getInfo:() => SubchannelInfo): SubchannelRef { +export function registerChannelzSubchannel(name: string, getInfo:() => SubchannelInfo, channelzEnabled: boolean): SubchannelRef { const id = getNextId(); const ref: SubchannelRef = {id, name, kind: 'subchannel'}; - subchannels[id] = { ref, getInfo }; + if (channelzEnabled) { + subchannels[id] = { ref, getInfo }; + } return ref; } -export function registerChannelzServer(getInfo: () => ServerInfo): ServerRef { +export function registerChannelzServer(getInfo: () => ServerInfo, channelzEnabled: boolean): ServerRef { const id = getNextId(); const ref: ServerRef = {id, kind: 'server'}; - servers[id] = { ref, getInfo }; + if (channelzEnabled) { + servers[id] = { ref, getInfo }; + } return ref; } -export function registerChannelzSocket(name: string, getInfo: () => SocketInfo): SocketRef { +export function registerChannelzSocket(name: string, getInfo: () => SocketInfo, channelzEnabled: boolean): SocketRef { const id = getNextId(); const ref: SocketRef = {id, name, kind: 'socket'}; - sockets[id] = { ref, getInfo}; + if (channelzEnabled) { + sockets[id] = { ref, getInfo}; + } return ref; } diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 829941faa..974c3dfc6 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -161,17 +161,11 @@ export class Server { if (this.options['grpc.enable_channelz'] === 0) { this.channelzEnabled = false; } + this.channelzRef = registerChannelzServer(() => this.getChannelzInfo(), this.channelzEnabled); if (this.channelzEnabled) { - this.channelzRef = registerChannelzServer(() => this.getChannelzInfo()); this.channelzTrace.addTrace('CT_INFO', 'Server created'); - this.trace('Server constructed'); - } else { - // Dummy channelz ref that will never be used - this.channelzRef = { - kind: 'server', - id: -1 - }; } + this.trace('Server constructed'); } private getChannelzInfo(): ServerInfo { @@ -431,34 +425,28 @@ export class Server { } } let channelzRef: SocketRef; + channelzRef = registerChannelzSocket(subchannelAddressToString(boundSubchannelAddress), () => { + return { + localAddress: boundSubchannelAddress, + remoteAddress: null, + security: null, + remoteName: null, + streamsStarted: 0, + streamsSucceeded: 0, + streamsFailed: 0, + messagesSent: 0, + messagesReceived: 0, + keepAlivesSent: 0, + lastLocalStreamCreatedTimestamp: null, + lastRemoteStreamCreatedTimestamp: null, + lastMessageSentTimestamp: null, + lastMessageReceivedTimestamp: null, + localFlowControlWindow: null, + remoteFlowControlWindow: null + }; + }, this.channelzEnabled); if (this.channelzEnabled) { - channelzRef = registerChannelzSocket(subchannelAddressToString(boundSubchannelAddress), () => { - return { - localAddress: boundSubchannelAddress, - remoteAddress: null, - security: null, - remoteName: null, - streamsStarted: 0, - streamsSucceeded: 0, - streamsFailed: 0, - messagesSent: 0, - messagesReceived: 0, - keepAlivesSent: 0, - lastLocalStreamCreatedTimestamp: null, - lastRemoteStreamCreatedTimestamp: null, - lastMessageSentTimestamp: null, - lastMessageReceivedTimestamp: null, - localFlowControlWindow: null, - remoteFlowControlWindow: null - }; - }); this.listenerChildrenTracker.refChild(channelzRef); - } else { - channelzRef = { - kind: 'socket', - id: -1, - name: '' - }; } this.http2ServerList.push({server: http2Server, channelzRef: channelzRef}); this.trace('Successfully bound ' + subchannelAddressToString(boundSubchannelAddress)); @@ -509,34 +497,28 @@ export class Server { port: boundAddress.port }; let channelzRef: SocketRef; + channelzRef = registerChannelzSocket(subchannelAddressToString(boundSubchannelAddress), () => { + return { + localAddress: boundSubchannelAddress, + remoteAddress: null, + security: null, + remoteName: null, + streamsStarted: 0, + streamsSucceeded: 0, + streamsFailed: 0, + messagesSent: 0, + messagesReceived: 0, + keepAlivesSent: 0, + lastLocalStreamCreatedTimestamp: null, + lastRemoteStreamCreatedTimestamp: null, + lastMessageSentTimestamp: null, + lastMessageReceivedTimestamp: null, + localFlowControlWindow: null, + remoteFlowControlWindow: null + }; + }, this.channelzEnabled); if (this.channelzEnabled) { - channelzRef = registerChannelzSocket(subchannelAddressToString(boundSubchannelAddress), () => { - return { - localAddress: boundSubchannelAddress, - remoteAddress: null, - security: null, - remoteName: null, - streamsStarted: 0, - streamsSucceeded: 0, - streamsFailed: 0, - messagesSent: 0, - messagesReceived: 0, - keepAlivesSent: 0, - lastLocalStreamCreatedTimestamp: null, - lastRemoteStreamCreatedTimestamp: null, - lastMessageSentTimestamp: null, - lastMessageReceivedTimestamp: null, - localFlowControlWindow: null, - remoteFlowControlWindow: null - }; - }); this.listenerChildrenTracker.refChild(channelzRef); - } else { - channelzRef = { - kind: 'socket', - id: -1, - name: '' - }; } this.http2ServerList.push({server: http2Server, channelzRef: channelzRef}); this.trace('Successfully bound ' + subchannelAddressToString(boundSubchannelAddress)); @@ -893,15 +875,7 @@ export class Server { } let channelzRef: SocketRef; - if (this.channelzEnabled) { - channelzRef = registerChannelzSocket(session.socket.remoteAddress ?? 'unknown', this.getChannelzSessionInfoGetter(session)); - } else { - channelzRef = { - kind: 'socket', - id: -1, - name: '' - } - } + channelzRef = registerChannelzSocket(session.socket.remoteAddress ?? 'unknown', this.getChannelzSessionInfoGetter(session), this.channelzEnabled); const channelzSessionInfo: ChannelzSessionInfo = { ref: channelzRef, diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 800274f99..5ef06b7bd 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -227,16 +227,9 @@ export class Subchannel { this.channelzEnabled = false; } this.channelzTrace = new ChannelzTrace(); + this.channelzRef = registerChannelzSubchannel(this.subchannelAddressString, () => this.getChannelzInfo(), this.channelzEnabled); if (this.channelzEnabled) { - this.channelzRef = registerChannelzSubchannel(this.subchannelAddressString, () => this.getChannelzInfo()); this.channelzTrace.addTrace('CT_INFO', 'Subchannel created'); - } else { - // Dummy channelz ref that will never be used - this.channelzRef = { - kind: 'subchannel', - id: -1, - name: '' - }; } this.trace('Subchannel constructed with options ' + JSON.stringify(options, undefined, 2)); } @@ -484,8 +477,8 @@ export class Subchannel { connectionOptions ); this.session = session; + this.channelzSocketRef = registerChannelzSocket(this.subchannelAddressString, () => this.getChannelzSocketInfo()!, this.channelzEnabled); if (this.channelzEnabled) { - this.channelzSocketRef = registerChannelzSocket(this.subchannelAddressString, () => this.getChannelzSocketInfo()!); this.childrenTracker.refChild(this.channelzSocketRef); } session.unref(); From 12c58c29237ea48f9278fa3d01f4889a1f558bc1 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 7 Apr 2022 17:57:18 -0700 Subject: [PATCH 217/450] grpc-js: Disable per-session memory limit by default --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/subchannel.ts | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index bb8adff8f..9fab8d838 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.6.2", + "version": "1.6.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", diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 800274f99..474a05562 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -407,6 +407,12 @@ export class Subchannel { connectionOptions.maxSessionMemory = this.options[ 'grpc-node.max_session_memory' ]; + } else { + /* By default, set a very large max session memory limit, to effectively + * disable enforcement of the limit. Some testing indicates that Node's + * behavior degrades badly when this limit is reached, so we solve that + * by disabling the check entirely. */ + connectionOptions.maxSessionMemory = Number.MAX_SAFE_INTEGER; } let addressScheme = 'http://'; if ('secureContext' in connectionOptions) { From 7ac345e4dc7c5122b9a4707613f8a9aa506f800b Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 8 Apr 2022 10:13:46 -0700 Subject: [PATCH 218/450] grpc-js: Add more details to keepalive ping tracing --- packages/grpc-js/src/subchannel.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 800274f99..58f995d7b 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -328,6 +328,10 @@ export class Subchannel { logging.trace(LogVerbosity.DEBUG, 'subchannel_internals', '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' ' + text); } + private keepaliveTrace(text: string): void { + logging.trace(LogVerbosity.DEBUG, 'keepalive', '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' ' + text); + } + private handleBackoffTimer() { if (this.continueConnecting) { this.transitionToState( @@ -358,18 +362,15 @@ export class Subchannel { if (this.channelzEnabled) { this.keepalivesSent += 1; } - logging.trace( - LogVerbosity.DEBUG, - 'keepalive', - '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' ' + - 'Sending ping' - ); + this.keepaliveTrace('Sending ping with timeout ' + this.keepaliveTimeoutMs + 'ms'); this.keepaliveTimeoutId = setTimeout(() => { + this.keepaliveTrace('Ping timeout passed without response'); this.transitionToState([ConnectivityState.READY], ConnectivityState.IDLE); }, this.keepaliveTimeoutMs); this.keepaliveTimeoutId.unref?.(); this.session!.ping( (err: Error | null, duration: number, payload: Buffer) => { + this.keepaliveTrace('Received ping response'); clearTimeout(this.keepaliveTimeoutId); } ); From abbaf13c62fa02da001a5d5598bf3cdf1a86563a Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 8 Apr 2022 10:25:15 -0700 Subject: [PATCH 219/450] grpc-js-xds: Don't stop backoff timers for LRS streams --- packages/grpc-js-xds/src/xds-client.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index 7a12af1f6..bdc123959 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -781,7 +781,6 @@ export class XdsClient { trace('Received LRS response'); /* Once we get any response from the server, we assume that the stream is * in a good state, so we can reset the backoff timer. */ - this.lrsBackoff.stop(); this.lrsBackoff.reset(); if ( !this.receivedLrsSettingsForCurrentStream || From ae93d556ec44cd372fff78e69c674904ba63b223 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 8 Apr 2022 11:23:00 -0700 Subject: [PATCH 220/450] grpc-js: Don't clear ping timeout when still connected --- packages/grpc-js/src/subchannel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 800274f99..22c3363c7 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -773,7 +773,7 @@ export class Subchannel { } this.backoffTimeout.unref(); if (!this.keepaliveWithoutCalls) { - this.stopKeepalivePings(); + clearInterval(this.keepaliveIntervalId); } this.checkBothRefcounts(); } From 57d7827ab8341ca90c4c512a371a212760a41aaf Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 11 Apr 2022 10:12:24 -0700 Subject: [PATCH 221/450] grpc-js-xds: Include Node ID in XdsClient status errors --- packages/grpc-js-xds/src/xds-client.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index 7a12af1f6..2eabc5863 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -726,7 +726,7 @@ export class XdsClient { if (serviceKind) { this.adsState[serviceKind].reportStreamError({ code: status.UNAVAILABLE, - details: message, + details: message + ' Node ID=' + this.adsNodeV3!.id, metadata: new Metadata() }); resourceNames = this.adsState[serviceKind].getResourceNames(); @@ -771,6 +771,7 @@ export class XdsClient { } private reportStreamError(status: StatusObject) { + status = {...status, details: status.details + ' Node ID=' + this.adsNodeV3!.id}; this.adsState.eds.reportStreamError(status); this.adsState.cds.reportStreamError(status); this.adsState.rds.reportStreamError(status); From 1e1f73236387bbce8dd216317643b739ad464fa8 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 11 Apr 2022 10:42:42 -0700 Subject: [PATCH 222/450] grpc-js-xds: Reject EDS updates with duplicate locality/priority pairs --- .../grpc-js-xds/src/xds-stream-state/eds-state.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts index fe9f3c624..a050b44c9 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts @@ -17,6 +17,7 @@ import { experimental, logVerbosity, StatusObject } from "@grpc/grpc-js"; import { isIPv4, isIPv6 } from "net"; +import { Locality__Output } from "../generated/envoy/config/core/v3/Locality"; import { ClusterLoadAssignment__Output } from "../generated/envoy/config/endpoint/v3/ClusterLoadAssignment"; import { Any__Output } from "../generated/google/protobuf/Any"; import { HandleResponseResult, RejectedResourceEntry, ResourcePair, Watcher, XdsStreamState } from "./xds-stream-state"; @@ -27,6 +28,10 @@ function trace(text: string): void { experimental.trace(logVerbosity.DEBUG, TRACER_NAME, text); } +function localitiesEqual(a: Locality__Output, b: Locality__Output) { + return a.region === b.region && a.sub_zone === b.sub_zone && a.zone === b.zone; +} + export class EdsState implements XdsStreamState { public versionInfo = ''; public nonce = ''; @@ -112,7 +117,17 @@ export class EdsState implements XdsStreamState { * @param message */ private validateResponse(message: ClusterLoadAssignment__Output) { + const seenLocalities: {locality: Locality__Output, priority: number}[] = []; for (const endpoint of message.endpoints) { + if (!endpoint.locality) { + return false; + } + for (const {locality, priority} of seenLocalities) { + if (localitiesEqual(endpoint.locality, locality) && endpoint.priority === priority) { + return false; + } + } + seenLocalities.push({locality: endpoint.locality, priority: endpoint.priority}); for (const lb of endpoint.lb_endpoints) { const socketAddress = lb.endpoint?.address?.socket_address; if (!socketAddress) { From 553fb7a819cdb555d03b44c24ca4750a0d85ac31 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 11 Apr 2022 14:43:18 -0700 Subject: [PATCH 223/450] grpc-js: Add comment about stopKeepalivePings usage --- packages/grpc-js/src/subchannel.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 22c3363c7..39ccc01bb 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -384,6 +384,11 @@ export class Subchannel { * sending pings should also involve some network activity. */ } + /** + * Stop keepalive pings when terminating a connection. This discards the + * outstanding ping timeout, so it should not be called if the same + * connection will still be used. + */ private stopKeepalivePings() { clearInterval(this.keepaliveIntervalId); clearTimeout(this.keepaliveTimeoutId); From 6c686772cbee628651910dbbd1a8da5b488deeda Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 12 Apr 2022 16:16:57 -0700 Subject: [PATCH 224/450] grpc-js: Fix handling of calls after resolution failure --- packages/grpc-js/src/channel.ts | 30 +++++++++++++++---- .../grpc-js/src/resolving-load-balancer.ts | 5 ++-- packages/grpc-js/test/test-client.ts | 24 +++++++++++++++ 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 3d014607e..88bf3a7e0 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -20,6 +20,7 @@ import { Call, Http2CallStream, CallStreamOptions, + StatusObject, } from './call-stream'; import { ChannelCredentials } from './channel-credentials'; import { ChannelOptions } from './channel-options'; @@ -170,6 +171,14 @@ export class ChannelImplementation implements Channel { */ private callRefTimer: NodeJS.Timer; private configSelector: ConfigSelector | null = null; + /** + * This is the error from the name resolver if it failed most recently. It + * is only used to end calls that start while there is no config selector + * and the name resolver is in backoff, so it should be nulled if + * configSelector becomes set or the channel state becomes anything other + * than TRANSIENT_FAILURE. + */ + private currentResolutionError: StatusObject | null = null; // Channelz info private readonly channelzEnabled: boolean = true; @@ -290,6 +299,7 @@ export class ChannelImplementation implements Channel { this.channelzTrace.addTrace('CT_INFO', 'Address resolution succeeded'); } this.configSelector = configSelector; + this.currentResolutionError = null; /* We process the queue asynchronously to ensure that the corresponding * load balancer update has completed. */ process.nextTick(() => { @@ -309,6 +319,9 @@ export class ChannelImplementation implements Channel { if (this.configSelectionQueue.length > 0) { this.trace('Name resolution failed with calls queued for config selection'); } + if (this.configSelector === null) { + this.currentResolutionError = status; + } const localQueue = this.configSelectionQueue; this.configSelectionQueue = []; this.callRefTimerUnref(); @@ -591,6 +604,9 @@ export class ChannelImplementation implements Channel { watcherObject.callback(); } } + if (newState !== ConnectivityState.TRANSIENT_FAILURE) { + this.currentResolutionError = null; + } } private tryGetConfig(stream: Http2CallStream, metadata: Metadata) { @@ -605,11 +621,15 @@ export class ChannelImplementation implements Channel { * ResolvingLoadBalancer may be idle and if so it needs to be kicked * because it now has a pending request. */ this.resolvingLoadBalancer.exitIdle(); - this.configSelectionQueue.push({ - callStream: stream, - callMetadata: metadata, - }); - this.callRefTimerRef(); + if (this.currentResolutionError && !metadata.getOptions().waitForReady) { + stream.cancelWithStatus(this.currentResolutionError.code, this.currentResolutionError.details); + } else { + this.configSelectionQueue.push({ + callStream: stream, + callMetadata: metadata, + }); + this.callRefTimerRef(); + } } else { const callConfig = this.configSelector(stream.getMethod(), metadata); if (callConfig.status === Status.OK) { diff --git a/packages/grpc-js/src/resolving-load-balancer.ts b/packages/grpc-js/src/resolving-load-balancer.ts index 907067dfc..7b9f92cb8 100644 --- a/packages/grpc-js/src/resolving-load-balancer.ts +++ b/packages/grpc-js/src/resolving-load-balancer.ts @@ -268,6 +268,7 @@ export class ResolvingLoadBalancer implements LoadBalancer { if (this.currentState === ConnectivityState.IDLE) { this.updateState(ConnectivityState.CONNECTING, new QueuePicker(this)); } + this.backoffTimeout.runOnce(); } private updateState(connectivityState: ConnectivityState, picker: Picker) { @@ -294,18 +295,16 @@ export class ResolvingLoadBalancer implements LoadBalancer { ); this.onFailedResolution(error); } - this.backoffTimeout.runOnce(); } exitIdle() { this.childLoadBalancer.exitIdle(); - if (this.currentState === ConnectivityState.IDLE) { + if (this.currentState === ConnectivityState.IDLE || this.currentState === ConnectivityState.TRANSIENT_FAILURE) { if (this.backoffTimeout.isRunning()) { this.continueResolving = true; } else { this.updateResolution(); } - this.updateState(ConnectivityState.CONNECTING, new QueuePicker(this)); } } diff --git a/packages/grpc-js/test/test-client.ts b/packages/grpc-js/test/test-client.ts index 4a02ff3de..21dad99f1 100644 --- a/packages/grpc-js/test/test-client.ts +++ b/packages/grpc-js/test/test-client.ts @@ -92,4 +92,28 @@ describe('Client without a server', () => { }); }); }); +}); + +describe('Client with a nonexistent target domain', () => { + let client: Client; + before(() => { + // DNS name that does not exist per RFC 6761 section 6.4 + client = new Client('host.invalid', clientInsecureCreds); + }); + after(() => { + client.close(); + }); + it('should fail multiple calls', function(done) { + this.timeout(5000); + // Regression test for https://github.com/grpc/grpc-node/issues/1411 + client.makeUnaryRequest('/service/method', x => x, x => x, Buffer.from([]), (error, value) => { + assert(error); + assert.strictEqual(error?.code, grpc.status.UNAVAILABLE); + client.makeUnaryRequest('/service/method', x => x, x => x, Buffer.from([]), (error, value) => { + assert(error); + assert.strictEqual(error?.code, grpc.status.UNAVAILABLE); + done(); + }); + }); + }); }); \ No newline at end of file From c112d167bb0af504c4a1121d2f6f28c9454d3e4d Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 13 Apr 2022 11:27:31 -0700 Subject: [PATCH 225/450] grpc-js: Update version to 1.6.4 --- 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 9fab8d838..408168e9d 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.6.3", + "version": "1.6.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", From 478900d191d8f4e6c2e57e9ff732ad974253ceef Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 14 Apr 2022 16:51:16 -0700 Subject: [PATCH 226/450] grpc-js: Consistently re-resolve when idle --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/resolving-load-balancer.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 408168e9d..09a88b5a5 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.6.4", + "version": "1.6.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/resolving-load-balancer.ts b/packages/grpc-js/src/resolving-load-balancer.ts index 7b9f92cb8..985b6e31e 100644 --- a/packages/grpc-js/src/resolving-load-balancer.ts +++ b/packages/grpc-js/src/resolving-load-balancer.ts @@ -298,7 +298,6 @@ export class ResolvingLoadBalancer implements LoadBalancer { } exitIdle() { - this.childLoadBalancer.exitIdle(); if (this.currentState === ConnectivityState.IDLE || this.currentState === ConnectivityState.TRANSIENT_FAILURE) { if (this.backoffTimeout.isRunning()) { this.continueResolving = true; @@ -306,6 +305,7 @@ export class ResolvingLoadBalancer implements LoadBalancer { this.updateResolution(); } } + this.childLoadBalancer.exitIdle(); } updateAddressList( From 8cbc3dc8258fa31d29a15f59ef230abb69651bb0 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 14 Apr 2022 17:28:22 -0700 Subject: [PATCH 227/450] grpc-js: Make a reachable code path for requestReresolution in pick_first --- .../grpc-js/src/load-balancer-pick-first.ts | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/grpc-js/src/load-balancer-pick-first.ts b/packages/grpc-js/src/load-balancer-pick-first.ts index 884af50b7..240f0e9ff 100644 --- a/packages/grpc-js/src/load-balancer-pick-first.ts +++ b/packages/grpc-js/src/load-balancer-pick-first.ts @@ -184,8 +184,10 @@ export class PickFirstLoadBalancer implements LoadBalancer { ) { /* If all of the subchannels are IDLE we should go back to a * basic IDLE state where there is no subchannel list to avoid - * holding unused resources */ - this.resetSubchannelList(); + * holding unused resources. We do not reset triedAllSubchannels + * because that is a reminder to request reresolution the next time + * this LB policy needs to connect. */ + this.resetSubchannelList(false); this.updateState(ConnectivityState.IDLE, new QueuePicker(this)); return; } @@ -337,7 +339,7 @@ export class PickFirstLoadBalancer implements LoadBalancer { this.channelControlHelper.updateState(newState, picker); } - private resetSubchannelList() { + private resetSubchannelList(resetTriedAllSubchannels = true) { for (const subchannel of this.subchannels) { subchannel.removeConnectivityStateListener(this.subchannelStateListener); subchannel.unref(); @@ -352,7 +354,9 @@ export class PickFirstLoadBalancer implements LoadBalancer { [ConnectivityState.TRANSIENT_FAILURE]: 0, }; this.subchannels = []; - this.triedAllSubchannels = false; + if (resetTriedAllSubchannels) { + this.triedAllSubchannels = false; + } } /** @@ -425,6 +429,12 @@ export class PickFirstLoadBalancer implements LoadBalancer { } exitIdle() { + if ( + this.currentState === ConnectivityState.IDLE || + this.triedAllSubchannels + ) { + this.channelControlHelper.requestReresolution(); + } for (const subchannel of this.subchannels) { subchannel.startConnecting(); } @@ -433,12 +443,6 @@ export class PickFirstLoadBalancer implements LoadBalancer { this.connectToAddressList(); } } - if ( - this.currentState === ConnectivityState.IDLE || - this.triedAllSubchannels - ) { - this.channelControlHelper.requestReresolution(); - } } resetBackoff() { From cf11b60ce20123394dc6cb21488c665c7787d84e Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 18 Apr 2022 09:36:57 -0700 Subject: [PATCH 228/450] grpc-js: End calls when keepalive pings time out --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/subchannel.ts | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 09a88b5a5..a0df55736 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.6.5", + "version": "1.6.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/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 5880f3f97..5d479a73a 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -358,7 +358,7 @@ export class Subchannel { this.keepaliveTrace('Sending ping with timeout ' + this.keepaliveTimeoutMs + 'ms'); this.keepaliveTimeoutId = setTimeout(() => { this.keepaliveTrace('Ping timeout passed without response'); - this.transitionToState([ConnectivityState.READY], ConnectivityState.IDLE); + this.handleDisconnect(); }, this.keepaliveTimeoutMs); this.keepaliveTimeoutId.unref?.(); this.session!.ping( @@ -642,6 +642,15 @@ export class Subchannel { ); } + private handleDisconnect() { + this.transitionToState( + [ConnectivityState.READY], + ConnectivityState.TRANSIENT_FAILURE); + for (const listener of this.disconnectListeners) { + listener(); + } + } + /** * Initiate a state transition from any element of oldStates to the new * state. If the current connectivityState is not in oldStates, do nothing. @@ -672,12 +681,7 @@ export class Subchannel { const session = this.session!; session.socket.once('close', () => { if (this.session === session) { - this.transitionToState( - [ConnectivityState.READY], - ConnectivityState.TRANSIENT_FAILURE); - for (const listener of this.disconnectListeners) { - listener(); - } + this.handleDisconnect(); } }); if (this.keepaliveWithoutCalls) { From c9b7d4d285176a6be437b724c118c85f3f08c66d Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 18 Apr 2022 09:56:06 -0700 Subject: [PATCH 229/450] grpc-js: DNS: unset continueResolving when starting a resolution attempt --- packages/grpc-js/src/resolver-dns.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/grpc-js/src/resolver-dns.ts b/packages/grpc-js/src/resolver-dns.ts index c4cb64a74..47de8dbca 100644 --- a/packages/grpc-js/src/resolver-dns.ts +++ b/packages/grpc-js/src/resolver-dns.ts @@ -314,6 +314,7 @@ class DnsResolver implements Resolver { } private startResolutionWithBackoff() { + this.continueResolving = false; this.startResolution(); this.backoff.runOnce(); this.startNextResolutionTimer(); From 964c7a68aabd3e45f87b0d0045bb604e1bd67ae7 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 19 Apr 2022 10:21:49 -0700 Subject: [PATCH 230/450] grpc-js: Fix double resolver calls in DNS resolver --- packages/grpc-js/src/backoff-timeout.ts | 1 + packages/grpc-js/src/resolver-dns.ts | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/src/backoff-timeout.ts b/packages/grpc-js/src/backoff-timeout.ts index dc7be277a..f523e259a 100644 --- a/packages/grpc-js/src/backoff-timeout.ts +++ b/packages/grpc-js/src/backoff-timeout.ts @@ -100,6 +100,7 @@ export class BackoffTimeout { } private runTimer(delay: number) { + clearTimeout(this.timerId); this.timerId = setTimeout(() => { this.callback(); this.running = false; diff --git a/packages/grpc-js/src/resolver-dns.ts b/packages/grpc-js/src/resolver-dns.ts index 47de8dbca..14de26561 100644 --- a/packages/grpc-js/src/resolver-dns.ts +++ b/packages/grpc-js/src/resolver-dns.ts @@ -158,7 +158,6 @@ class DnsResolver implements Resolver { if (this.ipResult !== null) { trace('Returning IP address for target ' + uriToString(this.target)); setImmediate(() => { - this.backoff.reset(); this.listener.onSuccessfulResolution( this.ipResult!, null, @@ -167,6 +166,8 @@ class DnsResolver implements Resolver { {} ); }); + this.backoff.stop(); + this.backoff.reset(); return; } if (this.dnsHostname === null) { @@ -178,7 +179,11 @@ class DnsResolver implements Resolver { metadata: new Metadata(), }); }); + this.stopNextResolutionTimer(); } else { + if (this.pendingLookupPromise !== null) { + return; + } trace('Looking up DNS hostname ' + this.dnsHostname); /* We clear out latestLookupResult here to ensure that it contains the * latest result since the last time we started resolving. That way, the @@ -299,6 +304,7 @@ class DnsResolver implements Resolver { } private startNextResolutionTimer() { + clearTimeout(this.nextResolutionTimer); this.nextResolutionTimer = setTimeout(() => { this.stopNextResolutionTimer(); if (this.continueResolving) { @@ -314,10 +320,12 @@ class DnsResolver implements Resolver { } private startResolutionWithBackoff() { + if (this.pendingLookupPromise === null) { this.continueResolving = false; this.startResolution(); this.backoff.runOnce(); this.startNextResolutionTimer(); + } } updateResolution() { From 5311c03867c7e3bdb1c167fcd76d44d6b5d2e63a Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 19 Apr 2022 13:18:59 -0700 Subject: [PATCH 231/450] grpc-js: Report error when no message received for unary response --- packages/grpc-js/src/client.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/src/client.ts b/packages/grpc-js/src/client.ts index ed9407cd8..20f56bcb5 100644 --- a/packages/grpc-js/src/client.ts +++ b/packages/grpc-js/src/client.ts @@ -338,7 +338,15 @@ export class Client { } receivedStatus = true; if (status.code === Status.OK) { - callProperties.callback!(null, responseMessage!); + if (responseMessage === null) { + callProperties.callback!(callErrorFromStatus({ + code: Status.INTERNAL, + details: 'No message received', + metadata: status.metadata + })); + } else { + callProperties.callback!(null, responseMessage); + } } else { callProperties.callback!(callErrorFromStatus(status)); } @@ -455,7 +463,15 @@ export class Client { } receivedStatus = true; if (status.code === Status.OK) { - callProperties.callback!(null, responseMessage!); + if (responseMessage === null) { + callProperties.callback!(callErrorFromStatus({ + code: Status.INTERNAL, + details: 'No message received', + metadata: status.metadata + })); + } else { + callProperties.callback!(null, responseMessage); + } } else { callProperties.callback!(callErrorFromStatus(status)); } From 32514224ce1c85cd6e3c0c2e4a8c197acc90e0b9 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 20 Apr 2022 13:06:43 -0700 Subject: [PATCH 232/450] grpc-js: Fix shutting down subchannels in separate pools --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/subchannel-pool.ts | 14 +++++--------- packages/grpc-js/src/subchannel.ts | 2 +- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index a0df55736..723b108ff 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.6.6", + "version": "1.6.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-pool.ts b/packages/grpc-js/src/subchannel-pool.ts index cd74cad81..b7ef362c3 100644 --- a/packages/grpc-js/src/subchannel-pool.ts +++ b/packages/grpc-js/src/subchannel-pool.ts @@ -49,10 +49,8 @@ export class SubchannelPool { /** * A pool of subchannels use for making connections. Subchannels with the * exact same parameters will be reused. - * @param global If true, this is the global subchannel pool. Otherwise, it - * is the pool for a single channel. */ - constructor(private global: boolean) {} + constructor() {} /** * Unrefs all unused subchannels and cancels the cleanup task if all @@ -95,7 +93,7 @@ export class SubchannelPool { * Ensures that the cleanup task is spawned. */ ensureCleanupTask(): void { - if (this.global && this.cleanupTimer === null) { + if (this.cleanupTimer === null) { this.cleanupTimer = setInterval(() => { this.unrefUnusedSubchannels(); }, REF_CHECK_INTERVAL); @@ -156,14 +154,12 @@ export class SubchannelPool { channelCredentials, subchannel, }); - if (this.global) { - subchannel.ref(); - } + subchannel.ref(); return subchannel; } } -const globalSubchannelPool = new SubchannelPool(true); +const globalSubchannelPool = new SubchannelPool(); /** * Get either the global subchannel pool, or a new subchannel pool. @@ -173,6 +169,6 @@ export function getSubchannelPool(global: boolean): SubchannelPool { if (global) { return globalSubchannelPool; } else { - return new SubchannelPool(false); + return new SubchannelPool(); } } diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 5d479a73a..372ab5160 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -741,7 +741,7 @@ export class Subchannel { } this.transitionToState( [ConnectivityState.CONNECTING, ConnectivityState.READY], - ConnectivityState.TRANSIENT_FAILURE + ConnectivityState.IDLE ); if (this.channelzEnabled) { unregisterChannelzRef(this.channelzRef); From b07ea8b35418ecfd88bccf856bffe8b75eef3727 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 21 Apr 2022 14:42:04 -0700 Subject: [PATCH 233/450] grpc-js: Update outlier detection to address recent spec changes --- .../src/load-balancer-outlier-detection.ts | 51 +++++++++++++++---- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index e69e2ef99..3bd062110 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -334,17 +334,21 @@ class OutlierDetectionCounterFilterFactory implements FilterFactory = new Map(); private latestConfig: OutlierDetectionLoadBalancingConfig | null = null; private ejectionTimer: NodeJS.Timer; + private timerStartTime: Date | null = null; constructor(channelControlHelper: ChannelControlHelper) { this.childBalancer = new ChildLoadBalancerHandler(createChildChannelControlHelper(channelControlHelper, { @@ -373,7 +378,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { }, updateState: (connectivityState: ConnectivityState, picker: Picker) => { if (connectivityState === ConnectivityState.READY) { - channelControlHelper.updateState(connectivityState, new OutlierDetectionPicker(picker)); + channelControlHelper.updateState(connectivityState, new OutlierDetectionPicker(picker, this.isCountingEnabled())); } else { channelControlHelper.updateState(connectivityState, picker); } @@ -383,6 +388,12 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { clearInterval(this.ejectionTimer); } + private isCountingEnabled(): boolean { + return this.latestConfig !== null && + (this.latestConfig.getSuccessRateEjectionConfig() !== null || + this.latestConfig.getFailurePercentageEjectionConfig() !== null); + } + private getCurrentEjectionPercent() { let ejectionCount = 0; for (const mapEntry of this.addressMap.values()) { @@ -501,16 +512,26 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { } } - private runChecks() { - const ejectionTimestamp = new Date(); - + private switchAllBuckets() { for (const mapEntry of this.addressMap.values()) { mapEntry.counter.switchBuckets(); } + } + + private startTimer(delayMs: number) { + this.ejectionTimer = setTimeout(() => this.runChecks(), delayMs); + } + + private runChecks() { + const ejectionTimestamp = new Date(); + + this.switchAllBuckets(); if (!this.latestConfig) { return; } + this.timerStartTime = ejectionTimestamp; + this.startTimer(this.latestConfig.getIntervalMs()); this.runSuccessRateCheck(ejectionTimestamp); this.runFailurePercentageCheck(ejectionTimestamp); @@ -561,10 +582,21 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { ); this.childBalancer.updateAddressList(addressList, childPolicy, attributes); - if (this.latestConfig === null || this.latestConfig.getIntervalMs() !== lbConfig.getIntervalMs()) { - clearInterval(this.ejectionTimer); - this.ejectionTimer = setInterval(() => this.runChecks(), lbConfig.getIntervalMs()); + if (lbConfig.getSuccessRateEjectionConfig() || lbConfig.getFailurePercentageEjectionConfig()) { + if (this.timerStartTime) { + clearTimeout(this.ejectionTimer); + const remainingDelay = lbConfig.getIntervalMs() - ((new Date()).getTime() - this.timerStartTime.getTime()); + this.startTimer(remainingDelay); + } else { + this.timerStartTime = new Date(); + this.startTimer(lbConfig.getIntervalMs()); + this.switchAllBuckets(); + } + } else { + this.timerStartTime = null; + clearTimeout(this.ejectionTimer); } + this.latestConfig = lbConfig; } exitIdle(): void { @@ -574,6 +606,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { this.childBalancer.resetBackoff(); } destroy(): void { + clearTimeout(this.ejectionTimer); this.childBalancer.destroy(); } getTypeName(): string { From cd58695674679bdf070fea3390b86d51dddf0996 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 21 Apr 2022 16:09:24 -0700 Subject: [PATCH 234/450] grpc-js: Add regression tests for repeated DNS requests --- packages/grpc-js/test/test-resolver.ts | 64 ++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/packages/grpc-js/test/test-resolver.ts b/packages/grpc-js/test/test-resolver.ts index 354413ea6..512740cad 100644 --- a/packages/grpc-js/test/test-resolver.ts +++ b/packages/grpc-js/test/test-resolver.ts @@ -356,6 +356,70 @@ describe('Name Resolver', () => { const resolver2 = resolverManager.createResolver(target2, listener, {}); resolver2.updateResolution(); }); + it('should not keep repeating successful resolutions', done => { + const target = resolverManager.mapUriDefaultScheme(parseUri('localhost')!)!; + let resultCount = 0; + const resolver = resolverManager.createResolver(target, { + onSuccessfulResolution: ( + addressList: SubchannelAddress[], + serviceConfig: ServiceConfig | null, + serviceConfigError: StatusObject | null + ) => { + assert( + addressList.some( + addr => + isTcpSubchannelAddress(addr) && + addr.host === '127.0.0.1' && + addr.port === 443 + ) + ); + assert( + addressList.some( + addr => + isTcpSubchannelAddress(addr) && + addr.host === '::1' && + addr.port === 443 + ) + ); + resultCount += 1; + if (resultCount === 1) { + process.nextTick(() => resolver.updateResolution()); + } + }, + onError: (error: StatusObject) => { + assert.ifError(error); + }, + }, {'grpc.dns_min_time_between_resolutions_ms': 2000}); + resolver.updateResolution(); + setTimeout(() => { + assert.strictEqual(resultCount, 2, `resultCount ${resultCount} !== 2`); + done(); + }, 10_000); + }).timeout(15_000); + it('should not keep repeating failed resolutions', done => { + const target = resolverManager.mapUriDefaultScheme(parseUri('host.invalid')!)!; + let resultCount = 0; + const resolver = resolverManager.createResolver(target, { + onSuccessfulResolution: ( + addressList: SubchannelAddress[], + serviceConfig: ServiceConfig | null, + serviceConfigError: StatusObject | null + ) => { + assert.fail('Resolution succeeded unexpectedly'); + }, + onError: (error: StatusObject) => { + resultCount += 1; + if (resultCount === 1) { + process.nextTick(() => resolver.updateResolution()); + } + }, + }, {}); + resolver.updateResolution(); + setTimeout(() => { + assert.strictEqual(resultCount, 2, `resultCount ${resultCount} !== 2`); + done(); + }, 10_000); + }).timeout(15_000); }); describe('UDS Names', () => { it('Should handle a relative Unix Domain Socket name', done => { From db65d566e651c96cdba909f22e28bbf7be312778 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 26 Apr 2022 10:09:22 -0700 Subject: [PATCH 235/450] grpc-js: Fix mean calculation in outlier detection LB policy --- packages/grpc-js/src/load-balancer-outlier-detection.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index 3bd062110..2c231c406 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -429,7 +429,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { } // Step 2 - const successRateMean = successRates.reduce((a, b) => a + b); + const successRateMean = successRates.reduce((a, b) => a + b) / successRates.length; let successRateVariance = 0; for (const rate of successRates) { const deviation = rate - successRateMean; From 01823377be02b78869c92d8c147944a1b789139b Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 28 Apr 2022 10:34:30 -0700 Subject: [PATCH 236/450] grpc-js: Add calling context to call errors --- packages/grpc-js/src/call.ts | 6 ++++-- packages/grpc-js/src/client.ts | 16 ++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/packages/grpc-js/src/call.ts b/packages/grpc-js/src/call.ts index fcc3159db..10b606a44 100644 --- a/packages/grpc-js/src/call.ts +++ b/packages/grpc-js/src/call.ts @@ -76,9 +76,11 @@ export type ClientDuplexStream< * error is not necessarily a problem in gRPC itself. * @param status */ -export function callErrorFromStatus(status: StatusObject): ServiceError { +export function callErrorFromStatus(status: StatusObject, callerStack: string): ServiceError { const message = `${status.code} ${Status[status.code]}: ${status.details}`; - return Object.assign(new Error(message), status); + const error = new Error(message); + const stack = `${error.stack}\nfor call at\n${callerStack}`; + return Object.assign(new Error(message), status, {stack}); } export class ClientUnaryCallImpl diff --git a/packages/grpc-js/src/client.ts b/packages/grpc-js/src/client.ts index 20f56bcb5..747c5c877 100644 --- a/packages/grpc-js/src/client.ts +++ b/packages/grpc-js/src/client.ts @@ -321,6 +321,7 @@ export class Client { } let responseMessage: ResponseType | null = null; let receivedStatus = false; + const callerStack = (new Error().stack!).split('\n').slice(1).join('\n'); call.start(callProperties.metadata, { onReceiveMetadata: (metadata) => { emitter.emit('metadata', metadata); @@ -343,12 +344,12 @@ export class Client { code: Status.INTERNAL, details: 'No message received', metadata: status.metadata - })); + }, callerStack)); } else { callProperties.callback!(null, responseMessage); } } else { - callProperties.callback!(callErrorFromStatus(status)); + callProperties.callback!(callErrorFromStatus(status, callerStack)); } emitter.emit('status', status); }, @@ -446,6 +447,7 @@ export class Client { } let responseMessage: ResponseType | null = null; let receivedStatus = false; + const callerStack = (new Error().stack!).split('\n').slice(1).join('\n'); call.start(callProperties.metadata, { onReceiveMetadata: (metadata) => { emitter.emit('metadata', metadata); @@ -468,12 +470,12 @@ export class Client { code: Status.INTERNAL, details: 'No message received', metadata: status.metadata - })); + }, callerStack)); } else { callProperties.callback!(null, responseMessage); } } else { - callProperties.callback!(callErrorFromStatus(status)); + callProperties.callback!(callErrorFromStatus(status, callerStack)); } emitter.emit('status', status); }, @@ -575,6 +577,7 @@ export class Client { call.setCredentials(callProperties.callOptions.credentials); } let receivedStatus = false; + const callerStack = (new Error().stack!).split('\n').slice(1).join('\n'); call.start(callProperties.metadata, { onReceiveMetadata(metadata: Metadata) { stream.emit('metadata', metadata); @@ -590,7 +593,7 @@ export class Client { receivedStatus = true; stream.push(null); if (status.code !== Status.OK) { - stream.emit('error', callErrorFromStatus(status)); + stream.emit('error', callErrorFromStatus(status, callerStack)); } stream.emit('status', status); }, @@ -672,6 +675,7 @@ export class Client { call.setCredentials(callProperties.callOptions.credentials); } let receivedStatus = false; + const callerStack = (new Error().stack!).split('\n').slice(1).join('\n'); call.start(callProperties.metadata, { onReceiveMetadata(metadata: Metadata) { stream.emit('metadata', metadata); @@ -686,7 +690,7 @@ export class Client { receivedStatus = true; stream.push(null); if (status.code !== Status.OK) { - stream.emit('error', callErrorFromStatus(status)); + stream.emit('error', callErrorFromStatus(status, callerStack)); } stream.emit('status', status); }, From 3388765cbb723907de1cc74349b666cc548a891e Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 2 May 2022 10:54:03 -0700 Subject: [PATCH 237/450] proto-loader: Update to Long 5.x --- packages/proto-loader/package.json | 4 ++-- packages/proto-loader/src/index.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index 9b9431dc1..c9998bafb 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/proto-loader", - "version": "0.6.9", + "version": "0.6.10", "author": "Google Inc.", "contributors": [ { @@ -47,7 +47,7 @@ "dependencies": { "@types/long": "^4.0.1", "lodash.camelcase": "^4.3.0", - "long": "^4.0.0", + "long": "^5.2.0", "protobufjs": "^6.10.0", "yargs": "^16.2.0" }, diff --git a/packages/proto-loader/src/index.ts b/packages/proto-loader/src/index.ts index 24a249400..d607668a9 100644 --- a/packages/proto-loader/src/index.ts +++ b/packages/proto-loader/src/index.ts @@ -22,9 +22,9 @@ import * as descriptor from 'protobufjs/ext/descriptor'; import { loadProtosWithOptionsSync, loadProtosWithOptions, Options, addCommonProtos } from './util'; -export { Long } from 'long'; +import Long = require('long'); -export { Options }; +export { Options, Long }; /** * This type exists for use with code generated by the proto-loader-gen-types From 2b67d5b010db5713d12a0f93ae4c0f26c6d7384c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 3 May 2022 10:16:54 -0700 Subject: [PATCH 238/450] proto-loader: Don't force long@5 --- packages/proto-loader/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index c9998bafb..4b177e87c 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/proto-loader", - "version": "0.6.10", + "version": "0.6.11", "author": "Google Inc.", "contributors": [ { @@ -47,7 +47,7 @@ "dependencies": { "@types/long": "^4.0.1", "lodash.camelcase": "^4.3.0", - "long": "^5.2.0", + "long": "^4.0.0 || ^5.2.0", "protobufjs": "^6.10.0", "yargs": "^16.2.0" }, From d8d957bf8cda8139d46d5da5e2fad912868a4191 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 5 May 2022 09:27:48 -0700 Subject: [PATCH 239/450] proto-loader: Switch long dependency back to 4.x --- packages/proto-loader/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index 4b177e87c..759e54713 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/proto-loader", - "version": "0.6.11", + "version": "0.6.12", "author": "Google Inc.", "contributors": [ { @@ -47,7 +47,7 @@ "dependencies": { "@types/long": "^4.0.1", "lodash.camelcase": "^4.3.0", - "long": "^4.0.0 || ^5.2.0", + "long": "^4.0.0", "protobufjs": "^6.10.0", "yargs": "^16.2.0" }, From 067bb13f275cf2bbcb2fbacf4a757a7a3c7d4035 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 12 May 2022 17:18:55 -0700 Subject: [PATCH 240/450] grpc-js-xds: Refactor xDS stream state and add resource timer --- packages/grpc-js-xds/src/xds-client.ts | 10 +- .../src/xds-stream-state/cds-state.ts | 156 +-------------- .../src/xds-stream-state/eds-state.ts | 130 +----------- .../src/xds-stream-state/lds-state.ts | 135 ++----------- .../src/xds-stream-state/rds-state.ts | 122 +---------- .../src/xds-stream-state/xds-stream-state.ts | 189 +++++++++++++++++- 6 files changed, 236 insertions(+), 506 deletions(-) diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index 7a12af1f6..5f75a2cab 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -309,7 +309,7 @@ export class XdsClient { const edsState = new EdsState(() => { this.updateNames('eds'); }); - const cdsState = new CdsState(edsState, () => { + const cdsState = new CdsState(() => { this.updateNames('cds'); }); const rdsState = new RdsState(() => { @@ -630,6 +630,7 @@ export class XdsClient { this.updateNames(service); } } + this.reportAdsStreamStarted(); } } @@ -777,6 +778,13 @@ export class XdsClient { this.adsState.lds.reportStreamError(status); } + private reportAdsStreamStarted() { + this.adsState.eds.reportAdsStreamStart(); + this.adsState.cds.reportAdsStreamStart(); + this.adsState.rds.reportAdsStreamStart(); + this.adsState.lds.reportAdsStreamStart(); + } + private handleLrsResponse(message: LoadStatsResponse__Output) { trace('Received LRS response'); /* Once we get any response from the server, we assume that the stream is diff --git a/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts index 8c3c4d739..9fd12d6ed 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/cds-state.ts @@ -15,94 +15,21 @@ * */ -import { experimental, logVerbosity, StatusObject } from "@grpc/grpc-js"; import { EXPERIMENTAL_OUTLIER_DETECTION } from "../environment"; import { Cluster__Output } from "../generated/envoy/config/cluster/v3/Cluster"; -import { Any__Output } from "../generated/google/protobuf/Any"; import { Duration__Output } from "../generated/google/protobuf/Duration"; import { UInt32Value__Output } from "../generated/google/protobuf/UInt32Value"; -import { EdsState } from "./eds-state"; -import { HandleResponseResult, RejectedResourceEntry, ResourcePair, Watcher, XdsStreamState } from "./xds-stream-state"; +import { BaseXdsStreamState, XdsStreamState } from "./xds-stream-state"; -const TRACER_NAME = 'xds_client'; - -function trace(text: string): void { - experimental.trace(logVerbosity.DEBUG, TRACER_NAME, text); -} - -export class CdsState implements XdsStreamState { - versionInfo = ''; - nonce = ''; - - private watchers: Map[]> = new Map< - string, - Watcher[] - >(); - - private latestResponses: Cluster__Output[] = []; - private latestIsV2 = false; - - constructor( - private edsState: EdsState, - private updateResourceNames: () => void - ) {} - - /** - * Add the watcher to the watcher list. Returns true if the list of resource - * names has changed, and false otherwise. - * @param clusterName - * @param watcher - */ - addWatcher(clusterName: string, watcher: Watcher): void { - trace('Adding CDS watcher for clusterName ' + clusterName); - let watchersEntry = this.watchers.get(clusterName); - let addedServiceName = false; - if (watchersEntry === undefined) { - addedServiceName = true; - watchersEntry = []; - this.watchers.set(clusterName, watchersEntry); - } - watchersEntry.push(watcher); - - /* If we have already received an update for the requested edsServiceName, - * immediately pass that update along to the watcher */ - const isV2 = this.latestIsV2; - for (const message of this.latestResponses) { - if (message.name === clusterName) { - /* These updates normally occur asynchronously, so we ensure that - * the same happens here */ - process.nextTick(() => { - trace('Reporting existing CDS update for new watcher for clusterName ' + clusterName); - watcher.onValidUpdate(message, isV2); - }); - } - } - if (addedServiceName) { - this.updateResourceNames(); - } +export class CdsState extends BaseXdsStreamState implements XdsStreamState { + protected isStateOfTheWorld(): boolean { + return true; } - - removeWatcher(clusterName: string, watcher: Watcher): void { - trace('Removing CDS watcher for clusterName ' + clusterName); - const watchersEntry = this.watchers.get(clusterName); - let removedServiceName = false; - if (watchersEntry !== undefined) { - const entryIndex = watchersEntry.indexOf(watcher); - if (entryIndex >= 0) { - watchersEntry.splice(entryIndex, 1); - } - if (watchersEntry.length === 0) { - removedServiceName = true; - this.watchers.delete(clusterName); - } - } - if (removedServiceName) { - this.updateResourceNames(); - } + protected getResourceName(resource: Cluster__Output): string { + return resource.name; } - - getResourceNames(): string[] { - return Array.from(this.watchers.keys()); + protected getProtocolName(): string { + return 'CDS'; } private validateNonnegativeDuration(duration: Duration__Output | null): boolean { @@ -125,7 +52,7 @@ export class CdsState implements XdsStreamState { return percentage.value >=0 && percentage.value <= 100; } - private validateResponse(message: Cluster__Output): boolean { + public validateResponse(message: Cluster__Output): boolean { if (message.type !== 'EDS') { return false; } @@ -167,69 +94,4 @@ export class CdsState implements XdsStreamState { } return true; } - - /** - * Given a list of clusterNames (which may actually be the cluster name), - * for each watcher watching a name not on the list, call that watcher's - * onResourceDoesNotExist method. - * @param allClusterNames - */ - private handleMissingNames(allClusterNames: Set): string[] { - const missingNames: string[] = []; - for (const [clusterName, watcherList] of this.watchers.entries()) { - if (!allClusterNames.has(clusterName)) { - trace('Reporting CDS resource does not exist for clusterName ' + clusterName); - missingNames.push(clusterName); - for (const watcher of watcherList) { - watcher.onResourceDoesNotExist(); - } - } - } - return missingNames; - } - - handleResponses(responses: ResourcePair[], isV2: boolean): HandleResponseResult { - const validResponses: Cluster__Output[] = []; - const result: HandleResponseResult = { - accepted: [], - rejected: [], - missing: [] - } - for (const {resource, raw} of responses) { - if (this.validateResponse(resource)) { - validResponses.push(resource); - result.accepted.push({ - name: resource.name, - raw: raw}); - } else { - trace('CDS validation failed for message ' + JSON.stringify(resource)); - result.rejected.push({ - name: resource.name, - raw: raw, - error: `Cluster validation failed for resource ${resource.name}` - }); - } - } - this.latestResponses = validResponses; - this.latestIsV2 = isV2; - const allClusterNames: Set = new Set(); - for (const message of validResponses) { - allClusterNames.add(message.name); - const watchers = this.watchers.get(message.name) ?? []; - for (const watcher of watchers) { - watcher.onValidUpdate(message, isV2); - } - } - trace('Received CDS updates for cluster names [' + Array.from(allClusterNames) + ']'); - result.missing = this.handleMissingNames(allClusterNames); - return result; - } - - reportStreamError(status: StatusObject): void { - for (const watcherList of this.watchers.values()) { - for (const watcher of watcherList) { - watcher.onTransientError(status); - } - } - } } \ No newline at end of file diff --git a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts index fe9f3c624..fb2a99485 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts @@ -19,7 +19,7 @@ import { experimental, logVerbosity, StatusObject } from "@grpc/grpc-js"; import { isIPv4, isIPv6 } from "net"; import { ClusterLoadAssignment__Output } from "../generated/envoy/config/endpoint/v3/ClusterLoadAssignment"; import { Any__Output } from "../generated/google/protobuf/Any"; -import { HandleResponseResult, RejectedResourceEntry, ResourcePair, Watcher, XdsStreamState } from "./xds-stream-state"; +import { BaseXdsStreamState, HandleResponseResult, RejectedResourceEntry, ResourcePair, Watcher, XdsStreamState } from "./xds-stream-state"; const TRACER_NAME = 'xds_client'; @@ -27,83 +27,15 @@ function trace(text: string): void { experimental.trace(logVerbosity.DEBUG, TRACER_NAME, text); } -export class EdsState implements XdsStreamState { - public versionInfo = ''; - public nonce = ''; - - private watchers: Map< - string, - Watcher[] - > = new Map[]>(); - - private latestResponses: ClusterLoadAssignment__Output[] = []; - private latestIsV2 = false; - - constructor(private updateResourceNames: () => void) {} - - /** - * Add the watcher to the watcher list. Returns true if the list of resource - * names has changed, and false otherwise. - * @param edsServiceName - * @param watcher - */ - addWatcher( - edsServiceName: string, - watcher: Watcher - ): void { - let watchersEntry = this.watchers.get(edsServiceName); - let addedServiceName = false; - if (watchersEntry === undefined) { - addedServiceName = true; - watchersEntry = []; - this.watchers.set(edsServiceName, watchersEntry); - } - trace('Adding EDS watcher (' + watchersEntry.length + ' ->' + (watchersEntry.length + 1) + ') for edsServiceName ' + edsServiceName); - watchersEntry.push(watcher); - - /* If we have already received an update for the requested edsServiceName, - * immediately pass that update along to the watcher */ - const isV2 = this.latestIsV2; - for (const message of this.latestResponses) { - if (message.cluster_name === edsServiceName) { - /* These updates normally occur asynchronously, so we ensure that - * the same happens here */ - process.nextTick(() => { - trace('Reporting existing EDS update for new watcher for edsServiceName ' + edsServiceName); - watcher.onValidUpdate(message, isV2); - }); - } - } - if (addedServiceName) { - this.updateResourceNames(); - } +export class EdsState extends BaseXdsStreamState implements XdsStreamState { + protected getResourceName(resource: ClusterLoadAssignment__Output): string { + return resource.cluster_name; } - - removeWatcher( - edsServiceName: string, - watcher: Watcher - ): void { - trace('Removing EDS watcher for edsServiceName ' + edsServiceName); - const watchersEntry = this.watchers.get(edsServiceName); - let removedServiceName = false; - if (watchersEntry !== undefined) { - const entryIndex = watchersEntry.indexOf(watcher); - if (entryIndex >= 0) { - trace('Removed EDS watcher (' + watchersEntry.length + ' -> ' + (watchersEntry.length - 1) + ') for edsServiceName ' + edsServiceName); - watchersEntry.splice(entryIndex, 1); - } - if (watchersEntry.length === 0) { - removedServiceName = true; - this.watchers.delete(edsServiceName); - } - } - if (removedServiceName) { - this.updateResourceNames(); - } + protected getProtocolName(): string { + return 'EDS'; } - - getResourceNames(): string[] { - return Array.from(this.watchers.keys()); + protected isStateOfTheWorld(): boolean { + return false; } /** @@ -111,7 +43,7 @@ export class EdsState implements XdsStreamState { * https://github.com/grpc/proposal/blob/master/A27-xds-global-load-balancing.md#clusterloadassignment-proto * @param message */ - private validateResponse(message: ClusterLoadAssignment__Output) { + public validateResponse(message: ClusterLoadAssignment__Output) { for (const endpoint of message.endpoints) { for (const lb of endpoint.lb_endpoints) { const socketAddress = lb.endpoint?.address?.socket_address; @@ -128,48 +60,4 @@ export class EdsState implements XdsStreamState { } return true; } - - handleResponses(responses: ResourcePair[], isV2: boolean): HandleResponseResult { - const validResponses: ClusterLoadAssignment__Output[] = []; - let result: HandleResponseResult = { - accepted: [], - rejected: [], - missing: [] - } - for (const {resource, raw} of responses) { - if (this.validateResponse(resource)) { - validResponses.push(resource); - result.accepted.push({ - name: resource.cluster_name, - raw: raw}); - } else { - trace('EDS validation failed for message ' + JSON.stringify(resource)); - result.rejected.push({ - name: resource.cluster_name, - raw: raw, - error: `ClusterLoadAssignment validation failed for resource ${resource.cluster_name}` - }); - } - } - this.latestResponses = validResponses; - this.latestIsV2 = isV2; - const allClusterNames: Set = new Set(); - for (const message of validResponses) { - allClusterNames.add(message.cluster_name); - const watchers = this.watchers.get(message.cluster_name) ?? []; - for (const watcher of watchers) { - watcher.onValidUpdate(message, isV2); - } - } - trace('Received EDS updates for cluster names [' + Array.from(allClusterNames) + ']'); - return result; - } - - reportStreamError(status: StatusObject): void { - for (const watcherList of this.watchers.values()) { - for (const watcher of watcherList) { - watcher.onTransientError(status); - } - } - } } \ No newline at end of file diff --git a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts index 7c27c948f..bd5b6423f 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts @@ -15,16 +15,13 @@ * */ -import * as protoLoader from '@grpc/proto-loader'; -import { experimental, logVerbosity, StatusObject } from "@grpc/grpc-js"; +import { experimental, logVerbosity } from "@grpc/grpc-js"; import { Listener__Output } from '../generated/envoy/config/listener/v3/Listener'; import { RdsState } from "./rds-state"; -import { HandleResponseResult, RejectedResourceEntry, ResourcePair, Watcher, XdsStreamState } from "./xds-stream-state"; -import { HttpConnectionManager__Output } from '../generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpConnectionManager'; +import { BaseXdsStreamState, XdsStreamState } from "./xds-stream-state"; import { decodeSingleResource, HTTP_CONNECTION_MANGER_TYPE_URL_V2, HTTP_CONNECTION_MANGER_TYPE_URL_V3 } from '../resources'; import { getTopLevelFilterUrl, validateTopLevelFilter } from '../http-filter'; import { EXPERIMENTAL_FAULT_INJECTION } from '../environment'; -import { Any__Output } from '../generated/google/protobuf/Any'; const TRACER_NAME = 'xds_client'; @@ -34,69 +31,22 @@ function trace(text: string): void { const ROUTER_FILTER_URL = 'type.googleapis.com/envoy.extensions.filters.http.router.v3.Router'; -export class LdsState implements XdsStreamState { - versionInfo = ''; - nonce = ''; - - private watchers: Map[]> = new Map[]>(); - private latestResponses: Listener__Output[] = []; - private latestIsV2 = false; - - constructor(private rdsState: RdsState, private updateResourceNames: () => void) {} - - addWatcher(targetName: string, watcher: Watcher) { - trace('Adding RDS watcher for targetName ' + targetName); - let watchersEntry = this.watchers.get(targetName); - let addedServiceName = false; - if (watchersEntry === undefined) { - addedServiceName = true; - watchersEntry = []; - this.watchers.set(targetName, watchersEntry); - } - watchersEntry.push(watcher); - - /* If we have already received an update for the requested edsServiceName, - * immediately pass that update along to the watcher */ - const isV2 = this.latestIsV2; - for (const message of this.latestResponses) { - if (message.name === targetName) { - /* These updates normally occur asynchronously, so we ensure that - * the same happens here */ - process.nextTick(() => { - trace('Reporting existing RDS update for new watcher for targetName ' + targetName); - watcher.onValidUpdate(message, isV2); - }); - } - } - if (addedServiceName) { - this.updateResourceNames(); - } +export class LdsState extends BaseXdsStreamState implements XdsStreamState { + protected getResourceName(resource: Listener__Output): string { + return resource.name; } - - removeWatcher(targetName: string, watcher: Watcher): void { - trace('Removing RDS watcher for targetName ' + targetName); - const watchersEntry = this.watchers.get(targetName); - let removedServiceName = false; - if (watchersEntry !== undefined) { - const entryIndex = watchersEntry.indexOf(watcher); - if (entryIndex >= 0) { - watchersEntry.splice(entryIndex, 1); - } - if (watchersEntry.length === 0) { - removedServiceName = true; - this.watchers.delete(targetName); - } - } - if (removedServiceName) { - this.updateResourceNames(); - } + protected getProtocolName(): string { + return 'LDS'; + } + protected isStateOfTheWorld(): boolean { + return true; } - getResourceNames(): string[] { - return Array.from(this.watchers.keys()); + constructor(private rdsState: RdsState, updateResourceNames: () => void) { + super(updateResourceNames); } - private validateResponse(message: Listener__Output, isV2: boolean): boolean { + public validateResponse(message: Listener__Output, isV2: boolean): boolean { if ( !( message.api_listener?.api_listener && @@ -143,63 +93,4 @@ export class LdsState implements XdsStreamState { } return false; } - - private handleMissingNames(allTargetNames: Set): string[] { - const missingNames: string[] = []; - for (const [targetName, watcherList] of this.watchers.entries()) { - if (!allTargetNames.has(targetName)) { - missingNames.push(targetName); - for (const watcher of watcherList) { - watcher.onResourceDoesNotExist(); - } - } - } - return missingNames; - } - - handleResponses(responses: ResourcePair[], isV2: boolean): HandleResponseResult { - const validResponses: Listener__Output[] = []; - let result: HandleResponseResult = { - accepted: [], - rejected: [], - missing: [] - } - for (const {resource, raw} of responses) { - if (this.validateResponse(resource, isV2)) { - validResponses.push(resource); - result.accepted.push({ - name: resource.name, - raw: raw - }); - } else { - trace('LDS validation failed for message ' + JSON.stringify(resource)); - result.rejected.push({ - name: resource.name, - raw: raw, - error: `Listener validation failed for resource ${resource.name}` - }); - } - } - this.latestResponses = validResponses; - this.latestIsV2 = isV2; - const allTargetNames = new Set(); - for (const message of validResponses) { - allTargetNames.add(message.name); - const watchers = this.watchers.get(message.name) ?? []; - for (const watcher of watchers) { - watcher.onValidUpdate(message, isV2); - } - } - trace('Received LDS response with listener names [' + Array.from(allTargetNames) + ']'); - result.missing = this.handleMissingNames(allTargetNames); - return result; - } - - reportStreamError(status: StatusObject): void { - for (const watcherList of this.watchers.values()) { - for (const watcher of watcherList) { - watcher.onTransientError(status); - } - } - } } \ No newline at end of file diff --git a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts index bc1c4a818..77a84469b 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts @@ -15,20 +15,10 @@ * */ -import { experimental, logVerbosity, StatusObject } from "@grpc/grpc-js"; import { EXPERIMENTAL_FAULT_INJECTION } from "../environment"; import { RouteConfiguration__Output } from "../generated/envoy/config/route/v3/RouteConfiguration"; -import { Any__Output } from "../generated/google/protobuf/Any"; import { validateOverrideFilter } from "../http-filter"; -import { CdsLoadBalancingConfig } from "../load-balancer-cds"; -import { HandleResponseResult, RejectedResourceEntry, ResourcePair, Watcher, XdsStreamState } from "./xds-stream-state"; -import ServiceConfig = experimental.ServiceConfig; - -const TRACER_NAME = 'xds_client'; - -function trace(text: string): void { - experimental.trace(logVerbosity.DEBUG, TRACER_NAME, text); -} +import { BaseXdsStreamState, XdsStreamState } from "./xds-stream-state"; const SUPPORTED_PATH_SPECIFIERS = ['prefix', 'path', 'safe_regex']; const SUPPPORTED_HEADER_MATCH_SPECIFIERS = [ @@ -40,68 +30,16 @@ const SUPPPORTED_HEADER_MATCH_SPECIFIERS = [ 'suffix_match']; const SUPPORTED_CLUSTER_SPECIFIERS = ['cluster', 'weighted_clusters', 'cluster_header']; -export class RdsState implements XdsStreamState { - versionInfo = ''; - nonce = ''; - - private watchers: Map[]> = new Map[]>(); - private latestResponses: RouteConfiguration__Output[] = []; - private latestIsV2 = false; - - constructor(private updateResourceNames: () => void) {} - - addWatcher(routeConfigName: string, watcher: Watcher) { - trace('Adding RDS watcher for routeConfigName ' + routeConfigName); - let watchersEntry = this.watchers.get(routeConfigName); - let addedServiceName = false; - if (watchersEntry === undefined) { - addedServiceName = true; - watchersEntry = []; - this.watchers.set(routeConfigName, watchersEntry); - } - watchersEntry.push(watcher); - - /* If we have already received an update for the requested edsServiceName, - * immediately pass that update along to the watcher */ - const isV2 = this.latestIsV2; - for (const message of this.latestResponses) { - if (message.name === routeConfigName) { - /* These updates normally occur asynchronously, so we ensure that - * the same happens here */ - process.nextTick(() => { - trace('Reporting existing RDS update for new watcher for routeConfigName ' + routeConfigName); - watcher.onValidUpdate(message, isV2); - }); - } - } - if (addedServiceName) { - this.updateResourceNames(); - } +export class RdsState extends BaseXdsStreamState implements XdsStreamState { + protected isStateOfTheWorld(): boolean { + return false; } - - removeWatcher(routeConfigName: string, watcher: Watcher): void { - trace('Removing RDS watcher for routeConfigName ' + routeConfigName); - const watchersEntry = this.watchers.get(routeConfigName); - let removedServiceName = false; - if (watchersEntry !== undefined) { - const entryIndex = watchersEntry.indexOf(watcher); - if (entryIndex >= 0) { - watchersEntry.splice(entryIndex, 1); - } - if (watchersEntry.length === 0) { - removedServiceName = true; - this.watchers.delete(routeConfigName); - } - } - if (removedServiceName) { - this.updateResourceNames(); - } + protected getResourceName(resource: RouteConfiguration__Output): string { + return resource.name; } - - getResourceNames(): string[] { - return Array.from(this.watchers.keys()); + protected getProtocolName(): string { + return 'RDS'; } - validateResponse(message: RouteConfiguration__Output, isV2: boolean): boolean { // https://github.com/grpc/proposal/blob/master/A28-xds-traffic-splitting-and-routing.md#response-validation for (const virtualHost of message.virtual_hosts) { @@ -172,48 +110,4 @@ export class RdsState implements XdsStreamState { } return true; } - - handleResponses(responses: ResourcePair[], isV2: boolean): HandleResponseResult { - const validResponses: RouteConfiguration__Output[] = []; - let result: HandleResponseResult = { - accepted: [], - rejected: [], - missing: [] - } - for (const {resource, raw} of responses) { - if (this.validateResponse(resource, isV2)) { - validResponses.push(resource); - result.accepted.push({ - name: resource.name, - raw: raw}); - } else { - trace('RDS validation failed for message ' + JSON.stringify(resource)); - result.rejected.push({ - name: resource.name, - raw: raw, - error: `Route validation failed for resource ${resource.name}` - }); - } - } - this.latestResponses = validResponses; - this.latestIsV2 = isV2; - const allRouteConfigNames = new Set(); - for (const message of validResponses) { - allRouteConfigNames.add(message.name); - const watchers = this.watchers.get(message.name) ?? []; - for (const watcher of watchers) { - watcher.onValidUpdate(message, isV2); - } - } - trace('Received RDS response with route config names [' + Array.from(allRouteConfigNames) + ']'); - return result; - } - - reportStreamError(status: StatusObject): void { - for (const watcherList of this.watchers.values()) { - for (const watcher of watcherList) { - watcher.onTransientError(status); - } - } - } } \ No newline at end of file diff --git a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts index c8cbc41cf..2ff5130c4 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts @@ -15,9 +15,11 @@ * */ -import { StatusObject } from "@grpc/grpc-js"; +import { experimental, logVerbosity, StatusObject } from "@grpc/grpc-js"; import { Any__Output } from "../generated/google/protobuf/Any"; +const TRACER_NAME = 'xds_client'; + export interface Watcher { /* Including the isV2 flag here is a bit of a kludge. It would probably be * better for XdsStreamState#handleResponses to transform the protobuf @@ -63,4 +65,189 @@ export interface XdsStreamState { handleResponses(responses: ResourcePair[], isV2: boolean): HandleResponseResult; reportStreamError(status: StatusObject): void; + reportAdsStreamStart(): void; + + addWatcher(name: string, watcher: Watcher): void; + removeWatcher(resourceName: string, watcher: Watcher): void; +} + +interface SubscriptionEntry { + watchers: Watcher[]; + cachedResponse: ResponseType | null; + resourceTimer: NodeJS.Timer; +} + +const RESOURCE_TIMEOUT_MS = 15_000; + +export abstract class BaseXdsStreamState implements XdsStreamState { + versionInfo = ''; + nonce = ''; + + private subscriptions: Map> = new Map>(); + private latestIsV2 = false; + private isAdsStreamRunning = false; + + constructor(private updateResourceNames: () => void) {} + + protected trace(text: string) { + experimental.trace(logVerbosity.DEBUG, TRACER_NAME, this.getProtocolName() + ' | ' + text); + } + + private startResourceTimer(subscriptionEntry: SubscriptionEntry) { + clearTimeout(subscriptionEntry.resourceTimer); + subscriptionEntry.resourceTimer = setTimeout(() => { + for (const watcher of subscriptionEntry.watchers) { + watcher.onResourceDoesNotExist(); + } + }, RESOURCE_TIMEOUT_MS); + } + + addWatcher(name: string, watcher: Watcher): void { + this.trace('Adding watcher for name ' + name); + let subscriptionEntry = this.subscriptions.get(name); + let addedName = false; + if (subscriptionEntry === undefined) { + addedName = true; + subscriptionEntry = { + watchers: [], + cachedResponse: null, + resourceTimer: setTimeout(() => {}, 0) + }; + this.startResourceTimer(subscriptionEntry); + this.subscriptions.set(name, subscriptionEntry); + } + subscriptionEntry.watchers.push(watcher); + if (subscriptionEntry.cachedResponse !== null) { + const cachedResponse = subscriptionEntry.cachedResponse; + /* These updates normally occur asynchronously, so we ensure that + * the same happens here */ + process.nextTick(() => { + this.trace('Reporting existing update for new watcher for name ' + name); + watcher.onValidUpdate(cachedResponse, this.latestIsV2); + }); + } + if (addedName) { + this.updateResourceNames(); + } + } + removeWatcher(resourceName: string, watcher: Watcher): void { + this.trace('Removing watcher for name ' + resourceName); + const subscriptionEntry = this.subscriptions.get(resourceName); + if (subscriptionEntry !== undefined) { + const entryIndex = subscriptionEntry.watchers.indexOf(watcher); + if (entryIndex >= 0) { + subscriptionEntry.watchers.splice(entryIndex, 1); + } + if (subscriptionEntry.watchers.length === 0) { + clearTimeout(subscriptionEntry.resourceTimer); + this.subscriptions.delete(resourceName); + this.updateResourceNames(); + } + } + } + + getResourceNames(): string[] { + return Array.from(this.subscriptions.keys()); + } + handleResponses(responses: ResourcePair[], isV2: boolean): HandleResponseResult { + const validResponses: ResponseType[] = []; + let result: HandleResponseResult = { + accepted: [], + rejected: [], + missing: [] + } + for (const {resource, raw} of responses) { + const resourceName = this.getResourceName(resource); + if (this.validateResponse(resource, isV2)) { + validResponses.push(resource); + result.accepted.push({ + name: resourceName, + raw: raw}); + } else { + this.trace('Validation failed for message ' + JSON.stringify(resource)); + result.rejected.push({ + name: resourceName, + raw: raw, + error: `Validation failed for resource ${resourceName}` + }); + } + } + this.latestIsV2 = isV2; + const allResourceNames = new Set(); + for (const resource of validResponses) { + const resourceName = this.getResourceName(resource); + allResourceNames.add(resourceName); + const subscriptionEntry = this.subscriptions.get(resourceName); + if (subscriptionEntry) { + const watchers = subscriptionEntry.watchers; + for (const watcher of watchers) { + watcher.onValidUpdate(resource, isV2); + } + clearTimeout(subscriptionEntry.resourceTimer); + subscriptionEntry.cachedResponse = resource; + } + } + result.missing = this.handleMissingNames(allResourceNames); + this.trace('Received response with resource names [' + Array.from(allResourceNames) + ']'); + return result; + } + reportStreamError(status: StatusObject): void { + for (const subscriptionEntry of this.subscriptions.values()) { + for (const watcher of subscriptionEntry.watchers) { + watcher.onTransientError(status); + } + clearTimeout(subscriptionEntry.resourceTimer); + } + this.isAdsStreamRunning = false; + } + + reportAdsStreamStart() { + this.isAdsStreamRunning = true; + for (const subscriptionEntry of this.subscriptions.values()) { + if (subscriptionEntry.cachedResponse === null) { + this.startResourceTimer(subscriptionEntry); + } + } + } + + private handleMissingNames(allResponseNames: Set): string[] { + if (this.isStateOfTheWorld()) { + const missingNames: string[] = []; + for (const [resourceName, subscriptionEntry] of this.subscriptions.entries()) { + if (!allResponseNames.has(resourceName) && subscriptionEntry.cachedResponse !== null) { + this.trace('Reporting resource does not exist named ' + resourceName); + missingNames.push(resourceName); + for (const watcher of subscriptionEntry.watchers) { + watcher.onResourceDoesNotExist(); + } + } + } + return missingNames; + } else { + return []; + } + } + + /** + * Apply the validation rules for this resource type to this resource + * instance. + * This function is public so that the LDS validateResponse can call into + * the RDS validateResponse. + * @param resource The resource object sent by the xDS server + * @param isV2 If true, the resource is an xDS V2 resource instead of xDS V3 + */ + public abstract validateResponse(resource: ResponseType, isV2: boolean): boolean; + /** + * Get the name of a resource object. The name is some field of the object, so + * getting it depends on the specific type. + * @param resource + */ + protected abstract getResourceName(resource: ResponseType): string; + protected abstract getProtocolName(): string; + /** + * Indicates whether responses are "state of the world", i.e. that they + * contain all resources and that omitted previously-seen resources should + * be treated as removed. + */ + protected abstract isStateOfTheWorld(): boolean; } \ No newline at end of file From a041056e712975e8ded07d032512ee70063c8cb1 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 12 May 2022 17:19:46 -0700 Subject: [PATCH 241/450] Borrow Linux test job for xDS tests --- test/kokoro/linux.cfg | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/kokoro/linux.cfg b/test/kokoro/linux.cfg index 63f88d399..c13d03f35 100644 --- a/test/kokoro/linux.cfg +++ b/test/kokoro/linux.cfg @@ -14,10 +14,10 @@ # Config file for Kokoro (in protobuf text format) # Location of the continuous shell script in repository. -build_file: "grpc-node/test/kokoro.sh" -timeout_mins: 60 +build_file: "grpc-node/packages/grpc-js-xds/scripts/xds.sh" +timeout_mins: 360 action { define_artifacts { - regex: "github/grpc-node/reports/**/sponge_log.xml" + regex: "github/grpc/reports/**" } -} \ No newline at end of file +} From 65075e50a742c04d4544252f55a2f24471e45e31 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 12 May 2022 17:34:25 -0700 Subject: [PATCH 242/450] Only start the timer if the ADS stream is running --- packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts index 2ff5130c4..1d96728a2 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts @@ -113,7 +113,9 @@ export abstract class BaseXdsStreamState implements XdsStreamState cachedResponse: null, resourceTimer: setTimeout(() => {}, 0) }; - this.startResourceTimer(subscriptionEntry); + if (this.isAdsStreamRunning) { + this.startResourceTimer(subscriptionEntry); + } this.subscriptions.set(name, subscriptionEntry); } subscriptionEntry.watchers.push(watcher); From 9035327af12c989933946047f7125e4d636b6611 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 12 May 2022 17:38:28 -0700 Subject: [PATCH 243/450] Clear the nonce when the stream ends --- packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts index 1d96728a2..0b806f843 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts @@ -201,6 +201,7 @@ export abstract class BaseXdsStreamState implements XdsStreamState clearTimeout(subscriptionEntry.resourceTimer); } this.isAdsStreamRunning = false; + this.nonce = ''; } reportAdsStreamStart() { From 9502f5265de4c1ebc5aeb4bd4eb8c9c6ca829ded Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 13 May 2022 09:48:36 -0700 Subject: [PATCH 244/450] Revert "Borrow Linux test job for xDS tests" This reverts commit a041056e712975e8ded07d032512ee70063c8cb1. --- test/kokoro/linux.cfg | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/kokoro/linux.cfg b/test/kokoro/linux.cfg index c13d03f35..63f88d399 100644 --- a/test/kokoro/linux.cfg +++ b/test/kokoro/linux.cfg @@ -14,10 +14,10 @@ # 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 +build_file: "grpc-node/test/kokoro.sh" +timeout_mins: 60 action { define_artifacts { - regex: "github/grpc/reports/**" + regex: "github/grpc-node/reports/**/sponge_log.xml" } -} +} \ No newline at end of file From 0a0e13eedecedb31e91ad2d250c5fca6f31e46b6 Mon Sep 17 00:00:00 2001 From: Bart Slinger Date: Thu, 19 May 2022 23:45:11 +0200 Subject: [PATCH 245/450] handle disconnectListeners in reverse to allow listener removal in loop --- packages/grpc-js/src/subchannel.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 5d479a73a..eb7d0840c 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -646,7 +646,8 @@ export class Subchannel { this.transitionToState( [ConnectivityState.READY], ConnectivityState.TRANSIENT_FAILURE); - for (const listener of this.disconnectListeners) { + for (let i = this.disconnectListeners.length - 1; i >= 0; i--) { + const listener = this.disconnectListeners[i]; listener(); } } From 97717003f4dce64c64748517cff4a2077484ba04 Mon Sep 17 00:00:00 2001 From: Bart Slinger Date: Fri, 20 May 2022 08:27:01 +0200 Subject: [PATCH 246/450] grpc-js: Use Set instead of Array for disconnectListeners --- packages/grpc-js/src/subchannel.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index eb7d0840c..4d18ca9ca 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -108,7 +108,7 @@ export class Subchannel { * socket disconnects. Used for ending active calls with an UNAVAILABLE * status. */ - private disconnectListeners: Array<() => void> = []; + private disconnectListeners: Set<() => void> = new Set(); private backoffTimeout: BackoffTimeout; @@ -646,8 +646,7 @@ export class Subchannel { this.transitionToState( [ConnectivityState.READY], ConnectivityState.TRANSIENT_FAILURE); - for (let i = this.disconnectListeners.length - 1; i >= 0; i--) { - const listener = this.disconnectListeners[i]; + for (const listener of this.disconnectListeners.values()) { listener(); } } @@ -972,14 +971,11 @@ export class Subchannel { } addDisconnectListener(listener: () => void) { - this.disconnectListeners.push(listener); + this.disconnectListeners.add(listener); } removeDisconnectListener(listener: () => void) { - const listenerIndex = this.disconnectListeners.indexOf(listener); - if (listenerIndex > -1) { - this.disconnectListeners.splice(listenerIndex, 1); - } + this.disconnectListeners.delete(listener); } /** From aa97aa8a1c3e936be6fa4938f6467e044bc66ec6 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 23 May 2022 11:28:39 -0700 Subject: [PATCH 247/450] grpc-js-xds: Add support for k8s interop test framework --- packages/grpc-js-xds/interop/Dockerfile | 30 ++++ packages/grpc-js-xds/scripts/xds_k8s_lb.sh | 166 +++++++++++++++++++++ test/kokoro/xds_k8s_lb.cfg | 26 ++++ 3 files changed, 222 insertions(+) create mode 100644 packages/grpc-js-xds/interop/Dockerfile create mode 100755 packages/grpc-js-xds/scripts/xds_k8s_lb.sh create mode 100644 test/kokoro/xds_k8s_lb.cfg diff --git a/packages/grpc-js-xds/interop/Dockerfile b/packages/grpc-js-xds/interop/Dockerfile new file mode 100644 index 000000000..dbb4433b3 --- /dev/null +++ b/packages/grpc-js-xds/interop/Dockerfile @@ -0,0 +1,30 @@ +# 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. + +# Dockerfile for building the xDS interop client. To build the image, run the +# following command from grpc-node directory: +# docker build -t -f packages/grpc-js-xds/interop/Dockerfile . + +FROM node:16-alpine + +# Make a grpc-node directory and copy the repo into it. +WORKDIR /node/src/grpc-node +COPY . . + +WORKDIR /node/src/grpc-node/packages/grpc-js +RUN npm install +WORKDIR /node/src/grpc-node/packages/grpc-js-xds +RUN npm install + +ENTRYPOINT [ "node", "/node/src/grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client" ] diff --git a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh new file mode 100755 index 000000000..7672251d6 --- /dev/null +++ b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh @@ -0,0 +1,166 @@ +#!/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}/grpc/${TEST_DRIVER_BRANCH:-master}/tools/internal_ci/linux/grpc_xds_k8s_install_test_driver.sh" +## xDS test client Docker images +readonly SERVER_IMAGE_NAME="gcr.io/grpc-testing/xds-interop/java-server:v1.46.x" +readonly CLIENT_IMAGE_NAME="gcr.io/grpc-testing/xds-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 +# 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}" \ + . + + popd + + gcloud -q auth configure-docker + + docker push "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" +} + +####################################### +# 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}" + # 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=$(echo "$KOKORO_JOB_NAME" | sed -E 's|^grpc/node/([^/]+)/.*|\1|') \ + --xml_output_file="${TEST_XML_OUTPUT_DIR}/${test_name}/sponge_log.xml" +} + +####################################### +# 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")" + + # 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_SECURITY + activate_secondary_gke_cluster GKE_CLUSTER_PSM_SECURITY + + 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=("api_listener_test" "change_backend_service_test" "failover_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}" + if (( failed_tests > 0 )); then + exit 1 + fi +} + +main "$@" \ No newline at end of file diff --git a/test/kokoro/xds_k8s_lb.cfg b/test/kokoro/xds_k8s_lb.cfg new file mode 100644 index 000000000..17a3f3b3b --- /dev/null +++ b/test/kokoro/xds_k8s_lb.cfg @@ -0,0 +1,26 @@ +# 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. + +# 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" +timeout_mins: 180 +action { + define_artifacts { + regex: "artifacts/**/*sponge_log.xml" + regex: "artifacts/**/*sponge_log.log" + strip_prefix: "artifacts" + } +} \ No newline at end of file From ce169c22b483a27e776e003d7630b158bd0cc7f7 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 23 May 2022 15:59:01 -0700 Subject: [PATCH 248/450] Reduce docker image size with extra build step --- packages/grpc-js-xds/interop/Dockerfile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/interop/Dockerfile b/packages/grpc-js-xds/interop/Dockerfile index dbb4433b3..bc85d3b21 100644 --- a/packages/grpc-js-xds/interop/Dockerfile +++ b/packages/grpc-js-xds/interop/Dockerfile @@ -16,7 +16,7 @@ # following command from grpc-node directory: # docker build -t -f packages/grpc-js-xds/interop/Dockerfile . -FROM node:16-alpine +FROM node:16-alpine as build # Make a grpc-node directory and copy the repo into it. WORKDIR /node/src/grpc-node @@ -27,4 +27,9 @@ RUN npm install WORKDIR /node/src/grpc-node/packages/grpc-js-xds RUN npm install +FROM node:16-alpine +WORKDIR /node/src/grpc-node +COPY --from=build /node/src/grpc-node/packages/grpc-js ./packages/grpc-js/ +COPY --from=build /node/src/grpc-node/packages/grpc-js-xds ./packages/grpc-js-xds/ + ENTRYPOINT [ "node", "/node/src/grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client" ] From 30bf5a1bac096d4eebeb0b848ede389bff27e226 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 23 May 2022 16:19:07 -0700 Subject: [PATCH 249/450] Fix cluster references Co-authored-by: Sergii Tkachenko --- packages/grpc-js-xds/scripts/xds_k8s_lb.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh index 7672251d6..8ec1760a1 100755 --- a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh @@ -139,8 +139,8 @@ main() { 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_SECURITY - activate_secondary_gke_cluster GKE_CLUSTER_PSM_SECURITY + activate_gke_cluster GKE_CLUSTER_PSM_LB + activate_secondary_gke_cluster GKE_CLUSTER_PSM_LB set -x if [[ -n "${KOKORO_ARTIFACTS_DIR}" ]]; then From 55175ae8c281307e05f147987822aedf5b4d85ee Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 23 May 2022 16:21:27 -0700 Subject: [PATCH 250/450] Add missing newlines at EOF --- packages/grpc-js-xds/scripts/xds_k8s_lb.sh | 2 +- test/kokoro/xds_k8s_lb.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh index 8ec1760a1..9cf98d2fc 100755 --- a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh @@ -163,4 +163,4 @@ main() { fi } -main "$@" \ No newline at end of file +main "$@" diff --git a/test/kokoro/xds_k8s_lb.cfg b/test/kokoro/xds_k8s_lb.cfg index 17a3f3b3b..b9940cfdc 100644 --- a/test/kokoro/xds_k8s_lb.cfg +++ b/test/kokoro/xds_k8s_lb.cfg @@ -23,4 +23,4 @@ action { regex: "artifacts/**/*sponge_log.log" strip_prefix: "artifacts" } -} \ No newline at end of file +} From bbcf471c99512a178f74e9de7d9dcee363649507 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 23 May 2022 16:30:18 -0700 Subject: [PATCH 251/450] grpc-js: Specify 'types' option in tsconfig file --- packages/grpc-js/tsconfig.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/tsconfig.json b/packages/grpc-js/tsconfig.json index ba675db78..310b633c7 100644 --- a/packages/grpc-js/tsconfig.json +++ b/packages/grpc-js/tsconfig.json @@ -6,7 +6,8 @@ "target": "es2017", "module": "commonjs", "resolveJsonModule": true, - "incremental": true + "incremental": true, + "types": ["mocha"] }, "include": [ "src/**/*.ts", From 67cfbae7aac90c3e60320f72c14dc4ec2985cd14 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 23 May 2022 16:46:51 -0700 Subject: [PATCH 252/450] Use cd instead of WORKDIR in Dockerfile Co-authored-by: Sergii Tkachenko --- packages/grpc-js-xds/interop/Dockerfile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js-xds/interop/Dockerfile b/packages/grpc-js-xds/interop/Dockerfile index bc85d3b21..b18d02a4a 100644 --- a/packages/grpc-js-xds/interop/Dockerfile +++ b/packages/grpc-js-xds/interop/Dockerfile @@ -22,10 +22,8 @@ FROM node:16-alpine as build WORKDIR /node/src/grpc-node COPY . . -WORKDIR /node/src/grpc-node/packages/grpc-js -RUN npm install -WORKDIR /node/src/grpc-node/packages/grpc-js-xds -RUN npm install +RUN cd packages/grpc-js && npm install +RUN cd packages/grpc-js-xds && npm install FROM node:16-alpine WORKDIR /node/src/grpc-node From ad6d650408f4650c6e7c897c02ae4bf7bc3fddb1 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 24 May 2022 09:41:05 -0700 Subject: [PATCH 253/450] Revert "Use cd instead of WORKDIR in Dockerfile" --- packages/grpc-js-xds/interop/Dockerfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js-xds/interop/Dockerfile b/packages/grpc-js-xds/interop/Dockerfile index b18d02a4a..bc85d3b21 100644 --- a/packages/grpc-js-xds/interop/Dockerfile +++ b/packages/grpc-js-xds/interop/Dockerfile @@ -22,8 +22,10 @@ FROM node:16-alpine as build WORKDIR /node/src/grpc-node COPY . . -RUN cd packages/grpc-js && npm install -RUN cd packages/grpc-js-xds && npm install +WORKDIR /node/src/grpc-node/packages/grpc-js +RUN npm install +WORKDIR /node/src/grpc-node/packages/grpc-js-xds +RUN npm install FROM node:16-alpine WORKDIR /node/src/grpc-node From ee0c6bc9eaa80e43c82f44e40566b038cb49fd24 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 24 May 2022 10:35:55 -0700 Subject: [PATCH 254/450] Add baseline_test to test list --- packages/grpc-js-xds/scripts/xds_k8s_lb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh index 9cf98d2fc..efdde91e7 100755 --- a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh @@ -153,7 +153,7 @@ main() { # Run tests cd "${TEST_DRIVER_FULL_DIR}" local failed_tests=0 - test_suites=("api_listener_test" "change_backend_service_test" "failover_test" "remove_neg_test" "round_robin_test") + test_suites=("baseline_test" "api_listener_test" "change_backend_service_test" "failover_test" "remove_neg_test" "round_robin_test") for test in "${test_suites[@]}"; do run_test $test || (( failed_tests++ )) done From be749bf94f96a03ec5e3bf0aabed2566f5c79f31 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 24 May 2022 11:14:26 -0700 Subject: [PATCH 255/450] Update submodules in test script --- packages/grpc-js-xds/scripts/xds_k8s_lb.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh index efdde91e7..0ff34ac4b 100755 --- a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh @@ -135,6 +135,8 @@ main() { local script_dir script_dir="$(dirname "$0")" + 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}")" From e61c8f9ecd2c20a1baaeaf284aa813bc8e66473c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 24 May 2022 13:11:41 -0700 Subject: [PATCH 256/450] Change directory before submodules update --- packages/grpc-js-xds/scripts/xds_k8s_lb.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh index 0ff34ac4b..b4c9f81a2 100755 --- a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh @@ -135,6 +135,8 @@ main() { local script_dir script_dir="$(dirname "$0")" + cd "${script_dir}" + git submodule update --init --recursive # Source the test driver from the master branch. From e94bd36bf15d75fb3e49f52eeddadc371702b90e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Conall=20=C3=93=20Cofaigh?= Date: Mon, 30 May 2022 13:54:05 +0100 Subject: [PATCH 257/450] bump protobufjs to "^6.11.3" --- packages/proto-loader/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index 759e54713..53b6e829d 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -48,7 +48,7 @@ "@types/long": "^4.0.1", "lodash.camelcase": "^4.3.0", "long": "^4.0.0", - "protobufjs": "^6.10.0", + "protobufjs": "^6.11.3", "yargs": "^16.2.0" }, "devDependencies": { From b78db9d2225a391e23a0e6cefd2b85f919e708f1 Mon Sep 17 00:00:00 2001 From: Andrew Matheny Date: Wed, 1 Jun 2022 12:33:31 -0400 Subject: [PATCH 258/450] Propagate callEnd events --- packages/grpc-js/src/server-call.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index 315c9d9aa..725199e3a 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -726,6 +726,8 @@ export class Http2ServerCallStream< call.cancelled = true; call.emit('cancelled', reason); }); + + this.once('callEnd', (status) => call.emit('callEnd', status)); } setupReadable( From d846cf51272f2ed03c1dd8b845536fa7a901f396 Mon Sep 17 00:00:00 2001 From: Andrew Matheny Date: Wed, 1 Jun 2022 12:34:11 -0400 Subject: [PATCH 259/450] Expose http path in call --- packages/grpc-js/src/server-call.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index 725199e3a..1f7f3eb04 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -80,6 +80,7 @@ export type ServerSurfaceCall = { getPeer(): string; sendMetadata(responseMetadata: Metadata): void; getDeadline(): Deadline; + getPath(): string; } & EventEmitter; export type ServerUnaryCall = ServerSurfaceCall & { @@ -127,6 +128,10 @@ export class ServerUnaryCallImpl getDeadline(): Deadline { return this.call.getDeadline(); } + + getPath(): string { + return this.call.getPath(); + } } export class ServerReadableStreamImpl @@ -165,6 +170,10 @@ export class ServerReadableStreamImpl getDeadline(): Deadline { return this.call.getDeadline(); } + + getPath(): string { + return this.call.getPath(); + } } export class ServerWritableStreamImpl @@ -202,6 +211,10 @@ export class ServerWritableStreamImpl return this.call.getDeadline(); } + getPath(): string { + return this.call.getPath(); + } + _write( chunk: ResponseType, encoding: string, @@ -279,6 +292,10 @@ export class ServerDuplexStreamImpl return this.call.getDeadline(); } + getPath(): string { + return this.call.getPath(); + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any end(metadata?: any) { if (metadata) { @@ -901,6 +918,10 @@ export class Http2ServerCallStream< getDeadline(): Deadline { return this.deadline; } + + getPath(): string { + return this.handler.path; + } } /* eslint-disable @typescript-eslint/no-explicit-any */ From 475559f976088deae1c3d8a512fd9c57425ddba3 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 6 Jun 2022 14:08:13 -0700 Subject: [PATCH 260/450] proto-loader: Increment version to 0.6.13 --- packages/proto-loader/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index 53b6e829d..65639c501 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/proto-loader", - "version": "0.6.12", + "version": "0.6.13", "author": "Google Inc.", "contributors": [ { From 07b73ad129e0368dfa95fab531d45ab754b9844b Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 7 Jun 2022 11:07:47 -0700 Subject: [PATCH 261/450] grpc-js: Add a test for compressing large messages --- .../grpc-js/test/fixtures/test_service.proto | 1 + packages/grpc-js/test/generated/Response.ts | 2 ++ .../grpc-js/test/generated/TestService.ts | 32 +++++++++---------- packages/grpc-js/test/test-server.ts | 16 +++++++++- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/packages/grpc-js/test/fixtures/test_service.proto b/packages/grpc-js/test/fixtures/test_service.proto index f99393d14..64ce0d378 100644 --- a/packages/grpc-js/test/fixtures/test_service.proto +++ b/packages/grpc-js/test/fixtures/test_service.proto @@ -25,6 +25,7 @@ message Request { message Response { int32 count = 1; + string message = 2; } service TestService { diff --git a/packages/grpc-js/test/generated/Response.ts b/packages/grpc-js/test/generated/Response.ts index 217fc75e8..465ab7203 100644 --- a/packages/grpc-js/test/generated/Response.ts +++ b/packages/grpc-js/test/generated/Response.ts @@ -3,8 +3,10 @@ export interface Response { 'count'?: (number); + 'message'?: (string); } export interface Response__Output { 'count': (number); + 'message': (string); } diff --git a/packages/grpc-js/test/generated/TestService.ts b/packages/grpc-js/test/generated/TestService.ts index 75bff33e4..e477c99b5 100644 --- a/packages/grpc-js/test/generated/TestService.ts +++ b/packages/grpc-js/test/generated/TestService.ts @@ -11,28 +11,28 @@ export interface TestServiceClient extends grpc.Client { bidiStream(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_Request, _Response__Output>; bidiStream(options?: grpc.CallOptions): grpc.ClientDuplexStream<_Request, _Response__Output>; - ClientStream(metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientWritableStream<_Request>; - ClientStream(metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientWritableStream<_Request>; - ClientStream(options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientWritableStream<_Request>; - ClientStream(callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientWritableStream<_Request>; - clientStream(metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientWritableStream<_Request>; - clientStream(metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientWritableStream<_Request>; - clientStream(options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientWritableStream<_Request>; - clientStream(callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientWritableStream<_Request>; + ClientStream(metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_Response__Output>): grpc.ClientWritableStream<_Request>; + ClientStream(metadata: grpc.Metadata, callback: grpc.requestCallback<_Response__Output>): grpc.ClientWritableStream<_Request>; + ClientStream(options: grpc.CallOptions, callback: grpc.requestCallback<_Response__Output>): grpc.ClientWritableStream<_Request>; + ClientStream(callback: grpc.requestCallback<_Response__Output>): grpc.ClientWritableStream<_Request>; + clientStream(metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_Response__Output>): grpc.ClientWritableStream<_Request>; + clientStream(metadata: grpc.Metadata, callback: grpc.requestCallback<_Response__Output>): grpc.ClientWritableStream<_Request>; + clientStream(options: grpc.CallOptions, callback: grpc.requestCallback<_Response__Output>): grpc.ClientWritableStream<_Request>; + clientStream(callback: grpc.requestCallback<_Response__Output>): grpc.ClientWritableStream<_Request>; ServerStream(argument: _Request, metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientReadableStream<_Response__Output>; ServerStream(argument: _Request, options?: grpc.CallOptions): grpc.ClientReadableStream<_Response__Output>; serverStream(argument: _Request, metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientReadableStream<_Response__Output>; serverStream(argument: _Request, options?: grpc.CallOptions): grpc.ClientReadableStream<_Response__Output>; - Unary(argument: _Request, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientUnaryCall; - Unary(argument: _Request, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientUnaryCall; - Unary(argument: _Request, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientUnaryCall; - Unary(argument: _Request, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientUnaryCall; - unary(argument: _Request, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientUnaryCall; - unary(argument: _Request, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientUnaryCall; - unary(argument: _Request, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientUnaryCall; - unary(argument: _Request, callback: (error?: grpc.ServiceError, result?: _Response__Output) => void): grpc.ClientUnaryCall; + Unary(argument: _Request, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_Response__Output>): grpc.ClientUnaryCall; + Unary(argument: _Request, metadata: grpc.Metadata, callback: grpc.requestCallback<_Response__Output>): grpc.ClientUnaryCall; + Unary(argument: _Request, options: grpc.CallOptions, callback: grpc.requestCallback<_Response__Output>): grpc.ClientUnaryCall; + Unary(argument: _Request, callback: grpc.requestCallback<_Response__Output>): grpc.ClientUnaryCall; + unary(argument: _Request, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_Response__Output>): grpc.ClientUnaryCall; + unary(argument: _Request, metadata: grpc.Metadata, callback: grpc.requestCallback<_Response__Output>): grpc.ClientUnaryCall; + unary(argument: _Request, options: grpc.CallOptions, callback: grpc.requestCallback<_Response__Output>): grpc.ClientUnaryCall; + unary(argument: _Request, callback: grpc.requestCallback<_Response__Output>): grpc.ClientUnaryCall; } diff --git a/packages/grpc-js/test/test-server.ts b/packages/grpc-js/test/test-server.ts index 2513b1fe2..0c0ba168e 100644 --- a/packages/grpc-js/test/test-server.ts +++ b/packages/grpc-js/test/test-server.ts @@ -623,7 +623,7 @@ describe('Generic client and server', () => { describe('Compressed requests', () => { const testServiceHandlers: TestServiceHandlers = { Unary(call, callback) { - callback(null, { count: 500000 }); + callback(null, { count: 500000, message: call.request.message }); }, ClientStream(call, callback) { @@ -847,6 +847,20 @@ describe('Compressed requests', () => { }) }); }); + + it('Should handle large messages', done => { + let longMessage = ''; + for (let i = 0; i < 400000; i++) { + const letter = 'abcdefghijklmnopqrstuvwxyz'[Math.floor(Math.random() * 26)]; + longMessage = longMessage + letter.repeat(10); + } + + client.unary({message: longMessage}, (err, response) => { + assert.ifError(err); + assert.strictEqual(response?.message, longMessage); + done(); + }) + }) /* As of Node 16, Writable and Duplex streams validate the encoding * argument to write, and the flags values we are passing there are not From 0c543aa2b27f9ea2890bbe3d7cb88c696412225d Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 15 Jun 2022 10:09:53 -0700 Subject: [PATCH 262/450] xDS k8s interop script: publish version-tagged docker images --- packages/grpc-js-xds/scripts/xds_k8s_lb.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh index b4c9f81a2..0d333b7ee 100755 --- a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh @@ -45,6 +45,11 @@ build_test_app_docker_images() { -t "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \ . + if [[ -n $KOKORO_JOB_NAME ]]; then + branch_name=$(echo "$KOKORO_JOB_NAME" | sed -E 's|^grpc/node/([^/]+)/.*|\1|') + tag_and_push_docker_image "${CLIENT_IMAGE_NAME}" "${GIT_COMMIT}" "${branch_name}" + fi + popd gcloud -q auth configure-docker From e4435a50f6c857dfd8edbade4856c172b8856617 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 21 Jun 2022 15:51:03 -0700 Subject: [PATCH 263/450] Use new TESTING_VERSION variable --- packages/grpc-js-xds/scripts/xds_k8s_lb.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh index 0d333b7ee..58a951376 100755 --- a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh @@ -45,9 +45,8 @@ build_test_app_docker_images() { -t "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \ . - if [[ -n $KOKORO_JOB_NAME ]]; then - branch_name=$(echo "$KOKORO_JOB_NAME" | sed -E 's|^grpc/node/([^/]+)/.*|\1|') - tag_and_push_docker_image "${CLIENT_IMAGE_NAME}" "${GIT_COMMIT}" "${branch_name}" + if is_version_branch "${TESTING_VERSION}"; then + tag_and_push_docker_image "${CLIENT_IMAGE_NAME}" "${GIT_COMMIT}" "${TESTING_VERSION}" fi popd @@ -111,7 +110,7 @@ run_test() { --secondary_kube_context="${SECONDARY_KUBE_CONTEXT}" \ --client_image="${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \ --server_image="${SERVER_IMAGE_NAME}" \ - --testing_version=$(echo "$KOKORO_JOB_NAME" | sed -E 's|^grpc/node/([^/]+)/.*|\1|') \ + --testing_version="${TESTING_VERSION}" \ --xml_output_file="${TEST_XML_OUTPUT_DIR}/${test_name}/sponge_log.xml" } From 92cf5df8d57431a6eca94a6bec057363b29a8182 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 23 Jun 2022 14:33:15 -0700 Subject: [PATCH 264/450] Add xDS k8s url_map test script --- .../grpc-js-xds/scripts/xds_k8s_url_map.sh | 152 ++++++++++++++++++ test/kokoro/xds_k8s_url_map.cfg | 26 +++ 2 files changed, 178 insertions(+) create mode 100644 packages/grpc-js-xds/scripts/xds_k8s_url_map.sh create mode 100644 test/kokoro/xds_k8s_url_map.cfg diff --git a/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh b/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh new file mode 100644 index 000000000..ca33cf0d2 --- /dev/null +++ b/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh @@ -0,0 +1,152 @@ +#!/usr/bin/env bash +# Copyright 2021 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}/grpc/${TEST_DRIVER_BRANCH:-master}/tools/internal_ci/linux/grpc_xds_k8s_install_test_driver.sh" +## xDS test client Docker images +readonly CLIENT_IMAGE_NAME="gcr.io/grpc-testing/xds-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 +# 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 src/python/grpcio_tests/tests_py3_only/interop/Dockerfile.client \ + -t "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \ + . + + popd + + gcloud -q auth configure-docker + + docker push "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" +} + +####################################### +# 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}" + set -x + python3 -m "tests.${test_name}" \ + --flagfile="${TEST_DRIVER_FLAGFILE}" \ + --kube_context="${KUBE_CONTEXT}" \ + --client_image="${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \ + --testing_version="${TESTING_VERSION}" \ + --xml_output_file="${TEST_XML_OUTPUT_DIR}/${test_name}/sponge_log.xml" \ + --flagfile="config/url-map.cfg" + set +x +} + +####################################### +# 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")" + + # 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 +} + +main "$@" diff --git a/test/kokoro/xds_k8s_url_map.cfg b/test/kokoro/xds_k8s_url_map.cfg new file mode 100644 index 000000000..dd4cce76d --- /dev/null +++ b/test/kokoro/xds_k8s_url_map.cfg @@ -0,0 +1,26 @@ +# 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. + +# 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" +timeout_mins: 180 +action { + define_artifacts { + regex: "artifacts/**/*sponge_log.xml" + regex: "artifacts/**/*sponge_log.log" + strip_prefix: "artifacts" + } +} From 47461134fb1a282517e8c2717f3e98c26488f229 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 23 Jun 2022 15:28:22 -0700 Subject: [PATCH 265/450] Update copyright date --- packages/grpc-js-xds/scripts/xds_k8s_url_map.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ca33cf0d2..901938ad2 100644 --- a/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Copyright 2021 gRPC authors. +# 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. From 1ad6a58059b6637a408b836d8ad591135e859d3d Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 24 Jun 2022 10:20:01 -0700 Subject: [PATCH 266/450] xDS k8s tests: fix a line in the url_map test script The line copied from the Python script was hardcoded and not handled by a variable, so I did not change it on the first pass. --- packages/grpc-js-xds/scripts/xds_k8s_url_map.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 901938ad2..bf2d4df67 100644 --- a/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh @@ -40,7 +40,7 @@ build_test_app_docker_images() { pushd "${SRC_DIR}" docker build \ - -f src/python/grpcio_tests/tests_py3_only/interop/Dockerfile.client \ + -f ${BUILD_APP_PATH} \ -t "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \ . From 5a039aa90b743919782cd64d349830ce46162f82 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 24 Jun 2022 15:29:52 -0700 Subject: [PATCH 267/450] Use quotation marks for variable substitution Co-authored-by: Sergii Tkachenko --- packages/grpc-js-xds/scripts/xds_k8s_url_map.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 bf2d4df67..8b07b655e 100644 --- a/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh @@ -40,7 +40,7 @@ build_test_app_docker_images() { pushd "${SRC_DIR}" docker build \ - -f ${BUILD_APP_PATH} \ + -f "${BUILD_APP_PATH}" \ -t "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \ . From 4db0cd2ac995efe08185f6b825b2aa641441dc57 Mon Sep 17 00:00:00 2001 From: Sergii Tkachenko Date: Fri, 24 Jun 2022 16:08:59 -0700 Subject: [PATCH 268/450] xDS k8s tests: fix docker auth error in the build scripts Docker auth needed to be done before pushing thats to the GCR. Also add missing versioned image tagging to xds_k8s_url_map.sh. --- packages/grpc-js-xds/scripts/xds_k8s_lb.sh | 8 +++----- packages/grpc-js-xds/scripts/xds_k8s_url_map.sh | 8 +++++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh index 58a951376..ca300f0c2 100755 --- a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh @@ -31,6 +31,7 @@ readonly LANGUAGE_NAME="Node" # 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: @@ -45,15 +46,12 @@ build_test_app_docker_images() { -t "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \ . + gcloud -q auth configure-docker + 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 - - gcloud -q auth configure-docker - - docker push "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" } ####################################### 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 901938ad2..a865e4e5b 100644 --- a/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh @@ -30,6 +30,7 @@ readonly LANGUAGE_NAME="Node" # 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: @@ -44,11 +45,12 @@ build_test_app_docker_images() { -t "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \ . - popd - gcloud -q auth configure-docker - 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 } ####################################### From 1463ffa42ed2d5de7c23c772684b944a60c5c90c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 28 Jun 2022 14:05:29 -0700 Subject: [PATCH 269/450] Backport xDS k8s test scripts to the v1.6.x branch --- packages/grpc-js-xds/scripts/xds_k8s_lb.sh | 172 ++++++++++++++++++ .../grpc-js-xds/scripts/xds_k8s_url_map.sh | 154 ++++++++++++++++ test/kokoro/xds_k8s_lb.cfg | 26 +++ test/kokoro/xds_k8s_url_map.cfg | 26 +++ 4 files changed, 378 insertions(+) create mode 100755 packages/grpc-js-xds/scripts/xds_k8s_lb.sh create mode 100644 packages/grpc-js-xds/scripts/xds_k8s_url_map.sh create mode 100644 test/kokoro/xds_k8s_lb.cfg create mode 100644 test/kokoro/xds_k8s_url_map.cfg diff --git a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh new file mode 100755 index 000000000..ca300f0c2 --- /dev/null +++ b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh @@ -0,0 +1,172 @@ +#!/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}/grpc/${TEST_DRIVER_BRANCH:-master}/tools/internal_ci/linux/grpc_xds_k8s_install_test_driver.sh" +## xDS test client Docker images +readonly SERVER_IMAGE_NAME="gcr.io/grpc-testing/xds-interop/java-server:v1.46.x" +readonly CLIENT_IMAGE_NAME="gcr.io/grpc-testing/xds-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 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}" + # 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}" \ + --xml_output_file="${TEST_XML_OUTPUT_DIR}/${test_name}/sponge_log.xml" +} + +####################################### +# 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=("baseline_test" "api_listener_test" "change_backend_service_test" "failover_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}" + if (( failed_tests > 0 )); then + exit 1 + fi +} + +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 new file mode 100644 index 000000000..4371f235c --- /dev/null +++ b/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh @@ -0,0 +1,154 @@ +#!/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}/grpc/${TEST_DRIVER_BRANCH:-master}/tools/internal_ci/linux/grpc_xds_k8s_install_test_driver.sh" +## xDS test client Docker images +readonly CLIENT_IMAGE_NAME="gcr.io/grpc-testing/xds-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 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}" + set -x + python3 -m "tests.${test_name}" \ + --flagfile="${TEST_DRIVER_FLAGFILE}" \ + --kube_context="${KUBE_CONTEXT}" \ + --client_image="${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \ + --testing_version="${TESTING_VERSION}" \ + --xml_output_file="${TEST_XML_OUTPUT_DIR}/${test_name}/sponge_log.xml" \ + --flagfile="config/url-map.cfg" + set +x +} + +####################################### +# 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")" + + # 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 +} + +main "$@" diff --git a/test/kokoro/xds_k8s_lb.cfg b/test/kokoro/xds_k8s_lb.cfg new file mode 100644 index 000000000..b9940cfdc --- /dev/null +++ b/test/kokoro/xds_k8s_lb.cfg @@ -0,0 +1,26 @@ +# 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. + +# 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" +timeout_mins: 180 +action { + define_artifacts { + regex: "artifacts/**/*sponge_log.xml" + regex: "artifacts/**/*sponge_log.log" + strip_prefix: "artifacts" + } +} diff --git a/test/kokoro/xds_k8s_url_map.cfg b/test/kokoro/xds_k8s_url_map.cfg new file mode 100644 index 000000000..dd4cce76d --- /dev/null +++ b/test/kokoro/xds_k8s_url_map.cfg @@ -0,0 +1,26 @@ +# 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. + +# 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" +timeout_mins: 180 +action { + define_artifacts { + regex: "artifacts/**/*sponge_log.xml" + regex: "artifacts/**/*sponge_log.log" + strip_prefix: "artifacts" + } +} From 15a962aab629bf7c3c001407f4244279fc72c6e3 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 7 Jul 2022 10:37:15 -0700 Subject: [PATCH 270/450] Enable xDS tracing in k8s framework tests --- packages/grpc-js-xds/interop/Dockerfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/grpc-js-xds/interop/Dockerfile b/packages/grpc-js-xds/interop/Dockerfile index bc85d3b21..e8a0a98cb 100644 --- a/packages/grpc-js-xds/interop/Dockerfile +++ b/packages/grpc-js-xds/interop/Dockerfile @@ -32,4 +32,7 @@ WORKDIR /node/src/grpc-node COPY --from=build /node/src/grpc-node/packages/grpc-js ./packages/grpc-js/ COPY --from=build /node/src/grpc-node/packages/grpc-js-xds ./packages/grpc-js-xds/ +ENV GRPC_VERBOSITY="DEBUG" +ENV GRPC_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weighted_target,round_robin,resolving_load_balancer,subchannel,keepalive,dns_resolver,fault_injection,http_filter,csds + ENTRYPOINT [ "node", "/node/src/grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client" ] From c6d7d2aa033b2ebd88bd010552124c47e9af79e8 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 7 Jul 2022 14:34:20 -0700 Subject: [PATCH 271/450] Backport xDS k8s interop docker image to version branch --- packages/grpc-js-xds/interop/Dockerfile | 38 +++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 packages/grpc-js-xds/interop/Dockerfile diff --git a/packages/grpc-js-xds/interop/Dockerfile b/packages/grpc-js-xds/interop/Dockerfile new file mode 100644 index 000000000..e8a0a98cb --- /dev/null +++ b/packages/grpc-js-xds/interop/Dockerfile @@ -0,0 +1,38 @@ +# 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. + +# Dockerfile for building the xDS interop client. To build the image, run the +# following command from grpc-node directory: +# docker build -t -f packages/grpc-js-xds/interop/Dockerfile . + +FROM node:16-alpine as build + +# Make a grpc-node directory and copy the repo into it. +WORKDIR /node/src/grpc-node +COPY . . + +WORKDIR /node/src/grpc-node/packages/grpc-js +RUN npm install +WORKDIR /node/src/grpc-node/packages/grpc-js-xds +RUN npm install + +FROM node:16-alpine +WORKDIR /node/src/grpc-node +COPY --from=build /node/src/grpc-node/packages/grpc-js ./packages/grpc-js/ +COPY --from=build /node/src/grpc-node/packages/grpc-js-xds ./packages/grpc-js-xds/ + +ENV GRPC_VERBOSITY="DEBUG" +ENV GRPC_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weighted_target,round_robin,resolving_load_balancer,subchannel,keepalive,dns_resolver,fault_injection,http_filter,csds + +ENTRYPOINT [ "node", "/node/src/grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client" ] From 914ccdc19d52b22e7ea5fc5e8250984a68165201 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 8 Jul 2022 10:05:07 -0700 Subject: [PATCH 272/450] Clone submodules in xds k8s url map script --- packages/grpc-js-xds/scripts/xds_k8s_url_map.sh | 4 ++++ 1 file changed, 4 insertions(+) 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 4371f235c..c29d0c0a5 100644 --- a/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh @@ -133,6 +133,10 @@ 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}")" From 6641494e029e648206b42e218a4a8d9536955f8b Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 8 Jul 2022 10:05:07 -0700 Subject: [PATCH 273/450] Clone submodules in xds k8s url map script --- packages/grpc-js-xds/scripts/xds_k8s_url_map.sh | 4 ++++ 1 file changed, 4 insertions(+) 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 4371f235c..c29d0c0a5 100644 --- a/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh @@ -133,6 +133,10 @@ 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}")" From 7b4704cc921cddf7c6084c69704ac940c4450b98 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 11 Jul 2022 11:32:04 -0700 Subject: [PATCH 274/450] proto-loader: Update protobufjs dependency to 7.x --- packages/proto-loader/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index 65639c501..07e66c9fe 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/proto-loader", - "version": "0.6.13", + "version": "0.7.0", "author": "Google Inc.", "contributors": [ { @@ -48,7 +48,7 @@ "@types/long": "^4.0.1", "lodash.camelcase": "^4.3.0", "long": "^4.0.0", - "protobufjs": "^6.11.3", + "protobufjs": "^7.0.0", "yargs": "^16.2.0" }, "devDependencies": { From 27b7bb8928118292892dd5727089be32b325fed3 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 19 Jul 2022 10:52:02 -0700 Subject: [PATCH 275/450] grpc-js: Update proto-loader dependency to ^0.7.0 --- 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 723b108ff..5fae717a4 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -58,7 +58,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.6.4", + "@grpc/proto-loader": "^0.7.0", "@types/node": ">=12.12.47" }, "files": [ From 50c58238ff62b5e8d94fd4e795ff42ebc76d08a4 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 20 Jul 2022 15:22:53 -0700 Subject: [PATCH 276/450] grpc-js: Update version to 1.6.8 --- 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 5fae717a4..3ceaefebe 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.6.7", + "version": "1.6.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", From 3ab4ee34678d4e026013c55b2821da0553e737ea Mon Sep 17 00:00:00 2001 From: Christophe Diederichs Date: Thu, 21 Jul 2022 17:48:28 +0100 Subject: [PATCH 277/450] include .map files in proto-loader npm package --- packages/proto-loader/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index 07e66c9fe..550346d04 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -38,7 +38,7 @@ "files": [ "LICENSE", "build/src/*.d.ts", - "build/src/*.js", + "build/src/*.{js,js.map}", "build/bin/*.js" ], "bin": { From 924fb9a3297febe3cceb8000822b80b8f5ffcee1 Mon Sep 17 00:00:00 2001 From: Christophe Diederichs Date: Fri, 22 Jul 2022 09:23:22 +0100 Subject: [PATCH 278/450] include proto-loader-gen-types.js.map in release --- packages/proto-loader/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index 550346d04..c306fe9b6 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -39,7 +39,7 @@ "LICENSE", "build/src/*.d.ts", "build/src/*.{js,js.map}", - "build/bin/*.js" + "build/bin/*.{js,js.map}" ], "bin": { "proto-loader-gen-types": "./build/bin/proto-loader-gen-types.js" From fbf7944646b4286b97a93c15274180ab5ac29b6c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 22 Jul 2022 12:58:22 -0700 Subject: [PATCH 279/450] grpc-js: Outlier detection: Fix standard deviation calculation --- packages/grpc-js/src/load-balancer-outlier-detection.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index 2c231c406..dde618b73 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -430,11 +430,12 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { // Step 2 const successRateMean = successRates.reduce((a, b) => a + b) / successRates.length; - let successRateVariance = 0; + let successRateDeviationSum = 0; for (const rate of successRates) { const deviation = rate - successRateMean; - successRateVariance += deviation * deviation; + successRateDeviationSum += deviation * deviation; } + const successRateVariance = successRateDeviationSum / successRates.length; const successRateStdev = Math.sqrt(successRateVariance); const ejectionThreshold = successRateMean - successRateStdev * (successRateConfig.stdev_factor / 1000); From 90e8886d988bd5348c994bfb5d29a88df6a84782 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 2 Aug 2022 11:02:02 -0700 Subject: [PATCH 280/450] grpc-js: Add outlier detection tracing and enable it in interop tests --- packages/grpc-js-xds/interop/Dockerfile | 2 +- .../src/load-balancer-outlier-detection.ts | 31 ++++++++++++++++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/packages/grpc-js-xds/interop/Dockerfile b/packages/grpc-js-xds/interop/Dockerfile index e8a0a98cb..b93e309d7 100644 --- a/packages/grpc-js-xds/interop/Dockerfile +++ b/packages/grpc-js-xds/interop/Dockerfile @@ -33,6 +33,6 @@ COPY --from=build /node/src/grpc-node/packages/grpc-js ./packages/grpc-js/ COPY --from=build /node/src/grpc-node/packages/grpc-js-xds ./packages/grpc-js-xds/ ENV GRPC_VERBOSITY="DEBUG" -ENV GRPC_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weighted_target,round_robin,resolving_load_balancer,subchannel,keepalive,dns_resolver,fault_injection,http_filter,csds +ENV GRPC_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weighted_target,round_robin,resolving_load_balancer,subchannel,keepalive,dns_resolver,fault_injection,http_filter,csds,outlier_detection ENTRYPOINT [ "node", "/node/src/grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client" ] diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index dde618b73..e9793beab 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -18,7 +18,7 @@ import { ChannelOptions, connectivityState, StatusObject } from "."; import { Call } from "./call-stream"; import { ConnectivityState } from "./connectivity-state"; -import { Status } from "./constants"; +import { LogVerbosity, Status } from "./constants"; import { durationToMs, isDuration, msToDuration } from "./duration"; import { ChannelControlHelper, createChildChannelControlHelper, registerLoadBalancerType } from "./experimental"; import { BaseFilter, Filter, FilterFactory } from "./filter"; @@ -28,7 +28,13 @@ import { PickArgs, Picker, PickResult, PickResultType, QueuePicker, UnavailableP import { Subchannel } from "./subchannel"; import { SubchannelAddress, subchannelAddressToString } from "./subchannel-address"; import { BaseSubchannelWrapper, ConnectivityStateListener, SubchannelInterface } from "./subchannel-interface"; +import * as logging from './logging'; +const TRACER_NAME = 'outlier_detection'; + +function trace(text: string): void { + logging.trace(LogVerbosity.DEBUG, TRACER_NAME, text); +} const TYPE_NAME = 'outlier_detection'; @@ -412,6 +418,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { if (!successRateConfig) { return; } + trace('Running success rate check'); // Step 1 const targetRequestVolume = successRateConfig.request_volume; let addresesWithTargetVolume = 0; @@ -424,6 +431,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { successRates.push(successes/(successes + failures)); } } + trace('Found ' + addresesWithTargetVolume + ' success rate candidates; currentEjectionPercent=' + this.getCurrentEjectionPercent() + ' successRates=[' + successRates + ']'); if (addresesWithTargetVolume < successRateConfig.minimum_hosts) { return; } @@ -438,9 +446,10 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { const successRateVariance = successRateDeviationSum / successRates.length; const successRateStdev = Math.sqrt(successRateVariance); const ejectionThreshold = successRateMean - successRateStdev * (successRateConfig.stdev_factor / 1000); + trace('stdev=' + successRateStdev + ' ejectionThreshold=' + ejectionThreshold); // Step 3 - for (const mapEntry of this.addressMap.values()) { + for (const [address, mapEntry] of this.addressMap.entries()) { // Step 3.i if (this.getCurrentEjectionPercent() > this.latestConfig.getMaxEjectionPercent()) { break; @@ -453,9 +462,12 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { } // Step 3.iii const successRate = successes / (successes + failures); + trace('Checking candidate ' + address + ' successRate=' + successRate); if (successRate < ejectionThreshold) { const randomNumber = Math.random() * 100; + trace('Candidate ' + address + ' randomNumber=' + randomNumber + ' enforcement_percentage=' + successRateConfig.enforcement_percentage); if (randomNumber < successRateConfig.enforcement_percentage) { + trace('Ejecting candidate ' + address); this.eject(mapEntry, ejectionTimestamp); } } @@ -470,13 +482,14 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { if (!failurePercentageConfig) { return; } + trace('Running failure percentage check. threshold=' + failurePercentageConfig.threshold + ' request volume threshold=' + failurePercentageConfig.request_volume); // Step 1 if (this.addressMap.size < failurePercentageConfig.minimum_hosts) { return; } // Step 2 - for (const mapEntry of this.addressMap.values()) { + for (const [address, mapEntry] of this.addressMap.entries()) { // Step 2.i if (this.getCurrentEjectionPercent() > this.latestConfig.getMaxEjectionPercent()) { break; @@ -484,6 +497,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { // Step 2.ii const successes = mapEntry.counter.getLastSuccesses(); const failures = mapEntry.counter.getLastFailures(); + trace('Candidate successes=' + successes + ' failures=' + failures); if (successes + failures < failurePercentageConfig.request_volume) { continue; } @@ -491,7 +505,9 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { const failurePercentage = (failures * 100) / (failures + successes); if (failurePercentage > failurePercentageConfig.threshold) { const randomNumber = Math.random() * 100; + trace('Candidate ' + address + ' randomNumber=' + randomNumber + ' enforcement_percentage=' + failurePercentageConfig.enforcement_percentage); if (randomNumber < failurePercentageConfig.enforcement_percentage) { + trace('Ejecting candidate ' + address); this.eject(mapEntry, ejectionTimestamp); } } @@ -525,6 +541,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { private runChecks() { const ejectionTimestamp = new Date(); + trace('Ejection timer running'); this.switchAllBuckets(); @@ -537,7 +554,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { this.runSuccessRateCheck(ejectionTimestamp); this.runFailurePercentageCheck(ejectionTimestamp); - for (const mapEntry of this.addressMap.values()) { + for (const [address, mapEntry] of this.addressMap.entries()) { if (mapEntry.currentEjectionTimestamp === null) { if (mapEntry.ejectionTimeMultiplier > 0) { mapEntry.ejectionTimeMultiplier -= 1; @@ -548,6 +565,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { const returnTime = new Date(mapEntry.currentEjectionTimestamp.getTime()); returnTime.setMilliseconds(returnTime.getMilliseconds() + Math.min(baseEjectionTimeMs * mapEntry.ejectionTimeMultiplier, Math.max(baseEjectionTimeMs, maxEjectionTimeMs))); if (returnTime < new Date()) { + trace('Unejecting ' + address); this.uneject(mapEntry); } } @@ -564,6 +582,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { } for (const address of subchannelAddresses) { if (!this.addressMap.has(address)) { + trace('Adding map entry for ' + address); this.addressMap.set(address, { counter: new CallCounter(), currentEjectionTimestamp: null, @@ -574,6 +593,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { } for (const key of this.addressMap.keys()) { if (!subchannelAddresses.has(key)) { + trace('Removing map entry for ' + key); this.addressMap.delete(key); } } @@ -585,15 +605,18 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { if (lbConfig.getSuccessRateEjectionConfig() || lbConfig.getFailurePercentageEjectionConfig()) { if (this.timerStartTime) { + trace('Previous timer existed. Replacing timer'); clearTimeout(this.ejectionTimer); const remainingDelay = lbConfig.getIntervalMs() - ((new Date()).getTime() - this.timerStartTime.getTime()); this.startTimer(remainingDelay); } else { + trace('Starting new timer'); this.timerStartTime = new Date(); this.startTimer(lbConfig.getIntervalMs()); this.switchAllBuckets(); } } else { + trace('Counting disabled. Cancelling timer.'); this.timerStartTime = null; clearTimeout(this.ejectionTimer); } From 1e531501550d989c7260370261ecf9423b3cf599 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 2 Aug 2022 13:48:16 -0700 Subject: [PATCH 281/450] Update outlier detection behavior for gRFC updates --- packages/grpc-js-xds/src/load-balancer-cds.ts | 5 ++--- packages/grpc-js/src/load-balancer-outlier-detection.ts | 9 ++++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js-xds/src/load-balancer-cds.ts b/packages/grpc-js-xds/src/load-balancer-cds.ts index a6dbf42f0..4d47b2546 100644 --- a/packages/grpc-js-xds/src/load-balancer-cds.ts +++ b/packages/grpc-js-xds/src/load-balancer-cds.ts @@ -79,9 +79,8 @@ function translateOutlierDetectionConfig(outlierDetection: OutlierDetection__Out return undefined; } if (!outlierDetection) { - /* No-op outlier detection config, with max possible interval and no - * ejection criteria configured. */ - return new OutlierDetectionLoadBalancingConfig(~(1<<31), null, null, null, null, null, []); + /* No-op outlier detection config, with all fields unset. */ + return new OutlierDetectionLoadBalancingConfig(null, null, null, null, null, null, []); } let successRateConfig: Partial | null = null; /* Success rate ejection is enabled by default, so we only disable it if diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index e9793beab..4219e293a 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -357,7 +357,10 @@ class OutlierDetectionPicker implements Picker { extraFilterFactories: extraFilterFactories }; } else { - return wrappedPick; + return { + ...wrappedPick, + subchannel: subchannelWrapper.getWrappedSubchannel() + } } } else { return wrappedPick; @@ -619,6 +622,10 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { trace('Counting disabled. Cancelling timer.'); this.timerStartTime = null; clearTimeout(this.ejectionTimer); + for (const mapEntry of this.addressMap.values()) { + this.uneject(mapEntry); + mapEntry.ejectionTimeMultiplier = 0; + } } this.latestConfig = lbConfig; From b3f23d805efd1f30d44375c62de82845e78d5fd2 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 4 Aug 2022 12:54:15 -0700 Subject: [PATCH 282/450] grpc-js: Implement getConnectivityState in subchannel wrapper --- packages/grpc-js/src/load-balancer-outlier-detection.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index 4219e293a..afbeb3459 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -215,6 +215,14 @@ class OutlierDetectionSubchannelWrapper extends BaseSubchannelWrapper implements }); } + getConnectivityState(): connectivityState { + if (this.ejected) { + return ConnectivityState.TRANSIENT_FAILURE; + } else { + return this.childSubchannelState; + } + } + /** * Add a listener function to be called whenever the wrapper's * connectivity state changes. From 78fe8c6d05f82eddc270dcbd3995868e3a49c038 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 4 Aug 2022 15:56:28 -0700 Subject: [PATCH 283/450] grpc-js: Initialize connectivity state from subchannel in outlier detection subchannel wrapper --- packages/grpc-js/src/load-balancer-outlier-detection.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index afbeb3459..0ef401c9a 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -199,12 +199,13 @@ export class OutlierDetectionLoadBalancingConfig implements LoadBalancingConfig } class OutlierDetectionSubchannelWrapper extends BaseSubchannelWrapper implements SubchannelInterface { - private childSubchannelState: ConnectivityState = ConnectivityState.IDLE; + private childSubchannelState: ConnectivityState; private stateListeners: ConnectivityStateListener[] = []; private ejected: boolean = false; private refCount: number = 0; constructor(childSubchannel: SubchannelInterface, private mapEntry?: MapEntry) { super(childSubchannel); + this.childSubchannelState = childSubchannel.getConnectivityState(); childSubchannel.addConnectivityStateListener((subchannel, previousState, newState) => { this.childSubchannelState = newState; if (!this.ejected) { From 001cce7db07ee06c648e9f364003e5fb7879d052 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 4 Aug 2022 16:02:05 -0700 Subject: [PATCH 284/450] grpc-js: Propagate ejection when recreating outlier detection subchannel wrapper --- packages/grpc-js/src/load-balancer-outlier-detection.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index 0ef401c9a..ee400d45f 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -391,6 +391,10 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { const originalSubchannel = channelControlHelper.createSubchannel(subchannelAddress, subchannelArgs); const mapEntry = this.addressMap.get(subchannelAddressToString(subchannelAddress)); const subchannelWrapper = new OutlierDetectionSubchannelWrapper(originalSubchannel, mapEntry); + if (mapEntry?.currentEjectionTimestamp !== null) { + // If the address is ejected, propagate that to the new subchannel wrapper + subchannelWrapper.eject(); + } mapEntry?.subchannelWrappers.push(subchannelWrapper); return subchannelWrapper; }, From edbdc570c7492b8be7eda2cb5f5afa0915a68f3b Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 2 Aug 2022 11:02:02 -0700 Subject: [PATCH 285/450] grpc-js: Add outlier detection tracing and enable it in interop tests --- packages/grpc-js-xds/interop/Dockerfile | 2 +- .../src/load-balancer-outlier-detection.ts | 31 ++++++++++++++++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/packages/grpc-js-xds/interop/Dockerfile b/packages/grpc-js-xds/interop/Dockerfile index e8a0a98cb..b93e309d7 100644 --- a/packages/grpc-js-xds/interop/Dockerfile +++ b/packages/grpc-js-xds/interop/Dockerfile @@ -33,6 +33,6 @@ COPY --from=build /node/src/grpc-node/packages/grpc-js ./packages/grpc-js/ COPY --from=build /node/src/grpc-node/packages/grpc-js-xds ./packages/grpc-js-xds/ ENV GRPC_VERBOSITY="DEBUG" -ENV GRPC_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weighted_target,round_robin,resolving_load_balancer,subchannel,keepalive,dns_resolver,fault_injection,http_filter,csds +ENV GRPC_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weighted_target,round_robin,resolving_load_balancer,subchannel,keepalive,dns_resolver,fault_injection,http_filter,csds,outlier_detection ENTRYPOINT [ "node", "/node/src/grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client" ] diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index dde618b73..e9793beab 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -18,7 +18,7 @@ import { ChannelOptions, connectivityState, StatusObject } from "."; import { Call } from "./call-stream"; import { ConnectivityState } from "./connectivity-state"; -import { Status } from "./constants"; +import { LogVerbosity, Status } from "./constants"; import { durationToMs, isDuration, msToDuration } from "./duration"; import { ChannelControlHelper, createChildChannelControlHelper, registerLoadBalancerType } from "./experimental"; import { BaseFilter, Filter, FilterFactory } from "./filter"; @@ -28,7 +28,13 @@ import { PickArgs, Picker, PickResult, PickResultType, QueuePicker, UnavailableP import { Subchannel } from "./subchannel"; import { SubchannelAddress, subchannelAddressToString } from "./subchannel-address"; import { BaseSubchannelWrapper, ConnectivityStateListener, SubchannelInterface } from "./subchannel-interface"; +import * as logging from './logging'; +const TRACER_NAME = 'outlier_detection'; + +function trace(text: string): void { + logging.trace(LogVerbosity.DEBUG, TRACER_NAME, text); +} const TYPE_NAME = 'outlier_detection'; @@ -412,6 +418,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { if (!successRateConfig) { return; } + trace('Running success rate check'); // Step 1 const targetRequestVolume = successRateConfig.request_volume; let addresesWithTargetVolume = 0; @@ -424,6 +431,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { successRates.push(successes/(successes + failures)); } } + trace('Found ' + addresesWithTargetVolume + ' success rate candidates; currentEjectionPercent=' + this.getCurrentEjectionPercent() + ' successRates=[' + successRates + ']'); if (addresesWithTargetVolume < successRateConfig.minimum_hosts) { return; } @@ -438,9 +446,10 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { const successRateVariance = successRateDeviationSum / successRates.length; const successRateStdev = Math.sqrt(successRateVariance); const ejectionThreshold = successRateMean - successRateStdev * (successRateConfig.stdev_factor / 1000); + trace('stdev=' + successRateStdev + ' ejectionThreshold=' + ejectionThreshold); // Step 3 - for (const mapEntry of this.addressMap.values()) { + for (const [address, mapEntry] of this.addressMap.entries()) { // Step 3.i if (this.getCurrentEjectionPercent() > this.latestConfig.getMaxEjectionPercent()) { break; @@ -453,9 +462,12 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { } // Step 3.iii const successRate = successes / (successes + failures); + trace('Checking candidate ' + address + ' successRate=' + successRate); if (successRate < ejectionThreshold) { const randomNumber = Math.random() * 100; + trace('Candidate ' + address + ' randomNumber=' + randomNumber + ' enforcement_percentage=' + successRateConfig.enforcement_percentage); if (randomNumber < successRateConfig.enforcement_percentage) { + trace('Ejecting candidate ' + address); this.eject(mapEntry, ejectionTimestamp); } } @@ -470,13 +482,14 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { if (!failurePercentageConfig) { return; } + trace('Running failure percentage check. threshold=' + failurePercentageConfig.threshold + ' request volume threshold=' + failurePercentageConfig.request_volume); // Step 1 if (this.addressMap.size < failurePercentageConfig.minimum_hosts) { return; } // Step 2 - for (const mapEntry of this.addressMap.values()) { + for (const [address, mapEntry] of this.addressMap.entries()) { // Step 2.i if (this.getCurrentEjectionPercent() > this.latestConfig.getMaxEjectionPercent()) { break; @@ -484,6 +497,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { // Step 2.ii const successes = mapEntry.counter.getLastSuccesses(); const failures = mapEntry.counter.getLastFailures(); + trace('Candidate successes=' + successes + ' failures=' + failures); if (successes + failures < failurePercentageConfig.request_volume) { continue; } @@ -491,7 +505,9 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { const failurePercentage = (failures * 100) / (failures + successes); if (failurePercentage > failurePercentageConfig.threshold) { const randomNumber = Math.random() * 100; + trace('Candidate ' + address + ' randomNumber=' + randomNumber + ' enforcement_percentage=' + failurePercentageConfig.enforcement_percentage); if (randomNumber < failurePercentageConfig.enforcement_percentage) { + trace('Ejecting candidate ' + address); this.eject(mapEntry, ejectionTimestamp); } } @@ -525,6 +541,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { private runChecks() { const ejectionTimestamp = new Date(); + trace('Ejection timer running'); this.switchAllBuckets(); @@ -537,7 +554,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { this.runSuccessRateCheck(ejectionTimestamp); this.runFailurePercentageCheck(ejectionTimestamp); - for (const mapEntry of this.addressMap.values()) { + for (const [address, mapEntry] of this.addressMap.entries()) { if (mapEntry.currentEjectionTimestamp === null) { if (mapEntry.ejectionTimeMultiplier > 0) { mapEntry.ejectionTimeMultiplier -= 1; @@ -548,6 +565,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { const returnTime = new Date(mapEntry.currentEjectionTimestamp.getTime()); returnTime.setMilliseconds(returnTime.getMilliseconds() + Math.min(baseEjectionTimeMs * mapEntry.ejectionTimeMultiplier, Math.max(baseEjectionTimeMs, maxEjectionTimeMs))); if (returnTime < new Date()) { + trace('Unejecting ' + address); this.uneject(mapEntry); } } @@ -564,6 +582,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { } for (const address of subchannelAddresses) { if (!this.addressMap.has(address)) { + trace('Adding map entry for ' + address); this.addressMap.set(address, { counter: new CallCounter(), currentEjectionTimestamp: null, @@ -574,6 +593,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { } for (const key of this.addressMap.keys()) { if (!subchannelAddresses.has(key)) { + trace('Removing map entry for ' + key); this.addressMap.delete(key); } } @@ -585,15 +605,18 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { if (lbConfig.getSuccessRateEjectionConfig() || lbConfig.getFailurePercentageEjectionConfig()) { if (this.timerStartTime) { + trace('Previous timer existed. Replacing timer'); clearTimeout(this.ejectionTimer); const remainingDelay = lbConfig.getIntervalMs() - ((new Date()).getTime() - this.timerStartTime.getTime()); this.startTimer(remainingDelay); } else { + trace('Starting new timer'); this.timerStartTime = new Date(); this.startTimer(lbConfig.getIntervalMs()); this.switchAllBuckets(); } } else { + trace('Counting disabled. Cancelling timer.'); this.timerStartTime = null; clearTimeout(this.ejectionTimer); } From 9be6c6c5dab57d3f9f5408c5ee0f6d9ad2a99445 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 2 Aug 2022 13:48:16 -0700 Subject: [PATCH 286/450] Update outlier detection behavior for gRFC updates --- packages/grpc-js-xds/src/load-balancer-cds.ts | 5 ++--- packages/grpc-js/src/load-balancer-outlier-detection.ts | 9 ++++++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js-xds/src/load-balancer-cds.ts b/packages/grpc-js-xds/src/load-balancer-cds.ts index a6dbf42f0..4d47b2546 100644 --- a/packages/grpc-js-xds/src/load-balancer-cds.ts +++ b/packages/grpc-js-xds/src/load-balancer-cds.ts @@ -79,9 +79,8 @@ function translateOutlierDetectionConfig(outlierDetection: OutlierDetection__Out return undefined; } if (!outlierDetection) { - /* No-op outlier detection config, with max possible interval and no - * ejection criteria configured. */ - return new OutlierDetectionLoadBalancingConfig(~(1<<31), null, null, null, null, null, []); + /* No-op outlier detection config, with all fields unset. */ + return new OutlierDetectionLoadBalancingConfig(null, null, null, null, null, null, []); } let successRateConfig: Partial | null = null; /* Success rate ejection is enabled by default, so we only disable it if diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index e9793beab..4219e293a 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -357,7 +357,10 @@ class OutlierDetectionPicker implements Picker { extraFilterFactories: extraFilterFactories }; } else { - return wrappedPick; + return { + ...wrappedPick, + subchannel: subchannelWrapper.getWrappedSubchannel() + } } } else { return wrappedPick; @@ -619,6 +622,10 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { trace('Counting disabled. Cancelling timer.'); this.timerStartTime = null; clearTimeout(this.ejectionTimer); + for (const mapEntry of this.addressMap.values()) { + this.uneject(mapEntry); + mapEntry.ejectionTimeMultiplier = 0; + } } this.latestConfig = lbConfig; From 3328798d28f544a752f4328fc670a46009a769ba Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 4 Aug 2022 12:54:15 -0700 Subject: [PATCH 287/450] grpc-js: Implement getConnectivityState in subchannel wrapper --- packages/grpc-js/src/load-balancer-outlier-detection.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index 4219e293a..afbeb3459 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -215,6 +215,14 @@ class OutlierDetectionSubchannelWrapper extends BaseSubchannelWrapper implements }); } + getConnectivityState(): connectivityState { + if (this.ejected) { + return ConnectivityState.TRANSIENT_FAILURE; + } else { + return this.childSubchannelState; + } + } + /** * Add a listener function to be called whenever the wrapper's * connectivity state changes. From 4cfe75b43a72ca98d7745417be86206d611426ac Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 4 Aug 2022 15:56:28 -0700 Subject: [PATCH 288/450] grpc-js: Initialize connectivity state from subchannel in outlier detection subchannel wrapper --- packages/grpc-js/src/load-balancer-outlier-detection.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index afbeb3459..0ef401c9a 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -199,12 +199,13 @@ export class OutlierDetectionLoadBalancingConfig implements LoadBalancingConfig } class OutlierDetectionSubchannelWrapper extends BaseSubchannelWrapper implements SubchannelInterface { - private childSubchannelState: ConnectivityState = ConnectivityState.IDLE; + private childSubchannelState: ConnectivityState; private stateListeners: ConnectivityStateListener[] = []; private ejected: boolean = false; private refCount: number = 0; constructor(childSubchannel: SubchannelInterface, private mapEntry?: MapEntry) { super(childSubchannel); + this.childSubchannelState = childSubchannel.getConnectivityState(); childSubchannel.addConnectivityStateListener((subchannel, previousState, newState) => { this.childSubchannelState = newState; if (!this.ejected) { From 36f37cb78fb6fd987d9834d71a797ae8fabe2428 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 4 Aug 2022 16:02:05 -0700 Subject: [PATCH 289/450] grpc-js: Propagate ejection when recreating outlier detection subchannel wrapper --- packages/grpc-js/src/load-balancer-outlier-detection.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index 0ef401c9a..ee400d45f 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -391,6 +391,10 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { const originalSubchannel = channelControlHelper.createSubchannel(subchannelAddress, subchannelArgs); const mapEntry = this.addressMap.get(subchannelAddressToString(subchannelAddress)); const subchannelWrapper = new OutlierDetectionSubchannelWrapper(originalSubchannel, mapEntry); + if (mapEntry?.currentEjectionTimestamp !== null) { + // If the address is ejected, propagate that to the new subchannel wrapper + subchannelWrapper.eject(); + } mapEntry?.subchannelWrappers.push(subchannelWrapper); return subchannelWrapper; }, From d0dc6cd46e94b48bcf9520d587747a230dfcb2dd Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 8 Aug 2022 11:36:10 -0700 Subject: [PATCH 290/450] grpc-js-xds: Enable the outlier detection interop test --- packages/grpc-js-xds/scripts/xds_k8s_lb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh index ca300f0c2..ff915db59 100755 --- a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh @@ -159,7 +159,7 @@ main() { # Run tests cd "${TEST_DRIVER_FULL_DIR}" local failed_tests=0 - test_suites=("baseline_test" "api_listener_test" "change_backend_service_test" "failover_test" "remove_neg_test" "round_robin_test") + test_suites=("baseline_test" "api_listener_test" "change_backend_service_test" "failover_test" "remove_neg_test" "round_robin_test" "outlier_detection") for test in "${test_suites[@]}"; do run_test $test || (( failed_tests++ )) done From e2960a87d29862b83cae8ec558c41847d7f33cb1 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 8 Aug 2022 11:36:10 -0700 Subject: [PATCH 291/450] grpc-js-xds: Enable the outlier detection interop test --- packages/grpc-js-xds/scripts/xds_k8s_lb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh index ca300f0c2..ff915db59 100755 --- a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh @@ -159,7 +159,7 @@ main() { # Run tests cd "${TEST_DRIVER_FULL_DIR}" local failed_tests=0 - test_suites=("baseline_test" "api_listener_test" "change_backend_service_test" "failover_test" "remove_neg_test" "round_robin_test") + test_suites=("baseline_test" "api_listener_test" "change_backend_service_test" "failover_test" "remove_neg_test" "round_robin_test" "outlier_detection") for test in "${test_suites[@]}"; do run_test $test || (( failed_tests++ )) done From ee1e330157067e479690106b2dffa1fcf904b0e5 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 8 Aug 2022 12:50:50 -0700 Subject: [PATCH 292/450] grpc-js: Avoid explicit bind in trailer event handler --- packages/grpc-js/src/call-stream.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/src/call-stream.ts b/packages/grpc-js/src/call-stream.ts index e8f312752..f265512f4 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -573,7 +573,9 @@ export class Http2CallStream implements Call { } } }); - stream.on('trailers', this.handleTrailers.bind(this)); + stream.on('trailers', (headers: http2.IncomingHttpHeaders) => { + this.handleTrailers(headers); + }); stream.on('data', (data: Buffer) => { this.trace('receive HTTP/2 data frame of length ' + data.length); const messages = this.decoder.write(data); From 31d28b5f147e1392bab22e042aa0282c16a18567 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 8 Aug 2022 13:05:26 -0700 Subject: [PATCH 293/450] grpc-js: Handle errors when trying to ping --- packages/grpc-js/src/subchannel.ts | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 5d1bf8973..87c0cd2cd 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -361,12 +361,21 @@ export class Subchannel { this.handleDisconnect(); }, this.keepaliveTimeoutMs); this.keepaliveTimeoutId.unref?.(); - this.session!.ping( - (err: Error | null, duration: number, payload: Buffer) => { - this.keepaliveTrace('Received ping response'); - clearTimeout(this.keepaliveTimeoutId); - } - ); + try { + this.session!.ping( + (err: Error | null, duration: number, payload: Buffer) => { + this.keepaliveTrace('Received ping response'); + clearTimeout(this.keepaliveTimeoutId); + } + ); + } catch (e) { + /* If we fail to send a ping, the connection is no longer functional, so + * we should discard it. */ + this.transitionToState( + [ConnectivityState.READY], + ConnectivityState.TRANSIENT_FAILURE + ); + } } private startKeepalivePings() { From c1ab4c4a1b69a79fb7b69eff68a0bcfc517b28c9 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 8 Aug 2022 13:44:02 -0700 Subject: [PATCH 294/450] grpc-js: Update version to 1.6.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 3ceaefebe..b10ad4a47 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.6.8", + "version": "1.6.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 e87b8640757ce583ab441a0807617eeafc3df6a2 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 8 Aug 2022 17:18:02 -0700 Subject: [PATCH 295/450] grpc-js: Update version to 1.6.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 3ceaefebe..b10ad4a47 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.6.8", + "version": "1.6.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 9e3935ec839009a5b64af935bfd503a634753367 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Tue, 9 Aug 2022 12:26:33 +0200 Subject: [PATCH 296/450] fix: update `long` to v5 --- packages/proto-loader/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index 07e66c9fe..6aef44a99 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -47,7 +47,7 @@ "dependencies": { "@types/long": "^4.0.1", "lodash.camelcase": "^4.3.0", - "long": "^4.0.0", + "long": "^5.0.0", "protobufjs": "^7.0.0", "yargs": "^16.2.0" }, From d23d7bdd09d9adce9b4704e50e38aacd48f7d334 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Tue, 9 Aug 2022 12:32:57 +0200 Subject: [PATCH 297/450] remove types `long` ships with types now --- packages/proto-loader/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index 6aef44a99..60af4242f 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -45,7 +45,6 @@ "proto-loader-gen-types": "./build/bin/proto-loader-gen-types.js" }, "dependencies": { - "@types/long": "^4.0.1", "lodash.camelcase": "^4.3.0", "long": "^5.0.0", "protobufjs": "^7.0.0", From 3f4418faf01cd029512cb3cbf48319d3b4f367ca Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 11 Aug 2022 18:01:01 -0700 Subject: [PATCH 298/450] grpc-js: Drain incoming http2 data after outputting status --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/call-stream.ts | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index b10ad4a47..72b4b10ed 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.6.9", + "version": "1.6.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", diff --git a/packages/grpc-js/src/call-stream.ts b/packages/grpc-js/src/call-stream.ts index f265512f4..c405405e8 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -329,6 +329,11 @@ export class Http2CallStream implements Call { process.nextTick(() => { this.listener?.onReceiveStatus(filteredStatus); }); + /* Leave the http2 stream in flowing state to drain incoming messages, to + * ensure that the stream closure completes. The call stream already does + * not push more messages after the status is output, so the messages go + * nowhere either way. */ + this.http2Stream?.resume(); if (this.subchannel) { this.subchannel.callUnref(); this.subchannel.removeDisconnectListener(this.disconnectListener); @@ -577,6 +582,11 @@ export class Http2CallStream implements Call { this.handleTrailers(headers); }); stream.on('data', (data: Buffer) => { + /* If the status has already been output, allow the http2 stream to + * drain without processing the data. */ + if (this.statusOutput) { + return; + } this.trace('receive HTTP/2 data frame of length ' + data.length); const messages = this.decoder.write(data); @@ -688,9 +698,6 @@ export class Http2CallStream implements Call { } this.streamEndWatchers.forEach(watcher => watcher(false)); }); - if (!this.pendingRead) { - stream.pause(); - } if (this.pendingWrite) { if (!this.pendingWriteCallback) { throw new Error('Invalid state in write handling code'); From 9ba4ed36217a4a45c39138301e1bfffedfa9e888 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 15 Aug 2022 09:36:35 -0700 Subject: [PATCH 299/450] grpc-js-xds: Fix outlier detection interop test name --- packages/grpc-js-xds/scripts/xds_k8s_lb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh index ff915db59..0e45cd86f 100755 --- a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh @@ -159,7 +159,7 @@ main() { # Run tests cd "${TEST_DRIVER_FULL_DIR}" local failed_tests=0 - test_suites=("baseline_test" "api_listener_test" "change_backend_service_test" "failover_test" "remove_neg_test" "round_robin_test" "outlier_detection") + test_suites=("baseline_test" "api_listener_test" "change_backend_service_test" "failover_test" "remove_neg_test" "round_robin_test" "outlier_detection_test") for test in "${test_suites[@]}"; do run_test $test || (( failed_tests++ )) done From ff16cdf02104295b08f1cbc124b0cba89a6336cc Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 15 Aug 2022 09:36:35 -0700 Subject: [PATCH 300/450] grpc-js-xds: Fix outlier detection interop test name --- packages/grpc-js-xds/scripts/xds_k8s_lb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh index ff915db59..0e45cd86f 100755 --- a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh @@ -159,7 +159,7 @@ main() { # Run tests cd "${TEST_DRIVER_FULL_DIR}" local failed_tests=0 - test_suites=("baseline_test" "api_listener_test" "change_backend_service_test" "failover_test" "remove_neg_test" "round_robin_test" "outlier_detection") + test_suites=("baseline_test" "api_listener_test" "change_backend_service_test" "failover_test" "remove_neg_test" "round_robin_test" "outlier_detection_test") for test in "${test_suites[@]}"; do run_test $test || (( failed_tests++ )) done From 9d0eb60d1948255fbe0af6ad4a2585734e5db366 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 17 Aug 2022 09:30:53 -0700 Subject: [PATCH 301/450] proto-loader: Update dependencies to fix compilation error --- packages/proto-loader/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index 07e66c9fe..9c813337e 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/proto-loader", - "version": "0.7.0", + "version": "0.7.1", "author": "Google Inc.", "contributors": [ { @@ -58,9 +58,9 @@ "@types/node": "^10.17.26", "@types/yargs": "^16.0.4", "clang-format": "^1.2.2", - "gts": "^1.1.0", + "gts": "^3.1.0", "rimraf": "^3.0.2", - "typescript": "~3.8.3" + "typescript": "~4.7.4" }, "engines": { "node": ">=6" From d0e7f356db02656ce1ba06b1f26d0a217348c481 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 17 Aug 2022 12:44:48 -0700 Subject: [PATCH 302/450] proto-loader: Undo upgrade of 'long' dependency --- packages/proto-loader/package.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index 09f815c86..53b269d1b 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/proto-loader", - "version": "0.7.1", + "version": "0.7.2", "author": "Google Inc.", "contributors": [ { @@ -45,8 +45,9 @@ "proto-loader-gen-types": "./build/bin/proto-loader-gen-types.js" }, "dependencies": { + "@types/long": "^4.0.1", "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", + "long": "^4.0.0", "protobufjs": "^7.0.0", "yargs": "^16.2.0" }, From 7ca0cc006922588190597278288b65007f30ad7d Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 17 Aug 2022 16:32:20 -0700 Subject: [PATCH 303/450] grpc-js-xds: Implement ignore_resource_deletion option --- packages/grpc-js-xds/src/xds-client.ts | 4 +++ .../src/xds-stream-state/xds-stream-state.ts | 36 +++++++++++++++---- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index d2b3f1823..0c8126cbe 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -360,6 +360,10 @@ export class XdsClient { } else { this.apiVersion = XdsApiVersion.V2; } + if (bootstrapInfo.xdsServers[0].serverFeatures.indexOf('ignore_resource_deletion') >= 0) { + this.adsState.lds.enableIgnoreResourceDeletion(); + this.adsState.cds.enableIgnoreResourceDeletion(); + } const nodeV2: NodeV2 = { ...bootstrapInfo.node, build_version: `gRPC Node Pure JS ${clientVersion}`, diff --git a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts index 0b806f843..88d36c77d 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts @@ -75,6 +75,7 @@ interface SubscriptionEntry { watchers: Watcher[]; cachedResponse: ResponseType | null; resourceTimer: NodeJS.Timer; + deletionIgnored: boolean; } const RESOURCE_TIMEOUT_MS = 15_000; @@ -86,11 +87,12 @@ export abstract class BaseXdsStreamState implements XdsStreamState private subscriptions: Map> = new Map>(); private latestIsV2 = false; private isAdsStreamRunning = false; + private ignoreResourceDeletion = false; constructor(private updateResourceNames: () => void) {} - protected trace(text: string) { - experimental.trace(logVerbosity.DEBUG, TRACER_NAME, this.getProtocolName() + ' | ' + text); + protected trace(text: string, verbosity = logVerbosity.DEBUG) { + experimental.trace(verbosity, TRACER_NAME, this.getProtocolName() + ' | ' + text); } private startResourceTimer(subscriptionEntry: SubscriptionEntry) { @@ -111,7 +113,8 @@ export abstract class BaseXdsStreamState implements XdsStreamState subscriptionEntry = { watchers: [], cachedResponse: null, - resourceTimer: setTimeout(() => {}, 0) + resourceTimer: setTimeout(() => {}, 0), + deletionIgnored: false }; if (this.isAdsStreamRunning) { this.startResourceTimer(subscriptionEntry); @@ -142,6 +145,9 @@ export abstract class BaseXdsStreamState implements XdsStreamState } if (subscriptionEntry.watchers.length === 0) { clearTimeout(subscriptionEntry.resourceTimer); + if (subscriptionEntry.deletionIgnored) { + this.trace('Unsubscribing from resource with previously ignored deletion: ' + resourceName, logVerbosity.INFO); + } this.subscriptions.delete(resourceName); this.updateResourceNames(); } @@ -187,6 +193,10 @@ export abstract class BaseXdsStreamState implements XdsStreamState } clearTimeout(subscriptionEntry.resourceTimer); subscriptionEntry.cachedResponse = resource; + if (subscriptionEntry.deletionIgnored) { + this.trace('Received resource with previously ignored deletion: ' + resourceName, logVerbosity.INFO); + subscriptionEntry.deletionIgnored = false; + } } } result.missing = this.handleMissingNames(allResourceNames); @@ -218,10 +228,18 @@ export abstract class BaseXdsStreamState implements XdsStreamState const missingNames: string[] = []; for (const [resourceName, subscriptionEntry] of this.subscriptions.entries()) { if (!allResponseNames.has(resourceName) && subscriptionEntry.cachedResponse !== null) { - this.trace('Reporting resource does not exist named ' + resourceName); - missingNames.push(resourceName); - for (const watcher of subscriptionEntry.watchers) { - watcher.onResourceDoesNotExist(); + if (this.ignoreResourceDeletion) { + if (!subscriptionEntry.deletionIgnored) { + this.trace('Ignoring nonexistent resource ' + resourceName, logVerbosity.ERROR); + subscriptionEntry.deletionIgnored = true; + } + } else { + this.trace('Reporting resource does not exist named ' + resourceName); + missingNames.push(resourceName); + for (const watcher of subscriptionEntry.watchers) { + watcher.onResourceDoesNotExist(); + } + subscriptionEntry.cachedResponse = null; } } } @@ -231,6 +249,10 @@ export abstract class BaseXdsStreamState implements XdsStreamState } } + enableIgnoreResourceDeletion() { + this.ignoreResourceDeletion = true; + } + /** * Apply the validation rules for this resource type to this resource * instance. From a3b698e837cfa6cc5be0c989b2d0f2db7694af65 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 17 Aug 2022 17:00:02 -0700 Subject: [PATCH 304/450] Don't use tracer for ignored resource deletion logs --- .../src/xds-stream-state/xds-stream-state.ts | 10 +++++----- packages/grpc-js/src/experimental.ts | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts index 88d36c77d..7b3bc0189 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts @@ -91,8 +91,8 @@ export abstract class BaseXdsStreamState implements XdsStreamState constructor(private updateResourceNames: () => void) {} - protected trace(text: string, verbosity = logVerbosity.DEBUG) { - experimental.trace(verbosity, TRACER_NAME, this.getProtocolName() + ' | ' + text); + protected trace(text: string) { + experimental.trace(logVerbosity.DEBUG, TRACER_NAME, this.getProtocolName() + ' | ' + text); } private startResourceTimer(subscriptionEntry: SubscriptionEntry) { @@ -146,7 +146,7 @@ export abstract class BaseXdsStreamState implements XdsStreamState if (subscriptionEntry.watchers.length === 0) { clearTimeout(subscriptionEntry.resourceTimer); if (subscriptionEntry.deletionIgnored) { - this.trace('Unsubscribing from resource with previously ignored deletion: ' + resourceName, logVerbosity.INFO); + experimental.log(logVerbosity.INFO, 'Unsubscribing from resource with previously ignored deletion: ' + resourceName); } this.subscriptions.delete(resourceName); this.updateResourceNames(); @@ -194,7 +194,7 @@ export abstract class BaseXdsStreamState implements XdsStreamState clearTimeout(subscriptionEntry.resourceTimer); subscriptionEntry.cachedResponse = resource; if (subscriptionEntry.deletionIgnored) { - this.trace('Received resource with previously ignored deletion: ' + resourceName, logVerbosity.INFO); + experimental.log(logVerbosity.INFO, 'Received resource with previously ignored deletion: ' + resourceName); subscriptionEntry.deletionIgnored = false; } } @@ -230,7 +230,7 @@ export abstract class BaseXdsStreamState implements XdsStreamState if (!allResponseNames.has(resourceName) && subscriptionEntry.cachedResponse !== null) { if (this.ignoreResourceDeletion) { if (!subscriptionEntry.deletionIgnored) { - this.trace('Ignoring nonexistent resource ' + resourceName, logVerbosity.ERROR); + experimental.log(logVerbosity.ERROR, 'Ignoring nonexistent resource ' + resourceName); subscriptionEntry.deletionIgnored = true; } } else { diff --git a/packages/grpc-js/src/experimental.ts b/packages/grpc-js/src/experimental.ts index fcafbeb01..d58495f46 100644 --- a/packages/grpc-js/src/experimental.ts +++ b/packages/grpc-js/src/experimental.ts @@ -1,4 +1,4 @@ -export { trace } from './logging'; +export { trace, log } from './logging'; export { Resolver, ResolverListener, From 5a7f89a5f5c768807f1c879069a2901af7a6b478 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 18 Aug 2022 14:25:49 -0700 Subject: [PATCH 305/450] grpc-js: Switch LB policy when new one is not CONNECTING --- packages/grpc-js/src/load-balancer-child-handler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/src/load-balancer-child-handler.ts b/packages/grpc-js/src/load-balancer-child-handler.ts index 0591c92fd..64b341810 100644 --- a/packages/grpc-js/src/load-balancer-child-handler.ts +++ b/packages/grpc-js/src/load-balancer-child-handler.ts @@ -48,7 +48,7 @@ export class ChildLoadBalancerHandler implements LoadBalancer { } updateState(connectivityState: ConnectivityState, picker: Picker): void { if (this.calledByPendingChild()) { - if (connectivityState !== ConnectivityState.READY) { + if (connectivityState === ConnectivityState.CONNECTING) { return; } this.parent.currentChild?.destroy(); From 3e6730cd24bebd6780daa8b69161568881ab622b Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 18 Aug 2022 14:55:58 -0700 Subject: [PATCH 306/450] grpc-js-xds: delay picker updates while updating children in weighted target and xds_cluster_manager --- .../grpc-js-xds/src/load-balancer-weighted-target.ts | 11 ++++++++++- .../src/load-balancer-xds-cluster-manager.ts | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js-xds/src/load-balancer-weighted-target.ts b/packages/grpc-js-xds/src/load-balancer-weighted-target.ts index a7a28c663..5d7cfa04e 100644 --- a/packages/grpc-js-xds/src/load-balancer-weighted-target.ts +++ b/packages/grpc-js-xds/src/load-balancer-weighted-target.ts @@ -181,7 +181,7 @@ export class WeightedTargetLoadBalancer implements LoadBalancer { trace('Target ' + this.name + ' ' + ConnectivityState[this.connectivityState] + ' -> ' + ConnectivityState[connectivityState]); this.connectivityState = connectivityState; this.picker = picker; - this.parent.updateState(); + this.parent.maybeUpdateState(); } updateAddressList(addressList: SubchannelAddress[], lbConfig: WeightedTarget, attributes: { [key: string]: unknown; }): void { @@ -238,9 +238,16 @@ export class WeightedTargetLoadBalancer implements LoadBalancer { * List of current target names. */ private targetList: string[] = []; + private updatesPaused = false; constructor(private channelControlHelper: ChannelControlHelper) {} + private maybeUpdateState() { + if (!this.updatesPaused) { + this.updateState() + } + } + private updateState() { const pickerList: WeightedPicker[] = []; let end = 0; @@ -343,6 +350,7 @@ export class WeightedTargetLoadBalancer implements LoadBalancer { childAddressList.push(childAddress); } + this.updatesPaused = true; this.targetList = Array.from(lbConfig.getTargets().keys()); for (const [targetName, targetConfig] of lbConfig.getTargets()) { let target = this.targets.get(targetName); @@ -364,6 +372,7 @@ export class WeightedTargetLoadBalancer implements LoadBalancer { target.deactivate(); } } + this.updatesPaused = false; this.updateState(); } diff --git a/packages/grpc-js-xds/src/load-balancer-xds-cluster-manager.ts b/packages/grpc-js-xds/src/load-balancer-xds-cluster-manager.ts index 6210ea84a..bfc55c809 100644 --- a/packages/grpc-js-xds/src/load-balancer-xds-cluster-manager.ts +++ b/packages/grpc-js-xds/src/load-balancer-xds-cluster-manager.ts @@ -144,7 +144,7 @@ class XdsClusterManager implements LoadBalancer { trace('Child ' + this.name + ' ' + ConnectivityState[this.connectivityState] + ' -> ' + ConnectivityState[connectivityState]); this.connectivityState = connectivityState; this.picker = picker; - this.parent.updateState(); + this.parent.maybeUpdateState(); } updateAddressList(addressList: SubchannelAddress[], lbConfig: ClusterManagerChild, attributes: { [key: string]: unknown; }): void { const childConfig = getFirstUsableConfig(lbConfig.child_policy); @@ -173,8 +173,15 @@ class XdsClusterManager implements LoadBalancer { private children: Map = new Map(); // Shutdown is a placeholder value that will never appear in normal operation. private currentState: ConnectivityState = ConnectivityState.SHUTDOWN; + private updatesPaused = false; constructor(private channelControlHelper: ChannelControlHelper) {} + private maybeUpdateState() { + if (!this.updatesPaused) { + this.updateState(); + } + } + private updateState() { const pickerMap: Map = new Map(); let anyReady = false; @@ -250,6 +257,7 @@ class XdsClusterManager implements LoadBalancer { namesToRemove.push(name); } } + this.updatesPaused = true; for (const name of namesToRemove) { this.children.get(name)!.destroy(); this.children.delete(name); @@ -262,6 +270,7 @@ class XdsClusterManager implements LoadBalancer { this.children.set(name, newChild); } } + this.updatesPaused = false; this.updateState(); } exitIdle(): void { From e1b2cad25ea15f1ae848069a5b80c5ae2b2b5ef3 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 22 Aug 2022 14:28:34 -0700 Subject: [PATCH 307/450] grpc-js-xds: Make various fixes to the priority LB policy --- .../grpc-js-xds/src/load-balancer-priority.ts | 120 ++++++++---------- 1 file changed, 56 insertions(+), 64 deletions(-) diff --git a/packages/grpc-js-xds/src/load-balancer-priority.ts b/packages/grpc-js-xds/src/load-balancer-priority.ts index b05e459a7..9f4f68e1f 100644 --- a/packages/grpc-js-xds/src/load-balancer-priority.ts +++ b/packages/grpc-js-xds/src/load-balancer-priority.ts @@ -115,7 +115,6 @@ interface PriorityChildBalancer { resetBackoff(): void; deactivate(): void; maybeReactivate(): void; - cancelFailoverTimer(): void; isFailoverTimerPending(): boolean; getConnectivityState(): ConnectivityState; getPicker(): Picker; @@ -138,6 +137,7 @@ export class PriorityLoadBalancer implements LoadBalancer { private childBalancer: ChildLoadBalancerHandler; private failoverTimer: NodeJS.Timer | null = null; private deactivationTimer: NodeJS.Timer | null = null; + private seenReadyOrIdleSinceTransientFailure = false; constructor(private parent: PriorityLoadBalancer, private name: string) { this.childBalancer = new ChildLoadBalancerHandler(experimental.createChildChannelControlHelper(this.parent.channelControlHelper, { updateState: (connectivityState: ConnectivityState, picker: Picker) => { @@ -145,12 +145,24 @@ export class PriorityLoadBalancer implements LoadBalancer { }, })); this.picker = new QueuePicker(this.childBalancer); + this.startFailoverTimer(); } private updateState(connectivityState: ConnectivityState, picker: Picker) { trace('Child ' + this.name + ' ' + ConnectivityState[this.connectivityState] + ' -> ' + ConnectivityState[connectivityState]); this.connectivityState = connectivityState; this.picker = picker; + if (connectivityState === ConnectivityState.CONNECTING) { + if (this.seenReadyOrIdleSinceTransientFailure && this.failoverTimer === null) { + this.startFailoverTimer(); + } + } else if (connectivityState === ConnectivityState.READY || connectivityState === ConnectivityState.IDLE) { + this.seenReadyOrIdleSinceTransientFailure = true; + this.cancelFailoverTimer(); + } else if (connectivityState === ConnectivityState.TRANSIENT_FAILURE) { + this.seenReadyOrIdleSinceTransientFailure = false; + this.cancelFailoverTimer(); + } this.parent.onChildStateChange(this); } @@ -174,13 +186,9 @@ export class PriorityLoadBalancer implements LoadBalancer { attributes: { [key: string]: unknown } ): void { this.childBalancer.updateAddressList(addressList, lbConfig, attributes); - this.startFailoverTimer(); } exitIdle() { - if (this.connectivityState === ConnectivityState.IDLE) { - this.startFailoverTimer(); - } this.childBalancer.exitIdle(); } @@ -204,7 +212,7 @@ export class PriorityLoadBalancer implements LoadBalancer { } } - cancelFailoverTimer() { + private cancelFailoverTimer() { if (this.failoverTimer !== null) { clearTimeout(this.failoverTimer); this.failoverTimer = null; @@ -267,6 +275,8 @@ export class PriorityLoadBalancer implements LoadBalancer { */ private currentChildFromBeforeUpdate: PriorityChildBalancer | null = null; + private updatesPaused = false; + constructor(private channelControlHelper: ChannelControlHelper) {} private updateState(state: ConnectivityState, picker: Picker) { @@ -286,6 +296,9 @@ export class PriorityLoadBalancer implements LoadBalancer { private onChildStateChange(child: PriorityChildBalancer) { const childState = child.getConnectivityState(); trace('Child ' + child.getName() + ' transitioning to ' + ConnectivityState[childState]); + if (this.updatesPaused) { + return; + } if (child === this.currentChildFromBeforeUpdate) { if ( childState === ConnectivityState.READY || @@ -294,40 +307,11 @@ export class PriorityLoadBalancer implements LoadBalancer { this.updateState(childState, child.getPicker()); } else { this.currentChildFromBeforeUpdate = null; - this.tryNextPriority(true); + this.choosePriority(); } return; } - const childPriority = this.priorities.indexOf(child.getName()); - if (childPriority < 0) { - // child is not in the priority list, ignore updates - return; - } - if (this.currentPriority !== null && childPriority > this.currentPriority) { - // child is lower priority than the currently selected child, ignore updates - return; - } - if (childState === ConnectivityState.TRANSIENT_FAILURE) { - /* Report connecting if and only if the currently selected child is the - * one entering TRANSIENT_FAILURE */ - this.tryNextPriority(childPriority === this.currentPriority); - return; - } - if (this.currentPriority === null || childPriority < this.currentPriority) { - /* In this case, either there is no currently selected child or this - * child is higher priority than the currently selected child, so we want - * to switch to it if it is READY or IDLE. */ - if ( - childState === ConnectivityState.READY || - childState === ConnectivityState.IDLE - ) { - this.selectPriority(childPriority); - } - return; - } - /* The currently selected child has updated state to something other than - * TRANSIENT_FAILURE, so we pass that update along */ - this.updateState(childState, child.getPicker()); + this.choosePriority(); } private deleteChild(child: PriorityChildBalancer) { @@ -335,7 +319,7 @@ export class PriorityLoadBalancer implements LoadBalancer { this.currentChildFromBeforeUpdate = null; /* If we get to this point, the currentChildFromBeforeUpdate was still in * use, so we are still trying to connect to the specified priorities */ - this.tryNextPriority(true); + this.choosePriority(); } } @@ -348,7 +332,6 @@ export class PriorityLoadBalancer implements LoadBalancer { private selectPriority(priority: number) { this.currentPriority = priority; const chosenChild = this.children.get(this.priorities[priority])!; - chosenChild.cancelFailoverTimer(); this.updateState( chosenChild.getConnectivityState(), chosenChild.getPicker() @@ -360,20 +343,22 @@ export class PriorityLoadBalancer implements LoadBalancer { } } - /** - * Check each child in priority order until we find one to use - * @param reportConnecting Whether we should report a CONNECTING state if we - * stop before picking a specific child. This should be true when we have - * not already selected a child. - */ - private tryNextPriority(reportConnecting: boolean) { - for (const [index, childName] of this.priorities.entries()) { + private choosePriority() { + if (this.priorities.length === 0) { + this.updateState(ConnectivityState.TRANSIENT_FAILURE, new UnavailablePicker({code: Status.UNAVAILABLE, details: 'priority policy has empty priority list', metadata: new Metadata()})); + return; + } + + this.currentPriority = null; + for (const [priority, childName] of this.priorities.entries()) { + trace('Trying priority ' + priority + ' child ' + childName); let child = this.children.get(childName); /* If the child doesn't already exist, create it and update it. */ if (child === undefined) { - if (reportConnecting) { + if (this.currentChildFromBeforeUpdate === null) { this.updateState(ConnectivityState.CONNECTING, new QueuePicker(this)); } + this.currentPriority = priority; child = new this.PriorityChildImpl(this, childName); this.children.set(childName, child); const childUpdate = this.latestUpdates.get(childName); @@ -383,6 +368,7 @@ export class PriorityLoadBalancer implements LoadBalancer { childUpdate.lbConfig, this.latestAttributes ); + return; } } /* We're going to try to use this child, so reactivate it if it has been @@ -392,28 +378,33 @@ export class PriorityLoadBalancer implements LoadBalancer { child.getConnectivityState() === ConnectivityState.READY || child.getConnectivityState() === ConnectivityState.IDLE ) { - this.selectPriority(index); + this.selectPriority(priority); return; } if (child.isFailoverTimerPending()) { - /* This child is still trying to connect. Wait until its failover timer - * has ended to continue to the next one */ - if (reportConnecting) { + this.currentPriority = priority; + if (this.currentChildFromBeforeUpdate === null) { + /* This child is still trying to connect. Wait until its failover timer + * has ended to continue to the next one */ this.updateState(ConnectivityState.CONNECTING, new QueuePicker(this)); + return; } + } + } + + /* If we didn't find any priority to try, pick the first one in the state + * CONNECTING */ + for (const [priority, childName] of this.priorities.entries()) { + let child = this.children.get(childName)!; + if (child.getConnectivityState() === ConnectivityState.CONNECTING) { + this.updateState(child.getConnectivityState(), child.getPicker()); return; } } - this.currentPriority = null; - this.currentChildFromBeforeUpdate = null; - this.updateState( - ConnectivityState.TRANSIENT_FAILURE, - new UnavailablePicker({ - code: Status.UNAVAILABLE, - details: 'No ready priority', - metadata: new Metadata(), - }) - ); + + // Did not find any child in CONNECTING, delegate to last child + const child = this.children.get(this.priorities[this.priorities.length - 1])!; + this.updateState(child.getConnectivityState(), child.getPicker()); } updateAddressList( @@ -464,6 +455,7 @@ export class PriorityLoadBalancer implements LoadBalancer { this.latestAttributes = attributes; this.latestUpdates.clear(); this.priorities = lbConfig.getPriorities(); + this.updatesPaused = true; /* Pair up the new child configs with the corresponding address lists, and * update all existing children with their new configs */ for (const [childName, childConfig] of lbConfig.getChildren()) { @@ -492,8 +484,8 @@ export class PriorityLoadBalancer implements LoadBalancer { child.deactivate(); } } - // Only report connecting if there are no existing children - this.tryNextPriority(this.children.size === 0); + this.updatesPaused = false; + this.choosePriority(); } exitIdle(): void { if (this.currentPriority !== null) { From 460fa93b9c216687ed2e6ab640f9ce49241e0f0f Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 23 Aug 2022 13:38:56 -0700 Subject: [PATCH 308/450] grpc-js-xds: priority: remove currentChildFromBeforeUpdate --- .../grpc-js-xds/src/load-balancer-priority.ts | 76 +++++-------------- 1 file changed, 17 insertions(+), 59 deletions(-) diff --git a/packages/grpc-js-xds/src/load-balancer-priority.ts b/packages/grpc-js-xds/src/load-balancer-priority.ts index 9f4f68e1f..12037a777 100644 --- a/packages/grpc-js-xds/src/load-balancer-priority.ts +++ b/packages/grpc-js-xds/src/load-balancer-priority.ts @@ -266,14 +266,6 @@ export class PriorityLoadBalancer implements LoadBalancer { * Current chosen priority that requests are sent to */ private currentPriority: number | null = null; - /** - * After an update, this preserves the currently selected child from before - * the update. We continue to use that child until it disconnects, or - * another higher-priority child connects, or it is deleted because it is not - * in the new priority list at all and its retention interval has expired, or - * we try and fail to connect to every child in the new priority list. - */ - private currentChildFromBeforeUpdate: PriorityChildBalancer | null = null; private updatesPaused = false; @@ -299,28 +291,11 @@ export class PriorityLoadBalancer implements LoadBalancer { if (this.updatesPaused) { return; } - if (child === this.currentChildFromBeforeUpdate) { - if ( - childState === ConnectivityState.READY || - childState === ConnectivityState.IDLE - ) { - this.updateState(childState, child.getPicker()); - } else { - this.currentChildFromBeforeUpdate = null; - this.choosePriority(); - } - return; - } this.choosePriority(); } private deleteChild(child: PriorityChildBalancer) { - if (child === this.currentChildFromBeforeUpdate) { - this.currentChildFromBeforeUpdate = null; - /* If we get to this point, the currentChildFromBeforeUpdate was still in - * use, so we are still trying to connect to the specified priorities */ - this.choosePriority(); - } + this.children.delete(child.getName()); } /** @@ -329,17 +304,17 @@ export class PriorityLoadBalancer implements LoadBalancer { * child connects. * @param priority */ - private selectPriority(priority: number) { + private selectPriority(priority: number, deactivateLowerPriorities: boolean) { this.currentPriority = priority; const chosenChild = this.children.get(this.priorities[priority])!; this.updateState( chosenChild.getConnectivityState(), chosenChild.getPicker() ); - this.currentChildFromBeforeUpdate = null; - // Deactivate each child of lower priority than the chosen child - for (let i = priority + 1; i < this.priorities.length; i++) { - this.children.get(this.priorities[i])?.deactivate(); + if (deactivateLowerPriorities) { + for (let i = priority + 1; i < this.priorities.length; i++) { + this.children.get(this.priorities[i])?.deactivate(); + } } } @@ -349,16 +324,11 @@ export class PriorityLoadBalancer implements LoadBalancer { return; } - this.currentPriority = null; for (const [priority, childName] of this.priorities.entries()) { trace('Trying priority ' + priority + ' child ' + childName); let child = this.children.get(childName); /* If the child doesn't already exist, create it and update it. */ if (child === undefined) { - if (this.currentChildFromBeforeUpdate === null) { - this.updateState(ConnectivityState.CONNECTING, new QueuePicker(this)); - } - this.currentPriority = priority; child = new this.PriorityChildImpl(this, childName); this.children.set(childName, child); const childUpdate = this.latestUpdates.get(childName); @@ -368,27 +338,24 @@ export class PriorityLoadBalancer implements LoadBalancer { childUpdate.lbConfig, this.latestAttributes ); - return; } + } else { + /* We're going to try to use this child, so reactivate it if it has been + * deactivated */ + child.maybeReactivate(); } - /* We're going to try to use this child, so reactivate it if it has been - * deactivated */ - child.maybeReactivate(); if ( child.getConnectivityState() === ConnectivityState.READY || child.getConnectivityState() === ConnectivityState.IDLE ) { - this.selectPriority(priority); + this.selectPriority(priority, true); return; } if (child.isFailoverTimerPending()) { - this.currentPriority = priority; - if (this.currentChildFromBeforeUpdate === null) { - /* This child is still trying to connect. Wait until its failover timer - * has ended to continue to the next one */ - this.updateState(ConnectivityState.CONNECTING, new QueuePicker(this)); - return; - } + this.selectPriority(priority, false); + /* This child is still trying to connect. Wait until its failover timer + * has ended to continue to the next one */ + return; } } @@ -397,14 +364,13 @@ export class PriorityLoadBalancer implements LoadBalancer { for (const [priority, childName] of this.priorities.entries()) { let child = this.children.get(childName)!; if (child.getConnectivityState() === ConnectivityState.CONNECTING) { - this.updateState(child.getConnectivityState(), child.getPicker()); + this.selectPriority(priority, false); return; } } // Did not find any child in CONNECTING, delegate to last child - const child = this.children.get(this.priorities[this.priorities.length - 1])!; - this.updateState(child.getConnectivityState(), child.getPicker()); + this.selectPriority(this.priorities.length - 1, false); } updateAddressList( @@ -446,12 +412,6 @@ export class PriorityLoadBalancer implements LoadBalancer { } childAddressList.push(childAddress); } - if (this.currentPriority !== null) { - this.currentChildFromBeforeUpdate = this.children.get( - this.priorities[this.currentPriority] - )!; - this.currentPriority = null; - } this.latestAttributes = attributes; this.latestUpdates.clear(); this.priorities = lbConfig.getPriorities(); @@ -502,8 +462,6 @@ export class PriorityLoadBalancer implements LoadBalancer { child.destroy(); } this.children.clear(); - this.currentChildFromBeforeUpdate?.destroy(); - this.currentChildFromBeforeUpdate = null; } getTypeName(): string { return TYPE_NAME; From f15efb63deaf8a84cee358b69434319628e8175a Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 24 Aug 2022 10:27:53 -0700 Subject: [PATCH 309/450] grpc-js: Outlier Detection: fix failure percentage min hosts check --- .../grpc-js/src/load-balancer-outlier-detection.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index ee400d45f..dccca7c04 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -500,7 +500,15 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { } trace('Running failure percentage check. threshold=' + failurePercentageConfig.threshold + ' request volume threshold=' + failurePercentageConfig.request_volume); // Step 1 - if (this.addressMap.size < failurePercentageConfig.minimum_hosts) { + let addresesWithTargetVolume = 0; + for (const mapEntry of this.addressMap.values()) { + const successes = mapEntry.counter.getLastSuccesses(); + const failures = mapEntry.counter.getLastFailures(); + if (successes + failures >= failurePercentageConfig.request_volume) { + addresesWithTargetVolume += 1; + } + } + if (addresesWithTargetVolume < failurePercentageConfig.minimum_hosts) { return; } From 8664c837db2f03e17b5bfd70a9d352a9a318448a Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 24 Aug 2022 10:59:15 -0700 Subject: [PATCH 310/450] Fix spelling --- packages/grpc-js/src/load-balancer-outlier-detection.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index dccca7c04..a799e5b09 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -500,15 +500,15 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { } trace('Running failure percentage check. threshold=' + failurePercentageConfig.threshold + ' request volume threshold=' + failurePercentageConfig.request_volume); // Step 1 - let addresesWithTargetVolume = 0; + let addressesWithTargetVolume = 0; for (const mapEntry of this.addressMap.values()) { const successes = mapEntry.counter.getLastSuccesses(); const failures = mapEntry.counter.getLastFailures(); if (successes + failures >= failurePercentageConfig.request_volume) { - addresesWithTargetVolume += 1; + addressesWithTargetVolume += 1; } } - if (addresesWithTargetVolume < failurePercentageConfig.minimum_hosts) { + if (addressesWithTargetVolume < failurePercentageConfig.minimum_hosts) { return; } From 7a138a696509494dcf9912569064f48b4421ee7b Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 17 Aug 2022 09:30:53 -0700 Subject: [PATCH 311/450] proto-loader: Update dependencies to fix compilation error --- packages/proto-loader/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index 9b9431dc1..989e34eac 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -58,9 +58,9 @@ "@types/node": "^10.17.26", "@types/yargs": "^16.0.4", "clang-format": "^1.2.2", - "gts": "^1.1.0", + "gts": "^3.1.0", "rimraf": "^3.0.2", - "typescript": "~3.8.3" + "typescript": "~4.7.4" }, "engines": { "node": ">=6" From 1d5801aa90784746809d3f7e10c9693d919bdc3f Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 24 Aug 2022 14:54:09 -0700 Subject: [PATCH 312/450] grpc-js: Stop ejecting when current percent is equal to max --- packages/grpc-js/src/load-balancer-outlier-detection.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index a799e5b09..bf7a72f87 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -467,7 +467,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { // Step 3 for (const [address, mapEntry] of this.addressMap.entries()) { // Step 3.i - if (this.getCurrentEjectionPercent() > this.latestConfig.getMaxEjectionPercent()) { + if (this.getCurrentEjectionPercent() >= this.latestConfig.getMaxEjectionPercent()) { break; } // Step 3.ii @@ -515,7 +515,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { // Step 2 for (const [address, mapEntry] of this.addressMap.entries()) { // Step 2.i - if (this.getCurrentEjectionPercent() > this.latestConfig.getMaxEjectionPercent()) { + if (this.getCurrentEjectionPercent() >= this.latestConfig.getMaxEjectionPercent()) { break; } // Step 2.ii From 2c6fd779d8151580492e8e482add5a53bcfce42a Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 25 Aug 2022 14:22:00 -0700 Subject: [PATCH 313/450] grpc-js-xds: Use authority override to select VirtualHost when provided --- packages/grpc-js-xds/src/resolver-xds.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js-xds/src/resolver-xds.ts b/packages/grpc-js-xds/src/resolver-xds.ts index f6e2ad402..8c447931d 100644 --- a/packages/grpc-js-xds/src/resolver-xds.ts +++ b/packages/grpc-js-xds/src/resolver-xds.ts @@ -319,9 +319,12 @@ class XdsResolver implements Resolver { private handleRouteConfig(routeConfig: RouteConfiguration__Output, isV2: boolean) { this.latestRouteConfig = routeConfig; this.latestRouteConfigIsV2 = isV2; - const virtualHost = findVirtualHostForDomain(routeConfig.virtual_hosts, this.target.path); + /* Select the virtual host using the default authority override if it + * exists, and the channel target otherwise. */ + const hostDomain = this.channelOptions['grpc.default_authority'] ?? this.target.path; + const virtualHost = findVirtualHostForDomain(routeConfig.virtual_hosts, hostDomain); if (virtualHost === null) { - this.reportResolutionError('No matching route found'); + this.reportResolutionError('No matching route found for ' + hostDomain); return; } const virtualHostHttpFilterOverrides = new Map(); From 594933aa2b9c0b0d59635383c6e8f7b7829eb7de Mon Sep 17 00:00:00 2001 From: Sergii Tkachenko Date: Fri, 26 Aug 2022 17:49:48 -0700 Subject: [PATCH 314/450] xDS interop: enable pod log collection in the buildscripts - Enables pod log collection in all PSM interop jobs implemented in https://github.com/grpc/grpc/pull/30594. - Associate test suite runs with their own log file, so it's displayed on the "Target Log" tab - Adds missing `--force_cleanup` to the lb test (reduces leaked resources) - Fix run_test not returning correct exit status, causing false positives in some cases. See https://github.com/grpc/grpc/pull/30768 --- packages/grpc-js-xds/scripts/xds_k8s_lb.sh | 8 +++++++- packages/grpc-js-xds/scripts/xds_k8s_url_map.sh | 10 +++++++--- test/kokoro/xds_k8s_lb.cfg | 2 +- test/kokoro/xds_k8s_url_map.cfg | 2 +- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh index 0e45cd86f..ca747f7ea 100755 --- a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh @@ -98,6 +98,8 @@ 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: @@ -109,7 +111,11 @@ run_test() { --client_image="${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \ --server_image="${SERVER_IMAGE_NAME}" \ --testing_version="${TESTING_VERSION}" \ - --xml_output_file="${TEST_XML_OUTPUT_DIR}/${test_name}/sponge_log.xml" + --force_cleanup \ + --collect_app_logs \ + --log_dir="${out_dir}" \ + --xml_output_file="${out_dir}/sponge_log.xml" \ + |& tee "${out_dir}/sponge_log.log" } ####################################### 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 c29d0c0a5..69126c72b 100644 --- a/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh @@ -98,15 +98,19 @@ 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}" \ - --xml_output_file="${TEST_XML_OUTPUT_DIR}/${test_name}/sponge_log.xml" \ - --flagfile="config/url-map.cfg" - set +x + --collect_app_logs \ + --log_dir="${out_dir}" \ + --xml_output_file="${out_dir}/sponge_log.xml" \ + |& tee "${out_dir}/sponge_log.log" } ####################################### diff --git a/test/kokoro/xds_k8s_lb.cfg b/test/kokoro/xds_k8s_lb.cfg index b9940cfdc..09aa3d17d 100644 --- a/test/kokoro/xds_k8s_lb.cfg +++ b/test/kokoro/xds_k8s_lb.cfg @@ -20,7 +20,7 @@ timeout_mins: 180 action { define_artifacts { regex: "artifacts/**/*sponge_log.xml" - regex: "artifacts/**/*sponge_log.log" + regex: "artifacts/**/*.log" strip_prefix: "artifacts" } } diff --git a/test/kokoro/xds_k8s_url_map.cfg b/test/kokoro/xds_k8s_url_map.cfg index dd4cce76d..50d523b66 100644 --- a/test/kokoro/xds_k8s_url_map.cfg +++ b/test/kokoro/xds_k8s_url_map.cfg @@ -20,7 +20,7 @@ timeout_mins: 180 action { define_artifacts { regex: "artifacts/**/*sponge_log.xml" - regex: "artifacts/**/*sponge_log.log" + regex: "artifacts/**/*.log" strip_prefix: "artifacts" } } From a82e40ff9a7946df11557a77ee6b00e5c8bd946b Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 29 Aug 2022 09:52:13 -0700 Subject: [PATCH 315/450] grpc-js: Handle errors when decoding status details --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/call-stream.ts | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 72b4b10ed..dab771696 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.6.10", + "version": "1.6.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", diff --git a/packages/grpc-js/src/call-stream.ts b/packages/grpc-js/src/call-stream.ts index c405405e8..0bb4d01cb 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -488,7 +488,11 @@ export class Http2CallStream implements Call { } let details = ''; if (typeof metadataMap['grpc-message'] === 'string') { - details = decodeURI(metadataMap['grpc-message']); + try { + details = decodeURI(metadataMap['grpc-message']); + } catch (e) { + details = metadataMap['grpc-messages'] as string; + } metadata.remove('grpc-message'); this.trace( 'received status details string "' + details + '" from server' From c323369929e321a3de3465caeb97c74a527c7156 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 29 Aug 2022 15:41:51 -0700 Subject: [PATCH 316/450] grpc-js: Enable outlier detection by default --- packages/grpc-js/src/load-balancer-outlier-detection.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index bf7a72f87..685cfc60d 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -38,7 +38,7 @@ function trace(text: string): void { const TYPE_NAME = 'outlier_detection'; -const OUTLIER_DETECTION_ENABLED = process.env.GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION === 'true'; +const OUTLIER_DETECTION_ENABLED = process.env.GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION !== 'false'; export interface SuccessRateEjectionConfig { readonly stdev_factor: number; From ccd855fb5add8e92e22418a84ed5eccedf239a6f Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 29 Aug 2022 18:18:53 -0700 Subject: [PATCH 317/450] grpc-js: Fix typo in previous status message handling fix --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/call-stream.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index dab771696..8ca6eb1c6 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.6.11", + "version": "1.6.12", "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/call-stream.ts b/packages/grpc-js/src/call-stream.ts index 0bb4d01cb..d7151eb6f 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -491,7 +491,7 @@ export class Http2CallStream implements Call { try { details = decodeURI(metadataMap['grpc-message']); } catch (e) { - details = metadataMap['grpc-messages'] as string; + details = metadataMap['grpc-message']; } metadata.remove('grpc-message'); this.trace( From bc66ebf62f0a8418c9ee90a1a038a7492078bb4d Mon Sep 17 00:00:00 2001 From: install <1994052+install@users.noreply.github.com> Date: Fri, 5 Aug 2022 12:38:36 -0400 Subject: [PATCH 318/450] proto-loader-gen-types Typename templates - Allow for customizing the naming pattern for both restricted and permissive types --- packages/proto-loader/README.md | 4 + .../bin/proto-loader-gen-types.ts | 84 ++++++++++++------- 2 files changed, 59 insertions(+), 29 deletions(-) diff --git a/packages/proto-loader/README.md b/packages/proto-loader/README.md index 123fad111..818f0efda 100644 --- a/packages/proto-loader/README.md +++ b/packages/proto-loader/README.md @@ -88,6 +88,10 @@ Options: -O, --outDir Directory in which to output files [string] [required] --grpcLib The gRPC implementation library that these types will be used with [string] [required] + --inputTemplate Template for mapping input or "permissive" type names + [string] [default: "%s"] + --outputTemplate Template for mapping output or "restricted" type names + [string] [default: "%s__Output"] ``` ### Example Usage diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index a819d12d4..bb5b35f81 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -26,12 +26,25 @@ import * as yargs from 'yargs'; import camelCase = require('lodash.camelcase'); import { loadProtosWithOptions, addCommonProtos } from '../src/util'; +const templateStr = "%s"; +const useNameFmter = ({outputTemplate, inputTemplate}: GeneratorOptions) => { + if (outputTemplate === inputTemplate) { + throw new Error('inputTemplate and outputTemplate must differ') + } + return { + outputName: (n: string) => outputTemplate.replace(templateStr, n), + inputName: (n: string) => inputTemplate.replace(templateStr, n) + }; +} + type GeneratorOptions = Protobuf.IParseOptions & Protobuf.IConversionOptions & { includeDirs?: string[]; grpcLib: string; outDir: string; verbose?: boolean; includeComments?: boolean; + inputTemplate: string; + outputTemplate: string; } class TextFormatter { @@ -114,15 +127,16 @@ function getTypeInterfaceName(type: Protobuf.Type | Protobuf.Enum | Protobuf.Ser return type.fullName.replace(/\./g, '_'); } -function getImportLine(dependency: Protobuf.Type | Protobuf.Enum | Protobuf.Service, from?: Protobuf.Type | Protobuf.Service) { +function getImportLine(dependency: Protobuf.Type | Protobuf.Enum | Protobuf.Service, from: Protobuf.Type | Protobuf.Service | undefined, options: GeneratorOptions) { const filePath = from === undefined ? './' + getImportPath(dependency) : getRelativeImportPath(from, dependency); + const {outputName, inputName} = useNameFmter(options); const typeInterfaceName = getTypeInterfaceName(dependency); let importedTypes: string; /* If the dependency is defined within a message, it will be generated in that * message's file and exported using its typeInterfaceName. */ if (dependency.parent instanceof Protobuf.Type) { if (dependency instanceof Protobuf.Type) { - importedTypes = `${typeInterfaceName}, ${typeInterfaceName}__Output`; + importedTypes = `${inputName(typeInterfaceName)}, ${outputName(typeInterfaceName)}`; } else if (dependency instanceof Protobuf.Enum) { importedTypes = `${typeInterfaceName}`; } else if (dependency instanceof Protobuf.Service) { @@ -132,7 +146,7 @@ function getImportLine(dependency: Protobuf.Type | Protobuf.Enum | Protobuf.Serv } } else { if (dependency instanceof Protobuf.Type) { - importedTypes = `${dependency.name} as ${typeInterfaceName}, ${dependency.name}__Output as ${typeInterfaceName}__Output`; + importedTypes = `${inputName(dependency.name)} as ${inputName(typeInterfaceName)}, ${outputName(dependency.name)} as ${outputName(typeInterfaceName)}`; } else if (dependency instanceof Protobuf.Enum) { importedTypes = `${dependency.name} as ${typeInterfaceName}`; } else if (dependency instanceof Protobuf.Service) { @@ -170,7 +184,8 @@ function formatComment(formatter: TextFormatter, comment?: string | null) { // GENERATOR FUNCTIONS -function getTypeNamePermissive(fieldType: string, resolvedType: Protobuf.Type | Protobuf.Enum | null, repeated: boolean, map: boolean): string { +function getTypeNamePermissive(fieldType: string, resolvedType: Protobuf.Type | Protobuf.Enum | null, repeated: boolean, map: boolean, options: GeneratorOptions): string { + const {inputName} = useNameFmter(options); switch (fieldType) { case 'double': case 'float': @@ -200,9 +215,9 @@ function getTypeNamePermissive(fieldType: string, resolvedType: Protobuf.Type | const typeInterfaceName = getTypeInterfaceName(resolvedType); if (resolvedType instanceof Protobuf.Type) { if (repeated || map) { - return typeInterfaceName; + return inputName(typeInterfaceName); } else { - return `${typeInterfaceName} | null`; + return `${inputName(typeInterfaceName)} | null`; } } else { return `${typeInterfaceName} | keyof typeof ${typeInterfaceName}`; @@ -210,8 +225,8 @@ function getTypeNamePermissive(fieldType: string, resolvedType: Protobuf.Type | } } -function getFieldTypePermissive(field: Protobuf.FieldBase): string { - const valueType = getTypeNamePermissive(field.type, field.resolvedType, field.repeated, field.map); +function getFieldTypePermissive(field: Protobuf.FieldBase, options: GeneratorOptions): string { + const valueType = getTypeNamePermissive(field.type, field.resolvedType, field.repeated, field.map, options); if (field instanceof Protobuf.MapField) { const keyType = field.keyType === 'string' ? 'string' : 'number'; return `{[key: ${keyType}]: ${valueType}}`; @@ -221,23 +236,24 @@ function getFieldTypePermissive(field: Protobuf.FieldBase): string { } function generatePermissiveMessageInterface(formatter: TextFormatter, messageType: Protobuf.Type, options: GeneratorOptions, nameOverride?: string) { + const {inputName} = useNameFmter(options); if (options.includeComments) { formatComment(formatter, messageType.comment); } if (messageType.fullName === '.google.protobuf.Any') { /* This describes the behavior of the Protobuf.js Any wrapper fromObject * replacement function */ - formatter.writeLine('export type Any = AnyExtension | {'); + formatter.writeLine(`export type ${inputName('Any')} = AnyExtension | {`); formatter.writeLine(' type_url: string;'); formatter.writeLine(' value: Buffer | Uint8Array | string;'); formatter.writeLine('}'); return; } - formatter.writeLine(`export interface ${nameOverride ?? messageType.name} {`); + formatter.writeLine(`export interface ${inputName(nameOverride ?? messageType.name)} {`); formatter.indent(); for (const field of messageType.fieldsArray) { const repeatedString = field.repeated ? '[]' : ''; - const type: string = getFieldTypePermissive(field); + const type: string = getFieldTypePermissive(field, options); if (options.includeComments) { formatComment(formatter, field.comment); } @@ -255,6 +271,7 @@ function generatePermissiveMessageInterface(formatter: TextFormatter, messageTyp } function getTypeNameRestricted(fieldType: string, resolvedType: Protobuf.Type | Protobuf.Enum | null, repeated: boolean, map: boolean, options: GeneratorOptions): string { + const {outputName} = useNameFmter(options); switch (fieldType) { case 'double': case 'float': @@ -302,9 +319,9 @@ function getTypeNameRestricted(fieldType: string, resolvedType: Protobuf.Type | /* null is only used to represent absent message values if the defaults * option is set, and only for non-repeated, non-map fields. */ if (options.defaults && !repeated && !map) { - return `${typeInterfaceName}__Output | null`; + return `${outputName(typeInterfaceName)} | null`; } else { - return `${typeInterfaceName}__Output`; + return `${outputName(typeInterfaceName)}`; } } else { if (options.enums == String) { @@ -327,6 +344,7 @@ function getFieldTypeRestricted(field: Protobuf.FieldBase, options: GeneratorOpt } function generateRestrictedMessageInterface(formatter: TextFormatter, messageType: Protobuf.Type, options: GeneratorOptions, nameOverride?: string) { + const {outputName} = useNameFmter(options); if (options.includeComments) { formatComment(formatter, messageType.comment); } @@ -334,13 +352,13 @@ function generateRestrictedMessageInterface(formatter: TextFormatter, messageTyp /* This describes the behavior of the Protobuf.js Any wrapper toObject * replacement function */ let optionalString = options.defaults ? '' : '?'; - formatter.writeLine('export type Any__Output = AnyExtension | {'); + formatter.writeLine(`export type ${outputName('Any')} = AnyExtension | {`); formatter.writeLine(` type_url${optionalString}: string;`); formatter.writeLine(` value${optionalString}: ${getTypeNameRestricted('bytes', null, false, false, options)};`); formatter.writeLine('}'); return; } - formatter.writeLine(`export interface ${nameOverride ?? messageType.name}__Output {`); + formatter.writeLine(`export interface ${outputName(nameOverride ?? messageType.name)} {`); formatter.indent(); for (const field of messageType.fieldsArray) { let fieldGuaranteed: boolean; @@ -389,7 +407,7 @@ function generateMessageInterfaces(formatter: TextFormatter, messageType: Protob continue; } seenDeps.add(dependency.fullName); - formatter.writeLine(getImportLine(dependency, messageType)); + formatter.writeLine(getImportLine(dependency, messageType, options)); } if (field.type.indexOf('64') >= 0) { usesLong = true; @@ -404,7 +422,7 @@ function generateMessageInterfaces(formatter: TextFormatter, messageType: Protob continue; } seenDeps.add(dependency.fullName); - formatter.writeLine(getImportLine(dependency, messageType)); + formatter.writeLine(getImportLine(dependency, messageType, options)); } if (field.type.indexOf('64') >= 0) { usesLong = true; @@ -487,6 +505,7 @@ const CLIENT_RESERVED_METHOD_NAMES = new Set([ ]); function generateServiceClientInterface(formatter: TextFormatter, serviceType: Protobuf.Service, options: GeneratorOptions) { + const {outputName, inputName} = useNameFmter(options); if (options.includeComments) { formatComment(formatter, serviceType.comment); } @@ -501,8 +520,8 @@ function generateServiceClientInterface(formatter: TextFormatter, serviceType: P if (options.includeComments) { formatComment(formatter, method.comment); } - const requestType = getTypeInterfaceName(method.resolvedRequestType!); - const responseType = getTypeInterfaceName(method.resolvedResponseType!) + '__Output'; + const requestType = inputName(getTypeInterfaceName(method.resolvedRequestType!)); + const responseType = outputName(getTypeInterfaceName(method.resolvedResponseType!)); const callbackType = `grpc.requestCallback<${responseType}>`; if (method.requestStream) { if (method.responseStream) { @@ -541,6 +560,7 @@ function generateServiceClientInterface(formatter: TextFormatter, serviceType: P } function generateServiceHandlerInterface(formatter: TextFormatter, serviceType: Protobuf.Service, options: GeneratorOptions) { + const {inputName, outputName} = useNameFmter(options); if (options.includeComments) { formatComment(formatter, serviceType.comment); } @@ -551,8 +571,8 @@ function generateServiceHandlerInterface(formatter: TextFormatter, serviceType: if (options.includeComments) { formatComment(formatter, method.comment); } - const requestType = getTypeInterfaceName(method.resolvedRequestType!) + '__Output'; - const responseType = getTypeInterfaceName(method.resolvedResponseType!); + const requestType = outputName(getTypeInterfaceName(method.resolvedRequestType!)); + const responseType = inputName(getTypeInterfaceName(method.resolvedResponseType!)); if (method.requestStream) { if (method.responseStream) { // Bidi streaming @@ -576,14 +596,15 @@ function generateServiceHandlerInterface(formatter: TextFormatter, serviceType: formatter.writeLine('}'); } -function generateServiceDefinitionInterface(formatter: TextFormatter, serviceType: Protobuf.Service) { +function generateServiceDefinitionInterface(formatter: TextFormatter, serviceType: Protobuf.Service, options: GeneratorOptions) { + const {inputName, outputName} = useNameFmter(options); formatter.writeLine(`export interface ${serviceType.name}Definition extends grpc.ServiceDefinition {`); formatter.indent(); for (const methodName of Object.keys(serviceType.methods).sort()) { const method = serviceType.methods[methodName]; const requestType = getTypeInterfaceName(method.resolvedRequestType!); const responseType = getTypeInterfaceName(method.resolvedResponseType!); - formatter.writeLine(`${methodName}: MethodDefinition<${requestType}, ${responseType}, ${requestType}__Output, ${responseType}__Output>`); + formatter.writeLine(`${methodName}: MethodDefinition<${inputName(requestType)}, ${inputName(responseType)}, ${outputName(requestType)}, ${outputName(responseType)}>`); } formatter.unindent(); formatter.writeLine('}') @@ -601,7 +622,7 @@ function generateServiceInterfaces(formatter: TextFormatter, serviceType: Protob dependencies.add(method.resolvedResponseType!); } for (const dep of Array.from(dependencies.values()).sort(compareName)) { - formatter.writeLine(getImportLine(dep, serviceType)); + formatter.writeLine(getImportLine(dep, serviceType, options)); } formatter.writeLine(''); @@ -611,7 +632,7 @@ function generateServiceInterfaces(formatter: TextFormatter, serviceType: Protob generateServiceHandlerInterface(formatter, serviceType, options); formatter.writeLine(''); - generateServiceDefinitionInterface(formatter, serviceType); + generateServiceDefinitionInterface(formatter, serviceType, options); } function containsDefinition(definitionType: typeof Protobuf.Type | typeof Protobuf.Enum, namespace: Protobuf.NamespaceBase): boolean { @@ -645,7 +666,7 @@ function generateDefinitionImports(formatter: TextFormatter, namespace: Protobuf function generateServiceImports(formatter: TextFormatter, namespace: Protobuf.NamespaceBase, options: GeneratorOptions) { for (const nested of namespace.nestedArray.sort(compareName)) { if (nested instanceof Protobuf.Service) { - formatter.writeLine(getImportLine(nested)); + formatter.writeLine(getImportLine(nested, undefined, options)); } else if (isNamespaceBase(nested) && !(nested instanceof Protobuf.Type) && !(nested instanceof Protobuf.Enum)) { generateServiceImports(formatter, nested, options); } @@ -776,7 +797,7 @@ async function runScript() { .normalize(['includeDirs', 'outDir']) .array('includeDirs') .boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs', 'json', 'verbose', 'includeComments']) - .string(['longs', 'enums', 'bytes']) + .string(['longs', 'enums', 'bytes', 'inputTemplate', 'outputTemplate']) .default('keepCase', false) .default('defaults', false) .default('arrays', false) @@ -787,6 +808,8 @@ async function runScript() { .default('longs', 'Long') .default('enums', 'number') .default('bytes', 'Buffer') + .default('inputTemplate', `${templateStr}`) + .default('outputTemplate', `${templateStr}__Output`) .coerce('longs', value => { switch (value) { case 'String': return String; @@ -805,7 +828,8 @@ async function runScript() { case 'String': return String; default: return undefined; } - }).alias({ + }) + .alias({ includeDirs: 'I', outDir: 'O', verbose: 'v' @@ -822,7 +846,9 @@ async function runScript() { includeComments: 'Generate doc comments from comments in the original files', includeDirs: 'Directories to search for included files', outDir: 'Directory in which to output files', - grpcLib: 'The gRPC implementation library that these types will be used with' + grpcLib: 'The gRPC implementation library that these types will be used with', + inputTemplate: 'Template for mapping input or "permissive" type names', + outputTemplate: 'Template for mapping output or "restricted" type names', }).demandOption(['outDir', 'grpcLib']) .demand(1) .usage('$0 [options] filenames...') From d81ec8e5326a8f48cc824878b8ce7ecb09b95ffb Mon Sep 17 00:00:00 2001 From: install <1994052+install@users.noreply.github.com> Date: Wed, 7 Sep 2022 09:59:22 -0400 Subject: [PATCH 319/450] Update golden tests - use input/output templates --- .../google/api/CustomHttpPattern.ts | 4 +- .../golden-generated/google/api/Http.ts | 10 +- .../golden-generated/google/api/HttpRule.ts | 16 +- .../longrunning/CancelOperationRequest.ts | 4 +- .../longrunning/DeleteOperationRequest.ts | 4 +- .../google/longrunning/GetOperationRequest.ts | 4 +- .../longrunning/ListOperationsRequest.ts | 4 +- .../longrunning/ListOperationsResponse.ts | 10 +- .../google/longrunning/Operation.ts | 20 +-- .../google/longrunning/OperationInfo.ts | 4 +- .../google/longrunning/Operations.ts | 116 +++++++------- .../longrunning/WaitOperationRequest.ts | 10 +- .../golden-generated/google/protobuf/Any.ts | 4 +- .../google/protobuf/DescriptorProto.ts | 54 +++---- .../google/protobuf/Duration.ts | 4 +- .../golden-generated/google/protobuf/Empty.ts | 4 +- .../google/protobuf/EnumDescriptorProto.ts | 16 +- .../google/protobuf/EnumOptions.ts | 10 +- .../protobuf/EnumValueDescriptorProto.ts | 10 +- .../google/protobuf/EnumValueOptions.ts | 10 +- .../google/protobuf/FieldDescriptorProto.ts | 10 +- .../google/protobuf/FieldOptions.ts | 10 +- .../google/protobuf/FileDescriptorProto.ts | 40 ++--- .../google/protobuf/FileDescriptorSet.ts | 10 +- .../google/protobuf/FileOptions.ts | 10 +- .../google/protobuf/GeneratedCodeInfo.ts | 12 +- .../google/protobuf/MessageOptions.ts | 10 +- .../google/protobuf/MethodDescriptorProto.ts | 10 +- .../google/protobuf/MethodOptions.ts | 22 +-- .../google/protobuf/OneofDescriptorProto.ts | 10 +- .../google/protobuf/OneofOptions.ts | 10 +- .../google/protobuf/ServiceDescriptorProto.ts | 16 +- .../google/protobuf/ServiceOptions.ts | 10 +- .../google/protobuf/SourceCodeInfo.ts | 12 +- .../google/protobuf/Timestamp.ts | 4 +- .../google/protobuf/UninterpretedOption.ts | 12 +- .../golden-generated/google/rpc/Status.ts | 10 +- .../google/showcase/v1beta1/BlockRequest.ts | 22 +-- .../google/showcase/v1beta1/BlockResponse.ts | 4 +- .../google/showcase/v1beta1/Echo.ts | 142 +++++++++--------- .../google/showcase/v1beta1/EchoRequest.ts | 10 +- .../google/showcase/v1beta1/EchoResponse.ts | 4 +- .../google/showcase/v1beta1/ExpandRequest.ts | 10 +- .../showcase/v1beta1/PagedExpandRequest.ts | 4 +- .../showcase/v1beta1/PagedExpandResponse.ts | 10 +- .../google/showcase/v1beta1/WaitMetadata.ts | 10 +- .../google/showcase/v1beta1/WaitRequest.ts | 28 ++-- .../google/showcase/v1beta1/WaitResponse.ts | 4 +- packages/proto-loader/package.json | 2 +- 49 files changed, 393 insertions(+), 393 deletions(-) diff --git a/packages/proto-loader/golden-generated/google/api/CustomHttpPattern.ts b/packages/proto-loader/golden-generated/google/api/CustomHttpPattern.ts index 2b6490be6..2f6e20297 100644 --- a/packages/proto-loader/golden-generated/google/api/CustomHttpPattern.ts +++ b/packages/proto-loader/golden-generated/google/api/CustomHttpPattern.ts @@ -4,7 +4,7 @@ /** * A custom pattern is used for defining custom HTTP verb. */ -export interface CustomHttpPattern { +export interface ICustomHttpPattern { /** * The name of this custom HTTP verb. */ @@ -18,7 +18,7 @@ export interface CustomHttpPattern { /** * A custom pattern is used for defining custom HTTP verb. */ -export interface CustomHttpPattern__Output { +export interface OCustomHttpPattern { /** * The name of this custom HTTP verb. */ diff --git a/packages/proto-loader/golden-generated/google/api/Http.ts b/packages/proto-loader/golden-generated/google/api/Http.ts index e9b3cb309..6b6ae8a63 100644 --- a/packages/proto-loader/golden-generated/google/api/Http.ts +++ b/packages/proto-loader/golden-generated/google/api/Http.ts @@ -1,19 +1,19 @@ // Original file: deps/googleapis/google/api/http.proto -import type { HttpRule as _google_api_HttpRule, HttpRule__Output as _google_api_HttpRule__Output } from '../../google/api/HttpRule'; +import type { IHttpRule as I_google_api_HttpRule, OHttpRule as O_google_api_HttpRule } from '../../google/api/HttpRule'; /** * Defines the HTTP configuration for an API service. It contains a list of * [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method * to one or more HTTP REST API methods. */ -export interface Http { +export interface IHttp { /** * A list of HTTP configuration rules that apply to individual API methods. * * **NOTE:** All service configuration rules follow "last one wins" order. */ - 'rules'?: (_google_api_HttpRule)[]; + 'rules'?: (I_google_api_HttpRule)[]; /** * When set to true, URL path parameters will be fully URI-decoded except in * cases of single segment matches in reserved expansion, where "%2F" will be @@ -30,13 +30,13 @@ export interface Http { * [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method * to one or more HTTP REST API methods. */ -export interface Http__Output { +export interface OHttp { /** * A list of HTTP configuration rules that apply to individual API methods. * * **NOTE:** All service configuration rules follow "last one wins" order. */ - 'rules': (_google_api_HttpRule__Output)[]; + 'rules': (O_google_api_HttpRule)[]; /** * When set to true, URL path parameters will be fully URI-decoded except in * cases of single segment matches in reserved expansion, where "%2F" will be diff --git a/packages/proto-loader/golden-generated/google/api/HttpRule.ts b/packages/proto-loader/golden-generated/google/api/HttpRule.ts index 243a99f80..90efdc00d 100644 --- a/packages/proto-loader/golden-generated/google/api/HttpRule.ts +++ b/packages/proto-loader/golden-generated/google/api/HttpRule.ts @@ -1,7 +1,7 @@ // Original file: deps/googleapis/google/api/http.proto -import type { CustomHttpPattern as _google_api_CustomHttpPattern, CustomHttpPattern__Output as _google_api_CustomHttpPattern__Output } from '../../google/api/CustomHttpPattern'; -import type { HttpRule as _google_api_HttpRule, HttpRule__Output as _google_api_HttpRule__Output } from '../../google/api/HttpRule'; +import type { ICustomHttpPattern as I_google_api_CustomHttpPattern, OCustomHttpPattern as O_google_api_CustomHttpPattern } from '../../google/api/CustomHttpPattern'; +import type { IHttpRule as I_google_api_HttpRule, OHttpRule as O_google_api_HttpRule } from '../../google/api/HttpRule'; /** * # gRPC Transcoding @@ -274,7 +274,7 @@ import type { HttpRule as _google_api_HttpRule, HttpRule__Output as _google_api_ * the request or response body to a repeated field. However, some gRPC * Transcoding implementations may not support this feature. */ -export interface HttpRule { +export interface IHttpRule { /** * Selects a method to which this rule applies. * @@ -317,13 +317,13 @@ export interface HttpRule { * HTTP method unspecified for this rule. The wild-card rule is useful * for services that provide content to Web (HTML) clients. */ - 'custom'?: (_google_api_CustomHttpPattern | null); + 'custom'?: (I_google_api_CustomHttpPattern | null); /** * Additional HTTP bindings for the selector. Nested bindings must * not contain an `additional_bindings` field themselves (that is, * the nesting may only be one level deep). */ - 'additional_bindings'?: (_google_api_HttpRule)[]; + 'additional_bindings'?: (I_google_api_HttpRule)[]; /** * Optional. The name of the response field whose value is mapped to the HTTP * response body. When omitted, the entire response message will be used @@ -612,7 +612,7 @@ export interface HttpRule { * the request or response body to a repeated field. However, some gRPC * Transcoding implementations may not support this feature. */ -export interface HttpRule__Output { +export interface OHttpRule { /** * Selects a method to which this rule applies. * @@ -655,13 +655,13 @@ export interface HttpRule__Output { * HTTP method unspecified for this rule. The wild-card rule is useful * for services that provide content to Web (HTML) clients. */ - 'custom'?: (_google_api_CustomHttpPattern__Output | null); + 'custom'?: (O_google_api_CustomHttpPattern | null); /** * Additional HTTP bindings for the selector. Nested bindings must * not contain an `additional_bindings` field themselves (that is, * the nesting may only be one level deep). */ - 'additional_bindings': (_google_api_HttpRule__Output)[]; + 'additional_bindings': (O_google_api_HttpRule)[]; /** * Optional. The name of the response field whose value is mapped to the HTTP * response body. When omitted, the entire response message will be used diff --git a/packages/proto-loader/golden-generated/google/longrunning/CancelOperationRequest.ts b/packages/proto-loader/golden-generated/google/longrunning/CancelOperationRequest.ts index 05fbc842e..7e0f15ed8 100644 --- a/packages/proto-loader/golden-generated/google/longrunning/CancelOperationRequest.ts +++ b/packages/proto-loader/golden-generated/google/longrunning/CancelOperationRequest.ts @@ -4,7 +4,7 @@ /** * The request message for [Operations.CancelOperation][google.longrunning.Operations.CancelOperation]. */ -export interface CancelOperationRequest { +export interface ICancelOperationRequest { /** * The name of the operation resource to be cancelled. */ @@ -14,7 +14,7 @@ export interface CancelOperationRequest { /** * The request message for [Operations.CancelOperation][google.longrunning.Operations.CancelOperation]. */ -export interface CancelOperationRequest__Output { +export interface OCancelOperationRequest { /** * The name of the operation resource to be cancelled. */ diff --git a/packages/proto-loader/golden-generated/google/longrunning/DeleteOperationRequest.ts b/packages/proto-loader/golden-generated/google/longrunning/DeleteOperationRequest.ts index 0ad87cde9..39d669d0a 100644 --- a/packages/proto-loader/golden-generated/google/longrunning/DeleteOperationRequest.ts +++ b/packages/proto-loader/golden-generated/google/longrunning/DeleteOperationRequest.ts @@ -4,7 +4,7 @@ /** * The request message for [Operations.DeleteOperation][google.longrunning.Operations.DeleteOperation]. */ -export interface DeleteOperationRequest { +export interface IDeleteOperationRequest { /** * The name of the operation resource to be deleted. */ @@ -14,7 +14,7 @@ export interface DeleteOperationRequest { /** * The request message for [Operations.DeleteOperation][google.longrunning.Operations.DeleteOperation]. */ -export interface DeleteOperationRequest__Output { +export interface ODeleteOperationRequest { /** * The name of the operation resource to be deleted. */ diff --git a/packages/proto-loader/golden-generated/google/longrunning/GetOperationRequest.ts b/packages/proto-loader/golden-generated/google/longrunning/GetOperationRequest.ts index 039f01674..9667e2e87 100644 --- a/packages/proto-loader/golden-generated/google/longrunning/GetOperationRequest.ts +++ b/packages/proto-loader/golden-generated/google/longrunning/GetOperationRequest.ts @@ -4,7 +4,7 @@ /** * The request message for [Operations.GetOperation][google.longrunning.Operations.GetOperation]. */ -export interface GetOperationRequest { +export interface IGetOperationRequest { /** * The name of the operation resource. */ @@ -14,7 +14,7 @@ export interface GetOperationRequest { /** * The request message for [Operations.GetOperation][google.longrunning.Operations.GetOperation]. */ -export interface GetOperationRequest__Output { +export interface OGetOperationRequest { /** * The name of the operation resource. */ diff --git a/packages/proto-loader/golden-generated/google/longrunning/ListOperationsRequest.ts b/packages/proto-loader/golden-generated/google/longrunning/ListOperationsRequest.ts index 294ec6773..49dcd39f0 100644 --- a/packages/proto-loader/golden-generated/google/longrunning/ListOperationsRequest.ts +++ b/packages/proto-loader/golden-generated/google/longrunning/ListOperationsRequest.ts @@ -4,7 +4,7 @@ /** * The request message for [Operations.ListOperations][google.longrunning.Operations.ListOperations]. */ -export interface ListOperationsRequest { +export interface IListOperationsRequest { /** * The standard list filter. */ @@ -26,7 +26,7 @@ export interface ListOperationsRequest { /** * The request message for [Operations.ListOperations][google.longrunning.Operations.ListOperations]. */ -export interface ListOperationsRequest__Output { +export interface OListOperationsRequest { /** * The standard list filter. */ diff --git a/packages/proto-loader/golden-generated/google/longrunning/ListOperationsResponse.ts b/packages/proto-loader/golden-generated/google/longrunning/ListOperationsResponse.ts index c295aa801..1e8b9ed5a 100644 --- a/packages/proto-loader/golden-generated/google/longrunning/ListOperationsResponse.ts +++ b/packages/proto-loader/golden-generated/google/longrunning/ListOperationsResponse.ts @@ -1,15 +1,15 @@ // Original file: deps/googleapis/google/longrunning/operations.proto -import type { Operation as _google_longrunning_Operation, Operation__Output as _google_longrunning_Operation__Output } from '../../google/longrunning/Operation'; +import type { IOperation as I_google_longrunning_Operation, OOperation as O_google_longrunning_Operation } from '../../google/longrunning/Operation'; /** * The response message for [Operations.ListOperations][google.longrunning.Operations.ListOperations]. */ -export interface ListOperationsResponse { +export interface IListOperationsResponse { /** * A list of operations that matches the specified filter in the request. */ - 'operations'?: (_google_longrunning_Operation)[]; + 'operations'?: (I_google_longrunning_Operation)[]; /** * The standard List next-page token. */ @@ -19,11 +19,11 @@ export interface ListOperationsResponse { /** * The response message for [Operations.ListOperations][google.longrunning.Operations.ListOperations]. */ -export interface ListOperationsResponse__Output { +export interface OListOperationsResponse { /** * A list of operations that matches the specified filter in the request. */ - 'operations': (_google_longrunning_Operation__Output)[]; + 'operations': (O_google_longrunning_Operation)[]; /** * The standard List next-page token. */ diff --git a/packages/proto-loader/golden-generated/google/longrunning/Operation.ts b/packages/proto-loader/golden-generated/google/longrunning/Operation.ts index 2a4bbe1ee..bbd1d8078 100644 --- a/packages/proto-loader/golden-generated/google/longrunning/Operation.ts +++ b/packages/proto-loader/golden-generated/google/longrunning/Operation.ts @@ -1,13 +1,13 @@ // Original file: deps/googleapis/google/longrunning/operations.proto -import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../google/protobuf/Any'; -import type { Status as _google_rpc_Status, Status__Output as _google_rpc_Status__Output } from '../../google/rpc/Status'; +import type { IAny as I_google_protobuf_Any, OAny as O_google_protobuf_Any } from '../../google/protobuf/Any'; +import type { IStatus as I_google_rpc_Status, OStatus as O_google_rpc_Status } from '../../google/rpc/Status'; /** * This resource represents a long-running operation that is the result of a * network API call. */ -export interface Operation { +export interface IOperation { /** * The server-assigned name, which is only unique within the same service that * originally returns it. If you use the default HTTP mapping, the @@ -20,7 +20,7 @@ export interface Operation { * Some services might not provide such metadata. Any method that returns a * long-running operation should document the metadata type, if any. */ - 'metadata'?: (_google_protobuf_Any | null); + 'metadata'?: (I_google_protobuf_Any | null); /** * If the value is `false`, it means the operation is still in progress. * If `true`, the operation is completed, and either `error` or `response` is @@ -30,7 +30,7 @@ export interface Operation { /** * The error result of the operation in case of failure or cancellation. */ - 'error'?: (_google_rpc_Status | null); + 'error'?: (I_google_rpc_Status | null); /** * The normal response of the operation in case of success. If the original * method returns no data on success, such as `Delete`, the response is @@ -41,7 +41,7 @@ export interface Operation { * is `TakeSnapshot()`, the inferred response type is * `TakeSnapshotResponse`. */ - 'response'?: (_google_protobuf_Any | null); + 'response'?: (I_google_protobuf_Any | null); /** * The operation result, which can be either an `error` or a valid `response`. * If `done` == `false`, neither `error` nor `response` is set. @@ -54,7 +54,7 @@ export interface Operation { * This resource represents a long-running operation that is the result of a * network API call. */ -export interface Operation__Output { +export interface OOperation { /** * The server-assigned name, which is only unique within the same service that * originally returns it. If you use the default HTTP mapping, the @@ -67,7 +67,7 @@ export interface Operation__Output { * Some services might not provide such metadata. Any method that returns a * long-running operation should document the metadata type, if any. */ - 'metadata': (_google_protobuf_Any__Output | null); + 'metadata': (O_google_protobuf_Any | null); /** * If the value is `false`, it means the operation is still in progress. * If `true`, the operation is completed, and either `error` or `response` is @@ -77,7 +77,7 @@ export interface Operation__Output { /** * The error result of the operation in case of failure or cancellation. */ - 'error'?: (_google_rpc_Status__Output | null); + 'error'?: (O_google_rpc_Status | null); /** * The normal response of the operation in case of success. If the original * method returns no data on success, such as `Delete`, the response is @@ -88,7 +88,7 @@ export interface Operation__Output { * is `TakeSnapshot()`, the inferred response type is * `TakeSnapshotResponse`. */ - 'response'?: (_google_protobuf_Any__Output | null); + 'response'?: (O_google_protobuf_Any | null); /** * The operation result, which can be either an `error` or a valid `response`. * If `done` == `false`, neither `error` nor `response` is set. diff --git a/packages/proto-loader/golden-generated/google/longrunning/OperationInfo.ts b/packages/proto-loader/golden-generated/google/longrunning/OperationInfo.ts index 343e2f8c9..907574412 100644 --- a/packages/proto-loader/golden-generated/google/longrunning/OperationInfo.ts +++ b/packages/proto-loader/golden-generated/google/longrunning/OperationInfo.ts @@ -14,7 +14,7 @@ * }; * } */ -export interface OperationInfo { +export interface IOperationInfo { /** * Required. The message name of the primary return type for this * long-running operation. @@ -51,7 +51,7 @@ export interface OperationInfo { * }; * } */ -export interface OperationInfo__Output { +export interface OOperationInfo { /** * Required. The message name of the primary return type for this * long-running operation. diff --git a/packages/proto-loader/golden-generated/google/longrunning/Operations.ts b/packages/proto-loader/golden-generated/google/longrunning/Operations.ts index 6358cbbfd..00d6a95d2 100644 --- a/packages/proto-loader/golden-generated/google/longrunning/Operations.ts +++ b/packages/proto-loader/golden-generated/google/longrunning/Operations.ts @@ -2,14 +2,14 @@ import type * as grpc from '@grpc/grpc-js' import type { MethodDefinition } from '@grpc/proto-loader' -import type { CancelOperationRequest as _google_longrunning_CancelOperationRequest, CancelOperationRequest__Output as _google_longrunning_CancelOperationRequest__Output } from '../../google/longrunning/CancelOperationRequest'; -import type { DeleteOperationRequest as _google_longrunning_DeleteOperationRequest, DeleteOperationRequest__Output as _google_longrunning_DeleteOperationRequest__Output } from '../../google/longrunning/DeleteOperationRequest'; -import type { Empty as _google_protobuf_Empty, Empty__Output as _google_protobuf_Empty__Output } from '../../google/protobuf/Empty'; -import type { GetOperationRequest as _google_longrunning_GetOperationRequest, GetOperationRequest__Output as _google_longrunning_GetOperationRequest__Output } from '../../google/longrunning/GetOperationRequest'; -import type { ListOperationsRequest as _google_longrunning_ListOperationsRequest, ListOperationsRequest__Output as _google_longrunning_ListOperationsRequest__Output } from '../../google/longrunning/ListOperationsRequest'; -import type { ListOperationsResponse as _google_longrunning_ListOperationsResponse, ListOperationsResponse__Output as _google_longrunning_ListOperationsResponse__Output } from '../../google/longrunning/ListOperationsResponse'; -import type { Operation as _google_longrunning_Operation, Operation__Output as _google_longrunning_Operation__Output } from '../../google/longrunning/Operation'; -import type { WaitOperationRequest as _google_longrunning_WaitOperationRequest, WaitOperationRequest__Output as _google_longrunning_WaitOperationRequest__Output } from '../../google/longrunning/WaitOperationRequest'; +import type { ICancelOperationRequest as I_google_longrunning_CancelOperationRequest, OCancelOperationRequest as O_google_longrunning_CancelOperationRequest } from '../../google/longrunning/CancelOperationRequest'; +import type { IDeleteOperationRequest as I_google_longrunning_DeleteOperationRequest, ODeleteOperationRequest as O_google_longrunning_DeleteOperationRequest } from '../../google/longrunning/DeleteOperationRequest'; +import type { IEmpty as I_google_protobuf_Empty, OEmpty as O_google_protobuf_Empty } from '../../google/protobuf/Empty'; +import type { IGetOperationRequest as I_google_longrunning_GetOperationRequest, OGetOperationRequest as O_google_longrunning_GetOperationRequest } from '../../google/longrunning/GetOperationRequest'; +import type { IListOperationsRequest as I_google_longrunning_ListOperationsRequest, OListOperationsRequest as O_google_longrunning_ListOperationsRequest } from '../../google/longrunning/ListOperationsRequest'; +import type { IListOperationsResponse as I_google_longrunning_ListOperationsResponse, OListOperationsResponse as O_google_longrunning_ListOperationsResponse } from '../../google/longrunning/ListOperationsResponse'; +import type { IOperation as I_google_longrunning_Operation, OOperation as O_google_longrunning_Operation } from '../../google/longrunning/Operation'; +import type { IWaitOperationRequest as I_google_longrunning_WaitOperationRequest, OWaitOperationRequest as O_google_longrunning_WaitOperationRequest } from '../../google/longrunning/WaitOperationRequest'; /** * Manages long-running operations with an API service. @@ -35,10 +35,10 @@ export interface OperationsClient extends grpc.Client { * an [Operation.error][google.longrunning.Operation.error] value with a [google.rpc.Status.code][google.rpc.Status.code] of 1, * corresponding to `Code.CANCELLED`. */ - CancelOperation(argument: _google_longrunning_CancelOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; - CancelOperation(argument: _google_longrunning_CancelOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; - CancelOperation(argument: _google_longrunning_CancelOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; - CancelOperation(argument: _google_longrunning_CancelOperationRequest, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; + CancelOperation(argument: I_google_longrunning_CancelOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + CancelOperation(argument: I_google_longrunning_CancelOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback): grpc.ClientUnaryCall; + CancelOperation(argument: I_google_longrunning_CancelOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + CancelOperation(argument: I_google_longrunning_CancelOperationRequest, callback: grpc.requestCallback): grpc.ClientUnaryCall; /** * Starts asynchronous cancellation on a long-running operation. The server * makes a best effort to cancel the operation, but success is not @@ -51,10 +51,10 @@ export interface OperationsClient extends grpc.Client { * an [Operation.error][google.longrunning.Operation.error] value with a [google.rpc.Status.code][google.rpc.Status.code] of 1, * corresponding to `Code.CANCELLED`. */ - cancelOperation(argument: _google_longrunning_CancelOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; - cancelOperation(argument: _google_longrunning_CancelOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; - cancelOperation(argument: _google_longrunning_CancelOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; - cancelOperation(argument: _google_longrunning_CancelOperationRequest, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; + cancelOperation(argument: I_google_longrunning_CancelOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + cancelOperation(argument: I_google_longrunning_CancelOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback): grpc.ClientUnaryCall; + cancelOperation(argument: I_google_longrunning_CancelOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + cancelOperation(argument: I_google_longrunning_CancelOperationRequest, callback: grpc.requestCallback): grpc.ClientUnaryCall; /** * Deletes a long-running operation. This method indicates that the client is @@ -62,39 +62,39 @@ export interface OperationsClient extends grpc.Client { * operation. If the server doesn't support this method, it returns * `google.rpc.Code.UNIMPLEMENTED`. */ - DeleteOperation(argument: _google_longrunning_DeleteOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; - DeleteOperation(argument: _google_longrunning_DeleteOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; - DeleteOperation(argument: _google_longrunning_DeleteOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; - DeleteOperation(argument: _google_longrunning_DeleteOperationRequest, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; + DeleteOperation(argument: I_google_longrunning_DeleteOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + DeleteOperation(argument: I_google_longrunning_DeleteOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback): grpc.ClientUnaryCall; + DeleteOperation(argument: I_google_longrunning_DeleteOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + DeleteOperation(argument: I_google_longrunning_DeleteOperationRequest, callback: grpc.requestCallback): grpc.ClientUnaryCall; /** * Deletes a long-running operation. This method indicates that the client is * no longer interested in the operation result. It does not cancel the * operation. If the server doesn't support this method, it returns * `google.rpc.Code.UNIMPLEMENTED`. */ - deleteOperation(argument: _google_longrunning_DeleteOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; - deleteOperation(argument: _google_longrunning_DeleteOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; - deleteOperation(argument: _google_longrunning_DeleteOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; - deleteOperation(argument: _google_longrunning_DeleteOperationRequest, callback: grpc.requestCallback<_google_protobuf_Empty__Output>): grpc.ClientUnaryCall; + deleteOperation(argument: I_google_longrunning_DeleteOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + deleteOperation(argument: I_google_longrunning_DeleteOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback): grpc.ClientUnaryCall; + deleteOperation(argument: I_google_longrunning_DeleteOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + deleteOperation(argument: I_google_longrunning_DeleteOperationRequest, callback: grpc.requestCallback): grpc.ClientUnaryCall; /** * Gets the latest state of a long-running operation. Clients can use this * method to poll the operation result at intervals as recommended by the API * service. */ - GetOperation(argument: _google_longrunning_GetOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; - GetOperation(argument: _google_longrunning_GetOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; - GetOperation(argument: _google_longrunning_GetOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; - GetOperation(argument: _google_longrunning_GetOperationRequest, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + GetOperation(argument: I_google_longrunning_GetOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + GetOperation(argument: I_google_longrunning_GetOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback): grpc.ClientUnaryCall; + GetOperation(argument: I_google_longrunning_GetOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + GetOperation(argument: I_google_longrunning_GetOperationRequest, callback: grpc.requestCallback): grpc.ClientUnaryCall; /** * Gets the latest state of a long-running operation. Clients can use this * method to poll the operation result at intervals as recommended by the API * service. */ - getOperation(argument: _google_longrunning_GetOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; - getOperation(argument: _google_longrunning_GetOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; - getOperation(argument: _google_longrunning_GetOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; - getOperation(argument: _google_longrunning_GetOperationRequest, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + getOperation(argument: I_google_longrunning_GetOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + getOperation(argument: I_google_longrunning_GetOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback): grpc.ClientUnaryCall; + getOperation(argument: I_google_longrunning_GetOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + getOperation(argument: I_google_longrunning_GetOperationRequest, callback: grpc.requestCallback): grpc.ClientUnaryCall; /** * Lists operations that match the specified filter in the request. If the @@ -108,10 +108,10 @@ export interface OperationsClient extends grpc.Client { * collection id, however overriding users must ensure the name binding * is the parent resource, without the operations collection id. */ - ListOperations(argument: _google_longrunning_ListOperationsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_ListOperationsResponse__Output>): grpc.ClientUnaryCall; - ListOperations(argument: _google_longrunning_ListOperationsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_longrunning_ListOperationsResponse__Output>): grpc.ClientUnaryCall; - ListOperations(argument: _google_longrunning_ListOperationsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_ListOperationsResponse__Output>): grpc.ClientUnaryCall; - ListOperations(argument: _google_longrunning_ListOperationsRequest, callback: grpc.requestCallback<_google_longrunning_ListOperationsResponse__Output>): grpc.ClientUnaryCall; + ListOperations(argument: I_google_longrunning_ListOperationsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + ListOperations(argument: I_google_longrunning_ListOperationsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback): grpc.ClientUnaryCall; + ListOperations(argument: I_google_longrunning_ListOperationsRequest, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + ListOperations(argument: I_google_longrunning_ListOperationsRequest, callback: grpc.requestCallback): grpc.ClientUnaryCall; /** * Lists operations that match the specified filter in the request. If the * server doesn't support this method, it returns `UNIMPLEMENTED`. @@ -124,10 +124,10 @@ export interface OperationsClient extends grpc.Client { * collection id, however overriding users must ensure the name binding * is the parent resource, without the operations collection id. */ - listOperations(argument: _google_longrunning_ListOperationsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_ListOperationsResponse__Output>): grpc.ClientUnaryCall; - listOperations(argument: _google_longrunning_ListOperationsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_longrunning_ListOperationsResponse__Output>): grpc.ClientUnaryCall; - listOperations(argument: _google_longrunning_ListOperationsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_ListOperationsResponse__Output>): grpc.ClientUnaryCall; - listOperations(argument: _google_longrunning_ListOperationsRequest, callback: grpc.requestCallback<_google_longrunning_ListOperationsResponse__Output>): grpc.ClientUnaryCall; + listOperations(argument: I_google_longrunning_ListOperationsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + listOperations(argument: I_google_longrunning_ListOperationsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback): grpc.ClientUnaryCall; + listOperations(argument: I_google_longrunning_ListOperationsRequest, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + listOperations(argument: I_google_longrunning_ListOperationsRequest, callback: grpc.requestCallback): grpc.ClientUnaryCall; /** * Waits for the specified long-running operation until it is done or reaches @@ -140,10 +140,10 @@ export interface OperationsClient extends grpc.Client { * state before the specified timeout (including immediately), meaning even an * immediate response is no guarantee that the operation is done. */ - WaitOperation(argument: _google_longrunning_WaitOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; - WaitOperation(argument: _google_longrunning_WaitOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; - WaitOperation(argument: _google_longrunning_WaitOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; - WaitOperation(argument: _google_longrunning_WaitOperationRequest, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + WaitOperation(argument: I_google_longrunning_WaitOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + WaitOperation(argument: I_google_longrunning_WaitOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback): grpc.ClientUnaryCall; + WaitOperation(argument: I_google_longrunning_WaitOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + WaitOperation(argument: I_google_longrunning_WaitOperationRequest, callback: grpc.requestCallback): grpc.ClientUnaryCall; /** * Waits for the specified long-running operation until it is done or reaches * at most a specified timeout, returning the latest state. If the operation @@ -155,10 +155,10 @@ export interface OperationsClient extends grpc.Client { * state before the specified timeout (including immediately), meaning even an * immediate response is no guarantee that the operation is done. */ - waitOperation(argument: _google_longrunning_WaitOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; - waitOperation(argument: _google_longrunning_WaitOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; - waitOperation(argument: _google_longrunning_WaitOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; - waitOperation(argument: _google_longrunning_WaitOperationRequest, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + waitOperation(argument: I_google_longrunning_WaitOperationRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + waitOperation(argument: I_google_longrunning_WaitOperationRequest, metadata: grpc.Metadata, callback: grpc.requestCallback): grpc.ClientUnaryCall; + waitOperation(argument: I_google_longrunning_WaitOperationRequest, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + waitOperation(argument: I_google_longrunning_WaitOperationRequest, callback: grpc.requestCallback): grpc.ClientUnaryCall; } @@ -186,7 +186,7 @@ export interface OperationsHandlers extends grpc.UntypedServiceImplementation { * an [Operation.error][google.longrunning.Operation.error] value with a [google.rpc.Status.code][google.rpc.Status.code] of 1, * corresponding to `Code.CANCELLED`. */ - CancelOperation: grpc.handleUnaryCall<_google_longrunning_CancelOperationRequest__Output, _google_protobuf_Empty>; + CancelOperation: grpc.handleUnaryCall; /** * Deletes a long-running operation. This method indicates that the client is @@ -194,14 +194,14 @@ export interface OperationsHandlers extends grpc.UntypedServiceImplementation { * operation. If the server doesn't support this method, it returns * `google.rpc.Code.UNIMPLEMENTED`. */ - DeleteOperation: grpc.handleUnaryCall<_google_longrunning_DeleteOperationRequest__Output, _google_protobuf_Empty>; + DeleteOperation: grpc.handleUnaryCall; /** * Gets the latest state of a long-running operation. Clients can use this * method to poll the operation result at intervals as recommended by the API * service. */ - GetOperation: grpc.handleUnaryCall<_google_longrunning_GetOperationRequest__Output, _google_longrunning_Operation>; + GetOperation: grpc.handleUnaryCall; /** * Lists operations that match the specified filter in the request. If the @@ -215,7 +215,7 @@ export interface OperationsHandlers extends grpc.UntypedServiceImplementation { * collection id, however overriding users must ensure the name binding * is the parent resource, without the operations collection id. */ - ListOperations: grpc.handleUnaryCall<_google_longrunning_ListOperationsRequest__Output, _google_longrunning_ListOperationsResponse>; + ListOperations: grpc.handleUnaryCall; /** * Waits for the specified long-running operation until it is done or reaches @@ -228,14 +228,14 @@ export interface OperationsHandlers extends grpc.UntypedServiceImplementation { * state before the specified timeout (including immediately), meaning even an * immediate response is no guarantee that the operation is done. */ - WaitOperation: grpc.handleUnaryCall<_google_longrunning_WaitOperationRequest__Output, _google_longrunning_Operation>; + WaitOperation: grpc.handleUnaryCall; } export interface OperationsDefinition extends grpc.ServiceDefinition { - CancelOperation: MethodDefinition<_google_longrunning_CancelOperationRequest, _google_protobuf_Empty, _google_longrunning_CancelOperationRequest__Output, _google_protobuf_Empty__Output> - DeleteOperation: MethodDefinition<_google_longrunning_DeleteOperationRequest, _google_protobuf_Empty, _google_longrunning_DeleteOperationRequest__Output, _google_protobuf_Empty__Output> - GetOperation: MethodDefinition<_google_longrunning_GetOperationRequest, _google_longrunning_Operation, _google_longrunning_GetOperationRequest__Output, _google_longrunning_Operation__Output> - ListOperations: MethodDefinition<_google_longrunning_ListOperationsRequest, _google_longrunning_ListOperationsResponse, _google_longrunning_ListOperationsRequest__Output, _google_longrunning_ListOperationsResponse__Output> - WaitOperation: MethodDefinition<_google_longrunning_WaitOperationRequest, _google_longrunning_Operation, _google_longrunning_WaitOperationRequest__Output, _google_longrunning_Operation__Output> + CancelOperation: MethodDefinition + DeleteOperation: MethodDefinition + GetOperation: MethodDefinition + ListOperations: MethodDefinition + WaitOperation: MethodDefinition } diff --git a/packages/proto-loader/golden-generated/google/longrunning/WaitOperationRequest.ts b/packages/proto-loader/golden-generated/google/longrunning/WaitOperationRequest.ts index f97e39dc4..2f11f7580 100644 --- a/packages/proto-loader/golden-generated/google/longrunning/WaitOperationRequest.ts +++ b/packages/proto-loader/golden-generated/google/longrunning/WaitOperationRequest.ts @@ -1,11 +1,11 @@ // Original file: deps/googleapis/google/longrunning/operations.proto -import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../google/protobuf/Duration'; +import type { IDuration as I_google_protobuf_Duration, ODuration as O_google_protobuf_Duration } from '../../google/protobuf/Duration'; /** * The request message for [Operations.WaitOperation][google.longrunning.Operations.WaitOperation]. */ -export interface WaitOperationRequest { +export interface IWaitOperationRequest { /** * The name of the operation resource to wait on. */ @@ -15,13 +15,13 @@ export interface WaitOperationRequest { * will be at most the time permitted by the underlying HTTP/RPC protocol. * If RPC context deadline is also specified, the shorter one will be used. */ - 'timeout'?: (_google_protobuf_Duration | null); + 'timeout'?: (I_google_protobuf_Duration | null); } /** * The request message for [Operations.WaitOperation][google.longrunning.Operations.WaitOperation]. */ -export interface WaitOperationRequest__Output { +export interface OWaitOperationRequest { /** * The name of the operation resource to wait on. */ @@ -31,5 +31,5 @@ export interface WaitOperationRequest__Output { * will be at most the time permitted by the underlying HTTP/RPC protocol. * If RPC context deadline is also specified, the shorter one will be used. */ - 'timeout': (_google_protobuf_Duration__Output | null); + 'timeout': (O_google_protobuf_Duration | null); } diff --git a/packages/proto-loader/golden-generated/google/protobuf/Any.ts b/packages/proto-loader/golden-generated/google/protobuf/Any.ts index fe0d05f12..d9ee4e200 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/Any.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/Any.ts @@ -2,12 +2,12 @@ import type { AnyExtension } from '@grpc/proto-loader'; -export type Any = AnyExtension | { +export type IAny = AnyExtension | { type_url: string; value: Buffer | Uint8Array | string; } -export type Any__Output = AnyExtension | { +export type OAny = AnyExtension | { type_url: string; value: Buffer; } diff --git a/packages/proto-loader/golden-generated/google/protobuf/DescriptorProto.ts b/packages/proto-loader/golden-generated/google/protobuf/DescriptorProto.ts index f729437f4..5f568ca2c 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/DescriptorProto.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/DescriptorProto.ts @@ -1,53 +1,53 @@ // Original file: null -import type { FieldDescriptorProto as _google_protobuf_FieldDescriptorProto, FieldDescriptorProto__Output as _google_protobuf_FieldDescriptorProto__Output } from '../../google/protobuf/FieldDescriptorProto'; -import type { DescriptorProto as _google_protobuf_DescriptorProto, DescriptorProto__Output as _google_protobuf_DescriptorProto__Output } from '../../google/protobuf/DescriptorProto'; -import type { EnumDescriptorProto as _google_protobuf_EnumDescriptorProto, EnumDescriptorProto__Output as _google_protobuf_EnumDescriptorProto__Output } from '../../google/protobuf/EnumDescriptorProto'; -import type { MessageOptions as _google_protobuf_MessageOptions, MessageOptions__Output as _google_protobuf_MessageOptions__Output } from '../../google/protobuf/MessageOptions'; -import type { OneofDescriptorProto as _google_protobuf_OneofDescriptorProto, OneofDescriptorProto__Output as _google_protobuf_OneofDescriptorProto__Output } from '../../google/protobuf/OneofDescriptorProto'; +import type { IFieldDescriptorProto as I_google_protobuf_FieldDescriptorProto, OFieldDescriptorProto as O_google_protobuf_FieldDescriptorProto } from '../../google/protobuf/FieldDescriptorProto'; +import type { IDescriptorProto as I_google_protobuf_DescriptorProto, ODescriptorProto as O_google_protobuf_DescriptorProto } from '../../google/protobuf/DescriptorProto'; +import type { IEnumDescriptorProto as I_google_protobuf_EnumDescriptorProto, OEnumDescriptorProto as O_google_protobuf_EnumDescriptorProto } from '../../google/protobuf/EnumDescriptorProto'; +import type { IMessageOptions as I_google_protobuf_MessageOptions, OMessageOptions as O_google_protobuf_MessageOptions } from '../../google/protobuf/MessageOptions'; +import type { IOneofDescriptorProto as I_google_protobuf_OneofDescriptorProto, OOneofDescriptorProto as O_google_protobuf_OneofDescriptorProto } from '../../google/protobuf/OneofDescriptorProto'; -export interface _google_protobuf_DescriptorProto_ExtensionRange { +export interface I_google_protobuf_DescriptorProto_ExtensionRange { 'start'?: (number); 'end'?: (number); } -export interface _google_protobuf_DescriptorProto_ExtensionRange__Output { +export interface O_google_protobuf_DescriptorProto_ExtensionRange { 'start': (number); 'end': (number); } -export interface _google_protobuf_DescriptorProto_ReservedRange { +export interface I_google_protobuf_DescriptorProto_ReservedRange { 'start'?: (number); 'end'?: (number); } -export interface _google_protobuf_DescriptorProto_ReservedRange__Output { +export interface O_google_protobuf_DescriptorProto_ReservedRange { 'start': (number); 'end': (number); } -export interface DescriptorProto { +export interface IDescriptorProto { 'name'?: (string); - 'field'?: (_google_protobuf_FieldDescriptorProto)[]; - 'nestedType'?: (_google_protobuf_DescriptorProto)[]; - 'enumType'?: (_google_protobuf_EnumDescriptorProto)[]; - 'extensionRange'?: (_google_protobuf_DescriptorProto_ExtensionRange)[]; - 'extension'?: (_google_protobuf_FieldDescriptorProto)[]; - 'options'?: (_google_protobuf_MessageOptions | null); - 'oneofDecl'?: (_google_protobuf_OneofDescriptorProto)[]; - 'reservedRange'?: (_google_protobuf_DescriptorProto_ReservedRange)[]; + 'field'?: (I_google_protobuf_FieldDescriptorProto)[]; + 'nestedType'?: (I_google_protobuf_DescriptorProto)[]; + 'enumType'?: (I_google_protobuf_EnumDescriptorProto)[]; + 'extensionRange'?: (I_google_protobuf_DescriptorProto_ExtensionRange)[]; + 'extension'?: (I_google_protobuf_FieldDescriptorProto)[]; + 'options'?: (I_google_protobuf_MessageOptions | null); + 'oneofDecl'?: (I_google_protobuf_OneofDescriptorProto)[]; + 'reservedRange'?: (I_google_protobuf_DescriptorProto_ReservedRange)[]; 'reservedName'?: (string)[]; } -export interface DescriptorProto__Output { +export interface ODescriptorProto { 'name': (string); - 'field': (_google_protobuf_FieldDescriptorProto__Output)[]; - 'nestedType': (_google_protobuf_DescriptorProto__Output)[]; - 'enumType': (_google_protobuf_EnumDescriptorProto__Output)[]; - 'extensionRange': (_google_protobuf_DescriptorProto_ExtensionRange__Output)[]; - 'extension': (_google_protobuf_FieldDescriptorProto__Output)[]; - 'options': (_google_protobuf_MessageOptions__Output | null); - 'oneofDecl': (_google_protobuf_OneofDescriptorProto__Output)[]; - 'reservedRange': (_google_protobuf_DescriptorProto_ReservedRange__Output)[]; + 'field': (O_google_protobuf_FieldDescriptorProto)[]; + 'nestedType': (O_google_protobuf_DescriptorProto)[]; + 'enumType': (O_google_protobuf_EnumDescriptorProto)[]; + 'extensionRange': (O_google_protobuf_DescriptorProto_ExtensionRange)[]; + 'extension': (O_google_protobuf_FieldDescriptorProto)[]; + 'options': (O_google_protobuf_MessageOptions | null); + 'oneofDecl': (O_google_protobuf_OneofDescriptorProto)[]; + 'reservedRange': (O_google_protobuf_DescriptorProto_ReservedRange)[]; 'reservedName': (string)[]; } diff --git a/packages/proto-loader/golden-generated/google/protobuf/Duration.ts b/packages/proto-loader/golden-generated/google/protobuf/Duration.ts index 8595377a0..d5e3be89a 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/Duration.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/Duration.ts @@ -2,12 +2,12 @@ import type { Long } from '@grpc/proto-loader'; -export interface Duration { +export interface IDuration { 'seconds'?: (number | string | Long); 'nanos'?: (number); } -export interface Duration__Output { +export interface ODuration { 'seconds': (string); 'nanos': (number); } diff --git a/packages/proto-loader/golden-generated/google/protobuf/Empty.ts b/packages/proto-loader/golden-generated/google/protobuf/Empty.ts index f32c2a284..6594cc86c 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/Empty.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/Empty.ts @@ -1,8 +1,8 @@ // Original file: null -export interface Empty { +export interface IEmpty { } -export interface Empty__Output { +export interface OEmpty { } diff --git a/packages/proto-loader/golden-generated/google/protobuf/EnumDescriptorProto.ts b/packages/proto-loader/golden-generated/google/protobuf/EnumDescriptorProto.ts index dc4c9673e..30f52c610 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/EnumDescriptorProto.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/EnumDescriptorProto.ts @@ -1,16 +1,16 @@ // Original file: null -import type { EnumValueDescriptorProto as _google_protobuf_EnumValueDescriptorProto, EnumValueDescriptorProto__Output as _google_protobuf_EnumValueDescriptorProto__Output } from '../../google/protobuf/EnumValueDescriptorProto'; -import type { EnumOptions as _google_protobuf_EnumOptions, EnumOptions__Output as _google_protobuf_EnumOptions__Output } from '../../google/protobuf/EnumOptions'; +import type { IEnumValueDescriptorProto as I_google_protobuf_EnumValueDescriptorProto, OEnumValueDescriptorProto as O_google_protobuf_EnumValueDescriptorProto } from '../../google/protobuf/EnumValueDescriptorProto'; +import type { IEnumOptions as I_google_protobuf_EnumOptions, OEnumOptions as O_google_protobuf_EnumOptions } from '../../google/protobuf/EnumOptions'; -export interface EnumDescriptorProto { +export interface IEnumDescriptorProto { 'name'?: (string); - 'value'?: (_google_protobuf_EnumValueDescriptorProto)[]; - 'options'?: (_google_protobuf_EnumOptions | null); + 'value'?: (I_google_protobuf_EnumValueDescriptorProto)[]; + 'options'?: (I_google_protobuf_EnumOptions | null); } -export interface EnumDescriptorProto__Output { +export interface OEnumDescriptorProto { 'name': (string); - 'value': (_google_protobuf_EnumValueDescriptorProto__Output)[]; - 'options': (_google_protobuf_EnumOptions__Output | null); + 'value': (O_google_protobuf_EnumValueDescriptorProto)[]; + 'options': (O_google_protobuf_EnumOptions | null); } diff --git a/packages/proto-loader/golden-generated/google/protobuf/EnumOptions.ts b/packages/proto-loader/golden-generated/google/protobuf/EnumOptions.ts index b92ade4f9..6d2a0c2c6 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/EnumOptions.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/EnumOptions.ts @@ -1,15 +1,15 @@ // Original file: null -import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; +import type { IUninterpretedOption as I_google_protobuf_UninterpretedOption, OUninterpretedOption as O_google_protobuf_UninterpretedOption } from '../../google/protobuf/UninterpretedOption'; -export interface EnumOptions { +export interface IEnumOptions { 'allowAlias'?: (boolean); 'deprecated'?: (boolean); - 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; + 'uninterpretedOption'?: (I_google_protobuf_UninterpretedOption)[]; } -export interface EnumOptions__Output { +export interface OEnumOptions { 'allowAlias': (boolean); 'deprecated': (boolean); - 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; + 'uninterpretedOption': (O_google_protobuf_UninterpretedOption)[]; } diff --git a/packages/proto-loader/golden-generated/google/protobuf/EnumValueDescriptorProto.ts b/packages/proto-loader/golden-generated/google/protobuf/EnumValueDescriptorProto.ts index 7f8e57ea5..44cfcde4a 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/EnumValueDescriptorProto.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/EnumValueDescriptorProto.ts @@ -1,15 +1,15 @@ // Original file: null -import type { EnumValueOptions as _google_protobuf_EnumValueOptions, EnumValueOptions__Output as _google_protobuf_EnumValueOptions__Output } from '../../google/protobuf/EnumValueOptions'; +import type { IEnumValueOptions as I_google_protobuf_EnumValueOptions, OEnumValueOptions as O_google_protobuf_EnumValueOptions } from '../../google/protobuf/EnumValueOptions'; -export interface EnumValueDescriptorProto { +export interface IEnumValueDescriptorProto { 'name'?: (string); 'number'?: (number); - 'options'?: (_google_protobuf_EnumValueOptions | null); + 'options'?: (I_google_protobuf_EnumValueOptions | null); } -export interface EnumValueDescriptorProto__Output { +export interface OEnumValueDescriptorProto { 'name': (string); 'number': (number); - 'options': (_google_protobuf_EnumValueOptions__Output | null); + 'options': (O_google_protobuf_EnumValueOptions | null); } diff --git a/packages/proto-loader/golden-generated/google/protobuf/EnumValueOptions.ts b/packages/proto-loader/golden-generated/google/protobuf/EnumValueOptions.ts index e60ee6f4c..143381113 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/EnumValueOptions.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/EnumValueOptions.ts @@ -1,13 +1,13 @@ // Original file: null -import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; +import type { IUninterpretedOption as I_google_protobuf_UninterpretedOption, OUninterpretedOption as O_google_protobuf_UninterpretedOption } from '../../google/protobuf/UninterpretedOption'; -export interface EnumValueOptions { +export interface IEnumValueOptions { 'deprecated'?: (boolean); - 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; + 'uninterpretedOption'?: (I_google_protobuf_UninterpretedOption)[]; } -export interface EnumValueOptions__Output { +export interface OEnumValueOptions { 'deprecated': (boolean); - 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; + 'uninterpretedOption': (O_google_protobuf_UninterpretedOption)[]; } diff --git a/packages/proto-loader/golden-generated/google/protobuf/FieldDescriptorProto.ts b/packages/proto-loader/golden-generated/google/protobuf/FieldDescriptorProto.ts index c511e2eff..0a713e9dc 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/FieldDescriptorProto.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/FieldDescriptorProto.ts @@ -1,6 +1,6 @@ // Original file: null -import type { FieldOptions as _google_protobuf_FieldOptions, FieldOptions__Output as _google_protobuf_FieldOptions__Output } from '../../google/protobuf/FieldOptions'; +import type { IFieldOptions as I_google_protobuf_FieldOptions, OFieldOptions as O_google_protobuf_FieldOptions } from '../../google/protobuf/FieldOptions'; // Original file: null @@ -33,7 +33,7 @@ export enum _google_protobuf_FieldDescriptorProto_Type { TYPE_SINT64 = 18, } -export interface FieldDescriptorProto { +export interface IFieldDescriptorProto { 'name'?: (string); 'extendee'?: (string); 'number'?: (number); @@ -41,12 +41,12 @@ export interface FieldDescriptorProto { 'type'?: (_google_protobuf_FieldDescriptorProto_Type | keyof typeof _google_protobuf_FieldDescriptorProto_Type); 'typeName'?: (string); 'defaultValue'?: (string); - 'options'?: (_google_protobuf_FieldOptions | null); + 'options'?: (I_google_protobuf_FieldOptions | null); 'oneofIndex'?: (number); 'jsonName'?: (string); } -export interface FieldDescriptorProto__Output { +export interface OFieldDescriptorProto { 'name': (string); 'extendee': (string); 'number': (number); @@ -54,7 +54,7 @@ export interface FieldDescriptorProto__Output { 'type': (keyof typeof _google_protobuf_FieldDescriptorProto_Type); 'typeName': (string); 'defaultValue': (string); - 'options': (_google_protobuf_FieldOptions__Output | null); + 'options': (O_google_protobuf_FieldOptions | null); 'oneofIndex': (number); 'jsonName': (string); } diff --git a/packages/proto-loader/golden-generated/google/protobuf/FieldOptions.ts b/packages/proto-loader/golden-generated/google/protobuf/FieldOptions.ts index 8304053f1..076b35983 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/FieldOptions.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/FieldOptions.ts @@ -1,6 +1,6 @@ // Original file: null -import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; +import type { IUninterpretedOption as I_google_protobuf_UninterpretedOption, OUninterpretedOption as O_google_protobuf_UninterpretedOption } from '../../google/protobuf/UninterpretedOption'; import type { FieldBehavior as _google_api_FieldBehavior } from '../../google/api/FieldBehavior'; // Original file: null @@ -19,24 +19,24 @@ export enum _google_protobuf_FieldOptions_JSType { JS_NUMBER = 2, } -export interface FieldOptions { +export interface IFieldOptions { 'ctype'?: (_google_protobuf_FieldOptions_CType | keyof typeof _google_protobuf_FieldOptions_CType); 'packed'?: (boolean); 'deprecated'?: (boolean); 'lazy'?: (boolean); 'jstype'?: (_google_protobuf_FieldOptions_JSType | keyof typeof _google_protobuf_FieldOptions_JSType); 'weak'?: (boolean); - 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; + 'uninterpretedOption'?: (I_google_protobuf_UninterpretedOption)[]; '.google.api.field_behavior'?: (_google_api_FieldBehavior | keyof typeof _google_api_FieldBehavior)[]; } -export interface FieldOptions__Output { +export interface OFieldOptions { 'ctype': (keyof typeof _google_protobuf_FieldOptions_CType); 'packed': (boolean); 'deprecated': (boolean); 'lazy': (boolean); 'jstype': (keyof typeof _google_protobuf_FieldOptions_JSType); 'weak': (boolean); - 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; + 'uninterpretedOption': (O_google_protobuf_UninterpretedOption)[]; '.google.api.field_behavior': (keyof typeof _google_api_FieldBehavior)[]; } diff --git a/packages/proto-loader/golden-generated/google/protobuf/FileDescriptorProto.ts b/packages/proto-loader/golden-generated/google/protobuf/FileDescriptorProto.ts index b723da7c0..c98732f9d 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/FileDescriptorProto.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/FileDescriptorProto.ts @@ -1,37 +1,37 @@ // Original file: null -import type { DescriptorProto as _google_protobuf_DescriptorProto, DescriptorProto__Output as _google_protobuf_DescriptorProto__Output } from '../../google/protobuf/DescriptorProto'; -import type { EnumDescriptorProto as _google_protobuf_EnumDescriptorProto, EnumDescriptorProto__Output as _google_protobuf_EnumDescriptorProto__Output } from '../../google/protobuf/EnumDescriptorProto'; -import type { ServiceDescriptorProto as _google_protobuf_ServiceDescriptorProto, ServiceDescriptorProto__Output as _google_protobuf_ServiceDescriptorProto__Output } from '../../google/protobuf/ServiceDescriptorProto'; -import type { FieldDescriptorProto as _google_protobuf_FieldDescriptorProto, FieldDescriptorProto__Output as _google_protobuf_FieldDescriptorProto__Output } from '../../google/protobuf/FieldDescriptorProto'; -import type { FileOptions as _google_protobuf_FileOptions, FileOptions__Output as _google_protobuf_FileOptions__Output } from '../../google/protobuf/FileOptions'; -import type { SourceCodeInfo as _google_protobuf_SourceCodeInfo, SourceCodeInfo__Output as _google_protobuf_SourceCodeInfo__Output } from '../../google/protobuf/SourceCodeInfo'; +import type { IDescriptorProto as I_google_protobuf_DescriptorProto, ODescriptorProto as O_google_protobuf_DescriptorProto } from '../../google/protobuf/DescriptorProto'; +import type { IEnumDescriptorProto as I_google_protobuf_EnumDescriptorProto, OEnumDescriptorProto as O_google_protobuf_EnumDescriptorProto } from '../../google/protobuf/EnumDescriptorProto'; +import type { IServiceDescriptorProto as I_google_protobuf_ServiceDescriptorProto, OServiceDescriptorProto as O_google_protobuf_ServiceDescriptorProto } from '../../google/protobuf/ServiceDescriptorProto'; +import type { IFieldDescriptorProto as I_google_protobuf_FieldDescriptorProto, OFieldDescriptorProto as O_google_protobuf_FieldDescriptorProto } from '../../google/protobuf/FieldDescriptorProto'; +import type { IFileOptions as I_google_protobuf_FileOptions, OFileOptions as O_google_protobuf_FileOptions } from '../../google/protobuf/FileOptions'; +import type { ISourceCodeInfo as I_google_protobuf_SourceCodeInfo, OSourceCodeInfo as O_google_protobuf_SourceCodeInfo } from '../../google/protobuf/SourceCodeInfo'; -export interface FileDescriptorProto { +export interface IFileDescriptorProto { 'name'?: (string); 'package'?: (string); 'dependency'?: (string)[]; - 'messageType'?: (_google_protobuf_DescriptorProto)[]; - 'enumType'?: (_google_protobuf_EnumDescriptorProto)[]; - 'service'?: (_google_protobuf_ServiceDescriptorProto)[]; - 'extension'?: (_google_protobuf_FieldDescriptorProto)[]; - 'options'?: (_google_protobuf_FileOptions | null); - 'sourceCodeInfo'?: (_google_protobuf_SourceCodeInfo | null); + 'messageType'?: (I_google_protobuf_DescriptorProto)[]; + 'enumType'?: (I_google_protobuf_EnumDescriptorProto)[]; + 'service'?: (I_google_protobuf_ServiceDescriptorProto)[]; + 'extension'?: (I_google_protobuf_FieldDescriptorProto)[]; + 'options'?: (I_google_protobuf_FileOptions | null); + 'sourceCodeInfo'?: (I_google_protobuf_SourceCodeInfo | null); 'publicDependency'?: (number)[]; 'weakDependency'?: (number)[]; 'syntax'?: (string); } -export interface FileDescriptorProto__Output { +export interface OFileDescriptorProto { 'name': (string); 'package': (string); 'dependency': (string)[]; - 'messageType': (_google_protobuf_DescriptorProto__Output)[]; - 'enumType': (_google_protobuf_EnumDescriptorProto__Output)[]; - 'service': (_google_protobuf_ServiceDescriptorProto__Output)[]; - 'extension': (_google_protobuf_FieldDescriptorProto__Output)[]; - 'options': (_google_protobuf_FileOptions__Output | null); - 'sourceCodeInfo': (_google_protobuf_SourceCodeInfo__Output | null); + 'messageType': (O_google_protobuf_DescriptorProto)[]; + 'enumType': (O_google_protobuf_EnumDescriptorProto)[]; + 'service': (O_google_protobuf_ServiceDescriptorProto)[]; + 'extension': (O_google_protobuf_FieldDescriptorProto)[]; + 'options': (O_google_protobuf_FileOptions | null); + 'sourceCodeInfo': (O_google_protobuf_SourceCodeInfo | null); 'publicDependency': (number)[]; 'weakDependency': (number)[]; 'syntax': (string); diff --git a/packages/proto-loader/golden-generated/google/protobuf/FileDescriptorSet.ts b/packages/proto-loader/golden-generated/google/protobuf/FileDescriptorSet.ts index 74ded2471..9c940ed5e 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/FileDescriptorSet.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/FileDescriptorSet.ts @@ -1,11 +1,11 @@ // Original file: null -import type { FileDescriptorProto as _google_protobuf_FileDescriptorProto, FileDescriptorProto__Output as _google_protobuf_FileDescriptorProto__Output } from '../../google/protobuf/FileDescriptorProto'; +import type { IFileDescriptorProto as I_google_protobuf_FileDescriptorProto, OFileDescriptorProto as O_google_protobuf_FileDescriptorProto } from '../../google/protobuf/FileDescriptorProto'; -export interface FileDescriptorSet { - 'file'?: (_google_protobuf_FileDescriptorProto)[]; +export interface IFileDescriptorSet { + 'file'?: (I_google_protobuf_FileDescriptorProto)[]; } -export interface FileDescriptorSet__Output { - 'file': (_google_protobuf_FileDescriptorProto__Output)[]; +export interface OFileDescriptorSet { + 'file': (O_google_protobuf_FileDescriptorProto)[]; } diff --git a/packages/proto-loader/golden-generated/google/protobuf/FileOptions.ts b/packages/proto-loader/golden-generated/google/protobuf/FileOptions.ts index 573e847c0..2b832e0f8 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/FileOptions.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/FileOptions.ts @@ -1,6 +1,6 @@ // Original file: null -import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; +import type { IUninterpretedOption as I_google_protobuf_UninterpretedOption, OUninterpretedOption as O_google_protobuf_UninterpretedOption } from '../../google/protobuf/UninterpretedOption'; // Original file: null @@ -10,7 +10,7 @@ export enum _google_protobuf_FileOptions_OptimizeMode { LITE_RUNTIME = 3, } -export interface FileOptions { +export interface IFileOptions { 'javaPackage'?: (string); 'javaOuterClassname'?: (string); 'optimizeFor'?: (_google_protobuf_FileOptions_OptimizeMode | keyof typeof _google_protobuf_FileOptions_OptimizeMode); @@ -25,10 +25,10 @@ export interface FileOptions { 'ccEnableArenas'?: (boolean); 'objcClassPrefix'?: (string); 'csharpNamespace'?: (string); - 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; + 'uninterpretedOption'?: (I_google_protobuf_UninterpretedOption)[]; } -export interface FileOptions__Output { +export interface OFileOptions { 'javaPackage': (string); 'javaOuterClassname': (string); 'optimizeFor': (keyof typeof _google_protobuf_FileOptions_OptimizeMode); @@ -43,5 +43,5 @@ export interface FileOptions__Output { 'ccEnableArenas': (boolean); 'objcClassPrefix': (string); 'csharpNamespace': (string); - 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; + 'uninterpretedOption': (O_google_protobuf_UninterpretedOption)[]; } diff --git a/packages/proto-loader/golden-generated/google/protobuf/GeneratedCodeInfo.ts b/packages/proto-loader/golden-generated/google/protobuf/GeneratedCodeInfo.ts index 019fb0e15..62f9dc715 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/GeneratedCodeInfo.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/GeneratedCodeInfo.ts @@ -1,24 +1,24 @@ // Original file: null -export interface _google_protobuf_GeneratedCodeInfo_Annotation { +export interface I_google_protobuf_GeneratedCodeInfo_Annotation { 'path'?: (number)[]; 'sourceFile'?: (string); 'begin'?: (number); 'end'?: (number); } -export interface _google_protobuf_GeneratedCodeInfo_Annotation__Output { +export interface O_google_protobuf_GeneratedCodeInfo_Annotation { 'path': (number)[]; 'sourceFile': (string); 'begin': (number); 'end': (number); } -export interface GeneratedCodeInfo { - 'annotation'?: (_google_protobuf_GeneratedCodeInfo_Annotation)[]; +export interface IGeneratedCodeInfo { + 'annotation'?: (I_google_protobuf_GeneratedCodeInfo_Annotation)[]; } -export interface GeneratedCodeInfo__Output { - 'annotation': (_google_protobuf_GeneratedCodeInfo_Annotation__Output)[]; +export interface OGeneratedCodeInfo { + 'annotation': (O_google_protobuf_GeneratedCodeInfo_Annotation)[]; } diff --git a/packages/proto-loader/golden-generated/google/protobuf/MessageOptions.ts b/packages/proto-loader/golden-generated/google/protobuf/MessageOptions.ts index 31f669eb0..8c8885e63 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/MessageOptions.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/MessageOptions.ts @@ -1,19 +1,19 @@ // Original file: null -import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; +import type { IUninterpretedOption as I_google_protobuf_UninterpretedOption, OUninterpretedOption as O_google_protobuf_UninterpretedOption } from '../../google/protobuf/UninterpretedOption'; -export interface MessageOptions { +export interface IMessageOptions { 'messageSetWireFormat'?: (boolean); 'noStandardDescriptorAccessor'?: (boolean); 'deprecated'?: (boolean); 'mapEntry'?: (boolean); - 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; + 'uninterpretedOption'?: (I_google_protobuf_UninterpretedOption)[]; } -export interface MessageOptions__Output { +export interface OMessageOptions { 'messageSetWireFormat': (boolean); 'noStandardDescriptorAccessor': (boolean); 'deprecated': (boolean); 'mapEntry': (boolean); - 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; + 'uninterpretedOption': (O_google_protobuf_UninterpretedOption)[]; } diff --git a/packages/proto-loader/golden-generated/google/protobuf/MethodDescriptorProto.ts b/packages/proto-loader/golden-generated/google/protobuf/MethodDescriptorProto.ts index c76c0ea23..0826370df 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/MethodDescriptorProto.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/MethodDescriptorProto.ts @@ -1,21 +1,21 @@ // Original file: null -import type { MethodOptions as _google_protobuf_MethodOptions, MethodOptions__Output as _google_protobuf_MethodOptions__Output } from '../../google/protobuf/MethodOptions'; +import type { IMethodOptions as I_google_protobuf_MethodOptions, OMethodOptions as O_google_protobuf_MethodOptions } from '../../google/protobuf/MethodOptions'; -export interface MethodDescriptorProto { +export interface IMethodDescriptorProto { 'name'?: (string); 'inputType'?: (string); 'outputType'?: (string); - 'options'?: (_google_protobuf_MethodOptions | null); + 'options'?: (I_google_protobuf_MethodOptions | null); 'clientStreaming'?: (boolean); 'serverStreaming'?: (boolean); } -export interface MethodDescriptorProto__Output { +export interface OMethodDescriptorProto { 'name': (string); 'inputType': (string); 'outputType': (string); - 'options': (_google_protobuf_MethodOptions__Output | null); + 'options': (O_google_protobuf_MethodOptions | null); 'clientStreaming': (boolean); 'serverStreaming': (boolean); } diff --git a/packages/proto-loader/golden-generated/google/protobuf/MethodOptions.ts b/packages/proto-loader/golden-generated/google/protobuf/MethodOptions.ts index 7581b9643..5f0b69008 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/MethodOptions.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/MethodOptions.ts @@ -1,21 +1,21 @@ // Original file: null -import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; -import type { OperationInfo as _google_longrunning_OperationInfo, OperationInfo__Output as _google_longrunning_OperationInfo__Output } from '../../google/longrunning/OperationInfo'; -import type { HttpRule as _google_api_HttpRule, HttpRule__Output as _google_api_HttpRule__Output } from '../../google/api/HttpRule'; +import type { IUninterpretedOption as I_google_protobuf_UninterpretedOption, OUninterpretedOption as O_google_protobuf_UninterpretedOption } from '../../google/protobuf/UninterpretedOption'; +import type { IOperationInfo as I_google_longrunning_OperationInfo, OOperationInfo as O_google_longrunning_OperationInfo } from '../../google/longrunning/OperationInfo'; +import type { IHttpRule as I_google_api_HttpRule, OHttpRule as O_google_api_HttpRule } from '../../google/api/HttpRule'; -export interface MethodOptions { +export interface IMethodOptions { 'deprecated'?: (boolean); - 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; - '.google.longrunning.operation_info'?: (_google_longrunning_OperationInfo | null); + 'uninterpretedOption'?: (I_google_protobuf_UninterpretedOption)[]; + '.google.longrunning.operation_info'?: (I_google_longrunning_OperationInfo | null); '.google.api.method_signature'?: (string)[]; - '.google.api.http'?: (_google_api_HttpRule | null); + '.google.api.http'?: (I_google_api_HttpRule | null); } -export interface MethodOptions__Output { +export interface OMethodOptions { 'deprecated': (boolean); - 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; - '.google.longrunning.operation_info': (_google_longrunning_OperationInfo__Output | null); + 'uninterpretedOption': (O_google_protobuf_UninterpretedOption)[]; + '.google.longrunning.operation_info': (O_google_longrunning_OperationInfo | null); '.google.api.method_signature': (string)[]; - '.google.api.http': (_google_api_HttpRule__Output | null); + '.google.api.http': (O_google_api_HttpRule | null); } diff --git a/packages/proto-loader/golden-generated/google/protobuf/OneofDescriptorProto.ts b/packages/proto-loader/golden-generated/google/protobuf/OneofDescriptorProto.ts index 636f13ed4..6394270ea 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/OneofDescriptorProto.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/OneofDescriptorProto.ts @@ -1,13 +1,13 @@ // Original file: null -import type { OneofOptions as _google_protobuf_OneofOptions, OneofOptions__Output as _google_protobuf_OneofOptions__Output } from '../../google/protobuf/OneofOptions'; +import type { IOneofOptions as I_google_protobuf_OneofOptions, OOneofOptions as O_google_protobuf_OneofOptions } from '../../google/protobuf/OneofOptions'; -export interface OneofDescriptorProto { +export interface IOneofDescriptorProto { 'name'?: (string); - 'options'?: (_google_protobuf_OneofOptions | null); + 'options'?: (I_google_protobuf_OneofOptions | null); } -export interface OneofDescriptorProto__Output { +export interface OOneofDescriptorProto { 'name': (string); - 'options': (_google_protobuf_OneofOptions__Output | null); + 'options': (O_google_protobuf_OneofOptions | null); } diff --git a/packages/proto-loader/golden-generated/google/protobuf/OneofOptions.ts b/packages/proto-loader/golden-generated/google/protobuf/OneofOptions.ts index d81d34797..73280ad73 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/OneofOptions.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/OneofOptions.ts @@ -1,11 +1,11 @@ // Original file: null -import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; +import type { IUninterpretedOption as I_google_protobuf_UninterpretedOption, OUninterpretedOption as O_google_protobuf_UninterpretedOption } from '../../google/protobuf/UninterpretedOption'; -export interface OneofOptions { - 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; +export interface IOneofOptions { + 'uninterpretedOption'?: (I_google_protobuf_UninterpretedOption)[]; } -export interface OneofOptions__Output { - 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; +export interface OOneofOptions { + 'uninterpretedOption': (O_google_protobuf_UninterpretedOption)[]; } diff --git a/packages/proto-loader/golden-generated/google/protobuf/ServiceDescriptorProto.ts b/packages/proto-loader/golden-generated/google/protobuf/ServiceDescriptorProto.ts index 40c9263ea..a0427fda5 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/ServiceDescriptorProto.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/ServiceDescriptorProto.ts @@ -1,16 +1,16 @@ // Original file: null -import type { MethodDescriptorProto as _google_protobuf_MethodDescriptorProto, MethodDescriptorProto__Output as _google_protobuf_MethodDescriptorProto__Output } from '../../google/protobuf/MethodDescriptorProto'; -import type { ServiceOptions as _google_protobuf_ServiceOptions, ServiceOptions__Output as _google_protobuf_ServiceOptions__Output } from '../../google/protobuf/ServiceOptions'; +import type { IMethodDescriptorProto as I_google_protobuf_MethodDescriptorProto, OMethodDescriptorProto as O_google_protobuf_MethodDescriptorProto } from '../../google/protobuf/MethodDescriptorProto'; +import type { IServiceOptions as I_google_protobuf_ServiceOptions, OServiceOptions as O_google_protobuf_ServiceOptions } from '../../google/protobuf/ServiceOptions'; -export interface ServiceDescriptorProto { +export interface IServiceDescriptorProto { 'name'?: (string); - 'method'?: (_google_protobuf_MethodDescriptorProto)[]; - 'options'?: (_google_protobuf_ServiceOptions | null); + 'method'?: (I_google_protobuf_MethodDescriptorProto)[]; + 'options'?: (I_google_protobuf_ServiceOptions | null); } -export interface ServiceDescriptorProto__Output { +export interface OServiceDescriptorProto { 'name': (string); - 'method': (_google_protobuf_MethodDescriptorProto__Output)[]; - 'options': (_google_protobuf_ServiceOptions__Output | null); + 'method': (O_google_protobuf_MethodDescriptorProto)[]; + 'options': (O_google_protobuf_ServiceOptions | null); } diff --git a/packages/proto-loader/golden-generated/google/protobuf/ServiceOptions.ts b/packages/proto-loader/golden-generated/google/protobuf/ServiceOptions.ts index c0522eca3..0ddc8e187 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/ServiceOptions.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/ServiceOptions.ts @@ -1,17 +1,17 @@ // Original file: null -import type { UninterpretedOption as _google_protobuf_UninterpretedOption, UninterpretedOption__Output as _google_protobuf_UninterpretedOption__Output } from '../../google/protobuf/UninterpretedOption'; +import type { IUninterpretedOption as I_google_protobuf_UninterpretedOption, OUninterpretedOption as O_google_protobuf_UninterpretedOption } from '../../google/protobuf/UninterpretedOption'; -export interface ServiceOptions { +export interface IServiceOptions { 'deprecated'?: (boolean); - 'uninterpretedOption'?: (_google_protobuf_UninterpretedOption)[]; + 'uninterpretedOption'?: (I_google_protobuf_UninterpretedOption)[]; '.google.api.default_host'?: (string); '.google.api.oauth_scopes'?: (string); } -export interface ServiceOptions__Output { +export interface OServiceOptions { 'deprecated': (boolean); - 'uninterpretedOption': (_google_protobuf_UninterpretedOption__Output)[]; + 'uninterpretedOption': (O_google_protobuf_UninterpretedOption)[]; '.google.api.default_host': (string); '.google.api.oauth_scopes': (string); } diff --git a/packages/proto-loader/golden-generated/google/protobuf/SourceCodeInfo.ts b/packages/proto-loader/golden-generated/google/protobuf/SourceCodeInfo.ts index d30e59b4f..4d0856604 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/SourceCodeInfo.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/SourceCodeInfo.ts @@ -1,7 +1,7 @@ // Original file: null -export interface _google_protobuf_SourceCodeInfo_Location { +export interface I_google_protobuf_SourceCodeInfo_Location { 'path'?: (number)[]; 'span'?: (number)[]; 'leadingComments'?: (string); @@ -9,7 +9,7 @@ export interface _google_protobuf_SourceCodeInfo_Location { 'leadingDetachedComments'?: (string)[]; } -export interface _google_protobuf_SourceCodeInfo_Location__Output { +export interface O_google_protobuf_SourceCodeInfo_Location { 'path': (number)[]; 'span': (number)[]; 'leadingComments': (string); @@ -17,10 +17,10 @@ export interface _google_protobuf_SourceCodeInfo_Location__Output { 'leadingDetachedComments': (string)[]; } -export interface SourceCodeInfo { - 'location'?: (_google_protobuf_SourceCodeInfo_Location)[]; +export interface ISourceCodeInfo { + 'location'?: (I_google_protobuf_SourceCodeInfo_Location)[]; } -export interface SourceCodeInfo__Output { - 'location': (_google_protobuf_SourceCodeInfo_Location__Output)[]; +export interface OSourceCodeInfo { + 'location': (O_google_protobuf_SourceCodeInfo_Location)[]; } diff --git a/packages/proto-loader/golden-generated/google/protobuf/Timestamp.ts b/packages/proto-loader/golden-generated/google/protobuf/Timestamp.ts index ceaa32b5f..06d756134 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/Timestamp.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/Timestamp.ts @@ -2,12 +2,12 @@ import type { Long } from '@grpc/proto-loader'; -export interface Timestamp { +export interface ITimestamp { 'seconds'?: (number | string | Long); 'nanos'?: (number); } -export interface Timestamp__Output { +export interface OTimestamp { 'seconds': (string); 'nanos': (number); } diff --git a/packages/proto-loader/golden-generated/google/protobuf/UninterpretedOption.ts b/packages/proto-loader/golden-generated/google/protobuf/UninterpretedOption.ts index 433820f55..fa0feaf52 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/UninterpretedOption.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/UninterpretedOption.ts @@ -2,18 +2,18 @@ import type { Long } from '@grpc/proto-loader'; -export interface _google_protobuf_UninterpretedOption_NamePart { +export interface I_google_protobuf_UninterpretedOption_NamePart { 'namePart'?: (string); 'isExtension'?: (boolean); } -export interface _google_protobuf_UninterpretedOption_NamePart__Output { +export interface O_google_protobuf_UninterpretedOption_NamePart { 'namePart': (string); 'isExtension': (boolean); } -export interface UninterpretedOption { - 'name'?: (_google_protobuf_UninterpretedOption_NamePart)[]; +export interface IUninterpretedOption { + 'name'?: (I_google_protobuf_UninterpretedOption_NamePart)[]; 'identifierValue'?: (string); 'positiveIntValue'?: (number | string | Long); 'negativeIntValue'?: (number | string | Long); @@ -22,8 +22,8 @@ export interface UninterpretedOption { 'aggregateValue'?: (string); } -export interface UninterpretedOption__Output { - 'name': (_google_protobuf_UninterpretedOption_NamePart__Output)[]; +export interface OUninterpretedOption { + 'name': (O_google_protobuf_UninterpretedOption_NamePart)[]; 'identifierValue': (string); 'positiveIntValue': (string); 'negativeIntValue': (string); diff --git a/packages/proto-loader/golden-generated/google/rpc/Status.ts b/packages/proto-loader/golden-generated/google/rpc/Status.ts index 4ce45b6a9..05cf71c5f 100644 --- a/packages/proto-loader/golden-generated/google/rpc/Status.ts +++ b/packages/proto-loader/golden-generated/google/rpc/Status.ts @@ -1,6 +1,6 @@ // Original file: deps/googleapis/google/rpc/status.proto -import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../google/protobuf/Any'; +import type { IAny as I_google_protobuf_Any, OAny as O_google_protobuf_Any } from '../../google/protobuf/Any'; /** * The `Status` type defines a logical error model that is suitable for @@ -11,7 +11,7 @@ import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__ * You can find out more about this error model and how to work with it in the * [API Design Guide](https://cloud.google.com/apis/design/errors). */ -export interface Status { +export interface IStatus { /** * The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. */ @@ -26,7 +26,7 @@ export interface Status { * A list of messages that carry the error details. There is a common set of * message types for APIs to use. */ - 'details'?: (_google_protobuf_Any)[]; + 'details'?: (I_google_protobuf_Any)[]; } /** @@ -38,7 +38,7 @@ export interface Status { * You can find out more about this error model and how to work with it in the * [API Design Guide](https://cloud.google.com/apis/design/errors). */ -export interface Status__Output { +export interface OStatus { /** * The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. */ @@ -53,5 +53,5 @@ export interface Status__Output { * A list of messages that carry the error details. There is a common set of * message types for APIs to use. */ - 'details': (_google_protobuf_Any__Output)[]; + 'details': (O_google_protobuf_Any)[]; } diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/BlockRequest.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/BlockRequest.ts index 383c409c5..29d10f6dd 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/BlockRequest.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/BlockRequest.ts @@ -1,45 +1,45 @@ // Original file: deps/gapic-showcase/schema/google/showcase/v1beta1/echo.proto -import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../google/protobuf/Duration'; -import type { Status as _google_rpc_Status, Status__Output as _google_rpc_Status__Output } from '../../../google/rpc/Status'; -import type { BlockResponse as _google_showcase_v1beta1_BlockResponse, BlockResponse__Output as _google_showcase_v1beta1_BlockResponse__Output } from '../../../google/showcase/v1beta1/BlockResponse'; +import type { IDuration as I_google_protobuf_Duration, ODuration as O_google_protobuf_Duration } from '../../../google/protobuf/Duration'; +import type { IStatus as I_google_rpc_Status, OStatus as O_google_rpc_Status } from '../../../google/rpc/Status'; +import type { IBlockResponse as I_google_showcase_v1beta1_BlockResponse, OBlockResponse as O_google_showcase_v1beta1_BlockResponse } from '../../../google/showcase/v1beta1/BlockResponse'; /** * The request for Block method. */ -export interface BlockRequest { +export interface IBlockRequest { /** * The amount of time to block before returning a response. */ - 'response_delay'?: (_google_protobuf_Duration | null); + 'response_delay'?: (I_google_protobuf_Duration | null); /** * The error that will be returned by the server. If this code is specified * to be the OK rpc code, an empty response will be returned. */ - 'error'?: (_google_rpc_Status | null); + 'error'?: (I_google_rpc_Status | null); /** * The response to be returned that will signify successful method call. */ - 'success'?: (_google_showcase_v1beta1_BlockResponse | null); + 'success'?: (I_google_showcase_v1beta1_BlockResponse | null); 'response'?: "error"|"success"; } /** * The request for Block method. */ -export interface BlockRequest__Output { +export interface OBlockRequest { /** * The amount of time to block before returning a response. */ - 'response_delay': (_google_protobuf_Duration__Output | null); + 'response_delay': (O_google_protobuf_Duration | null); /** * The error that will be returned by the server. If this code is specified * to be the OK rpc code, an empty response will be returned. */ - 'error'?: (_google_rpc_Status__Output | null); + 'error'?: (O_google_rpc_Status | null); /** * The response to be returned that will signify successful method call. */ - 'success'?: (_google_showcase_v1beta1_BlockResponse__Output | null); + 'success'?: (O_google_showcase_v1beta1_BlockResponse | null); 'response': "error"|"success"; } diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/BlockResponse.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/BlockResponse.ts index 5634b19d4..3bb9bddf2 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/BlockResponse.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/BlockResponse.ts @@ -4,7 +4,7 @@ /** * The response for Block method. */ -export interface BlockResponse { +export interface IBlockResponse { /** * This content can contain anything, the server will not depend on a value * here. @@ -15,7 +15,7 @@ export interface BlockResponse { /** * The response for Block method. */ -export interface BlockResponse__Output { +export interface OBlockResponse { /** * This content can contain anything, the server will not depend on a value * here. diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/Echo.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/Echo.ts index 30ecc8e23..a0330fe68 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/Echo.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/Echo.ts @@ -2,15 +2,15 @@ import type * as grpc from '@grpc/grpc-js' import type { MethodDefinition } from '@grpc/proto-loader' -import type { BlockRequest as _google_showcase_v1beta1_BlockRequest, BlockRequest__Output as _google_showcase_v1beta1_BlockRequest__Output } from '../../../google/showcase/v1beta1/BlockRequest'; -import type { BlockResponse as _google_showcase_v1beta1_BlockResponse, BlockResponse__Output as _google_showcase_v1beta1_BlockResponse__Output } from '../../../google/showcase/v1beta1/BlockResponse'; -import type { EchoRequest as _google_showcase_v1beta1_EchoRequest, EchoRequest__Output as _google_showcase_v1beta1_EchoRequest__Output } from '../../../google/showcase/v1beta1/EchoRequest'; -import type { EchoResponse as _google_showcase_v1beta1_EchoResponse, EchoResponse__Output as _google_showcase_v1beta1_EchoResponse__Output } from '../../../google/showcase/v1beta1/EchoResponse'; -import type { ExpandRequest as _google_showcase_v1beta1_ExpandRequest, ExpandRequest__Output as _google_showcase_v1beta1_ExpandRequest__Output } from '../../../google/showcase/v1beta1/ExpandRequest'; -import type { Operation as _google_longrunning_Operation, Operation__Output as _google_longrunning_Operation__Output } from '../../../google/longrunning/Operation'; -import type { PagedExpandRequest as _google_showcase_v1beta1_PagedExpandRequest, PagedExpandRequest__Output as _google_showcase_v1beta1_PagedExpandRequest__Output } from '../../../google/showcase/v1beta1/PagedExpandRequest'; -import type { PagedExpandResponse as _google_showcase_v1beta1_PagedExpandResponse, PagedExpandResponse__Output as _google_showcase_v1beta1_PagedExpandResponse__Output } from '../../../google/showcase/v1beta1/PagedExpandResponse'; -import type { WaitRequest as _google_showcase_v1beta1_WaitRequest, WaitRequest__Output as _google_showcase_v1beta1_WaitRequest__Output } from '../../../google/showcase/v1beta1/WaitRequest'; +import type { IBlockRequest as I_google_showcase_v1beta1_BlockRequest, OBlockRequest as O_google_showcase_v1beta1_BlockRequest } from '../../../google/showcase/v1beta1/BlockRequest'; +import type { IBlockResponse as I_google_showcase_v1beta1_BlockResponse, OBlockResponse as O_google_showcase_v1beta1_BlockResponse } from '../../../google/showcase/v1beta1/BlockResponse'; +import type { IEchoRequest as I_google_showcase_v1beta1_EchoRequest, OEchoRequest as O_google_showcase_v1beta1_EchoRequest } from '../../../google/showcase/v1beta1/EchoRequest'; +import type { IEchoResponse as I_google_showcase_v1beta1_EchoResponse, OEchoResponse as O_google_showcase_v1beta1_EchoResponse } from '../../../google/showcase/v1beta1/EchoResponse'; +import type { IExpandRequest as I_google_showcase_v1beta1_ExpandRequest, OExpandRequest as O_google_showcase_v1beta1_ExpandRequest } from '../../../google/showcase/v1beta1/ExpandRequest'; +import type { IOperation as I_google_longrunning_Operation, OOperation as O_google_longrunning_Operation } from '../../../google/longrunning/Operation'; +import type { IPagedExpandRequest as I_google_showcase_v1beta1_PagedExpandRequest, OPagedExpandRequest as O_google_showcase_v1beta1_PagedExpandRequest } from '../../../google/showcase/v1beta1/PagedExpandRequest'; +import type { IPagedExpandResponse as I_google_showcase_v1beta1_PagedExpandResponse, OPagedExpandResponse as O_google_showcase_v1beta1_PagedExpandResponse } from '../../../google/showcase/v1beta1/PagedExpandResponse'; +import type { IWaitRequest as I_google_showcase_v1beta1_WaitRequest, OWaitRequest as O_google_showcase_v1beta1_WaitRequest } from '../../../google/showcase/v1beta1/WaitRequest'; /** * This service is used showcase the four main types of rpcs - unary, server @@ -25,115 +25,115 @@ export interface EchoClient extends grpc.Client { * and then return the response or error. * This method showcases how a client handles delays or retries. */ - Block(argument: _google_showcase_v1beta1_BlockRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_BlockResponse__Output>): grpc.ClientUnaryCall; - Block(argument: _google_showcase_v1beta1_BlockRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_showcase_v1beta1_BlockResponse__Output>): grpc.ClientUnaryCall; - Block(argument: _google_showcase_v1beta1_BlockRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_BlockResponse__Output>): grpc.ClientUnaryCall; - Block(argument: _google_showcase_v1beta1_BlockRequest, callback: grpc.requestCallback<_google_showcase_v1beta1_BlockResponse__Output>): grpc.ClientUnaryCall; + Block(argument: I_google_showcase_v1beta1_BlockRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + Block(argument: I_google_showcase_v1beta1_BlockRequest, metadata: grpc.Metadata, callback: grpc.requestCallback): grpc.ClientUnaryCall; + Block(argument: I_google_showcase_v1beta1_BlockRequest, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + Block(argument: I_google_showcase_v1beta1_BlockRequest, callback: grpc.requestCallback): grpc.ClientUnaryCall; /** * This method will block (wait) for the requested amount of time * and then return the response or error. * This method showcases how a client handles delays or retries. */ - block(argument: _google_showcase_v1beta1_BlockRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_BlockResponse__Output>): grpc.ClientUnaryCall; - block(argument: _google_showcase_v1beta1_BlockRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_showcase_v1beta1_BlockResponse__Output>): grpc.ClientUnaryCall; - block(argument: _google_showcase_v1beta1_BlockRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_BlockResponse__Output>): grpc.ClientUnaryCall; - block(argument: _google_showcase_v1beta1_BlockRequest, callback: grpc.requestCallback<_google_showcase_v1beta1_BlockResponse__Output>): grpc.ClientUnaryCall; + block(argument: I_google_showcase_v1beta1_BlockRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + block(argument: I_google_showcase_v1beta1_BlockRequest, metadata: grpc.Metadata, callback: grpc.requestCallback): grpc.ClientUnaryCall; + block(argument: I_google_showcase_v1beta1_BlockRequest, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + block(argument: I_google_showcase_v1beta1_BlockRequest, callback: grpc.requestCallback): grpc.ClientUnaryCall; /** * This method, upon receiving a request on the stream, the same content will * be passed back on the stream. This method showcases bidirectional * streaming rpcs. */ - Chat(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_google_showcase_v1beta1_EchoRequest, _google_showcase_v1beta1_EchoResponse__Output>; - Chat(options?: grpc.CallOptions): grpc.ClientDuplexStream<_google_showcase_v1beta1_EchoRequest, _google_showcase_v1beta1_EchoResponse__Output>; + Chat(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream; + Chat(options?: grpc.CallOptions): grpc.ClientDuplexStream; /** * This method, upon receiving a request on the stream, the same content will * be passed back on the stream. This method showcases bidirectional * streaming rpcs. */ - chat(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_google_showcase_v1beta1_EchoRequest, _google_showcase_v1beta1_EchoResponse__Output>; - chat(options?: grpc.CallOptions): grpc.ClientDuplexStream<_google_showcase_v1beta1_EchoRequest, _google_showcase_v1beta1_EchoResponse__Output>; + chat(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream; + chat(options?: grpc.CallOptions): grpc.ClientDuplexStream; /** * This method will collect the words given to it. When the stream is closed * by the client, this method will return the a concatenation of the strings * passed to it. This method showcases client-side streaming rpcs. */ - Collect(metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; - Collect(metadata: grpc.Metadata, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; - Collect(options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; - Collect(callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; + Collect(metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientWritableStream; + Collect(metadata: grpc.Metadata, callback: grpc.requestCallback): grpc.ClientWritableStream; + Collect(options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientWritableStream; + Collect(callback: grpc.requestCallback): grpc.ClientWritableStream; /** * This method will collect the words given to it. When the stream is closed * by the client, this method will return the a concatenation of the strings * passed to it. This method showcases client-side streaming rpcs. */ - collect(metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; - collect(metadata: grpc.Metadata, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; - collect(options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; - collect(callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientWritableStream<_google_showcase_v1beta1_EchoRequest>; + collect(metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientWritableStream; + collect(metadata: grpc.Metadata, callback: grpc.requestCallback): grpc.ClientWritableStream; + collect(options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientWritableStream; + collect(callback: grpc.requestCallback): grpc.ClientWritableStream; /** * This method simply echos the request. This method is showcases unary rpcs. */ - Echo(argument: _google_showcase_v1beta1_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientUnaryCall; - Echo(argument: _google_showcase_v1beta1_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientUnaryCall; - Echo(argument: _google_showcase_v1beta1_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientUnaryCall; - Echo(argument: _google_showcase_v1beta1_EchoRequest, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo(argument: I_google_showcase_v1beta1_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + Echo(argument: I_google_showcase_v1beta1_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback): grpc.ClientUnaryCall; + Echo(argument: I_google_showcase_v1beta1_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + Echo(argument: I_google_showcase_v1beta1_EchoRequest, callback: grpc.requestCallback): grpc.ClientUnaryCall; /** * This method simply echos the request. This method is showcases unary rpcs. */ - echo(argument: _google_showcase_v1beta1_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientUnaryCall; - echo(argument: _google_showcase_v1beta1_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientUnaryCall; - echo(argument: _google_showcase_v1beta1_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientUnaryCall; - echo(argument: _google_showcase_v1beta1_EchoRequest, callback: grpc.requestCallback<_google_showcase_v1beta1_EchoResponse__Output>): grpc.ClientUnaryCall; + echo(argument: I_google_showcase_v1beta1_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + echo(argument: I_google_showcase_v1beta1_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback): grpc.ClientUnaryCall; + echo(argument: I_google_showcase_v1beta1_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + echo(argument: I_google_showcase_v1beta1_EchoRequest, callback: grpc.requestCallback): grpc.ClientUnaryCall; /** * This method split the given content into words and will pass each word back * through the stream. This method showcases server-side streaming rpcs. */ - Expand(argument: _google_showcase_v1beta1_ExpandRequest, metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientReadableStream<_google_showcase_v1beta1_EchoResponse__Output>; - Expand(argument: _google_showcase_v1beta1_ExpandRequest, options?: grpc.CallOptions): grpc.ClientReadableStream<_google_showcase_v1beta1_EchoResponse__Output>; + Expand(argument: I_google_showcase_v1beta1_ExpandRequest, metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientReadableStream; + Expand(argument: I_google_showcase_v1beta1_ExpandRequest, options?: grpc.CallOptions): grpc.ClientReadableStream; /** * This method split the given content into words and will pass each word back * through the stream. This method showcases server-side streaming rpcs. */ - expand(argument: _google_showcase_v1beta1_ExpandRequest, metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientReadableStream<_google_showcase_v1beta1_EchoResponse__Output>; - expand(argument: _google_showcase_v1beta1_ExpandRequest, options?: grpc.CallOptions): grpc.ClientReadableStream<_google_showcase_v1beta1_EchoResponse__Output>; + expand(argument: I_google_showcase_v1beta1_ExpandRequest, metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientReadableStream; + expand(argument: I_google_showcase_v1beta1_ExpandRequest, options?: grpc.CallOptions): grpc.ClientReadableStream; /** * This is similar to the Expand method but instead of returning a stream of * expanded words, this method returns a paged list of expanded words. */ - PagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_PagedExpandResponse__Output>): grpc.ClientUnaryCall; - PagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_showcase_v1beta1_PagedExpandResponse__Output>): grpc.ClientUnaryCall; - PagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_PagedExpandResponse__Output>): grpc.ClientUnaryCall; - PagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, callback: grpc.requestCallback<_google_showcase_v1beta1_PagedExpandResponse__Output>): grpc.ClientUnaryCall; + PagedExpand(argument: I_google_showcase_v1beta1_PagedExpandRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + PagedExpand(argument: I_google_showcase_v1beta1_PagedExpandRequest, metadata: grpc.Metadata, callback: grpc.requestCallback): grpc.ClientUnaryCall; + PagedExpand(argument: I_google_showcase_v1beta1_PagedExpandRequest, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + PagedExpand(argument: I_google_showcase_v1beta1_PagedExpandRequest, callback: grpc.requestCallback): grpc.ClientUnaryCall; /** * This is similar to the Expand method but instead of returning a stream of * expanded words, this method returns a paged list of expanded words. */ - pagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_PagedExpandResponse__Output>): grpc.ClientUnaryCall; - pagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_showcase_v1beta1_PagedExpandResponse__Output>): grpc.ClientUnaryCall; - pagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_showcase_v1beta1_PagedExpandResponse__Output>): grpc.ClientUnaryCall; - pagedExpand(argument: _google_showcase_v1beta1_PagedExpandRequest, callback: grpc.requestCallback<_google_showcase_v1beta1_PagedExpandResponse__Output>): grpc.ClientUnaryCall; + pagedExpand(argument: I_google_showcase_v1beta1_PagedExpandRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + pagedExpand(argument: I_google_showcase_v1beta1_PagedExpandRequest, metadata: grpc.Metadata, callback: grpc.requestCallback): grpc.ClientUnaryCall; + pagedExpand(argument: I_google_showcase_v1beta1_PagedExpandRequest, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + pagedExpand(argument: I_google_showcase_v1beta1_PagedExpandRequest, callback: grpc.requestCallback): grpc.ClientUnaryCall; /** * This method will wait the requested amount of and then return. * This method showcases how a client handles a request timing out. */ - Wait(argument: _google_showcase_v1beta1_WaitRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; - Wait(argument: _google_showcase_v1beta1_WaitRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; - Wait(argument: _google_showcase_v1beta1_WaitRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; - Wait(argument: _google_showcase_v1beta1_WaitRequest, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + Wait(argument: I_google_showcase_v1beta1_WaitRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + Wait(argument: I_google_showcase_v1beta1_WaitRequest, metadata: grpc.Metadata, callback: grpc.requestCallback): grpc.ClientUnaryCall; + Wait(argument: I_google_showcase_v1beta1_WaitRequest, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + Wait(argument: I_google_showcase_v1beta1_WaitRequest, callback: grpc.requestCallback): grpc.ClientUnaryCall; /** * This method will wait the requested amount of and then return. * This method showcases how a client handles a request timing out. */ - wait(argument: _google_showcase_v1beta1_WaitRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; - wait(argument: _google_showcase_v1beta1_WaitRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; - wait(argument: _google_showcase_v1beta1_WaitRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; - wait(argument: _google_showcase_v1beta1_WaitRequest, callback: grpc.requestCallback<_google_longrunning_Operation__Output>): grpc.ClientUnaryCall; + wait(argument: I_google_showcase_v1beta1_WaitRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + wait(argument: I_google_showcase_v1beta1_WaitRequest, metadata: grpc.Metadata, callback: grpc.requestCallback): grpc.ClientUnaryCall; + wait(argument: I_google_showcase_v1beta1_WaitRequest, options: grpc.CallOptions, callback: grpc.requestCallback): grpc.ClientUnaryCall; + wait(argument: I_google_showcase_v1beta1_WaitRequest, callback: grpc.requestCallback): grpc.ClientUnaryCall; } @@ -150,53 +150,53 @@ export interface EchoHandlers extends grpc.UntypedServiceImplementation { * and then return the response or error. * This method showcases how a client handles delays or retries. */ - Block: grpc.handleUnaryCall<_google_showcase_v1beta1_BlockRequest__Output, _google_showcase_v1beta1_BlockResponse>; + Block: grpc.handleUnaryCall; /** * This method, upon receiving a request on the stream, the same content will * be passed back on the stream. This method showcases bidirectional * streaming rpcs. */ - Chat: grpc.handleBidiStreamingCall<_google_showcase_v1beta1_EchoRequest__Output, _google_showcase_v1beta1_EchoResponse>; + Chat: grpc.handleBidiStreamingCall; /** * This method will collect the words given to it. When the stream is closed * by the client, this method will return the a concatenation of the strings * passed to it. This method showcases client-side streaming rpcs. */ - Collect: grpc.handleClientStreamingCall<_google_showcase_v1beta1_EchoRequest__Output, _google_showcase_v1beta1_EchoResponse>; + Collect: grpc.handleClientStreamingCall; /** * This method simply echos the request. This method is showcases unary rpcs. */ - Echo: grpc.handleUnaryCall<_google_showcase_v1beta1_EchoRequest__Output, _google_showcase_v1beta1_EchoResponse>; + Echo: grpc.handleUnaryCall; /** * This method split the given content into words and will pass each word back * through the stream. This method showcases server-side streaming rpcs. */ - Expand: grpc.handleServerStreamingCall<_google_showcase_v1beta1_ExpandRequest__Output, _google_showcase_v1beta1_EchoResponse>; + Expand: grpc.handleServerStreamingCall; /** * This is similar to the Expand method but instead of returning a stream of * expanded words, this method returns a paged list of expanded words. */ - PagedExpand: grpc.handleUnaryCall<_google_showcase_v1beta1_PagedExpandRequest__Output, _google_showcase_v1beta1_PagedExpandResponse>; + PagedExpand: grpc.handleUnaryCall; /** * This method will wait the requested amount of and then return. * This method showcases how a client handles a request timing out. */ - Wait: grpc.handleUnaryCall<_google_showcase_v1beta1_WaitRequest__Output, _google_longrunning_Operation>; + Wait: grpc.handleUnaryCall; } export interface EchoDefinition extends grpc.ServiceDefinition { - Block: MethodDefinition<_google_showcase_v1beta1_BlockRequest, _google_showcase_v1beta1_BlockResponse, _google_showcase_v1beta1_BlockRequest__Output, _google_showcase_v1beta1_BlockResponse__Output> - Chat: MethodDefinition<_google_showcase_v1beta1_EchoRequest, _google_showcase_v1beta1_EchoResponse, _google_showcase_v1beta1_EchoRequest__Output, _google_showcase_v1beta1_EchoResponse__Output> - Collect: MethodDefinition<_google_showcase_v1beta1_EchoRequest, _google_showcase_v1beta1_EchoResponse, _google_showcase_v1beta1_EchoRequest__Output, _google_showcase_v1beta1_EchoResponse__Output> - Echo: MethodDefinition<_google_showcase_v1beta1_EchoRequest, _google_showcase_v1beta1_EchoResponse, _google_showcase_v1beta1_EchoRequest__Output, _google_showcase_v1beta1_EchoResponse__Output> - Expand: MethodDefinition<_google_showcase_v1beta1_ExpandRequest, _google_showcase_v1beta1_EchoResponse, _google_showcase_v1beta1_ExpandRequest__Output, _google_showcase_v1beta1_EchoResponse__Output> - PagedExpand: MethodDefinition<_google_showcase_v1beta1_PagedExpandRequest, _google_showcase_v1beta1_PagedExpandResponse, _google_showcase_v1beta1_PagedExpandRequest__Output, _google_showcase_v1beta1_PagedExpandResponse__Output> - Wait: MethodDefinition<_google_showcase_v1beta1_WaitRequest, _google_longrunning_Operation, _google_showcase_v1beta1_WaitRequest__Output, _google_longrunning_Operation__Output> + Block: MethodDefinition + Chat: MethodDefinition + Collect: MethodDefinition + Echo: MethodDefinition + Expand: MethodDefinition + PagedExpand: MethodDefinition + Wait: MethodDefinition } diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoRequest.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoRequest.ts index fb2bb67d3..649a5d505 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoRequest.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoRequest.ts @@ -1,6 +1,6 @@ // Original file: deps/gapic-showcase/schema/google/showcase/v1beta1/echo.proto -import type { Status as _google_rpc_Status, Status__Output as _google_rpc_Status__Output } from '../../../google/rpc/Status'; +import type { IStatus as I_google_rpc_Status, OStatus as O_google_rpc_Status } from '../../../google/rpc/Status'; import type { Severity as _google_showcase_v1beta1_Severity } from '../../../google/showcase/v1beta1/Severity'; /** @@ -9,7 +9,7 @@ import type { Severity as _google_showcase_v1beta1_Severity } from '../../../goo * If status is set in this message * then the status will be returned as an error. */ -export interface EchoRequest { +export interface IEchoRequest { /** * The content to be echoed by the server. */ @@ -17,7 +17,7 @@ export interface EchoRequest { /** * The error to be thrown by the server. */ - 'error'?: (_google_rpc_Status | null); + 'error'?: (I_google_rpc_Status | null); /** * The severity to be echoed by the server. */ @@ -31,7 +31,7 @@ export interface EchoRequest { * If status is set in this message * then the status will be returned as an error. */ -export interface EchoRequest__Output { +export interface OEchoRequest { /** * The content to be echoed by the server. */ @@ -39,7 +39,7 @@ export interface EchoRequest__Output { /** * The error to be thrown by the server. */ - 'error'?: (_google_rpc_Status__Output | null); + 'error'?: (O_google_rpc_Status | null); /** * The severity to be echoed by the server. */ diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoResponse.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoResponse.ts index 3fda238a1..96b7ba25d 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoResponse.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoResponse.ts @@ -5,7 +5,7 @@ import type { Severity as _google_showcase_v1beta1_Severity } from '../../../goo /** * The response message for the Echo methods. */ -export interface EchoResponse { +export interface IEchoResponse { /** * The content specified in the request. */ @@ -19,7 +19,7 @@ export interface EchoResponse { /** * The response message for the Echo methods. */ -export interface EchoResponse__Output { +export interface OEchoResponse { /** * The content specified in the request. */ diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/ExpandRequest.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/ExpandRequest.ts index 33ce73c1f..4347a617a 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/ExpandRequest.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/ExpandRequest.ts @@ -1,11 +1,11 @@ // Original file: deps/gapic-showcase/schema/google/showcase/v1beta1/echo.proto -import type { Status as _google_rpc_Status, Status__Output as _google_rpc_Status__Output } from '../../../google/rpc/Status'; +import type { IStatus as I_google_rpc_Status, OStatus as O_google_rpc_Status } from '../../../google/rpc/Status'; /** * The request message for the Expand method. */ -export interface ExpandRequest { +export interface IExpandRequest { /** * The content that will be split into words and returned on the stream. */ @@ -13,13 +13,13 @@ export interface ExpandRequest { /** * The error that is thrown after all words are sent on the stream. */ - 'error'?: (_google_rpc_Status | null); + 'error'?: (I_google_rpc_Status | null); } /** * The request message for the Expand method. */ -export interface ExpandRequest__Output { +export interface OExpandRequest { /** * The content that will be split into words and returned on the stream. */ @@ -27,5 +27,5 @@ export interface ExpandRequest__Output { /** * The error that is thrown after all words are sent on the stream. */ - 'error': (_google_rpc_Status__Output | null); + 'error': (O_google_rpc_Status | null); } diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/PagedExpandRequest.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/PagedExpandRequest.ts index 13c945134..8c68ba990 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/PagedExpandRequest.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/PagedExpandRequest.ts @@ -4,7 +4,7 @@ /** * The request for the PagedExpand method. */ -export interface PagedExpandRequest { +export interface IPagedExpandRequest { /** * The string to expand. */ @@ -22,7 +22,7 @@ export interface PagedExpandRequest { /** * The request for the PagedExpand method. */ -export interface PagedExpandRequest__Output { +export interface OPagedExpandRequest { /** * The string to expand. */ diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/PagedExpandResponse.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/PagedExpandResponse.ts index 823de43ed..3b3ef90c2 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/PagedExpandResponse.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/PagedExpandResponse.ts @@ -1,15 +1,15 @@ // Original file: deps/gapic-showcase/schema/google/showcase/v1beta1/echo.proto -import type { EchoResponse as _google_showcase_v1beta1_EchoResponse, EchoResponse__Output as _google_showcase_v1beta1_EchoResponse__Output } from '../../../google/showcase/v1beta1/EchoResponse'; +import type { IEchoResponse as I_google_showcase_v1beta1_EchoResponse, OEchoResponse as O_google_showcase_v1beta1_EchoResponse } from '../../../google/showcase/v1beta1/EchoResponse'; /** * The response for the PagedExpand method. */ -export interface PagedExpandResponse { +export interface IPagedExpandResponse { /** * The words that were expanded. */ - 'responses'?: (_google_showcase_v1beta1_EchoResponse)[]; + 'responses'?: (I_google_showcase_v1beta1_EchoResponse)[]; /** * The next page token. */ @@ -19,11 +19,11 @@ export interface PagedExpandResponse { /** * The response for the PagedExpand method. */ -export interface PagedExpandResponse__Output { +export interface OPagedExpandResponse { /** * The words that were expanded. */ - 'responses': (_google_showcase_v1beta1_EchoResponse__Output)[]; + 'responses': (O_google_showcase_v1beta1_EchoResponse)[]; /** * The next page token. */ diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/WaitMetadata.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/WaitMetadata.ts index 5f17b4457..ddbe77c22 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/WaitMetadata.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/WaitMetadata.ts @@ -1,23 +1,23 @@ // Original file: deps/gapic-showcase/schema/google/showcase/v1beta1/echo.proto -import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp'; +import type { ITimestamp as I_google_protobuf_Timestamp, OTimestamp as O_google_protobuf_Timestamp } from '../../../google/protobuf/Timestamp'; /** * The metadata for Wait operation. */ -export interface WaitMetadata { +export interface IWaitMetadata { /** * The time that this operation will complete. */ - 'end_time'?: (_google_protobuf_Timestamp | null); + 'end_time'?: (I_google_protobuf_Timestamp | null); } /** * The metadata for Wait operation. */ -export interface WaitMetadata__Output { +export interface OWaitMetadata { /** * The time that this operation will complete. */ - 'end_time': (_google_protobuf_Timestamp__Output | null); + 'end_time': (O_google_protobuf_Timestamp | null); } diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/WaitRequest.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/WaitRequest.ts index 46c095b65..331a66947 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/WaitRequest.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/WaitRequest.ts @@ -1,31 +1,31 @@ // Original file: deps/gapic-showcase/schema/google/showcase/v1beta1/echo.proto -import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp'; -import type { Status as _google_rpc_Status, Status__Output as _google_rpc_Status__Output } from '../../../google/rpc/Status'; -import type { WaitResponse as _google_showcase_v1beta1_WaitResponse, WaitResponse__Output as _google_showcase_v1beta1_WaitResponse__Output } from '../../../google/showcase/v1beta1/WaitResponse'; -import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../google/protobuf/Duration'; +import type { ITimestamp as I_google_protobuf_Timestamp, OTimestamp as O_google_protobuf_Timestamp } from '../../../google/protobuf/Timestamp'; +import type { IStatus as I_google_rpc_Status, OStatus as O_google_rpc_Status } from '../../../google/rpc/Status'; +import type { IWaitResponse as I_google_showcase_v1beta1_WaitResponse, OWaitResponse as O_google_showcase_v1beta1_WaitResponse } from '../../../google/showcase/v1beta1/WaitResponse'; +import type { IDuration as I_google_protobuf_Duration, ODuration as O_google_protobuf_Duration } from '../../../google/protobuf/Duration'; /** * The request for Wait method. */ -export interface WaitRequest { +export interface IWaitRequest { /** * The time that this operation will complete. */ - 'end_time'?: (_google_protobuf_Timestamp | null); + 'end_time'?: (I_google_protobuf_Timestamp | null); /** * The error that will be returned by the server. If this code is specified * to be the OK rpc code, an empty response will be returned. */ - 'error'?: (_google_rpc_Status | null); + 'error'?: (I_google_rpc_Status | null); /** * The response to be returned on operation completion. */ - 'success'?: (_google_showcase_v1beta1_WaitResponse | null); + 'success'?: (I_google_showcase_v1beta1_WaitResponse | null); /** * The duration of this operation. */ - 'ttl'?: (_google_protobuf_Duration | null); + 'ttl'?: (I_google_protobuf_Duration | null); 'end'?: "end_time"|"ttl"; 'response'?: "error"|"success"; } @@ -33,24 +33,24 @@ export interface WaitRequest { /** * The request for Wait method. */ -export interface WaitRequest__Output { +export interface OWaitRequest { /** * The time that this operation will complete. */ - 'end_time'?: (_google_protobuf_Timestamp__Output | null); + 'end_time'?: (O_google_protobuf_Timestamp | null); /** * The error that will be returned by the server. If this code is specified * to be the OK rpc code, an empty response will be returned. */ - 'error'?: (_google_rpc_Status__Output | null); + 'error'?: (O_google_rpc_Status | null); /** * The response to be returned on operation completion. */ - 'success'?: (_google_showcase_v1beta1_WaitResponse__Output | null); + 'success'?: (O_google_showcase_v1beta1_WaitResponse | null); /** * The duration of this operation. */ - 'ttl'?: (_google_protobuf_Duration__Output | null); + 'ttl'?: (O_google_protobuf_Duration | null); 'end': "end_time"|"ttl"; 'response': "error"|"success"; } diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/WaitResponse.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/WaitResponse.ts index 84b804f6b..667b450e2 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/WaitResponse.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/WaitResponse.ts @@ -4,7 +4,7 @@ /** * The result of the Wait operation. */ -export interface WaitResponse { +export interface IWaitResponse { /** * This content of the result. */ @@ -14,7 +14,7 @@ export interface WaitResponse { /** * The result of the Wait operation. */ -export interface WaitResponse__Output { +export interface OWaitResponse { /** * This content of the result. */ diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index 97e006912..c9cf35b1e 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -24,7 +24,7 @@ "fix": "gts fix", "pretest": "npm run compile", "posttest": "npm run check", - "generate-golden": "node ./build/bin/proto-loader-gen-types.js --keepCase --longs=String --enums=String --defaults --oneofs --json --includeComments -I deps/gapic-showcase/schema/ deps/googleapis/ -O ./golden-generated --grpcLib @grpc/grpc-js google/showcase/v1beta1/echo.proto", + "generate-golden": "node ./build/bin/proto-loader-gen-types.js --keepCase --longs=String --enums=String --defaults --oneofs --json --includeComments --inputTemplate=I%s --outputTemplate=O%s -I deps/gapic-showcase/schema/ deps/googleapis/ -O ./golden-generated --grpcLib @grpc/grpc-js google/showcase/v1beta1/echo.proto", "validate-golden": "rm -rf ./golden-generated-old && mv ./golden-generated/ ./golden-generated-old && npm run generate-golden && diff -rb ./golden-generated ./golden-generated-old" }, "repository": { From d8022a557d978307ebe5a413703f3660172e2661 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 7 Sep 2022 11:16:12 -0700 Subject: [PATCH 320/450] grpc-js-xds: Enable outlier detection by default --- packages/grpc-js-xds/src/environment.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/src/environment.ts b/packages/grpc-js-xds/src/environment.ts index b8b518da4..250f791ac 100644 --- a/packages/grpc-js-xds/src/environment.ts +++ b/packages/grpc-js-xds/src/environment.ts @@ -16,4 +16,4 @@ */ export const EXPERIMENTAL_FAULT_INJECTION = (process.env.GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION ?? 'true') === 'true'; -export const EXPERIMENTAL_OUTLIER_DETECTION = process.env.GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION === 'true'; \ No newline at end of file +export const EXPERIMENTAL_OUTLIER_DETECTION = (process.env.GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION ?? 'true') === 'true'; \ No newline at end of file From 3c27ed4c0012f110e55240c7113f4333ea0f6fc4 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 7 Sep 2022 12:39:39 -0700 Subject: [PATCH 321/450] grpc-js: Update grpc-js outlier detection check to match xds check --- packages/grpc-js/src/load-balancer-outlier-detection.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index 685cfc60d..52a9bfc95 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -38,7 +38,7 @@ function trace(text: string): void { const TYPE_NAME = 'outlier_detection'; -const OUTLIER_DETECTION_ENABLED = process.env.GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION !== 'false'; +const OUTLIER_DETECTION_ENABLED = (process.env.GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION ?? 'true') === 'true'; export interface SuccessRateEjectionConfig { readonly stdev_factor: number; From 51de24ac0ced9a55a714b2c894b0b5f103619761 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 7 Sep 2022 13:11:14 -0700 Subject: [PATCH 322/450] grpc-js: Bump to 1.7.0 --- packages/grpc-js-xds/package.json | 4 ++-- packages/grpc-js/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index 9062403cd..fcb9279f0 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.6.1", + "version": "1.7.0", "description": "Plugin for @grpc/grpc-js. Adds the xds:// URL scheme and associated features.", "main": "build/src/index.js", "scripts": { @@ -47,7 +47,7 @@ "re2-wasm": "^1.0.1" }, "peerDependencies": { - "@grpc/grpc-js": "~1.6.0" + "@grpc/grpc-js": "~1.7.0" }, "engines": { "node": ">=10.10.0" diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 8ca6eb1c6..d5e5e6927 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.6.12", + "version": "1.7.0", "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 4a861a0d4b84931bd9ff5c16072bb0a496d482dc Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 7 Sep 2022 13:13:50 -0700 Subject: [PATCH 323/450] grpc-js-xds: Update outlier detection entry in README --- packages/grpc-js-xds/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/README.md b/packages/grpc-js-xds/README.md index 20bd924a8..bbdd98863 100644 --- a/packages/grpc-js-xds/README.md +++ b/packages/grpc-js-xds/README.md @@ -28,4 +28,4 @@ const client = new MyServiceClient('xds:///example.com:123'); - [xDS Circuit Breaking](https://github.com/grpc/proposal/blob/master/A32-xds-circuit-breaking.md) - [xDS Client-Side Fault Injection](https://github.com/grpc/proposal/blob/master/A33-Fault-Injection.md) - [Client Status Discovery Service](https://github.com/grpc/proposal/blob/master/A40-csds-support.md) - - [Outlier Detection](https://github.com/grpc/proposal/blob/master/A50-xds-outlier-detection.md) (experimental, disabled by default, enabled by setting the environment variable `GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION=true`) \ No newline at end of file + - [Outlier Detection](https://github.com/grpc/proposal/blob/master/A50-xds-outlier-detection.md) \ No newline at end of file From f438191182c5346bc998be1dcaf2263be237f274 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 7 Sep 2022 15:59:17 -0700 Subject: [PATCH 324/450] grpc-js: Add tests for outlier detection validation rules --- .../grpc-js/test/test-outlier-detection.ts | 246 ++++++++++++++++++ 1 file changed, 246 insertions(+) diff --git a/packages/grpc-js/test/test-outlier-detection.ts b/packages/grpc-js/test/test-outlier-detection.ts index 977a3058f..74e536767 100644 --- a/packages/grpc-js/test/test-outlier-detection.ts +++ b/packages/grpc-js/test/test-outlier-detection.ts @@ -19,6 +19,7 @@ import * as assert from 'assert'; import * as path from 'path'; import * as grpc from '../src'; import { loadProtoFile } from './common'; +import { OutlierDetectionLoadBalancingConfig } from '../src/load-balancer-outlier-detection' function multiDone(done: Mocha.Done, target: number) { let count = 0; @@ -67,6 +68,251 @@ const protoFile = path.join(__dirname, 'fixtures', 'echo_service.proto'); const EchoService = loadProtoFile(protoFile) .EchoService as grpc.ServiceClientConstructor; +describe('Outlier detection config validation', () => { + describe('interval', () => { + it('Should reject a negative interval', () => { + const loadBalancingConfig = { + interval: { + seconds: -1, + nanos: 0 + }, + child_policy: [{round_robin: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /interval parse error: values out of range for non-negative Duaration/); + }); + it('Should reject a large interval', () => { + const loadBalancingConfig = { + interval: { + seconds: 1e12, + nanos: 0 + }, + child_policy: [{round_robin: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /interval parse error: values out of range for non-negative Duaration/); + }); + it('Should reject a negative interval.nanos', () => { + const loadBalancingConfig = { + interval: { + seconds: 0, + nanos: -1 + }, + child_policy: [{round_robin: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /interval parse error: values out of range for non-negative Duaration/); + }); + it('Should reject a large interval.nanos', () => { + const loadBalancingConfig = { + interval: { + seconds: 0, + nanos: 1e12 + }, + child_policy: [{round_robin: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /interval parse error: values out of range for non-negative Duaration/); + }); + }); + describe('base_ejection_time', () => { + it('Should reject a negative base_ejection_time', () => { + const loadBalancingConfig = { + base_ejection_time: { + seconds: -1, + nanos: 0 + }, + child_policy: [{round_robin: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /base_ejection_time parse error: values out of range for non-negative Duaration/); + }); + it('Should reject a large base_ejection_time', () => { + const loadBalancingConfig = { + base_ejection_time: { + seconds: 1e12, + nanos: 0 + }, + child_policy: [{round_robin: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /base_ejection_time parse error: values out of range for non-negative Duaration/); + }); + it('Should reject a negative base_ejection_time.nanos', () => { + const loadBalancingConfig = { + base_ejection_time: { + seconds: 0, + nanos: -1 + }, + child_policy: [{round_robin: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /base_ejection_time parse error: values out of range for non-negative Duaration/); + }); + it('Should reject a large base_ejection_time.nanos', () => { + const loadBalancingConfig = { + base_ejection_time: { + seconds: 0, + nanos: 1e12 + }, + child_policy: [{round_robin: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /base_ejection_time parse error: values out of range for non-negative Duaration/); + }); + }); + describe('max_ejection_time', () => { + it('Should reject a negative max_ejection_time', () => { + const loadBalancingConfig = { + max_ejection_time: { + seconds: -1, + nanos: 0 + }, + child_policy: [{round_robin: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /max_ejection_time parse error: values out of range for non-negative Duaration/); + }); + it('Should reject a large max_ejection_time', () => { + const loadBalancingConfig = { + max_ejection_time: { + seconds: 1e12, + nanos: 0 + }, + child_policy: [{round_robin: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /max_ejection_time parse error: values out of range for non-negative Duaration/); + }); + it('Should reject a negative max_ejection_time.nanos', () => { + const loadBalancingConfig = { + max_ejection_time: { + seconds: 0, + nanos: -1 + }, + child_policy: [{round_robin: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /max_ejection_time parse error: values out of range for non-negative Duaration/); + }); + it('Should reject a large max_ejection_time.nanos', () => { + const loadBalancingConfig = { + max_ejection_time: { + seconds: 0, + nanos: 1e12 + }, + child_policy: [{round_robin: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /max_ejection_time parse error: values out of range for non-negative Duaration/); + }); + }); + describe('max_ejection_percent', () => { + it('Should reject a value above 100', () => { + const loadBalancingConfig = { + max_ejection_percent: 101, + child_policy: [{round_robin: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /max_ejection_percent parse error: value out of range for percentage/); + }); + it('Should reject a negative value', () => { + const loadBalancingConfig = { + max_ejection_percent: -1, + child_policy: [{round_robin: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /max_ejection_percent parse error: value out of range for percentage/); + }); + }); + describe('success_rate_ejection.enforcement_percentage', () => { + it('Should reject a value above 100', () => { + const loadBalancingConfig = { + success_rate_ejection: { + enforcement_percentage: 101 + }, + child_policy: [{round_robin: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /success_rate_ejection\.enforcement_percentage parse error: value out of range for percentage/); + }); + it('Should reject a negative value', () => { + const loadBalancingConfig = { + success_rate_ejection: { + enforcement_percentage: -1 + }, + child_policy: [{round_robin: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /success_rate_ejection\.enforcement_percentage parse error: value out of range for percentage/); + }); + }); + describe('failure_percentage_ejection.threshold', () => { + it('Should reject a value above 100', () => { + const loadBalancingConfig = { + failure_percentage_ejection: { + threshold: 101 + }, + child_policy: [{round_robin: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /failure_percentage_ejection\.threshold parse error: value out of range for percentage/); + }); + it('Should reject a negative value', () => { + const loadBalancingConfig = { + failure_percentage_ejection: { + threshold: -1 + }, + child_policy: [{round_robin: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /failure_percentage_ejection\.threshold parse error: value out of range for percentage/); + }); + }); + describe('failure_percentage_ejection.enforcement_percentage', () => { + it('Should reject a value above 100', () => { + const loadBalancingConfig = { + failure_percentage_ejection: { + enforcement_percentage: 101 + }, + child_policy: [{round_robin: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /failure_percentage_ejection\.enforcement_percentage parse error: value out of range for percentage/); + }); + it('Should reject a negative value', () => { + const loadBalancingConfig = { + failure_percentage_ejection: { + enforcement_percentage: -1 + }, + child_policy: [{round_robin: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /failure_percentage_ejection\.enforcement_percentage parse error: value out of range for percentage/); + }); + }); +}); + describe('Outlier detection', () => { const GOOD_PORTS = 4; let goodServer: grpc.Server; From b0e28f7f939f4989cbb4ac400accd1cf7db8319f Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 12 Sep 2022 11:20:19 -0700 Subject: [PATCH 325/450] grpc-js: Add test for sending metadata from call creds on channel creds --- .../grpc-js/test/test-channel-credentials.ts | 74 ++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/test/test-channel-credentials.ts b/packages/grpc-js/test/test-channel-credentials.ts index d6028f469..2b537ac97 100644 --- a/packages/grpc-js/test/test-channel-credentials.ts +++ b/packages/grpc-js/test/test-channel-credentials.ts @@ -17,12 +17,22 @@ import * as assert from 'assert'; import * as fs from 'fs'; +import * as path from 'path'; import { promisify } from 'util'; +import * as protoLoader from '@grpc/proto-loader'; import { CallCredentials } from '../src/call-credentials'; import { ChannelCredentials } from '../src/channel-credentials'; +import * as grpc from '../src'; +import { ServiceClient, ServiceClientConstructor } from '../src/make-client'; +import { TestServiceClient, TestServiceHandlers } from './generated/TestService'; +import { ProtoGrpcType as TestServiceGrpcType } from './generated/test_service'; -import { assert2, mockFunction } from './common'; +import { assert2, loadProtoFile, mockFunction } from './common'; +import { sendUnaryData, ServerUnaryCall, ServiceError } from '../src'; + +const protoFile = path.join(__dirname, 'fixtures', 'echo_service.proto'); +const echoService = loadProtoFile(protoFile).EchoService as ServiceClientConstructor; class CallCredentialsMock implements CallCredentials { child: CallCredentialsMock | null = null; @@ -138,3 +148,65 @@ describe('ChannelCredentials Implementation', () => { }); }); }); + +describe('ChannelCredentials usage', () => { + let client: ServiceClient; + let server: grpc.Server; + before(async () => { + const {ca, key, cert} = await pFixtures; + const serverCreds = grpc.ServerCredentials.createSsl(null, [{private_key: key, cert_chain: cert}]); + const channelCreds = ChannelCredentials.createSsl(ca); + const callCreds = CallCredentials.createFromMetadataGenerator((options, cb) => { + const metadata = new grpc.Metadata(); + metadata.set('test-key', 'test-value'); + cb(null, metadata); + }); + const combinedCreds = channelCreds.compose(callCreds); + return new Promise((resolve, reject) => { + + server = new grpc.Server(); + server.addService(echoService.service, { + echo(call: ServerUnaryCall, callback: sendUnaryData) { + call.sendMetadata(call.metadata); + callback(null, call.request); + }, + }); + + server.bindAsync( + 'localhost:0', + serverCreds, + (err, port) => { + if (err) { + reject(err); + return; + } + client = new echoService( + `localhost:${port}`, + combinedCreds, + {'grpc.ssl_target_name_override': 'foo.test.google.fr', 'grpc.default_authority': 'foo.test.google.fr'} + ); + server.start(); + resolve(); + } + ); + }); + }); + after(() => { + server.forceShutdown(); + }); + + it('Should send the metadata from call credentials attached to channel credentials', (done) => { + const call = client.echo( + { value: 'test value', value2: 3 }, + assert2.mustCall((error: ServiceError, response: any) => { + assert.ifError(error); + assert.deepStrictEqual(response, { value: 'test value', value2: 3 }); + }) + ); + call.on('metadata', assert2.mustCall((metadata: grpc.Metadata) => { + assert.deepStrictEqual(metadata.get('test-key'), ['test-value']); + + })); + assert2.afterMustCallsSatisfied(done); + }); +}); \ No newline at end of file From 9269f3a76f7c72d643ef5ad0db1261da08045bf1 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 12 Sep 2022 11:46:06 -0700 Subject: [PATCH 326/450] grpc-js: Restrict control-plane status codes --- packages/grpc-js/src/channel.ts | 47 ++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 88bf3a7e0..53b80c1cf 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -68,6 +68,28 @@ function getNewCallNumber(): number { return callNumber; } +const INAPPPROPRIATE_CONTROL_PLANE_CODES: Status[] = [ + Status.OK, + Status.INVALID_ARGUMENT, + Status.NOT_FOUND, + Status.ALREADY_EXISTS, + Status.FAILED_PRECONDITION, + Status.ABORTED, + Status.OUT_OF_RANGE, + Status.DATA_LOSS +] + +function restrictControlPlaneStatusCode(code: Status, details: string): {code: Status, details: string} { + if (INAPPPROPRIATE_CONTROL_PLANE_CODES.includes(code)) { + return { + code: Status.INTERNAL, + details: `Invalid status from control plane: ${code} ${Status[code]} ${details}` + } + } else { + return {code, details}; + } +} + /** * An interface that represents a communication channel to a server specified * by a given address. @@ -320,7 +342,7 @@ export class ChannelImplementation implements Channel { this.trace('Name resolution failed with calls queued for config selection'); } if (this.configSelector === null) { - this.currentResolutionError = status; + this.currentResolutionError = {...restrictControlPlaneStatusCode(status.code, status.details), metadata: status.metadata}; } const localQueue = this.configSelectionQueue; this.configSelectionQueue = []; @@ -534,10 +556,11 @@ export class ChannelImplementation implements Channel { }, (error: Error & { code: number }) => { // We assume the error code isn't 0 (Status.OK) - callStream.cancelWithStatus( + const {code, details} = restrictControlPlaneStatusCode( typeof error.code === 'number' ? error.code : Status.UNKNOWN, `Getting metadata from plugin failed with error: ${error.message}` - ); + ) + callStream.cancelWithStatus(code, details); } ); } @@ -549,17 +572,13 @@ export class ChannelImplementation implements Channel { if (callMetadata.getOptions().waitForReady) { this.pushPick(callStream, callMetadata, callConfig, dynamicFilters); } else { - callStream.cancelWithStatus( - pickResult.status!.code, - pickResult.status!.details - ); + const {code, details} = restrictControlPlaneStatusCode(pickResult.status!.code, pickResult.status!.details); + callStream.cancelWithStatus(code, details); } break; case PickResultType.DROP: - callStream.cancelWithStatus( - pickResult.status!.code, - pickResult.status!.details - ); + const {code, details} = restrictControlPlaneStatusCode(pickResult.status!.code, pickResult.status!.details); + callStream.cancelWithStatus(code, details); break; default: throw new Error( @@ -668,10 +687,8 @@ export class ChannelImplementation implements Channel { this.tryPick(stream, metadata, callConfig, []); } } else { - stream.cancelWithStatus( - callConfig.status, - 'Failed to route call to method ' + stream.getMethod() - ); + const {code, details} = restrictControlPlaneStatusCode(callConfig.status, 'Failed to route call to method ' + stream.getMethod()); + stream.cancelWithStatus(code, details); } } } From caf37e4f15b7837c03bf182696676ddeb0fbbfbf Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 12 Sep 2022 12:42:44 -0700 Subject: [PATCH 327/450] Fix constant name spelling --- packages/grpc-js/src/channel.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 53b80c1cf..93b2204c6 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -68,7 +68,7 @@ function getNewCallNumber(): number { return callNumber; } -const INAPPPROPRIATE_CONTROL_PLANE_CODES: Status[] = [ +const INAPPROPRIATE_CONTROL_PLANE_CODES: Status[] = [ Status.OK, Status.INVALID_ARGUMENT, Status.NOT_FOUND, @@ -80,7 +80,7 @@ const INAPPPROPRIATE_CONTROL_PLANE_CODES: Status[] = [ ] function restrictControlPlaneStatusCode(code: Status, details: string): {code: Status, details: string} { - if (INAPPPROPRIATE_CONTROL_PLANE_CODES.includes(code)) { + if (INAPPROPRIATE_CONTROL_PLANE_CODES.includes(code)) { return { code: Status.INTERNAL, details: `Invalid status from control plane: ${code} ${Status[code]} ${details}` From 02a43a302d563115c20ec95ec4818e6e21fba542 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 12 Sep 2022 13:47:57 -0700 Subject: [PATCH 328/450] grpc-js-xds: NACK WeightedCluster if total_weight is 0 --- packages/grpc-js-xds/src/xds-stream-state/rds-state.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts index 77a84469b..a5d3c47cf 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts @@ -89,6 +89,9 @@ export class RdsState extends BaseXdsStreamState imp } } if (route.route!.cluster_specifier === 'weighted_clusters') { + if (route.route.weighted_clusters!.total_weight?.value === 0) { + return false; + } let weightSum = 0; for (const clusterWeight of route.route.weighted_clusters!.clusters) { weightSum += clusterWeight.weight?.value ?? 0; From 640a1963c741b7721b00f462801958433a27a805 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 20 Sep 2022 16:20:22 -0700 Subject: [PATCH 329/450] grpc-js: Defer evaluating caller stack until an error --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/client.ts | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index d5e5e6927..c0db93ae0 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.7.0", + "version": "1.7.1", "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/client.ts b/packages/grpc-js/src/client.ts index 747c5c877..112fb7c7c 100644 --- a/packages/grpc-js/src/client.ts +++ b/packages/grpc-js/src/client.ts @@ -321,7 +321,7 @@ export class Client { } let responseMessage: ResponseType | null = null; let receivedStatus = false; - const callerStack = (new Error().stack!).split('\n').slice(1).join('\n'); + const callerStackError = new Error(); call.start(callProperties.metadata, { onReceiveMetadata: (metadata) => { emitter.emit('metadata', metadata); @@ -340,6 +340,7 @@ export class Client { receivedStatus = true; if (status.code === Status.OK) { if (responseMessage === null) { + const callerStack = callerStackError.stack!.split('\n').slice(1).join('\n'); callProperties.callback!(callErrorFromStatus({ code: Status.INTERNAL, details: 'No message received', @@ -349,6 +350,7 @@ export class Client { callProperties.callback!(null, responseMessage); } } else { + const callerStack = callerStackError.stack!.split('\n').slice(1).join('\n'); callProperties.callback!(callErrorFromStatus(status, callerStack)); } emitter.emit('status', status); @@ -447,7 +449,7 @@ export class Client { } let responseMessage: ResponseType | null = null; let receivedStatus = false; - const callerStack = (new Error().stack!).split('\n').slice(1).join('\n'); + const callerStackError = new Error(); call.start(callProperties.metadata, { onReceiveMetadata: (metadata) => { emitter.emit('metadata', metadata); @@ -466,6 +468,7 @@ export class Client { receivedStatus = true; if (status.code === Status.OK) { if (responseMessage === null) { + const callerStack = callerStackError.stack!.split('\n').slice(1).join('\n'); callProperties.callback!(callErrorFromStatus({ code: Status.INTERNAL, details: 'No message received', @@ -475,6 +478,7 @@ export class Client { callProperties.callback!(null, responseMessage); } } else { + const callerStack = callerStackError.stack!.split('\n').slice(1).join('\n'); callProperties.callback!(callErrorFromStatus(status, callerStack)); } emitter.emit('status', status); @@ -577,7 +581,7 @@ export class Client { call.setCredentials(callProperties.callOptions.credentials); } let receivedStatus = false; - const callerStack = (new Error().stack!).split('\n').slice(1).join('\n'); + const callerStackError = new Error(); call.start(callProperties.metadata, { onReceiveMetadata(metadata: Metadata) { stream.emit('metadata', metadata); @@ -593,6 +597,7 @@ export class Client { receivedStatus = true; stream.push(null); if (status.code !== Status.OK) { + const callerStack = callerStackError.stack!.split('\n').slice(1).join('\n'); stream.emit('error', callErrorFromStatus(status, callerStack)); } stream.emit('status', status); @@ -675,7 +680,7 @@ export class Client { call.setCredentials(callProperties.callOptions.credentials); } let receivedStatus = false; - const callerStack = (new Error().stack!).split('\n').slice(1).join('\n'); + const callerStackError = new Error(); call.start(callProperties.metadata, { onReceiveMetadata(metadata: Metadata) { stream.emit('metadata', metadata); @@ -690,6 +695,7 @@ export class Client { receivedStatus = true; stream.push(null); if (status.code !== Status.OK) { + const callerStack = callerStackError.stack!.split('\n').slice(1).join('\n'); stream.emit('error', callErrorFromStatus(status, callerStack)); } stream.emit('status', status); From 5b42e999e4182ac26dbce77c43374c0a4a02d206 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 20 Sep 2022 16:33:01 -0700 Subject: [PATCH 330/450] grpc-js: Refactor getting stack trace into function --- packages/grpc-js/src/client.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/grpc-js/src/client.ts b/packages/grpc-js/src/client.ts index 112fb7c7c..1198dc468 100644 --- a/packages/grpc-js/src/client.ts +++ b/packages/grpc-js/src/client.ts @@ -108,6 +108,10 @@ export type ClientOptions = Partial & { callInvocationTransformer?: CallInvocationTransformer; }; +function getErrorStackString(error: Error): string { + return error.stack!.split('\n').slice(1).join('\n'); +} + /** * A generic gRPC client. Primarily useful as a base class for all generated * clients. @@ -340,7 +344,7 @@ export class Client { receivedStatus = true; if (status.code === Status.OK) { if (responseMessage === null) { - const callerStack = callerStackError.stack!.split('\n').slice(1).join('\n'); + const callerStack = getErrorStackString(callerStackError); callProperties.callback!(callErrorFromStatus({ code: Status.INTERNAL, details: 'No message received', @@ -350,7 +354,7 @@ export class Client { callProperties.callback!(null, responseMessage); } } else { - const callerStack = callerStackError.stack!.split('\n').slice(1).join('\n'); + const callerStack = getErrorStackString(callerStackError); callProperties.callback!(callErrorFromStatus(status, callerStack)); } emitter.emit('status', status); @@ -468,7 +472,7 @@ export class Client { receivedStatus = true; if (status.code === Status.OK) { if (responseMessage === null) { - const callerStack = callerStackError.stack!.split('\n').slice(1).join('\n'); + const callerStack = getErrorStackString(callerStackError); callProperties.callback!(callErrorFromStatus({ code: Status.INTERNAL, details: 'No message received', @@ -478,7 +482,7 @@ export class Client { callProperties.callback!(null, responseMessage); } } else { - const callerStack = callerStackError.stack!.split('\n').slice(1).join('\n'); + const callerStack = getErrorStackString(callerStackError); callProperties.callback!(callErrorFromStatus(status, callerStack)); } emitter.emit('status', status); @@ -597,7 +601,7 @@ export class Client { receivedStatus = true; stream.push(null); if (status.code !== Status.OK) { - const callerStack = callerStackError.stack!.split('\n').slice(1).join('\n'); + const callerStack = getErrorStackString(callerStackError); stream.emit('error', callErrorFromStatus(status, callerStack)); } stream.emit('status', status); @@ -695,7 +699,7 @@ export class Client { receivedStatus = true; stream.push(null); if (status.code !== Status.OK) { - const callerStack = callerStackError.stack!.split('\n').slice(1).join('\n'); + const callerStack = getErrorStackString(callerStackError); stream.emit('error', callErrorFromStatus(status, callerStack)); } stream.emit('status', status); From 1c0b6459feaf8fa5aa393259ec10e4f1a30e3ada Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 21 Sep 2022 10:44:59 -0700 Subject: [PATCH 331/450] proto-loader: Bump to 0.7.3 --- packages/proto-loader/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/proto-loader/package.json b/packages/proto-loader/package.json index c9cf35b1e..cae7635f6 100644 --- a/packages/proto-loader/package.json +++ b/packages/proto-loader/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/proto-loader", - "version": "0.7.2", + "version": "0.7.3", "author": "Google Inc.", "contributors": [ { From 2aac1da48e82fc3663b75f18c527ffe56ae6cc79 Mon Sep 17 00:00:00 2001 From: Ryosuke Hayashi Date: Sun, 2 Oct 2022 19:13:19 +0900 Subject: [PATCH 332/450] Build arm64 binaries for mac --- packages/grpc-tools/build_binaries.sh | 61 +++++++++++++++------------ 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/packages/grpc-tools/build_binaries.sh b/packages/grpc-tools/build_binaries.sh index b26946afa..73f95f6d2 100755 --- a/packages/grpc-tools/build_binaries.sh +++ b/packages/grpc-tools/build_binaries.sh @@ -27,38 +27,45 @@ tools_version=$(jq '.version' < package.json | tr -d '"') out_dir=$base/../../artifacts/grpc-tools/v$tools_version mkdir -p "$out_dir" -case $(uname -s) in - Linux) - platform=linux - arch_list=( ia32 x64 ) - ;; - Darwin) - platform=darwin - arch_list=( x64 ) - ;; -esac +build () { + cmake_flag=$* -for arch in "${arch_list[@]}"; do - case $arch in - ia32) - toolchain_flag=-DCMAKE_TOOLCHAIN_FILE=linux_32bit.toolchain.cmake - ;; - *) - toolchain_flag=-DCMAKE_TOOLCHAIN_FILE=linux_64bit.toolchain.cmake - ;; - esac - rm -f $base/build/bin/protoc - rm -f $base/build/bin/grpc_node_plugin + rm -rf $base/build/bin rm -f $base/CMakeCache.txt rm -rf $base/CMakeFiles rm -f $protobuf_base/CMakeCache.txt rm -rf $protobuf_base/CMakeFiles - cmake $toolchain_flag . && cmake --build . --target clean && cmake --build . -- -j 12 - mkdir -p "$base/build/bin" + cmake $cmake_flag . && cmake --build . --target clean && cmake --build . -- -j 12 + mkdir -p $base/build/bin cp -L $protobuf_base/protoc $base/build/bin/protoc cp $base/grpc_node_plugin $base/build/bin/ file $base/build/bin/* - cd $base/build - tar -czf "$out_dir/$platform-$arch.tar.gz" bin/ - cd $base -done \ No newline at end of file +} + +artifacts() { + platform=$1 + arch=$2 + dir=$3 + + tar -czf $out_dir/$platform-$arch.tar.gz -C $(dirname $dir) $(basename $dir) +} + +case $(uname -s) in + Linux) + build -DCMAKE_TOOLCHAIN_FILE=linux_32bit.toolchain.cmake + artifacts linux ia32 $base/build/bin + build -DCMAKE_TOOLCHAIN_FILE=linux_64bit.toolchain.cmake + artifacts linux x64 $base/build/bin + ;; + Darwin) + build -DCMAKE_TOOLCHAIN_FILE=linux_64bit.toolchain.cmake -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" + + for arch in "x86_64" "arm64"; do + mkdir $base/build/bin/$arch + for bin in protoc grpc_node_plugin; do + lipo -extract x86_64 $base/build/bin/$bin -o $base/build/bin/$arch/$bin + done + artifacts darwin $arch $base/build/bin/$arch/ + done + ;; +esac From 7bbbf0d460271e02df9549f070cfa4cd48f57b64 Mon Sep 17 00:00:00 2001 From: nakamura-k30 <51692717+nakamura-k30@users.noreply.github.com> Date: Tue, 4 Oct 2022 20:12:46 +0900 Subject: [PATCH 333/450] list undocumented tracers --- doc/environment_variables.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/environment_variables.md b/doc/environment_variables.md index 0237dff7e..70b32e715 100644 --- a/doc/environment_variables.md +++ b/doc/environment_variables.md @@ -29,6 +29,7 @@ can be set. - `channel` - Traces channel events - `connectivity_state` - Traces channel connectivity state changes - `dns_resolver` - Traces DNS resolution + - `ip_resolver` - Traces IPv4/v6 resolution - `pick_first` - Traces the pick first load balancing policy - `proxy` - Traces proxy operations - `resolving_load_balancer` - Traces the resolving load balancer @@ -40,6 +41,9 @@ can be set. - `subchannel_flowctrl` - Traces HTTP/2 flow control. Includes per-call logs. - `subchannel_internals` - Traces HTTP/2 session state. Includes per-call logs. - `channel_stacktrace` - Traces channel construction events with stack traces. + - `keepalive` - Traces gRPC keepalive pings + - `index` - Traces module loading + - `outlier_detection` - Traces outlier detection events The following tracers are added by the `@grpc/grpc-js-xds` library: - `cds_balancer` - Traces the CDS load balancing policy From 98d2506139110f1a604bb9ec871f7833af8178dd Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 5 Oct 2022 09:54:42 -0700 Subject: [PATCH 334/450] grpc-tools: Bump to version 1.11.3 --- packages/grpc-tools/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-tools/package.json b/packages/grpc-tools/package.json index 95faa84c4..1c7deb250 100644 --- a/packages/grpc-tools/package.json +++ b/packages/grpc-tools/package.json @@ -1,6 +1,6 @@ { "name": "grpc-tools", - "version": "1.11.2", + "version": "1.11.3", "author": "Google Inc.", "description": "Tools for developing with gRPC on Node.js", "homepage": "https://grpc.io/", From 7229fc28eb90618fe6f54da0b8a345dc379852c6 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 5 Oct 2022 13:22:51 -0700 Subject: [PATCH 335/450] grpc-tools: Fix x64 arch name in build script --- packages/grpc-tools/build_binaries.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-tools/build_binaries.sh b/packages/grpc-tools/build_binaries.sh index 73f95f6d2..e44881083 100755 --- a/packages/grpc-tools/build_binaries.sh +++ b/packages/grpc-tools/build_binaries.sh @@ -60,7 +60,7 @@ case $(uname -s) in Darwin) build -DCMAKE_TOOLCHAIN_FILE=linux_64bit.toolchain.cmake -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" - for arch in "x86_64" "arm64"; do + for arch in "x64" "arm64"; do mkdir $base/build/bin/$arch for bin in protoc grpc_node_plugin; do lipo -extract x86_64 $base/build/bin/$bin -o $base/build/bin/$arch/$bin From 7942b23e79567d74b6b9d8796ab15f985f6926e2 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 10 Oct 2022 14:11:16 -0700 Subject: [PATCH 336/450] grpc-js-xds: Validate that endpoint weights sum to no more than 32 bit uint max per priority --- packages/grpc-js-xds/src/xds-stream-state/eds-state.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts index 91cb6f30f..dd1adf18a 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts @@ -50,6 +50,7 @@ export class EdsState extends BaseXdsStreamState */ public validateResponse(message: ClusterLoadAssignment__Output) { const seenLocalities: {locality: Locality__Output, priority: number}[] = []; + const priorityTotalWeights: Map = new Map(); for (const endpoint of message.endpoints) { if (!endpoint.locality) { return false; @@ -72,6 +73,12 @@ export class EdsState extends BaseXdsStreamState return false; } } + priorityTotalWeights.set(endpoint.priority, (priorityTotalWeights.get(endpoint.priority) ?? 0) + (endpoint.load_balancing_weight?.value ?? 0)); + } + for (const totalWeight of priorityTotalWeights.values()) { + if (totalWeight >= 1<<32) { + return false; + } } return true; } From 8832fc2d39d25417e59eeea295333c6525c9f6a3 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 11 Oct 2022 13:55:19 -0700 Subject: [PATCH 337/450] grpc-js-xds: Validate uniqueness of addresses in EDS updates --- .../grpc-js-xds/src/xds-stream-state/eds-state.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts index dd1adf18a..370cf7502 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts @@ -18,6 +18,7 @@ import { experimental, logVerbosity, StatusObject } from "@grpc/grpc-js"; import { isIPv4, isIPv6 } from "net"; import { Locality__Output } from "../generated/envoy/config/core/v3/Locality"; +import { SocketAddress__Output } from "../generated/envoy/config/core/v3/SocketAddress"; import { ClusterLoadAssignment__Output } from "../generated/envoy/config/endpoint/v3/ClusterLoadAssignment"; import { Any__Output } from "../generated/google/protobuf/Any"; import { BaseXdsStreamState, HandleResponseResult, RejectedResourceEntry, ResourcePair, Watcher, XdsStreamState } from "./xds-stream-state"; @@ -32,6 +33,10 @@ function localitiesEqual(a: Locality__Output, b: Locality__Output) { return a.region === b.region && a.sub_zone === b.sub_zone && a.zone === b.zone; } +function addressesEqual(a: SocketAddress__Output, b: SocketAddress__Output) { + return a.address === b.address && a.port_value === b.port_value; +} + export class EdsState extends BaseXdsStreamState implements XdsStreamState { protected getResourceName(resource: ClusterLoadAssignment__Output): string { return resource.cluster_name; @@ -50,6 +55,7 @@ export class EdsState extends BaseXdsStreamState */ public validateResponse(message: ClusterLoadAssignment__Output) { const seenLocalities: {locality: Locality__Output, priority: number}[] = []; + const seenAddresses: SocketAddress__Output[] = []; const priorityTotalWeights: Map = new Map(); for (const endpoint of message.endpoints) { if (!endpoint.locality) { @@ -72,6 +78,12 @@ export class EdsState extends BaseXdsStreamState if (!(isIPv4(socketAddress.address) || isIPv6(socketAddress.address))) { return false; } + for (const address of seenAddresses) { + if (addressesEqual(socketAddress, address)) { + return false; + } + } + seenAddresses.push(socketAddress); } priorityTotalWeights.set(endpoint.priority, (priorityTotalWeights.get(endpoint.priority) ?? 0) + (endpoint.load_balancing_weight?.value ?? 0)); } From bedc9628f5614f5f020c52a40dea064c53834371 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 11 Oct 2022 13:58:57 -0700 Subject: [PATCH 338/450] grpc-js-xds: Validate continuity of priorities in EDS updates --- packages/grpc-js-xds/src/xds-stream-state/eds-state.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts index 370cf7502..9b7b9cd5f 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts @@ -92,6 +92,11 @@ export class EdsState extends BaseXdsStreamState return false; } } + for (const priority of priorityTotalWeights.keys()) { + if (priority > 0 && !priorityTotalWeights.has(priority - 1)) { + return false; + } + } return true; } } \ No newline at end of file From 339eb37efd5fc6e7da177036913a0840c81c1195 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 26 Apr 2022 10:03:08 -0700 Subject: [PATCH 339/450] grpc-js: Refactor in preparation for retries --- .../grpc-js/src/call-credentials-filter.ts | 86 -- packages/grpc-js/src/call-interface.ts | 169 ++++ packages/grpc-js/src/call-number.ts | 22 + packages/grpc-js/src/call-stream.ts | 882 ------------------ packages/grpc-js/src/call.ts | 2 +- packages/grpc-js/src/channel.ts | 653 +------------ packages/grpc-js/src/client-interceptors.ts | 2 +- packages/grpc-js/src/client.ts | 3 +- packages/grpc-js/src/compression-filter.ts | 4 +- packages/grpc-js/src/deadline-filter.ts | 120 --- packages/grpc-js/src/deadline.ts | 58 ++ packages/grpc-js/src/experimental.ts | 2 +- packages/grpc-js/src/filter-stack.ts | 14 +- packages/grpc-js/src/filter.ts | 12 +- packages/grpc-js/src/index.ts | 5 +- packages/grpc-js/src/internal-channel.ts | 504 ++++++++++ .../src/load-balancer-outlier-detection.ts | 34 +- .../grpc-js/src/load-balancer-pick-first.ts | 2 +- .../grpc-js/src/load-balancer-round-robin.ts | 2 +- packages/grpc-js/src/load-balancing-call.ts | 281 ++++++ .../grpc-js/src/max-message-size-filter.ts | 30 +- packages/grpc-js/src/picker.ts | 23 +- packages/grpc-js/src/resolver-dns.ts | 2 +- packages/grpc-js/src/resolver-ip.ts | 2 +- packages/grpc-js/src/resolver.ts | 2 +- packages/grpc-js/src/resolving-call.ts | 219 +++++ .../grpc-js/src/resolving-load-balancer.ts | 2 +- packages/grpc-js/src/server-call.ts | 5 +- packages/grpc-js/src/service-config.ts | 23 + packages/grpc-js/src/status-builder.ts | 2 +- packages/grpc-js/src/subchannel-call.ts | 504 ++++++++++ packages/grpc-js/src/subchannel.ts | 91 +- packages/grpc-js/test/test-resolver.ts | 2 +- 33 files changed, 1886 insertions(+), 1878 deletions(-) delete mode 100644 packages/grpc-js/src/call-credentials-filter.ts create mode 100644 packages/grpc-js/src/call-interface.ts create mode 100644 packages/grpc-js/src/call-number.ts delete mode 100644 packages/grpc-js/src/call-stream.ts delete mode 100644 packages/grpc-js/src/deadline-filter.ts create mode 100644 packages/grpc-js/src/deadline.ts create mode 100644 packages/grpc-js/src/internal-channel.ts create mode 100644 packages/grpc-js/src/load-balancing-call.ts create mode 100644 packages/grpc-js/src/resolving-call.ts create mode 100644 packages/grpc-js/src/subchannel-call.ts diff --git a/packages/grpc-js/src/call-credentials-filter.ts b/packages/grpc-js/src/call-credentials-filter.ts deleted file mode 100644 index 5c746297e..000000000 --- a/packages/grpc-js/src/call-credentials-filter.ts +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2019 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 { Call } from './call-stream'; -import { Channel } from './channel'; -import { BaseFilter, Filter, FilterFactory } from './filter'; -import { Metadata } from './metadata'; -import { Status } from './constants'; -import { splitHostPort } from './uri-parser'; -import { ServiceError } from './call'; - -export class CallCredentialsFilter extends BaseFilter implements Filter { - private serviceUrl: string; - constructor( - private readonly channel: Channel, - private readonly stream: Call - ) { - super(); - this.channel = channel; - this.stream = stream; - const splitPath: string[] = stream.getMethod().split('/'); - let serviceName = ''; - /* The standard path format is "/{serviceName}/{methodName}", so if we split - * by '/', the first item should be empty and the second should be the - * service name */ - if (splitPath.length >= 2) { - serviceName = splitPath[1]; - } - const hostname = splitHostPort(stream.getHost())?.host ?? 'localhost'; - /* Currently, call credentials are only allowed on HTTPS connections, so we - * can assume that the scheme is "https" */ - this.serviceUrl = `https://${hostname}/${serviceName}`; - } - - async sendMetadata(metadata: Promise): Promise { - const credentials = this.stream.getCredentials(); - const credsMetadata = credentials.generateMetadata({ - service_url: this.serviceUrl, - }); - const resultMetadata = await metadata; - try { - resultMetadata.merge(await credsMetadata); - } catch (error) { - this.stream.cancelWithStatus( - Status.UNAUTHENTICATED, - `Failed to retrieve auth metadata with error: ${error.message}` - ); - return Promise.reject('Failed to retrieve auth metadata'); - } - if (resultMetadata.get('authorization').length > 1) { - this.stream.cancelWithStatus( - Status.INTERNAL, - '"authorization" metadata cannot have multiple values' - ); - return Promise.reject( - '"authorization" metadata cannot have multiple values' - ); - } - return resultMetadata; - } -} - -export class CallCredentialsFilterFactory - implements FilterFactory { - constructor(private readonly channel: Channel) { - this.channel = channel; - } - - createFilter(callStream: Call): CallCredentialsFilter { - return new CallCredentialsFilter(this.channel, callStream); - } -} diff --git a/packages/grpc-js/src/call-interface.ts b/packages/grpc-js/src/call-interface.ts new file mode 100644 index 000000000..891170fec --- /dev/null +++ b/packages/grpc-js/src/call-interface.ts @@ -0,0 +1,169 @@ +/* + * 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. + * + */ + +import { CallCredentials } from "./call-credentials"; +import { Status } from "./constants"; +import { Deadline } from "./deadline"; +import { Metadata } from "./metadata"; +import { ServerSurfaceCall } from "./server-call"; + +export interface CallStreamOptions { + deadline: Deadline; + flags: number; + host: string; + parentCall: ServerSurfaceCall | null; +} + +export type PartialCallStreamOptions = Partial; + +export interface StatusObject { + code: Status; + details: string; + metadata: Metadata; +} + +export const enum WriteFlags { + BufferHint = 1, + NoCompress = 2, + WriteThrough = 4, +} + +export interface WriteObject { + message: Buffer; + flags?: number; +} + +export interface MetadataListener { + (metadata: Metadata, next: (metadata: Metadata) => void): void; +} + +export interface MessageListener { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (message: any, next: (message: any) => void): void; +} + +export interface StatusListener { + (status: StatusObject, next: (status: StatusObject) => void): void; +} + +export interface FullListener { + onReceiveMetadata: MetadataListener; + onReceiveMessage: MessageListener; + onReceiveStatus: StatusListener; +} + +export type Listener = Partial; + +/** + * An object with methods for handling the responses to a call. + */ +export interface InterceptingListener { + onReceiveMetadata(metadata: Metadata): void; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + onReceiveMessage(message: any): void; + onReceiveStatus(status: StatusObject): void; +} + +export function isInterceptingListener( + listener: Listener | InterceptingListener +): listener is InterceptingListener { + return ( + listener.onReceiveMetadata !== undefined && + listener.onReceiveMetadata.length === 1 + ); +} + +export class InterceptingListenerImpl implements InterceptingListener { + private processingMetadata = false; + private hasPendingMessage = false; + private pendingMessage: any; + private processingMessage = false; + private pendingStatus: StatusObject | null = null; + constructor( + private listener: FullListener, + private nextListener: InterceptingListener + ) {} + + private processPendingMessage() { + if (this.hasPendingMessage) { + this.nextListener.onReceiveMessage(this.pendingMessage); + this.pendingMessage = null; + this.hasPendingMessage = false; + } + } + + private processPendingStatus() { + if (this.pendingStatus) { + this.nextListener.onReceiveStatus(this.pendingStatus); + } + } + + onReceiveMetadata(metadata: Metadata): void { + this.processingMetadata = true; + this.listener.onReceiveMetadata(metadata, (metadata) => { + this.processingMetadata = false; + this.nextListener.onReceiveMetadata(metadata); + this.processPendingMessage(); + this.processPendingStatus(); + }); + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + onReceiveMessage(message: any): void { + /* If this listener processes messages asynchronously, the last message may + * be reordered with respect to the status */ + this.processingMessage = true; + this.listener.onReceiveMessage(message, (msg) => { + this.processingMessage = false; + if (this.processingMetadata) { + this.pendingMessage = msg; + this.hasPendingMessage = true; + } else { + this.nextListener.onReceiveMessage(msg); + this.processPendingStatus(); + } + }); + } + onReceiveStatus(status: StatusObject): void { + this.listener.onReceiveStatus(status, (processedStatus) => { + if (this.processingMetadata || this.processingMessage) { + this.pendingStatus = processedStatus; + } else { + this.nextListener.onReceiveStatus(processedStatus); + } + }); + } +} + +export interface WriteCallback { + (error?: Error | null): void; +} + +export interface MessageContext { + callback?: WriteCallback; + flags?: number; +} + +export interface Call { + cancelWithStatus(status: Status, details: string): void; + getPeer(): string; + start(metadata: Metadata, listener: InterceptingListener): void; + sendMessageWithContext(context: MessageContext, message: Buffer): void; + startRead(): void; + halfClose(): void; + getCallNumber(): number; + setCredentials(credentials: CallCredentials): void; +} \ No newline at end of file diff --git a/packages/grpc-js/src/call-number.ts b/packages/grpc-js/src/call-number.ts new file mode 100644 index 000000000..48d34fac5 --- /dev/null +++ b/packages/grpc-js/src/call-number.ts @@ -0,0 +1,22 @@ +/* + * 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. + * + */ + +let nextCallNumber = 0; + +export function getNextCallNumber() { + return nextCallNumber++; +} \ No newline at end of file diff --git a/packages/grpc-js/src/call-stream.ts b/packages/grpc-js/src/call-stream.ts deleted file mode 100644 index e8f312752..000000000 --- a/packages/grpc-js/src/call-stream.ts +++ /dev/null @@ -1,882 +0,0 @@ -/* - * Copyright 2019 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 * as http2 from 'http2'; -import * as os from 'os'; - -import { CallCredentials } from './call-credentials'; -import { Propagate, Status } from './constants'; -import { Filter, FilterFactory } from './filter'; -import { FilterStackFactory, FilterStack } from './filter-stack'; -import { Metadata } from './metadata'; -import { StreamDecoder } from './stream-decoder'; -import { ChannelImplementation } from './channel'; -import { SubchannelCallStatsTracker, Subchannel } from './subchannel'; -import * as logging from './logging'; -import { LogVerbosity } from './constants'; -import { ServerSurfaceCall } from './server-call'; - -const TRACER_NAME = 'call_stream'; - -const { - HTTP2_HEADER_STATUS, - HTTP2_HEADER_CONTENT_TYPE, - NGHTTP2_CANCEL, -} = http2.constants; - -/** - * https://nodejs.org/api/errors.html#errors_class_systemerror - */ -interface SystemError extends Error { - address?: string; - code: string; - dest?: string; - errno: number; - info?: object; - message: string; - path?: string; - port?: number; - syscall: string; -} - -/** - * Should do approximately the same thing as util.getSystemErrorName but the - * TypeScript types don't have that function for some reason so I just made my - * own. - * @param errno - */ -function getSystemErrorName(errno: number): string { - for (const [name, num] of Object.entries(os.constants.errno)) { - if (num === errno) { - return name; - } - } - return 'Unknown system error ' + errno; -} - -export type Deadline = Date | number; - -function getMinDeadline(deadlineList: Deadline[]): Deadline { - let minValue = Infinity; - for (const deadline of deadlineList) { - const deadlineMsecs = - deadline instanceof Date ? deadline.getTime() : deadline; - if (deadlineMsecs < minValue) { - minValue = deadlineMsecs; - } - } - return minValue; -} - -export interface CallStreamOptions { - deadline: Deadline; - flags: number; - host: string; - parentCall: ServerSurfaceCall | null; -} - -export type PartialCallStreamOptions = Partial; - -export interface StatusObject { - code: Status; - details: string; - metadata: Metadata; -} - -export const enum WriteFlags { - BufferHint = 1, - NoCompress = 2, - WriteThrough = 4, -} - -export interface WriteObject { - message: Buffer; - flags?: number; -} - -export interface MetadataListener { - (metadata: Metadata, next: (metadata: Metadata) => void): void; -} - -export interface MessageListener { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (message: any, next: (message: any) => void): void; -} - -export interface StatusListener { - (status: StatusObject, next: (status: StatusObject) => void): void; -} - -export interface FullListener { - onReceiveMetadata: MetadataListener; - onReceiveMessage: MessageListener; - onReceiveStatus: StatusListener; -} - -export type Listener = Partial; - -/** - * An object with methods for handling the responses to a call. - */ -export interface InterceptingListener { - onReceiveMetadata(metadata: Metadata): void; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - onReceiveMessage(message: any): void; - onReceiveStatus(status: StatusObject): void; -} - -export function isInterceptingListener( - listener: Listener | InterceptingListener -): listener is InterceptingListener { - return ( - listener.onReceiveMetadata !== undefined && - listener.onReceiveMetadata.length === 1 - ); -} - -export class InterceptingListenerImpl implements InterceptingListener { - private processingMetadata = false; - private hasPendingMessage = false; - private pendingMessage: any; - private processingMessage = false; - private pendingStatus: StatusObject | null = null; - constructor( - private listener: FullListener, - private nextListener: InterceptingListener - ) {} - - private processPendingMessage() { - if (this.hasPendingMessage) { - this.nextListener.onReceiveMessage(this.pendingMessage); - this.pendingMessage = null; - this.hasPendingMessage = false; - } - } - - private processPendingStatus() { - if (this.pendingStatus) { - this.nextListener.onReceiveStatus(this.pendingStatus); - } - } - - onReceiveMetadata(metadata: Metadata): void { - this.processingMetadata = true; - this.listener.onReceiveMetadata(metadata, (metadata) => { - this.processingMetadata = false; - this.nextListener.onReceiveMetadata(metadata); - this.processPendingMessage(); - this.processPendingStatus(); - }); - } - // eslint-disable-next-line @typescript-eslint/no-explicit-any - onReceiveMessage(message: any): void { - /* If this listener processes messages asynchronously, the last message may - * be reordered with respect to the status */ - this.processingMessage = true; - this.listener.onReceiveMessage(message, (msg) => { - this.processingMessage = false; - if (this.processingMetadata) { - this.pendingMessage = msg; - this.hasPendingMessage = true; - } else { - this.nextListener.onReceiveMessage(msg); - this.processPendingStatus(); - } - }); - } - onReceiveStatus(status: StatusObject): void { - this.listener.onReceiveStatus(status, (processedStatus) => { - if (this.processingMetadata || this.processingMessage) { - this.pendingStatus = processedStatus; - } else { - this.nextListener.onReceiveStatus(processedStatus); - } - }); - } -} - -export interface WriteCallback { - (error?: Error | null): void; -} - -export interface MessageContext { - callback?: WriteCallback; - flags?: number; -} - -export interface Call { - cancelWithStatus(status: Status, details: string): void; - getPeer(): string; - start(metadata: Metadata, listener: InterceptingListener): void; - sendMessageWithContext(context: MessageContext, message: Buffer): void; - startRead(): void; - halfClose(): void; - - getDeadline(): Deadline; - getCredentials(): CallCredentials; - setCredentials(credentials: CallCredentials): void; - getMethod(): string; - getHost(): string; -} - -export class Http2CallStream implements Call { - credentials: CallCredentials; - filterStack: FilterStack; - private http2Stream: http2.ClientHttp2Stream | null = null; - private pendingRead = false; - private isWriteFilterPending = false; - private pendingWrite: Buffer | null = null; - private pendingWriteCallback: WriteCallback | null = null; - private writesClosed = false; - - private decoder = new StreamDecoder(); - - private isReadFilterPending = false; - private canPush = false; - /** - * Indicates that an 'end' event has come from the http2 stream, so there - * will be no more data events. - */ - private readsClosed = false; - - private statusOutput = false; - - private unpushedReadMessages: Buffer[] = []; - private unfilteredReadMessages: Buffer[] = []; - - // Status code mapped from :status. To be used if grpc-status is not received - private mappedStatusCode: Status = Status.UNKNOWN; - - // This is populated (non-null) if and only if the call has ended - private finalStatus: StatusObject | null = null; - - private subchannel: Subchannel | null = null; - private disconnectListener: () => void; - - private listener: InterceptingListener | null = null; - - private internalError: SystemError | null = null; - - private configDeadline: Deadline = Infinity; - - private statusWatchers: ((status: StatusObject) => void)[] = []; - private streamEndWatchers: ((success: boolean) => void)[] = []; - - private callStatsTracker: SubchannelCallStatsTracker | null = null; - - constructor( - private readonly methodName: string, - private readonly channel: ChannelImplementation, - private readonly options: CallStreamOptions, - filterStackFactory: FilterStackFactory, - private readonly channelCallCredentials: CallCredentials, - private readonly callNumber: number - ) { - this.filterStack = filterStackFactory.createFilter(this); - this.credentials = channelCallCredentials; - this.disconnectListener = () => { - this.endCall({ - code: Status.UNAVAILABLE, - details: 'Connection dropped', - metadata: new Metadata(), - }); - }; - if ( - this.options.parentCall && - this.options.flags & Propagate.CANCELLATION - ) { - this.options.parentCall.on('cancelled', () => { - this.cancelWithStatus(Status.CANCELLED, 'Cancelled by parent call'); - }); - } - } - - private outputStatus() { - /* Precondition: this.finalStatus !== null */ - if (this.listener && !this.statusOutput) { - this.statusOutput = true; - const filteredStatus = this.filterStack.receiveTrailers( - this.finalStatus! - ); - this.trace( - 'ended with status: code=' + - filteredStatus.code + - ' details="' + - filteredStatus.details + - '"' - ); - this.statusWatchers.forEach(watcher => watcher(filteredStatus)); - /* We delay the actual action of bubbling up the status to insulate the - * cleanup code in this class from any errors that may be thrown in the - * upper layers as a result of bubbling up the status. In particular, - * if the status is not OK, the "error" event may be emitted - * synchronously at the top level, which will result in a thrown error if - * the user does not handle that event. */ - process.nextTick(() => { - this.listener?.onReceiveStatus(filteredStatus); - }); - if (this.subchannel) { - this.subchannel.callUnref(); - this.subchannel.removeDisconnectListener(this.disconnectListener); - } - } - } - - private trace(text: string): void { - logging.trace( - LogVerbosity.DEBUG, - TRACER_NAME, - '[' + this.callNumber + '] ' + text - ); - } - - /** - * On first call, emits a 'status' event with the given StatusObject. - * Subsequent calls are no-ops. - * @param status The status of the call. - */ - private endCall(status: StatusObject): void { - /* If the status is OK and a new status comes in (e.g. from a - * deserialization failure), that new status takes priority */ - if (this.finalStatus === null || this.finalStatus.code === Status.OK) { - this.finalStatus = status; - this.maybeOutputStatus(); - } - this.destroyHttp2Stream(); - } - - private maybeOutputStatus() { - if (this.finalStatus !== null) { - /* The combination check of readsClosed and that the two message buffer - * arrays are empty checks that there all incoming data has been fully - * processed */ - if ( - this.finalStatus.code !== Status.OK || - (this.readsClosed && - this.unpushedReadMessages.length === 0 && - this.unfilteredReadMessages.length === 0 && - !this.isReadFilterPending) - ) { - this.outputStatus(); - } - } - } - - private push(message: Buffer): void { - this.trace( - 'pushing to reader message of length ' + - (message instanceof Buffer ? message.length : null) - ); - this.canPush = false; - process.nextTick(() => { - /* If we have already output the status any later messages should be - * ignored, and can cause out-of-order operation errors higher up in the - * stack. Checking as late as possible here to avoid any race conditions. - */ - if (this.statusOutput) { - return; - } - this.listener?.onReceiveMessage(message); - this.maybeOutputStatus(); - }); - } - - private handleFilterError(error: Error) { - this.cancelWithStatus(Status.INTERNAL, error.message); - } - - private handleFilteredRead(message: Buffer) { - /* If we the call has already ended with an error, we don't want to do - * anything with this message. Dropping it on the floor is correct - * behavior */ - if (this.finalStatus !== null && this.finalStatus.code !== Status.OK) { - this.maybeOutputStatus(); - return; - } - this.isReadFilterPending = false; - if (this.canPush) { - this.http2Stream!.pause(); - this.push(message); - } else { - this.trace( - 'unpushedReadMessages.push message of length ' + message.length - ); - this.unpushedReadMessages.push(message); - } - if (this.unfilteredReadMessages.length > 0) { - /* nextMessage is guaranteed not to be undefined because - unfilteredReadMessages is non-empty */ - const nextMessage = this.unfilteredReadMessages.shift()!; - this.filterReceivedMessage(nextMessage); - } - } - - private filterReceivedMessage(framedMessage: Buffer) { - /* If we the call has already ended with an error, we don't want to do - * anything with this message. Dropping it on the floor is correct - * behavior */ - if (this.finalStatus !== null && this.finalStatus.code !== Status.OK) { - this.maybeOutputStatus(); - return; - } - this.trace('filterReceivedMessage of length ' + framedMessage.length); - this.isReadFilterPending = true; - this.filterStack - .receiveMessage(Promise.resolve(framedMessage)) - .then( - this.handleFilteredRead.bind(this), - this.handleFilterError.bind(this) - ); - } - - private tryPush(messageBytes: Buffer): void { - if (this.isReadFilterPending) { - this.trace( - 'unfilteredReadMessages.push message of length ' + - (messageBytes && messageBytes.length) - ); - this.unfilteredReadMessages.push(messageBytes); - } else { - this.filterReceivedMessage(messageBytes); - } - } - - private handleTrailers(headers: http2.IncomingHttpHeaders) { - this.streamEndWatchers.forEach(watcher => watcher(true)); - let headersString = ''; - for (const header of Object.keys(headers)) { - headersString += '\t\t' + header + ': ' + headers[header] + '\n'; - } - this.trace('Received server trailers:\n' + headersString); - let metadata: Metadata; - try { - metadata = Metadata.fromHttp2Headers(headers); - } catch (e) { - 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'); - } - metadata.remove('grpc-status'); - } - let details = ''; - if (typeof metadataMap['grpc-message'] === 'string') { - details = decodeURI(metadataMap['grpc-message']); - metadata.remove('grpc-message'); - this.trace( - 'received status details string "' + details + '" from server' - ); - } - const status: StatusObject = { code, details, metadata }; - // This is a no-op if the call was already ended when handling headers. - this.endCall(status); - } - - private writeMessageToStream(message: Buffer, callback: WriteCallback) { - this.callStatsTracker?.addMessageSent(); - this.http2Stream!.write(message, callback); - } - - attachHttp2Stream( - stream: http2.ClientHttp2Stream, - subchannel: Subchannel, - extraFilters: Filter[], - callStatsTracker: SubchannelCallStatsTracker - ): void { - this.filterStack.push(extraFilters); - if (this.finalStatus !== null) { - stream.close(NGHTTP2_CANCEL); - } else { - this.trace( - 'attachHttp2Stream from subchannel ' + subchannel.getAddress() - ); - this.http2Stream = stream; - this.subchannel = subchannel; - this.callStatsTracker = callStatsTracker; - subchannel.addDisconnectListener(this.disconnectListener); - subchannel.callRef(); - stream.on('response', (headers, flags) => { - let headersString = ''; - for (const header of Object.keys(headers)) { - 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; - } - - if (flags & http2.constants.NGHTTP2_FLAG_END_STREAM) { - this.handleTrailers(headers); - } else { - let metadata: Metadata; - try { - metadata = Metadata.fromHttp2Headers(headers); - } catch (error) { - this.endCall({ - code: Status.UNKNOWN, - details: error.message, - metadata: new Metadata(), - }); - return; - } - try { - const finalMetadata = this.filterStack.receiveMetadata(metadata); - this.listener?.onReceiveMetadata(finalMetadata); - } catch (error) { - this.endCall({ - code: Status.UNKNOWN, - details: error.message, - metadata: new Metadata(), - }); - } - } - }); - stream.on('trailers', this.handleTrailers.bind(this)); - stream.on('data', (data: Buffer) => { - this.trace('receive HTTP/2 data frame of length ' + data.length); - const messages = this.decoder.write(data); - - for (const message of messages) { - this.trace('parsed message of length ' + message.length); - this.callStatsTracker!.addMessageReceived(); - this.tryPush(message); - } - }); - stream.on('end', () => { - this.readsClosed = true; - this.maybeOutputStatus(); - }); - stream.on('close', () => { - /* 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. */ - process.nextTick(() => { - this.trace('HTTP/2 stream closed with code ' + stream.rstCode); - /* If we have a final status with an OK status code, that means that - * we have received all of the messages and we have processed the - * trailers and the call completed successfully, so it doesn't matter - * how the stream ends after that */ - if (this.finalStatus?.code === Status.OK) { - return; - } - let code: Status; - let details = ''; - switch (stream.rstCode) { - case http2.constants.NGHTTP2_NO_ERROR: - /* If we get a NO_ERROR code and we already have a status, the - * stream completed properly and we just haven't fully processed - * it yet */ - if (this.finalStatus !== null) { - return; - } - code = Status.INTERNAL; - details = `Received RST_STREAM with code ${stream.rstCode}`; - break; - case http2.constants.NGHTTP2_REFUSED_STREAM: - code = Status.UNAVAILABLE; - details = 'Stream refused by server'; - break; - case http2.constants.NGHTTP2_CANCEL: - code = Status.CANCELLED; - details = 'Call cancelled'; - break; - case http2.constants.NGHTTP2_ENHANCE_YOUR_CALM: - code = Status.RESOURCE_EXHAUSTED; - details = 'Bandwidth exhausted or memory limit exceeded'; - break; - case http2.constants.NGHTTP2_INADEQUATE_SECURITY: - code = Status.PERMISSION_DENIED; - details = 'Protocol not secure enough'; - break; - case http2.constants.NGHTTP2_INTERNAL_ERROR: - code = Status.INTERNAL; - if (this.internalError === null) { - /* This error code was previously handled in the default case, and - * there are several instances of it online, so I wanted to - * preserve the original error message so that people find existing - * information in searches, but also include the more recognizable - * "Internal server error" message. */ - details = `Received RST_STREAM with code ${stream.rstCode} (Internal server error)`; - } else { - if (this.internalError.code === 'ECONNRESET' || this.internalError.code === 'ETIMEDOUT') { - code = Status.UNAVAILABLE; - details = this.internalError.message; - } else { - /* The "Received RST_STREAM with code ..." error is preserved - * here for continuity with errors reported online, but the - * error message at the end will probably be more relevant in - * most cases. */ - details = `Received RST_STREAM with code ${stream.rstCode} triggered by internal client error: ${this.internalError.message}`; - } - } - break; - default: - code = Status.INTERNAL; - details = `Received RST_STREAM with code ${stream.rstCode}`; - } - // This is a no-op if trailers were received at all. - // This is OK, because status codes emitted here correspond to more - // catastrophic issues that prevent us from receiving trailers in the - // first place. - this.endCall({ code, details, metadata: new Metadata() }); - }); - }); - stream.on('error', (err: SystemError) => { - /* We need an error handler here to stop "Uncaught Error" exceptions - * from bubbling up. However, errors here should all correspond to - * "close" events, where we will handle the error more granularly */ - /* Specifically looking for stream errors that were *not* constructed - * from a RST_STREAM response here: - * https://github.com/nodejs/node/blob/8b8620d580314050175983402dfddf2674e8e22a/lib/internal/http2/core.js#L2267 - */ - if (err.code !== 'ERR_HTTP2_STREAM_ERROR') { - this.trace( - 'Node error event: message=' + - err.message + - ' code=' + - err.code + - ' errno=' + - getSystemErrorName(err.errno) + - ' syscall=' + - err.syscall - ); - this.internalError = err; - } - this.streamEndWatchers.forEach(watcher => watcher(false)); - }); - if (!this.pendingRead) { - stream.pause(); - } - if (this.pendingWrite) { - if (!this.pendingWriteCallback) { - throw new Error('Invalid state in write handling code'); - } - this.trace( - 'sending data chunk of length ' + - this.pendingWrite.length + - ' (deferred)' - ); - try { - this.writeMessageToStream(this.pendingWrite, this.pendingWriteCallback); - } catch (error) { - this.endCall({ - code: Status.UNAVAILABLE, - details: `Write failed with error ${error.message}`, - metadata: new Metadata() - }); - } - } - this.maybeCloseWrites(); - } - } - - start(metadata: Metadata, listener: InterceptingListener) { - this.trace('Sending metadata'); - this.listener = listener; - this.channel._startCallStream(this, metadata); - this.maybeOutputStatus(); - } - - private destroyHttp2Stream() { - // The http2 stream could already have been destroyed if cancelWithStatus - // is called in response to an internal http2 error. - if (this.http2Stream !== null && !this.http2Stream.destroyed) { - /* 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 */ - let code: number; - if (this.finalStatus?.code === Status.OK) { - code = http2.constants.NGHTTP2_NO_ERROR; - } else { - code = http2.constants.NGHTTP2_CANCEL; - } - this.trace('close http2 stream with code ' + code); - this.http2Stream.close(code); - } - } - - cancelWithStatus(status: Status, details: string): void { - this.trace( - 'cancelWithStatus code: ' + status + ' details: "' + details + '"' - ); - this.endCall({ code: status, details, metadata: new Metadata() }); - } - - getDeadline(): Deadline { - const deadlineList = [this.options.deadline]; - if (this.options.parentCall && this.options.flags & Propagate.DEADLINE) { - deadlineList.push(this.options.parentCall.getDeadline()); - } - if (this.configDeadline) { - deadlineList.push(this.configDeadline); - } - return getMinDeadline(deadlineList); - } - - getCredentials(): CallCredentials { - return this.credentials; - } - - setCredentials(credentials: CallCredentials): void { - this.credentials = this.channelCallCredentials.compose(credentials); - } - - getStatus(): StatusObject | null { - return this.finalStatus; - } - - getPeer(): string { - return this.subchannel?.getAddress() ?? this.channel.getTarget(); - } - - getMethod(): string { - return this.methodName; - } - - getHost(): string { - return this.options.host; - } - - setConfigDeadline(configDeadline: Deadline) { - this.configDeadline = configDeadline; - } - - addStatusWatcher(watcher: (status: StatusObject) => void) { - this.statusWatchers.push(watcher); - } - - addStreamEndWatcher(watcher: (success: boolean) => void) { - this.streamEndWatchers.push(watcher); - } - - addFilters(extraFilters: Filter[]) { - this.filterStack.push(extraFilters); - } - - getCallNumber() { - return this.callNumber; - } - - startRead() { - /* If the stream has ended with an error, we should not emit any more - * messages and we should communicate that the stream has ended */ - if (this.finalStatus !== null && this.finalStatus.code !== Status.OK) { - this.readsClosed = true; - this.maybeOutputStatus(); - return; - } - this.canPush = true; - if (this.http2Stream === null) { - this.pendingRead = true; - } else { - if (this.unpushedReadMessages.length > 0) { - const nextMessage: Buffer = this.unpushedReadMessages.shift()!; - this.push(nextMessage); - return; - } - /* Only resume reading from the http2Stream if we don't have any pending - * messages to emit */ - this.http2Stream.resume(); - } - } - - private maybeCloseWrites() { - if ( - this.writesClosed && - !this.isWriteFilterPending && - this.http2Stream !== null - ) { - this.trace('calling end() on HTTP/2 stream'); - this.http2Stream.end(); - } - } - - sendMessageWithContext(context: MessageContext, message: Buffer) { - this.trace('write() called with message of length ' + message.length); - const writeObj: WriteObject = { - message, - flags: context.flags, - }; - const cb: WriteCallback = (error?: Error | null) => { - let code: Status = Status.UNAVAILABLE; - if ((error as NodeJS.ErrnoException)?.code === 'ERR_STREAM_WRITE_AFTER_END') { - code = Status.INTERNAL; - } - if (error) { - this.cancelWithStatus(code, `Write error: ${error.message}`); - } - context.callback?.(); - }; - this.isWriteFilterPending = true; - this.filterStack.sendMessage(Promise.resolve(writeObj)).then((message) => { - this.isWriteFilterPending = false; - if (this.http2Stream === null) { - this.trace( - 'deferring writing data chunk of length ' + message.message.length - ); - this.pendingWrite = message.message; - this.pendingWriteCallback = cb; - } else { - this.trace('sending data chunk of length ' + message.message.length); - try { - this.writeMessageToStream(message.message, cb); - } catch (error) { - this.endCall({ - code: Status.UNAVAILABLE, - details: `Write failed with error ${error.message}`, - metadata: new Metadata() - }); - } - this.maybeCloseWrites(); - } - }, this.handleFilterError.bind(this)); - } - - halfClose() { - this.trace('end() called'); - this.writesClosed = true; - this.maybeCloseWrites(); - } -} diff --git a/packages/grpc-js/src/call.ts b/packages/grpc-js/src/call.ts index fcc3159db..c587a195d 100644 --- a/packages/grpc-js/src/call.ts +++ b/packages/grpc-js/src/call.ts @@ -18,7 +18,7 @@ import { EventEmitter } from 'events'; import { Duplex, Readable, Writable } from 'stream'; -import { StatusObject, MessageContext } from './call-stream'; +import { StatusObject, MessageContext } from './call-interface'; import { Status } from './constants'; import { EmitterAugmentation1 } from './events'; import { Metadata } from './metadata'; diff --git a/packages/grpc-js/src/channel.ts b/packages/grpc-js/src/channel.ts index 635b52d6f..aaf14bb22 100644 --- a/packages/grpc-js/src/channel.ts +++ b/packages/grpc-js/src/channel.ts @@ -15,57 +15,15 @@ * */ -import { - Deadline, - Call, - Http2CallStream, - CallStreamOptions, -} from './call-stream'; import { ChannelCredentials } from './channel-credentials'; 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, PickResultType } from './picker'; -import { Metadata } from './metadata'; -import { Status, LogVerbosity, Propagate } from './constants'; -import { FilterStackFactory } from './filter-stack'; -import { CallCredentialsFilterFactory } from './call-credentials-filter'; -import { DeadlineFilterFactory } from './deadline-filter'; -import { CompressionFilterFactory } from './compression-filter'; -import { - CallConfig, - ConfigSelector, - getDefaultAuthority, - mapUriDefaultScheme, -} from './resolver'; -import { trace, log } 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'; -import { Filter } from './filter'; import { ConnectivityState } from './connectivity-state'; -import { ChannelInfo, ChannelRef, ChannelzCallTracker, ChannelzChildrenTracker, ChannelzTrace, registerChannelzChannel, SubchannelRef, unregisterChannelzRef } from './channelz'; -import { Subchannel } from './subchannel'; - -/** - * See https://nodejs.org/api/timers.html#timers_setinterval_callback_delay_args - */ -const MAX_TIMEOUT_TIME = 2147483647; - -let nextCallNumber = 0; - -function getNewCallNumber(): number { - const callNumber = nextCallNumber; - nextCallNumber += 1; - if (nextCallNumber >= Number.MAX_SAFE_INTEGER) { - nextCallNumber = 0; - } - return callNumber; -} +import { ChannelRef } from './channelz'; +import { Call } from './call-interface'; +import { InternalChannel } from './internal-channel'; +import { Deadline } from './deadline'; /** * An interface that represents a communication channel to a server specified @@ -132,57 +90,14 @@ export interface Channel { ): Call; } -interface ConnectivityStateWatcher { - currentState: ConnectivityState; - timer: NodeJS.Timeout | null; - callback: (error?: Error) => void; -} - export class ChannelImplementation implements Channel { - private resolvingLoadBalancer: ResolvingLoadBalancer; - private subchannelPool: SubchannelPool; - private connectivityState: ConnectivityState = ConnectivityState.IDLE; - private currentPicker: Picker = new UnavailablePicker(); - /** - * Calls queued up to get a call config. Should only be populated before the - * first time the resolver returns a result, which includes the ConfigSelector. - */ - private configSelectionQueue: Array<{ - callStream: Http2CallStream; - callMetadata: Metadata; - }> = []; - private pickQueue: Array<{ - callStream: Http2CallStream; - callMetadata: Metadata; - callConfig: CallConfig; - dynamicFilters: Filter[]; - }> = []; - private connectivityStateWatchers: ConnectivityStateWatcher[] = []; - private defaultAuthority: string; - private filterStackFactory: FilterStackFactory; - private target: GrpcUri; - /** - * This timer does not do anything on its own. Its purpose is to hold the - * event loop open while there are any pending calls for the channel that - * have not yet been assigned to specific subchannels. In other words, - * the invariant is that callRefTimer is reffed if and only if pickQueue - * is non-empty. - */ - private callRefTimer: NodeJS.Timer; - private configSelector: ConfigSelector | null = null; - // Channelz info - private readonly channelzEnabled: boolean = true; - private originalTarget: string; - private channelzRef: ChannelRef; - private channelzTrace: ChannelzTrace; - private callTracker = new ChannelzCallTracker(); - private childrenTracker = new ChannelzChildrenTracker(); + private internalChannel: InternalChannel; constructor( target: string, - private readonly credentials: ChannelCredentials, - private readonly options: ChannelOptions + credentials: ChannelCredentials, + options: ChannelOptions ) { if (typeof target !== 'string') { throw new TypeError('Channel target must be a string'); @@ -197,497 +112,20 @@ export class ChannelImplementation implements Channel { throw new TypeError('Channel options must be an object'); } } - this.originalTarget = target; - const originalTargetUri = parseUri(target); - if (originalTargetUri === null) { - throw new Error(`Could not parse target name "${target}"`); - } - /* This ensures that the target has a scheme that is registered with the - * resolver */ - const defaultSchemeMapResult = mapUriDefaultScheme(originalTargetUri); - if (defaultSchemeMapResult === null) { - throw new Error( - `Could not find a default scheme for target name "${target}"` - ); - } - - this.callRefTimer = setInterval(() => {}, MAX_TIMEOUT_TIME); - this.callRefTimer.unref?.(); - - if (this.options['grpc.enable_channelz'] === 0) { - this.channelzEnabled = false; - } - - this.channelzTrace = new ChannelzTrace(); - if (this.channelzEnabled) { - this.channelzRef = registerChannelzChannel(target, () => this.getChannelzInfo()); - this.channelzTrace.addTrace('CT_INFO', 'Channel created'); - } else { - // Dummy channelz ref that will never be used - this.channelzRef = { - kind: 'channel', - id: -1, - name: '' - }; - } - - if (this.options['grpc.default_authority']) { - this.defaultAuthority = this.options['grpc.default_authority'] as string; - } else { - this.defaultAuthority = getDefaultAuthority(defaultSchemeMapResult); - } - const proxyMapResult = mapProxyName(defaultSchemeMapResult, options); - this.target = proxyMapResult.target; - this.options = Object.assign({}, this.options, proxyMapResult.extraOptions); - - /* The global boolean parameter to getSubchannelPool has the inverse meaning to what - * the grpc.use_local_subchannel_pool channel option means. */ - this.subchannelPool = getSubchannelPool( - (options['grpc.use_local_subchannel_pool'] ?? 0) === 0 - ); - const channelControlHelper: ChannelControlHelper = { - createSubchannel: ( - subchannelAddress: SubchannelAddress, - subchannelArgs: ChannelOptions - ) => { - const subchannel = this.subchannelPool.getOrCreateSubchannel( - this.target, - subchannelAddress, - Object.assign({}, this.options, subchannelArgs), - this.credentials - ); - if (this.channelzEnabled) { - this.channelzTrace.addTrace('CT_INFO', 'Created subchannel or used existing subchannel', subchannel.getChannelzRef()); - } - return subchannel; - }, - updateState: (connectivityState: ConnectivityState, picker: Picker) => { - this.currentPicker = picker; - const queueCopy = this.pickQueue.slice(); - this.pickQueue = []; - this.callRefTimerUnref(); - for (const { callStream, callMetadata, callConfig, dynamicFilters } of queueCopy) { - this.tryPick(callStream, callMetadata, callConfig, dynamicFilters); - } - this.updateState(connectivityState); - }, - requestReresolution: () => { - // This should never be called. - throw new Error( - 'Resolving load balancer should never call requestReresolution' - ); - }, - addChannelzChild: (child: ChannelRef | SubchannelRef) => { - if (this.channelzEnabled) { - this.childrenTracker.refChild(child); - } - }, - removeChannelzChild: (child: ChannelRef | SubchannelRef) => { - if (this.channelzEnabled) { - this.childrenTracker.unrefChild(child); - } - } - }; - this.resolvingLoadBalancer = new ResolvingLoadBalancer( - this.target, - channelControlHelper, - options, - (configSelector) => { - if (this.channelzEnabled) { - this.channelzTrace.addTrace('CT_INFO', 'Address resolution succeeded'); - } - this.configSelector = configSelector; - /* We process the queue asynchronously to ensure that the corresponding - * load balancer update has completed. */ - process.nextTick(() => { - const localQueue = this.configSelectionQueue; - this.configSelectionQueue = []; - this.callRefTimerUnref(); - for (const { callStream, callMetadata } of localQueue) { - this.tryGetConfig(callStream, callMetadata); - } - this.configSelectionQueue = []; - }); - }, - (status) => { - if (this.channelzEnabled) { - this.channelzTrace.addTrace('CT_WARNING', 'Address resolution failed with code ' + status.code + ' and details "' + status.details + '"'); - } - if (this.configSelectionQueue.length > 0) { - this.trace('Name resolution failed with calls queued for config selection'); - } - const localQueue = this.configSelectionQueue; - this.configSelectionQueue = []; - this.callRefTimerUnref(); - for (const { callStream, callMetadata } of localQueue) { - if (callMetadata.getOptions().waitForReady) { - this.callRefTimerRef(); - this.configSelectionQueue.push({ callStream, callMetadata }); - } else { - callStream.cancelWithStatus(status.code, status.details); - } - } - } - ); - this.filterStackFactory = new FilterStackFactory([ - new CallCredentialsFilterFactory(this), - new DeadlineFilterFactory(this), - new MaxMessageSizeFilterFactory(this.options), - new CompressionFilterFactory(this, this.options), - ]); - this.trace('Channel constructed with options ' + JSON.stringify(options, undefined, 2)); - const error = new Error(); - trace(LogVerbosity.DEBUG, 'channel_stacktrace', '(' + this.channelzRef.id + ') ' + 'Channel constructed \n' + error.stack?.substring(error.stack.indexOf('\n')+1)); - } - - private getChannelzInfo(): ChannelInfo { - return { - target: this.originalTarget, - state: this.connectivityState, - trace: this.channelzTrace, - callTracker: this.callTracker, - children: this.childrenTracker.getChildLists() - }; - } - - private trace(text: string, verbosityOverride?: LogVerbosity) { - trace(verbosityOverride ?? LogVerbosity.DEBUG, 'channel', '(' + this.channelzRef.id + ') ' + uriToString(this.target) + ' ' + text); - } - - private callRefTimerRef() { - // If the hasRef function does not exist, always run the code - if (!this.callRefTimer.hasRef?.()) { - this.trace( - 'callRefTimer.ref | configSelectionQueue.length=' + - this.configSelectionQueue.length + - ' pickQueue.length=' + - this.pickQueue.length - ); - this.callRefTimer.ref?.(); - } - } - - private callRefTimerUnref() { - // If the hasRef function does not exist, always run the code - if (!this.callRefTimer.hasRef || this.callRefTimer.hasRef()) { - this.trace( - 'callRefTimer.unref | configSelectionQueue.length=' + - this.configSelectionQueue.length + - ' pickQueue.length=' + - this.pickQueue.length - ); - this.callRefTimer.unref?.(); - } - } - - private pushPick( - callStream: Http2CallStream, - callMetadata: Metadata, - callConfig: CallConfig, - dynamicFilters: Filter[] - ) { - this.pickQueue.push({ callStream, callMetadata, callConfig, dynamicFilters }); - this.callRefTimerRef(); - } - - /** - * Check the picker output for the given call and corresponding metadata, - * and take any relevant actions. Should not be called while iterating - * over pickQueue. - * @param callStream - * @param callMetadata - */ - private tryPick( - callStream: Http2CallStream, - callMetadata: Metadata, - callConfig: CallConfig, - dynamicFilters: Filter[] - ) { - const pickResult = this.currentPicker.pick({ - metadata: callMetadata, - extraPickInfo: callConfig.pickInformation, - }); - const subchannelString = pickResult.subchannel ? - '(' + pickResult.subchannel.getChannelzRef().id + ') ' + pickResult.subchannel.getAddress() : - '' + pickResult.subchannel; - this.trace( - 'Pick result for call [' + - callStream.getCallNumber() + - ']: ' + - PickResultType[pickResult.pickResultType] + - ' subchannel: ' + - subchannelString + - ' status: ' + - pickResult.status?.code + - ' ' + - pickResult.status?.details - ); - switch (pickResult.pickResultType) { - case PickResultType.COMPLETE: - if (pickResult.subchannel === null) { - callStream.cancelWithStatus( - Status.UNAVAILABLE, - 'Request dropped by load balancing policy' - ); - // End the call with an error - } else { - /* If the subchannel is not in the READY state, that indicates a bug - * somewhere in the load balancer or picker. So, we log an error and - * queue the pick to be tried again later. */ - if ( - pickResult.subchannel!.getConnectivityState() !== - ConnectivityState.READY - ) { - log( - LogVerbosity.ERROR, - 'Error: COMPLETE pick result subchannel ' + - subchannelString + - ' has state ' + - ConnectivityState[pickResult.subchannel!.getConnectivityState()] - ); - this.pushPick(callStream, callMetadata, callConfig, dynamicFilters); - break; - } - /* We need to clone the callMetadata here because the transparent - * retry code in the promise resolution handler use the same - * callMetadata object, so it needs to stay unmodified */ - callStream.filterStack - .sendMetadata(Promise.resolve(callMetadata.clone())) - .then( - (finalMetadata) => { - const subchannelState: ConnectivityState = pickResult.subchannel!.getConnectivityState(); - if (subchannelState === ConnectivityState.READY) { - try { - const pickExtraFilters = pickResult.extraFilterFactories.map(factory => factory.createFilter(callStream)); - pickResult.subchannel?.getRealSubchannel().startCallStream( - finalMetadata, - callStream, - [...dynamicFilters, ...pickExtraFilters] - ); - /* If we reach this point, the call stream has started - * successfully */ - callConfig.onCommitted?.(); - pickResult.onCallStarted?.(); - } catch (error) { - const errorCode = (error as NodeJS.ErrnoException).code; - if (errorCode === 'ERR_HTTP2_GOAWAY_SESSION' || - errorCode === 'ERR_HTTP2_INVALID_SESSION' - ) { - /* An error here indicates that something went wrong with - * the picked subchannel's http2 stream right before we - * tried to start the stream. We are handling a promise - * result here, so this is asynchronous with respect to the - * original tryPick call, so calling it again is not - * recursive. We call tryPick immediately instead of - * queueing this pick again because handling the queue is - * triggered by state changes, and we want to immediately - * check if the state has already changed since the - * previous tryPick call. We do this instead of cancelling - * the stream because the correct behavior may be - * re-queueing instead, based on the logic in the rest of - * tryPick */ - this.trace( - 'Failed to start call on picked subchannel ' + - subchannelString + - ' with error ' + - (error as Error).message + - '. Retrying pick', - LogVerbosity.INFO - ); - this.tryPick(callStream, callMetadata, callConfig, dynamicFilters); - } else { - this.trace( - 'Failed to start call on picked subchanel ' + - subchannelString + - ' with error ' + - (error as Error).message + - '. Ending call', - LogVerbosity.INFO - ); - callStream.cancelWithStatus( - Status.INTERNAL, - `Failed to start HTTP/2 stream with error: ${ - (error as Error).message - }` - ); - } - } - } else { - /* The logic for doing this here is the same as in the catch - * block above */ - this.trace( - 'Picked subchannel ' + - subchannelString + - ' has state ' + - ConnectivityState[subchannelState] + - ' after metadata filters. Retrying pick', - LogVerbosity.INFO - ); - this.tryPick(callStream, callMetadata, callConfig, dynamicFilters); - } - }, - (error: Error & { code: number }) => { - // We assume the error code isn't 0 (Status.OK) - callStream.cancelWithStatus( - typeof error.code === 'number' ? error.code : Status.UNKNOWN, - `Getting metadata from plugin failed with error: ${error.message}` - ); - } - ); - } - break; - case PickResultType.QUEUE: - this.pushPick(callStream, callMetadata, callConfig, dynamicFilters); - break; - case PickResultType.TRANSIENT_FAILURE: - if (callMetadata.getOptions().waitForReady) { - this.pushPick(callStream, callMetadata, callConfig, dynamicFilters); - } else { - callStream.cancelWithStatus( - pickResult.status!.code, - pickResult.status!.details - ); - } - break; - case PickResultType.DROP: - callStream.cancelWithStatus( - pickResult.status!.code, - pickResult.status!.details - ); - break; - default: - throw new Error( - `Invalid state: unknown pickResultType ${pickResult.pickResultType}` - ); - } - } - - private removeConnectivityStateWatcher( - watcherObject: ConnectivityStateWatcher - ) { - const watcherIndex = this.connectivityStateWatchers.findIndex( - (value) => value === watcherObject - ); - if (watcherIndex >= 0) { - this.connectivityStateWatchers.splice(watcherIndex, 1); - } - } - - private updateState(newState: ConnectivityState): void { - trace( - LogVerbosity.DEBUG, - 'connectivity_state', - '(' + this.channelzRef.id + ') ' + - uriToString(this.target) + - ' ' + - ConnectivityState[this.connectivityState] + - ' -> ' + - ConnectivityState[newState] - ); - if (this.channelzEnabled) { - this.channelzTrace.addTrace('CT_INFO', ConnectivityState[this.connectivityState] + ' -> ' + ConnectivityState[newState]); - } - this.connectivityState = newState; - const watchersCopy = this.connectivityStateWatchers.slice(); - for (const watcherObject of watchersCopy) { - if (newState !== watcherObject.currentState) { - if (watcherObject.timer) { - clearTimeout(watcherObject.timer); - } - this.removeConnectivityStateWatcher(watcherObject); - watcherObject.callback(); - } - } - } - - private tryGetConfig(stream: Http2CallStream, metadata: Metadata) { - if (stream.getStatus() !== null) { - /* If the stream has a status, it has already finished and we don't need - * to take any more actions on it. */ - return; - } - if (this.configSelector === null) { - /* This branch will only be taken at the beginning of the channel's life, - * before the resolver ever returns a result. So, the - * ResolvingLoadBalancer may be idle and if so it needs to be kicked - * because it now has a pending request. */ - this.resolvingLoadBalancer.exitIdle(); - this.configSelectionQueue.push({ - callStream: stream, - callMetadata: metadata, - }); - this.callRefTimerRef(); - } else { - const callConfig = this.configSelector(stream.getMethod(), metadata); - if (callConfig.status === Status.OK) { - if (callConfig.methodConfig.timeout) { - const deadline = new Date(); - deadline.setSeconds( - deadline.getSeconds() + callConfig.methodConfig.timeout.seconds - ); - deadline.setMilliseconds( - deadline.getMilliseconds() + - callConfig.methodConfig.timeout.nanos / 1_000_000 - ); - stream.setConfigDeadline(deadline); - // Refreshing the filters makes the deadline filter pick up the new deadline - stream.filterStack.refresh(); - } - if (callConfig.dynamicFilterFactories.length > 0) { - /* These dynamicFilters are the mechanism for implementing gRFC A39: - * https://github.com/grpc/proposal/blob/master/A39-xds-http-filters.md - * We run them here instead of with the rest of the filters because - * that spec says "the xDS HTTP filters will run in between name - * resolution and load balancing". - * - * We use the filter stack here to simplify the multi-filter async - * waterfall logic, but we pass along the underlying list of filters - * to avoid having nested filter stacks when combining it with the - * original filter stack. We do not pass along the original filter - * factory list because these filters may need to persist data - * between sending headers and other operations. */ - const dynamicFilterStackFactory = new FilterStackFactory(callConfig.dynamicFilterFactories); - const dynamicFilterStack = dynamicFilterStackFactory.createFilter(stream); - dynamicFilterStack.sendMetadata(Promise.resolve(metadata)).then(filteredMetadata => { - this.tryPick(stream, filteredMetadata, callConfig, dynamicFilterStack.getFilters()); - }); - } else { - this.tryPick(stream, metadata, callConfig, []); - } - } else { - stream.cancelWithStatus( - callConfig.status, - 'Failed to route call to method ' + stream.getMethod() - ); - } - } - } - _startCallStream(stream: Http2CallStream, metadata: Metadata) { - this.tryGetConfig(stream, metadata.clone()); + this.internalChannel = new InternalChannel(target, credentials, options); } close() { - this.resolvingLoadBalancer.destroy(); - this.updateState(ConnectivityState.SHUTDOWN); - clearInterval(this.callRefTimer); - if (this.channelzEnabled) { - unregisterChannelzRef(this.channelzRef); - } - - this.subchannelPool.unrefUnusedSubchannels(); + this.internalChannel.close(); } getTarget() { - return uriToString(this.target); + return this.internalChannel.getTarget(); } getConnectivityState(tryToConnect: boolean) { - const connectivityState = this.connectivityState; - if (tryToConnect) { - this.resolvingLoadBalancer.exitIdle(); - } - return connectivityState; + return this.internalChannel.getConnectivityState(tryToConnect); } watchConnectivityState( @@ -695,34 +133,7 @@ export class ChannelImplementation implements Channel { deadline: Date | number, callback: (error?: Error) => void ): void { - if (this.connectivityState === ConnectivityState.SHUTDOWN) { - throw new Error('Channel has been shut down'); - } - let timer = null; - if (deadline !== Infinity) { - const deadlineDate: Date = - deadline instanceof Date ? deadline : new Date(deadline); - const now = new Date(); - if (deadline === -Infinity || deadlineDate <= now) { - process.nextTick( - callback, - new Error('Deadline passed without connectivity state change') - ); - return; - } - timer = setTimeout(() => { - this.removeConnectivityStateWatcher(watcherObject); - callback( - new Error('Deadline passed without connectivity state change') - ); - }, deadlineDate.getTime() - now.getTime()); - } - const watcherObject = { - currentState, - callback, - timer, - }; - this.connectivityStateWatchers.push(watcherObject); + this.internalChannel.watchConnectivityState(currentState, deadline, callback); } /** @@ -731,7 +142,7 @@ export class ChannelImplementation implements Channel { * @returns */ getChannelzRef() { - return this.channelzRef; + return this.internalChannel.getChannelzRef(); } createCall( @@ -749,42 +160,6 @@ export class ChannelImplementation implements Channel { 'Channel#createCall: deadline must be a number or Date' ); } - if (this.connectivityState === ConnectivityState.SHUTDOWN) { - throw new Error('Channel has been shut down'); - } - const callNumber = getNewCallNumber(); - this.trace( - 'createCall [' + - callNumber + - '] method="' + - method + - '", deadline=' + - deadline - ); - const finalOptions: CallStreamOptions = { - deadline: deadline, - flags: propagateFlags ?? Propagate.DEFAULTS, - host: host ?? this.defaultAuthority, - parentCall: parentCall, - }; - const stream: Http2CallStream = new Http2CallStream( - method, - this, - finalOptions, - this.filterStackFactory, - this.credentials._getCallCredentials(), - callNumber - ); - if (this.channelzEnabled) { - this.callTracker.addCallStarted(); - stream.addStatusWatcher(status => { - if (status.code === Status.OK) { - this.callTracker.addCallSucceeded(); - } else { - this.callTracker.addCallFailed(); - } - }); - } - return stream; + return this.internalChannel.createCall(method, deadline, host, parentCall, propagateFlags); } } diff --git a/packages/grpc-js/src/client-interceptors.ts b/packages/grpc-js/src/client-interceptors.ts index ddb296ff1..52320b0b3 100644 --- a/packages/grpc-js/src/client-interceptors.ts +++ b/packages/grpc-js/src/client-interceptors.ts @@ -28,7 +28,7 @@ import { isInterceptingListener, MessageContext, Call, -} from './call-stream'; +} from './call-interface'; import { Status } from './constants'; import { Channel } from './channel'; import { CallOptions } from './client'; diff --git a/packages/grpc-js/src/client.ts b/packages/grpc-js/src/client.ts index ed9407cd8..688d8016c 100644 --- a/packages/grpc-js/src/client.ts +++ b/packages/grpc-js/src/client.ts @@ -29,7 +29,7 @@ import { SurfaceCall, } from './call'; import { CallCredentials } from './call-credentials'; -import { Deadline, StatusObject } from './call-stream'; +import { StatusObject } from './call-interface'; import { Channel, ChannelImplementation } from './channel'; import { ConnectivityState } from './connectivity-state'; import { ChannelCredentials } from './channel-credentials'; @@ -50,6 +50,7 @@ import { ServerWritableStream, ServerDuplexStream, } from './server-call'; +import { Deadline } from './deadline'; const CHANNEL_SYMBOL = Symbol(); const INTERCEPTOR_SYMBOL = Symbol(); diff --git a/packages/grpc-js/src/compression-filter.ts b/packages/grpc-js/src/compression-filter.ts index 40825467e..f87614114 100644 --- a/packages/grpc-js/src/compression-filter.ts +++ b/packages/grpc-js/src/compression-filter.ts @@ -17,7 +17,7 @@ import * as zlib from 'zlib'; -import { Call, WriteObject, WriteFlags } from './call-stream'; +import { WriteObject, WriteFlags } from './call-interface'; import { Channel } from './channel'; import { ChannelOptions } from './channel-options'; import { CompressionAlgorithms } from './compression-algorithms'; @@ -283,7 +283,7 @@ export class CompressionFilterFactory implements FilterFactory { private sharedFilterConfig: SharedCompressionFilterConfig = {}; constructor(private readonly channel: Channel, private readonly options: ChannelOptions) {} - createFilter(callStream: Call): CompressionFilter { + createFilter(): CompressionFilter { return new CompressionFilter(this.options, this.sharedFilterConfig); } } diff --git a/packages/grpc-js/src/deadline-filter.ts b/packages/grpc-js/src/deadline-filter.ts deleted file mode 100644 index 7bdd764f2..000000000 --- a/packages/grpc-js/src/deadline-filter.ts +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2019 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 { Call, StatusObject } from './call-stream'; -import { Channel } from './channel'; -import { Status } from './constants'; -import { BaseFilter, Filter, FilterFactory } from './filter'; -import { Metadata } from './metadata'; - -const units: Array<[string, number]> = [ - ['m', 1], - ['S', 1000], - ['M', 60 * 1000], - ['H', 60 * 60 * 1000], -]; - -function getDeadline(deadline: number) { - const now = new Date().getTime(); - const timeoutMs = Math.max(deadline - now, 0); - for (const [unit, factor] of units) { - const amount = timeoutMs / factor; - if (amount < 1e8) { - return String(Math.ceil(amount)) + unit; - } - } - throw new Error('Deadline is too far in the future'); -} - -export class DeadlineFilter extends BaseFilter implements Filter { - private timer: NodeJS.Timer | null = null; - private deadline = Infinity; - constructor( - private readonly channel: Channel, - private readonly callStream: Call - ) { - super(); - this.retreiveDeadline(); - this.runTimer(); - } - - private retreiveDeadline() { - const callDeadline = this.callStream.getDeadline(); - if (callDeadline instanceof Date) { - this.deadline = callDeadline.getTime(); - } else { - this.deadline = callDeadline; - } - } - - private runTimer() { - if (this.timer) { - clearTimeout(this.timer); - } - const now: number = new Date().getTime(); - const timeout = this.deadline - now; - if (timeout <= 0) { - process.nextTick(() => { - this.callStream.cancelWithStatus( - Status.DEADLINE_EXCEEDED, - 'Deadline exceeded' - ); - }); - } else if (this.deadline !== Infinity) { - this.timer = setTimeout(() => { - this.callStream.cancelWithStatus( - Status.DEADLINE_EXCEEDED, - 'Deadline exceeded' - ); - }, timeout); - this.timer.unref?.(); - } - } - - refresh() { - this.retreiveDeadline(); - this.runTimer(); - } - - async sendMetadata(metadata: Promise) { - if (this.deadline === Infinity) { - return metadata; - } - /* The input metadata promise depends on the original channel.connect() - * promise, so when it is complete that implies that the channel is - * connected */ - const finalMetadata = await metadata; - const timeoutString = getDeadline(this.deadline); - finalMetadata.set('grpc-timeout', timeoutString); - return finalMetadata; - } - - receiveTrailers(status: StatusObject) { - if (this.timer) { - clearTimeout(this.timer); - } - return status; - } -} - -export class DeadlineFilterFactory implements FilterFactory { - constructor(private readonly channel: Channel) {} - - createFilter(callStream: Call): DeadlineFilter { - return new DeadlineFilter(this.channel, callStream); - } -} diff --git a/packages/grpc-js/src/deadline.ts b/packages/grpc-js/src/deadline.ts new file mode 100644 index 000000000..58ea0a805 --- /dev/null +++ b/packages/grpc-js/src/deadline.ts @@ -0,0 +1,58 @@ +/* + * Copyright 2019 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. + * + */ + +export type Deadline = Date | number; + +export function minDeadline(...deadlineList: Deadline[]): Deadline { + let minValue = Infinity; + for (const deadline of deadlineList) { + const deadlineMsecs = + deadline instanceof Date ? deadline.getTime() : deadline; + if (deadlineMsecs < minValue) { + minValue = deadlineMsecs; + } + } + return minValue; +} + +const units: Array<[string, number]> = [ + ['m', 1], + ['S', 1000], + ['M', 60 * 1000], + ['H', 60 * 60 * 1000], +]; + +export function getDeadlineTimeoutString(deadline: Deadline) { + const now = new Date().getTime(); + if (deadline instanceof Date) { + deadline = deadline.getTime(); + } + const timeoutMs = Math.max(deadline - now, 0); + for (const [unit, factor] of units) { + const amount = timeoutMs / factor; + if (amount < 1e8) { + return String(Math.ceil(amount)) + unit; + } + } + throw new Error('Deadline is too far in the future') +} + +export function getRelativeTimeout(deadline: Deadline) { + const deadlineMs = deadline instanceof Date ? deadline.getTime() : deadline; + const now = new Date().getTime(); + return deadlineMs - now; +} \ No newline at end of file diff --git a/packages/grpc-js/src/experimental.ts b/packages/grpc-js/src/experimental.ts index fcafbeb01..f286bbcd6 100644 --- a/packages/grpc-js/src/experimental.ts +++ b/packages/grpc-js/src/experimental.ts @@ -31,7 +31,7 @@ export { PickArgs, PickResultType, } from './picker'; -export { Call as CallStream } from './call-stream'; +export { Call as CallStream } from './call-interface'; export { Filter, BaseFilter, FilterFactory } from './filter'; export { FilterStackFactory } from './filter-stack'; export { registerAdminService } from './admin'; diff --git a/packages/grpc-js/src/filter-stack.ts b/packages/grpc-js/src/filter-stack.ts index a9e754428..f44c43839 100644 --- a/packages/grpc-js/src/filter-stack.ts +++ b/packages/grpc-js/src/filter-stack.ts @@ -15,14 +15,14 @@ * */ -import { Call, StatusObject, WriteObject } from './call-stream'; +import { StatusObject, WriteObject } from './call-interface'; import { Filter, FilterFactory } from './filter'; import { Metadata } from './metadata'; export class FilterStack implements Filter { constructor(private readonly filters: Filter[]) {} - sendMetadata(metadata: Promise) { + sendMetadata(metadata: Promise): Promise { let result: Promise = metadata; for (let i = 0; i < this.filters.length; i++) { @@ -72,12 +72,6 @@ export class FilterStack implements Filter { return result; } - refresh(): void { - for (const filter of this.filters) { - filter.refresh(); - } - } - push(filters: Filter[]) { this.filters.unshift(...filters); } @@ -94,9 +88,9 @@ export class FilterStackFactory implements FilterFactory { this.factories.unshift(...filterFactories); } - createFilter(callStream: Call): FilterStack { + createFilter(): FilterStack { return new FilterStack( - this.factories.map((factory) => factory.createFilter(callStream)) + this.factories.map((factory) => factory.createFilter()) ); } } diff --git a/packages/grpc-js/src/filter.ts b/packages/grpc-js/src/filter.ts index 8475a0a5a..5313f91a8 100644 --- a/packages/grpc-js/src/filter.ts +++ b/packages/grpc-js/src/filter.ts @@ -15,12 +15,14 @@ * */ -import { Call, StatusObject, WriteObject } from './call-stream'; +import { StatusObject, WriteObject } from './call-interface'; import { Metadata } from './metadata'; /** * Filter classes represent related per-call logic and state that is primarily - * used to modify incoming and outgoing data + * used to modify incoming and outgoing data. All async filters can be + * rejected. The rejection error must be a StatusObject, and a rejection will + * cause the call to end with that status. */ export interface Filter { sendMetadata(metadata: Promise): Promise; @@ -32,8 +34,6 @@ export interface Filter { receiveMessage(message: Promise): Promise; receiveTrailers(status: StatusObject): StatusObject; - - refresh(): void; } export abstract class BaseFilter implements Filter { @@ -56,10 +56,8 @@ export abstract class BaseFilter implements Filter { receiveTrailers(status: StatusObject): StatusObject { return status; } - - refresh(): void {} } export interface FilterFactory { - createFilter(callStream: Call): T; + createFilter(): T; } diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index b4855fb59..786fa9925 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -23,7 +23,7 @@ import { ServiceError, } from './call'; import { CallCredentials, OAuth2Client } from './call-credentials'; -import { Deadline, StatusObject } from './call-stream'; +import { StatusObject } from './call-interface'; import { Channel, ChannelImplementation } from './channel'; import { CompressionAlgorithms } from './compression-algorithms'; import { ConnectivityState } from './connectivity-state'; @@ -237,7 +237,7 @@ export const getClientChannel = (client: Client) => { export { StatusBuilder }; -export { Listener } from './call-stream'; +export { Listener } from './call-interface'; export { Requester, @@ -275,6 +275,7 @@ import * as load_balancer_pick_first from './load-balancer-pick-first'; import * as load_balancer_round_robin from './load-balancer-round-robin'; import * as load_balancer_outlier_detection from './load-balancer-outlier-detection'; import * as channelz from './channelz'; +import { Deadline } from './deadline'; const clientVersion = require('../../package.json').version; diff --git a/packages/grpc-js/src/internal-channel.ts b/packages/grpc-js/src/internal-channel.ts new file mode 100644 index 000000000..772ed8e1d --- /dev/null +++ b/packages/grpc-js/src/internal-channel.ts @@ -0,0 +1,504 @@ +/* + * Copyright 2019 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 { ChannelCredentials } from './channel-credentials'; +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, PickResultType } from './picker'; +import { Metadata } from './metadata'; +import { Status, LogVerbosity, Propagate } from './constants'; +import { FilterStackFactory } from './filter-stack'; +import { CompressionFilterFactory } from './compression-filter'; +import { + CallConfig, + ConfigSelector, + getDefaultAuthority, + mapUriDefaultScheme, +} from './resolver'; +import { trace, log } from './logging'; +import { SubchannelAddress } from './subchannel-address'; +import { MaxMessageSizeFilterFactory } from './max-message-size-filter'; +import { mapProxyName } from './http_proxy'; +import { GrpcUri, parseUri, splitHostPort, uriToString } from './uri-parser'; +import { ServerSurfaceCall } from './server-call'; +import { Filter } from './filter'; + +import { ConnectivityState } from './connectivity-state'; +import { ChannelInfo, ChannelRef, ChannelzCallTracker, ChannelzChildrenTracker, ChannelzTrace, registerChannelzChannel, SubchannelRef, unregisterChannelzRef } from './channelz'; +import { Subchannel } from './subchannel'; +import { LoadBalancingCall } from './load-balancing-call'; +import { CallCredentials } from './call-credentials'; +import { Call, CallStreamOptions, InterceptingListener, MessageContext, StatusObject } from './call-interface'; +import { SubchannelCall } from './subchannel-call'; +import { Deadline, getDeadlineTimeoutString } from './deadline'; +import { ResolvingCall } from './resolving-call'; +import { getNextCallNumber } from './call-number'; + +/** + * See https://nodejs.org/api/timers.html#timers_setinterval_callback_delay_args + */ +const MAX_TIMEOUT_TIME = 2147483647; + +interface ConnectivityStateWatcher { + currentState: ConnectivityState; + timer: NodeJS.Timeout | null; + callback: (error?: Error) => void; +} + +export class InternalChannel { + + private resolvingLoadBalancer: ResolvingLoadBalancer; + private subchannelPool: SubchannelPool; + private connectivityState: ConnectivityState = ConnectivityState.IDLE; + private currentPicker: Picker = new UnavailablePicker(); + /** + * Calls queued up to get a call config. Should only be populated before the + * first time the resolver returns a result, which includes the ConfigSelector. + */ + private configSelectionQueue: ResolvingCall[] = []; + private pickQueue: LoadBalancingCall[] = []; + private connectivityStateWatchers: ConnectivityStateWatcher[] = []; + private defaultAuthority: string; + private filterStackFactory: FilterStackFactory; + private target: GrpcUri; + /** + * This timer does not do anything on its own. Its purpose is to hold the + * event loop open while there are any pending calls for the channel that + * have not yet been assigned to specific subchannels. In other words, + * the invariant is that callRefTimer is reffed if and only if pickQueue + * is non-empty. + */ + private callRefTimer: NodeJS.Timer; + private configSelector: ConfigSelector | null = null; + + // Channelz info + private readonly channelzEnabled: boolean = true; + private originalTarget: string; + private channelzRef: ChannelRef; + private channelzTrace: ChannelzTrace; + private callTracker = new ChannelzCallTracker(); + private childrenTracker = new ChannelzChildrenTracker(); + + constructor( + target: string, + private readonly credentials: ChannelCredentials, + private readonly options: ChannelOptions + ) { + if (typeof target !== 'string') { + throw new TypeError('Channel target must be a string'); + } + if (!(credentials instanceof ChannelCredentials)) { + throw new TypeError( + 'Channel credentials must be a ChannelCredentials object' + ); + } + if (options) { + if (typeof options !== 'object') { + throw new TypeError('Channel options must be an object'); + } + } + this.originalTarget = target; + const originalTargetUri = parseUri(target); + if (originalTargetUri === null) { + throw new Error(`Could not parse target name "${target}"`); + } + /* This ensures that the target has a scheme that is registered with the + * resolver */ + const defaultSchemeMapResult = mapUriDefaultScheme(originalTargetUri); + if (defaultSchemeMapResult === null) { + throw new Error( + `Could not find a default scheme for target name "${target}"` + ); + } + + this.callRefTimer = setInterval(() => {}, MAX_TIMEOUT_TIME); + this.callRefTimer.unref?.(); + + if (this.options['grpc.enable_channelz'] === 0) { + this.channelzEnabled = false; + } + + this.channelzTrace = new ChannelzTrace(); + if (this.channelzEnabled) { + this.channelzRef = registerChannelzChannel(target, () => this.getChannelzInfo()); + this.channelzTrace.addTrace('CT_INFO', 'Channel created'); + } else { + // Dummy channelz ref that will never be used + this.channelzRef = { + kind: 'channel', + id: -1, + name: '' + }; + } + + if (this.options['grpc.default_authority']) { + this.defaultAuthority = this.options['grpc.default_authority'] as string; + } else { + this.defaultAuthority = getDefaultAuthority(defaultSchemeMapResult); + } + const proxyMapResult = mapProxyName(defaultSchemeMapResult, options); + this.target = proxyMapResult.target; + this.options = Object.assign({}, this.options, proxyMapResult.extraOptions); + + /* The global boolean parameter to getSubchannelPool has the inverse meaning to what + * the grpc.use_local_subchannel_pool channel option means. */ + this.subchannelPool = getSubchannelPool( + (options['grpc.use_local_subchannel_pool'] ?? 0) === 0 + ); + const channelControlHelper: ChannelControlHelper = { + createSubchannel: ( + subchannelAddress: SubchannelAddress, + subchannelArgs: ChannelOptions + ) => { + const subchannel = this.subchannelPool.getOrCreateSubchannel( + this.target, + subchannelAddress, + Object.assign({}, this.options, subchannelArgs), + this.credentials + ); + if (this.channelzEnabled) { + this.channelzTrace.addTrace('CT_INFO', 'Created subchannel or used existing subchannel', subchannel.getChannelzRef()); + } + return subchannel; + }, + updateState: (connectivityState: ConnectivityState, picker: Picker) => { + this.currentPicker = picker; + const queueCopy = this.pickQueue.slice(); + this.pickQueue = []; + this.callRefTimerUnref(); + for (const call of queueCopy) { + call.doPick(); + } + this.updateState(connectivityState); + }, + requestReresolution: () => { + // This should never be called. + throw new Error( + 'Resolving load balancer should never call requestReresolution' + ); + }, + addChannelzChild: (child: ChannelRef | SubchannelRef) => { + if (this.channelzEnabled) { + this.childrenTracker.refChild(child); + } + }, + removeChannelzChild: (child: ChannelRef | SubchannelRef) => { + if (this.channelzEnabled) { + this.childrenTracker.unrefChild(child); + } + } + }; + this.resolvingLoadBalancer = new ResolvingLoadBalancer( + this.target, + channelControlHelper, + options, + (configSelector) => { + if (this.channelzEnabled) { + this.channelzTrace.addTrace('CT_INFO', 'Address resolution succeeded'); + } + this.configSelector = configSelector; + /* We process the queue asynchronously to ensure that the corresponding + * load balancer update has completed. */ + process.nextTick(() => { + const localQueue = this.configSelectionQueue; + this.configSelectionQueue = []; + this.callRefTimerUnref(); + for (const call of localQueue) { + call.getConfig(); + } + this.configSelectionQueue = []; + }); + }, + (status) => { + if (this.channelzEnabled) { + this.channelzTrace.addTrace('CT_WARNING', 'Address resolution failed with code ' + status.code + ' and details "' + status.details + '"'); + } + if (this.configSelectionQueue.length > 0) { + this.trace('Name resolution failed with calls queued for config selection'); + } + const localQueue = this.configSelectionQueue; + this.configSelectionQueue = []; + this.callRefTimerUnref(); + for (const call of localQueue) { + call.reportResolverError(status); + } + } + ); + this.filterStackFactory = new FilterStackFactory([ + new MaxMessageSizeFilterFactory(this.options), + new CompressionFilterFactory(this, this.options), + ]); + this.trace('Channel constructed with options ' + JSON.stringify(options, undefined, 2)); + const error = new Error(); + trace(LogVerbosity.DEBUG, 'channel_stacktrace', '(' + this.channelzRef.id + ') ' + 'Channel constructed \n' + error.stack?.substring(error.stack.indexOf('\n')+1)); + } + + private getChannelzInfo(): ChannelInfo { + return { + target: this.originalTarget, + state: this.connectivityState, + trace: this.channelzTrace, + callTracker: this.callTracker, + children: this.childrenTracker.getChildLists() + }; + } + + private trace(text: string, verbosityOverride?: LogVerbosity) { + trace(verbosityOverride ?? LogVerbosity.DEBUG, 'channel', '(' + this.channelzRef.id + ') ' + uriToString(this.target) + ' ' + text); + } + + private callRefTimerRef() { + // If the hasRef function does not exist, always run the code + if (!this.callRefTimer.hasRef?.()) { + this.trace( + 'callRefTimer.ref | configSelectionQueue.length=' + + this.configSelectionQueue.length + + ' pickQueue.length=' + + this.pickQueue.length + ); + this.callRefTimer.ref?.(); + } + } + + private callRefTimerUnref() { + // If the hasRef function does not exist, always run the code + if (!this.callRefTimer.hasRef || this.callRefTimer.hasRef()) { + this.trace( + 'callRefTimer.unref | configSelectionQueue.length=' + + this.configSelectionQueue.length + + ' pickQueue.length=' + + this.pickQueue.length + ); + this.callRefTimer.unref?.(); + } + } + + private removeConnectivityStateWatcher( + watcherObject: ConnectivityStateWatcher + ) { + const watcherIndex = this.connectivityStateWatchers.findIndex( + (value) => value === watcherObject + ); + if (watcherIndex >= 0) { + this.connectivityStateWatchers.splice(watcherIndex, 1); + } + } + + private updateState(newState: ConnectivityState): void { + trace( + LogVerbosity.DEBUG, + 'connectivity_state', + '(' + this.channelzRef.id + ') ' + + uriToString(this.target) + + ' ' + + ConnectivityState[this.connectivityState] + + ' -> ' + + ConnectivityState[newState] + ); + if (this.channelzEnabled) { + this.channelzTrace.addTrace('CT_INFO', ConnectivityState[this.connectivityState] + ' -> ' + ConnectivityState[newState]); + } + this.connectivityState = newState; + const watchersCopy = this.connectivityStateWatchers.slice(); + for (const watcherObject of watchersCopy) { + if (newState !== watcherObject.currentState) { + if (watcherObject.timer) { + clearTimeout(watcherObject.timer); + } + this.removeConnectivityStateWatcher(watcherObject); + watcherObject.callback(); + } + } + } + + doPick(metadata: Metadata, extraPickInfo: {[key: string]: string}) { + return this.currentPicker.pick({metadata: metadata, extraPickInfo: extraPickInfo}); + } + + queueCallForPick(call: LoadBalancingCall) { + this.pickQueue.push(call); + this.callRefTimerRef(); + } + + getConfig(method: string, metadata: Metadata) { + this.resolvingLoadBalancer.exitIdle(); + return this.configSelector?.(method, metadata) ?? null; + } + + queueCallForConfig(call: ResolvingCall) { + this.configSelectionQueue.push(call); + this.callRefTimerRef(); + } + + createLoadBalancingCall( + callConfig: CallConfig, + method: string, + host: string, + credentials: CallCredentials, + deadline: Deadline + ): LoadBalancingCall { + const callNumber = getNextCallNumber(); + this.trace( + 'createLoadBalancingCall [' + + callNumber + + '] method="' + + method + + '"' + ); + return new LoadBalancingCall(this, callConfig, method, host, credentials, deadline, this.filterStackFactory, callNumber); + } + + createInnerCall( + callConfig: CallConfig, + method: string, + host: string, + credentials: CallCredentials, + deadline: Deadline + ): Call { + // Create a RetryingCall if retries are enabled + return this.createLoadBalancingCall(callConfig, method, host, credentials, deadline); + } + + createResolvingCall( + method: string, + deadline: Deadline, + host: string | null | undefined, + parentCall: ServerSurfaceCall | null, + propagateFlags: number | null | undefined + ): ResolvingCall { + const callNumber = getNextCallNumber(); + this.trace( + 'createResolvingCall [' + + callNumber + + '] method="' + + method + + '", deadline=' + + deadline + ); + const finalOptions: CallStreamOptions = { + deadline: deadline, + flags: propagateFlags ?? Propagate.DEFAULTS, + host: host ?? this.defaultAuthority, + parentCall: parentCall, + }; + + const call = new ResolvingCall(this, method, finalOptions, this.filterStackFactory, this.credentials._getCallCredentials(), getNextCallNumber()); + + if (this.channelzEnabled) { + this.callTracker.addCallStarted(); + call.addStatusWatcher(status => { + if (status.code === Status.OK) { + this.callTracker.addCallSucceeded(); + } else { + this.callTracker.addCallFailed(); + } + }); + } + return call; + + } + + close() { + this.resolvingLoadBalancer.destroy(); + this.updateState(ConnectivityState.SHUTDOWN); + clearInterval(this.callRefTimer); + if (this.channelzEnabled) { + unregisterChannelzRef(this.channelzRef); + } + + this.subchannelPool.unrefUnusedSubchannels(); + } + + getTarget() { + return uriToString(this.target); + } + + getConnectivityState(tryToConnect: boolean) { + const connectivityState = this.connectivityState; + if (tryToConnect) { + this.resolvingLoadBalancer.exitIdle(); + } + return connectivityState; + } + + watchConnectivityState( + currentState: ConnectivityState, + deadline: Date | number, + callback: (error?: Error) => void + ): void { + if (this.connectivityState === ConnectivityState.SHUTDOWN) { + throw new Error('Channel has been shut down'); + } + let timer = null; + if (deadline !== Infinity) { + const deadlineDate: Date = + deadline instanceof Date ? deadline : new Date(deadline); + const now = new Date(); + if (deadline === -Infinity || deadlineDate <= now) { + process.nextTick( + callback, + new Error('Deadline passed without connectivity state change') + ); + return; + } + timer = setTimeout(() => { + this.removeConnectivityStateWatcher(watcherObject); + callback( + new Error('Deadline passed without connectivity state change') + ); + }, deadlineDate.getTime() - now.getTime()); + } + const watcherObject = { + currentState, + callback, + timer, + }; + this.connectivityStateWatchers.push(watcherObject); + } + + /** + * Get the channelz reference object for this channel. The returned value is + * garbage if channelz is disabled for this channel. + * @returns + */ + getChannelzRef() { + return this.channelzRef; + } + + createCall( + method: string, + deadline: Deadline, + host: string | null | undefined, + parentCall: ServerSurfaceCall | null, + propagateFlags: number | null | undefined + ): Call { + if (typeof method !== 'string') { + throw new TypeError('Channel#createCall: method must be a string'); + } + if (!(typeof deadline === 'number' || deadline instanceof Date)) { + throw new TypeError( + 'Channel#createCall: deadline must be a number or Date' + ); + } + if (this.connectivityState === ConnectivityState.SHUTDOWN) { + throw new Error('Channel has been shut down'); + } + return this.createResolvingCall(method, deadline, host, parentCall, propagateFlags); + } +} diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index e69e2ef99..5af0e79e7 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -15,8 +15,7 @@ * */ -import { ChannelOptions, connectivityState, StatusObject } from "."; -import { Call } from "./call-stream"; +import { ChannelOptions } from "./channel-options"; import { ConnectivityState } from "./connectivity-state"; import { Status } from "./constants"; import { durationToMs, isDuration, msToDuration } from "./duration"; @@ -311,28 +310,6 @@ interface MapEntry { subchannelWrappers: OutlierDetectionSubchannelWrapper[]; } -class OutlierDetectionCounterFilter extends BaseFilter implements Filter { - constructor(private callCounter: CallCounter) { - super(); - } - receiveTrailers(status: StatusObject): StatusObject { - if (status.code === Status.OK) { - this.callCounter.addSuccess(); - } else { - this.callCounter.addFailure(); - } - return status; - } -} - -class OutlierDetectionCounterFilterFactory implements FilterFactory { - constructor(private callCounter: CallCounter) {} - createFilter(callStream: Call): OutlierDetectionCounterFilter { - return new OutlierDetectionCounterFilter(this.callCounter); - } - -} - class OutlierDetectionPicker implements Picker { constructor(private wrappedPicker: Picker) {} pick(pickArgs: PickArgs): PickResult { @@ -344,7 +321,14 @@ class OutlierDetectionPicker implements Picker { return { ...wrappedPick, subchannel: subchannelWrapper.getWrappedSubchannel(), - extraFilterFactories: [...wrappedPick.extraFilterFactories, new OutlierDetectionCounterFilterFactory(mapEntry.counter)] + onCallEnded: statusCode => { + if (statusCode === Status.OK) { + mapEntry.counter.addSuccess(); + } else { + mapEntry.counter.addFailure(); + } + wrappedPick.onCallEnded?.(statusCode); + } }; } else { return wrappedPick; diff --git a/packages/grpc-js/src/load-balancer-pick-first.ts b/packages/grpc-js/src/load-balancer-pick-first.ts index 884af50b7..bb95aba13 100644 --- a/packages/grpc-js/src/load-balancer-pick-first.ts +++ b/packages/grpc-js/src/load-balancer-pick-first.ts @@ -84,8 +84,8 @@ class PickFirstPicker implements Picker { pickResultType: PickResultType.COMPLETE, subchannel: this.subchannel, status: null, - extraFilterFactories: [], onCallStarted: null, + onCallEnded: null }; } } diff --git a/packages/grpc-js/src/load-balancer-round-robin.ts b/packages/grpc-js/src/load-balancer-round-robin.ts index 8a4094a02..91c10b238 100644 --- a/packages/grpc-js/src/load-balancer-round-robin.ts +++ b/packages/grpc-js/src/load-balancer-round-robin.ts @@ -78,8 +78,8 @@ class RoundRobinPicker implements Picker { pickResultType: PickResultType.COMPLETE, subchannel: pickedSubchannel, status: null, - extraFilterFactories: [], onCallStarted: null, + onCallEnded: null }; } diff --git a/packages/grpc-js/src/load-balancing-call.ts b/packages/grpc-js/src/load-balancing-call.ts new file mode 100644 index 000000000..f791b86bc --- /dev/null +++ b/packages/grpc-js/src/load-balancing-call.ts @@ -0,0 +1,281 @@ +/* + * 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. + * + */ + +import { CallCredentials } from "./call-credentials"; +import { Call, InterceptingListener, MessageContext, StatusObject } from "./call-interface"; +import { SubchannelCall } from "./subchannel-call"; +import { ConnectivityState } from "./connectivity-state"; +import { LogVerbosity, Status } from "./constants"; +import { Deadline, getDeadlineTimeoutString } from "./deadline"; +import { FilterStack, FilterStackFactory } from "./filter-stack"; +import { InternalChannel } from "./internal-channel"; +import { Metadata } from "./metadata"; +import { PickResultType } from "./picker"; +import { CallConfig } from "./resolver"; +import { splitHostPort } from "./uri-parser"; +import * as logging from './logging'; + +const TRACER_NAME = 'load_balancing_call'; + +export type RpcProgress = 'NOT_STARTED' | 'DROP' | 'REFUSED' | 'PROCESSED'; + +export interface StatusObjectWithProgress extends StatusObject { + progress: RpcProgress; +} + +export class LoadBalancingCall implements Call { + private child: SubchannelCall | null = null; + private readPending = false; + private writeFilterPending = false; + private pendingMessage: {context: MessageContext, message: Buffer} | null = null; + private pendingHalfClose = false; + private ended = false; + private serviceUrl: string; + private filterStack: FilterStack; + private metadata: Metadata | null = null; + private listener: InterceptingListener | null = null; + private onCallEnded: ((statusCode: Status) => void) | null = null; + constructor( + private readonly channel: InternalChannel, + private readonly callConfig: CallConfig, + private readonly methodName: string, + private readonly host : string, + private readonly credentials: CallCredentials, + private readonly deadline: Deadline, + filterStackFactory: FilterStackFactory, + private readonly callNumber: number + ) { + this.filterStack = filterStackFactory.createFilter(); + + const splitPath: string[] = this.methodName.split('/'); + let serviceName = ''; + /* The standard path format is "/{serviceName}/{methodName}", so if we split + * by '/', the first item should be empty and the second should be the + * service name */ + if (splitPath.length >= 2) { + serviceName = splitPath[1]; + } + const hostname = splitHostPort(this.host)?.host ?? 'localhost'; + /* Currently, call credentials are only allowed on HTTPS connections, so we + * can assume that the scheme is "https" */ + this.serviceUrl = `https://${hostname}/${serviceName}`; + } + + private trace(text: string): void { + logging.trace( + LogVerbosity.DEBUG, + TRACER_NAME, + '[' + this.callNumber + '] ' + text + ); + } + + private outputStatus(status: StatusObject, progress: RpcProgress) { + if (!this.ended) { + this.ended = true; + this.trace('ended with status: code=' + status.code + ' details="' + status.details + '"'); + const filteredStatus = this.filterStack.receiveTrailers(status); + const finalStatus = {...filteredStatus, progress}; + this.listener?.onReceiveStatus(finalStatus); + this.onCallEnded?.(finalStatus.code); + } + } + + doPick() { + if (this.ended) { + return; + } + if (!this.metadata) { + throw new Error('doPick called before start'); + } + const pickResult = this.channel.doPick(this.metadata, this.callConfig.pickInformation); + const subchannelString = pickResult.subchannel ? + '(' + pickResult.subchannel.getChannelzRef().id + ') ' + pickResult.subchannel.getAddress() : + '' + pickResult.subchannel; + this.trace( + 'Pick result: ' + + PickResultType[pickResult.pickResultType] + + ' subchannel: ' + + subchannelString + + ' status: ' + + pickResult.status?.code + + ' ' + + pickResult.status?.details + ); + switch (pickResult.pickResultType) { + case PickResultType.COMPLETE: + this.credentials.generateMetadata({service_url: this.serviceUrl}).then( + (credsMetadata) => { + const finalMetadata = this.metadata!.clone(); + finalMetadata.merge(credsMetadata); + if (finalMetadata.get('authorization').length > 1) { + this.outputStatus( + { + code: Status.INTERNAL, + details: '"authorization" metadata cannot have multiple values', + metadata: new Metadata() + }, + 'PROCESSED' + ); + } + if (pickResult.subchannel!.getConnectivityState() !== ConnectivityState.READY) { + this.trace( + 'Picked subchannel ' + + subchannelString + + ' has state ' + + ConnectivityState[pickResult.subchannel!.getConnectivityState()] + + ' after getting credentials metadata. Retrying pick' + ); + this.doPick(); + return; + } + + if (this.deadline !== Infinity) { + finalMetadata.set('grpc-timeout', getDeadlineTimeoutString(this.deadline)); + } + try { + this.child = pickResult.subchannel!.getRealSubchannel().createCall(finalMetadata, this.host, this.methodName, { + onReceiveMetadata: metadata => { + this.listener!.onReceiveMetadata(this.filterStack.receiveMetadata(metadata)); + }, + onReceiveMessage: message => { + this.filterStack.receiveMessage(message).then(filteredMesssage => { + this.listener!.onReceiveMessage(filteredMesssage); + }, (status: StatusObject) => { + this.cancelWithStatus(status.code, status.details); + }); + }, + onReceiveStatus: status => { + this.outputStatus(status, 'PROCESSED'); + } + }); + } catch (error) { + this.trace( + 'Failed to start call on picked subchannel ' + + subchannelString + + ' with error ' + + (error as Error).message + ); + this.outputStatus( + { + code: Status.INTERNAL, + details: 'Failed to start HTTP/2 stream with error ' + (error as Error).message, + metadata: new Metadata() + }, + 'NOT_STARTED' + ); + return; + } + this.callConfig.onCommitted?.(); + pickResult.onCallStarted?.(); + this.onCallEnded = pickResult.onCallEnded; + this.trace('Created child call [' + this.child.getCallNumber() + ']'); + if (this.readPending) { + this.child.startRead(); + } + if (this.pendingMessage) { + this.child.sendMessageWithContext(this.pendingMessage.context, this.pendingMessage.message); + } + if (this.pendingHalfClose && !this.writeFilterPending) { + this.child.halfClose(); + } + }, (error: Error & { code: number }) => { + // We assume the error code isn't 0 (Status.OK) + this.outputStatus( + { + code: typeof error.code === 'number' ? error.code : Status.UNKNOWN, + details: `Getting metadata from plugin failed with error: ${error.message}`, + metadata: new Metadata() + }, + 'PROCESSED' + ); + } + ); + break; + case PickResultType.DROP: + this.outputStatus(pickResult.status!, 'DROP'); + break; + case PickResultType.TRANSIENT_FAILURE: + if (this.metadata.getOptions().waitForReady) { + this.channel.queueCallForPick(this); + } else { + this.outputStatus(pickResult.status!, 'PROCESSED'); + } + break; + case PickResultType.QUEUE: + this.channel.queueCallForPick(this); + } + } + + cancelWithStatus(status: Status, details: string): void { + this.trace('cancelWithStatus code: ' + status + ' details: "' + details + '"'); + this.child?.cancelWithStatus(status, details); + this.outputStatus({code: status, details: details, metadata: new Metadata()}, 'PROCESSED'); + } + getPeer(): string { + return this.child?.getPeer() ?? this.channel.getTarget(); + } + start(metadata: Metadata, listener: InterceptingListener): void { + this.trace('start called'); + this.listener = listener; + this.filterStack.sendMetadata(Promise.resolve(metadata)).then(filteredMetadata => { + this.metadata = filteredMetadata; + this.doPick(); + }, (status: StatusObject) => { + this.outputStatus(status, 'PROCESSED'); + }); + } + sendMessageWithContext(context: MessageContext, message: Buffer): void { + this.trace('write() called with message of length ' + message.length); + this.writeFilterPending = true; + this.filterStack.sendMessage(Promise.resolve({message: message, flags: context.flags})).then((filteredMessage) => { + this.writeFilterPending = false; + if (this.child) { + this.child.sendMessageWithContext(context, filteredMessage.message); + if (this.pendingHalfClose) { + this.child.halfClose(); + } + } else { + this.pendingMessage = {context, message: filteredMessage.message}; + } + }, (status: StatusObject) => { + this.cancelWithStatus(status.code, status.details); + }) + } + startRead(): void { + this.trace('startRead called'); + if (this.child) { + this.child.startRead(); + } else { + this.readPending = true; + } + } + halfClose(): void { + this.trace('halfClose called'); + if (this.child && !this.writeFilterPending) { + this.child.halfClose(); + } else { + this.pendingHalfClose = true; + } + } + setCredentials(credentials: CallCredentials): void { + throw new Error("Method not implemented."); + } + + getCallNumber(): number { + return this.callNumber; + } +} \ No newline at end of file diff --git a/packages/grpc-js/src/max-message-size-filter.ts b/packages/grpc-js/src/max-message-size-filter.ts index 9a3bc9c0a..62d01077c 100644 --- a/packages/grpc-js/src/max-message-size-filter.ts +++ b/packages/grpc-js/src/max-message-size-filter.ts @@ -16,20 +16,20 @@ */ import { BaseFilter, Filter, FilterFactory } from './filter'; -import { Call, WriteObject } from './call-stream'; +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( - private readonly options: ChannelOptions, - private readonly callStream: Call + private readonly options: ChannelOptions ) { super(); if ('grpc.max_send_message_length' in options) { @@ -48,11 +48,11 @@ export class MaxMessageSizeFilter extends BaseFilter implements Filter { } else { const concreteMessage = await message; if (concreteMessage.message.length > this.maxSendMessageSize) { - this.callStream.cancelWithStatus( - Status.RESOURCE_EXHAUSTED, - `Sent message larger than max (${concreteMessage.message.length} vs. ${this.maxSendMessageSize})` - ); - return Promise.reject('Message too large'); + throw { + code: Status.RESOURCE_EXHAUSTED, + details: `Sent message larger than max (${concreteMessage.message.length} vs. ${this.maxSendMessageSize})`, + metadata: new Metadata() + }; } else { return concreteMessage; } @@ -67,11 +67,11 @@ export class MaxMessageSizeFilter extends BaseFilter implements Filter { } else { const concreteMessage = await message; if (concreteMessage.length > this.maxReceiveMessageSize) { - this.callStream.cancelWithStatus( - Status.RESOURCE_EXHAUSTED, - `Received message larger than max (${concreteMessage.length} vs. ${this.maxReceiveMessageSize})` - ); - return Promise.reject('Message too large'); + throw { + code: Status.RESOURCE_EXHAUSTED, + details: `Received message larger than max (${concreteMessage.length} vs. ${this.maxReceiveMessageSize})`, + metadata: new Metadata() + }; } else { return concreteMessage; } @@ -83,7 +83,7 @@ export class MaxMessageSizeFilterFactory implements FilterFactory { constructor(private readonly options: ChannelOptions) {} - createFilter(callStream: Call): MaxMessageSizeFilter { - return new MaxMessageSizeFilter(this.options, callStream); + createFilter(): MaxMessageSizeFilter { + return new MaxMessageSizeFilter(this.options); } } diff --git a/packages/grpc-js/src/picker.ts b/packages/grpc-js/src/picker.ts index f366a6919..162596ef5 100644 --- a/packages/grpc-js/src/picker.ts +++ b/packages/grpc-js/src/picker.ts @@ -15,12 +15,10 @@ * */ -import { Subchannel } from './subchannel'; -import { StatusObject } from './call-stream'; +import { StatusObject } from './call-interface'; import { Metadata } from './metadata'; import { Status } from './constants'; import { LoadBalancer } from './load-balancer'; -import { FilterFactory, Filter } from './filter'; import { SubchannelInterface } from './subchannel-interface'; export enum PickResultType { @@ -43,45 +41,40 @@ export interface PickResult { * `pickResultType` is TRANSIENT_FAILURE. */ status: StatusObject | null; - /** - * Extra FilterFactory (can be multiple encapsulated in a FilterStackFactory) - * provided by the load balancer to be used with the call. For technical - * reasons filters from this factory will not see sendMetadata events. - */ - extraFilterFactories: FilterFactory[]; onCallStarted: (() => void) | null; + onCallEnded: ((statusCode: Status) => void) | null; } export interface CompletePickResult extends PickResult { pickResultType: PickResultType.COMPLETE; subchannel: SubchannelInterface | null; status: null; - extraFilterFactories: FilterFactory[]; onCallStarted: (() => void) | null; + onCallEnded: ((statusCode: Status) => void) | null; } export interface QueuePickResult extends PickResult { pickResultType: PickResultType.QUEUE; subchannel: null; status: null; - extraFilterFactories: []; onCallStarted: null; + onCallEnded: null; } export interface TransientFailurePickResult extends PickResult { pickResultType: PickResultType.TRANSIENT_FAILURE; subchannel: null; status: StatusObject; - extraFilterFactories: []; onCallStarted: null; + onCallEnded: null; } export interface DropCallPickResult extends PickResult { pickResultType: PickResultType.DROP; subchannel: null; status: StatusObject; - extraFilterFactories: []; onCallStarted: null; + onCallEnded: null; } export interface PickArgs { @@ -120,8 +113,8 @@ export class UnavailablePicker implements Picker { pickResultType: PickResultType.TRANSIENT_FAILURE, subchannel: null, status: this.status, - extraFilterFactories: [], onCallStarted: null, + onCallEnded: null }; } } @@ -149,8 +142,8 @@ export class QueuePicker { pickResultType: PickResultType.QUEUE, subchannel: null, status: null, - extraFilterFactories: [], onCallStarted: null, + onCallEnded: null }; } } diff --git a/packages/grpc-js/src/resolver-dns.ts b/packages/grpc-js/src/resolver-dns.ts index c4cb64a74..7c4028b06 100644 --- a/packages/grpc-js/src/resolver-dns.ts +++ b/packages/grpc-js/src/resolver-dns.ts @@ -24,7 +24,7 @@ import * as dns from 'dns'; import * as util from 'util'; import { extractAndSelectServiceConfig, ServiceConfig } from './service-config'; import { Status } from './constants'; -import { StatusObject } from './call-stream'; +import { StatusObject } from './call-interface'; import { Metadata } from './metadata'; import * as logging from './logging'; import { LogVerbosity } from './constants'; diff --git a/packages/grpc-js/src/resolver-ip.ts b/packages/grpc-js/src/resolver-ip.ts index 24efc3fdc..efb0b8dcb 100644 --- a/packages/grpc-js/src/resolver-ip.ts +++ b/packages/grpc-js/src/resolver-ip.ts @@ -15,7 +15,7 @@ */ import { isIPv4, isIPv6 } from 'net'; -import { StatusObject } from './call-stream'; +import { StatusObject } from './call-interface'; import { ChannelOptions } from './channel-options'; import { LogVerbosity, Status } from './constants'; import { Metadata } from './metadata'; diff --git a/packages/grpc-js/src/resolver.ts b/packages/grpc-js/src/resolver.ts index fcbc6894a..770004487 100644 --- a/packages/grpc-js/src/resolver.ts +++ b/packages/grpc-js/src/resolver.ts @@ -16,7 +16,7 @@ */ import { MethodConfig, ServiceConfig } from './service-config'; -import { StatusObject } from './call-stream'; +import { StatusObject } from './call-interface'; import { SubchannelAddress } from './subchannel-address'; import { GrpcUri, uriToString } from './uri-parser'; import { ChannelOptions } from './channel-options'; diff --git a/packages/grpc-js/src/resolving-call.ts b/packages/grpc-js/src/resolving-call.ts new file mode 100644 index 000000000..4cf24b4b1 --- /dev/null +++ b/packages/grpc-js/src/resolving-call.ts @@ -0,0 +1,219 @@ +/* + * 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. + * + */ + +import { CallCredentials } from "./call-credentials"; +import { Call, CallStreamOptions, InterceptingListener, MessageContext, StatusObject } from "./call-interface"; +import { LogVerbosity, Propagate, Status } from "./constants"; +import { Deadline, getDeadlineTimeoutString, getRelativeTimeout, minDeadline } from "./deadline"; +import { FilterStackFactory } from "./filter-stack"; +import { InternalChannel } from "./internal-channel"; +import { Metadata } from "./metadata"; +import * as logging from './logging'; + +const TRACER_NAME = 'resolving_call'; + +export class ResolvingCall implements Call { + private child: Call | null = null; + private readPending = false; + private pendingMessage: {context: MessageContext, message: Buffer} | null = null; + private pendingHalfClose = false; + private ended = false; + private metadata: Metadata | null = null; + private listener: InterceptingListener | null = null; + private deadline: Deadline; + private host: string; + private statusWatchers: ((status: StatusObject) => void)[] = []; + private deadlineTimer: NodeJS.Timer = setTimeout(() => {}, 0); + + constructor( + private readonly channel: InternalChannel, + private readonly method: string, + options: CallStreamOptions, + private readonly filterStackFactory: FilterStackFactory, + private credentials: CallCredentials, + private callNumber: number + ) { + this.deadline = options.deadline; + this.host = options.host; + if (options.parentCall) { + if (options.flags & Propagate.CANCELLATION) { + options.parentCall.on('cancelled', () => { + this.cancelWithStatus(Status.CANCELLED, 'Cancelled by parent call'); + }); + } + if (options.flags & Propagate.DEADLINE) { + this.trace('Propagating deadline from parent: ' + options.parentCall.getDeadline()); + this.deadline = minDeadline(this.deadline, options.parentCall.getDeadline()); + } + } + this.trace('Created'); + this.runDeadlineTimer(); + } + + private trace(text: string): void { + logging.trace( + LogVerbosity.DEBUG, + TRACER_NAME, + '[' + this.callNumber + '] ' + text + ); + } + + private runDeadlineTimer() { + clearTimeout(this.deadlineTimer); + this.trace('Deadline: ' + this.deadline); + if (this.deadline !== Infinity) { + const timeout = getRelativeTimeout(this.deadline); + this.trace('Deadline will be reached in ' + timeout + 'ms'); + const handleDeadline = () => { + this.cancelWithStatus( + Status.DEADLINE_EXCEEDED, + 'Deadline exceeded' + ); + } + if (timeout <= 0) { + process.nextTick(handleDeadline); + } else { + this.deadlineTimer = setTimeout(handleDeadline, timeout); + } + } + } + + private outputStatus(status: StatusObject) { + if (!this.ended) { + this.ended = true; + this.trace('ended with status: code=' + status.code + ' details="' + status.details + '"'); + this.statusWatchers.forEach(watcher => watcher(status)); + process.nextTick(() => { + this.listener?.onReceiveStatus(status); + }); + } + } + + getConfig(): void { + if (this.ended) { + return; + } + if (!this.metadata || !this.listener) { + throw new Error('getConfig called before start'); + } + const config = this.channel.getConfig(this.method, this.metadata); + if (!config) { + this.channel.queueCallForConfig(this); + return; + } + if (config.status !== Status.OK) { + this.outputStatus({ + code: config.status, + details: 'Failed to route call to ' + this.method, + metadata: new Metadata() + }); + return; + } + + if (config.methodConfig.timeout) { + const configDeadline = new Date(); + configDeadline.setSeconds( + configDeadline.getSeconds() + config.methodConfig.timeout.seconds + ); + configDeadline.setMilliseconds( + configDeadline.getMilliseconds() + + config.methodConfig.timeout.nanos / 1_000_000 + ); + this.deadline = minDeadline(this.deadline, configDeadline); + } + + this.filterStackFactory.push(config.dynamicFilterFactories); + + this.child = this.channel.createInnerCall(config, this.method, this.host, this.credentials, this.deadline); + this.child.start(this.metadata, { + onReceiveMetadata: metadata => { + this.listener!.onReceiveMetadata(metadata); + }, + onReceiveMessage: message => { + this.listener!.onReceiveMessage(message); + }, + onReceiveStatus: status => { + this.outputStatus(status); + } + }); + if (this.readPending) { + this.child.startRead(); + } + if (this.pendingMessage) { + this.child.sendMessageWithContext(this.pendingMessage.context, this.pendingMessage.message); + } + if (this.pendingHalfClose) { + this.child.halfClose(); + } + } + reportResolverError(status: StatusObject) { + if (this.metadata?.getOptions().waitForReady) { + this.channel.queueCallForConfig(this); + } else { + this.outputStatus(status); + } + } + cancelWithStatus(status: Status, details: string): void { + this.trace('cancelWithStatus code: ' + status + ' details: "' + details + '"'); + this.child?.cancelWithStatus(status, details); + this.outputStatus({code: status, details: details, metadata: new Metadata()}); + } + getPeer(): string { + return this.child?.getPeer() ?? this.channel.getTarget(); + } + start(metadata: Metadata, listener: InterceptingListener): void { + this.trace('start called'); + this.metadata = metadata.clone(); + this.listener = listener; + this.getConfig(); + } + sendMessageWithContext(context: MessageContext, message: Buffer): void { + this.trace('write() called with message of length ' + message.length); + if (this.child) { + this.child.sendMessageWithContext(context, message); + } else { + this.pendingMessage = {context, message}; + } + } + startRead(): void { + this.trace('startRead called'); + if (this.child) { + this.child.startRead(); + } else { + this.readPending = true; + } + } + halfClose(): void { + this.trace('halfClose called'); + if (this.child) { + this.child.halfClose(); + } else { + this.pendingHalfClose = true; + } + } + setCredentials(credentials: CallCredentials): void { + this.credentials = this.credentials.compose(credentials); + } + + addStatusWatcher(watcher: (status: StatusObject) => void) { + this.statusWatchers.push(watcher); + } + + getCallNumber(): number { + return this.callNumber; + } +} \ No newline at end of file diff --git a/packages/grpc-js/src/resolving-load-balancer.ts b/packages/grpc-js/src/resolving-load-balancer.ts index 907067dfc..47f7c3bb1 100644 --- a/packages/grpc-js/src/resolving-load-balancer.ts +++ b/packages/grpc-js/src/resolving-load-balancer.ts @@ -28,7 +28,7 @@ import { ServiceError } from './call'; import { Picker, UnavailablePicker, QueuePicker } from './picker'; import { BackoffOptions, BackoffTimeout } from './backoff-timeout'; import { Status } from './constants'; -import { StatusObject } from './call-stream'; +import { StatusObject } from './call-interface'; import { Metadata } from './metadata'; import * as logging from './logging'; import { LogVerbosity } from './constants'; diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index 315c9d9aa..388a8d339 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -20,7 +20,6 @@ import * as http2 from 'http2'; import { Duplex, Readable, Writable } from 'stream'; import * as zlib from 'zlib'; -import { Deadline, StatusObject } from './call-stream'; import { Status, DEFAULT_MAX_SEND_MESSAGE_LENGTH, @@ -33,6 +32,8 @@ import { StreamDecoder } from './stream-decoder'; import { ObjectReadable, ObjectWritable } from './object-stream'; import { ChannelOptions } from './channel-options'; import * as logging from './logging'; +import { StatusObject } from './call-interface'; +import { Deadline } from './deadline'; const TRACER_NAME = 'server_call'; @@ -508,6 +509,8 @@ export class Http2ServerCallStream< receiveMetadata(headers: http2.IncomingHttpHeaders) { const metadata = Metadata.fromHttp2Headers(headers); + trace('Request to ' + this.handler.path + ' received headers ' + JSON.stringify(metadata.toJSON())); + // TODO(cjihrig): Receive compression metadata. const timeoutHeader = metadata.get(GRPC_TIMEOUT_HEADER); diff --git a/packages/grpc-js/src/service-config.ts b/packages/grpc-js/src/service-config.ts index f310597e9..12802dad8 100644 --- a/packages/grpc-js/src/service-config.ts +++ b/packages/grpc-js/src/service-config.ts @@ -27,6 +27,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import * as os from 'os'; +import { Status } from './constants'; import { Duration } from './duration'; import { LoadBalancingConfig, @@ -38,18 +39,40 @@ export interface MethodConfigName { method?: string; } +export interface RetryPolicy { + maxAttempts: number; + initialBackoff: string; + maxBackoff: string; + backoffMultiplier: number; + retryableStatusCodes: (Status | string)[]; +} + +export interface HedgingPolicy { + maxAttempts: number; + hedgingDelay?: string; + nonFatalStatusCodes: (Status | string)[]; +} + export interface MethodConfig { name: MethodConfigName[]; waitForReady?: boolean; timeout?: Duration; maxRequestBytes?: number; maxResponseBytes?: number; + retryPolicy?: RetryPolicy; + hedgingPolicy?: HedgingPolicy; +} + +export interface RetryThrottling { + maxTokens: number; + tokenRatio: number; } export interface ServiceConfig { loadBalancingPolicy?: string; loadBalancingConfig: LoadBalancingConfig[]; methodConfig: MethodConfig[]; + retryThrottling?: RetryThrottling; } export interface ServiceConfigCanaryConfig { diff --git a/packages/grpc-js/src/status-builder.ts b/packages/grpc-js/src/status-builder.ts index 1109af1ac..78e2ea310 100644 --- a/packages/grpc-js/src/status-builder.ts +++ b/packages/grpc-js/src/status-builder.ts @@ -15,7 +15,7 @@ * */ -import { StatusObject } from './call-stream'; +import { StatusObject } from './call-interface'; import { Status } from './constants'; import { Metadata } from './metadata'; diff --git a/packages/grpc-js/src/subchannel-call.ts b/packages/grpc-js/src/subchannel-call.ts new file mode 100644 index 000000000..ac34823ba --- /dev/null +++ b/packages/grpc-js/src/subchannel-call.ts @@ -0,0 +1,504 @@ +/* + * Copyright 2019 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 * as http2 from 'http2'; +import * as os from 'os'; + +import { Status } from './constants'; +import { Metadata } from './metadata'; +import { StreamDecoder } from './stream-decoder'; +import { SubchannelCallStatsTracker, Subchannel } from './subchannel'; +import * as logging from './logging'; +import { LogVerbosity } from './constants'; +import { ServerSurfaceCall } from './server-call'; +import { Deadline } from './deadline'; +import { InterceptingListener, MessageContext, StatusObject, WriteCallback } from './call-interface'; + +const TRACER_NAME = 'subchannel_call'; + +const { + HTTP2_HEADER_STATUS, + HTTP2_HEADER_CONTENT_TYPE, + NGHTTP2_CANCEL, +} = http2.constants; + +/** + * https://nodejs.org/api/errors.html#errors_class_systemerror + */ +interface SystemError extends Error { + address?: string; + code: string; + dest?: string; + errno: number; + info?: object; + message: string; + path?: string; + port?: number; + syscall: string; +} + +/** + * Should do approximately the same thing as util.getSystemErrorName but the + * TypeScript types don't have that function for some reason so I just made my + * own. + * @param errno + */ +function getSystemErrorName(errno: number): string { + for (const [name, num] of Object.entries(os.constants.errno)) { + if (num === errno) { + return name; + } + } + return 'Unknown system error ' + errno; +} + +export interface SubchannelCall { + cancelWithStatus(status: Status, details: string): void; + getPeer(): string; + sendMessageWithContext(context: MessageContext, message: Buffer): void; + startRead(): void; + halfClose(): void; + getCallNumber(): number; +} + +export class Http2SubchannelCall implements SubchannelCall { + private decoder = new StreamDecoder(); + + private isReadFilterPending = false; + private canPush = false; + /** + * Indicates that an 'end' event has come from the http2 stream, so there + * will be no more data events. + */ + private readsClosed = false; + + private statusOutput = false; + + private unpushedReadMessages: Buffer[] = []; + + // Status code mapped from :status. To be used if grpc-status is not received + private mappedStatusCode: Status = Status.UNKNOWN; + + // This is populated (non-null) if and only if the call has ended + private finalStatus: StatusObject | null = null; + + private disconnectListener: () => void; + + private internalError: SystemError | null = null; + + constructor( + private readonly http2Stream: http2.ClientHttp2Stream, + private readonly callStatsTracker: SubchannelCallStatsTracker, + private readonly listener: InterceptingListener, + private readonly subchannel: Subchannel, + private readonly callId: number + ) { + this.disconnectListener = () => { + this.endCall({ + code: Status.UNAVAILABLE, + details: 'Connection dropped', + metadata: new Metadata(), + }); + }; + subchannel.addDisconnectListener(this.disconnectListener); + subchannel.callRef(); + http2Stream.on('response', (headers, flags) => { + let headersString = ''; + for (const header of Object.keys(headers)) { + 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; + } + + if (flags & http2.constants.NGHTTP2_FLAG_END_STREAM) { + this.handleTrailers(headers); + } else { + let metadata: Metadata; + try { + metadata = Metadata.fromHttp2Headers(headers); + } catch (error) { + this.endCall({ + code: Status.UNKNOWN, + details: (error as Error).message, + metadata: new Metadata(), + }); + return; + } + this.listener.onReceiveMetadata(metadata); + } + }); + http2Stream.on('trailers', (headers: http2.IncomingHttpHeaders) => { + this.handleTrailers(headers); + }); + http2Stream.on('data', (data: Buffer) => { + this.trace('receive HTTP/2 data frame of length ' + data.length); + const messages = this.decoder.write(data); + + for (const message of messages) { + this.trace('parsed message of length ' + message.length); + this.callStatsTracker!.addMessageReceived(); + this.tryPush(message); + } + }); + http2Stream.on('end', () => { + this.readsClosed = true; + this.maybeOutputStatus(); + }); + http2Stream.on('close', () => { + /* 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. */ + process.nextTick(() => { + this.trace('HTTP/2 stream closed with code ' + http2Stream.rstCode); + /* If we have a final status with an OK status code, that means that + * we have received all of the messages and we have processed the + * trailers and the call completed successfully, so it doesn't matter + * how the stream ends after that */ + if (this.finalStatus?.code === Status.OK) { + return; + } + let code: Status; + let details = ''; + switch (http2Stream.rstCode) { + case http2.constants.NGHTTP2_NO_ERROR: + /* If we get a NO_ERROR code and we already have a status, the + * stream completed properly and we just haven't fully processed + * it yet */ + if (this.finalStatus !== null) { + return; + } + code = Status.INTERNAL; + details = `Received RST_STREAM with code ${http2Stream.rstCode}`; + break; + case http2.constants.NGHTTP2_REFUSED_STREAM: + code = Status.UNAVAILABLE; + details = 'Stream refused by server'; + break; + case http2.constants.NGHTTP2_CANCEL: + code = Status.CANCELLED; + details = 'Call cancelled'; + break; + case http2.constants.NGHTTP2_ENHANCE_YOUR_CALM: + code = Status.RESOURCE_EXHAUSTED; + details = 'Bandwidth exhausted or memory limit exceeded'; + break; + case http2.constants.NGHTTP2_INADEQUATE_SECURITY: + code = Status.PERMISSION_DENIED; + details = 'Protocol not secure enough'; + break; + case http2.constants.NGHTTP2_INTERNAL_ERROR: + code = Status.INTERNAL; + if (this.internalError === null) { + /* This error code was previously handled in the default case, and + * there are several instances of it online, so I wanted to + * preserve the original error message so that people find existing + * information in searches, but also include the more recognizable + * "Internal server error" message. */ + details = `Received RST_STREAM with code ${http2Stream.rstCode} (Internal server error)`; + } else { + if (this.internalError.code === 'ECONNRESET' || this.internalError.code === 'ETIMEDOUT') { + code = Status.UNAVAILABLE; + details = this.internalError.message; + } else { + /* The "Received RST_STREAM with code ..." error is preserved + * here for continuity with errors reported online, but the + * error message at the end will probably be more relevant in + * most cases. */ + details = `Received RST_STREAM with code ${http2Stream.rstCode} triggered by internal client error: ${this.internalError.message}`; + } + } + break; + default: + code = Status.INTERNAL; + details = `Received RST_STREAM with code ${http2Stream.rstCode}`; + } + // This is a no-op if trailers were received at all. + // This is OK, because status codes emitted here correspond to more + // catastrophic issues that prevent us from receiving trailers in the + // first place. + this.endCall({ code, details, metadata: new Metadata() }); + }); + }); + http2Stream.on('error', (err: SystemError) => { + /* We need an error handler here to stop "Uncaught Error" exceptions + * from bubbling up. However, errors here should all correspond to + * "close" events, where we will handle the error more granularly */ + /* Specifically looking for stream errors that were *not* constructed + * from a RST_STREAM response here: + * https://github.com/nodejs/node/blob/8b8620d580314050175983402dfddf2674e8e22a/lib/internal/http2/core.js#L2267 + */ + if (err.code !== 'ERR_HTTP2_STREAM_ERROR') { + this.trace( + 'Node error event: message=' + + err.message + + ' code=' + + err.code + + ' errno=' + + getSystemErrorName(err.errno) + + ' syscall=' + + err.syscall + ); + this.internalError = err; + } + this.callStatsTracker.onStreamEnd(false); + }); + } + + private outputStatus() { + /* Precondition: this.finalStatus !== null */ + if (!this.statusOutput) { + this.statusOutput = true; + this.trace( + 'ended with status: code=' + + this.finalStatus!.code + + ' details="' + + this.finalStatus!.details + + '"' + ); + this.callStatsTracker.onCallEnd(this.finalStatus!); + /* We delay the actual action of bubbling up the status to insulate the + * cleanup code in this class from any errors that may be thrown in the + * upper layers as a result of bubbling up the status. In particular, + * if the status is not OK, the "error" event may be emitted + * synchronously at the top level, which will result in a thrown error if + * the user does not handle that event. */ + process.nextTick(() => { + this.listener.onReceiveStatus(this.finalStatus!); + }); + this.subchannel.callUnref(); + this.subchannel.removeDisconnectListener(this.disconnectListener); + } + } + + private trace(text: string): void { + logging.trace( + LogVerbosity.DEBUG, + TRACER_NAME, + '[' + this.callId + '] ' + text + ); + } + + /** + * On first call, emits a 'status' event with the given StatusObject. + * Subsequent calls are no-ops. + * @param status The status of the call. + */ + private endCall(status: StatusObject): void { + /* If the status is OK and a new status comes in (e.g. from a + * deserialization failure), that new status takes priority */ + if (this.finalStatus === null || this.finalStatus.code === Status.OK) { + this.finalStatus = status; + this.maybeOutputStatus(); + } + this.destroyHttp2Stream(); + } + + private maybeOutputStatus() { + if (this.finalStatus !== null) { + /* The combination check of readsClosed and that the two message buffer + * arrays are empty checks that there all incoming data has been fully + * processed */ + if ( + this.finalStatus.code !== Status.OK || + (this.readsClosed && + this.unpushedReadMessages.length === 0 && + !this.isReadFilterPending) + ) { + this.outputStatus(); + } + } + } + + private push(message: Buffer): void { + this.trace( + 'pushing to reader message of length ' + + (message instanceof Buffer ? message.length : null) + ); + this.canPush = false; + process.nextTick(() => { + /* If we have already output the status any later messages should be + * ignored, and can cause out-of-order operation errors higher up in the + * stack. Checking as late as possible here to avoid any race conditions. + */ + if (this.statusOutput) { + return; + } + this.listener.onReceiveMessage(message); + this.maybeOutputStatus(); + }); + } + + private tryPush(messageBytes: Buffer): void { + if (this.canPush) { + this.http2Stream!.pause(); + this.push(messageBytes); + } else { + this.trace( + 'unpushedReadMessages.push message of length ' + messageBytes.length + ); + this.unpushedReadMessages.push(messageBytes); + } + } + + private handleTrailers(headers: http2.IncomingHttpHeaders) { + this.callStatsTracker.onStreamEnd(true); + let headersString = ''; + for (const header of Object.keys(headers)) { + headersString += '\t\t' + header + ': ' + headers[header] + '\n'; + } + this.trace('Received server trailers:\n' + headersString); + let metadata: Metadata; + try { + metadata = Metadata.fromHttp2Headers(headers); + } catch (e) { + 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'); + } + metadata.remove('grpc-status'); + } + let details = ''; + if (typeof metadataMap['grpc-message'] === 'string') { + details = decodeURI(metadataMap['grpc-message']); + metadata.remove('grpc-message'); + this.trace( + 'received status details string "' + details + '" from server' + ); + } + const status: StatusObject = { code, details, metadata }; + // This is a no-op if the call was already ended when handling headers. + this.endCall(status); + } + + 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 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 */ + let code: number; + if (this.finalStatus?.code === Status.OK) { + code = http2.constants.NGHTTP2_NO_ERROR; + } else { + code = http2.constants.NGHTTP2_CANCEL; + } + this.trace('close http2 stream with code ' + code); + this.http2Stream.close(code); + } + } + + cancelWithStatus(status: Status, details: string): void { + this.trace( + 'cancelWithStatus code: ' + status + ' details: "' + details + '"' + ); + this.endCall({ code: status, details, metadata: new Metadata() }); + } + + getStatus(): StatusObject | null { + return this.finalStatus; + } + + getPeer(): string { + return this.subchannel.getAddress(); + } + + getCallNumber(): number { + return this.callId; + } + + startRead() { + /* If the stream has ended with an error, we should not emit any more + * messages and we should communicate that the stream has ended */ + if (this.finalStatus !== null && this.finalStatus.code !== Status.OK) { + this.readsClosed = true; + this.maybeOutputStatus(); + return; + } + this.canPush = true; + if (this.unpushedReadMessages.length > 0) { + const nextMessage: Buffer = this.unpushedReadMessages.shift()!; + this.push(nextMessage); + return; + } + /* Only resume reading from the http2Stream if we don't have any pending + * messages to emit */ + this.http2Stream.resume(); + } + + sendMessageWithContext(context: MessageContext, message: Buffer) { + this.trace('write() called with message of length ' + message.length); + const cb: WriteCallback = (error?: Error | null) => { + let code: Status = Status.UNAVAILABLE; + if ((error as NodeJS.ErrnoException)?.code === 'ERR_STREAM_WRITE_AFTER_END') { + code = Status.INTERNAL; + } + if (error) { + this.cancelWithStatus(code, `Write error: ${error.message}`); + } + context.callback?.(); + }; + this.trace('sending data chunk of length ' + message.length); + this.callStatsTracker.addMessageSent(); + try { + this.http2Stream!.write(message, cb); + } catch (error) { + this.endCall({ + code: Status.UNAVAILABLE, + details: `Write failed with error ${(error as Error).message}`, + metadata: new Metadata() + }); + } + } + + halfClose() { + this.trace('end() called'); + this.trace('calling end() on HTTP/2 stream'); + this.http2Stream.end(); + } +} diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 800274f99..563e69464 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -18,7 +18,6 @@ import * as http2 from 'http2'; import { ChannelCredentials } from './channel-credentials'; import { Metadata } from './metadata'; -import { Call, Http2CallStream, WriteObject } from './call-stream'; import { ChannelOptions } from './channel-options'; import { PeerCertificate, checkServerIdentity, TLSSocket, CipherNameAndProtocol } from 'tls'; import { ConnectivityState } from './connectivity-state'; @@ -30,7 +29,6 @@ import { getProxiedConnection, ProxyConnectionResult } from './http_proxy'; import * as net from 'net'; import { GrpcUri, parseUri, splitHostPort, uriToString } from './uri-parser'; import { ConnectionOptions } from 'tls'; -import { FilterFactory, Filter, BaseFilter } from './filter'; import { stringToSubchannelAddress, SubchannelAddress, @@ -38,18 +36,16 @@ import { } from './subchannel-address'; import { SubchannelRef, ChannelzTrace, ChannelzChildrenTracker, SubchannelInfo, registerChannelzSubchannel, ChannelzCallTracker, SocketInfo, SocketRef, unregisterChannelzRef, registerChannelzSocket, TlsInfo } from './channelz'; import { ConnectivityStateListener } from './subchannel-interface'; +import { Http2SubchannelCall } from './subchannel-call'; +import { getNextCallNumber } from './call-number'; +import { SubchannelCall } from './subchannel-call'; +import { InterceptingListener, StatusObject } from './call-interface'; const clientVersion = require('../../package.json').version; const TRACER_NAME = 'subchannel'; const FLOW_CONTROL_TRACER_NAME = 'subchannel_flowctrl'; -const MIN_CONNECT_TIMEOUT_MS = 20000; -const INITIAL_BACKOFF_MS = 1000; -const BACKOFF_MULTIPLIER = 1.6; -const MAX_BACKOFF_MS = 120000; -const BACKOFF_JITTER = 0.2; - /* setInterval and setTimeout only accept signed 32 bit integers. JS doesn't * have a constant for the max signed 32 bit integer, so this is a simple way * to calculate it */ @@ -59,6 +55,8 @@ const KEEPALIVE_TIMEOUT_MS = 20000; export interface SubchannelCallStatsTracker { addMessageSent(): void; addMessageReceived(): void; + onCallEnd(status: StatusObject): void; + onStreamEnd(success: boolean): void; } const { @@ -70,15 +68,6 @@ const { HTTP2_HEADER_USER_AGENT, } = http2.constants; -/** - * Get a number uniformly at random in the range [min, max) - * @param min - * @param max - */ -function uniformRandom(min: number, max: number) { - return Math.random() * (max - min) + min; -} - const tooManyPingsData: Buffer = Buffer.from('too_many_pings', 'ascii'); export class Subchannel { @@ -808,24 +797,13 @@ export class Subchannel { return false; } - /** - * Start a stream on the current session with the given `metadata` as headers - * and then attach it to the `callStream`. Must only be called if the - * subchannel's current connectivity state is READY. - * @param metadata - * @param callStream - */ - startCallStream( - metadata: Metadata, - callStream: Http2CallStream, - extraFilters: Filter[] - ) { + createCall(metadata: Metadata, host: string, method: string, listener: InterceptingListener): SubchannelCall { const headers = metadata.toHttp2Headers(); - headers[HTTP2_HEADER_AUTHORITY] = callStream.getHost(); + headers[HTTP2_HEADER_AUTHORITY] = host; headers[HTTP2_HEADER_USER_AGENT] = this.userAgent; headers[HTTP2_HEADER_CONTENT_TYPE] = 'application/grpc'; headers[HTTP2_HEADER_METHOD] = 'POST'; - headers[HTTP2_HEADER_PATH] = callStream.getMethod(); + headers[HTTP2_HEADER_PATH] = method; headers[HTTP2_HEADER_TE] = 'trailers'; let http2Stream: http2.ClientHttp2Stream; /* In theory, if an error is thrown by session.request because session has @@ -845,19 +823,6 @@ export class Subchannel { ); throw e; } - let headersString = ''; - for (const header of Object.keys(headers)) { - headersString += '\t\t' + header + ': ' + headers[header] + '\n'; - } - logging.trace( - LogVerbosity.DEBUG, - 'call_stream', - 'Starting stream [' + callStream.getCallNumber() + '] on subchannel ' + - '(' + this.channelzRef.id + ') ' + - this.subchannelAddressString + - ' with headers\n' + - headersString - ); this.flowControlTrace( 'local window size: ' + this.session!.state.localWindowSize + @@ -875,23 +840,7 @@ export class Subchannel { let statsTracker: SubchannelCallStatsTracker; if (this.channelzEnabled) { this.callTracker.addCallStarted(); - callStream.addStatusWatcher(status => { - if (status.code === Status.OK) { - this.callTracker.addCallSucceeded(); - } else { - this.callTracker.addCallFailed(); - } - }); this.streamTracker.addCallStarted(); - callStream.addStreamEndWatcher(success => { - if (streamSession === this.session) { - if (success) { - this.streamTracker.addCallSucceeded(); - } else { - this.streamTracker.addCallFailed(); - } - } - }); statsTracker = { addMessageSent: () => { this.messagesSent += 1; @@ -899,15 +848,33 @@ export class Subchannel { }, addMessageReceived: () => { this.messagesReceived += 1; + }, + onCallEnd: status => { + if (status.code === Status.OK) { + this.callTracker.addCallSucceeded(); + } else { + this.callTracker.addCallFailed(); + } + }, + onStreamEnd: success => { + if (streamSession === this.session) { + if (success) { + this.streamTracker.addCallSucceeded(); + } else { + this.streamTracker.addCallFailed(); + } + } } } } else { statsTracker = { addMessageSent: () => {}, - addMessageReceived: () => {} + addMessageReceived: () => {}, + onCallEnd: () => {}, + onStreamEnd: () => {} } } - callStream.attachHttp2Stream(http2Stream, this, extraFilters, statsTracker); + return new Http2SubchannelCall(http2Stream, statsTracker, listener, this, getNextCallNumber()); } /** diff --git a/packages/grpc-js/test/test-resolver.ts b/packages/grpc-js/test/test-resolver.ts index 354413ea6..1bcaabeb4 100644 --- a/packages/grpc-js/test/test-resolver.ts +++ b/packages/grpc-js/test/test-resolver.ts @@ -23,7 +23,7 @@ import * as resolver_dns from '../src/resolver-dns'; import * as resolver_uds from '../src/resolver-uds'; import * as resolver_ip from '../src/resolver-ip'; import { ServiceConfig } from '../src/service-config'; -import { StatusObject } from '../src/call-stream'; +import { StatusObject } from '../src/call-interface'; import { SubchannelAddress, isTcpSubchannelAddress, subchannelAddressToString } from "../src/subchannel-address"; import { parseUri, GrpcUri } from '../src/uri-parser'; From 8a312e63b719fe0166acb07c8a43f2a91253ea17 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 11 Oct 2022 16:50:49 -0700 Subject: [PATCH 340/450] grpc-js-xds: Update code to handle modified experimental APIs --- .../src/http-filter/fault-injection-filter.ts | 8 ++--- .../src/http-filter/router-filter.ts | 2 +- packages/grpc-js-xds/src/load-balancer-eds.ts | 28 +++-------------- packages/grpc-js-xds/src/load-balancer-lrs.ts | 31 +++---------------- .../src/load-balancer-xds-cluster-manager.ts | 4 +-- 5 files changed, 16 insertions(+), 57 deletions(-) diff --git a/packages/grpc-js-xds/src/http-filter/fault-injection-filter.ts b/packages/grpc-js-xds/src/http-filter/fault-injection-filter.ts index a49ec77d4..b02dfbc80 100644 --- a/packages/grpc-js-xds/src/http-filter/fault-injection-filter.ts +++ b/packages/grpc-js-xds/src/http-filter/fault-injection-filter.ts @@ -231,7 +231,7 @@ const NUMBER_REGEX = /\d+/; let totalActiveFaults = 0; class FaultInjectionFilter extends BaseFilter implements Filter { - constructor(private callStream: CallStream, private config: FaultInjectionConfig) { + constructor(private config: FaultInjectionConfig) { super(); } @@ -316,7 +316,7 @@ class FaultInjectionFilter extends BaseFilter implements Filter { } } if (abortStatus !== null && rollRandomPercentage(numerator, denominator)) { - this.callStream.cancelWithStatus(abortStatus, 'Fault injected'); + return Promise.reject({code: abortStatus, details: 'Fault injected', metadata: new Metadata()}); } } return metadata; @@ -333,8 +333,8 @@ class FaultInjectionFilterFactory implements FilterFactory } } - createFilter(callStream: experimental.CallStream): FaultInjectionFilter { - return new FaultInjectionFilter(callStream, this.config); + createFilter(): FaultInjectionFilter { + return new FaultInjectionFilter(this.config); } } diff --git a/packages/grpc-js-xds/src/http-filter/router-filter.ts b/packages/grpc-js-xds/src/http-filter/router-filter.ts index 81450c0ff..172a08740 100644 --- a/packages/grpc-js-xds/src/http-filter/router-filter.ts +++ b/packages/grpc-js-xds/src/http-filter/router-filter.ts @@ -26,7 +26,7 @@ class RouterFilter extends BaseFilter implements Filter {} class RouterFilterFactory implements FilterFactory { constructor(config: HttpFilterConfig, overrideConfig?: HttpFilterConfig) {} - createFilter(callStream: experimental.CallStream): RouterFilter { + createFilter(): RouterFilter { return new RouterFilter(); } } diff --git a/packages/grpc-js-xds/src/load-balancer-eds.ts b/packages/grpc-js-xds/src/load-balancer-eds.ts index e7aac0571..39ad2c2cb 100644 --- a/packages/grpc-js-xds/src/load-balancer-eds.ts +++ b/packages/grpc-js-xds/src/load-balancer-eds.ts @@ -146,24 +146,6 @@ export class EdsLoadBalancingConfig implements LoadBalancingConfig { } } -class CallEndTrackingFilter extends BaseFilter implements Filter { - constructor(private onCallEnd: () => void) { - super(); - } - receiveTrailers(status: StatusObject) { - this.onCallEnd(); - return status; - } -} - -class CallTrackingFilterFactory implements FilterFactory { - constructor(private onCallEnd: () => void) {} - - createFilter(callStream: CallStream) { - return new CallEndTrackingFilter(this.onCallEnd); - } -} - /** * This class load balances over a cluster by making an EDS request and then * transforming the result into a configuration for another load balancing @@ -217,9 +199,6 @@ export class EdsLoadBalancer implements LoadBalancer { * balancer. */ if (dropCategory === null) { const originalPick = originalPicker.pick(pickArgs); - const trackingFilterFactory: FilterFactory = new CallTrackingFilterFactory(() => { - this.concurrentRequests -= 1; - }); return { pickResultType: originalPick.pickResultType, status: originalPick.status, @@ -228,7 +207,10 @@ export class EdsLoadBalancer implements LoadBalancer { originalPick.onCallStarted?.(); this.concurrentRequests += 1; }, - extraFilterFactories: originalPick.extraFilterFactories.concat(trackingFilterFactory) + onCallEnded: status => { + originalPick.onCallEnded?.(status); + this.concurrentRequests -= 1; + } }; } else { let details: string; @@ -247,7 +229,7 @@ export class EdsLoadBalancer implements LoadBalancer { metadata: new Metadata(), }, subchannel: null, - extraFilterFactories: [], + onCallEnded: null, onCallStarted: null }; } diff --git a/packages/grpc-js-xds/src/load-balancer-lrs.ts b/packages/grpc-js-xds/src/load-balancer-lrs.ts index 145501fe9..0eaeeee34 100644 --- a/packages/grpc-js-xds/src/load-balancer-lrs.ts +++ b/packages/grpc-js-xds/src/load-balancer-lrs.ts @@ -108,29 +108,6 @@ export class LrsLoadBalancingConfig implements LoadBalancingConfig { } } -/** - * Filter class that reports when the call ends. - */ -class CallEndTrackingFilter extends BaseFilter implements Filter { - constructor(private localityStatsReporter: XdsClusterLocalityStats) { - super(); - } - - receiveTrailers(status: StatusObject) { - this.localityStatsReporter.addCallFinished(status.code !== Status.OK); - return status; - } -} - -class CallEndTrackingFilterFactory - implements FilterFactory { - constructor(private localityStatsReporter: XdsClusterLocalityStats) {} - - createFilter(callStream: Call): CallEndTrackingFilter { - return new CallEndTrackingFilter(this.localityStatsReporter); - } -} - /** * Picker that delegates picking to another picker, and reports when calls * created using those picks start and end. @@ -144,9 +121,6 @@ class LoadReportingPicker implements Picker { pick(pickArgs: PickArgs): PickResult { const wrappedPick = this.wrappedPicker.pick(pickArgs); if (wrappedPick.pickResultType === PickResultType.COMPLETE) { - const trackingFilterFactory = new CallEndTrackingFilterFactory( - this.localityStatsReporter - ); return { pickResultType: PickResultType.COMPLETE, subchannel: wrappedPick.subchannel, @@ -155,7 +129,10 @@ class LoadReportingPicker implements Picker { wrappedPick.onCallStarted?.(); this.localityStatsReporter.addCallStarted(); }, - extraFilterFactories: wrappedPick.extraFilterFactories.concat(trackingFilterFactory), + onCallEnded: status => { + wrappedPick.onCallEnded?.(status); + this.localityStatsReporter.addCallFinished(status !== Status.OK); + } }; } else { return wrappedPick; diff --git a/packages/grpc-js-xds/src/load-balancer-xds-cluster-manager.ts b/packages/grpc-js-xds/src/load-balancer-xds-cluster-manager.ts index bfc55c809..bfdb4dccc 100644 --- a/packages/grpc-js-xds/src/load-balancer-xds-cluster-manager.ts +++ b/packages/grpc-js-xds/src/load-balancer-xds-cluster-manager.ts @@ -107,8 +107,8 @@ class XdsClusterManagerPicker implements Picker { metadata: new Metadata(), }, subchannel: null, - extraFilterFactories: [], - onCallStarted: null + onCallStarted: null, + onCallEnded: null }; } } From 3003dbea52a9c78ae78292b874ee4677f4667010 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 12 Oct 2022 13:47:53 -0700 Subject: [PATCH 341/450] grpc-js-xds: Delete generated code for xDS v2 --- packages/grpc-js-xds/package.json | 3 +- packages/grpc-js-xds/src/generated/ads.ts | 57 ----- .../envoy/api/v2/DeltaDiscoveryRequest.ts | 202 ------------------ .../envoy/api/v2/DeltaDiscoveryResponse.ts | 63 ------ .../envoy/api/v2/DiscoveryRequest.ts | 110 ---------- .../envoy/api/v2/DiscoveryResponse.ts | 108 ---------- .../src/generated/envoy/api/v2/Resource.ts | 43 ---- .../generated/envoy/api/v2/core/Address.ts | 26 --- .../envoy/api/v2/core/AsyncDataSource.ts | 34 --- .../envoy/api/v2/core/BackoffStrategy.ts | 43 ---- .../generated/envoy/api/v2/core/BindConfig.ts | 49 ----- .../envoy/api/v2/core/BuildVersion.ts | 36 ---- .../generated/envoy/api/v2/core/CidrRange.ts | 33 --- .../envoy/api/v2/core/ControlPlane.ts | 26 --- .../generated/envoy/api/v2/core/DataSource.ts | 40 ---- .../generated/envoy/api/v2/core/Extension.ts | 75 ------- .../generated/envoy/api/v2/core/HeaderMap.ts | 17 -- .../envoy/api/v2/core/HeaderValue.ts | 38 ---- .../envoy/api/v2/core/HeaderValueOption.ts | 34 --- .../generated/envoy/api/v2/core/HttpUri.ts | 79 ------- .../generated/envoy/api/v2/core/Locality.ts | 56 ----- .../generated/envoy/api/v2/core/Metadata.ts | 67 ------ .../src/generated/envoy/api/v2/core/Node.ts | 173 --------------- .../src/generated/envoy/api/v2/core/Pipe.ts | 30 --- .../envoy/api/v2/core/RemoteDataSource.ts | 40 ---- .../envoy/api/v2/core/RequestMethod.ts | 17 -- .../envoy/api/v2/core/RetryPolicy.ts | 38 ---- .../envoy/api/v2/core/RoutingPriority.ts | 15 -- .../envoy/api/v2/core/RuntimeDouble.ts | 30 --- .../envoy/api/v2/core/RuntimeFeatureFlag.ts | 35 --- .../api/v2/core/RuntimeFractionalPercent.ts | 49 ----- .../envoy/api/v2/core/RuntimeUInt32.ts | 30 --- .../envoy/api/v2/core/SocketAddress.ts | 97 --------- .../envoy/api/v2/core/SocketOption.ts | 90 -------- .../envoy/api/v2/core/TcpKeepalive.ts | 43 ---- .../envoy/api/v2/core/TrafficDirection.ts | 19 -- .../envoy/api/v2/core/TransportSocket.ts | 46 ---- .../envoy/api/v2/endpoint/ClusterStats.ts | 117 ---------- .../v2/endpoint/EndpointLoadMetricStats.ts | 41 ---- .../api/v2/endpoint/UpstreamEndpointStats.ts | 106 --------- .../api/v2/endpoint/UpstreamLocalityStats.ts | 108 ---------- .../envoy/service/discovery/v2/AdsDummy.ts | 16 -- .../v2/AggregatedDiscoveryService.ts | 58 ----- .../load_stats/v2/LoadReportingService.ts | 113 ---------- .../service/load_stats/v2/LoadStatsRequest.ts | 34 --- .../load_stats/v2/LoadStatsResponse.ts | 71 ------ .../generated/envoy/type/FractionalPercent.ts | 68 ------ .../src/generated/envoy/type/Percent.ts | 16 -- .../generated/envoy/type/SemanticVersion.ts | 24 --- packages/grpc-js-xds/src/generated/lrs.ts | 51 ----- 50 files changed, 1 insertion(+), 2813 deletions(-) delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/DeltaDiscoveryRequest.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/DeltaDiscoveryResponse.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/DiscoveryRequest.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/DiscoveryResponse.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/Resource.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/Address.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/AsyncDataSource.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/BackoffStrategy.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/BindConfig.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/BuildVersion.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/CidrRange.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/ControlPlane.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/DataSource.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/Extension.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/HeaderMap.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/HeaderValue.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/HeaderValueOption.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/HttpUri.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/Locality.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/Metadata.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/Node.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/Pipe.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/RemoteDataSource.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/RequestMethod.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/RetryPolicy.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/RoutingPriority.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeDouble.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeFeatureFlag.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeFractionalPercent.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeUInt32.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/SocketAddress.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/SocketOption.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/TcpKeepalive.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/TrafficDirection.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/core/TransportSocket.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/ClusterStats.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/EndpointLoadMetricStats.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/UpstreamEndpointStats.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/UpstreamLocalityStats.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/service/discovery/v2/AdsDummy.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/service/discovery/v2/AggregatedDiscoveryService.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadReportingService.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadStatsRequest.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadStatsResponse.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/type/FractionalPercent.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/type/Percent.ts delete mode 100644 packages/grpc-js-xds/src/generated/envoy/type/SemanticVersion.ts diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index fcb9279f0..124c3ed7d 100644 --- a/packages/grpc-js-xds/package.json +++ b/packages/grpc-js-xds/package.json @@ -12,7 +12,7 @@ "prepare": "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/v2/ads.proto envoy/service/load_stats/v2/lrs.proto 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", + "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", "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" }, "repository": { @@ -56,7 +56,6 @@ "src/**/*.ts", "build/src/**/*.{js,d.ts,js.map}", "deps/envoy-api/envoy/admin/v3/**/*.proto", - "deps/envoy-api/envoy/api/v2/**/*.proto", "deps/envoy-api/envoy/config/**/*.proto", "deps/envoy-api/envoy/service/**/*.proto", "deps/envoy-api/envoy/type/**/*.proto", diff --git a/packages/grpc-js-xds/src/generated/ads.ts b/packages/grpc-js-xds/src/generated/ads.ts index e0e46bb25..228f6f1d4 100644 --- a/packages/grpc-js-xds/src/generated/ads.ts +++ b/packages/grpc-js-xds/src/generated/ads.ts @@ -1,7 +1,6 @@ import type * as grpc from '@grpc/grpc-js'; import type { EnumTypeDefinition, MessageTypeDefinition } from '@grpc/proto-loader'; -import type { AggregatedDiscoveryServiceClient as _envoy_service_discovery_v2_AggregatedDiscoveryServiceClient, AggregatedDiscoveryServiceDefinition as _envoy_service_discovery_v2_AggregatedDiscoveryServiceDefinition } from './envoy/service/discovery/v2/AggregatedDiscoveryService'; import type { AggregatedDiscoveryServiceClient as _envoy_service_discovery_v3_AggregatedDiscoveryServiceClient, AggregatedDiscoveryServiceDefinition as _envoy_service_discovery_v3_AggregatedDiscoveryServiceDefinition } from './envoy/service/discovery/v3/AggregatedDiscoveryService'; type SubtypeConstructor any, Subtype> = { @@ -12,47 +11,6 @@ export interface ProtoGrpcType { envoy: { annotations: { } - api: { - v2: { - DeltaDiscoveryRequest: MessageTypeDefinition - DeltaDiscoveryResponse: MessageTypeDefinition - DiscoveryRequest: MessageTypeDefinition - DiscoveryResponse: MessageTypeDefinition - Resource: MessageTypeDefinition - core: { - Address: MessageTypeDefinition - AsyncDataSource: MessageTypeDefinition - BackoffStrategy: MessageTypeDefinition - BindConfig: MessageTypeDefinition - BuildVersion: MessageTypeDefinition - CidrRange: MessageTypeDefinition - ControlPlane: MessageTypeDefinition - DataSource: MessageTypeDefinition - Extension: MessageTypeDefinition - HeaderMap: MessageTypeDefinition - HeaderValue: MessageTypeDefinition - HeaderValueOption: MessageTypeDefinition - HttpUri: MessageTypeDefinition - Locality: MessageTypeDefinition - Metadata: MessageTypeDefinition - Node: MessageTypeDefinition - Pipe: MessageTypeDefinition - RemoteDataSource: MessageTypeDefinition - RequestMethod: EnumTypeDefinition - RetryPolicy: MessageTypeDefinition - RoutingPriority: EnumTypeDefinition - RuntimeDouble: MessageTypeDefinition - RuntimeFeatureFlag: MessageTypeDefinition - RuntimeFractionalPercent: MessageTypeDefinition - RuntimeUInt32: MessageTypeDefinition - SocketAddress: MessageTypeDefinition - SocketOption: MessageTypeDefinition - TcpKeepalive: MessageTypeDefinition - TrafficDirection: EnumTypeDefinition - TransportSocket: MessageTypeDefinition - } - } - } config: { core: { v3: { @@ -95,18 +53,6 @@ export interface ProtoGrpcType { } service: { discovery: { - v2: { - AdsDummy: MessageTypeDefinition - /** - * See https://github.com/lyft/envoy-api#apis for a description of the role of - * ADS and how it is intended to be used by a management server. ADS requests - * have the same structure as their singleton xDS counterparts, but can - * multiplex many resource types on a single stream. The type_url in the - * DiscoveryRequest/DiscoveryResponse provides sufficient information to recover - * the multiplexed singleton APIs at the Envoy instance and management server. - */ - AggregatedDiscoveryService: SubtypeConstructor & { service: _envoy_service_discovery_v2_AggregatedDiscoveryServiceDefinition } - } v3: { AdsDummy: MessageTypeDefinition /** @@ -127,9 +73,6 @@ export interface ProtoGrpcType { } } type: { - FractionalPercent: MessageTypeDefinition - Percent: MessageTypeDefinition - SemanticVersion: MessageTypeDefinition v3: { FractionalPercent: MessageTypeDefinition Percent: MessageTypeDefinition diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/DeltaDiscoveryRequest.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/DeltaDiscoveryRequest.ts deleted file mode 100644 index 20ddb1b14..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/DeltaDiscoveryRequest.ts +++ /dev/null @@ -1,202 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/discovery.proto - -import type { Node as _envoy_api_v2_core_Node, Node__Output as _envoy_api_v2_core_Node__Output } from '../../../envoy/api/v2/core/Node'; -import type { Status as _google_rpc_Status, Status__Output as _google_rpc_Status__Output } from '../../../google/rpc/Status'; - -/** - * DeltaDiscoveryRequest and DeltaDiscoveryResponse are used in a new gRPC - * endpoint for Delta xDS. - * - * With Delta xDS, the DeltaDiscoveryResponses do not need to include a full - * snapshot of the tracked resources. Instead, DeltaDiscoveryResponses are a - * diff to the state of a xDS client. - * In Delta XDS there are per-resource versions, which allow tracking state at - * the resource granularity. - * An xDS Delta session is always in the context of a gRPC bidirectional - * stream. This allows the xDS server to keep track of the state of xDS clients - * connected to it. - * - * In Delta xDS the nonce field is required and used to pair - * DeltaDiscoveryResponse to a DeltaDiscoveryRequest ACK or NACK. - * Optionally, a response message level system_version_info is present for - * debugging purposes only. - * - * DeltaDiscoveryRequest plays two independent roles. Any DeltaDiscoveryRequest - * can be either or both of: [1] informing the server of what resources the - * client has gained/lost interest in (using resource_names_subscribe and - * resource_names_unsubscribe), or [2] (N)ACKing an earlier resource update from - * the server (using response_nonce, with presence of error_detail making it a NACK). - * Additionally, the first message (for a given type_url) of a reconnected gRPC stream - * has a third role: informing the server of the resources (and their versions) - * that the client already possesses, using the initial_resource_versions field. - * - * As with state-of-the-world, when multiple resource types are multiplexed (ADS), - * all requests/acknowledgments/updates are logically walled off by type_url: - * a Cluster ACK exists in a completely separate world from a prior Route NACK. - * In particular, initial_resource_versions being sent at the "start" of every - * gRPC stream actually entails a message for each type_url, each with its own - * initial_resource_versions. - * [#next-free-field: 8] - */ -export interface DeltaDiscoveryRequest { - /** - * The node making the request. - */ - 'node'?: (_envoy_api_v2_core_Node | null); - /** - * Type of the resource that is being requested, e.g. - * "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment". - */ - 'type_url'?: (string); - /** - * DeltaDiscoveryRequests allow the client to add or remove individual - * resources to the set of tracked resources in the context of a stream. - * All resource names in the resource_names_subscribe list are added to the - * set of tracked resources and all resource names in the resource_names_unsubscribe - * list are removed from the set of tracked resources. - * - * *Unlike* state-of-the-world xDS, an empty resource_names_subscribe or - * resource_names_unsubscribe list simply means that no resources are to be - * added or removed to the resource list. - * *Like* state-of-the-world xDS, the server must send updates for all tracked - * resources, but can also send updates for resources the client has not subscribed to. - * - * NOTE: the server must respond with all resources listed in resource_names_subscribe, - * even if it believes the client has the most recent version of them. The reason: - * the client may have dropped them, but then regained interest before it had a chance - * to send the unsubscribe message. See DeltaSubscriptionStateTest.RemoveThenAdd. - * - * These two fields can be set in any DeltaDiscoveryRequest, including ACKs - * and initial_resource_versions. - * - * A list of Resource names to add to the list of tracked resources. - */ - 'resource_names_subscribe'?: (string)[]; - /** - * A list of Resource names to remove from the list of tracked resources. - */ - 'resource_names_unsubscribe'?: (string)[]; - /** - * Informs the server of the versions of the resources the xDS client knows of, to enable the - * client to continue the same logical xDS session even in the face of gRPC stream reconnection. - * It will not be populated: [1] in the very first stream of a session, since the client will - * not yet have any resources, [2] in any message after the first in a stream (for a given - * type_url), since the server will already be correctly tracking the client's state. - * (In ADS, the first message *of each type_url* of a reconnected stream populates this map.) - * The map's keys are names of xDS resources known to the xDS client. - * The map's values are opaque resource versions. - */ - 'initial_resource_versions'?: ({[key: string]: string}); - /** - * When the DeltaDiscoveryRequest is a ACK or NACK message in response - * to a previous DeltaDiscoveryResponse, the response_nonce must be the - * nonce in the DeltaDiscoveryResponse. - * Otherwise (unlike in DiscoveryRequest) response_nonce must be omitted. - */ - 'response_nonce'?: (string); - /** - * This is populated when the previous :ref:`DiscoveryResponse ` - * failed to update configuration. The *message* field in *error_details* - * provides the Envoy internal exception related to the failure. - */ - 'error_detail'?: (_google_rpc_Status | null); -} - -/** - * DeltaDiscoveryRequest and DeltaDiscoveryResponse are used in a new gRPC - * endpoint for Delta xDS. - * - * With Delta xDS, the DeltaDiscoveryResponses do not need to include a full - * snapshot of the tracked resources. Instead, DeltaDiscoveryResponses are a - * diff to the state of a xDS client. - * In Delta XDS there are per-resource versions, which allow tracking state at - * the resource granularity. - * An xDS Delta session is always in the context of a gRPC bidirectional - * stream. This allows the xDS server to keep track of the state of xDS clients - * connected to it. - * - * In Delta xDS the nonce field is required and used to pair - * DeltaDiscoveryResponse to a DeltaDiscoveryRequest ACK or NACK. - * Optionally, a response message level system_version_info is present for - * debugging purposes only. - * - * DeltaDiscoveryRequest plays two independent roles. Any DeltaDiscoveryRequest - * can be either or both of: [1] informing the server of what resources the - * client has gained/lost interest in (using resource_names_subscribe and - * resource_names_unsubscribe), or [2] (N)ACKing an earlier resource update from - * the server (using response_nonce, with presence of error_detail making it a NACK). - * Additionally, the first message (for a given type_url) of a reconnected gRPC stream - * has a third role: informing the server of the resources (and their versions) - * that the client already possesses, using the initial_resource_versions field. - * - * As with state-of-the-world, when multiple resource types are multiplexed (ADS), - * all requests/acknowledgments/updates are logically walled off by type_url: - * a Cluster ACK exists in a completely separate world from a prior Route NACK. - * In particular, initial_resource_versions being sent at the "start" of every - * gRPC stream actually entails a message for each type_url, each with its own - * initial_resource_versions. - * [#next-free-field: 8] - */ -export interface DeltaDiscoveryRequest__Output { - /** - * The node making the request. - */ - 'node': (_envoy_api_v2_core_Node__Output | null); - /** - * Type of the resource that is being requested, e.g. - * "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment". - */ - 'type_url': (string); - /** - * DeltaDiscoveryRequests allow the client to add or remove individual - * resources to the set of tracked resources in the context of a stream. - * All resource names in the resource_names_subscribe list are added to the - * set of tracked resources and all resource names in the resource_names_unsubscribe - * list are removed from the set of tracked resources. - * - * *Unlike* state-of-the-world xDS, an empty resource_names_subscribe or - * resource_names_unsubscribe list simply means that no resources are to be - * added or removed to the resource list. - * *Like* state-of-the-world xDS, the server must send updates for all tracked - * resources, but can also send updates for resources the client has not subscribed to. - * - * NOTE: the server must respond with all resources listed in resource_names_subscribe, - * even if it believes the client has the most recent version of them. The reason: - * the client may have dropped them, but then regained interest before it had a chance - * to send the unsubscribe message. See DeltaSubscriptionStateTest.RemoveThenAdd. - * - * These two fields can be set in any DeltaDiscoveryRequest, including ACKs - * and initial_resource_versions. - * - * A list of Resource names to add to the list of tracked resources. - */ - 'resource_names_subscribe': (string)[]; - /** - * A list of Resource names to remove from the list of tracked resources. - */ - 'resource_names_unsubscribe': (string)[]; - /** - * Informs the server of the versions of the resources the xDS client knows of, to enable the - * client to continue the same logical xDS session even in the face of gRPC stream reconnection. - * It will not be populated: [1] in the very first stream of a session, since the client will - * not yet have any resources, [2] in any message after the first in a stream (for a given - * type_url), since the server will already be correctly tracking the client's state. - * (In ADS, the first message *of each type_url* of a reconnected stream populates this map.) - * The map's keys are names of xDS resources known to the xDS client. - * The map's values are opaque resource versions. - */ - 'initial_resource_versions': ({[key: string]: string}); - /** - * When the DeltaDiscoveryRequest is a ACK or NACK message in response - * to a previous DeltaDiscoveryResponse, the response_nonce must be the - * nonce in the DeltaDiscoveryResponse. - * Otherwise (unlike in DiscoveryRequest) response_nonce must be omitted. - */ - 'response_nonce': (string); - /** - * This is populated when the previous :ref:`DiscoveryResponse ` - * failed to update configuration. The *message* field in *error_details* - * provides the Envoy internal exception related to the failure. - */ - 'error_detail': (_google_rpc_Status__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/DeltaDiscoveryResponse.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/DeltaDiscoveryResponse.ts deleted file mode 100644 index 1a2584b95..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/DeltaDiscoveryResponse.ts +++ /dev/null @@ -1,63 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/discovery.proto - -import type { Resource as _envoy_api_v2_Resource, Resource__Output as _envoy_api_v2_Resource__Output } from '../../../envoy/api/v2/Resource'; - -/** - * [#next-free-field: 7] - */ -export interface DeltaDiscoveryResponse { - /** - * The version of the response data (used for debugging). - */ - 'system_version_info'?: (string); - /** - * The response resources. These are typed resources, whose types must match - * the type_url field. - */ - 'resources'?: (_envoy_api_v2_Resource)[]; - /** - * Type URL for resources. Identifies the xDS API when muxing over ADS. - * Must be consistent with the type_url in the Any within 'resources' if 'resources' is non-empty. - */ - 'type_url'?: (string); - /** - * The nonce provides a way for DeltaDiscoveryRequests to uniquely - * reference a DeltaDiscoveryResponse when (N)ACKing. The nonce is required. - */ - 'nonce'?: (string); - /** - * Resources names of resources that have be deleted and to be removed from the xDS Client. - * Removed resources for missing resources can be ignored. - */ - 'removed_resources'?: (string)[]; -} - -/** - * [#next-free-field: 7] - */ -export interface DeltaDiscoveryResponse__Output { - /** - * The version of the response data (used for debugging). - */ - 'system_version_info': (string); - /** - * The response resources. These are typed resources, whose types must match - * the type_url field. - */ - 'resources': (_envoy_api_v2_Resource__Output)[]; - /** - * Type URL for resources. Identifies the xDS API when muxing over ADS. - * Must be consistent with the type_url in the Any within 'resources' if 'resources' is non-empty. - */ - 'type_url': (string); - /** - * The nonce provides a way for DeltaDiscoveryRequests to uniquely - * reference a DeltaDiscoveryResponse when (N)ACKing. The nonce is required. - */ - 'nonce': (string); - /** - * Resources names of resources that have be deleted and to be removed from the xDS Client. - * Removed resources for missing resources can be ignored. - */ - 'removed_resources': (string)[]; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/DiscoveryRequest.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/DiscoveryRequest.ts deleted file mode 100644 index 2386e71c4..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/DiscoveryRequest.ts +++ /dev/null @@ -1,110 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/discovery.proto - -import type { Node as _envoy_api_v2_core_Node, Node__Output as _envoy_api_v2_core_Node__Output } from '../../../envoy/api/v2/core/Node'; -import type { Status as _google_rpc_Status, Status__Output as _google_rpc_Status__Output } from '../../../google/rpc/Status'; - -/** - * A DiscoveryRequest requests a set of versioned resources of the same type for - * a given Envoy node on some API. - * [#next-free-field: 7] - */ -export interface DiscoveryRequest { - /** - * The version_info provided in the request messages will be the version_info - * received with the most recent successfully processed response or empty on - * the first request. It is expected that no new request is sent after a - * response is received until the Envoy instance is ready to ACK/NACK the new - * configuration. ACK/NACK takes place by returning the new API config version - * as applied or the previous API config version respectively. Each type_url - * (see below) has an independent version associated with it. - */ - 'version_info'?: (string); - /** - * The node making the request. - */ - 'node'?: (_envoy_api_v2_core_Node | null); - /** - * List of resources to subscribe to, e.g. list of cluster names or a route - * configuration name. If this is empty, all resources for the API are - * returned. LDS/CDS may have empty resource_names, which will cause all - * resources for the Envoy instance to be returned. The LDS and CDS responses - * will then imply a number of resources that need to be fetched via EDS/RDS, - * which will be explicitly enumerated in resource_names. - */ - 'resource_names'?: (string)[]; - /** - * Type of the resource that is being requested, e.g. - * "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment". This is implicit - * in requests made via singleton xDS APIs such as CDS, LDS, etc. but is - * required for ADS. - */ - 'type_url'?: (string); - /** - * nonce corresponding to DiscoveryResponse being ACK/NACKed. See above - * discussion on version_info and the DiscoveryResponse nonce comment. This - * may be empty only if 1) this is a non-persistent-stream xDS such as HTTP, - * or 2) the client has not yet accepted an update in this xDS stream (unlike - * delta, where it is populated only for new explicit ACKs). - */ - 'response_nonce'?: (string); - /** - * This is populated when the previous :ref:`DiscoveryResponse ` - * failed to update configuration. The *message* field in *error_details* provides the Envoy - * internal exception related to the failure. It is only intended for consumption during manual - * debugging, the string provided is not guaranteed to be stable across Envoy versions. - */ - 'error_detail'?: (_google_rpc_Status | null); -} - -/** - * A DiscoveryRequest requests a set of versioned resources of the same type for - * a given Envoy node on some API. - * [#next-free-field: 7] - */ -export interface DiscoveryRequest__Output { - /** - * The version_info provided in the request messages will be the version_info - * received with the most recent successfully processed response or empty on - * the first request. It is expected that no new request is sent after a - * response is received until the Envoy instance is ready to ACK/NACK the new - * configuration. ACK/NACK takes place by returning the new API config version - * as applied or the previous API config version respectively. Each type_url - * (see below) has an independent version associated with it. - */ - 'version_info': (string); - /** - * The node making the request. - */ - 'node': (_envoy_api_v2_core_Node__Output | null); - /** - * List of resources to subscribe to, e.g. list of cluster names or a route - * configuration name. If this is empty, all resources for the API are - * returned. LDS/CDS may have empty resource_names, which will cause all - * resources for the Envoy instance to be returned. The LDS and CDS responses - * will then imply a number of resources that need to be fetched via EDS/RDS, - * which will be explicitly enumerated in resource_names. - */ - 'resource_names': (string)[]; - /** - * Type of the resource that is being requested, e.g. - * "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment". This is implicit - * in requests made via singleton xDS APIs such as CDS, LDS, etc. but is - * required for ADS. - */ - 'type_url': (string); - /** - * nonce corresponding to DiscoveryResponse being ACK/NACKed. See above - * discussion on version_info and the DiscoveryResponse nonce comment. This - * may be empty only if 1) this is a non-persistent-stream xDS such as HTTP, - * or 2) the client has not yet accepted an update in this xDS stream (unlike - * delta, where it is populated only for new explicit ACKs). - */ - 'response_nonce': (string); - /** - * This is populated when the previous :ref:`DiscoveryResponse ` - * failed to update configuration. The *message* field in *error_details* provides the Envoy - * internal exception related to the failure. It is only intended for consumption during manual - * debugging, the string provided is not guaranteed to be stable across Envoy versions. - */ - 'error_detail': (_google_rpc_Status__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/DiscoveryResponse.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/DiscoveryResponse.ts deleted file mode 100644 index 179143c67..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/DiscoveryResponse.ts +++ /dev/null @@ -1,108 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/discovery.proto - -import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any'; -import type { ControlPlane as _envoy_api_v2_core_ControlPlane, ControlPlane__Output as _envoy_api_v2_core_ControlPlane__Output } from '../../../envoy/api/v2/core/ControlPlane'; - -/** - * [#next-free-field: 7] - */ -export interface DiscoveryResponse { - /** - * The version of the response data. - */ - 'version_info'?: (string); - /** - * The response resources. These resources are typed and depend on the API being called. - */ - 'resources'?: (_google_protobuf_Any)[]; - /** - * [#not-implemented-hide:] - * Canary is used to support two Envoy command line flags: - * - * * --terminate-on-canary-transition-failure. When set, Envoy is able to - * terminate if it detects that configuration is stuck at canary. Consider - * this example sequence of updates: - * - Management server applies a canary config successfully. - * - Management server rolls back to a production config. - * - Envoy rejects the new production config. - * Since there is no sensible way to continue receiving configuration - * updates, Envoy will then terminate and apply production config from a - * clean slate. - * * --dry-run-canary. When set, a canary response will never be applied, only - * validated via a dry run. - */ - 'canary'?: (boolean); - /** - * Type URL for resources. Identifies the xDS API when muxing over ADS. - * Must be consistent with the type_url in the 'resources' repeated Any (if non-empty). - */ - 'type_url'?: (string); - /** - * For gRPC based subscriptions, the nonce provides a way to explicitly ack a - * specific DiscoveryResponse in a following DiscoveryRequest. Additional - * messages may have been sent by Envoy to the management server for the - * previous version on the stream prior to this DiscoveryResponse, that were - * unprocessed at response send time. The nonce allows the management server - * to ignore any further DiscoveryRequests for the previous version until a - * DiscoveryRequest bearing the nonce. The nonce is optional and is not - * required for non-stream based xDS implementations. - */ - 'nonce'?: (string); - /** - * [#not-implemented-hide:] - * The control plane instance that sent the response. - */ - 'control_plane'?: (_envoy_api_v2_core_ControlPlane | null); -} - -/** - * [#next-free-field: 7] - */ -export interface DiscoveryResponse__Output { - /** - * The version of the response data. - */ - 'version_info': (string); - /** - * The response resources. These resources are typed and depend on the API being called. - */ - 'resources': (_google_protobuf_Any__Output)[]; - /** - * [#not-implemented-hide:] - * Canary is used to support two Envoy command line flags: - * - * * --terminate-on-canary-transition-failure. When set, Envoy is able to - * terminate if it detects that configuration is stuck at canary. Consider - * this example sequence of updates: - * - Management server applies a canary config successfully. - * - Management server rolls back to a production config. - * - Envoy rejects the new production config. - * Since there is no sensible way to continue receiving configuration - * updates, Envoy will then terminate and apply production config from a - * clean slate. - * * --dry-run-canary. When set, a canary response will never be applied, only - * validated via a dry run. - */ - 'canary': (boolean); - /** - * Type URL for resources. Identifies the xDS API when muxing over ADS. - * Must be consistent with the type_url in the 'resources' repeated Any (if non-empty). - */ - 'type_url': (string); - /** - * For gRPC based subscriptions, the nonce provides a way to explicitly ack a - * specific DiscoveryResponse in a following DiscoveryRequest. Additional - * messages may have been sent by Envoy to the management server for the - * previous version on the stream prior to this DiscoveryResponse, that were - * unprocessed at response send time. The nonce allows the management server - * to ignore any further DiscoveryRequests for the previous version until a - * DiscoveryRequest bearing the nonce. The nonce is optional and is not - * required for non-stream based xDS implementations. - */ - 'nonce': (string); - /** - * [#not-implemented-hide:] - * The control plane instance that sent the response. - */ - 'control_plane': (_envoy_api_v2_core_ControlPlane__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/Resource.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/Resource.ts deleted file mode 100644 index 6ce856ee7..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/Resource.ts +++ /dev/null @@ -1,43 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/discovery.proto - -import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any'; - -export interface Resource { - /** - * The resource level version. It allows xDS to track the state of individual - * resources. - */ - 'version'?: (string); - /** - * The resource being tracked. - */ - 'resource'?: (_google_protobuf_Any | null); - /** - * The resource's name, to distinguish it from others of the same type of resource. - */ - 'name'?: (string); - /** - * The aliases are a list of other names that this resource can go by. - */ - 'aliases'?: (string)[]; -} - -export interface Resource__Output { - /** - * The resource level version. It allows xDS to track the state of individual - * resources. - */ - 'version': (string); - /** - * The resource being tracked. - */ - 'resource': (_google_protobuf_Any__Output | null); - /** - * The resource's name, to distinguish it from others of the same type of resource. - */ - 'name': (string); - /** - * The aliases are a list of other names that this resource can go by. - */ - 'aliases': (string)[]; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Address.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Address.ts deleted file mode 100644 index 65044b74a..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Address.ts +++ /dev/null @@ -1,26 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/address.proto - -import type { SocketAddress as _envoy_api_v2_core_SocketAddress, SocketAddress__Output as _envoy_api_v2_core_SocketAddress__Output } from '../../../../envoy/api/v2/core/SocketAddress'; -import type { Pipe as _envoy_api_v2_core_Pipe, Pipe__Output as _envoy_api_v2_core_Pipe__Output } from '../../../../envoy/api/v2/core/Pipe'; - -/** - * Addresses specify either a logical or physical address and port, which are - * used to tell Envoy where to bind/listen, connect to upstream and find - * management servers. - */ -export interface Address { - 'socket_address'?: (_envoy_api_v2_core_SocketAddress | null); - 'pipe'?: (_envoy_api_v2_core_Pipe | null); - 'address'?: "socket_address"|"pipe"; -} - -/** - * Addresses specify either a logical or physical address and port, which are - * used to tell Envoy where to bind/listen, connect to upstream and find - * management servers. - */ -export interface Address__Output { - 'socket_address'?: (_envoy_api_v2_core_SocketAddress__Output | null); - 'pipe'?: (_envoy_api_v2_core_Pipe__Output | null); - 'address': "socket_address"|"pipe"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/AsyncDataSource.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/AsyncDataSource.ts deleted file mode 100644 index 139f82689..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/AsyncDataSource.ts +++ /dev/null @@ -1,34 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - -import type { DataSource as _envoy_api_v2_core_DataSource, DataSource__Output as _envoy_api_v2_core_DataSource__Output } from '../../../../envoy/api/v2/core/DataSource'; -import type { RemoteDataSource as _envoy_api_v2_core_RemoteDataSource, RemoteDataSource__Output as _envoy_api_v2_core_RemoteDataSource__Output } from '../../../../envoy/api/v2/core/RemoteDataSource'; - -/** - * Async data source which support async data fetch. - */ -export interface AsyncDataSource { - /** - * Local async data source. - */ - 'local'?: (_envoy_api_v2_core_DataSource | null); - /** - * Remote async data source. - */ - 'remote'?: (_envoy_api_v2_core_RemoteDataSource | null); - 'specifier'?: "local"|"remote"; -} - -/** - * Async data source which support async data fetch. - */ -export interface AsyncDataSource__Output { - /** - * Local async data source. - */ - 'local'?: (_envoy_api_v2_core_DataSource__Output | null); - /** - * Remote async data source. - */ - 'remote'?: (_envoy_api_v2_core_RemoteDataSource__Output | null); - 'specifier': "local"|"remote"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BackoffStrategy.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BackoffStrategy.ts deleted file mode 100644 index 173aff0e1..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BackoffStrategy.ts +++ /dev/null @@ -1,43 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/backoff.proto - -import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; - -/** - * Configuration defining a jittered exponential back off strategy. - */ -export interface BackoffStrategy { - /** - * The base interval to be used for the next back off computation. It should - * be greater than zero and less than or equal to :ref:`max_interval - * `. - */ - 'base_interval'?: (_google_protobuf_Duration | null); - /** - * Specifies the maximum interval between retries. This parameter is optional, - * but must be greater than or equal to the :ref:`base_interval - * ` if set. The default - * is 10 times the :ref:`base_interval - * `. - */ - 'max_interval'?: (_google_protobuf_Duration | null); -} - -/** - * Configuration defining a jittered exponential back off strategy. - */ -export interface BackoffStrategy__Output { - /** - * The base interval to be used for the next back off computation. It should - * be greater than zero and less than or equal to :ref:`max_interval - * `. - */ - 'base_interval': (_google_protobuf_Duration__Output | null); - /** - * Specifies the maximum interval between retries. This parameter is optional, - * but must be greater than or equal to the :ref:`base_interval - * ` if set. The default - * is 10 times the :ref:`base_interval - * `. - */ - 'max_interval': (_google_protobuf_Duration__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BindConfig.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BindConfig.ts deleted file mode 100644 index d4765c1ba..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BindConfig.ts +++ /dev/null @@ -1,49 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/address.proto - -import type { SocketAddress as _envoy_api_v2_core_SocketAddress, SocketAddress__Output as _envoy_api_v2_core_SocketAddress__Output } from '../../../../envoy/api/v2/core/SocketAddress'; -import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; -import type { SocketOption as _envoy_api_v2_core_SocketOption, SocketOption__Output as _envoy_api_v2_core_SocketOption__Output } from '../../../../envoy/api/v2/core/SocketOption'; - -export interface BindConfig { - /** - * The address to bind to when creating a socket. - */ - 'source_address'?: (_envoy_api_v2_core_SocketAddress | null); - /** - * Whether to set the *IP_FREEBIND* option when creating the socket. When this - * flag is set to true, allows the :ref:`source_address - * ` to be an IP address - * that is not configured on the system running Envoy. When this flag is set - * to false, the option *IP_FREEBIND* is disabled on the socket. When this - * flag is not set (default), the socket is not modified, i.e. the option is - * neither enabled nor disabled. - */ - 'freebind'?: (_google_protobuf_BoolValue | null); - /** - * Additional socket options that may not be present in Envoy source code or - * precompiled binaries. - */ - 'socket_options'?: (_envoy_api_v2_core_SocketOption)[]; -} - -export interface BindConfig__Output { - /** - * The address to bind to when creating a socket. - */ - 'source_address': (_envoy_api_v2_core_SocketAddress__Output | null); - /** - * Whether to set the *IP_FREEBIND* option when creating the socket. When this - * flag is set to true, allows the :ref:`source_address - * ` to be an IP address - * that is not configured on the system running Envoy. When this flag is set - * to false, the option *IP_FREEBIND* is disabled on the socket. When this - * flag is not set (default), the socket is not modified, i.e. the option is - * neither enabled nor disabled. - */ - 'freebind': (_google_protobuf_BoolValue__Output | null); - /** - * Additional socket options that may not be present in Envoy source code or - * precompiled binaries. - */ - 'socket_options': (_envoy_api_v2_core_SocketOption__Output)[]; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BuildVersion.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BuildVersion.ts deleted file mode 100644 index a33015d89..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/BuildVersion.ts +++ /dev/null @@ -1,36 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - -import type { SemanticVersion as _envoy_type_SemanticVersion, SemanticVersion__Output as _envoy_type_SemanticVersion__Output } from '../../../../envoy/type/SemanticVersion'; -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; - -/** - * BuildVersion combines SemVer version of extension with free-form build information - * (i.e. 'alpha', 'private-build') as a set of strings. - */ -export interface BuildVersion { - /** - * SemVer version of extension. - */ - 'version'?: (_envoy_type_SemanticVersion | null); - /** - * Free-form build information. - * Envoy defines several well known keys in the source/common/version/version.h file - */ - 'metadata'?: (_google_protobuf_Struct | null); -} - -/** - * BuildVersion combines SemVer version of extension with free-form build information - * (i.e. 'alpha', 'private-build') as a set of strings. - */ -export interface BuildVersion__Output { - /** - * SemVer version of extension. - */ - 'version': (_envoy_type_SemanticVersion__Output | null); - /** - * Free-form build information. - * Envoy defines several well known keys in the source/common/version/version.h file - */ - 'metadata': (_google_protobuf_Struct__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/CidrRange.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/CidrRange.ts deleted file mode 100644 index 5e1df8a13..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/CidrRange.ts +++ /dev/null @@ -1,33 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/address.proto - -import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; - -/** - * CidrRange specifies an IP Address and a prefix length to construct - * the subnet mask for a `CIDR `_ range. - */ -export interface CidrRange { - /** - * IPv4 or IPv6 address, e.g. ``192.0.0.0`` or ``2001:db8::``. - */ - 'address_prefix'?: (string); - /** - * Length of prefix, e.g. 0, 32. Defaults to 0 when unset. - */ - 'prefix_len'?: (_google_protobuf_UInt32Value | null); -} - -/** - * CidrRange specifies an IP Address and a prefix length to construct - * the subnet mask for a `CIDR `_ range. - */ -export interface CidrRange__Output { - /** - * IPv4 or IPv6 address, e.g. ``192.0.0.0`` or ``2001:db8::``. - */ - 'address_prefix': (string); - /** - * Length of prefix, e.g. 0, 32. Defaults to 0 when unset. - */ - 'prefix_len': (_google_protobuf_UInt32Value__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/ControlPlane.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/ControlPlane.ts deleted file mode 100644 index 551f693a2..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/ControlPlane.ts +++ /dev/null @@ -1,26 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - - -/** - * Identifies a specific ControlPlane instance that Envoy is connected to. - */ -export interface ControlPlane { - /** - * An opaque control plane identifier that uniquely identifies an instance - * of control plane. This can be used to identify which control plane instance, - * the Envoy is connected to. - */ - 'identifier'?: (string); -} - -/** - * Identifies a specific ControlPlane instance that Envoy is connected to. - */ -export interface ControlPlane__Output { - /** - * An opaque control plane identifier that uniquely identifies an instance - * of control plane. This can be used to identify which control plane instance, - * the Envoy is connected to. - */ - 'identifier': (string); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/DataSource.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/DataSource.ts deleted file mode 100644 index a04100054..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/DataSource.ts +++ /dev/null @@ -1,40 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - - -/** - * Data source consisting of either a file or an inline value. - */ -export interface DataSource { - /** - * Local filesystem data source. - */ - 'filename'?: (string); - /** - * Bytes inlined in the configuration. - */ - 'inline_bytes'?: (Buffer | Uint8Array | string); - /** - * String inlined in the configuration. - */ - 'inline_string'?: (string); - 'specifier'?: "filename"|"inline_bytes"|"inline_string"; -} - -/** - * Data source consisting of either a file or an inline value. - */ -export interface DataSource__Output { - /** - * Local filesystem data source. - */ - 'filename'?: (string); - /** - * Bytes inlined in the configuration. - */ - 'inline_bytes'?: (Buffer); - /** - * String inlined in the configuration. - */ - 'inline_string'?: (string); - 'specifier': "filename"|"inline_bytes"|"inline_string"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Extension.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Extension.ts deleted file mode 100644 index 67c5e1736..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Extension.ts +++ /dev/null @@ -1,75 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - -import type { BuildVersion as _envoy_api_v2_core_BuildVersion, BuildVersion__Output as _envoy_api_v2_core_BuildVersion__Output } from '../../../../envoy/api/v2/core/BuildVersion'; - -/** - * Version and identification for an Envoy extension. - * [#next-free-field: 6] - */ -export interface Extension { - /** - * This is the name of the Envoy filter as specified in the Envoy - * configuration, e.g. envoy.filters.http.router, com.acme.widget. - */ - 'name'?: (string); - /** - * Category of the extension. - * Extension category names use reverse DNS notation. For instance "envoy.filters.listener" - * for Envoy's built-in listener filters or "com.acme.filters.http" for HTTP filters from - * acme.com vendor. - * [#comment:TODO(yanavlasov): Link to the doc with existing envoy category names.] - */ - 'category'?: (string); - /** - * [#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.] - */ - 'type_descriptor'?: (string); - /** - * The version is a property of the extension and maintained independently - * of other extensions and the Envoy API. - * This field is not set when extension did not provide version information. - */ - 'version'?: (_envoy_api_v2_core_BuildVersion | null); - /** - * Indicates that the extension is present but was disabled via dynamic configuration. - */ - 'disabled'?: (boolean); -} - -/** - * Version and identification for an Envoy extension. - * [#next-free-field: 6] - */ -export interface Extension__Output { - /** - * This is the name of the Envoy filter as specified in the Envoy - * configuration, e.g. envoy.filters.http.router, com.acme.widget. - */ - 'name': (string); - /** - * Category of the extension. - * Extension category names use reverse DNS notation. For instance "envoy.filters.listener" - * for Envoy's built-in listener filters or "com.acme.filters.http" for HTTP filters from - * acme.com vendor. - * [#comment:TODO(yanavlasov): Link to the doc with existing envoy category names.] - */ - 'category': (string); - /** - * [#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.] - */ - 'type_descriptor': (string); - /** - * The version is a property of the extension and maintained independently - * of other extensions and the Envoy API. - * This field is not set when extension did not provide version information. - */ - 'version': (_envoy_api_v2_core_BuildVersion__Output | null); - /** - * Indicates that the extension is present but was disabled via dynamic configuration. - */ - 'disabled': (boolean); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HeaderMap.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HeaderMap.ts deleted file mode 100644 index e093d4761..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HeaderMap.ts +++ /dev/null @@ -1,17 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - -import type { HeaderValue as _envoy_api_v2_core_HeaderValue, HeaderValue__Output as _envoy_api_v2_core_HeaderValue__Output } from '../../../../envoy/api/v2/core/HeaderValue'; - -/** - * Wrapper for a set of headers. - */ -export interface HeaderMap { - 'headers'?: (_envoy_api_v2_core_HeaderValue)[]; -} - -/** - * Wrapper for a set of headers. - */ -export interface HeaderMap__Output { - 'headers': (_envoy_api_v2_core_HeaderValue__Output)[]; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HeaderValue.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HeaderValue.ts deleted file mode 100644 index b36605324..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HeaderValue.ts +++ /dev/null @@ -1,38 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - - -/** - * Header name/value pair. - */ -export interface HeaderValue { - /** - * Header name. - */ - 'key'?: (string); - /** - * Header value. - * - * The same :ref:`format specifier ` as used for - * :ref:`HTTP access logging ` applies here, however - * unknown header values are replaced with the empty string instead of `-`. - */ - 'value'?: (string); -} - -/** - * Header name/value pair. - */ -export interface HeaderValue__Output { - /** - * Header name. - */ - 'key': (string); - /** - * Header value. - * - * The same :ref:`format specifier ` as used for - * :ref:`HTTP access logging ` applies here, however - * unknown header values are replaced with the empty string instead of `-`. - */ - 'value': (string); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HeaderValueOption.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HeaderValueOption.ts deleted file mode 100644 index 12421d8f4..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HeaderValueOption.ts +++ /dev/null @@ -1,34 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - -import type { HeaderValue as _envoy_api_v2_core_HeaderValue, HeaderValue__Output as _envoy_api_v2_core_HeaderValue__Output } from '../../../../envoy/api/v2/core/HeaderValue'; -import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; - -/** - * Header name/value pair plus option to control append behavior. - */ -export interface HeaderValueOption { - /** - * Header name/value pair that this option applies to. - */ - 'header'?: (_envoy_api_v2_core_HeaderValue | null); - /** - * Should the value be appended? If true (default), the value is appended to - * existing values. - */ - 'append'?: (_google_protobuf_BoolValue | null); -} - -/** - * Header name/value pair plus option to control append behavior. - */ -export interface HeaderValueOption__Output { - /** - * Header name/value pair that this option applies to. - */ - 'header': (_envoy_api_v2_core_HeaderValue__Output | null); - /** - * Should the value be appended? If true (default), the value is appended to - * existing values. - */ - 'append': (_google_protobuf_BoolValue__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HttpUri.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HttpUri.ts deleted file mode 100644 index c206a2454..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/HttpUri.ts +++ /dev/null @@ -1,79 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/http_uri.proto - -import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; - -/** - * Envoy external URI descriptor - */ -export interface HttpUri { - /** - * The HTTP server URI. It should be a full FQDN with protocol, host and path. - * - * Example: - * - * .. code-block:: yaml - * - * uri: https://www.googleapis.com/oauth2/v1/certs - */ - 'uri'?: (string); - /** - * A cluster is created in the Envoy "cluster_manager" config - * section. This field specifies the cluster name. - * - * Example: - * - * .. code-block:: yaml - * - * cluster: jwks_cluster - */ - 'cluster'?: (string); - /** - * Sets the maximum duration in milliseconds that a response can take to arrive upon request. - */ - 'timeout'?: (_google_protobuf_Duration | null); - /** - * Specify how `uri` is to be fetched. Today, this requires an explicit - * cluster, but in the future we may support dynamic cluster creation or - * inline DNS resolution. See `issue - * `_. - */ - 'http_upstream_type'?: "cluster"; -} - -/** - * Envoy external URI descriptor - */ -export interface HttpUri__Output { - /** - * The HTTP server URI. It should be a full FQDN with protocol, host and path. - * - * Example: - * - * .. code-block:: yaml - * - * uri: https://www.googleapis.com/oauth2/v1/certs - */ - 'uri': (string); - /** - * A cluster is created in the Envoy "cluster_manager" config - * section. This field specifies the cluster name. - * - * Example: - * - * .. code-block:: yaml - * - * cluster: jwks_cluster - */ - 'cluster'?: (string); - /** - * Sets the maximum duration in milliseconds that a response can take to arrive upon request. - */ - 'timeout': (_google_protobuf_Duration__Output | null); - /** - * Specify how `uri` is to be fetched. Today, this requires an explicit - * cluster, but in the future we may support dynamic cluster creation or - * inline DNS resolution. See `issue - * `_. - */ - 'http_upstream_type': "cluster"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Locality.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Locality.ts deleted file mode 100644 index 49fb232a4..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Locality.ts +++ /dev/null @@ -1,56 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - - -/** - * Identifies location of where either Envoy runs or where upstream hosts run. - */ -export interface Locality { - /** - * Region this :ref:`zone ` belongs to. - */ - 'region'?: (string); - /** - * Defines the local service zone where Envoy is running. Though optional, it - * should be set if discovery service routing is used and the discovery - * service exposes :ref:`zone data `, - * either in this message or via :option:`--service-zone`. The meaning of zone - * is context dependent, e.g. `Availability Zone (AZ) - * `_ - * on AWS, `Zone `_ on - * GCP, etc. - */ - 'zone'?: (string); - /** - * When used for locality of upstream hosts, this field further splits zone - * into smaller chunks of sub-zones so they can be load balanced - * independently. - */ - 'sub_zone'?: (string); -} - -/** - * Identifies location of where either Envoy runs or where upstream hosts run. - */ -export interface Locality__Output { - /** - * Region this :ref:`zone ` belongs to. - */ - 'region': (string); - /** - * Defines the local service zone where Envoy is running. Though optional, it - * should be set if discovery service routing is used and the discovery - * service exposes :ref:`zone data `, - * either in this message or via :option:`--service-zone`. The meaning of zone - * is context dependent, e.g. `Availability Zone (AZ) - * `_ - * on AWS, `Zone `_ on - * GCP, etc. - */ - 'zone': (string); - /** - * When used for locality of upstream hosts, this field further splits zone - * into smaller chunks of sub-zones so they can be load balanced - * independently. - */ - 'sub_zone': (string); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Metadata.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Metadata.ts deleted file mode 100644 index 7a6871eeb..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Metadata.ts +++ /dev/null @@ -1,67 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; - -/** - * Metadata provides additional inputs to filters based on matched listeners, - * filter chains, routes and endpoints. It is structured as a map, usually from - * filter name (in reverse DNS format) to metadata specific to the filter. Metadata - * key-values for a filter are merged as connection and request handling occurs, - * with later values for the same key overriding earlier values. - * - * An example use of metadata is providing additional values to - * http_connection_manager in the envoy.http_connection_manager.access_log - * namespace. - * - * Another example use of metadata is to per service config info in cluster metadata, which may get - * consumed by multiple filters. - * - * For load balancing, Metadata provides a means to subset cluster endpoints. - * Endpoints have a Metadata object associated and routes contain a Metadata - * object to match against. There are some well defined metadata used today for - * this purpose: - * - * * ``{"envoy.lb": {"canary": }}`` This indicates the canary status of an - * endpoint and is also used during header processing - * (x-envoy-upstream-canary) and for stats purposes. - * [#next-major-version: move to type/metadata/v2] - */ -export interface Metadata { - /** - * Key is the reverse DNS filter name, e.g. com.acme.widget. The envoy.* - * namespace is reserved for Envoy's built-in filters. - */ - 'filter_metadata'?: ({[key: string]: _google_protobuf_Struct}); -} - -/** - * Metadata provides additional inputs to filters based on matched listeners, - * filter chains, routes and endpoints. It is structured as a map, usually from - * filter name (in reverse DNS format) to metadata specific to the filter. Metadata - * key-values for a filter are merged as connection and request handling occurs, - * with later values for the same key overriding earlier values. - * - * An example use of metadata is providing additional values to - * http_connection_manager in the envoy.http_connection_manager.access_log - * namespace. - * - * Another example use of metadata is to per service config info in cluster metadata, which may get - * consumed by multiple filters. - * - * For load balancing, Metadata provides a means to subset cluster endpoints. - * Endpoints have a Metadata object associated and routes contain a Metadata - * object to match against. There are some well defined metadata used today for - * this purpose: - * - * * ``{"envoy.lb": {"canary": }}`` This indicates the canary status of an - * endpoint and is also used during header processing - * (x-envoy-upstream-canary) and for stats purposes. - * [#next-major-version: move to type/metadata/v2] - */ -export interface Metadata__Output { - /** - * Key is the reverse DNS filter name, e.g. com.acme.widget. The envoy.* - * namespace is reserved for Envoy's built-in filters. - */ - 'filter_metadata': ({[key: string]: _google_protobuf_Struct__Output}); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Node.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Node.ts deleted file mode 100644 index ddf10f08b..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Node.ts +++ /dev/null @@ -1,173 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; -import type { Locality as _envoy_api_v2_core_Locality, Locality__Output as _envoy_api_v2_core_Locality__Output } from '../../../../envoy/api/v2/core/Locality'; -import type { BuildVersion as _envoy_api_v2_core_BuildVersion, BuildVersion__Output as _envoy_api_v2_core_BuildVersion__Output } from '../../../../envoy/api/v2/core/BuildVersion'; -import type { Extension as _envoy_api_v2_core_Extension, Extension__Output as _envoy_api_v2_core_Extension__Output } from '../../../../envoy/api/v2/core/Extension'; -import type { Address as _envoy_api_v2_core_Address, Address__Output as _envoy_api_v2_core_Address__Output } from '../../../../envoy/api/v2/core/Address'; - -/** - * Identifies a specific Envoy instance. The node identifier is presented to the - * management server, which may use this identifier to distinguish per Envoy - * configuration for serving. - * [#next-free-field: 12] - */ -export interface Node { - /** - * An opaque node identifier for the Envoy node. This also provides the local - * service node name. It should be set if any of the following features are - * used: :ref:`statsd `, :ref:`CDS - * `, and :ref:`HTTP tracing - * `, either in this message or via - * :option:`--service-node`. - */ - 'id'?: (string); - /** - * Defines the local service cluster name where Envoy is running. Though - * optional, it should be set if any of the following features are used: - * :ref:`statsd `, :ref:`health check cluster - * verification - * `, - * :ref:`runtime override directory `, - * :ref:`user agent addition - * `, - * :ref:`HTTP global rate limiting `, - * :ref:`CDS `, and :ref:`HTTP tracing - * `, either in this message or via - * :option:`--service-cluster`. - */ - 'cluster'?: (string); - /** - * Opaque metadata extending the node identifier. Envoy will pass this - * directly to the management server. - */ - 'metadata'?: (_google_protobuf_Struct | null); - /** - * Locality specifying where the Envoy instance is running. - */ - 'locality'?: (_envoy_api_v2_core_Locality | null); - /** - * This is motivated by informing a management server during canary which - * version of Envoy is being tested in a heterogeneous fleet. This will be set - * by Envoy in management server RPCs. - * This field is deprecated in favor of the user_agent_name and user_agent_version values. - */ - 'build_version'?: (string); - /** - * Free-form string that identifies the entity requesting config. - * E.g. "envoy" or "grpc" - */ - 'user_agent_name'?: (string); - /** - * Free-form string that identifies the version of the entity requesting config. - * E.g. "1.12.2" or "abcd1234", or "SpecialEnvoyBuild" - */ - 'user_agent_version'?: (string); - /** - * Structured version of the entity requesting config. - */ - 'user_agent_build_version'?: (_envoy_api_v2_core_BuildVersion | null); - /** - * List of extensions and their versions supported by the node. - */ - 'extensions'?: (_envoy_api_v2_core_Extension)[]; - /** - * Client feature support list. These are well known features described - * in the Envoy API repository for a given major version of an API. Client features - * use reverse DNS naming scheme, for example `com.acme.feature`. - * See :ref:`the list of features ` that xDS client may - * support. - */ - 'client_features'?: (string)[]; - /** - * Known listening ports on the node as a generic hint to the management server - * 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. - */ - 'listening_addresses'?: (_envoy_api_v2_core_Address)[]; - 'user_agent_version_type'?: "user_agent_version"|"user_agent_build_version"; -} - -/** - * Identifies a specific Envoy instance. The node identifier is presented to the - * management server, which may use this identifier to distinguish per Envoy - * configuration for serving. - * [#next-free-field: 12] - */ -export interface Node__Output { - /** - * An opaque node identifier for the Envoy node. This also provides the local - * service node name. It should be set if any of the following features are - * used: :ref:`statsd `, :ref:`CDS - * `, and :ref:`HTTP tracing - * `, either in this message or via - * :option:`--service-node`. - */ - 'id': (string); - /** - * Defines the local service cluster name where Envoy is running. Though - * optional, it should be set if any of the following features are used: - * :ref:`statsd `, :ref:`health check cluster - * verification - * `, - * :ref:`runtime override directory `, - * :ref:`user agent addition - * `, - * :ref:`HTTP global rate limiting `, - * :ref:`CDS `, and :ref:`HTTP tracing - * `, either in this message or via - * :option:`--service-cluster`. - */ - 'cluster': (string); - /** - * Opaque metadata extending the node identifier. Envoy will pass this - * directly to the management server. - */ - 'metadata': (_google_protobuf_Struct__Output | null); - /** - * Locality specifying where the Envoy instance is running. - */ - 'locality': (_envoy_api_v2_core_Locality__Output | null); - /** - * This is motivated by informing a management server during canary which - * version of Envoy is being tested in a heterogeneous fleet. This will be set - * by Envoy in management server RPCs. - * This field is deprecated in favor of the user_agent_name and user_agent_version values. - */ - 'build_version': (string); - /** - * Free-form string that identifies the entity requesting config. - * E.g. "envoy" or "grpc" - */ - 'user_agent_name': (string); - /** - * Free-form string that identifies the version of the entity requesting config. - * E.g. "1.12.2" or "abcd1234", or "SpecialEnvoyBuild" - */ - 'user_agent_version'?: (string); - /** - * Structured version of the entity requesting config. - */ - 'user_agent_build_version'?: (_envoy_api_v2_core_BuildVersion__Output | null); - /** - * List of extensions and their versions supported by the node. - */ - 'extensions': (_envoy_api_v2_core_Extension__Output)[]; - /** - * Client feature support list. These are well known features described - * in the Envoy API repository for a given major version of an API. Client features - * use reverse DNS naming scheme, for example `com.acme.feature`. - * See :ref:`the list of features ` that xDS client may - * support. - */ - 'client_features': (string)[]; - /** - * Known listening ports on the node as a generic hint to the management server - * 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. - */ - 'listening_addresses': (_envoy_api_v2_core_Address__Output)[]; - 'user_agent_version_type': "user_agent_version"|"user_agent_build_version"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Pipe.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Pipe.ts deleted file mode 100644 index 9e6cbb82d..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/Pipe.ts +++ /dev/null @@ -1,30 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/address.proto - - -export interface Pipe { - /** - * Unix Domain Socket path. On Linux, paths starting with '@' will use the - * abstract namespace. The starting '@' is replaced by a null byte by Envoy. - * Paths starting with '@' will result in an error in environments other than - * Linux. - */ - 'path'?: (string); - /** - * The mode for the Pipe. Not applicable for abstract sockets. - */ - 'mode'?: (number); -} - -export interface Pipe__Output { - /** - * Unix Domain Socket path. On Linux, paths starting with '@' will use the - * abstract namespace. The starting '@' is replaced by a null byte by Envoy. - * Paths starting with '@' will result in an error in environments other than - * Linux. - */ - 'path': (string); - /** - * The mode for the Pipe. Not applicable for abstract sockets. - */ - 'mode': (number); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RemoteDataSource.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RemoteDataSource.ts deleted file mode 100644 index 516dbf864..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RemoteDataSource.ts +++ /dev/null @@ -1,40 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - -import type { HttpUri as _envoy_api_v2_core_HttpUri, HttpUri__Output as _envoy_api_v2_core_HttpUri__Output } from '../../../../envoy/api/v2/core/HttpUri'; -import type { RetryPolicy as _envoy_api_v2_core_RetryPolicy, RetryPolicy__Output as _envoy_api_v2_core_RetryPolicy__Output } from '../../../../envoy/api/v2/core/RetryPolicy'; - -/** - * The message specifies how to fetch data from remote and how to verify it. - */ -export interface RemoteDataSource { - /** - * The HTTP URI to fetch the remote data. - */ - 'http_uri'?: (_envoy_api_v2_core_HttpUri | null); - /** - * SHA256 string for verifying data. - */ - 'sha256'?: (string); - /** - * Retry policy for fetching remote data. - */ - 'retry_policy'?: (_envoy_api_v2_core_RetryPolicy | null); -} - -/** - * The message specifies how to fetch data from remote and how to verify it. - */ -export interface RemoteDataSource__Output { - /** - * The HTTP URI to fetch the remote data. - */ - 'http_uri': (_envoy_api_v2_core_HttpUri__Output | null); - /** - * SHA256 string for verifying data. - */ - 'sha256': (string); - /** - * Retry policy for fetching remote data. - */ - 'retry_policy': (_envoy_api_v2_core_RetryPolicy__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RequestMethod.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RequestMethod.ts deleted file mode 100644 index 029e9882d..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RequestMethod.ts +++ /dev/null @@ -1,17 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - -/** - * 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, -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RetryPolicy.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RetryPolicy.ts deleted file mode 100644 index 7ff35e375..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RetryPolicy.ts +++ /dev/null @@ -1,38 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - -import type { BackoffStrategy as _envoy_api_v2_core_BackoffStrategy, BackoffStrategy__Output as _envoy_api_v2_core_BackoffStrategy__Output } from '../../../../envoy/api/v2/core/BackoffStrategy'; -import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; - -/** - * The message specifies the retry policy of remote data source when fetching fails. - */ -export interface RetryPolicy { - /** - * Specifies parameters that control :ref:`retry backoff strategy `. - * This parameter is optional, in which case the default base interval is 1000 milliseconds. The - * default maximum interval is 10 times the base interval. - */ - 'retry_back_off'?: (_envoy_api_v2_core_BackoffStrategy | null); - /** - * Specifies the allowed number of retries. This parameter is optional and - * defaults to 1. - */ - 'num_retries'?: (_google_protobuf_UInt32Value | null); -} - -/** - * The message specifies the retry policy of remote data source when fetching fails. - */ -export interface RetryPolicy__Output { - /** - * Specifies parameters that control :ref:`retry backoff strategy `. - * This parameter is optional, in which case the default base interval is 1000 milliseconds. The - * default maximum interval is 10 times the base interval. - */ - 'retry_back_off': (_envoy_api_v2_core_BackoffStrategy__Output | null); - /** - * Specifies the allowed number of retries. This parameter is optional and - * defaults to 1. - */ - 'num_retries': (_google_protobuf_UInt32Value__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RoutingPriority.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RoutingPriority.ts deleted file mode 100644 index 5937fceb2..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RoutingPriority.ts +++ /dev/null @@ -1,15 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - -/** - * 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 enum RoutingPriority { - DEFAULT = 0, - HIGH = 1, -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeDouble.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeDouble.ts deleted file mode 100644 index 1ea2b8146..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeDouble.ts +++ /dev/null @@ -1,30 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - - -/** - * Runtime derived double with a default when not specified. - */ -export interface RuntimeDouble { - /** - * Default value if runtime value is not available. - */ - 'default_value'?: (number | string); - /** - * Runtime key to get value for comparison. This value is used if defined. - */ - 'runtime_key'?: (string); -} - -/** - * Runtime derived double with a default when not specified. - */ -export interface RuntimeDouble__Output { - /** - * Default value if runtime value is not available. - */ - 'default_value': (number); - /** - * Runtime key to get value for comparison. This value is used if defined. - */ - 'runtime_key': (string); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeFeatureFlag.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeFeatureFlag.ts deleted file mode 100644 index 4ad57de46..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeFeatureFlag.ts +++ /dev/null @@ -1,35 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - -import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from '../../../../google/protobuf/BoolValue'; - -/** - * Runtime derived bool with a default when not specified. - */ -export interface RuntimeFeatureFlag { - /** - * Default value if runtime value is not available. - */ - 'default_value'?: (_google_protobuf_BoolValue | null); - /** - * Runtime key to get value for comparison. This value is used if defined. The boolean value must - * be represented via its - * `canonical JSON encoding `_. - */ - 'runtime_key'?: (string); -} - -/** - * Runtime derived bool with a default when not specified. - */ -export interface RuntimeFeatureFlag__Output { - /** - * Default value if runtime value is not available. - */ - 'default_value': (_google_protobuf_BoolValue__Output | null); - /** - * Runtime key to get value for comparison. This value is used if defined. The boolean value must - * be represented via its - * `canonical JSON encoding `_. - */ - 'runtime_key': (string); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeFractionalPercent.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeFractionalPercent.ts deleted file mode 100644 index a168af60c..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeFractionalPercent.ts +++ /dev/null @@ -1,49 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - -import type { FractionalPercent as _envoy_type_FractionalPercent, FractionalPercent__Output as _envoy_type_FractionalPercent__Output } from '../../../../envoy/type/FractionalPercent'; - -/** - * Runtime derived FractionalPercent with defaults for when the numerator or denominator is not - * specified via a runtime key. - * - * .. note:: - * - * Parsing of the runtime key's data is implemented such that it may be represented as a - * :ref:`FractionalPercent ` proto represented as JSON/YAML - * and may also be represented as an integer with the assumption that the value is an integral - * percentage out of 100. For instance, a runtime key lookup returning the value "42" would parse - * as a `FractionalPercent` whose numerator is 42 and denominator is HUNDRED. - */ -export interface RuntimeFractionalPercent { - /** - * Default value if the runtime value's for the numerator/denominator keys are not available. - */ - 'default_value'?: (_envoy_type_FractionalPercent | null); - /** - * Runtime key for a YAML representation of a FractionalPercent. - */ - 'runtime_key'?: (string); -} - -/** - * Runtime derived FractionalPercent with defaults for when the numerator or denominator is not - * specified via a runtime key. - * - * .. note:: - * - * Parsing of the runtime key's data is implemented such that it may be represented as a - * :ref:`FractionalPercent ` proto represented as JSON/YAML - * and may also be represented as an integer with the assumption that the value is an integral - * percentage out of 100. For instance, a runtime key lookup returning the value "42" would parse - * as a `FractionalPercent` whose numerator is 42 and denominator is HUNDRED. - */ -export interface RuntimeFractionalPercent__Output { - /** - * Default value if the runtime value's for the numerator/denominator keys are not available. - */ - 'default_value': (_envoy_type_FractionalPercent__Output | null); - /** - * Runtime key for a YAML representation of a FractionalPercent. - */ - 'runtime_key': (string); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeUInt32.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeUInt32.ts deleted file mode 100644 index 72e8972a4..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/RuntimeUInt32.ts +++ /dev/null @@ -1,30 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - - -/** - * Runtime derived uint32 with a default when not specified. - */ -export interface RuntimeUInt32 { - /** - * Default value if runtime value is not available. - */ - 'default_value'?: (number); - /** - * Runtime key to get value for comparison. This value is used if defined. - */ - 'runtime_key'?: (string); -} - -/** - * Runtime derived uint32 with a default when not specified. - */ -export interface RuntimeUInt32__Output { - /** - * Default value if runtime value is not available. - */ - 'default_value': (number); - /** - * Runtime key to get value for comparison. This value is used if defined. - */ - 'runtime_key': (string); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/SocketAddress.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/SocketAddress.ts deleted file mode 100644 index f81c981c1..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/SocketAddress.ts +++ /dev/null @@ -1,97 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/address.proto - - -// Original file: deps/envoy-api/envoy/api/v2/core/address.proto - -export enum _envoy_api_v2_core_SocketAddress_Protocol { - TCP = 0, - UDP = 1, -} - -/** - * [#next-free-field: 7] - */ -export interface SocketAddress { - 'protocol'?: (_envoy_api_v2_core_SocketAddress_Protocol | keyof typeof _envoy_api_v2_core_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 ``::`` - * to bind to any address. [#comment:TODO(zuercher) reinstate when implemented: - * It is possible to distinguish a Listener address via the prefix/suffix matching - * in :ref:`FilterChainMatch `.] When used - * within an upstream :ref:`BindConfig `, the address - * controls the source address of outbound connections. For :ref:`clusters - * `, the cluster type determines whether the - * address must be an IP (*STATIC* or *EDS* clusters) or a hostname resolved by DNS - * (*STRICT_DNS* or *LOGICAL_DNS* clusters). Address resolution can be customized - * via :ref:`resolver_name `. - */ - 'address'?: (string); - 'port_value'?: (number); - /** - * This is only valid if :ref:`resolver_name - * ` is specified below and the - * named resolver is capable of named port resolution. - */ - 'named_port'?: (string); - /** - * The name of the custom resolver. This must have been registered with Envoy. If - * this is empty, a context dependent default applies. If the address is a concrete - * IP address, no resolution will occur. If address is a hostname this - * should be set for resolution other than DNS. Specifying a custom resolver with - * *STRICT_DNS* or *LOGICAL_DNS* will generate an error at runtime. - */ - 'resolver_name'?: (string); - /** - * When binding to an IPv6 address above, this enables `IPv4 compatibility - * `_. Binding to ``::`` will - * allow both IPv4 and IPv6 connections, with peer IPv4 addresses mapped into - * IPv6 space as ``::FFFF:``. - */ - 'ipv4_compat'?: (boolean); - 'port_specifier'?: "port_value"|"named_port"; -} - -/** - * [#next-free-field: 7] - */ -export interface SocketAddress__Output { - 'protocol': (keyof typeof _envoy_api_v2_core_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 ``::`` - * to bind to any address. [#comment:TODO(zuercher) reinstate when implemented: - * It is possible to distinguish a Listener address via the prefix/suffix matching - * in :ref:`FilterChainMatch `.] When used - * within an upstream :ref:`BindConfig `, the address - * controls the source address of outbound connections. For :ref:`clusters - * `, the cluster type determines whether the - * address must be an IP (*STATIC* or *EDS* clusters) or a hostname resolved by DNS - * (*STRICT_DNS* or *LOGICAL_DNS* clusters). Address resolution can be customized - * via :ref:`resolver_name `. - */ - 'address': (string); - 'port_value'?: (number); - /** - * This is only valid if :ref:`resolver_name - * ` is specified below and the - * named resolver is capable of named port resolution. - */ - 'named_port'?: (string); - /** - * The name of the custom resolver. This must have been registered with Envoy. If - * this is empty, a context dependent default applies. If the address is a concrete - * IP address, no resolution will occur. If address is a hostname this - * should be set for resolution other than DNS. Specifying a custom resolver with - * *STRICT_DNS* or *LOGICAL_DNS* will generate an error at runtime. - */ - 'resolver_name': (string); - /** - * When binding to an IPv6 address above, this enables `IPv4 compatibility - * `_. Binding to ``::`` will - * allow both IPv4 and IPv6 connections, with peer IPv4 addresses mapped into - * IPv6 space as ``::FFFF:``. - */ - 'ipv4_compat': (boolean); - 'port_specifier': "port_value"|"named_port"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/SocketOption.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/SocketOption.ts deleted file mode 100644 index 4a32e46b4..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/SocketOption.ts +++ /dev/null @@ -1,90 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/socket_option.proto - -import type { Long } from '@grpc/proto-loader'; - -// Original file: deps/envoy-api/envoy/api/v2/core/socket_option.proto - -export enum _envoy_api_v2_core_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, -} - -/** - * Generic socket option message. This would be used to set socket options that - * might not exist in upstream kernels or precompiled Envoy binaries. - * [#next-free-field: 7] - */ -export interface SocketOption { - /** - * An optional name to give this socket option for debugging, etc. - * Uniqueness is not required and no special meaning is assumed. - */ - 'description'?: (string); - /** - * Corresponding to the level value passed to setsockopt, such as IPPROTO_TCP - */ - 'level'?: (number | string | Long); - /** - * The numeric name as passed to setsockopt - */ - 'name'?: (number | string | Long); - /** - * Because many sockopts take an int value. - */ - 'int_value'?: (number | string | Long); - /** - * Otherwise it's a byte buffer. - */ - 'buf_value'?: (Buffer | Uint8Array | string); - /** - * The state in which the option will be applied. When used in BindConfig - * STATE_PREBIND is currently the only valid value. - */ - 'state'?: (_envoy_api_v2_core_SocketOption_SocketState | keyof typeof _envoy_api_v2_core_SocketOption_SocketState); - 'value'?: "int_value"|"buf_value"; -} - -/** - * Generic socket option message. This would be used to set socket options that - * might not exist in upstream kernels or precompiled Envoy binaries. - * [#next-free-field: 7] - */ -export interface SocketOption__Output { - /** - * An optional name to give this socket option for debugging, etc. - * Uniqueness is not required and no special meaning is assumed. - */ - 'description': (string); - /** - * Corresponding to the level value passed to setsockopt, such as IPPROTO_TCP - */ - 'level': (string); - /** - * The numeric name as passed to setsockopt - */ - 'name': (string); - /** - * Because many sockopts take an int value. - */ - 'int_value'?: (string); - /** - * Otherwise it's a byte buffer. - */ - 'buf_value'?: (Buffer); - /** - * 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_api_v2_core_SocketOption_SocketState); - 'value': "int_value"|"buf_value"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/TcpKeepalive.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/TcpKeepalive.ts deleted file mode 100644 index e9d805c76..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/TcpKeepalive.ts +++ /dev/null @@ -1,43 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/address.proto - -import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from '../../../../google/protobuf/UInt32Value'; - -export interface TcpKeepalive { - /** - * Maximum number of keepalive probes to send without response before deciding - * the connection is dead. Default is to use the OS level configuration (unless - * overridden, Linux defaults to 9.) - */ - 'keepalive_probes'?: (_google_protobuf_UInt32Value | null); - /** - * The number of seconds a connection needs to be idle before keep-alive probes - * start being sent. Default is to use the OS level configuration (unless - * overridden, Linux defaults to 7200s (i.e., 2 hours.) - */ - 'keepalive_time'?: (_google_protobuf_UInt32Value | null); - /** - * The number of seconds between keep-alive probes. Default is to use the OS - * level configuration (unless overridden, Linux defaults to 75s.) - */ - 'keepalive_interval'?: (_google_protobuf_UInt32Value | null); -} - -export interface TcpKeepalive__Output { - /** - * Maximum number of keepalive probes to send without response before deciding - * the connection is dead. Default is to use the OS level configuration (unless - * overridden, Linux defaults to 9.) - */ - 'keepalive_probes': (_google_protobuf_UInt32Value__Output | null); - /** - * The number of seconds a connection needs to be idle before keep-alive probes - * start being sent. Default is to use the OS level configuration (unless - * overridden, Linux defaults to 7200s (i.e., 2 hours.) - */ - 'keepalive_time': (_google_protobuf_UInt32Value__Output | null); - /** - * The number of seconds between keep-alive probes. Default is to use the OS - * level configuration (unless overridden, Linux defaults to 75s.) - */ - 'keepalive_interval': (_google_protobuf_UInt32Value__Output | null); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/TrafficDirection.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/TrafficDirection.ts deleted file mode 100644 index 41cf36523..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/TrafficDirection.ts +++ /dev/null @@ -1,19 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - -/** - * Identifies the direction of the traffic relative to the local Envoy. - */ -export enum 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, -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/TransportSocket.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/core/TransportSocket.ts deleted file mode 100644 index 87fbcaf38..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/core/TransportSocket.ts +++ /dev/null @@ -1,46 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/core/base.proto - -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; -import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../../google/protobuf/Any'; - -/** - * Configuration for transport socket in :ref:`listeners ` and - * :ref:`clusters `. If the configuration is - * empty, a default transport socket implementation and configuration will be - * chosen based on the platform and existence of tls_context. - */ -export interface TransportSocket { - /** - * The name of the transport socket to instantiate. The name must match a supported transport - * socket implementation. - */ - 'name'?: (string); - 'config'?: (_google_protobuf_Struct | null); - 'typed_config'?: (_google_protobuf_Any | null); - /** - * Implementation specific configuration which depends on the implementation being instantiated. - * See the supported transport socket implementations for further documentation. - */ - 'config_type'?: "config"|"typed_config"; -} - -/** - * Configuration for transport socket in :ref:`listeners ` and - * :ref:`clusters `. If the configuration is - * empty, a default transport socket implementation and configuration will be - * chosen based on the platform and existence of tls_context. - */ -export interface TransportSocket__Output { - /** - * The name of the transport socket to instantiate. The name must match a supported transport - * socket implementation. - */ - 'name': (string); - 'config'?: (_google_protobuf_Struct__Output | null); - 'typed_config'?: (_google_protobuf_Any__Output | null); - /** - * Implementation specific configuration which depends on the implementation being instantiated. - * See the supported transport socket implementations for further documentation. - */ - 'config_type': "config"|"typed_config"; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/ClusterStats.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/ClusterStats.ts deleted file mode 100644 index 3609ea1e4..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/ClusterStats.ts +++ /dev/null @@ -1,117 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/endpoint/load_report.proto - -import type { UpstreamLocalityStats as _envoy_api_v2_endpoint_UpstreamLocalityStats, UpstreamLocalityStats__Output as _envoy_api_v2_endpoint_UpstreamLocalityStats__Output } from '../../../../envoy/api/v2/endpoint/UpstreamLocalityStats'; -import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; -import type { Long } from '@grpc/proto-loader'; - -export interface _envoy_api_v2_endpoint_ClusterStats_DroppedRequests { - /** - * Identifier for the policy specifying the drop. - */ - 'category'?: (string); - /** - * Total number of deliberately dropped requests for the category. - */ - 'dropped_count'?: (number | string | Long); -} - -export interface _envoy_api_v2_endpoint_ClusterStats_DroppedRequests__Output { - /** - * Identifier for the policy specifying the drop. - */ - 'category': (string); - /** - * Total number of deliberately dropped requests for the category. - */ - 'dropped_count': (string); -} - -/** - * Per cluster load stats. Envoy reports these stats a management server in a - * :ref:`LoadStatsRequest` - * [#not-implemented-hide:] Not configuration. TBD how to doc proto APIs. - * Next ID: 7 - * [#next-free-field: 7] - */ -export interface ClusterStats { - /** - * The name of the cluster. - */ - 'cluster_name'?: (string); - /** - * Need at least one. - */ - 'upstream_locality_stats'?: (_envoy_api_v2_endpoint_UpstreamLocalityStats)[]; - /** - * Cluster-level stats such as total_successful_requests may be computed by - * summing upstream_locality_stats. In addition, below there are additional - * cluster-wide stats. - * - * The total number of dropped requests. This covers requests - * deliberately dropped by the drop_overload policy and circuit breaking. - */ - 'total_dropped_requests'?: (number | string | Long); - /** - * Period over which the actual load report occurred. This will be guaranteed to include every - * request reported. Due to system load and delays between the *LoadStatsRequest* sent from Envoy - * and the *LoadStatsResponse* message sent from the management server, this may be longer than - * the requested load reporting interval in the *LoadStatsResponse*. - */ - 'load_report_interval'?: (_google_protobuf_Duration | null); - /** - * Information about deliberately dropped requests for each category specified - * in the DropOverload policy. - */ - 'dropped_requests'?: (_envoy_api_v2_endpoint_ClusterStats_DroppedRequests)[]; - /** - * The eds_cluster_config service_name of the cluster. - * It's possible that two clusters send the same service_name to EDS, - * in that case, the management server is supposed to do aggregation on the load reports. - */ - 'cluster_service_name'?: (string); -} - -/** - * Per cluster load stats. Envoy reports these stats a management server in a - * :ref:`LoadStatsRequest` - * [#not-implemented-hide:] Not configuration. TBD how to doc proto APIs. - * Next ID: 7 - * [#next-free-field: 7] - */ -export interface ClusterStats__Output { - /** - * The name of the cluster. - */ - 'cluster_name': (string); - /** - * Need at least one. - */ - 'upstream_locality_stats': (_envoy_api_v2_endpoint_UpstreamLocalityStats__Output)[]; - /** - * Cluster-level stats such as total_successful_requests may be computed by - * summing upstream_locality_stats. In addition, below there are additional - * cluster-wide stats. - * - * The total number of dropped requests. This covers requests - * deliberately dropped by the drop_overload policy and circuit breaking. - */ - 'total_dropped_requests': (string); - /** - * Period over which the actual load report occurred. This will be guaranteed to include every - * request reported. Due to system load and delays between the *LoadStatsRequest* sent from Envoy - * and the *LoadStatsResponse* message sent from the management server, this may be longer than - * the requested load reporting interval in the *LoadStatsResponse*. - */ - 'load_report_interval': (_google_protobuf_Duration__Output | null); - /** - * Information about deliberately dropped requests for each category specified - * in the DropOverload policy. - */ - 'dropped_requests': (_envoy_api_v2_endpoint_ClusterStats_DroppedRequests__Output)[]; - /** - * The eds_cluster_config service_name of the cluster. - * It's possible that two clusters send the same service_name to EDS, - * in that case, the management server is supposed to do aggregation on the load reports. - */ - 'cluster_service_name': (string); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/EndpointLoadMetricStats.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/EndpointLoadMetricStats.ts deleted file mode 100644 index 335b759b6..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/EndpointLoadMetricStats.ts +++ /dev/null @@ -1,41 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/endpoint/load_report.proto - -import type { Long } from '@grpc/proto-loader'; - -/** - * [#not-implemented-hide:] Not configuration. TBD how to doc proto APIs. - */ -export interface EndpointLoadMetricStats { - /** - * Name of the metric; may be empty. - */ - 'metric_name'?: (string); - /** - * Number of calls that finished and included this metric. - */ - 'num_requests_finished_with_metric'?: (number | string | Long); - /** - * Sum of metric values across all calls that finished with this metric for - * load_reporting_interval. - */ - 'total_metric_value'?: (number | string); -} - -/** - * [#not-implemented-hide:] Not configuration. TBD how to doc proto APIs. - */ -export interface EndpointLoadMetricStats__Output { - /** - * Name of the metric; may be empty. - */ - 'metric_name': (string); - /** - * Number of calls that finished and included this metric. - */ - 'num_requests_finished_with_metric': (string); - /** - * Sum of metric values across all calls that finished with this metric for - * load_reporting_interval. - */ - 'total_metric_value': (number); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/UpstreamEndpointStats.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/UpstreamEndpointStats.ts deleted file mode 100644 index e4551bd37..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/UpstreamEndpointStats.ts +++ /dev/null @@ -1,106 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/endpoint/load_report.proto - -import type { Address as _envoy_api_v2_core_Address, Address__Output as _envoy_api_v2_core_Address__Output } from '../../../../envoy/api/v2/core/Address'; -import type { EndpointLoadMetricStats as _envoy_api_v2_endpoint_EndpointLoadMetricStats, EndpointLoadMetricStats__Output as _envoy_api_v2_endpoint_EndpointLoadMetricStats__Output } from '../../../../envoy/api/v2/endpoint/EndpointLoadMetricStats'; -import type { Struct as _google_protobuf_Struct, Struct__Output as _google_protobuf_Struct__Output } from '../../../../google/protobuf/Struct'; -import type { Long } from '@grpc/proto-loader'; - -/** - * [#not-implemented-hide:] Not configuration. TBD how to doc proto APIs. - * [#next-free-field: 8] - */ -export interface UpstreamEndpointStats { - /** - * Upstream host address. - */ - 'address'?: (_envoy_api_v2_core_Address | null); - /** - * The total number of requests successfully completed by the endpoints in the - * locality. These include non-5xx responses for HTTP, where errors - * originate at the client and the endpoint responded successfully. For gRPC, - * the grpc-status values are those not covered by total_error_requests below. - */ - 'total_successful_requests'?: (number | string | Long); - /** - * The total number of unfinished requests for this endpoint. - */ - 'total_requests_in_progress'?: (number | string | Long); - /** - * The total number of requests that failed due to errors at the endpoint. - * For HTTP these are responses with 5xx status codes and for gRPC the - * grpc-status values: - * - * - DeadlineExceeded - * - Unimplemented - * - Internal - * - Unavailable - * - Unknown - * - DataLoss - */ - 'total_error_requests'?: (number | string | Long); - /** - * Stats for multi-dimensional load balancing. - */ - 'load_metric_stats'?: (_envoy_api_v2_endpoint_EndpointLoadMetricStats)[]; - /** - * Opaque and implementation dependent metadata of the - * endpoint. Envoy will pass this directly to the management server. - */ - 'metadata'?: (_google_protobuf_Struct | null); - /** - * The total number of requests that were issued to this endpoint - * since the last report. A single TCP connection, HTTP or gRPC - * request or stream is counted as one request. - */ - 'total_issued_requests'?: (number | string | Long); -} - -/** - * [#not-implemented-hide:] Not configuration. TBD how to doc proto APIs. - * [#next-free-field: 8] - */ -export interface UpstreamEndpointStats__Output { - /** - * Upstream host address. - */ - 'address': (_envoy_api_v2_core_Address__Output | null); - /** - * The total number of requests successfully completed by the endpoints in the - * locality. These include non-5xx responses for HTTP, where errors - * originate at the client and the endpoint responded successfully. For gRPC, - * the grpc-status values are those not covered by total_error_requests below. - */ - 'total_successful_requests': (string); - /** - * The total number of unfinished requests for this endpoint. - */ - 'total_requests_in_progress': (string); - /** - * The total number of requests that failed due to errors at the endpoint. - * For HTTP these are responses with 5xx status codes and for gRPC the - * grpc-status values: - * - * - DeadlineExceeded - * - Unimplemented - * - Internal - * - Unavailable - * - Unknown - * - DataLoss - */ - 'total_error_requests': (string); - /** - * Stats for multi-dimensional load balancing. - */ - 'load_metric_stats': (_envoy_api_v2_endpoint_EndpointLoadMetricStats__Output)[]; - /** - * Opaque and implementation dependent metadata of the - * endpoint. Envoy will pass this directly to the management server. - */ - 'metadata': (_google_protobuf_Struct__Output | null); - /** - * The total number of requests that were issued to this endpoint - * since the last report. A single TCP connection, HTTP or gRPC - * request or stream is counted as one request. - */ - 'total_issued_requests': (string); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/UpstreamLocalityStats.ts b/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/UpstreamLocalityStats.ts deleted file mode 100644 index df4d4eb89..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/api/v2/endpoint/UpstreamLocalityStats.ts +++ /dev/null @@ -1,108 +0,0 @@ -// Original file: deps/envoy-api/envoy/api/v2/endpoint/load_report.proto - -import type { Locality as _envoy_api_v2_core_Locality, Locality__Output as _envoy_api_v2_core_Locality__Output } from '../../../../envoy/api/v2/core/Locality'; -import type { EndpointLoadMetricStats as _envoy_api_v2_endpoint_EndpointLoadMetricStats, EndpointLoadMetricStats__Output as _envoy_api_v2_endpoint_EndpointLoadMetricStats__Output } from '../../../../envoy/api/v2/endpoint/EndpointLoadMetricStats'; -import type { UpstreamEndpointStats as _envoy_api_v2_endpoint_UpstreamEndpointStats, UpstreamEndpointStats__Output as _envoy_api_v2_endpoint_UpstreamEndpointStats__Output } from '../../../../envoy/api/v2/endpoint/UpstreamEndpointStats'; -import type { Long } from '@grpc/proto-loader'; - -/** - * These are stats Envoy reports to GLB every so often. Report frequency is - * defined by - * :ref:`LoadStatsResponse.load_reporting_interval`. - * Stats per upstream region/zone and optionally per subzone. - * [#not-implemented-hide:] Not configuration. TBD how to doc proto APIs. - * [#next-free-field: 9] - */ -export interface UpstreamLocalityStats { - /** - * Name of zone, region and optionally endpoint group these metrics were - * collected from. Zone and region names could be empty if unknown. - */ - 'locality'?: (_envoy_api_v2_core_Locality | null); - /** - * The total number of requests successfully completed by the endpoints in the - * locality. - */ - 'total_successful_requests'?: (number | string | Long); - /** - * The total number of unfinished requests - */ - 'total_requests_in_progress'?: (number | string | Long); - /** - * The total number of requests that failed due to errors at the endpoint, - * aggregated over all endpoints in the locality. - */ - 'total_error_requests'?: (number | string | Long); - /** - * Stats for multi-dimensional load balancing. - */ - 'load_metric_stats'?: (_envoy_api_v2_endpoint_EndpointLoadMetricStats)[]; - /** - * [#not-implemented-hide:] The priority of the endpoint group these metrics - * were collected from. - */ - 'priority'?: (number); - /** - * Endpoint granularity stats information for this locality. This information - * is populated if the Server requests it by setting - * :ref:`LoadStatsResponse.report_endpoint_granularity`. - */ - 'upstream_endpoint_stats'?: (_envoy_api_v2_endpoint_UpstreamEndpointStats)[]; - /** - * The total number of requests that were issued by this Envoy since - * the last report. This information is aggregated over all the - * upstream endpoints in the locality. - */ - 'total_issued_requests'?: (number | string | Long); -} - -/** - * These are stats Envoy reports to GLB every so often. Report frequency is - * defined by - * :ref:`LoadStatsResponse.load_reporting_interval`. - * Stats per upstream region/zone and optionally per subzone. - * [#not-implemented-hide:] Not configuration. TBD how to doc proto APIs. - * [#next-free-field: 9] - */ -export interface UpstreamLocalityStats__Output { - /** - * Name of zone, region and optionally endpoint group these metrics were - * collected from. Zone and region names could be empty if unknown. - */ - 'locality': (_envoy_api_v2_core_Locality__Output | null); - /** - * The total number of requests successfully completed by the endpoints in the - * locality. - */ - 'total_successful_requests': (string); - /** - * The total number of unfinished requests - */ - 'total_requests_in_progress': (string); - /** - * The total number of requests that failed due to errors at the endpoint, - * aggregated over all endpoints in the locality. - */ - 'total_error_requests': (string); - /** - * Stats for multi-dimensional load balancing. - */ - 'load_metric_stats': (_envoy_api_v2_endpoint_EndpointLoadMetricStats__Output)[]; - /** - * [#not-implemented-hide:] The priority of the endpoint group these metrics - * were collected from. - */ - 'priority': (number); - /** - * Endpoint granularity stats information for this locality. This information - * is populated if the Server requests it by setting - * :ref:`LoadStatsResponse.report_endpoint_granularity`. - */ - 'upstream_endpoint_stats': (_envoy_api_v2_endpoint_UpstreamEndpointStats__Output)[]; - /** - * The total number of requests that were issued by this Envoy since - * the last report. This information is aggregated over all the - * upstream endpoints in the locality. - */ - 'total_issued_requests': (string); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v2/AdsDummy.ts b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v2/AdsDummy.ts deleted file mode 100644 index eeb6aa6af..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v2/AdsDummy.ts +++ /dev/null @@ -1,16 +0,0 @@ -// Original file: deps/envoy-api/envoy/service/discovery/v2/ads.proto - - -/** - * [#not-implemented-hide:] Not configuration. Workaround c++ protobuf issue with importing - * services: https://github.com/google/protobuf/issues/4221 - */ -export interface AdsDummy { -} - -/** - * [#not-implemented-hide:] Not configuration. Workaround c++ protobuf issue with importing - * services: https://github.com/google/protobuf/issues/4221 - */ -export interface AdsDummy__Output { -} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v2/AggregatedDiscoveryService.ts b/packages/grpc-js-xds/src/generated/envoy/service/discovery/v2/AggregatedDiscoveryService.ts deleted file mode 100644 index 6044118bc..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/service/discovery/v2/AggregatedDiscoveryService.ts +++ /dev/null @@ -1,58 +0,0 @@ -// Original file: deps/envoy-api/envoy/service/discovery/v2/ads.proto - -import type * as grpc from '@grpc/grpc-js' -import type { MethodDefinition } from '@grpc/proto-loader' -import type { DeltaDiscoveryRequest as _envoy_api_v2_DeltaDiscoveryRequest, DeltaDiscoveryRequest__Output as _envoy_api_v2_DeltaDiscoveryRequest__Output } from '../../../../envoy/api/v2/DeltaDiscoveryRequest'; -import type { DeltaDiscoveryResponse as _envoy_api_v2_DeltaDiscoveryResponse, DeltaDiscoveryResponse__Output as _envoy_api_v2_DeltaDiscoveryResponse__Output } from '../../../../envoy/api/v2/DeltaDiscoveryResponse'; -import type { DiscoveryRequest as _envoy_api_v2_DiscoveryRequest, DiscoveryRequest__Output as _envoy_api_v2_DiscoveryRequest__Output } from '../../../../envoy/api/v2/DiscoveryRequest'; -import type { DiscoveryResponse as _envoy_api_v2_DiscoveryResponse, DiscoveryResponse__Output as _envoy_api_v2_DiscoveryResponse__Output } from '../../../../envoy/api/v2/DiscoveryResponse'; - -/** - * See https://github.com/lyft/envoy-api#apis for a description of the role of - * ADS and how it is intended to be used by a management server. ADS requests - * have the same structure as their singleton xDS counterparts, but can - * multiplex many resource types on a single stream. The type_url in the - * DiscoveryRequest/DiscoveryResponse provides sufficient information to recover - * the multiplexed singleton APIs at the Envoy instance and management server. - */ -export interface AggregatedDiscoveryServiceClient extends grpc.Client { - DeltaAggregatedResources(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_api_v2_DeltaDiscoveryRequest, _envoy_api_v2_DeltaDiscoveryResponse__Output>; - DeltaAggregatedResources(options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_api_v2_DeltaDiscoveryRequest, _envoy_api_v2_DeltaDiscoveryResponse__Output>; - deltaAggregatedResources(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_api_v2_DeltaDiscoveryRequest, _envoy_api_v2_DeltaDiscoveryResponse__Output>; - deltaAggregatedResources(options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_api_v2_DeltaDiscoveryRequest, _envoy_api_v2_DeltaDiscoveryResponse__Output>; - - /** - * This is a gRPC-only API. - */ - StreamAggregatedResources(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_api_v2_DiscoveryRequest, _envoy_api_v2_DiscoveryResponse__Output>; - StreamAggregatedResources(options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_api_v2_DiscoveryRequest, _envoy_api_v2_DiscoveryResponse__Output>; - /** - * This is a gRPC-only API. - */ - streamAggregatedResources(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_api_v2_DiscoveryRequest, _envoy_api_v2_DiscoveryResponse__Output>; - streamAggregatedResources(options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_api_v2_DiscoveryRequest, _envoy_api_v2_DiscoveryResponse__Output>; - -} - -/** - * See https://github.com/lyft/envoy-api#apis for a description of the role of - * ADS and how it is intended to be used by a management server. ADS requests - * have the same structure as their singleton xDS counterparts, but can - * multiplex many resource types on a single stream. The type_url in the - * DiscoveryRequest/DiscoveryResponse provides sufficient information to recover - * the multiplexed singleton APIs at the Envoy instance and management server. - */ -export interface AggregatedDiscoveryServiceHandlers extends grpc.UntypedServiceImplementation { - DeltaAggregatedResources: grpc.handleBidiStreamingCall<_envoy_api_v2_DeltaDiscoveryRequest__Output, _envoy_api_v2_DeltaDiscoveryResponse>; - - /** - * This is a gRPC-only API. - */ - StreamAggregatedResources: grpc.handleBidiStreamingCall<_envoy_api_v2_DiscoveryRequest__Output, _envoy_api_v2_DiscoveryResponse>; - -} - -export interface AggregatedDiscoveryServiceDefinition extends grpc.ServiceDefinition { - DeltaAggregatedResources: MethodDefinition<_envoy_api_v2_DeltaDiscoveryRequest, _envoy_api_v2_DeltaDiscoveryResponse, _envoy_api_v2_DeltaDiscoveryRequest__Output, _envoy_api_v2_DeltaDiscoveryResponse__Output> - StreamAggregatedResources: MethodDefinition<_envoy_api_v2_DiscoveryRequest, _envoy_api_v2_DiscoveryResponse, _envoy_api_v2_DiscoveryRequest__Output, _envoy_api_v2_DiscoveryResponse__Output> -} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadReportingService.ts b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadReportingService.ts deleted file mode 100644 index 2a95752de..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadReportingService.ts +++ /dev/null @@ -1,113 +0,0 @@ -// Original file: deps/envoy-api/envoy/service/load_stats/v2/lrs.proto - -import type * as grpc from '@grpc/grpc-js' -import type { MethodDefinition } from '@grpc/proto-loader' -import type { LoadStatsRequest as _envoy_service_load_stats_v2_LoadStatsRequest, LoadStatsRequest__Output as _envoy_service_load_stats_v2_LoadStatsRequest__Output } from '../../../../envoy/service/load_stats/v2/LoadStatsRequest'; -import type { LoadStatsResponse as _envoy_service_load_stats_v2_LoadStatsResponse, LoadStatsResponse__Output as _envoy_service_load_stats_v2_LoadStatsResponse__Output } from '../../../../envoy/service/load_stats/v2/LoadStatsResponse'; - -export interface LoadReportingServiceClient extends grpc.Client { - /** - * Advanced API to allow for multi-dimensional load balancing by remote - * server. For receiving LB assignments, the steps are: - * 1, The management server is configured with per cluster/zone/load metric - * capacity configuration. The capacity configuration definition is - * outside of the scope of this document. - * 2. Envoy issues a standard {Stream,Fetch}Endpoints request for the clusters - * to balance. - * - * Independently, Envoy will initiate a StreamLoadStats bidi stream with a - * management server: - * 1. Once a connection establishes, the management server publishes a - * LoadStatsResponse for all clusters it is interested in learning load - * stats about. - * 2. For each cluster, Envoy load balances incoming traffic to upstream hosts - * based on per-zone weights and/or per-instance weights (if specified) - * based on intra-zone LbPolicy. This information comes from the above - * {Stream,Fetch}Endpoints. - * 3. When upstream hosts reply, they optionally add header with ASCII representation of EndpointLoadMetricStats. - * 4. Envoy aggregates load reports over the period of time given to it in - * LoadStatsResponse.load_reporting_interval. This includes aggregation - * stats Envoy maintains by itself (total_requests, rpc_errors etc.) as - * well as load metrics from upstream hosts. - * 5. When the timer of load_reporting_interval expires, Envoy sends new - * LoadStatsRequest filled with load reports for each cluster. - * 6. The management server uses the load reports from all reported Envoys - * from around the world, computes global assignment and prepares traffic - * assignment destined for each zone Envoys are located in. Goto 2. - */ - StreamLoadStats(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_service_load_stats_v2_LoadStatsRequest, _envoy_service_load_stats_v2_LoadStatsResponse__Output>; - StreamLoadStats(options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_service_load_stats_v2_LoadStatsRequest, _envoy_service_load_stats_v2_LoadStatsResponse__Output>; - /** - * Advanced API to allow for multi-dimensional load balancing by remote - * server. For receiving LB assignments, the steps are: - * 1, The management server is configured with per cluster/zone/load metric - * capacity configuration. The capacity configuration definition is - * outside of the scope of this document. - * 2. Envoy issues a standard {Stream,Fetch}Endpoints request for the clusters - * to balance. - * - * Independently, Envoy will initiate a StreamLoadStats bidi stream with a - * management server: - * 1. Once a connection establishes, the management server publishes a - * LoadStatsResponse for all clusters it is interested in learning load - * stats about. - * 2. For each cluster, Envoy load balances incoming traffic to upstream hosts - * based on per-zone weights and/or per-instance weights (if specified) - * based on intra-zone LbPolicy. This information comes from the above - * {Stream,Fetch}Endpoints. - * 3. When upstream hosts reply, they optionally add header with ASCII representation of EndpointLoadMetricStats. - * 4. Envoy aggregates load reports over the period of time given to it in - * LoadStatsResponse.load_reporting_interval. This includes aggregation - * stats Envoy maintains by itself (total_requests, rpc_errors etc.) as - * well as load metrics from upstream hosts. - * 5. When the timer of load_reporting_interval expires, Envoy sends new - * LoadStatsRequest filled with load reports for each cluster. - * 6. The management server uses the load reports from all reported Envoys - * from around the world, computes global assignment and prepares traffic - * assignment destined for each zone Envoys are located in. Goto 2. - */ - streamLoadStats(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_service_load_stats_v2_LoadStatsRequest, _envoy_service_load_stats_v2_LoadStatsResponse__Output>; - streamLoadStats(options?: grpc.CallOptions): grpc.ClientDuplexStream<_envoy_service_load_stats_v2_LoadStatsRequest, _envoy_service_load_stats_v2_LoadStatsResponse__Output>; - -} - -export interface LoadReportingServiceHandlers extends grpc.UntypedServiceImplementation { - /** - * Advanced API to allow for multi-dimensional load balancing by remote - * server. For receiving LB assignments, the steps are: - * 1, The management server is configured with per cluster/zone/load metric - * capacity configuration. The capacity configuration definition is - * outside of the scope of this document. - * 2. Envoy issues a standard {Stream,Fetch}Endpoints request for the clusters - * to balance. - * - * Independently, Envoy will initiate a StreamLoadStats bidi stream with a - * management server: - * 1. Once a connection establishes, the management server publishes a - * LoadStatsResponse for all clusters it is interested in learning load - * stats about. - * 2. For each cluster, Envoy load balances incoming traffic to upstream hosts - * based on per-zone weights and/or per-instance weights (if specified) - * based on intra-zone LbPolicy. This information comes from the above - * {Stream,Fetch}Endpoints. - * 3. When upstream hosts reply, they optionally add header with ASCII representation of EndpointLoadMetricStats. - * 4. Envoy aggregates load reports over the period of time given to it in - * LoadStatsResponse.load_reporting_interval. This includes aggregation - * stats Envoy maintains by itself (total_requests, rpc_errors etc.) as - * well as load metrics from upstream hosts. - * 5. When the timer of load_reporting_interval expires, Envoy sends new - * LoadStatsRequest filled with load reports for each cluster. - * 6. The management server uses the load reports from all reported Envoys - * from around the world, computes global assignment and prepares traffic - * assignment destined for each zone Envoys are located in. Goto 2. - */ - StreamLoadStats: grpc.handleBidiStreamingCall<_envoy_service_load_stats_v2_LoadStatsRequest__Output, _envoy_service_load_stats_v2_LoadStatsResponse>; - -} - -export interface LoadReportingServiceDefinition extends grpc.ServiceDefinition { - StreamLoadStats: MethodDefinition<_envoy_service_load_stats_v2_LoadStatsRequest, _envoy_service_load_stats_v2_LoadStatsResponse, _envoy_service_load_stats_v2_LoadStatsRequest__Output, _envoy_service_load_stats_v2_LoadStatsResponse__Output> -} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadStatsRequest.ts b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadStatsRequest.ts deleted file mode 100644 index 3cd5ebc2f..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadStatsRequest.ts +++ /dev/null @@ -1,34 +0,0 @@ -// Original file: deps/envoy-api/envoy/service/load_stats/v2/lrs.proto - -import type { Node as _envoy_api_v2_core_Node, Node__Output as _envoy_api_v2_core_Node__Output } from '../../../../envoy/api/v2/core/Node'; -import type { ClusterStats as _envoy_api_v2_endpoint_ClusterStats, ClusterStats__Output as _envoy_api_v2_endpoint_ClusterStats__Output } from '../../../../envoy/api/v2/endpoint/ClusterStats'; - -/** - * A load report Envoy sends to the management server. - * [#not-implemented-hide:] Not configuration. TBD how to doc proto APIs. - */ -export interface LoadStatsRequest { - /** - * Node identifier for Envoy instance. - */ - 'node'?: (_envoy_api_v2_core_Node | null); - /** - * A list of load stats to report. - */ - 'cluster_stats'?: (_envoy_api_v2_endpoint_ClusterStats)[]; -} - -/** - * A load report Envoy sends to the management server. - * [#not-implemented-hide:] Not configuration. TBD how to doc proto APIs. - */ -export interface LoadStatsRequest__Output { - /** - * Node identifier for Envoy instance. - */ - 'node': (_envoy_api_v2_core_Node__Output | null); - /** - * A list of load stats to report. - */ - 'cluster_stats': (_envoy_api_v2_endpoint_ClusterStats__Output)[]; -} diff --git a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadStatsResponse.ts b/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadStatsResponse.ts deleted file mode 100644 index 1065fe22f..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/service/load_stats/v2/LoadStatsResponse.ts +++ /dev/null @@ -1,71 +0,0 @@ -// Original file: deps/envoy-api/envoy/service/load_stats/v2/lrs.proto - -import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../../google/protobuf/Duration'; - -/** - * The management server sends envoy a LoadStatsResponse with all clusters it - * is interested in learning load stats about. - * [#not-implemented-hide:] Not configuration. TBD how to doc proto APIs. - */ -export interface LoadStatsResponse { - /** - * Clusters to report stats for. - * Not populated if *send_all_clusters* is true. - */ - 'clusters'?: (string)[]; - /** - * The minimum interval of time to collect stats over. This is only a minimum for two reasons: - * 1. There may be some delay from when the timer fires until stats sampling occurs. - * 2. For clusters that were already feature in the previous *LoadStatsResponse*, any traffic - * that is observed in between the corresponding previous *LoadStatsRequest* and this - * *LoadStatsResponse* will also be accumulated and billed to the cluster. This avoids a period - * of inobservability that might otherwise exists between the messages. New clusters are not - * subject to this consideration. - */ - 'load_reporting_interval'?: (_google_protobuf_Duration | null); - /** - * Set to *true* if the management server supports endpoint granularity - * report. - */ - 'report_endpoint_granularity'?: (boolean); - /** - * If true, the client should send all clusters it knows about. - * Only clients that advertise the "envoy.lrs.supports_send_all_clusters" capability in their - * :ref:`client_features` field will honor this field. - */ - 'send_all_clusters'?: (boolean); -} - -/** - * The management server sends envoy a LoadStatsResponse with all clusters it - * is interested in learning load stats about. - * [#not-implemented-hide:] Not configuration. TBD how to doc proto APIs. - */ -export interface LoadStatsResponse__Output { - /** - * Clusters to report stats for. - * Not populated if *send_all_clusters* is true. - */ - 'clusters': (string)[]; - /** - * The minimum interval of time to collect stats over. This is only a minimum for two reasons: - * 1. There may be some delay from when the timer fires until stats sampling occurs. - * 2. For clusters that were already feature in the previous *LoadStatsResponse*, any traffic - * that is observed in between the corresponding previous *LoadStatsRequest* and this - * *LoadStatsResponse* will also be accumulated and billed to the cluster. This avoids a period - * of inobservability that might otherwise exists between the messages. New clusters are not - * subject to this consideration. - */ - 'load_reporting_interval': (_google_protobuf_Duration__Output | null); - /** - * Set to *true* if the management server supports endpoint granularity - * report. - */ - 'report_endpoint_granularity': (boolean); - /** - * If true, the client should send all clusters it knows about. - * Only clients that advertise the "envoy.lrs.supports_send_all_clusters" capability in their - * :ref:`client_features` field will honor this field. - */ - 'send_all_clusters': (boolean); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/type/FractionalPercent.ts b/packages/grpc-js-xds/src/generated/envoy/type/FractionalPercent.ts deleted file mode 100644 index e450f0bfa..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/type/FractionalPercent.ts +++ /dev/null @@ -1,68 +0,0 @@ -// Original file: deps/envoy-api/envoy/type/percent.proto - - -// Original file: deps/envoy-api/envoy/type/percent.proto - -/** - * Fraction percentages support several fixed denominator values. - */ -export enum _envoy_type_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, -} - -/** - * A fractional percentage is used in cases in which for performance reasons performing floating - * point to integer conversions during randomness calculations is undesirable. The message includes - * both a numerator and denominator that together determine the final fractional value. - * - * * **Example**: 1/100 = 1%. - * * **Example**: 3/10000 = 0.03%. - */ -export interface FractionalPercent { - /** - * Specifies the numerator. Defaults to 0. - */ - 'numerator'?: (number); - /** - * Specifies the denominator. If the denominator specified is less than the numerator, the final - * fractional percentage is capped at 1 (100%). - */ - 'denominator'?: (_envoy_type_FractionalPercent_DenominatorType | keyof typeof _envoy_type_FractionalPercent_DenominatorType); -} - -/** - * A fractional percentage is used in cases in which for performance reasons performing floating - * point to integer conversions during randomness calculations is undesirable. The message includes - * both a numerator and denominator that together determine the final fractional value. - * - * * **Example**: 1/100 = 1%. - * * **Example**: 3/10000 = 0.03%. - */ -export interface FractionalPercent__Output { - /** - * Specifies the numerator. Defaults to 0. - */ - 'numerator': (number); - /** - * 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_FractionalPercent_DenominatorType); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/type/Percent.ts b/packages/grpc-js-xds/src/generated/envoy/type/Percent.ts deleted file mode 100644 index 364419994..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/type/Percent.ts +++ /dev/null @@ -1,16 +0,0 @@ -// Original file: deps/envoy-api/envoy/type/percent.proto - - -/** - * Identifies a percentage, in the range [0.0, 100.0]. - */ -export interface Percent { - 'value'?: (number | string); -} - -/** - * Identifies a percentage, in the range [0.0, 100.0]. - */ -export interface Percent__Output { - 'value': (number); -} diff --git a/packages/grpc-js-xds/src/generated/envoy/type/SemanticVersion.ts b/packages/grpc-js-xds/src/generated/envoy/type/SemanticVersion.ts deleted file mode 100644 index f99431703..000000000 --- a/packages/grpc-js-xds/src/generated/envoy/type/SemanticVersion.ts +++ /dev/null @@ -1,24 +0,0 @@ -// Original file: deps/envoy-api/envoy/type/semantic_version.proto - - -/** - * Envoy uses SemVer (https://semver.org/). Major/minor versions indicate - * expected behaviors and APIs, the patch version field is used only - * for security fixes and can be generally ignored. - */ -export interface SemanticVersion { - 'major_number'?: (number); - 'minor_number'?: (number); - 'patch'?: (number); -} - -/** - * Envoy uses SemVer (https://semver.org/). Major/minor versions indicate - * expected behaviors and APIs, the patch version field is used only - * for security fixes and can be generally ignored. - */ -export interface SemanticVersion__Output { - 'major_number': (number); - 'minor_number': (number); - 'patch': (number); -} diff --git a/packages/grpc-js-xds/src/generated/lrs.ts b/packages/grpc-js-xds/src/generated/lrs.ts index e92f80800..e57d6c249 100644 --- a/packages/grpc-js-xds/src/generated/lrs.ts +++ b/packages/grpc-js-xds/src/generated/lrs.ts @@ -1,7 +1,6 @@ import type * as grpc from '@grpc/grpc-js'; import type { EnumTypeDefinition, MessageTypeDefinition } from '@grpc/proto-loader'; -import type { LoadReportingServiceClient as _envoy_service_load_stats_v2_LoadReportingServiceClient, LoadReportingServiceDefinition as _envoy_service_load_stats_v2_LoadReportingServiceDefinition } from './envoy/service/load_stats/v2/LoadReportingService'; import type { LoadReportingServiceClient as _envoy_service_load_stats_v3_LoadReportingServiceClient, LoadReportingServiceDefinition as _envoy_service_load_stats_v3_LoadReportingServiceDefinition } from './envoy/service/load_stats/v3/LoadReportingService'; type SubtypeConstructor any, Subtype> = { @@ -12,48 +11,6 @@ export interface ProtoGrpcType { envoy: { annotations: { } - api: { - v2: { - core: { - Address: MessageTypeDefinition - AsyncDataSource: MessageTypeDefinition - BackoffStrategy: MessageTypeDefinition - BindConfig: MessageTypeDefinition - BuildVersion: MessageTypeDefinition - CidrRange: MessageTypeDefinition - ControlPlane: MessageTypeDefinition - DataSource: MessageTypeDefinition - Extension: MessageTypeDefinition - HeaderMap: MessageTypeDefinition - HeaderValue: MessageTypeDefinition - HeaderValueOption: MessageTypeDefinition - HttpUri: MessageTypeDefinition - Locality: MessageTypeDefinition - Metadata: MessageTypeDefinition - Node: MessageTypeDefinition - Pipe: MessageTypeDefinition - RemoteDataSource: MessageTypeDefinition - RequestMethod: EnumTypeDefinition - RetryPolicy: MessageTypeDefinition - RoutingPriority: EnumTypeDefinition - RuntimeDouble: MessageTypeDefinition - RuntimeFeatureFlag: MessageTypeDefinition - RuntimeFractionalPercent: MessageTypeDefinition - RuntimeUInt32: MessageTypeDefinition - SocketAddress: MessageTypeDefinition - SocketOption: MessageTypeDefinition - TcpKeepalive: MessageTypeDefinition - TrafficDirection: EnumTypeDefinition - TransportSocket: MessageTypeDefinition - } - endpoint: { - ClusterStats: MessageTypeDefinition - EndpointLoadMetricStats: MessageTypeDefinition - UpstreamEndpointStats: MessageTypeDefinition - UpstreamLocalityStats: MessageTypeDefinition - } - } - } config: { core: { v3: { @@ -104,11 +61,6 @@ export interface ProtoGrpcType { } service: { load_stats: { - v2: { - LoadReportingService: SubtypeConstructor & { service: _envoy_service_load_stats_v2_LoadReportingServiceDefinition } - LoadStatsRequest: MessageTypeDefinition - LoadStatsResponse: MessageTypeDefinition - } v3: { LoadReportingService: SubtypeConstructor & { service: _envoy_service_load_stats_v3_LoadReportingServiceDefinition } LoadStatsRequest: MessageTypeDefinition @@ -117,9 +69,6 @@ export interface ProtoGrpcType { } } type: { - FractionalPercent: MessageTypeDefinition - Percent: MessageTypeDefinition - SemanticVersion: MessageTypeDefinition v3: { FractionalPercent: MessageTypeDefinition Percent: MessageTypeDefinition From 4ac8d6dab36b494cd49bca0a83068b067dd562e0 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 12 Oct 2022 13:48:39 -0700 Subject: [PATCH 342/450] grpc-js-xds: Remove all code for handling xDS v2 --- packages/grpc-js-xds/src/csds.ts | 14 +- packages/grpc-js-xds/src/load-balancer-eds.ts | 2 +- packages/grpc-js-xds/src/load-balancer-lrs.ts | 2 +- packages/grpc-js-xds/src/resolver-xds.ts | 28 +- packages/grpc-js-xds/src/resources.ts | 27 +- packages/grpc-js-xds/src/xds-client.ts | 432 +++++------------- .../src/xds-stream-state/lds-state.ts | 13 +- .../src/xds-stream-state/rds-state.ts | 8 +- .../src/xds-stream-state/xds-stream-state.ts | 15 +- 9 files changed, 173 insertions(+), 368 deletions(-) diff --git a/packages/grpc-js-xds/src/csds.ts b/packages/grpc-js-xds/src/csds.ts index 6454e1ad1..114c18042 100644 --- a/packages/grpc-js-xds/src/csds.ts +++ b/packages/grpc-js-xds/src/csds.ts @@ -21,7 +21,7 @@ import { ClientStatusDiscoveryServiceHandlers } from "./generated/envoy/service/ import { ClientStatusRequest__Output } from "./generated/envoy/service/status/v3/ClientStatusRequest"; import { ClientStatusResponse } from "./generated/envoy/service/status/v3/ClientStatusResponse"; import { Timestamp } from "./generated/google/protobuf/Timestamp"; -import { AdsTypeUrl, CDS_TYPE_URL_V2, CDS_TYPE_URL_V3, EDS_TYPE_URL_V2, EDS_TYPE_URL_V3, LDS_TYPE_URL_V2, LDS_TYPE_URL_V3, RDS_TYPE_URL_V2, RDS_TYPE_URL_V3 } from "./resources"; +import { AdsTypeUrl, CDS_TYPE_URL, EDS_TYPE_URL, LDS_TYPE_URL, RDS_TYPE_URL } from "./resources"; import { HandleResponseResult } from "./xds-stream-state/xds-stream-state"; import { sendUnaryData, ServerDuplexStream, ServerUnaryCall, status, experimental, loadPackageDefinition, logVerbosity } from '@grpc/grpc-js'; import { loadSync } from "@grpc/proto-loader"; @@ -50,14 +50,10 @@ function dateToProtoTimestamp(date?: Date | null): Timestamp | null { let clientNode: Node | null = null; const configStatus = { - [EDS_TYPE_URL_V2]: new Map(), - [EDS_TYPE_URL_V3]: new Map(), - [CDS_TYPE_URL_V2]: new Map(), - [CDS_TYPE_URL_V3]: new Map(), - [RDS_TYPE_URL_V2]: new Map(), - [RDS_TYPE_URL_V3]: new Map(), - [LDS_TYPE_URL_V2]: new Map(), - [LDS_TYPE_URL_V3]: new Map() + [EDS_TYPE_URL]: new Map(), + [CDS_TYPE_URL]: new Map(), + [RDS_TYPE_URL]: new Map(), + [LDS_TYPE_URL]: new Map() }; /** diff --git a/packages/grpc-js-xds/src/load-balancer-eds.ts b/packages/grpc-js-xds/src/load-balancer-eds.ts index e7aac0571..6bec1fd19 100644 --- a/packages/grpc-js-xds/src/load-balancer-eds.ts +++ b/packages/grpc-js-xds/src/load-balancer-eds.ts @@ -18,7 +18,7 @@ import { connectivityState as ConnectivityState, status as Status, Metadata, logVerbosity as LogVerbosity, experimental, StatusObject } from '@grpc/grpc-js'; import { getSingletonXdsClient, XdsClient, XdsClusterDropStats } from './xds-client'; import { ClusterLoadAssignment__Output } from './generated/envoy/config/endpoint/v3/ClusterLoadAssignment'; -import { Locality__Output } from './generated/envoy/api/v2/core/Locality'; +import { Locality__Output } from './generated/envoy/config/core/v3/Locality'; import { LocalitySubchannelAddress, PriorityChild, PriorityLoadBalancingConfig } from './load-balancer-priority'; import LoadBalancer = experimental.LoadBalancer; import ChannelControlHelper = experimental.ChannelControlHelper; diff --git a/packages/grpc-js-xds/src/load-balancer-lrs.ts b/packages/grpc-js-xds/src/load-balancer-lrs.ts index 145501fe9..27c62c19b 100644 --- a/packages/grpc-js-xds/src/load-balancer-lrs.ts +++ b/packages/grpc-js-xds/src/load-balancer-lrs.ts @@ -16,7 +16,7 @@ */ import { connectivityState as ConnectivityState, StatusObject, status as Status, experimental } from '@grpc/grpc-js'; -import { Locality__Output } from './generated/envoy/api/v2/core/Locality'; +import { Locality__Output } from './generated/envoy/config/core/v3/Locality'; import { XdsClusterLocalityStats, XdsClient, getSingletonXdsClient } from './xds-client'; import LoadBalancer = experimental.LoadBalancer; import ChannelControlHelper = experimental.ChannelControlHelper; diff --git a/packages/grpc-js-xds/src/resolver-xds.ts b/packages/grpc-js-xds/src/resolver-xds.ts index 8c447931d..496c37094 100644 --- a/packages/grpc-js-xds/src/resolver-xds.ts +++ b/packages/grpc-js-xds/src/resolver-xds.ts @@ -40,7 +40,7 @@ import { XdsClusterManagerLoadBalancingConfig } from './load-balancer-xds-cluste import { ExactValueMatcher, FullMatcher, HeaderMatcher, Matcher, PathExactValueMatcher, PathPrefixValueMatcher, PathSafeRegexValueMatcher, PrefixValueMatcher, PresentValueMatcher, RangeValueMatcher, RejectValueMatcher, SafeRegexValueMatcher, SuffixValueMatcher, ValueMatcher } from './matcher'; import { envoyFractionToFraction, Fraction } from "./fraction"; import { RouteAction, SingleClusterRouteAction, WeightedCluster, WeightedClusterRouteAction } from './route-action'; -import { decodeSingleResource, HTTP_CONNECTION_MANGER_TYPE_URL_V3 } from './resources'; +import { decodeSingleResource, HTTP_CONNECTION_MANGER_TYPE_URL } from './resources'; import Duration = experimental.Duration; import { Duration__Output } from './generated/google/protobuf/Duration'; import { createHttpFilter, HttpFilterConfig, parseOverrideFilterConfig, parseTopLevelFilterConfig } from './http-filter'; @@ -212,7 +212,6 @@ class XdsResolver implements Resolver { private latestRouteConfigName: string | null = null; private latestRouteConfig: RouteConfiguration__Output | null = null; - private latestRouteConfigIsV2 = false; private clusterRefcounts = new Map(); @@ -226,15 +225,15 @@ class XdsResolver implements Resolver { private channelOptions: ChannelOptions ) { this.ldsWatcher = { - onValidUpdate: (update: Listener__Output, isV2: boolean) => { - const httpConnectionManager = decodeSingleResource(HTTP_CONNECTION_MANGER_TYPE_URL_V3, update.api_listener!.api_listener!.value); + onValidUpdate: (update: Listener__Output) => { + const httpConnectionManager = decodeSingleResource(HTTP_CONNECTION_MANGER_TYPE_URL, update.api_listener!.api_listener!.value); const defaultTimeout = httpConnectionManager.common_http_protocol_options?.idle_timeout; if (defaultTimeout === null || defaultTimeout === undefined) { this.latestDefaultTimeout = undefined; } else { this.latestDefaultTimeout = protoDurationToDuration(defaultTimeout); } - if (!isV2 && EXPERIMENTAL_FAULT_INJECTION) { + if (EXPERIMENTAL_FAULT_INJECTION) { this.ldsHttpFilterConfigs = []; for (const filter of httpConnectionManager.http_filters) { // typed_config must be set here, or validation would have failed @@ -260,7 +259,7 @@ class XdsResolver implements Resolver { if (this.latestRouteConfigName) { getSingletonXdsClient().removeRouteWatcher(this.latestRouteConfigName, this.rdsWatcher); } - this.handleRouteConfig(httpConnectionManager.route_config!, isV2); + this.handleRouteConfig(httpConnectionManager.route_config!); break; default: // This is prevented by the validation rules @@ -280,8 +279,8 @@ class XdsResolver implements Resolver { } }; this.rdsWatcher = { - onValidUpdate: (update: RouteConfiguration__Output, isV2: boolean) => { - this.handleRouteConfig(update, isV2); + onValidUpdate: (update: RouteConfiguration__Output) => { + this.handleRouteConfig(update); }, onTransientError: (error: StatusObject) => { /* A transient error only needs to bubble up as a failure if we have @@ -311,14 +310,13 @@ class XdsResolver implements Resolver { refCount.refCount -= 1; if (!refCount.inLastConfig && refCount.refCount === 0) { this.clusterRefcounts.delete(clusterName); - this.handleRouteConfig(this.latestRouteConfig!, this.latestRouteConfigIsV2); + this.handleRouteConfig(this.latestRouteConfig!); } } } - private handleRouteConfig(routeConfig: RouteConfiguration__Output, isV2: boolean) { + private handleRouteConfig(routeConfig: RouteConfiguration__Output) { this.latestRouteConfig = routeConfig; - this.latestRouteConfigIsV2 = isV2; /* Select the virtual host using the default authority override if it * exists, and the channel target otherwise. */ const hostDomain = this.channelOptions['grpc.default_authority'] ?? this.target.path; @@ -328,7 +326,7 @@ class XdsResolver implements Resolver { return; } const virtualHostHttpFilterOverrides = new Map(); - if (!isV2 && EXPERIMENTAL_FAULT_INJECTION) { + if (EXPERIMENTAL_FAULT_INJECTION) { for (const [name, filter] of Object.entries(virtualHost.typed_per_filter_config ?? {})) { const parsedConfig = parseOverrideFilterConfig(filter); if (parsedConfig) { @@ -357,7 +355,7 @@ class XdsResolver implements Resolver { timeout = undefined; } const routeHttpFilterOverrides = new Map(); - if (!isV2 && EXPERIMENTAL_FAULT_INJECTION) { + if (EXPERIMENTAL_FAULT_INJECTION) { for (const [name, filter] of Object.entries(route.typed_per_filter_config ?? {})) { const parsedConfig = parseOverrideFilterConfig(filter); if (parsedConfig) { @@ -372,7 +370,7 @@ class XdsResolver implements Resolver { const cluster = route.route!.cluster!; allConfigClusters.add(cluster); const extraFilterFactories: FilterFactory[] = []; - if (!isV2 && EXPERIMENTAL_FAULT_INJECTION) { + if (EXPERIMENTAL_FAULT_INJECTION) { for (const filterConfig of this.ldsHttpFilterConfigs) { if (routeHttpFilterOverrides.has(filterConfig.name)) { const filter = createHttpFilter(filterConfig.config, routeHttpFilterOverrides.get(filterConfig.name)!); @@ -401,7 +399,7 @@ class XdsResolver implements Resolver { allConfigClusters.add(clusterWeight.name); const extraFilterFactories: FilterFactory[] = []; const clusterHttpFilterOverrides = new Map(); - if (!isV2 && EXPERIMENTAL_FAULT_INJECTION) { + if (EXPERIMENTAL_FAULT_INJECTION) { for (const [name, filter] of Object.entries(clusterWeight.typed_per_filter_config ?? {})) { const parsedConfig = parseOverrideFilterConfig(filter); if (parsedConfig) { diff --git a/packages/grpc-js-xds/src/resources.ts b/packages/grpc-js-xds/src/resources.ts index 4a7e22763..0972ce97d 100644 --- a/packages/grpc-js-xds/src/resources.ts +++ b/packages/grpc-js-xds/src/resources.ts @@ -23,29 +23,22 @@ import { Listener__Output } from './generated/envoy/config/listener/v3/Listener' import { RouteConfiguration__Output } from './generated/envoy/config/route/v3/RouteConfiguration'; import { HttpConnectionManager__Output } from './generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpConnectionManager'; -export const EDS_TYPE_URL_V2 = 'type.googleapis.com/envoy.api.v2.ClusterLoadAssignment'; -export const CDS_TYPE_URL_V2 = 'type.googleapis.com/envoy.api.v2.Cluster'; -export const LDS_TYPE_URL_V2 = 'type.googleapis.com/envoy.api.v2.Listener'; -export const RDS_TYPE_URL_V2 = 'type.googleapis.com/envoy.api.v2.RouteConfiguration'; +export const EDS_TYPE_URL = 'type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment'; +export const CDS_TYPE_URL = 'type.googleapis.com/envoy.config.cluster.v3.Cluster'; +export const LDS_TYPE_URL = 'type.googleapis.com/envoy.config.listener.v3.Listener'; +export const RDS_TYPE_URL = 'type.googleapis.com/envoy.config.route.v3.RouteConfiguration'; -export const EDS_TYPE_URL_V3 = 'type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment'; -export const CDS_TYPE_URL_V3 = 'type.googleapis.com/envoy.config.cluster.v3.Cluster'; -export const LDS_TYPE_URL_V3 = 'type.googleapis.com/envoy.config.listener.v3.Listener'; -export const RDS_TYPE_URL_V3 = 'type.googleapis.com/envoy.config.route.v3.RouteConfiguration'; - -export type EdsTypeUrl = 'type.googleapis.com/envoy.api.v2.ClusterLoadAssignment' | 'type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment'; -export type CdsTypeUrl = 'type.googleapis.com/envoy.api.v2.Cluster' | 'type.googleapis.com/envoy.config.cluster.v3.Cluster'; -export type LdsTypeUrl = 'type.googleapis.com/envoy.api.v2.Listener' | 'type.googleapis.com/envoy.config.listener.v3.Listener'; -export type RdsTypeUrl = 'type.googleapis.com/envoy.api.v2.RouteConfiguration' | 'type.googleapis.com/envoy.config.route.v3.RouteConfiguration'; +export type EdsTypeUrl = 'type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment'; +export type CdsTypeUrl = 'type.googleapis.com/envoy.config.cluster.v3.Cluster'; +export type LdsTypeUrl = 'type.googleapis.com/envoy.config.listener.v3.Listener'; +export type RdsTypeUrl = 'type.googleapis.com/envoy.config.route.v3.RouteConfiguration'; export type AdsTypeUrl = EdsTypeUrl | CdsTypeUrl | RdsTypeUrl | LdsTypeUrl; -export const HTTP_CONNECTION_MANGER_TYPE_URL_V2 = - 'type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager'; -export const HTTP_CONNECTION_MANGER_TYPE_URL_V3 = +export const HTTP_CONNECTION_MANGER_TYPE_URL = 'type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager'; -export type HttpConnectionManagerTypeUrl = 'type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager' | 'type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager'; +export type HttpConnectionManagerTypeUrl = 'type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager'; /** * Map type URLs to their corresponding message types diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index 0c8126cbe..439ed80ea 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -22,17 +22,12 @@ import { loadPackageDefinition, StatusObject, status, logVerbosity, Metadata, ex import * as adsTypes from './generated/ads'; import * as lrsTypes from './generated/lrs'; import { loadBootstrapInfo } from './xds-bootstrap'; -import { Node as NodeV2 } from './generated/envoy/api/v2/core/Node'; -import { Node as NodeV3 } from './generated/envoy/config/core/v3/Node'; -import { AggregatedDiscoveryServiceClient as AggregatedDiscoveryServiceClientV2 } from './generated/envoy/service/discovery/v2/AggregatedDiscoveryService'; -import { AggregatedDiscoveryServiceClient as AggregatedDiscoveryServiceClientV3 } from './generated/envoy/service/discovery/v3/AggregatedDiscoveryService'; -import { DiscoveryRequest as DiscoveryRequestV2 } from './generated/envoy/api/v2/DiscoveryRequest'; -import { DiscoveryRequest as DiscoveryRequestV3 } from './generated/envoy/service/discovery/v3/DiscoveryRequest'; +import { Node } from './generated/envoy/config/core/v3/Node'; +import { AggregatedDiscoveryServiceClient } from './generated/envoy/service/discovery/v3/AggregatedDiscoveryService'; +import { DiscoveryRequest } from './generated/envoy/service/discovery/v3/DiscoveryRequest'; import { DiscoveryResponse__Output } from './generated/envoy/service/discovery/v3/DiscoveryResponse'; -import { LoadReportingServiceClient as LoadReportingServiceClientV2 } from './generated/envoy/service/load_stats/v2/LoadReportingService'; -import { LoadReportingServiceClient as LoadReportingServiceClientV3 } from './generated/envoy/service/load_stats/v3/LoadReportingService'; -import { LoadStatsRequest as LoadStatsRequestV2 } from './generated/envoy/service/load_stats/v2/LoadStatsRequest'; -import { LoadStatsRequest as LoadStatsRequestV3 } from './generated/envoy/service/load_stats/v3/LoadStatsRequest'; +import { LoadReportingServiceClient } from './generated/envoy/service/load_stats/v3/LoadReportingService'; +import { LoadStatsRequest } from './generated/envoy/service/load_stats/v3/LoadStatsRequest'; import { LoadStatsResponse__Output } from './generated/envoy/service/load_stats/v3/LoadStatsResponse'; import { Locality, Locality__Output } from './generated/envoy/config/core/v3/Locality'; import { Listener__Output } from './generated/envoy/config/listener/v3/Listener'; @@ -50,7 +45,7 @@ import { ClusterLoadAssignment__Output } from './generated/envoy/config/endpoint import { Cluster__Output } from './generated/envoy/config/cluster/v3/Cluster'; import { RouteConfiguration__Output } from './generated/envoy/config/route/v3/RouteConfiguration'; import { Duration } from './generated/google/protobuf/Duration'; -import { AdsOutputType, AdsTypeUrl, CDS_TYPE_URL_V2, CDS_TYPE_URL_V3, decodeSingleResource, EDS_TYPE_URL_V2, EDS_TYPE_URL_V3, LDS_TYPE_URL_V2, LDS_TYPE_URL_V3, RDS_TYPE_URL_V2, RDS_TYPE_URL_V3 } from './resources'; +import { AdsOutputType, AdsTypeUrl, CDS_TYPE_URL, decodeSingleResource, EDS_TYPE_URL, LDS_TYPE_URL, RDS_TYPE_URL } from './resources'; import { setCsdsClientNode, updateCsdsRequestedNameList, updateCsdsResourceResponse } from './csds'; const TRACER_NAME = 'xds_client'; @@ -74,8 +69,6 @@ function loadAdsProtos(): Promise< loadedProtos = protoLoader .load( [ - 'envoy/service/discovery/v2/ads.proto', - 'envoy/service/load_stats/v2/lrs.proto', 'envoy/service/discovery/v3/ads.proto', 'envoy/service/load_stats/v3/lrs.proto', ], @@ -85,6 +78,7 @@ function loadAdsProtos(): Promise< enums: String, defaults: true, oneofs: true, + json: true, includeDirs: [ // Paths are relative to src/build __dirname + '/../../deps/envoy-api/', @@ -234,62 +228,38 @@ interface AdsState { lds: LdsState; } -enum XdsApiVersion { - V2, - V3 -} - function getResponseMessages( targetTypeUrl: T, - allowedTypeUrls: string[], resources: Any__Output[] ): ResourcePair>[] { const result: ResourcePair>[] = []; for (const resource of resources) { - if (allowedTypeUrls.includes(resource.type_url)) { - result.push({ - resource: decodeSingleResource(targetTypeUrl, resource.value), - raw: resource - }); - } else { + if (resource.type_url !== targetTypeUrl) { throw new Error( - `ADS Error: Invalid resource type ${resource.type_url}, expected ${allowedTypeUrls}` + `ADS Error: Invalid resource type ${resource.type_url}, expected ${targetTypeUrl}` ); } + result.push({ + resource: decodeSingleResource(targetTypeUrl, resource.value), + raw: resource + }); } return result; } export class XdsClient { - private apiVersion: XdsApiVersion = XdsApiVersion.V2; - - private adsNodeV2: NodeV2 | null = null; - private adsNodeV3: NodeV3 | null = null; - /* A client initiates connections lazily, so the client we don't use won't - * use significant extra resources. */ - private adsClientV2: AggregatedDiscoveryServiceClientV2 | null = null; - private adsClientV3: AggregatedDiscoveryServiceClientV3 | null = null; - /* TypeScript typing is structural, so we can take advantage of the fact that - * the output structures for the two call types are identical. */ - private adsCallV2: ClientDuplexStream< - DiscoveryRequestV2, - DiscoveryResponse__Output - > | null = null; - private adsCallV3: ClientDuplexStream< - DiscoveryRequestV3, + + private adsNode: Node | null = null; + private adsClient: AggregatedDiscoveryServiceClient | null = null; + private adsCall: ClientDuplexStream< + DiscoveryRequest, DiscoveryResponse__Output > | null = null; - private lrsNodeV2: NodeV2 | null = null; - private lrsNodeV3: NodeV3 | null = null; - private lrsClientV2: LoadReportingServiceClientV2 | null = null; - private lrsClientV3: LoadReportingServiceClientV3 | null = null; - private lrsCallV2: ClientDuplexStream< - LoadStatsRequestV2, - LoadStatsResponse__Output - > | null = null; - private lrsCallV3: ClientDuplexStream< - LoadStatsRequestV3, + private lrsNode: Node | null = null; + private lrsClient: LoadReportingServiceClient | null = null; + private lrsCall: ClientDuplexStream< + LoadStatsRequest, LoadStatsResponse__Output > | null = null; private latestLrsSettings: LoadStatsResponse__Output | null = null; @@ -355,48 +325,24 @@ export class XdsClient { }); return; } - if (bootstrapInfo.xdsServers[0].serverFeatures.indexOf('xds_v3') >= 0) { - this.apiVersion = XdsApiVersion.V3; - } else { - this.apiVersion = XdsApiVersion.V2; - } if (bootstrapInfo.xdsServers[0].serverFeatures.indexOf('ignore_resource_deletion') >= 0) { this.adsState.lds.enableIgnoreResourceDeletion(); this.adsState.cds.enableIgnoreResourceDeletion(); } - const nodeV2: NodeV2 = { - ...bootstrapInfo.node, - build_version: `gRPC Node Pure JS ${clientVersion}`, - user_agent_name: 'gRPC Node Pure JS', - }; - const nodeV3: NodeV3 = { + const userAgentName = 'gRPC Node Pure JS'; + this.adsNode = { ...bootstrapInfo.node, - user_agent_name: 'gRPC Node Pure JS', - }; - this.adsNodeV2 = { - ...nodeV2, - client_features: ['envoy.lb.does_not_support_overprovisioning'], - }; - this.adsNodeV3 = { - ...nodeV3, + user_agent_name: userAgentName, client_features: ['envoy.lb.does_not_support_overprovisioning'], }; - this.lrsNodeV2 = { - ...nodeV2, - client_features: ['envoy.lrs.supports_send_all_clusters'], - }; - this.lrsNodeV3 = { - ...nodeV3, + this.lrsNode = { + ...bootstrapInfo.node, + user_agent_name: userAgentName, client_features: ['envoy.lrs.supports_send_all_clusters'], }; - setCsdsClientNode(this.adsNodeV3); - if (this.apiVersion === XdsApiVersion.V2) { - trace('ADS Node: ' + JSON.stringify(this.adsNodeV2, undefined, 2)); - trace('LRS Node: ' + JSON.stringify(this.lrsNodeV2, undefined, 2)); - } else { - trace('ADS Node: ' + JSON.stringify(this.adsNodeV3, undefined, 2)); - trace('LRS Node: ' + JSON.stringify(this.lrsNodeV3, undefined, 2)); - } + setCsdsClientNode(this.adsNode); + trace('ADS Node: ' + JSON.stringify(this.adsNode, undefined, 2)); + trace('LRS Node: ' + JSON.stringify(this.lrsNode, undefined, 2)); const credentialsConfigs = bootstrapInfo.xdsServers[0].channelCreds; let channelCreds: ChannelCredentials | null = null; for (const config of credentialsConfigs) { @@ -421,24 +367,14 @@ export class XdsClient { const serverUri = bootstrapInfo.xdsServers[0].serverUri trace('Starting xDS client connected to server URI ' + bootstrapInfo.xdsServers[0].serverUri); const channel = new Channel(serverUri, channelCreds, channelArgs); - this.adsClientV2 = new protoDefinitions.envoy.service.discovery.v2.AggregatedDiscoveryService( - serverUri, - channelCreds, - {channelOverride: channel} - ); - this.adsClientV3 = new protoDefinitions.envoy.service.discovery.v3.AggregatedDiscoveryService( + this.adsClient = new protoDefinitions.envoy.service.discovery.v3.AggregatedDiscoveryService( serverUri, channelCreds, {channelOverride: channel} ); this.maybeStartAdsStream(); - this.lrsClientV2 = new protoDefinitions.envoy.service.load_stats.v2.LoadReportingService( - serverUri, - channelCreds, - {channelOverride: channel} - ); - this.lrsClientV3 = new protoDefinitions.envoy.service.load_stats.v3.LoadReportingService( + this.lrsClient = new protoDefinitions.envoy.service.load_stats.v3.LoadReportingService( serverUri, channelCreds, {channelOverride: channel} @@ -463,55 +399,36 @@ export class XdsClient { result: HandleResponseResult; serviceKind: AdsServiceKind; } | null = null; - let isV2: boolean; - switch (message.type_url) { - case EDS_TYPE_URL_V2: - case CDS_TYPE_URL_V2: - case RDS_TYPE_URL_V2: - case LDS_TYPE_URL_V2: - isV2 = true; - break; - default: - isV2 = false; - } try { switch (message.type_url) { - case EDS_TYPE_URL_V2: - case EDS_TYPE_URL_V3: + case EDS_TYPE_URL: handleResponseResult = { result: this.adsState.eds.handleResponses( - getResponseMessages(EDS_TYPE_URL_V3, [EDS_TYPE_URL_V2, EDS_TYPE_URL_V3], message.resources), - isV2 + getResponseMessages(EDS_TYPE_URL, message.resources) ), serviceKind: 'eds' }; break; - case CDS_TYPE_URL_V2: - case CDS_TYPE_URL_V3: + case CDS_TYPE_URL: handleResponseResult = { result: this.adsState.cds.handleResponses( - getResponseMessages(CDS_TYPE_URL_V3, [CDS_TYPE_URL_V2, CDS_TYPE_URL_V3], message.resources), - isV2 + getResponseMessages(CDS_TYPE_URL, message.resources) ), serviceKind: 'cds' }; break; - case RDS_TYPE_URL_V2: - case RDS_TYPE_URL_V3: + case RDS_TYPE_URL: handleResponseResult = { result: this.adsState.rds.handleResponses( - getResponseMessages(RDS_TYPE_URL_V3, [RDS_TYPE_URL_V2, RDS_TYPE_URL_V3], message.resources), - isV2 + getResponseMessages(RDS_TYPE_URL, message.resources) ), serviceKind: 'rds' }; break; - case LDS_TYPE_URL_V2: - case LDS_TYPE_URL_V3: + case LDS_TYPE_URL: handleResponseResult = { result: this.adsState.lds.handleResponses( - getResponseMessages(LDS_TYPE_URL_V3, [LDS_TYPE_URL_V2, LDS_TYPE_URL_V3], message.resources), - isV2 + getResponseMessages(LDS_TYPE_URL, message.resources) ), serviceKind: 'lds' } @@ -548,8 +465,7 @@ export class XdsClient { trace( 'ADS stream ended. code=' + streamStatus.code + ' details= ' + streamStatus.details ); - this.adsCallV2 = null; - this.adsCallV3 = null; + this.adsCall = null; if (streamStatus.code !== status.OK) { this.reportStreamError(streamStatus); } @@ -560,48 +476,6 @@ export class XdsClient { } } - private maybeStartAdsStreamV2(): boolean { - if (this.apiVersion !== XdsApiVersion.V2) { - return false; - } - if (this.adsClientV2 === null) { - return false; - } - if (this.adsCallV2 !== null) { - return false; - } - this.adsCallV2 = this.adsClientV2.StreamAggregatedResources(); - this.adsCallV2.on('data', (message: DiscoveryResponse__Output) => { - this.handleAdsResponse(message); - }); - this.adsCallV2.on('status', (status: StatusObject) => { - this.handleAdsCallStatus(status); - }); - this.adsCallV2.on('error', () => {}); - return true; - } - - private maybeStartAdsStreamV3(): boolean { - if (this.apiVersion !== XdsApiVersion.V3) { - return false; - } - if (this.adsClientV3 === null) { - return false; - } - if (this.adsCallV3 !== null) { - return false; - } - this.adsCallV3 = this.adsClientV3.StreamAggregatedResources(); - this.adsCallV3.on('data', (message: DiscoveryResponse__Output) => { - this.handleAdsResponse(message); - }); - this.adsCallV3.on('status', (status: StatusObject) => { - this.handleAdsCallStatus(status); - }); - this.adsCallV3.on('error', () => {}); - return true; - } - /** * Start the ADS stream if the client exists and there is not already an * existing stream, and there are resources to request. @@ -616,73 +490,55 @@ export class XdsClient { this.adsState.lds.getResourceNames().length === 0) { return; } - let streamStarted: boolean; - if (this.apiVersion === XdsApiVersion.V2) { - streamStarted = this.maybeStartAdsStreamV2(); - } else { - streamStarted = this.maybeStartAdsStreamV3(); + if (this.adsClient === null) { + return; } - if (streamStarted) { - trace('Started ADS stream'); - // Backoff relative to when we start the request - this.adsBackoff.runOnce(); - - const allServiceKinds: AdsServiceKind[] = ['eds', 'cds', 'rds', 'lds']; - for (const service of allServiceKinds) { - const state = this.adsState[service]; - if (state.getResourceNames().length > 0) { - this.updateNames(service); - } + if (this.adsCall !== null) { + return; + } + this.adsCall = this.adsClient.StreamAggregatedResources(); + this.adsCall.on('data', (message: DiscoveryResponse__Output) => { + this.handleAdsResponse(message); + }); + this.adsCall.on('status', (status: StatusObject) => { + this.handleAdsCallStatus(status); + }); + this.adsCall.on('error', () => {}); + trace('Started ADS stream'); + // Backoff relative to when we start the request + this.adsBackoff.runOnce(); + + const allServiceKinds: AdsServiceKind[] = ['eds', 'cds', 'rds', 'lds']; + for (const service of allServiceKinds) { + const state = this.adsState[service]; + if (state.getResourceNames().length > 0) { + this.updateNames(service); } - this.reportAdsStreamStarted(); } + this.reportAdsStreamStarted(); } private maybeSendAdsMessage(typeUrl: string, resourceNames: string[], responseNonce: string, versionInfo: string, errorMessage?: string) { - if (this.apiVersion === XdsApiVersion.V2) { - this.adsCallV2?.write({ - node: this.adsNodeV2!, - type_url: typeUrl, - resource_names: resourceNames, - response_nonce: responseNonce, - version_info: versionInfo, - error_detail: errorMessage ? { message: errorMessage } : undefined - }); - } else { - this.adsCallV3?.write({ - node: this.adsNodeV3!, - type_url: typeUrl, - resource_names: resourceNames, - response_nonce: responseNonce, - version_info: versionInfo, - error_detail: errorMessage ? { message: errorMessage } : undefined - }); - } + this.adsCall?.write({ + node: this.adsNode!, + type_url: typeUrl, + resource_names: resourceNames, + response_nonce: responseNonce, + version_info: versionInfo, + error_detail: errorMessage ? { message: errorMessage } : undefined + }); } private getTypeUrl(serviceKind: AdsServiceKind): AdsTypeUrl { - if (this.apiVersion === XdsApiVersion.V2) { - switch (serviceKind) { - case 'eds': - return EDS_TYPE_URL_V2; - case 'cds': - return CDS_TYPE_URL_V2; - case 'rds': - return RDS_TYPE_URL_V2; - case 'lds': - return LDS_TYPE_URL_V2; - } - } else { - switch (serviceKind) { - case 'eds': - return EDS_TYPE_URL_V3; - case 'cds': - return CDS_TYPE_URL_V3; - case 'rds': - return RDS_TYPE_URL_V3; - case 'lds': - return LDS_TYPE_URL_V3; - } + switch (serviceKind) { + case 'eds': + return EDS_TYPE_URL; + case 'cds': + return CDS_TYPE_URL; + case 'rds': + return RDS_TYPE_URL; + case 'lds': + return LDS_TYPE_URL; } } @@ -708,20 +564,16 @@ export class XdsClient { let versionInfo: string; let serviceKind: AdsServiceKind | null; switch (typeUrl) { - case EDS_TYPE_URL_V2: - case EDS_TYPE_URL_V3: + case EDS_TYPE_URL: serviceKind = 'eds'; break; - case CDS_TYPE_URL_V2: - case CDS_TYPE_URL_V3: + case CDS_TYPE_URL: serviceKind = 'cds'; break; - case RDS_TYPE_URL_V2: - case RDS_TYPE_URL_V3: + case RDS_TYPE_URL: serviceKind = 'rds'; break; - case LDS_TYPE_URL_V2: - case LDS_TYPE_URL_V3: + case LDS_TYPE_URL: serviceKind = 'lds'; break; default: @@ -731,7 +583,7 @@ export class XdsClient { if (serviceKind) { this.adsState[serviceKind].reportStreamError({ code: status.UNAVAILABLE, - details: message + ' Node ID=' + this.adsNodeV3!.id, + details: message + ' Node ID=' + this.adsNode!.id, metadata: new Metadata() }); resourceNames = this.adsState[serviceKind].getResourceNames(); @@ -750,19 +602,15 @@ export class XdsClient { this.adsState.cds.getResourceNames().length === 0 && this.adsState.rds.getResourceNames().length === 0 && this.adsState.lds.getResourceNames().length === 0) { - this.adsCallV2?.end(); - this.adsCallV2 = null; - this.adsCallV3?.end(); - this.adsCallV3 = null; - this.lrsCallV2?.end(); - this.lrsCallV2 = null; - this.lrsCallV3?.end(); - this.lrsCallV3 = null; + this.adsCall?.end(); + this.adsCall = null; + this.lrsCall?.end(); + this.lrsCall = null; return; } this.maybeStartAdsStream(); this.maybeStartLrsStream(); - if (!this.adsCallV2 && !this.adsCallV3) { + if (!this.adsCall) { /* If the stream is not set up yet at this point, shortcut the rest * becuase nothing will actually be sent. This would mainly happen if * the bootstrap file has not been read yet. In that case, the output @@ -776,7 +624,7 @@ export class XdsClient { } private reportStreamError(status: StatusObject) { - status = {...status, details: status.details + ' Node ID=' + this.adsNodeV3!.id}; + status = {...status, details: status.details + ' Node ID=' + this.adsNode!.id}; this.adsState.eds.reportStreamError(status); this.adsState.cds.reportStreamError(status); this.adsState.rds.reportStreamError(status); @@ -823,8 +671,7 @@ export class XdsClient { trace( 'LRS stream ended. code=' + streamStatus.code + ' details= ' + streamStatus.details ); - this.lrsCallV2 = null; - this.lrsCallV3 = null; + this.lrsCall = null; clearInterval(this.statsTimer); /* If the backoff timer is no longer running, we do not need to wait any * more to start the new call. */ @@ -833,41 +680,22 @@ export class XdsClient { } } - private maybeStartLrsStreamV2(): boolean { - if (!this.lrsClientV2) { - return false; - } - if (this.lrsCallV2) { - return false; - } - this.lrsCallV2 = this.lrsClientV2.streamLoadStats(); - this.receivedLrsSettingsForCurrentStream = false; - this.lrsCallV2.on('data', (message: LoadStatsResponse__Output) => { - this.handleLrsResponse(message); - }); - this.lrsCallV2.on('status', (status: StatusObject) => { - this.handleLrsCallStatus(status); - }); - this.lrsCallV2.on('error', () => {}); - return true; - } - private maybeStartLrsStreamV3(): boolean { - if (!this.lrsClientV3) { + if (!this.lrsClient) { return false; } - if (this.lrsCallV3) { + if (this.lrsCall) { return false; } - this.lrsCallV3 = this.lrsClientV3.streamLoadStats(); + this.lrsCall = this.lrsClient.streamLoadStats(); this.receivedLrsSettingsForCurrentStream = false; - this.lrsCallV3.on('data', (message: LoadStatsResponse__Output) => { + this.lrsCall.on('data', (message: LoadStatsResponse__Output) => { this.handleLrsResponse(message); }); - this.lrsCallV3.on('status', (status: StatusObject) => { + this.lrsCall.on('status', (status: StatusObject) => { this.handleLrsCallStatus(status); }); - this.lrsCallV3.on('error', () => {}); + this.lrsCall.on('error', () => {}); return true; } @@ -881,39 +709,37 @@ export class XdsClient { this.adsState.lds.getResourceNames().length === 0) { return; } - - let streamStarted: boolean; - if (this.apiVersion === XdsApiVersion.V2) { - streamStarted = this.maybeStartLrsStreamV2(); - } else { - streamStarted = this.maybeStartLrsStreamV3(); + if (!this.lrsClient) { + return; } - - if (streamStarted) { - trace('Starting LRS stream'); - this.lrsBackoff.runOnce(); - /* Send buffered stats information when starting LRS stream. If there is no - * buffered stats information, it will still send the node field. */ - this.sendStats(); + if (this.lrsCall) { + return; } + this.lrsCall = this.lrsClient.streamLoadStats(); + this.receivedLrsSettingsForCurrentStream = false; + this.lrsCall.on('data', (message: LoadStatsResponse__Output) => { + this.handleLrsResponse(message); + }); + this.lrsCall.on('status', (status: StatusObject) => { + this.handleLrsCallStatus(status); + }); + this.lrsCall.on('error', () => {}); + trace('Starting LRS stream'); + this.lrsBackoff.runOnce(); + /* Send buffered stats information when starting LRS stream. If there is no + * buffered stats information, it will still send the node field. */ + this.sendStats(); } private maybeSendLrsMessage(clusterStats: ClusterStats[]) { - if (this.apiVersion === XdsApiVersion.V2) { - this.lrsCallV2?.write({ - node: this.lrsNodeV2!, - cluster_stats: clusterStats - }); - } else { - this.lrsCallV3?.write({ - node: this.lrsNodeV3!, - cluster_stats: clusterStats - }); - } + this.lrsCall?.write({ + node: this.lrsNode!, + cluster_stats: clusterStats + }); } private sendStats() { - if (this.lrsCallV2 === null && this.lrsCallV3 === null) { + if (this.lrsCall === null) { return; } if (!this.latestLrsSettings) { @@ -1121,14 +947,10 @@ export class XdsClient { } private shutdown(): void { - this.adsCallV2?.cancel(); - this.adsCallV3?.cancel(); - this.adsClientV2?.close(); - this.adsClientV3?.close(); - this.lrsCallV2?.cancel(); - this.lrsCallV3?.cancel(); - this.lrsClientV2?.close(); - this.lrsClientV3?.close(); + this.adsCall?.cancel(); + this.adsClient?.close(); + this.lrsCall?.cancel(); + this.lrsClient?.close(); this.hasShutdown = true; } } diff --git a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts index bd5b6423f..c215076db 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/lds-state.ts @@ -19,7 +19,7 @@ import { experimental, logVerbosity } from "@grpc/grpc-js"; import { Listener__Output } from '../generated/envoy/config/listener/v3/Listener'; import { RdsState } from "./rds-state"; import { BaseXdsStreamState, XdsStreamState } from "./xds-stream-state"; -import { decodeSingleResource, HTTP_CONNECTION_MANGER_TYPE_URL_V2, HTTP_CONNECTION_MANGER_TYPE_URL_V3 } from '../resources'; +import { decodeSingleResource, HTTP_CONNECTION_MANGER_TYPE_URL } from '../resources'; import { getTopLevelFilterUrl, validateTopLevelFilter } from '../http-filter'; import { EXPERIMENTAL_FAULT_INJECTION } from '../environment'; @@ -46,18 +46,17 @@ export class LdsState extends BaseXdsStreamState implements Xd super(updateResourceNames); } - public validateResponse(message: Listener__Output, isV2: boolean): boolean { + public validateResponse(message: Listener__Output): boolean { if ( !( message.api_listener?.api_listener && - (message.api_listener.api_listener.type_url === HTTP_CONNECTION_MANGER_TYPE_URL_V2 || - message.api_listener.api_listener.type_url === HTTP_CONNECTION_MANGER_TYPE_URL_V3) + message.api_listener.api_listener.type_url === HTTP_CONNECTION_MANGER_TYPE_URL ) ) { return false; } - const httpConnectionManager = decodeSingleResource(HTTP_CONNECTION_MANGER_TYPE_URL_V3, message.api_listener!.api_listener.value); - if (!isV2 && EXPERIMENTAL_FAULT_INJECTION) { + const httpConnectionManager = decodeSingleResource(HTTP_CONNECTION_MANGER_TYPE_URL, message.api_listener!.api_listener.value); + if (EXPERIMENTAL_FAULT_INJECTION) { const filterNames = new Set(); for (const [index, httpFilter] of httpConnectionManager.http_filters.entries()) { if (filterNames.has(httpFilter.name)) { @@ -89,7 +88,7 @@ export class LdsState extends BaseXdsStreamState implements Xd case 'rds': return !!httpConnectionManager.rds?.config_source?.ads; case 'route_config': - return this.rdsState.validateResponse(httpConnectionManager.route_config!, isV2); + return this.rdsState.validateResponse(httpConnectionManager.route_config!); } return false; } diff --git a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts index a5d3c47cf..119ac6b92 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts @@ -40,7 +40,7 @@ export class RdsState extends BaseXdsStreamState imp protected getProtocolName(): string { return 'RDS'; } - validateResponse(message: RouteConfiguration__Output, isV2: boolean): boolean { + validateResponse(message: RouteConfiguration__Output): boolean { // https://github.com/grpc/proposal/blob/master/A28-xds-traffic-splitting-and-routing.md#response-validation for (const virtualHost of message.virtual_hosts) { for (const domainPattern of virtualHost.domains) { @@ -55,7 +55,7 @@ export class RdsState extends BaseXdsStreamState imp return false; } } - if (!isV2 && EXPERIMENTAL_FAULT_INJECTION) { + if (EXPERIMENTAL_FAULT_INJECTION) { for (const filterConfig of Object.values(virtualHost.typed_per_filter_config ?? {})) { if (!validateOverrideFilter(filterConfig)) { return false; @@ -81,7 +81,7 @@ export class RdsState extends BaseXdsStreamState imp if ((route.route === undefined) || (route.route === null) || SUPPORTED_CLUSTER_SPECIFIERS.indexOf(route.route.cluster_specifier) < 0) { return false; } - if (!isV2 && EXPERIMENTAL_FAULT_INJECTION) { + if (EXPERIMENTAL_FAULT_INJECTION) { for (const [name, filterConfig] of Object.entries(route.typed_per_filter_config ?? {})) { if (!validateOverrideFilter(filterConfig)) { return false; @@ -99,7 +99,7 @@ export class RdsState extends BaseXdsStreamState imp if (weightSum !== route.route.weighted_clusters!.total_weight?.value ?? 100) { return false; } - if (!isV2 && EXPERIMENTAL_FAULT_INJECTION) { + if (EXPERIMENTAL_FAULT_INJECTION) { for (const weightedCluster of route.route!.weighted_clusters!.clusters) { for (const filterConfig of Object.values(weightedCluster.typed_per_filter_config ?? {})) { if (!validateOverrideFilter(filterConfig)) { diff --git a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts index 7b3bc0189..86c2cea4b 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts @@ -26,7 +26,7 @@ export interface Watcher { * message type into a library-specific configuration object type, to * remove a lot of duplicate logic, including logic for handling that * flag. */ - onValidUpdate(update: UpdateType, isV2: boolean): void; + onValidUpdate(update: UpdateType): void; onTransientError(error: StatusObject): void; onResourceDoesNotExist(): void; } @@ -85,7 +85,6 @@ export abstract class BaseXdsStreamState implements XdsStreamState nonce = ''; private subscriptions: Map> = new Map>(); - private latestIsV2 = false; private isAdsStreamRunning = false; private ignoreResourceDeletion = false; @@ -128,7 +127,7 @@ export abstract class BaseXdsStreamState implements XdsStreamState * the same happens here */ process.nextTick(() => { this.trace('Reporting existing update for new watcher for name ' + name); - watcher.onValidUpdate(cachedResponse, this.latestIsV2); + watcher.onValidUpdate(cachedResponse); }); } if (addedName) { @@ -157,7 +156,7 @@ export abstract class BaseXdsStreamState implements XdsStreamState getResourceNames(): string[] { return Array.from(this.subscriptions.keys()); } - handleResponses(responses: ResourcePair[], isV2: boolean): HandleResponseResult { + handleResponses(responses: ResourcePair[]): HandleResponseResult { const validResponses: ResponseType[] = []; let result: HandleResponseResult = { accepted: [], @@ -166,7 +165,7 @@ export abstract class BaseXdsStreamState implements XdsStreamState } for (const {resource, raw} of responses) { const resourceName = this.getResourceName(resource); - if (this.validateResponse(resource, isV2)) { + if (this.validateResponse(resource)) { validResponses.push(resource); result.accepted.push({ name: resourceName, @@ -180,7 +179,6 @@ export abstract class BaseXdsStreamState implements XdsStreamState }); } } - this.latestIsV2 = isV2; const allResourceNames = new Set(); for (const resource of validResponses) { const resourceName = this.getResourceName(resource); @@ -189,7 +187,7 @@ export abstract class BaseXdsStreamState implements XdsStreamState if (subscriptionEntry) { const watchers = subscriptionEntry.watchers; for (const watcher of watchers) { - watcher.onValidUpdate(resource, isV2); + watcher.onValidUpdate(resource); } clearTimeout(subscriptionEntry.resourceTimer); subscriptionEntry.cachedResponse = resource; @@ -259,9 +257,8 @@ export abstract class BaseXdsStreamState implements XdsStreamState * This function is public so that the LDS validateResponse can call into * the RDS validateResponse. * @param resource The resource object sent by the xDS server - * @param isV2 If true, the resource is an xDS V2 resource instead of xDS V3 */ - public abstract validateResponse(resource: ResponseType, isV2: boolean): boolean; + public abstract validateResponse(resource: ResponseType): boolean; /** * Get the name of a resource object. The name is some field of the object, so * getting it depends on the specific type. From 75a6d0a24b01d18448f72dc6df3a4e1de497d333 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 14 Oct 2022 09:45:57 -0700 Subject: [PATCH 343/450] grpc-js: Handle the grpc-node.max_session_memory option consistently on the client and server --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/server.ts | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index c0db93ae0..087060154 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.7.1", + "version": "1.7.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", diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 974c3dfc6..499fde4a3 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -346,6 +346,12 @@ export class Server { serverOptions.maxSessionMemory = this.options[ 'grpc-node.max_session_memory' ]; + } else { + /* By default, set a very large max session memory limit, to effectively + * disable enforcement of the limit. Some testing indicates that Node's + * behavior degrades badly when this limit is reached, so we solve that + * by disabling the check entirely. */ + serverOptions.maxSessionMemory = Number.MAX_SAFE_INTEGER; } if ('grpc.max_concurrent_streams' in this.options) { serverOptions.settings = { From 59a2cbceeb288b0967dca7daafee254292bc0e1a Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 14 Oct 2022 10:27:38 -0700 Subject: [PATCH 344/450] grpc-js: Remove redundant calls to setCredentials --- packages/grpc-js/src/client-interceptors.ts | 8 -------- packages/grpc-js/src/client.ts | 12 ------------ 2 files changed, 20 deletions(-) diff --git a/packages/grpc-js/src/client-interceptors.ts b/packages/grpc-js/src/client-interceptors.ts index 52320b0b3..d9c88f448 100644 --- a/packages/grpc-js/src/client-interceptors.ts +++ b/packages/grpc-js/src/client-interceptors.ts @@ -198,8 +198,6 @@ export interface InterceptingCallInterface { sendMessage(message: any): void; startRead(): void; halfClose(): void; - - setCredentials(credentials: CallCredentials): void; } export class InterceptingCall implements InterceptingCallInterface { @@ -337,9 +335,6 @@ export class InterceptingCall implements InterceptingCallInterface { } }); } - setCredentials(credentials: CallCredentials): void { - this.nextCall.setCredentials(credentials); - } } function getCall(channel: Channel, path: string, options: CallOptions): Call { @@ -371,9 +366,6 @@ class BaseInterceptingCall implements InterceptingCallInterface { getPeer(): string { return this.call.getPeer(); } - setCredentials(credentials: CallCredentials): void { - this.call.setCredentials(credentials); - } // eslint-disable-next-line @typescript-eslint/no-explicit-any sendMessageWithContext(context: MessageContext, message: any): void { let serialized: Buffer; diff --git a/packages/grpc-js/src/client.ts b/packages/grpc-js/src/client.ts index d97c9fa3f..f96f8fdf0 100644 --- a/packages/grpc-js/src/client.ts +++ b/packages/grpc-js/src/client.ts @@ -321,9 +321,6 @@ export class Client { * before calling the CallInvocationTransformer, and we need to create the * call after that. */ emitter.call = call; - if (callProperties.callOptions.credentials) { - call.setCredentials(callProperties.callOptions.credentials); - } let responseMessage: ResponseType | null = null; let receivedStatus = false; const callerStackError = new Error(); @@ -449,9 +446,6 @@ export class Client { * before calling the CallInvocationTransformer, and we need to create the * call after that. */ emitter.call = call; - if (callProperties.callOptions.credentials) { - call.setCredentials(callProperties.callOptions.credentials); - } let responseMessage: ResponseType | null = null; let receivedStatus = false; const callerStackError = new Error(); @@ -582,9 +576,6 @@ export class Client { * before calling the CallInvocationTransformer, and we need to create the * call after that. */ stream.call = call; - if (callProperties.callOptions.credentials) { - call.setCredentials(callProperties.callOptions.credentials); - } let receivedStatus = false; const callerStackError = new Error(); call.start(callProperties.metadata, { @@ -681,9 +672,6 @@ export class Client { * before calling the CallInvocationTransformer, and we need to create the * call after that. */ stream.call = call; - if (callProperties.callOptions.credentials) { - call.setCredentials(callProperties.callOptions.credentials); - } let receivedStatus = false; const callerStackError = new Error(); call.start(callProperties.metadata, { From 63d9f6a6d68ceef57e72f02e37c91d140ae32196 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 14 Oct 2022 11:18:26 -0700 Subject: [PATCH 345/450] Ensure ordering between received messages and status --- packages/grpc-js/src/load-balancing-call.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/src/load-balancing-call.ts b/packages/grpc-js/src/load-balancing-call.ts index 36af8b683..73c1fa9fd 100644 --- a/packages/grpc-js/src/load-balancing-call.ts +++ b/packages/grpc-js/src/load-balancing-call.ts @@ -44,6 +44,8 @@ export class LoadBalancingCall implements Call { private writeFilterPending = false; private pendingMessage: {context: MessageContext, message: Buffer} | null = null; private pendingHalfClose = false; + private readFilterPending = false; + private pendingChildStatus: StatusObject | null = null; private ended = false; private serviceUrl: string; private filterStack: FilterStack; @@ -153,14 +155,23 @@ export class LoadBalancingCall implements Call { this.listener!.onReceiveMetadata(this.filterStack.receiveMetadata(metadata)); }, onReceiveMessage: message => { + this.readFilterPending = true; this.filterStack.receiveMessage(message).then(filteredMesssage => { + this.readFilterPending = false; this.listener!.onReceiveMessage(filteredMesssage); + if (this.pendingChildStatus) { + this.outputStatus(this.pendingChildStatus, 'PROCESSED'); + } }, (status: StatusObject) => { this.cancelWithStatus(status.code, status.details); }); }, onReceiveStatus: status => { - this.outputStatus(status, 'PROCESSED'); + if (this.readFilterPending) { + this.pendingChildStatus = status; + } else { + this.outputStatus(status, 'PROCESSED'); + } } }); } catch (error) { From 955f088379829cc362496b10e992ab0d1f8c591c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 14 Oct 2022 11:46:32 -0700 Subject: [PATCH 346/450] grpc-js: Test against actively maintained Node versions --- run-tests.bat | 6 +++--- run-tests.sh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/run-tests.bat b/run-tests.bat index 3b0aa07d0..4262f2844 100644 --- a/run-tests.bat +++ b/run-tests.bat @@ -28,8 +28,8 @@ SET JOBS=8 call nvm version -call nvm install 10 -call nvm use 10 +call nvm install 18 +call nvm use 18 git submodule update --init --recursive @@ -40,7 +40,7 @@ call npm install || goto :error SET JUNIT_REPORT_STACK=1 SET FAILED=0 -for %%v in (10 12) do ( +for %%v in (14 16 18) do ( call nvm install %%v call nvm use %%v if "%%v"=="4" ( diff --git a/run-tests.sh b/run-tests.sh index 4bcb388b4..b2e8f6a4e 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -28,7 +28,7 @@ cd $ROOT git submodule update --init --recursive if [ ! -n "$node_versions" ] ; then - node_versions="10 12 14 16" + node_versions="14 16 18" fi set +ex From 276b7b66d020314562000f9fa905e860b7e360c3 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 14 Oct 2022 13:29:57 -0700 Subject: [PATCH 347/450] grpc-js-xds: Fix limit representation for priority weight validation --- packages/grpc-js-xds/src/xds-stream-state/eds-state.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts index 9b7b9cd5f..cec6a4764 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts @@ -25,6 +25,8 @@ import { BaseXdsStreamState, HandleResponseResult, RejectedResourceEntry, Resour const TRACER_NAME = 'xds_client'; +const UINT32_MAX = 0xFFFFFFFF; + function trace(text: string): void { experimental.trace(logVerbosity.DEBUG, TRACER_NAME, text); } @@ -88,7 +90,7 @@ export class EdsState extends BaseXdsStreamState priorityTotalWeights.set(endpoint.priority, (priorityTotalWeights.get(endpoint.priority) ?? 0) + (endpoint.load_balancing_weight?.value ?? 0)); } for (const totalWeight of priorityTotalWeights.values()) { - if (totalWeight >= 1<<32) { + if (totalWeight > UINT32_MAX) { return false; } } From 223bf8f4b04bdb412b55bc14146f86c228a682f7 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 17 Oct 2022 10:11:38 -0700 Subject: [PATCH 348/450] Don't test on Node 18 yet --- run-tests.bat | 6 +++--- run-tests.sh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/run-tests.bat b/run-tests.bat index 4262f2844..6b94b78de 100644 --- a/run-tests.bat +++ b/run-tests.bat @@ -28,8 +28,8 @@ SET JOBS=8 call nvm version -call nvm install 18 -call nvm use 18 +call nvm install 16 +call nvm use 16 git submodule update --init --recursive @@ -40,7 +40,7 @@ call npm install || goto :error SET JUNIT_REPORT_STACK=1 SET FAILED=0 -for %%v in (14 16 18) do ( +for %%v in (14 16) do ( call nvm install %%v call nvm use %%v if "%%v"=="4" ( diff --git a/run-tests.sh b/run-tests.sh index b2e8f6a4e..0adcc0f17 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -28,7 +28,7 @@ cd $ROOT git submodule update --init --recursive if [ ! -n "$node_versions" ] ; then - node_versions="14 16 18" + node_versions="14 16" fi set +ex From c4c321d37dfca78a5b97f433652147628fa43186 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 17 Oct 2022 11:32:22 -0700 Subject: [PATCH 349/450] grpc-js: Handle filters in ResolvingCall instead of LoadBalancingCall --- packages/grpc-js/src/internal-channel.ts | 2 +- packages/grpc-js/src/load-balancing-call.ts | 59 +++---------- packages/grpc-js/src/resolving-call.ts | 96 +++++++++++++++------ 3 files changed, 83 insertions(+), 74 deletions(-) diff --git a/packages/grpc-js/src/internal-channel.ts b/packages/grpc-js/src/internal-channel.ts index 2a775e7d8..16f4b9832 100644 --- a/packages/grpc-js/src/internal-channel.ts +++ b/packages/grpc-js/src/internal-channel.ts @@ -402,7 +402,7 @@ export class InternalChannel { method + '"' ); - return new LoadBalancingCall(this, callConfig, method, host, credentials, deadline, this.filterStackFactory, callNumber); + return new LoadBalancingCall(this, callConfig, method, host, credentials, deadline, callNumber); } createInnerCall( diff --git a/packages/grpc-js/src/load-balancing-call.ts b/packages/grpc-js/src/load-balancing-call.ts index 73c1fa9fd..6faa15592 100644 --- a/packages/grpc-js/src/load-balancing-call.ts +++ b/packages/grpc-js/src/load-balancing-call.ts @@ -41,14 +41,11 @@ export interface StatusObjectWithProgress extends StatusObject { export class LoadBalancingCall implements Call { private child: SubchannelCall | null = null; private readPending = false; - private writeFilterPending = false; private pendingMessage: {context: MessageContext, message: Buffer} | null = null; private pendingHalfClose = false; - private readFilterPending = false; private pendingChildStatus: StatusObject | null = null; private ended = false; private serviceUrl: string; - private filterStack: FilterStack; private metadata: Metadata | null = null; private listener: InterceptingListener | null = null; private onCallEnded: ((statusCode: Status) => void) | null = null; @@ -59,11 +56,8 @@ export class LoadBalancingCall implements Call { private readonly host : string, private readonly credentials: CallCredentials, private readonly deadline: Deadline, - filterStackFactory: FilterStackFactory, private readonly callNumber: number ) { - this.filterStack = filterStackFactory.createFilter(); - const splitPath: string[] = this.methodName.split('/'); let serviceName = ''; /* The standard path format is "/{serviceName}/{methodName}", so if we split @@ -90,8 +84,7 @@ export class LoadBalancingCall implements Call { if (!this.ended) { this.ended = true; this.trace('ended with status: code=' + status.code + ' details="' + status.details + '"'); - const filteredStatus = this.filterStack.receiveTrailers(status); - const finalStatus = {...filteredStatus, progress}; + const finalStatus = {...status, progress}; this.listener?.onReceiveStatus(finalStatus); this.onCallEnded?.(finalStatus.code); } @@ -152,26 +145,13 @@ export class LoadBalancingCall implements Call { try { this.child = pickResult.subchannel!.getRealSubchannel().createCall(finalMetadata, this.host, this.methodName, { onReceiveMetadata: metadata => { - this.listener!.onReceiveMetadata(this.filterStack.receiveMetadata(metadata)); + this.listener!.onReceiveMetadata(metadata); }, onReceiveMessage: message => { - this.readFilterPending = true; - this.filterStack.receiveMessage(message).then(filteredMesssage => { - this.readFilterPending = false; - this.listener!.onReceiveMessage(filteredMesssage); - if (this.pendingChildStatus) { - this.outputStatus(this.pendingChildStatus, 'PROCESSED'); - } - }, (status: StatusObject) => { - this.cancelWithStatus(status.code, status.details); - }); + this.listener!.onReceiveMessage(message); }, onReceiveStatus: status => { - if (this.readFilterPending) { - this.pendingChildStatus = status; - } else { - this.outputStatus(status, 'PROCESSED'); - } + this.outputStatus(status, 'PROCESSED'); } }); } catch (error) { @@ -201,7 +181,7 @@ export class LoadBalancingCall implements Call { if (this.pendingMessage) { this.child.sendMessageWithContext(this.pendingMessage.context, this.pendingMessage.message); } - if (this.pendingHalfClose && !this.writeFilterPending) { + if (this.pendingHalfClose) { this.child.halfClose(); } }, (error: Error & { code: number }) => { @@ -249,29 +229,16 @@ export class LoadBalancingCall implements Call { start(metadata: Metadata, listener: InterceptingListener): void { this.trace('start called'); this.listener = listener; - this.filterStack.sendMetadata(Promise.resolve(metadata)).then(filteredMetadata => { - this.metadata = filteredMetadata; - this.doPick(); - }, (status: StatusObject) => { - this.outputStatus(status, 'PROCESSED'); - }); + this.metadata = metadata; + this.doPick(); } sendMessageWithContext(context: MessageContext, message: Buffer): void { this.trace('write() called with message of length ' + message.length); - this.writeFilterPending = true; - this.filterStack.sendMessage(Promise.resolve({message: message, flags: context.flags})).then((filteredMessage) => { - this.writeFilterPending = false; - if (this.child) { - this.child.sendMessageWithContext(context, filteredMessage.message); - if (this.pendingHalfClose) { - this.child.halfClose(); - } - } else { - this.pendingMessage = {context, message: filteredMessage.message}; - } - }, (status: StatusObject) => { - this.cancelWithStatus(status.code, status.details); - }) + if (this.child) { + this.child.sendMessageWithContext(context, message); + } else { + this.pendingMessage = {context, message}; + } } startRead(): void { this.trace('startRead called'); @@ -283,7 +250,7 @@ export class LoadBalancingCall implements Call { } halfClose(): void { this.trace('halfClose called'); - if (this.child && !this.writeFilterPending) { + if (this.child) { this.child.halfClose(); } else { this.pendingHalfClose = true; diff --git a/packages/grpc-js/src/resolving-call.ts b/packages/grpc-js/src/resolving-call.ts index 76a7bd208..f2e5741fa 100644 --- a/packages/grpc-js/src/resolving-call.ts +++ b/packages/grpc-js/src/resolving-call.ts @@ -19,7 +19,7 @@ import { CallCredentials } from "./call-credentials"; import { Call, CallStreamOptions, InterceptingListener, MessageContext, StatusObject } from "./call-interface"; import { LogVerbosity, Propagate, Status } from "./constants"; import { Deadline, getDeadlineTimeoutString, getRelativeTimeout, minDeadline } from "./deadline"; -import { FilterStackFactory } from "./filter-stack"; +import { FilterStack, FilterStackFactory } from "./filter-stack"; import { InternalChannel } from "./internal-channel"; import { Metadata } from "./metadata"; import * as logging from './logging'; @@ -33,12 +33,16 @@ export class ResolvingCall implements Call { private pendingMessage: {context: MessageContext, message: Buffer} | null = null; private pendingHalfClose = false; private ended = false; + private readFilterPending = false; + private writeFilterPending = false; + private pendingChildStatus: StatusObject | null = null; private metadata: Metadata | null = null; private listener: InterceptingListener | null = null; private deadline: Deadline; private host: string; private statusWatchers: ((status: StatusObject) => void)[] = []; private deadlineTimer: NodeJS.Timer = setTimeout(() => {}, 0); + private filterStack: FilterStack | null = null; constructor( private readonly channel: InternalChannel, @@ -96,14 +100,35 @@ export class ResolvingCall implements Call { private outputStatus(status: StatusObject) { if (!this.ended) { this.ended = true; - this.trace('ended with status: code=' + status.code + ' details="' + status.details + '"'); - this.statusWatchers.forEach(watcher => watcher(status)); + if (!this.filterStack) { + this.filterStack = this.filterStackFactory.createFilter(); + } + const filteredStatus = this.filterStack.receiveTrailers(status); + this.trace('ended with status: code=' + filteredStatus.code + ' details="' + filteredStatus.details + '"'); + this.statusWatchers.forEach(watcher => watcher(filteredStatus)); process.nextTick(() => { - this.listener?.onReceiveStatus(status); + this.listener?.onReceiveStatus(filteredStatus); }); } } + private sendMessageOnChild(context: MessageContext, message: Buffer): void { + if (!this.child) { + throw new Error('sendMessageonChild called with child not populated'); + } + const child = this.child; + this.writeFilterPending = true; + this.filterStack!.sendMessage(Promise.resolve({message: message, flags: context.flags})).then((filteredMessage) => { + this.writeFilterPending = false; + child.sendMessageWithContext(context, filteredMessage.message); + if (this.pendingHalfClose) { + child.halfClose(); + } + }, (status: StatusObject) => { + this.cancelWithStatus(status.code, status.details); + }); + } + getConfig(): void { if (this.ended) { return; @@ -148,29 +173,46 @@ export class ResolvingCall implements Call { } this.filterStackFactory.push(config.dynamicFilterFactories); - - this.child = this.channel.createInnerCall(config, this.method, this.host, this.credentials, this.deadline); - this.child.start(this.metadata, { - onReceiveMetadata: metadata => { - this.listener!.onReceiveMetadata(metadata); - }, - onReceiveMessage: message => { - this.listener!.onReceiveMessage(message); - }, - onReceiveStatus: status => { - this.outputStatus(status); + this.filterStack = this.filterStackFactory.createFilter(); + this.filterStack.sendMetadata(Promise.resolve(this.metadata)).then(filteredMetadata => { + this.child = this.channel.createInnerCall(config, this.method, this.host, this.credentials, this.deadline); + this.child.start(filteredMetadata, { + onReceiveMetadata: metadata => { + this.listener!.onReceiveMetadata(this.filterStack!.receiveMetadata(metadata)); + }, + onReceiveMessage: message => { + this.readFilterPending = true; + this.filterStack!.receiveMessage(message).then(filteredMesssage => { + this.readFilterPending = false; + this.listener!.onReceiveMessage(filteredMesssage); + if (this.pendingChildStatus) { + this.outputStatus(this.pendingChildStatus); + } + }, (status: StatusObject) => { + this.cancelWithStatus(status.code, status.details); + }); + }, + onReceiveStatus: status => { + if (this.readFilterPending) { + this.pendingChildStatus = status; + } else { + this.outputStatus(status); + } + } + }); + if (this.readPending) { + this.child.startRead(); } - }); - if (this.readPending) { - this.child.startRead(); - } - if (this.pendingMessage) { - this.child.sendMessageWithContext(this.pendingMessage.context, this.pendingMessage.message); - } - if (this.pendingHalfClose) { - this.child.halfClose(); - } + if (this.pendingMessage) { + this.sendMessageOnChild(this.pendingMessage.context, this.pendingMessage.message); + } else if (this.pendingHalfClose) { + this.child.halfClose(); + } + }, (status: StatusObject) => { + this.outputStatus(status); + }) } + reportResolverError(status: StatusObject) { if (this.metadata?.getOptions().waitForReady) { this.channel.queueCallForConfig(this); @@ -195,7 +237,7 @@ export class ResolvingCall implements Call { sendMessageWithContext(context: MessageContext, message: Buffer): void { this.trace('write() called with message of length ' + message.length); if (this.child) { - this.child.sendMessageWithContext(context, message); + this.sendMessageOnChild(context, message); } else { this.pendingMessage = {context, message}; } @@ -210,7 +252,7 @@ export class ResolvingCall implements Call { } halfClose(): void { this.trace('halfClose called'); - if (this.child) { + if (this.child && !this.writeFilterPending) { this.child.halfClose(); } else { this.pendingHalfClose = true; From 24c4cd7bb81c983fb9bde4e62d66493a02733cdc Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 18 Oct 2022 16:29:22 -0700 Subject: [PATCH 350/450] grpc-js: Add more outlier detection tests and tracing --- .../src/load-balancer-outlier-detection.ts | 4 +- .../grpc-js/test/test-outlier-detection.ts | 169 ++++++++++++++++++ 2 files changed, 172 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index 1f1710e75..cdf580523 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -423,9 +423,10 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { const targetRequestVolume = successRateConfig.request_volume; let addresesWithTargetVolume = 0; const successRates: number[] = [] - for (const mapEntry of this.addressMap.values()) { + for (const [address, mapEntry] of this.addressMap) { const successes = mapEntry.counter.getLastSuccesses(); const failures = mapEntry.counter.getLastFailures(); + trace('Stats for ' + address + ': successes=' + successes + ' failures=' + failures + ' targetRequestVolume=' + targetRequestVolume); if (successes + failures >= targetRequestVolume) { addresesWithTargetVolume += 1; successRates.push(successes/(successes + failures)); @@ -545,6 +546,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { private startTimer(delayMs: number) { this.ejectionTimer = setTimeout(() => this.runChecks(), delayMs); + this.ejectionTimer.unref?.(); } private runChecks() { diff --git a/packages/grpc-js/test/test-outlier-detection.ts b/packages/grpc-js/test/test-outlier-detection.ts index 74e536767..c9021e605 100644 --- a/packages/grpc-js/test/test-outlier-detection.ts +++ b/packages/grpc-js/test/test-outlier-detection.ts @@ -20,6 +20,7 @@ import * as path from 'path'; import * as grpc from '../src'; import { loadProtoFile } from './common'; import { OutlierDetectionLoadBalancingConfig } from '../src/load-balancer-outlier-detection' +import { ServiceClient } from '../src/make-client'; function multiDone(done: Mocha.Done, target: number) { let count = 0; @@ -49,6 +50,54 @@ const defaultOutlierDetectionServiceConfig = { const defaultOutlierDetectionServiceConfigString = JSON.stringify(defaultOutlierDetectionServiceConfig); +const successRateOutlierDetectionServiceConfig = { + methodConfig: [], + loadBalancingConfig: [ + { + outlier_detection: { + interval: { + seconds: 1, + nanos: 0 + }, + base_ejection_time: { + seconds: 3, + nanos: 0 + }, + success_rate_ejection: { + request_volume: 5 + }, + child_policy: [{round_robin: {}}] + } + } + ] +}; + +const successRateOutlierDetectionServiceConfigString = JSON.stringify(successRateOutlierDetectionServiceConfig); + +const failurePercentageOutlierDetectionServiceConfig = { + methodConfig: [], + loadBalancingConfig: [ + { + outlier_detection: { + interval: { + seconds: 1, + nanos: 0 + }, + base_ejection_time: { + seconds: 3, + nanos: 0 + }, + failure_percentage_ejection: { + request_volume: 5 + }, + child_policy: [{round_robin: {}}] + } + } + ] +}; + +const falurePercentageOutlierDetectionServiceConfigString = JSON.stringify(failurePercentageOutlierDetectionServiceConfig); + const goodService = { echo: (call: grpc.ServerUnaryCall, callback: grpc.sendUnaryData) => { callback(null, call.request) @@ -353,6 +402,20 @@ describe('Outlier detection', () => { badServer.forceShutdown(); }); + function makeManyRequests(makeOneRequest: (callback: (error?: Error) => void) => void, total: number, callback: (error?: Error) => void) { + if (total === 0) { + callback(); + return; + } + makeOneRequest(error => { + if (error) { + callback(error); + return; + } + makeManyRequests(makeOneRequest, total - 1, callback); + }); + } + it('Should allow normal operation with one server', done => { const client = new EchoService(`localhost:${goodPorts[0]}`, grpc.credentials.createInsecure(), {'grpc.service_config': defaultOutlierDetectionServiceConfigString}); client.echo( @@ -364,4 +427,110 @@ describe('Outlier detection', () => { } ); }); + describe('Success rate', () => { + let makeCheckedRequest: (callback: () => void) => void; + let makeUncheckedRequest:(callback: (error?: Error) => void) => void; + before(() => { + const target = 'ipv4:///' + goodPorts.map(port => `127.0.0.1:${port}`).join(',') + `,127.0.0.1:${badPort}`; + const client = new EchoService(target, grpc.credentials.createInsecure(), {'grpc.service_config': successRateOutlierDetectionServiceConfigString}); + makeUncheckedRequest = (callback: () => void) => { + client.echo( + { value: 'test value', value2: 3 }, + (error: grpc.ServiceError, response: any) => { + callback(); + } + ); + }; + makeCheckedRequest = (callback: (error?: Error) => void) => { + client.echo( + { value: 'test value', value2: 3 }, + (error: grpc.ServiceError, response: any) => { + callback(error); + } + ); + }; + }); + it('Should eject a server if it is failing requests', done => { + // Make a large volume of requests + makeManyRequests(makeUncheckedRequest, 50, () => { + // Give outlier detection time to run ejection checks + setTimeout(() => { + // Make enough requests to go around all servers + makeManyRequests(makeCheckedRequest, 10, done); + }, 1000); + }); + }); + it('Should uneject a server after the ejection period', function(done) { + this.timeout(5000); + makeManyRequests(makeUncheckedRequest, 50, () => { + setTimeout(() => { + makeManyRequests(makeCheckedRequest, 10, error => { + if (error) { + done(error); + return; + } + setTimeout(() => { + makeManyRequests(makeCheckedRequest, 10, error => { + assert(error); + done(); + }); + }, 3000); + }); + }, 1000); + }) + }); + }); + describe('Failure percentage', () => { + let makeCheckedRequest: (callback: () => void) => void; + let makeUncheckedRequest:(callback: (error?: Error) => void) => void; + before(() => { + const target = 'ipv4:///' + goodPorts.map(port => `127.0.0.1:${port}`).join(',') + `,127.0.0.1:${badPort}`; + const client = new EchoService(target, grpc.credentials.createInsecure(), {'grpc.service_config': falurePercentageOutlierDetectionServiceConfigString}); + makeUncheckedRequest = (callback: () => void) => { + client.echo( + { value: 'test value', value2: 3 }, + (error: grpc.ServiceError, response: any) => { + callback(); + } + ); + }; + makeCheckedRequest = (callback: (error?: Error) => void) => { + client.echo( + { value: 'test value', value2: 3 }, + (error: grpc.ServiceError, response: any) => { + callback(error); + } + ); + }; + }); + it('Should eject a server if it is failing requests', done => { + // Make a large volume of requests + makeManyRequests(makeUncheckedRequest, 50, () => { + // Give outlier detection time to run ejection checks + setTimeout(() => { + // Make enough requests to go around all servers + makeManyRequests(makeCheckedRequest, 10, done); + }, 1000); + }); + }); + it('Should uneject a server after the ejection period', function(done) { + this.timeout(5000); + makeManyRequests(makeUncheckedRequest, 50, () => { + setTimeout(() => { + makeManyRequests(makeCheckedRequest, 10, error => { + if (error) { + done(error); + return; + } + setTimeout(() => { + makeManyRequests(makeCheckedRequest, 10, error => { + assert(error); + done(); + }); + }, 3000); + }); + }, 1000); + }) + }); + }); }); \ No newline at end of file From 2f124ad68bfe5d9df1130d7c25ea340a50b87a58 Mon Sep 17 00:00:00 2001 From: AVVS Date: Wed, 19 Oct 2022 14:48:11 -0700 Subject: [PATCH 351/450] fix: perf issues in hot paths 1. no unused timers, wrap tracing calls to avoid stringifying 2. track graceful end of the call and avoid emitting 'cancelled' in such cases 3. remove validate calls in metadata on operations where it's not needed 4. refactor server session stream handlers into separate channelz enabled/disabled handlers 5. refactor message request logic - reduce amount of microtasks generated 6. improve sendStatus a little when there is no metadata involved --- packages/grpc-js/src/call-stream.ts | 4 + .../generated/grpc/channelz/v1/Channelz.ts | 104 ++--- packages/grpc-js/src/metadata.ts | 64 ++- packages/grpc-js/src/server-call.ts | 305 +++++++------ packages/grpc-js/src/server.ts | 413 +++++++++++------- 5 files changed, 502 insertions(+), 388 deletions(-) diff --git a/packages/grpc-js/src/call-stream.ts b/packages/grpc-js/src/call-stream.ts index d7151eb6f..488e35fc8 100644 --- a/packages/grpc-js/src/call-stream.ts +++ b/packages/grpc-js/src/call-stream.ts @@ -97,6 +97,10 @@ export interface StatusObject { metadata: Metadata; } +export type PartialStatusObject = Pick & { + metadata: Metadata | null; +} + export const enum WriteFlags { BufferHint = 1, NoCompress = 2, diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/Channelz.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/Channelz.ts index ace712454..4c8c18aa7 100644 --- a/packages/grpc-js/src/generated/grpc/channelz/v1/Channelz.ts +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/Channelz.ts @@ -25,102 +25,102 @@ export interface ChannelzClient extends grpc.Client { /** * Returns a single Channel, or else a NOT_FOUND code. */ - GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetChannelResponse__Output) => void): grpc.ClientUnaryCall; - GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetChannelResponse__Output) => void): grpc.ClientUnaryCall; - GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetChannelResponse__Output) => void): grpc.ClientUnaryCall; - GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetChannelResponse__Output) => void): grpc.ClientUnaryCall; + GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetChannelResponse__Output>): grpc.ClientUnaryCall; + GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetChannelResponse__Output>): grpc.ClientUnaryCall; + GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetChannelResponse__Output>): grpc.ClientUnaryCall; + GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetChannelResponse__Output>): grpc.ClientUnaryCall; /** * Returns a single Server, or else a NOT_FOUND code. */ - GetServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; - GetServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; - GetServer(argument: _grpc_channelz_v1_GetServerRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; - GetServer(argument: _grpc_channelz_v1_GetServerRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; + GetServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall; + GetServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall; + GetServer(argument: _grpc_channelz_v1_GetServerRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall; + GetServer(argument: _grpc_channelz_v1_GetServerRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall; /** * Returns a single Server, or else a NOT_FOUND code. */ - getServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; - getServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; - getServer(argument: _grpc_channelz_v1_GetServerRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; - getServer(argument: _grpc_channelz_v1_GetServerRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; + getServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall; + getServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall; + getServer(argument: _grpc_channelz_v1_GetServerRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall; + getServer(argument: _grpc_channelz_v1_GetServerRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall; /** * Gets all server sockets that exist in the process. */ - GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; - GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; - GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; - GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; + GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall; + GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall; + GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall; + GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall; /** * Gets all server sockets that exist in the process. */ - getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; - getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; - getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; - getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; + getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall; + getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall; + getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall; + getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall; /** * Gets all servers that exist in the process. */ - GetServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; - GetServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; - GetServers(argument: _grpc_channelz_v1_GetServersRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; - GetServers(argument: _grpc_channelz_v1_GetServersRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; + GetServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall; + GetServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall; + GetServers(argument: _grpc_channelz_v1_GetServersRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall; + GetServers(argument: _grpc_channelz_v1_GetServersRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall; /** * Gets all servers that exist in the process. */ - getServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; - getServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; - getServers(argument: _grpc_channelz_v1_GetServersRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; - getServers(argument: _grpc_channelz_v1_GetServersRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; + getServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall; + getServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall; + getServers(argument: _grpc_channelz_v1_GetServersRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall; + getServers(argument: _grpc_channelz_v1_GetServersRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall; /** * Returns a single Socket or else a NOT_FOUND code. */ - GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; - GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; - GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; - GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; + GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall; + GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall; + GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall; + GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall; /** * Returns a single Socket or else a NOT_FOUND code. */ - getSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; - getSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; - getSocket(argument: _grpc_channelz_v1_GetSocketRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; - getSocket(argument: _grpc_channelz_v1_GetSocketRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; + getSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall; + getSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall; + getSocket(argument: _grpc_channelz_v1_GetSocketRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall; + getSocket(argument: _grpc_channelz_v1_GetSocketRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall; /** * Returns a single Subchannel, or else a NOT_FOUND code. */ - GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; - GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; - GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; - GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; + GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall; + GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall; + GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall; + GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall; /** * Returns a single Subchannel, or else a NOT_FOUND code. */ - getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; - getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; - getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; - getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; + getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall; + getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall; + getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall; + getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall; /** * Gets all root channels (i.e. channels the application has directly * created). This does not include subchannels nor non-top level channels. */ - GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; - GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; - GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; - GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; + GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall; + GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall; + GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall; + GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall; /** * Gets all root channels (i.e. channels the application has directly * created). This does not include subchannels nor non-top level channels. */ - getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; - getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; - getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; - getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; + getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall; + getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall; + getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall; + getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall; } diff --git a/packages/grpc-js/src/metadata.ts b/packages/grpc-js/src/metadata.ts index 04db642ef..376cb491a 100644 --- a/packages/grpc-js/src/metadata.ts +++ b/packages/grpc-js/src/metadata.ts @@ -48,13 +48,14 @@ function validate(key: string, value?: MetadataValue): void { if (!isLegalKey(key)) { throw new Error('Metadata key "' + key + '" contains illegal characters'); } + if (value !== null && value !== undefined) { if (isBinaryKey(key)) { - if (!(value instanceof Buffer)) { + if (!Buffer.isBuffer(value)) { throw new Error("keys that end with '-bin' must have Buffer values"); } } else { - if (value instanceof Buffer) { + if (Buffer.isBuffer(value)) { throw new Error( "keys that don't end with '-bin' must have String values" ); @@ -88,12 +89,8 @@ export class Metadata { protected internalRepr: MetadataObject = new Map(); private options: MetadataOptions; - constructor(options?: MetadataOptions) { - if (options === undefined) { - this.options = {}; - } else { - this.options = options; - } + constructor(options: MetadataOptions = {}) { + this.options = options; } /** @@ -120,9 +117,7 @@ export class Metadata { key = normalizeKey(key); validate(key, value); - const existingValue: MetadataValue[] | undefined = this.internalRepr.get( - key - ); + const existingValue: MetadataValue[] | undefined = this.internalRepr.get(key); if (existingValue === undefined) { this.internalRepr.set(key, [value]); @@ -137,7 +132,7 @@ export class Metadata { */ remove(key: string): void { key = normalizeKey(key); - validate(key); + // validate(key); this.internalRepr.delete(key); } @@ -148,7 +143,7 @@ export class Metadata { */ get(key: string): MetadataValue[] { key = normalizeKey(key); - validate(key); + // validate(key); return this.internalRepr.get(key) || []; } @@ -160,12 +155,12 @@ export class Metadata { getMap(): { [key: string]: MetadataValue } { const result: { [key: string]: MetadataValue } = {}; - this.internalRepr.forEach((values, key) => { + for (const [key, values] of this.internalRepr) { if (values.length > 0) { const v = values[0]; - result[key] = v instanceof Buffer ? v.slice() : v; + result[key] = Buffer.isBuffer(v) ? Buffer.from(v) : v; } - }); + } return result; } @@ -177,9 +172,9 @@ export class Metadata { const newMetadata = new Metadata(this.options); const newInternalRepr = newMetadata.internalRepr; - this.internalRepr.forEach((value, key) => { + for (const [key, value] of this.internalRepr) { const clonedValue: MetadataValue[] = value.map((v) => { - if (v instanceof Buffer) { + if (Buffer.isBuffer(v)) { return Buffer.from(v); } else { return v; @@ -187,7 +182,7 @@ export class Metadata { }); newInternalRepr.set(key, clonedValue); - }); + } return newMetadata; } @@ -200,13 +195,13 @@ export class Metadata { * @param other A Metadata object. */ merge(other: Metadata): void { - other.internalRepr.forEach((values, key) => { + for (const [key, values] of other.internalRepr) { const mergedValue: MetadataValue[] = ( this.internalRepr.get(key) || [] ).concat(values); this.internalRepr.set(key, mergedValue); - }); + } } setOptions(options: MetadataOptions) { @@ -223,17 +218,13 @@ export class Metadata { toHttp2Headers(): http2.OutgoingHttpHeaders { // NOTE: Node <8.9 formats http2 headers incorrectly. const result: http2.OutgoingHttpHeaders = {}; - this.internalRepr.forEach((values, key) => { + + for (const [key, values] of this.internalRepr) { // We assume that the user's interaction with this object is limited to // through its public API (i.e. keys and values are already validated). - result[key] = values.map((value) => { - if (value instanceof Buffer) { - return value.toString('base64'); - } else { - return value; - } - }); - }); + result[key] = values.map(bufToString); + } + return result; } @@ -248,7 +239,7 @@ export class Metadata { */ toJSON() { const result: { [key: string]: MetadataValue[] } = {}; - for (const [key, values] of this.internalRepr.entries()) { + for (const [key, values] of this.internalRepr) { result[key] = values; } return result; @@ -261,10 +252,10 @@ export class Metadata { */ static fromHttp2Headers(headers: http2.IncomingHttpHeaders): Metadata { const result = new Metadata(); - Object.keys(headers).forEach((key) => { + for (const key of Object.keys(headers)) { // Reserved headers (beginning with `:`) are not valid keys. if (key.charAt(0) === ':') { - return; + continue; } const values = headers[key]; @@ -297,7 +288,12 @@ export class Metadata { const message = `Failed to add metadata entry ${key}: ${values}. ${error.message}. For more information see https://github.com/grpc/grpc-node/issues/1173`; log(LogVerbosity.ERROR, message); } - }); + } + return result; } } + +const bufToString = (val: string | Buffer): string => { + return Buffer.isBuffer(val) ? val.toString('base64') : val +}; diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index 1f7f3eb04..84ff7c8ee 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -19,8 +19,9 @@ import { EventEmitter } from 'events'; import * as http2 from 'http2'; import { Duplex, Readable, Writable } from 'stream'; import * as zlib from 'zlib'; +import { promisify } from 'util'; -import { Deadline, StatusObject } from './call-stream'; +import { Deadline, StatusObject, PartialStatusObject } from './call-stream'; import { Status, DEFAULT_MAX_SEND_MESSAGE_LENGTH, @@ -35,6 +36,8 @@ import { ChannelOptions } from './channel-options'; import * as logging from './logging'; const TRACER_NAME = 'server_call'; +const unzip = promisify(zlib.unzip); +const inflate = promisify(zlib.inflate); function trace(text: string): void { logging.trace(LogVerbosity.DEBUG, TRACER_NAME, text); @@ -86,25 +89,22 @@ export type ServerSurfaceCall = { export type ServerUnaryCall = ServerSurfaceCall & { request: RequestType; }; -export type ServerReadableStream< - RequestType, - ResponseType -> = ServerSurfaceCall & ObjectReadable; -export type ServerWritableStream< - RequestType, - ResponseType -> = ServerSurfaceCall & - ObjectWritable & { - request: RequestType; - end: (metadata?: Metadata) => void; - }; +export type ServerReadableStream = + ServerSurfaceCall & ObjectReadable; +export type ServerWritableStream = + ServerSurfaceCall & + ObjectWritable & { + request: RequestType; + end: (metadata?: Metadata) => void; + }; export type ServerDuplexStream = ServerSurfaceCall & ObjectReadable & ObjectWritable & { end: (metadata?: Metadata) => void }; export class ServerUnaryCallImpl extends EventEmitter - implements ServerUnaryCall { + implements ServerUnaryCall +{ cancelled: boolean; constructor( @@ -136,7 +136,8 @@ export class ServerUnaryCallImpl export class ServerReadableStreamImpl extends Readable - implements ServerReadableStream { + implements ServerReadableStream +{ cancelled: boolean; constructor( @@ -178,7 +179,8 @@ export class ServerReadableStreamImpl export class ServerWritableStreamImpl extends Writable - implements ServerWritableStream { + implements ServerWritableStream +{ cancelled: boolean; private trailingMetadata: Metadata; @@ -257,7 +259,8 @@ export class ServerWritableStreamImpl export class ServerDuplexStreamImpl extends Duplex - implements ServerDuplexStream { + implements ServerDuplexStream +{ cancelled: boolean; private trailingMetadata: Metadata; @@ -395,7 +398,8 @@ export class Http2ServerCallStream< ResponseType > extends EventEmitter { cancelled = false; - deadlineTimer: NodeJS.Timer = setTimeout(() => {}, 0); + deadlineTimer: NodeJS.Timer | null = null; + private statusSent = false; private deadline: Deadline = Infinity; private wantTrailers = false; private metadataSent = false; @@ -428,10 +432,20 @@ export class Http2ServerCallStream< ' stream closed with rstCode ' + this.stream.rstCode ); - this.cancelled = true; - this.emit('cancelled', 'cancelled'); - this.emit('streamEnd', false); - this.sendStatus({code: Status.CANCELLED, details: 'Cancelled by client', metadata: new Metadata()}); + + if (!this.statusSent) { + this.cancelled = true; + this.emit('cancelled', 'cancelled'); + this.emit('streamEnd', false); + this.sendStatus({ + code: Status.CANCELLED, + details: 'Cancelled by client', + metadata: null, + }); + } + + // to compensate for a fact that cancelled is not always called + this.emit('close'); }); this.stream.on('drain', () => { @@ -444,9 +458,6 @@ export class Http2ServerCallStream< if ('grpc.max_receive_message_length' in options) { this.maxReceiveMessageSize = options['grpc.max_receive_message_length']!; } - - // Clear noop timer - clearTimeout(this.deadlineTimer); } private checkCancelled(): boolean { @@ -458,52 +469,22 @@ export class Http2ServerCallStream< return this.cancelled; } - private getDecompressedMessage(message: Buffer, encoding: string) { - switch (encoding) { - case 'deflate': { - return new Promise((resolve, reject) => { - zlib.inflate(message.slice(5), (err, output) => { - if (err) { - this.sendError({ - code: Status.INTERNAL, - details: `Received "grpc-encoding" header "${encoding}" but ${encoding} decompression failed`, - }); - resolve(); - } else { - resolve(output); - } - }); - }); - } - - case 'gzip': { - return new Promise((resolve, reject) => { - zlib.unzip(message.slice(5), (err, output) => { - if (err) { - this.sendError({ - code: Status.INTERNAL, - details: `Received "grpc-encoding" header "${encoding}" but ${encoding} decompression failed`, - }); - resolve(); - } else { - resolve(output); - } - }); - }); - } - - case 'identity': { - return Promise.resolve(message.slice(5)); - } - - default: { - this.sendError({ - code: Status.UNIMPLEMENTED, - details: `Received message compressed with unsupported encoding "${encoding}"`, - }); - return Promise.resolve(); - } + private getDecompressedMessage( + message: Buffer, + encoding: string + ): Buffer | Promise { + if (encoding === 'deflate') { + return inflate(message.subarray(5)); + } else if (encoding === 'gzip') { + return unzip(message.subarray(5)); + } else if (encoding === 'identity') { + return message.subarray(5); } + + return Promise.reject({ + code: Status.UNIMPLEMENTED, + details: `Received message compressed with unsupported encoding "${encoding}"`, + }); } sendMetadata(customMetadata?: Metadata) { @@ -518,13 +499,22 @@ export class Http2ServerCallStream< this.metadataSent = true; const custom = customMetadata ? customMetadata.toHttp2Headers() : null; // TODO(cjihrig): Include compression headers. - const headers = Object.assign({}, defaultResponseHeaders, custom); + const headers = { ...defaultResponseHeaders, ...custom }; this.stream.respond(headers, defaultResponseOptions); } receiveMetadata(headers: http2.IncomingHttpHeaders) { const metadata = Metadata.fromHttp2Headers(headers); + if (logging.isTracerEnabled(TRACER_NAME)) { + trace( + 'Request to ' + + this.handler.path + + ' received headers ' + + JSON.stringify(metadata.toJSON()) + ); + } + // TODO(cjihrig): Receive compression metadata. const timeoutHeader = metadata.get(GRPC_TIMEOUT_HEADER); @@ -556,52 +546,95 @@ export class Http2ServerCallStream< return metadata; } - receiveUnaryMessage(encoding: string): Promise { - return new Promise((resolve, reject) => { - const stream = this.stream; - const chunks: Buffer[] = []; - let totalLength = 0; + receiveUnaryMessage( + encoding: string, + next: ( + err: Partial | null, + request?: RequestType + ) => void + ): void { + const { stream } = this; + + let receivedLength = 0; + const call = this; + const body: Buffer[] = []; + const limit = this.maxReceiveMessageSize; + + stream.on('data', onData); + stream.on('end', onEnd); + stream.on('error', onEnd); + + function onData(chunk: Buffer) { + receivedLength += chunk.byteLength; + + if (limit !== -1 && receivedLength > limit) { + stream.removeListener('data', onData); + stream.removeListener('end', onEnd); + stream.removeListener('error', onEnd); + next({ + code: Status.RESOURCE_EXHAUSTED, + details: `Received message larger than max (${receivedLength} vs. ${limit})`, + }); + return; + } - stream.on('data', (data: Buffer) => { - chunks.push(data); - totalLength += data.byteLength; - }); + body.push(chunk); + } - stream.once('end', async () => { - try { - const requestBytes = Buffer.concat(chunks, totalLength); - if ( - this.maxReceiveMessageSize !== -1 && - requestBytes.length > this.maxReceiveMessageSize - ) { - this.sendError({ - code: Status.RESOURCE_EXHAUSTED, - details: `Received message larger than max (${requestBytes.length} vs. ${this.maxReceiveMessageSize})`, - }); - resolve(); - } - - this.emit('receiveMessage'); - - const compressed = requestBytes.readUInt8(0) === 1; - const compressedMessageEncoding = compressed ? encoding : 'identity'; - const decompressedMessage = await this.getDecompressedMessage(requestBytes, compressedMessageEncoding); - - // Encountered an error with decompression; it'll already have been propogated back - // Just return early - if (!decompressedMessage) { - resolve(); - } - else { - resolve(this.deserializeMessage(decompressedMessage)); - } - } catch (err) { - err.code = Status.INTERNAL; - this.sendError(err); - resolve(); - } - }); - }); + function onEnd(err?: Error) { + stream.removeListener('data', onData); + stream.removeListener('end', onEnd); + stream.removeListener('error', onEnd); + + if (err !== undefined) { + next({ code: Status.INTERNAL, details: err.message }); + return; + } + + if (receivedLength === 0) { + next({ code: Status.INTERNAL, details: 'received empty unary message' }) + return; + } + + call.emit('receiveMessage'); + + const requestBytes = Buffer.concat(body, receivedLength); + const compressed = requestBytes.readUInt8(0) === 1; + const compressedMessageEncoding = compressed ? encoding : 'identity'; + const decompressedMessage = call.getDecompressedMessage( + requestBytes, + compressedMessageEncoding + ); + + if (Buffer.isBuffer(decompressedMessage)) { + call.safeDeserializeMessage(decompressedMessage, next); + return; + } + + decompressedMessage.then( + (decompressed) => call.safeDeserializeMessage(decompressed, next), + (err: any) => next( + err.code + ? err + : { + code: Status.INTERNAL, + details: `Received "grpc-encoding" header "${encoding}" but ${encoding} decompression failed`, + } + ) + ) + } + } + + private safeDeserializeMessage( + buffer: Buffer, + next: (err: Partial | null, request?: RequestType) => void + ) { + try { + next(null, this.deserializeMessage(buffer)); + } catch (err) { + err.code = Status.INTERNAL; + next(err); + } } serializeMessage(value: ResponseType) { @@ -623,18 +656,19 @@ export class Http2ServerCallStream< async sendUnaryMessage( err: ServerErrorResponse | ServerStatusResponse | null, value?: ResponseType | null, - metadata?: Metadata, + metadata?: Metadata | null, flags?: number ) { if (this.checkCancelled()) { return; } - if (!metadata) { - metadata = new Metadata(); + + if (metadata === undefined) { + metadata = null; } if (err) { - if (!Object.prototype.hasOwnProperty.call(err, 'metadata')) { + if (!Object.prototype.hasOwnProperty.call(err, 'metadata') && metadata) { err.metadata = metadata; } this.sendError(err); @@ -652,7 +686,7 @@ export class Http2ServerCallStream< } } - sendStatus(statusObj: StatusObject) { + sendStatus(statusObj: PartialStatusObject) { this.emit('callEnd', statusObj.code); this.emit('streamEnd', statusObj.code === Status.OK); if (this.checkCancelled()) { @@ -668,20 +702,19 @@ export class Http2ServerCallStream< statusObj.details ); - clearTimeout(this.deadlineTimer); + if (this.deadlineTimer) clearTimeout(this.deadlineTimer); if (!this.wantTrailers) { this.wantTrailers = true; this.stream.once('wantTrailers', () => { - const trailersToSend = Object.assign( - { - [GRPC_STATUS_HEADER]: statusObj.code, - [GRPC_MESSAGE_HEADER]: encodeURI(statusObj.details as string), - }, - statusObj.metadata.toHttp2Headers() - ); + const trailersToSend = { + [GRPC_STATUS_HEADER]: statusObj.code, + [GRPC_MESSAGE_HEADER]: encodeURI(statusObj.details), + ...statusObj.metadata?.toHttp2Headers(), + }; this.stream.sendTrailers(trailersToSend); + this.statusSent = true; }); this.sendMetadata(); this.stream.end(); @@ -689,13 +722,13 @@ export class Http2ServerCallStream< } sendError(error: ServerErrorResponse | ServerStatusResponse) { - const status: StatusObject = { + const status: PartialStatusObject = { code: Status.UNKNOWN, details: 'message' in error ? error.message : 'Unknown Error', metadata: 'metadata' in error && error.metadata !== undefined ? error.metadata - : new Metadata(), + : null, }; if ( @@ -744,6 +777,9 @@ export class Http2ServerCallStream< call.emit('cancelled', reason); }); + // to compensate for the fact that cancelled is no longer always called + this.once('close', () => call.emit('close')) + this.once('callEnd', (status) => call.emit('callEnd', status)); } @@ -766,7 +802,7 @@ export class Http2ServerCallStream< pushedEnd = true; this.pushOrBufferMessage(readable, null); } - } + }; this.stream.on('data', async (data: Buffer) => { const messages = decoder.write(data); @@ -788,12 +824,15 @@ export class Http2ServerCallStream< const compressed = message.readUInt8(0) === 1; const compressedMessageEncoding = compressed ? encoding : 'identity'; - const decompressedMessage = await this.getDecompressedMessage(message, compressedMessageEncoding); + const decompressedMessage = await this.getDecompressedMessage( + message, + compressedMessageEncoding + ); // Encountered an error with decompression; it'll already have been propogated back // Just return early if (!decompressedMessage) return; - + this.pushOrBufferMessage(readable, decompressedMessage); } pendingMessageProcessing = false; diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 499fde4a3..2e89f459b 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -62,6 +62,10 @@ import { parseUri } from './uri-parser'; import { ChannelzCallTracker, ChannelzChildrenTracker, ChannelzTrace, registerChannelzServer, registerChannelzSocket, ServerInfo, ServerRef, SocketInfo, SocketRef, TlsInfo, unregisterChannelzRef } from './channelz'; import { CipherNameAndProtocol, TLSSocket } from 'tls'; +const { + HTTP2_HEADER_PATH +} = http2.constants + const TRACER_NAME = 'server'; interface BindResult { @@ -77,7 +81,6 @@ function getUnimplementedStatusResponse( return { code: Status.UNIMPLEMENTED, details: `The server does not implement the method ${methodName}`, - metadata: new Metadata(), }; } @@ -147,6 +150,7 @@ export class Server { private sessions = new Map(); private started = false; private options: ChannelOptions; + private serverAddressString: string = 'null' // Channelz Info private readonly channelzEnabled: boolean = true; @@ -165,6 +169,7 @@ export class Server { if (this.channelzEnabled) { this.channelzTrace.addTrace('CT_INFO', 'Server created'); } + this.trace('Server constructed'); } @@ -730,150 +735,210 @@ export class Server { return this.channelzRef; } - private _setupHandlers( - http2Server: http2.Http2Server | http2.Http2SecureServer - ): void { - if (http2Server === null) { - return; + private _verifyContentType(stream: http2.ServerHttp2Stream, headers: http2.IncomingHttpHeaders): boolean { + const contentType = headers[http2.constants.HTTP2_HEADER_CONTENT_TYPE]; + + if ( + typeof contentType !== 'string' || + !contentType.startsWith('application/grpc') + ) { + stream.respond( + { + [http2.constants.HTTP2_HEADER_STATUS]: + http2.constants.HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE, + }, + { endStream: true } + ); + return false } - http2Server.on( - 'stream', - (stream: http2.ServerHttp2Stream, headers: http2.IncomingHttpHeaders) => { - const channelzSessionInfo = this.sessions.get(stream.session as http2.ServerHttp2Session); - if (this.channelzEnabled) { - this.callTracker.addCallStarted(); - channelzSessionInfo?.streamTracker.addCallStarted(); - } - const contentType = headers[http2.constants.HTTP2_HEADER_CONTENT_TYPE]; - - if ( - typeof contentType !== 'string' || - !contentType.startsWith('application/grpc') - ) { - stream.respond( - { - [http2.constants.HTTP2_HEADER_STATUS]: - http2.constants.HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE, - }, - { endStream: true } - ); - this.callTracker.addCallFailed(); - if (this.channelzEnabled) { - channelzSessionInfo?.streamTracker.addCallFailed(); - } - return; - } + return true + } - let call: Http2ServerCallStream | null = null; + private _retrieveHandler(headers: http2.IncomingHttpHeaders): Handler { + const path = headers[HTTP2_HEADER_PATH] as string - try { - const path = headers[http2.constants.HTTP2_HEADER_PATH] as string; - const serverAddress = http2Server.address(); - let serverAddressString = 'null'; - if (serverAddress) { - if (typeof serverAddress === 'string') { - serverAddressString = serverAddress; - } else { - serverAddressString = - serverAddress.address + ':' + serverAddress.port; - } - } - this.trace( - 'Received call to method ' + - path + - ' at address ' + - serverAddressString - ); - const handler = this.handlers.get(path); + this.trace( + 'Received call to method ' + + path + + ' at address ' + + this.serverAddressString + ); - if (handler === undefined) { - this.trace( - 'No handler registered for method ' + - path + - '. Sending UNIMPLEMENTED status.' - ); - throw getUnimplementedStatusResponse(path); - } + const handler = this.handlers.get(path); - call = new Http2ServerCallStream(stream, handler, this.options); - call.once('callEnd', (code: Status) => { - if (code === Status.OK) { - this.callTracker.addCallSucceeded(); - } else { - this.callTracker.addCallFailed(); - } - }); - if (this.channelzEnabled && channelzSessionInfo) { - call.once('streamEnd', (success: boolean) => { - if (success) { - channelzSessionInfo.streamTracker.addCallSucceeded(); - } else { - channelzSessionInfo.streamTracker.addCallFailed(); - } - }); - call.on('sendMessage', () => { - channelzSessionInfo.messagesSent += 1; - channelzSessionInfo.lastMessageSentTimestamp = new Date(); - }); - call.on('receiveMessage', () => { - channelzSessionInfo.messagesReceived += 1; - channelzSessionInfo.lastMessageReceivedTimestamp = new Date(); - }); - } - const metadata = call.receiveMetadata(headers); - const encoding = (metadata.get('grpc-encoding')[0] as string | undefined) ?? 'identity'; - metadata.remove('grpc-encoding'); - - switch (handler.type) { - case 'unary': - handleUnary(call, handler as UntypedUnaryHandler, metadata, encoding); - break; - case 'clientStream': - handleClientStreaming( - call, - handler as UntypedClientStreamingHandler, - metadata, - encoding - ); - break; - case 'serverStream': - handleServerStreaming( - call, - handler as UntypedServerStreamingHandler, - metadata, - encoding - ); - break; - case 'bidi': - handleBidiStreaming( - call, - handler as UntypedBidiStreamingHandler, - metadata, - encoding - ); - break; - default: - throw new Error(`Unknown handler type: ${handler.type}`); - } - } catch (err) { - if (!call) { - call = new Http2ServerCallStream(stream, null!, this.options); - if (this.channelzEnabled) { - this.callTracker.addCallFailed(); - channelzSessionInfo?.streamTracker.addCallFailed() - } - } + if (handler === undefined) { + this.trace( + 'No handler registered for method ' + + path + + '. Sending UNIMPLEMENTED status.' + ); + throw getUnimplementedStatusResponse(path); + } - if (err.code === undefined) { - err.code = Status.INTERNAL; - } + return handler + } + + private _respondWithError>( + err: T, + stream: http2.ServerHttp2Stream, + channelzSessionInfo: ChannelzSessionInfo | null = null + ) { + const call = new Http2ServerCallStream(stream, null!, this.options); + + if (err.code === undefined) { + err.code = Status.INTERNAL; + } - call.sendError(err); + if (this.channelzEnabled) { + this.callTracker.addCallFailed(); + channelzSessionInfo?.streamTracker.addCallFailed() + } + + call.sendError(err); + } + + private _channelzHandler(stream: http2.ServerHttp2Stream, headers: http2.IncomingHttpHeaders) { + 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 + } + + let handler: Handler + try { + handler = this._retrieveHandler(headers) + } catch (err) { + this._respondWithError(err, stream, channelzSessionInfo) + return + } + + const call = new Http2ServerCallStream(stream, handler, this.options); + + call.once('callEnd', (code: Status) => { + if (code === Status.OK) { + this.callTracker.addCallSucceeded(); + } else { + this.callTracker.addCallFailed(); + } + }); + + if (channelzSessionInfo) { + call.once('streamEnd', (success: boolean) => { + if (success) { + channelzSessionInfo.streamTracker.addCallSucceeded(); + } else { + channelzSessionInfo.streamTracker.addCallFailed(); } + }); + call.on('sendMessage', () => { + channelzSessionInfo.messagesSent += 1; + channelzSessionInfo.lastMessageSentTimestamp = new Date(); + }); + call.on('receiveMessage', () => { + channelzSessionInfo.messagesReceived += 1; + channelzSessionInfo.lastMessageReceivedTimestamp = new Date(); + }); + } + + if (!this._runHandlerForCall(call, handler, headers)) { + this.callTracker.addCallFailed(); + channelzSessionInfo?.streamTracker.addCallFailed() + + call.sendError({ + code: Status.INTERNAL, + details: `Unknown handler type: ${handler.type}` + }); + } + } + + private _streamHandler(stream: http2.ServerHttp2Stream, headers: http2.IncomingHttpHeaders) { + if (this._verifyContentType(stream, headers) !== true) { + return + } + + let handler: Handler + try { + handler = this._retrieveHandler(headers) + } catch (err) { + this._respondWithError(err, stream, null) + return + } + + const call = new Http2ServerCallStream(stream, handler, this.options) + if (!this._runHandlerForCall(call, handler, headers)) { + call.sendError({ + code: Status.INTERNAL, + details: `Unknown handler type: ${handler.type}` + }); + } + } + + private _runHandlerForCall(call: Http2ServerCallStream, handler: Handler, headers: http2.IncomingHttpHeaders): boolean { + const metadata = call.receiveMetadata(headers); + const encoding = (metadata.get('grpc-encoding')[0] as string | undefined) ?? 'identity'; + metadata.remove('grpc-encoding'); + + const { type } = handler + if (type === 'unary') { + handleUnary(call, handler as UntypedUnaryHandler, metadata, encoding); + } else if (type === 'clientStream') { + handleClientStreaming( + call, + handler as UntypedClientStreamingHandler, + metadata, + encoding + ); + } else if (type === 'serverStream') { + handleServerStreaming( + call, + handler as UntypedServerStreamingHandler, + metadata, + encoding + ); + } else if (type === 'bidi') { + handleBidiStreaming( + call, + handler as UntypedBidiStreamingHandler, + metadata, + encoding + ); + } 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 + : this._streamHandler + http2Server.on('stream', handler.bind(this)) http2Server.on('session', (session) => { if (!this.started) { session.destroy(); @@ -910,35 +975,40 @@ export class Server { } } -async function handleUnary( +function handleUnary( call: Http2ServerCallStream, handler: UnaryHandler, metadata: Metadata, encoding: string -): Promise { - const request = await call.receiveUnaryMessage(encoding); +): void { + call.receiveUnaryMessage(encoding, (err, request) => { + if (err) { + call.sendError(err) + return + } - if (request === undefined || call.cancelled) { - return; - } + if (request === undefined || call.cancelled) { + return; + } - const emitter = new ServerUnaryCallImpl( - call, - metadata, - request - ); + const emitter = new ServerUnaryCallImpl( + call, + metadata, + request + ); - handler.func( - emitter, - ( - err: ServerErrorResponse | ServerStatusResponse | null, - value?: ResponseType | null, - trailer?: Metadata, - flags?: number - ) => { - call.sendUnaryMessage(err, value, trailer, flags); - } - ); + handler.func( + emitter, + ( + err: ServerErrorResponse | ServerStatusResponse | null, + value?: ResponseType | null, + trailer?: Metadata, + flags?: number + ) => { + call.sendUnaryMessage(err, value, trailer, flags); + } + ); + }); } function handleClientStreaming( @@ -972,26 +1042,31 @@ function handleClientStreaming( handler.func(stream, respond); } -async function handleServerStreaming( +function handleServerStreaming( call: Http2ServerCallStream, handler: ServerStreamingHandler, metadata: Metadata, encoding: string -): Promise { - const request = await call.receiveUnaryMessage(encoding); +): void { + call.receiveUnaryMessage(encoding, (err, request) => { + if (err) { + call.sendError(err) + return + } - if (request === undefined || call.cancelled) { - return; - } + if (request === undefined || call.cancelled) { + return; + } - const stream = new ServerWritableStreamImpl( - call, - metadata, - handler.serialize, - request - ); + const stream = new ServerWritableStreamImpl( + call, + metadata, + handler.serialize, + request + ); - handler.func(stream); + handler.func(stream); + }); } function handleBidiStreaming( From 93de96f490d5683315532ee0bcdbcccff04c5ed3 Mon Sep 17 00:00:00 2001 From: AVVS Date: Wed, 19 Oct 2022 15:25:42 -0700 Subject: [PATCH 352/450] revert: extra close event on stream --- packages/grpc-js/src/server-call.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index 84ff7c8ee..6ddfe13b9 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -443,9 +443,6 @@ export class Http2ServerCallStream< metadata: null, }); } - - // to compensate for a fact that cancelled is not always called - this.emit('close'); }); this.stream.on('drain', () => { @@ -777,9 +774,6 @@ export class Http2ServerCallStream< call.emit('cancelled', reason); }); - // to compensate for the fact that cancelled is no longer always called - this.once('close', () => call.emit('close')) - this.once('callEnd', (status) => call.emit('callEnd', status)); } From 035c260e3665ebcd67b2be3477d3fe8f08f787d7 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 18 Oct 2022 13:25:58 -0700 Subject: [PATCH 353/450] grpc-js: Implement retries --- packages/grpc-js/src/channel-options.ts | 11 + packages/grpc-js/src/internal-channel.ts | 45 +- packages/grpc-js/src/load-balancing-call.ts | 13 +- .../grpc-js/src/resolving-load-balancer.ts | 3 +- packages/grpc-js/src/retrying-call.ts | 590 ++++++++++++++++++ packages/grpc-js/src/service-config.ts | 95 ++- packages/grpc-js/src/subchannel-call.ts | 14 +- packages/grpc-js/src/subchannel.ts | 4 +- 8 files changed, 762 insertions(+), 13 deletions(-) create mode 100644 packages/grpc-js/src/retrying-call.ts diff --git a/packages/grpc-js/src/channel-options.ts b/packages/grpc-js/src/channel-options.ts index b7fc92fa9..0842f4e1c 100644 --- a/packages/grpc-js/src/channel-options.ts +++ b/packages/grpc-js/src/channel-options.ts @@ -44,6 +44,14 @@ export interface ChannelOptions { 'grpc.default_compression_algorithm'?: CompressionAlgorithms; 'grpc.enable_channelz'?: number; 'grpc.dns_min_time_between_resolutions_ms'?: number; + 'grpc.enable_retries'?: number; + 'grpc.per_rpc_retry_buffer_size'?: number; + /* This option is pattered like a core option, but the core does not have + * this option. It is closely related to the option + * grpc.per_rpc_retry_buffer_size, which is in the core. The core will likely + * implement this functionality using the ResourceQuota mechanism, so there + * will probably not be any collision or other inconsistency. */ + 'grpc.retry_buffer_size'?: number; 'grpc-node.max_session_memory'?: number; // eslint-disable-next-line @typescript-eslint/no-explicit-any [key: string]: any; @@ -71,6 +79,9 @@ export const recognizedOptions = { 'grpc.enable_http_proxy': true, 'grpc.enable_channelz': true, 'grpc.dns_min_time_between_resolutions_ms': true, + 'grpc.enable_retries': true, + 'grpc.per_rpc_retry_buffer_size': true, + 'grpc.retry_buffer_size': true, 'grpc-node.max_session_memory': true, }; diff --git a/packages/grpc-js/src/internal-channel.ts b/packages/grpc-js/src/internal-channel.ts index 16f4b9832..d0ae88c5d 100644 --- a/packages/grpc-js/src/internal-channel.ts +++ b/packages/grpc-js/src/internal-channel.ts @@ -50,6 +50,7 @@ import { Deadline, getDeadlineTimeoutString } from './deadline'; import { ResolvingCall } from './resolving-call'; import { getNextCallNumber } from './call-number'; import { restrictControlPlaneStatusCode } from './control-plane-status'; +import { MessageBufferTracker, RetryingCall, RetryThrottler } from './retrying-call'; /** * See https://nodejs.org/api/timers.html#timers_setinterval_callback_delay_args @@ -78,6 +79,11 @@ interface ErrorConfigResult { type GetConfigResult = NoneConfigResult | SuccessConfigResult | ErrorConfigResult; +const RETRY_THROTTLER_MAP: Map = new Map(); + +const DEFAULT_RETRY_BUFFER_SIZE_BYTES = 1<<24; // 16 MB +const DEFAULT_PER_RPC_RETRY_BUFFER_SIZE_BYTES = 1<<20; // 1 MB + export class InternalChannel { private resolvingLoadBalancer: ResolvingLoadBalancer; @@ -111,6 +117,7 @@ export class InternalChannel { * than TRANSIENT_FAILURE. */ private currentResolutionError: StatusObject | null = null; + private retryBufferTracker: MessageBufferTracker; // Channelz info private readonly channelzEnabled: boolean = true; @@ -179,6 +186,10 @@ export class InternalChannel { this.subchannelPool = getSubchannelPool( (options['grpc.use_local_subchannel_pool'] ?? 0) === 0 ); + this.retryBufferTracker = new MessageBufferTracker( + options['grpc.retry_buffer_size'] ?? DEFAULT_RETRY_BUFFER_SIZE_BYTES, + options['grpc.per_rpc_retry_buffer_size'] ?? DEFAULT_PER_RPC_RETRY_BUFFER_SIZE_BYTES + ); const channelControlHelper: ChannelControlHelper = { createSubchannel: ( subchannelAddress: SubchannelAddress, @@ -226,7 +237,12 @@ export class InternalChannel { this.target, channelControlHelper, options, - (configSelector) => { + (serviceConfig, configSelector) => { + if (serviceConfig.retryThrottling) { + RETRY_THROTTLER_MAP.set(this.getTarget(), new RetryThrottler(serviceConfig.retryThrottling.maxTokens, serviceConfig.retryThrottling.tokenRatio, RETRY_THROTTLER_MAP.get(this.getTarget()))); + } else { + RETRY_THROTTLER_MAP.delete(this.getTarget()); + } if (this.channelzEnabled) { this.channelzTrace.addTrace('CT_INFO', 'Address resolution succeeded'); } @@ -243,6 +259,7 @@ export class InternalChannel { } this.configSelectionQueue = []; }); + }, (status) => { if (this.channelzEnabled) { @@ -405,6 +422,24 @@ export class InternalChannel { return new LoadBalancingCall(this, callConfig, method, host, credentials, deadline, callNumber); } + createRetryingCall( + callConfig: CallConfig, + method: string, + host: string, + credentials: CallCredentials, + deadline: Deadline + ): RetryingCall { + const callNumber = getNextCallNumber(); + this.trace( + 'createRetryingCall [' + + callNumber + + '] method="' + + method + + '"' + ); + return new RetryingCall(this, callConfig, method, host, credentials, deadline, callNumber, this.retryBufferTracker, RETRY_THROTTLER_MAP.get(this.getTarget())) + } + createInnerCall( callConfig: CallConfig, method: string, @@ -413,7 +448,11 @@ export class InternalChannel { deadline: Deadline ): Call { // Create a RetryingCall if retries are enabled - return this.createLoadBalancingCall(callConfig, method, host, credentials, deadline); + if (this.options['grpc.enable_retries'] === 0) { + return this.createLoadBalancingCall(callConfig, method, host, credentials, deadline); + } else { + return this.createRetryingCall(callConfig, method, host, credentials, deadline); + } } createResolvingCall( @@ -439,7 +478,7 @@ export class InternalChannel { parentCall: parentCall, }; - const call = new ResolvingCall(this, method, finalOptions, this.filterStackFactory, this.credentials._getCallCredentials(), getNextCallNumber()); + const call = new ResolvingCall(this, method, finalOptions, this.filterStackFactory, this.credentials._getCallCredentials(), callNumber); if (this.channelzEnabled) { this.callTracker.addCallStarted(); diff --git a/packages/grpc-js/src/load-balancing-call.ts b/packages/grpc-js/src/load-balancing-call.ts index 6faa15592..23b9a9174 100644 --- a/packages/grpc-js/src/load-balancing-call.ts +++ b/packages/grpc-js/src/load-balancing-call.ts @@ -29,6 +29,7 @@ import { CallConfig } from "./resolver"; import { splitHostPort } from "./uri-parser"; import * as logging from './logging'; import { restrictControlPlaneStatusCode } from "./control-plane-status"; +import * as http2 from 'http2'; const TRACER_NAME = 'load_balancing_call'; @@ -38,6 +39,10 @@ export interface StatusObjectWithProgress extends StatusObject { progress: RpcProgress; } +export interface LoadBalancingCallInterceptingListener extends InterceptingListener { + onReceiveStatus(status: StatusObjectWithProgress): void; +} + export class LoadBalancingCall implements Call { private child: SubchannelCall | null = null; private readPending = false; @@ -151,7 +156,11 @@ export class LoadBalancingCall implements Call { this.listener!.onReceiveMessage(message); }, onReceiveStatus: status => { - this.outputStatus(status, 'PROCESSED'); + if (status.code === http2.constants.NGHTTP2_REFUSED_STREAM) { + this.outputStatus(status, 'REFUSED'); + } else { + this.outputStatus(status, 'PROCESSED'); + } } }); } catch (error) { @@ -226,7 +235,7 @@ export class LoadBalancingCall implements Call { getPeer(): string { return this.child?.getPeer() ?? this.channel.getTarget(); } - start(metadata: Metadata, listener: InterceptingListener): void { + start(metadata: Metadata, listener: LoadBalancingCallInterceptingListener): void { this.trace('start called'); this.listener = listener; this.metadata = metadata; diff --git a/packages/grpc-js/src/resolving-load-balancer.ts b/packages/grpc-js/src/resolving-load-balancer.ts index da097cc42..a39606f2c 100644 --- a/packages/grpc-js/src/resolving-load-balancer.ts +++ b/packages/grpc-js/src/resolving-load-balancer.ts @@ -83,7 +83,7 @@ function getDefaultConfigSelector( } export interface ResolutionCallback { - (configSelector: ConfigSelector): void; + (serviceConfig: ServiceConfig, configSelector: ConfigSelector): void; } export interface ResolutionFailureCallback { @@ -239,6 +239,7 @@ export class ResolvingLoadBalancer implements LoadBalancer { const finalServiceConfig = workingServiceConfig ?? this.defaultServiceConfig; this.onSuccessfulResolution( + finalServiceConfig, configSelector ?? getDefaultConfigSelector(finalServiceConfig) ); }, diff --git a/packages/grpc-js/src/retrying-call.ts b/packages/grpc-js/src/retrying-call.ts new file mode 100644 index 000000000..7c15023d5 --- /dev/null +++ b/packages/grpc-js/src/retrying-call.ts @@ -0,0 +1,590 @@ +/* + * 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. + * + */ + +import { CallCredentials } from "./call-credentials"; +import { LogVerbosity, Status } from "./constants"; +import { Deadline } from "./deadline"; +import { Metadata } from "./metadata"; +import { CallConfig } from "./resolver"; +import * as logging from './logging'; +import { Call, InterceptingListener, MessageContext, StatusObject, WriteCallback, WriteObject } from "./call-interface"; +import { LoadBalancingCall, StatusObjectWithProgress } from "./load-balancing-call"; +import { InternalChannel } from "./internal-channel"; + +const TRACER_NAME = 'retrying_call'; + +export class RetryThrottler { + private tokens: number; + constructor(private readonly maxTokens: number, private readonly tokenRatio: number, previousRetryThrottler?: RetryThrottler) { + if (previousRetryThrottler) { + /* When carrying over tokens from a previous config, rescale them to the + * new max value */ + this.tokens = previousRetryThrottler.tokens * (maxTokens / previousRetryThrottler.maxTokens); + } else { + this.tokens = maxTokens; + } + } + + addCallSucceeded() { + this.tokens = Math.max(this.tokens + this.tokenRatio, this.maxTokens); + } + + addCallFailed() { + this.tokens = Math.min(this.tokens - 1, 0); + } + + canRetryCall() { + return this.tokens > this.maxTokens / 2; + } +} + +export class MessageBufferTracker { + private totalAllocated: number = 0; + private allocatedPerCall: Map = new Map(); + + constructor(private totalLimit: number, private limitPerCall: number) {} + + allocate(size: number, callId: number): boolean { + const currentPerCall = this.allocatedPerCall.get(callId) ?? 0; + if (this.limitPerCall - currentPerCall < size || this.totalLimit - this.totalAllocated < size) { + return false; + } + this.allocatedPerCall.set(callId, currentPerCall + size); + this.totalAllocated += size; + return true; + } + + free(size: number, callId: number) { + if (this.totalAllocated < size) { + throw new Error(`Invalid buffer allocation state: call ${callId} freed ${size} > total allocated ${this.totalAllocated}`); + } + this.totalAllocated -= size; + const currentPerCall = this.allocatedPerCall.get(callId) ?? 0; + if (currentPerCall < size) { + throw new Error(`Invalid buffer allocation state: call ${callId} freed ${size} > allocated for call ${currentPerCall}`); + } + this.allocatedPerCall.set(callId, currentPerCall - size); + } + + freeAll(callId: number) { + const currentPerCall = this.allocatedPerCall.get(callId) ?? 0; + if (this.totalAllocated < currentPerCall) { + throw new Error(`Invalid buffer allocation state: call ${callId} allocated ${currentPerCall} > total allocated ${this.totalAllocated}`); + } + this.totalAllocated -= currentPerCall; + this.allocatedPerCall.delete(callId); + } +} + +type UnderlyingCallState = 'ACTIVE' | 'COMPLETED'; + +interface UnderlyingCall { + state: UnderlyingCallState; + call: LoadBalancingCall; + nextMessageToSend: number; +} + +/** + * A retrying call can be in one of these states: + * RETRY: Retries are configured and new attempts may be sent + * HEDGING: Hedging is configured and new attempts may be sent + * TRANSPARENT_ONLY: Neither retries nor hedging are configured, and + * transparent retry attempts may still be sent + * COMMITTED: One attempt is committed, and no new attempts will be + * sent + */ +type RetryingCallState = 'RETRY' | 'HEDGING' | 'TRANSPARENT_ONLY' | 'COMMITTED'; + +/** + * The different types of objects that can be stored in the write buffer, with + * the following meanings: + * MESSAGE: This is a message to be sent. + * HALF_CLOSE: When this entry is reached, the calls should send a half-close. + * FREED: This slot previously contained a message that has been sent on all + * child calls and is no longer needed. + */ +type WriteBufferEntryType = 'MESSAGE' | 'HALF_CLOSE' | 'FREED'; + +/** + * Entry in the buffer of messages to send to the remote end. + */ +interface WriteBufferEntry { + entryType: WriteBufferEntryType; + /** + * Message to send. + * Only populated if entryType is MESSAGE. + */ + message?: WriteObject; + /** + * Callback to call after sending the message. + * Only populated if entryType is MESSAGE and the call is in the COMMITTED + * state. + */ + callback?: WriteCallback; +} + +const PREVIONS_RPC_ATTEMPTS_METADATA_KEY = 'grpc-previous-rpc-attempts'; + +export class RetryingCall implements Call { + private state: RetryingCallState; + private listener: InterceptingListener | null = null; + private initialMetadata: Metadata | null = null; + private underlyingCalls: UnderlyingCall[] = []; + private writeBuffer: WriteBufferEntry[] = []; + private transparentRetryUsed: boolean = false; + /** + * Number of attempts so far + */ + private attempts: number = 0; + private hedgingTimer: NodeJS.Timer | null = null; + private committedCallIndex: number | null = null; + private initialRetryBackoffSec = 0; + private nextRetryBackoffSec = 0; + constructor( + private readonly channel: InternalChannel, + private readonly callConfig: CallConfig, + private readonly methodName: string, + private readonly host: string, + private readonly credentials: CallCredentials, + private readonly deadline: Deadline, + private readonly callNumber: number, + private readonly bufferTracker: MessageBufferTracker, + private readonly retryThrottler?: RetryThrottler + ) { + if (callConfig.methodConfig.retryPolicy) { + this.state = 'RETRY'; + const retryPolicy = callConfig.methodConfig.retryPolicy; + this.nextRetryBackoffSec = this.initialRetryBackoffSec = Number(retryPolicy.initialBackoff.substring(0, retryPolicy.initialBackoff.length - 1)); + } else if (callConfig.methodConfig.hedgingPolicy) { + this.state = 'HEDGING'; + } else { + this.state = 'TRANSPARENT_ONLY'; + } + } + getCallNumber(): number { + return this.callNumber; + } + + private trace(text: string): void { + logging.trace( + LogVerbosity.DEBUG, + TRACER_NAME, + '[' + this.callNumber + '] ' + text + ); + } + + private reportStatus(statusObject: StatusObject) { + this.trace('ended with status: code=' + statusObject.code + ' details="' + statusObject.details + '"'); + process.nextTick(() => { + this.listener?.onReceiveStatus(statusObject); + }); + } + + cancelWithStatus(status: Status, details: string): void { + this.trace('cancelWithStatus code: ' + status + ' details: "' + details + '"'); + this.reportStatus({code: status, details, metadata: new Metadata()}); + for (const {call} of this.underlyingCalls) { + call.cancelWithStatus(status, details); + } + } + getPeer(): string { + if (this.committedCallIndex !== null) { + return this.underlyingCalls[this.committedCallIndex].call.getPeer(); + } else { + return 'unknown'; + } + } + + private commitCall(index: number) { + if (this.state === 'COMMITTED') { + return; + } + if (this.underlyingCalls[index].state === 'COMPLETED') { + return; + } + this.trace('Committing call [' + this.underlyingCalls[index].call.getCallNumber() + '] at index ' + index); + this.state = 'COMMITTED'; + this.committedCallIndex = index; + for (let i = 0; i < this.underlyingCalls.length; i++) { + if (i === index) { + continue; + } + if (this.underlyingCalls[i].state === 'COMPLETED') { + continue; + } + this.underlyingCalls[i].state = 'COMPLETED'; + this.underlyingCalls[i].call.cancelWithStatus(Status.CANCELLED, 'Discarded in favor of other hedged attempt'); + } + for (let messageIndex = 0; messageIndex < this.underlyingCalls[index].nextMessageToSend - 1; messageIndex += 1) { + const bufferEntry = this.writeBuffer[messageIndex]; + if (bufferEntry.entryType === 'MESSAGE') { + this.bufferTracker.free(bufferEntry.message!.message.length, this.callNumber); + this.writeBuffer[messageIndex] = { + entryType: 'FREED' + }; + } + } + } + + private commitCallWithMostMessages() { + let mostMessages = -1; + let callWithMostMessages = -1; + for (const [index, childCall] of this.underlyingCalls.entries()) { + if (childCall.nextMessageToSend > mostMessages) { + mostMessages = childCall.nextMessageToSend; + callWithMostMessages = index; + } + } + this.commitCall(callWithMostMessages); + } + + private isStatusCodeInList(list: (Status | string)[], code: Status) { + return list.some((value => value === code || value.toString().toLowerCase() === Status[code].toLowerCase())); + } + + private getNextRetryBackoffMs() { + const retryPolicy = this.callConfig?.methodConfig.retryPolicy; + if (!retryPolicy) { + return 0; + } + const nextBackoffMs = Math.random() * this.nextRetryBackoffSec * 1000; + const maxBackoffSec = Number(retryPolicy.maxBackoff.substring(0, retryPolicy.maxBackoff.length - 1)); + this.nextRetryBackoffSec = Math.min(this.nextRetryBackoffSec * retryPolicy.backoffMultiplier, maxBackoffSec); + return nextBackoffMs + } + + private maybeRetryCall(pushback: number | null, callback: (retried: boolean) => void) { + if (this.state !== 'RETRY') { + callback(false); + return; + } + const retryPolicy = this.callConfig!.methodConfig.retryPolicy!; + if (this.attempts >= retryPolicy.maxAttempts) { + callback(false); + return; + } + let retryDelayMs: number; + if (pushback === null) { + retryDelayMs = this.getNextRetryBackoffMs(); + } else if (pushback < 0) { + this.state = 'TRANSPARENT_ONLY'; + callback(false); + return; + } else { + retryDelayMs = pushback; + this.nextRetryBackoffSec = this.initialRetryBackoffSec; + } + setTimeout(() => { + if (this.state !== 'RETRY') { + callback(false); + return; + } + if (this.retryThrottler?.canRetryCall() ?? true) { + callback(true); + this.attempts += 1; + this.startNewAttempt(); + } + }, retryDelayMs); + } + + private countActiveCalls(): number { + let count = 0; + for (const call of this.underlyingCalls) { + if (call?.state === 'ACTIVE') { + count += 1; + } + } + return count; + } + + private handleProcessedStatus(status: StatusObject, callIndex: number, pushback: number | null) { + switch (this.state) { + case 'COMMITTED': + case 'TRANSPARENT_ONLY': + this.commitCall(callIndex); + this.reportStatus(status); + break; + case 'HEDGING': + if (this.isStatusCodeInList(this.callConfig!.methodConfig.hedgingPolicy!.nonFatalStatusCodes, status.code)) { + this.retryThrottler?.addCallFailed(); + let delayMs: number; + if (pushback === null) { + delayMs = 0; + } else if (pushback < 0) { + this.state = 'TRANSPARENT_ONLY'; + this.commitCall(callIndex); + this.reportStatus(status); + return; + } else { + delayMs = pushback; + } + setTimeout(() => { + this.maybeStartHedgingAttempt(); + // If after trying to start a call there are no active calls, this was the last one + if (this.countActiveCalls() === 0) { + this.commitCall(callIndex); + this.reportStatus(status); + } + }, delayMs); + } else { + this.commitCall(callIndex); + this.reportStatus(status); + } + break; + case 'RETRY': + if (this.isStatusCodeInList(this.callConfig!.methodConfig.retryPolicy!.retryableStatusCodes, status.code)) { + this.retryThrottler?.addCallFailed(); + this.maybeRetryCall(pushback, (retried) => { + if (!retried) { + this.commitCall(callIndex); + this.reportStatus(status); + } + }); + } else { + this.commitCall(callIndex); + this.reportStatus(status); + } + break; + } + } + + private getPushback(metadata: Metadata): number | null { + const mdValue = metadata.get('grpc-retry-pushback-ms'); + if (mdValue.length === 0) { + return null; + } + try { + return parseInt(mdValue[0] as string); + } catch (e) { + return -1; + } + } + + private handleChildStatus(status: StatusObjectWithProgress, callIndex: number) { + if (this.underlyingCalls[callIndex].state === 'COMPLETED') { + return; + } + this.underlyingCalls[callIndex].state = 'COMPLETED'; + if (status.code === Status.OK) { + this.retryThrottler?.addCallSucceeded(); + this.commitCall(callIndex); + this.reportStatus(status); + return; + } + if (this.state === 'COMMITTED') { + this.reportStatus(status); + return; + } + const pushback = this.getPushback(status.metadata); + switch (status.progress) { + case 'NOT_STARTED': + // RPC never leaves the client, always safe to retry + this.startNewAttempt(); + break; + case 'REFUSED': + // RPC reaches the server library, but not the server application logic + if (this.transparentRetryUsed) { + this.handleProcessedStatus(status, callIndex, pushback); + } else { + this.transparentRetryUsed = true; + this.startNewAttempt(); + }; + break; + case 'DROP': + this.commitCall(callIndex); + this.reportStatus(status); + break; + case 'PROCESSED': + this.handleProcessedStatus(status, callIndex, pushback); + break; + } + } + + private maybeStartHedgingAttempt() { + if (this.state !== 'HEDGING') { + return; + } + if (!this.callConfig.methodConfig.hedgingPolicy) { + return; + } + const hedgingPolicy = this.callConfig.methodConfig.hedgingPolicy; + if (this.attempts >= hedgingPolicy.maxAttempts) { + return; + } + this.attempts += 1; + this.startNewAttempt(); + this.maybeStartHedgingTimer(); + } + + private maybeStartHedgingTimer() { + if (this.hedgingTimer) { + clearTimeout(this.hedgingTimer); + } + if (this.state !== 'HEDGING') { + return; + } + if (!this.callConfig.methodConfig.hedgingPolicy) { + return; + } + const hedgingPolicy = this.callConfig.methodConfig.hedgingPolicy; + if (this.attempts >= hedgingPolicy.maxAttempts) { + return; + } + const hedgingDelayString = hedgingPolicy.hedgingDelay ?? '0s'; + const hedgingDelaySec = Number(hedgingDelayString.substring(0, hedgingDelayString.length - 1)); + this.hedgingTimer = setTimeout(() => { + this.maybeStartHedgingAttempt(); + }, hedgingDelaySec * 1000); + this.hedgingTimer.unref?.(); + } + + private startNewAttempt() { + const child = this.channel.createLoadBalancingCall(this.callConfig, this.methodName, this.host, this.credentials, this.deadline); + this.trace('Created child call [' + child.getCallNumber() + '] for attempt ' + this.attempts); + const index = this.underlyingCalls.length; + this.underlyingCalls.push({state: 'ACTIVE', call: child, nextMessageToSend: 0}); + const previousAttempts = this.attempts - 1; + const initialMetadata = this.initialMetadata!.clone(); + if (previousAttempts > 0) { + initialMetadata.set(PREVIONS_RPC_ATTEMPTS_METADATA_KEY, `${previousAttempts}`); + } + let receivedMetadata = false; + child.start(initialMetadata, { + onReceiveMetadata: metadata => { + this.commitCall(index); + receivedMetadata = true; + if (previousAttempts > 0) { + metadata.set(PREVIONS_RPC_ATTEMPTS_METADATA_KEY, `${previousAttempts}`); + } + if (this.underlyingCalls[index].state === 'ACTIVE') { + this.listener!.onReceiveMetadata(metadata); + } + }, + onReceiveMessage: message => { + this.commitCall(index); + if (this.underlyingCalls[index].state === 'ACTIVE') { + this.listener!.onReceiveMessage(message); + } + }, + onReceiveStatus: status => { + if (!receivedMetadata && previousAttempts > 0) { + status.metadata.set(PREVIONS_RPC_ATTEMPTS_METADATA_KEY, `${previousAttempts}`); + } + this.commitCall(index); + this.handleChildStatus(status, index); + } + }) + } + + start(metadata: Metadata, listener: InterceptingListener): void { + this.trace('start called'); + this.listener = listener; + this.initialMetadata = metadata; + this.attempts += 1; + this.startNewAttempt(); + this.maybeStartHedgingTimer(); + } + + private sendNextChildMessage(childIndex: number) { + const childCall = this.underlyingCalls[childIndex]; + if (childCall.state === 'COMPLETED') { + return; + } + if (this.writeBuffer[childCall.nextMessageToSend]) { + const bufferEntry = this.writeBuffer[childCall.nextMessageToSend]; + switch (bufferEntry.entryType) { + case 'MESSAGE': + childCall.call.sendMessageWithContext({ + callback: (error) => { + // Ignore error + childCall.nextMessageToSend += 1; + this.sendNextChildMessage(childIndex); + } + }, bufferEntry.message!.message); + break; + case 'HALF_CLOSE': + childCall.nextMessageToSend += 1; + childCall.call.halfClose(); + break; + case 'FREED': + // Should not be possible + break; + } + } + } + + sendMessageWithContext(context: MessageContext, message: Buffer): void { + this.trace('write() called with message of length ' + message.length); + const writeObj: WriteObject = { + message, + flags: context.flags, + }; + const messageIndex = this.writeBuffer.length; + const bufferEntry: WriteBufferEntry = { + entryType: 'MESSAGE', + message: writeObj + }; + this.writeBuffer[messageIndex] = bufferEntry; + if (this.bufferTracker.allocate(message.length, this.callNumber)) { + context.callback?.(); + for (const [callIndex, call] of this.underlyingCalls.entries()) { + if (call.state === 'ACTIVE' && call.nextMessageToSend === messageIndex) { + call.call.sendMessageWithContext({ + callback: (error) => { + // Ignore error + call.nextMessageToSend += 1; + this.sendNextChildMessage(callIndex); + } + }, message); + } + } + } else { + this.commitCallWithMostMessages(); + bufferEntry.callback = context.callback; + } + } + startRead(): void { + this.trace('startRead called'); + for (const underlyingCall of this.underlyingCalls) { + if (underlyingCall?.state === 'ACTIVE') { + underlyingCall.call.startRead(); + } + } + } + halfClose(): void { + this.trace('halfClose called'); + const halfCloseIndex = this.writeBuffer.length; + this.writeBuffer[halfCloseIndex] = { + entryType: 'HALF_CLOSE' + }; + for (const call of this.underlyingCalls) { + if (call?.state === 'ACTIVE' && call.nextMessageToSend === halfCloseIndex) { + call.nextMessageToSend += 1; + call.call.halfClose(); + } + } + } + setCredentials(newCredentials: CallCredentials): void { + throw new Error("Method not implemented."); + } + getMethod(): string { + return this.methodName; + } + getHost(): string { + return this.host; + } +} \ No newline at end of file diff --git a/packages/grpc-js/src/service-config.ts b/packages/grpc-js/src/service-config.ts index 12802dad8..a45355ace 100644 --- a/packages/grpc-js/src/service-config.ts +++ b/packages/grpc-js/src/service-config.ts @@ -86,7 +86,7 @@ export interface ServiceConfigCanaryConfig { * Recognizes a number with up to 9 digits after the decimal point, followed by * an "s", representing a number of seconds. */ -const TIMEOUT_REGEX = /^\d+(\.\d{1,9})?s$/; +const DURATION_REGEX = /^\d+(\.\d{1,9})?s$/; /** * Client language name used for determining whether this client matches a @@ -111,6 +111,75 @@ function validateName(obj: any): MethodConfigName { return result; } +function validateRetryPolicy(obj: any): RetryPolicy { + if (!('maxAttempts' in obj) || !Number.isInteger(obj.maxAttempts) || obj.maxAttempts < 2) { + throw new Error('Invalid method config retry policy: maxAttempts must be an integer at least 2'); + } + if (!('initialBackoff' in obj) || typeof obj.initialBackoff !== 'string' || !DURATION_REGEX.test(obj.initialBackoff)) { + throw new Error('Invalid method config retry policy: initialBackoff must be a string consisting of a positive integer followed by s'); + } + if (!('maxBackoff' in obj) || typeof obj.maxBackoff !== 'string' || !DURATION_REGEX.test(obj.maxBackoff)) { + throw new Error('Invalid method config retry policy: maxBackoff must be a string consisting of a positive integer followed by s'); + } + if (!('backoffMultiplier' in obj) || typeof obj.backoffMultiplier !== 'number' || obj.backoffMultiplier <= 0) { + throw new Error('Invalid method config retry policy: backoffMultiplier must be a number greater than 0'); + } + if (('retryableStatusCodes' in obj) && Array.isArray(obj.retryableStatusCodes)) { + for (const value of obj.retryableStatusCodes) { + if (typeof value === 'number') { + if (!Object.values(Status).includes(value)) { + throw new Error('Invlid method config retry policy: retryableStatusCodes value not in status code range'); + } + } else if (typeof value === 'string') { + if (!Object.values(Status).includes(value.toUpperCase())) { + throw new Error('Invlid method config retry policy: retryableStatusCodes value not a status code name'); + } + } else { + throw new Error('Invlid method config retry policy: retryableStatusCodes value must be a string or number'); + } + } + } + return { + maxAttempts: obj.maxAttempts, + initialBackoff: obj.initialBackoff, + maxBackoff: obj.maxBackoff, + backoffMultiplier: obj.backoffMultiplier, + retryableStatusCodes: obj.retryableStatusCodes + }; +} + +function validateHedgingPolicy(obj: any): HedgingPolicy { + if (!('maxAttempts' in obj) || !Number.isInteger(obj.maxAttempts) || obj.maxAttempts < 2) { + throw new Error('Invalid method config hedging policy: maxAttempts must be an integer at least 2'); + } + if (('hedgingDelay' in obj) && (typeof obj.hedgingDelay !== 'string' || !DURATION_REGEX.test(obj.hedgingDelay))) { + throw new Error('Invalid method config hedging policy: hedgingDelay must be a string consisting of a positive integer followed by s'); + } + if (('nonFatalStatusCodes' in obj) && Array.isArray(obj.nonFatalStatusCodes)) { + for (const value of obj.nonFatalStatusCodes) { + if (typeof value === 'number') { + if (!Object.values(Status).includes(value)) { + throw new Error('Invlid method config hedging policy: nonFatalStatusCodes value not in status code range'); + } + } else if (typeof value === 'string') { + if (!Object.values(Status).includes(value.toUpperCase())) { + throw new Error('Invlid method config hedging policy: nonFatalStatusCodes value not a status code name'); + } + } else { + throw new Error('Invlid method config hedging policy: nonFatalStatusCodes value must be a string or number'); + } + } + } + const result: HedgingPolicy = { + maxAttempts: obj.maxAttempts, + nonFatalStatusCodes: obj.nonFatalStatusCodes + } + if (obj.hedgingDelay) { + result.hedgingDelay = obj.hedgingDelay; + } + return result; +} + function validateMethodConfig(obj: any): MethodConfig { const result: MethodConfig = { name: [], @@ -144,7 +213,7 @@ function validateMethodConfig(obj: any): MethodConfig { result.timeout = obj.timeout; } else if ( typeof obj.timeout === 'string' && - TIMEOUT_REGEX.test(obj.timeout) + DURATION_REGEX.test(obj.timeout) ) { const timeoutParts = obj.timeout .substring(0, obj.timeout.length - 1) @@ -169,9 +238,31 @@ function validateMethodConfig(obj: any): MethodConfig { } result.maxResponseBytes = obj.maxResponseBytes; } + if ('retryPolicy' in obj) { + if ('hedgingPolicy' in obj) { + throw new Error('Invalid method config: retryPolicy and hedgingPolicy cannot both be specified'); + } else { + result.retryPolicy = validateRetryPolicy(obj.retryPolicy); + } + } else if ('hedgingPolicy' in obj) { + result.hedgingPolicy = validateHedgingPolicy(obj.hedgingPolicy); + } return result; } +export function validateRetryThrottling(obj: any): RetryThrottling { + if (!('maxTokens' in obj) || typeof obj.maxTokens !== 'number' || obj.maxTokens <=0 || obj.maxTokens > 1000) { + throw new Error('Invalid retryThrottling: maxTokens must be a number in (0, 1000]'); + } + if (!('tokenRatio' in obj) || typeof obj.tokenRatio !== 'number' || obj.tokenRatio <= 0) { + throw new Error('Invalid retryThrottling: tokenRatio must be a number greater than 0'); + } + return { + maxTokens: +(obj.maxTokens as number).toFixed(3), + tokenRatio: +(obj.tokenRatio as number).toFixed(3) + }; +} + export function validateServiceConfig(obj: any): ServiceConfig { const result: ServiceConfig = { loadBalancingConfig: [], diff --git a/packages/grpc-js/src/subchannel-call.ts b/packages/grpc-js/src/subchannel-call.ts index e2cd645af..2bc6fb0c7 100644 --- a/packages/grpc-js/src/subchannel-call.ts +++ b/packages/grpc-js/src/subchannel-call.ts @@ -75,6 +75,14 @@ export interface SubchannelCall { getCallNumber(): number; } +export interface StatusObjectWithRstCode extends StatusObject { + rstCode?: number; +} + +export interface SubchannelCallInterceptingListener extends InterceptingListener { + onReceiveStatus(status: StatusObjectWithRstCode): void; +} + export class Http2SubchannelCall implements SubchannelCall { private decoder = new StreamDecoder(); @@ -103,7 +111,7 @@ export class Http2SubchannelCall implements SubchannelCall { constructor( private readonly http2Stream: http2.ClientHttp2Stream, private readonly callStatsTracker: SubchannelCallStatsTracker, - private readonly listener: InterceptingListener, + private readonly listener: SubchannelCallInterceptingListener, private readonly subchannel: Subchannel, private readonly callId: number ) { @@ -257,7 +265,7 @@ export class Http2SubchannelCall implements SubchannelCall { // This is OK, because status codes emitted here correspond to more // catastrophic issues that prevent us from receiving trailers in the // first place. - this.endCall({ code, details, metadata: new Metadata() }); + this.endCall({ code, details, metadata: new Metadata(), rstCode: http2Stream.rstCode }); }); }); http2Stream.on('error', (err: SystemError) => { @@ -329,7 +337,7 @@ export class Http2SubchannelCall implements SubchannelCall { * Subsequent calls are no-ops. * @param status The status of the call. */ - private endCall(status: StatusObject): void { + private endCall(status: StatusObjectWithRstCode): void { /* If the status is OK and a new status comes in (e.g. from a * deserialization failure), that new status takes priority */ if (this.finalStatus === null || this.finalStatus.code === Status.OK) { diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 104c36c24..0d9773b30 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -36,7 +36,7 @@ import { } from './subchannel-address'; import { SubchannelRef, ChannelzTrace, ChannelzChildrenTracker, SubchannelInfo, registerChannelzSubchannel, ChannelzCallTracker, SocketInfo, SocketRef, unregisterChannelzRef, registerChannelzSocket, TlsInfo } from './channelz'; import { ConnectivityStateListener } from './subchannel-interface'; -import { Http2SubchannelCall } from './subchannel-call'; +import { Http2SubchannelCall, SubchannelCallInterceptingListener } from './subchannel-call'; import { getNextCallNumber } from './call-number'; import { SubchannelCall } from './subchannel-call'; import { InterceptingListener, StatusObject } from './call-interface'; @@ -815,7 +815,7 @@ export class Subchannel { return false; } - createCall(metadata: Metadata, host: string, method: string, listener: InterceptingListener): SubchannelCall { + createCall(metadata: Metadata, host: string, method: string, listener: SubchannelCallInterceptingListener): SubchannelCall { const headers = metadata.toHttp2Headers(); headers[HTTP2_HEADER_AUTHORITY] = host; headers[HTTP2_HEADER_USER_AGENT] = this.userAgent; From e840d1f855f5320bd1c2ee2a3642e5d92b9bafbb Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 20 Oct 2022 15:47:16 -0700 Subject: [PATCH 354/450] grpc-js: Bump to 1.7.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 087060154..55ddb10aa 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.7.2", + "version": "1.7.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 bcf4ce2b401b7a1d399b19b1fd8d9fe89fc14ebe Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 21 Oct 2022 15:21:19 -0700 Subject: [PATCH 355/450] grpc-js-xds: Log stats periodically in interop tests --- packages/grpc-js-xds/interop/xds-interop-client.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/grpc-js-xds/interop/xds-interop-client.ts b/packages/grpc-js-xds/interop/xds-interop-client.ts index 029525a45..59c505b46 100644 --- a/packages/grpc-js-xds/interop/xds-interop-client.ts +++ b/packages/grpc-js-xds/interop/xds-interop-client.ts @@ -310,6 +310,9 @@ function sendConstantQps(client: TestServiceClient, qps: number, failOnFailedRpc makeSingleRequest(client, callType, failOnFailedRpcs, callStatsTracker); } }, 1000/qps); + setInterval(() => { + console.log(`Accumulated stats: ${JSON.stringify(accumulatedStats, undefined, 2)}`); + }, 1000); } const callTypeEnumMap = { From 124712979b3b0af4a83aa6ee88d634d63a2bea87 Mon Sep 17 00:00:00 2001 From: natiz Date: Wed, 26 Oct 2022 12:12:09 +0300 Subject: [PATCH 356/450] grpc-tools: Update protoc to v3.19.1 last working version of protoc that includes javascript --- packages/grpc-tools/deps/protobuf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-tools/deps/protobuf b/packages/grpc-tools/deps/protobuf index 6aa539bf0..7c40b2df1 160000 --- a/packages/grpc-tools/deps/protobuf +++ b/packages/grpc-tools/deps/protobuf @@ -1 +1 @@ -Subproject commit 6aa539bf0195f188ff86efe6fb8bfa2b676cdd46 +Subproject commit 7c40b2df1fdf6f414c1c18c789715a9c948a0725 From e7144897d06ce910f684c729c96ce56db9c9c3d9 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 1 Nov 2022 09:26:29 -0700 Subject: [PATCH 357/450] grpc-js: Restart deadline timer after getting timeout from service config --- packages/grpc-js/src/resolving-call.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/grpc-js/src/resolving-call.ts b/packages/grpc-js/src/resolving-call.ts index 76a7bd208..96592d71d 100644 --- a/packages/grpc-js/src/resolving-call.ts +++ b/packages/grpc-js/src/resolving-call.ts @@ -145,6 +145,7 @@ export class ResolvingCall implements Call { config.methodConfig.timeout.nanos / 1_000_000 ); this.deadline = minDeadline(this.deadline, configDeadline); + this.runDeadlineTimer(); } this.filterStackFactory.push(config.dynamicFilterFactories); From b3bcff1d7b9e30b664390432fcf9758f03842dd9 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 1 Nov 2022 10:39:06 -0700 Subject: [PATCH 358/450] grpc-js: Pin @types/lodash to fix broken build --- 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 087060154..fa0df34e0 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -17,7 +17,7 @@ "devDependencies": { "@types/gulp": "^4.0.6", "@types/gulp-mocha": "0.0.32", - "@types/lodash": "^4.14.108", + "@types/lodash": "4.14.186", "@types/mocha": "^5.2.6", "@types/ncp": "^2.0.1", "@types/pify": "^3.0.2", From 8f33dc72466b02a6ef5bdd8784d03d8c3e5e16f4 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 4 Nov 2022 11:21:24 -0700 Subject: [PATCH 359/450] grpc-js: Update to newest typescript compiler --- packages/grpc-js/package.json | 6 ++-- packages/grpc-js/src/call-credentials.ts | 4 +++ packages/grpc-js/src/client-interceptors.ts | 5 +-- packages/grpc-js/src/error.ts | 37 +++++++++++++++++++ packages/grpc-js/src/metadata.ts | 3 +- packages/grpc-js/src/server-call.ts | 39 +++++++++++---------- packages/grpc-js/src/server.ts | 11 ++++-- 7 files changed, 78 insertions(+), 27 deletions(-) create mode 100644 packages/grpc-js/src/error.ts diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index fff572fa9..cd1c74bb5 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -17,14 +17,14 @@ "devDependencies": { "@types/gulp": "^4.0.6", "@types/gulp-mocha": "0.0.32", - "@types/lodash": "4.14.186", + "@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", "clang-format": "^1.0.55", "execa": "^2.0.3", - "gts": "^2.0.0", + "gts": "^3.1.1", "gulp": "^4.0.2", "gulp-mocha": "^6.0.0", "lodash": "^4.17.4", @@ -35,7 +35,7 @@ "rimraf": "^3.0.2", "semver": "^7.3.5", "ts-node": "^8.3.0", - "typescript": "^3.7.2" + "typescript": "^4.8.4" }, "contributors": [ { diff --git a/packages/grpc-js/src/call-credentials.ts b/packages/grpc-js/src/call-credentials.ts index bbc88a895..b98624ee2 100644 --- a/packages/grpc-js/src/call-credentials.ts +++ b/packages/grpc-js/src/call-credentials.ts @@ -115,6 +115,10 @@ export abstract class CallCredentials { reject(err); return; } + if (!headers) { + reject(new Error('Headers not set by metadata plugin')); + return; + } resolve(headers); } ); diff --git a/packages/grpc-js/src/client-interceptors.ts b/packages/grpc-js/src/client-interceptors.ts index d9c88f448..d95828550 100644 --- a/packages/grpc-js/src/client-interceptors.ts +++ b/packages/grpc-js/src/client-interceptors.ts @@ -34,6 +34,7 @@ import { Channel } from './channel'; import { CallOptions } from './client'; import { CallCredentials } from './call-credentials'; import { ClientMethodDefinition } from './make-client'; +import { getErrorMessage } from './error'; /** * Error class associated with passing both interceptors and interceptor @@ -374,7 +375,7 @@ class BaseInterceptingCall implements InterceptingCallInterface { } catch (e) { this.call.cancelWithStatus( Status.INTERNAL, - `Request message serialization failure: ${e.message}` + `Request message serialization failure: ${getErrorMessage(e)}` ); return; } @@ -401,7 +402,7 @@ class BaseInterceptingCall implements InterceptingCallInterface { } catch (e) { readError = { code: Status.INTERNAL, - details: `Response message parsing error: ${e.message}`, + details: `Response message parsing error: ${getErrorMessage(e)}`, metadata: new Metadata(), }; this.call.cancelWithStatus(readError.code, readError.details); diff --git a/packages/grpc-js/src/error.ts b/packages/grpc-js/src/error.ts new file mode 100644 index 000000000..b973128a7 --- /dev/null +++ b/packages/grpc-js/src/error.ts @@ -0,0 +1,37 @@ +/* + * 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. + * + */ + +export function getErrorMessage(error: unknown): string { + if (error instanceof Error) { + return error.message; + } else { + return String(error); + } +} + +export function getErrorCode(error: unknown): number | null { + if ( + typeof error === 'object' && + error !== null && + 'code' in error && + typeof (error as Record).code === 'number' + ) { + return (error as Record).code; + } else { + return null; + } +} \ No newline at end of file diff --git a/packages/grpc-js/src/metadata.ts b/packages/grpc-js/src/metadata.ts index 376cb491a..0dddd9465 100644 --- a/packages/grpc-js/src/metadata.ts +++ b/packages/grpc-js/src/metadata.ts @@ -18,6 +18,7 @@ import * as http2 from 'http2'; import { log } from './logging'; import { LogVerbosity } from './constants'; +import { getErrorMessage } from './error'; const LEGAL_KEY_REGEX = /^[0-9a-z_.-]+$/; const LEGAL_NON_BINARY_VALUE_REGEX = /^[ -~]*$/; @@ -285,7 +286,7 @@ export class Metadata { } } } catch (error) { - const message = `Failed to add metadata entry ${key}: ${values}. ${error.message}. For more information see https://github.com/grpc/grpc-node/issues/1173`; + const message = `Failed to add metadata entry ${key}: ${values}. ${getErrorMessage(error)}. For more information see https://github.com/grpc/grpc-node/issues/1173`; log(LogVerbosity.ERROR, message); } } diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index b27bb1b20..a000b8ffe 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -35,6 +35,7 @@ import { ChannelOptions } from './channel-options'; import * as logging from './logging'; import { StatusObject, PartialStatusObject } from './call-interface'; import { Deadline } from './deadline'; +import { getErrorCode, getErrorMessage } from './error'; const TRACER_NAME = 'server_call'; const unzip = promisify(zlib.unzip); @@ -232,8 +233,10 @@ export class ServerWritableStreamImpl return; } } catch (err) { - err.code = Status.INTERNAL; - this.emit('error', err); + this.emit('error', { + details: getErrorMessage(err), + code: Status.INTERNAL + }); } callback(); @@ -630,8 +633,10 @@ export class Http2ServerCallStream< try { next(null, this.deserializeMessage(buffer)); } catch (err) { - err.code = Status.INTERNAL; - next(err); + next({ + details: getErrorMessage(err), + code: Status.INTERNAL + }); } } @@ -679,8 +684,10 @@ export class Http2ServerCallStream< this.write(response); this.sendStatus({ code: Status.OK, details: 'OK', metadata }); } catch (err) { - err.code = Status.INTERNAL; - this.sendError(err); + this.sendError({ + details: getErrorMessage(err), + code: Status.INTERNAL + }); } } @@ -909,21 +916,15 @@ export class Http2ServerCallStream< } catch (error) { // Ignore any remaining messages when errors occur. this.bufferedMessages.length = 0; - - if ( - !( - 'code' in error && - typeof error.code === 'number' && - Number.isInteger(error.code) && - error.code >= Status.OK && - error.code <= Status.UNAUTHENTICATED - ) - ) { - // The error code is not a valid gRPC code so its being overwritten. - error.code = Status.INTERNAL; + let code = getErrorCode(error); + if (code === null || code < Status.OK || code > Status.UNAUTHENTICATED) { + code = Status.INTERNAL } - readable.emit('error', error); + readable.emit('error', { + details: getErrorMessage(error), + code: code + }); } this.isPushPending = false; diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 2e89f459b..9f7321408 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -61,6 +61,7 @@ import { import { parseUri } from './uri-parser'; import { ChannelzCallTracker, ChannelzChildrenTracker, ChannelzTrace, registerChannelzServer, registerChannelzSocket, ServerInfo, ServerRef, SocketInfo, SocketRef, TlsInfo, unregisterChannelzRef } from './channelz'; import { CipherNameAndProtocol, TLSSocket } from 'tls'; +import { getErrorCode, getErrorMessage } from './error'; const { HTTP2_HEADER_PATH @@ -814,7 +815,10 @@ export class Server { try { handler = this._retrieveHandler(headers) } catch (err) { - this._respondWithError(err, stream, channelzSessionInfo) + this._respondWithError({ + details: getErrorMessage(err), + code: getErrorCode(err) ?? undefined + }, stream, channelzSessionInfo) return } @@ -866,7 +870,10 @@ export class Server { try { handler = this._retrieveHandler(headers) } catch (err) { - this._respondWithError(err, stream, null) + this._respondWithError({ + details: getErrorMessage(err), + code: getErrorCode(err) ?? undefined + }, stream, null) return } From f392d4d8c5b3d1992f571b210e4f50f62c973e46 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 4 Nov 2022 15:15:54 -0700 Subject: [PATCH 360/450] grpc-js-xds: interop client: correct for setInterval variance --- .../grpc-js-xds/interop/xds-interop-client.ts | 59 ++++++++++++++++--- 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/packages/grpc-js-xds/interop/xds-interop-client.ts b/packages/grpc-js-xds/interop/xds-interop-client.ts index 59c505b46..72bbec61d 100644 --- a/packages/grpc-js-xds/interop/xds-interop-client.ts +++ b/packages/grpc-js-xds/interop/xds-interop-client.ts @@ -180,6 +180,27 @@ class CallStatsTracker { } } +class RecentTimestampList { + private timeList: bigint[] = []; + private nextIndex = 0; + + constructor(private readonly size: number) {} + + isFull() { + return this.timeList.length === this.size; + } + + insertTimestamp(timestamp: bigint) { + this.timeList[this.nextIndex] = timestamp; + this.nextIndex = (this.nextIndex + 1) % this.size; + } + + getSpan(): bigint { + const lastIndex = (this.nextIndex + this.size - 1) % this.size; + return this.timeList[lastIndex] - this.timeList[this.nextIndex]; + } +} + type CallType = 'EmptyCall' | 'UnaryCall'; interface ClientConfiguration { @@ -246,7 +267,13 @@ const callTimeHistogram: {[callType: string]: {[status: number]: number[]}} = { EmptyCall: {} } -function makeSingleRequest(client: TestServiceClient, type: CallType, failOnFailedRpcs: boolean, callStatsTracker: CallStatsTracker) { +/** + * Timestamps output by process.hrtime.bigint() are a bigint number of + * nanoseconds. This is the representation of 1 second in that context. + */ +const TIMESTAMP_ONE_SECOND = BigInt(1e9); + +function makeSingleRequest(client: TestServiceClient, type: CallType, failOnFailedRpcs: boolean, callStatsTracker: CallStatsTracker, callStartTimestamps: RecentTimestampList) { const callEnumName = callTypeEnumMapReverse[type]; addAccumulatedCallStarted(callEnumName); const notifier = callStatsTracker.startCall(); @@ -254,19 +281,20 @@ function makeSingleRequest(client: TestServiceClient, type: CallType, failOnFail let hostname: string | null = null; let completed: boolean = false; let completedWithError: boolean = false; - const startTime = process.hrtime(); + 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 statusCode = error?.code ?? grpc.status.OK; - const duration = process.hrtime(startTime); + const duration = process.hrtime.bigint() - startTime; + const durationSeconds = Number(duration / TIMESTAMP_ONE_SECOND) | 0; if (!callTimeHistogram[type][statusCode]) { callTimeHistogram[type][statusCode] = []; } - if (callTimeHistogram[type][statusCode][duration[0]]) { - callTimeHistogram[type][statusCode][duration[0]] += 1; + if (callTimeHistogram[type][statusCode][durationSeconds]) { + callTimeHistogram[type][statusCode][durationSeconds] += 1; } else { - callTimeHistogram[type][statusCode][duration[0]] = 1; + callTimeHistogram[type][statusCode][durationSeconds] = 1; } addAccumulatedCallEnded(callEnumName, statusCode); if (error) { @@ -301,13 +329,28 @@ function makeSingleRequest(client: TestServiceClient, type: CallType, failOnFail } } }); - + /* callStartTimestamps tracks the last N timestamps of started calls, where N + * is the target QPS. If the measured span of time between the first and last + * of those N calls is greater than 1 second, we make another call + * ~immediately to correct for that. */ + callStartTimestamps.insertTimestamp(startTime); + if (callStartTimestamps.isFull()) { + if (callStartTimestamps.getSpan() > TIMESTAMP_ONE_SECOND) { + setImmediate(() => { + makeSingleRequest(client, type, failOnFailedRpcs, callStatsTracker, callStartTimestamps); + }); + } + } } function sendConstantQps(client: TestServiceClient, qps: number, failOnFailedRpcs: boolean, callStatsTracker: CallStatsTracker) { + const callStartTimestampsTrackers: {[callType: string]: RecentTimestampList} = {}; + for (const callType of currentConfig.callTypes) { + callStartTimestampsTrackers[callType] = new RecentTimestampList(qps); + } setInterval(() => { for (const callType of currentConfig.callTypes) { - makeSingleRequest(client, callType, failOnFailedRpcs, callStatsTracker); + makeSingleRequest(client, callType, failOnFailedRpcs, callStatsTracker, callStartTimestampsTrackers[callType]); } }, 1000/qps); setInterval(() => { From 26c8c379853eeba3f3c5c1a90064bc01fa47fbd3 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 17 Oct 2022 11:32:22 -0700 Subject: [PATCH 361/450] grpc-js: Handle filters in ResolvingCall instead of LoadBalancingCall --- packages/grpc-js/src/internal-channel.ts | 2 +- packages/grpc-js/src/load-balancing-call.ts | 59 +++---------- packages/grpc-js/src/resolving-call.ts | 96 +++++++++++++++------ 3 files changed, 83 insertions(+), 74 deletions(-) diff --git a/packages/grpc-js/src/internal-channel.ts b/packages/grpc-js/src/internal-channel.ts index 2a775e7d8..16f4b9832 100644 --- a/packages/grpc-js/src/internal-channel.ts +++ b/packages/grpc-js/src/internal-channel.ts @@ -402,7 +402,7 @@ export class InternalChannel { method + '"' ); - return new LoadBalancingCall(this, callConfig, method, host, credentials, deadline, this.filterStackFactory, callNumber); + return new LoadBalancingCall(this, callConfig, method, host, credentials, deadline, callNumber); } createInnerCall( diff --git a/packages/grpc-js/src/load-balancing-call.ts b/packages/grpc-js/src/load-balancing-call.ts index 73c1fa9fd..6faa15592 100644 --- a/packages/grpc-js/src/load-balancing-call.ts +++ b/packages/grpc-js/src/load-balancing-call.ts @@ -41,14 +41,11 @@ export interface StatusObjectWithProgress extends StatusObject { export class LoadBalancingCall implements Call { private child: SubchannelCall | null = null; private readPending = false; - private writeFilterPending = false; private pendingMessage: {context: MessageContext, message: Buffer} | null = null; private pendingHalfClose = false; - private readFilterPending = false; private pendingChildStatus: StatusObject | null = null; private ended = false; private serviceUrl: string; - private filterStack: FilterStack; private metadata: Metadata | null = null; private listener: InterceptingListener | null = null; private onCallEnded: ((statusCode: Status) => void) | null = null; @@ -59,11 +56,8 @@ export class LoadBalancingCall implements Call { private readonly host : string, private readonly credentials: CallCredentials, private readonly deadline: Deadline, - filterStackFactory: FilterStackFactory, private readonly callNumber: number ) { - this.filterStack = filterStackFactory.createFilter(); - const splitPath: string[] = this.methodName.split('/'); let serviceName = ''; /* The standard path format is "/{serviceName}/{methodName}", so if we split @@ -90,8 +84,7 @@ export class LoadBalancingCall implements Call { if (!this.ended) { this.ended = true; this.trace('ended with status: code=' + status.code + ' details="' + status.details + '"'); - const filteredStatus = this.filterStack.receiveTrailers(status); - const finalStatus = {...filteredStatus, progress}; + const finalStatus = {...status, progress}; this.listener?.onReceiveStatus(finalStatus); this.onCallEnded?.(finalStatus.code); } @@ -152,26 +145,13 @@ export class LoadBalancingCall implements Call { try { this.child = pickResult.subchannel!.getRealSubchannel().createCall(finalMetadata, this.host, this.methodName, { onReceiveMetadata: metadata => { - this.listener!.onReceiveMetadata(this.filterStack.receiveMetadata(metadata)); + this.listener!.onReceiveMetadata(metadata); }, onReceiveMessage: message => { - this.readFilterPending = true; - this.filterStack.receiveMessage(message).then(filteredMesssage => { - this.readFilterPending = false; - this.listener!.onReceiveMessage(filteredMesssage); - if (this.pendingChildStatus) { - this.outputStatus(this.pendingChildStatus, 'PROCESSED'); - } - }, (status: StatusObject) => { - this.cancelWithStatus(status.code, status.details); - }); + this.listener!.onReceiveMessage(message); }, onReceiveStatus: status => { - if (this.readFilterPending) { - this.pendingChildStatus = status; - } else { - this.outputStatus(status, 'PROCESSED'); - } + this.outputStatus(status, 'PROCESSED'); } }); } catch (error) { @@ -201,7 +181,7 @@ export class LoadBalancingCall implements Call { if (this.pendingMessage) { this.child.sendMessageWithContext(this.pendingMessage.context, this.pendingMessage.message); } - if (this.pendingHalfClose && !this.writeFilterPending) { + if (this.pendingHalfClose) { this.child.halfClose(); } }, (error: Error & { code: number }) => { @@ -249,29 +229,16 @@ export class LoadBalancingCall implements Call { start(metadata: Metadata, listener: InterceptingListener): void { this.trace('start called'); this.listener = listener; - this.filterStack.sendMetadata(Promise.resolve(metadata)).then(filteredMetadata => { - this.metadata = filteredMetadata; - this.doPick(); - }, (status: StatusObject) => { - this.outputStatus(status, 'PROCESSED'); - }); + this.metadata = metadata; + this.doPick(); } sendMessageWithContext(context: MessageContext, message: Buffer): void { this.trace('write() called with message of length ' + message.length); - this.writeFilterPending = true; - this.filterStack.sendMessage(Promise.resolve({message: message, flags: context.flags})).then((filteredMessage) => { - this.writeFilterPending = false; - if (this.child) { - this.child.sendMessageWithContext(context, filteredMessage.message); - if (this.pendingHalfClose) { - this.child.halfClose(); - } - } else { - this.pendingMessage = {context, message: filteredMessage.message}; - } - }, (status: StatusObject) => { - this.cancelWithStatus(status.code, status.details); - }) + if (this.child) { + this.child.sendMessageWithContext(context, message); + } else { + this.pendingMessage = {context, message}; + } } startRead(): void { this.trace('startRead called'); @@ -283,7 +250,7 @@ export class LoadBalancingCall implements Call { } halfClose(): void { this.trace('halfClose called'); - if (this.child && !this.writeFilterPending) { + if (this.child) { this.child.halfClose(); } else { this.pendingHalfClose = true; diff --git a/packages/grpc-js/src/resolving-call.ts b/packages/grpc-js/src/resolving-call.ts index 96592d71d..fe29a4f7a 100644 --- a/packages/grpc-js/src/resolving-call.ts +++ b/packages/grpc-js/src/resolving-call.ts @@ -19,7 +19,7 @@ import { CallCredentials } from "./call-credentials"; import { Call, CallStreamOptions, InterceptingListener, MessageContext, StatusObject } from "./call-interface"; import { LogVerbosity, Propagate, Status } from "./constants"; import { Deadline, getDeadlineTimeoutString, getRelativeTimeout, minDeadline } from "./deadline"; -import { FilterStackFactory } from "./filter-stack"; +import { FilterStack, FilterStackFactory } from "./filter-stack"; import { InternalChannel } from "./internal-channel"; import { Metadata } from "./metadata"; import * as logging from './logging'; @@ -33,12 +33,16 @@ export class ResolvingCall implements Call { private pendingMessage: {context: MessageContext, message: Buffer} | null = null; private pendingHalfClose = false; private ended = false; + private readFilterPending = false; + private writeFilterPending = false; + private pendingChildStatus: StatusObject | null = null; private metadata: Metadata | null = null; private listener: InterceptingListener | null = null; private deadline: Deadline; private host: string; private statusWatchers: ((status: StatusObject) => void)[] = []; private deadlineTimer: NodeJS.Timer = setTimeout(() => {}, 0); + private filterStack: FilterStack | null = null; constructor( private readonly channel: InternalChannel, @@ -96,14 +100,35 @@ export class ResolvingCall implements Call { private outputStatus(status: StatusObject) { if (!this.ended) { this.ended = true; - this.trace('ended with status: code=' + status.code + ' details="' + status.details + '"'); - this.statusWatchers.forEach(watcher => watcher(status)); + if (!this.filterStack) { + this.filterStack = this.filterStackFactory.createFilter(); + } + const filteredStatus = this.filterStack.receiveTrailers(status); + this.trace('ended with status: code=' + filteredStatus.code + ' details="' + filteredStatus.details + '"'); + this.statusWatchers.forEach(watcher => watcher(filteredStatus)); process.nextTick(() => { - this.listener?.onReceiveStatus(status); + this.listener?.onReceiveStatus(filteredStatus); }); } } + private sendMessageOnChild(context: MessageContext, message: Buffer): void { + if (!this.child) { + throw new Error('sendMessageonChild called with child not populated'); + } + const child = this.child; + this.writeFilterPending = true; + this.filterStack!.sendMessage(Promise.resolve({message: message, flags: context.flags})).then((filteredMessage) => { + this.writeFilterPending = false; + child.sendMessageWithContext(context, filteredMessage.message); + if (this.pendingHalfClose) { + child.halfClose(); + } + }, (status: StatusObject) => { + this.cancelWithStatus(status.code, status.details); + }); + } + getConfig(): void { if (this.ended) { return; @@ -149,29 +174,46 @@ export class ResolvingCall implements Call { } this.filterStackFactory.push(config.dynamicFilterFactories); - - this.child = this.channel.createInnerCall(config, this.method, this.host, this.credentials, this.deadline); - this.child.start(this.metadata, { - onReceiveMetadata: metadata => { - this.listener!.onReceiveMetadata(metadata); - }, - onReceiveMessage: message => { - this.listener!.onReceiveMessage(message); - }, - onReceiveStatus: status => { - this.outputStatus(status); + this.filterStack = this.filterStackFactory.createFilter(); + this.filterStack.sendMetadata(Promise.resolve(this.metadata)).then(filteredMetadata => { + this.child = this.channel.createInnerCall(config, this.method, this.host, this.credentials, this.deadline); + this.child.start(filteredMetadata, { + onReceiveMetadata: metadata => { + this.listener!.onReceiveMetadata(this.filterStack!.receiveMetadata(metadata)); + }, + onReceiveMessage: message => { + this.readFilterPending = true; + this.filterStack!.receiveMessage(message).then(filteredMesssage => { + this.readFilterPending = false; + this.listener!.onReceiveMessage(filteredMesssage); + if (this.pendingChildStatus) { + this.outputStatus(this.pendingChildStatus); + } + }, (status: StatusObject) => { + this.cancelWithStatus(status.code, status.details); + }); + }, + onReceiveStatus: status => { + if (this.readFilterPending) { + this.pendingChildStatus = status; + } else { + this.outputStatus(status); + } + } + }); + if (this.readPending) { + this.child.startRead(); } - }); - if (this.readPending) { - this.child.startRead(); - } - if (this.pendingMessage) { - this.child.sendMessageWithContext(this.pendingMessage.context, this.pendingMessage.message); - } - if (this.pendingHalfClose) { - this.child.halfClose(); - } + if (this.pendingMessage) { + this.sendMessageOnChild(this.pendingMessage.context, this.pendingMessage.message); + } else if (this.pendingHalfClose) { + this.child.halfClose(); + } + }, (status: StatusObject) => { + this.outputStatus(status); + }) } + reportResolverError(status: StatusObject) { if (this.metadata?.getOptions().waitForReady) { this.channel.queueCallForConfig(this); @@ -196,7 +238,7 @@ export class ResolvingCall implements Call { sendMessageWithContext(context: MessageContext, message: Buffer): void { this.trace('write() called with message of length ' + message.length); if (this.child) { - this.child.sendMessageWithContext(context, message); + this.sendMessageOnChild(context, message); } else { this.pendingMessage = {context, message}; } @@ -211,7 +253,7 @@ export class ResolvingCall implements Call { } halfClose(): void { this.trace('halfClose called'); - if (this.child) { + if (this.child && !this.writeFilterPending) { this.child.halfClose(); } else { this.pendingHalfClose = true; From b4449083b905b4d4daa08fff93f8588c95730098 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 8 Nov 2022 12:40:22 -0800 Subject: [PATCH 362/450] grpc-js-xds: interop: output CPU profile logs in old framework tests --- packages/grpc-js-xds/scripts/xds.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/scripts/xds.sh b/packages/grpc-js-xds/scripts/xds.sh index 2df2ae42d..6b4987371 100755 --- a/packages/grpc-js-xds/scripts/xds.sh +++ b/packages/grpc-js-xds/scripts/xds.sh @@ -59,7 +59,7 @@ GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weigh --gcp_suffix=$(date '+%s') \ --verbose \ ${XDS_V3_OPT-} \ - --client_cmd="$(which node) --enable-source-maps grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client \ + --client_cmd="$(which node) --enable-source-maps --prof --logfile=grpc/reports/prof.log grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client \ --server=xds:///{server_uri} \ --stats_port={stats_port} \ --qps={qps} \ From 959f698fc4dfe257773157bca0c8f8a0e33de1da Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 8 Nov 2022 14:46:17 -0800 Subject: [PATCH 363/450] Use absolute path for logfile output Co-authored-by: Sergii Tkachenko --- packages/grpc-js-xds/scripts/xds.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/scripts/xds.sh b/packages/grpc-js-xds/scripts/xds.sh index 6b4987371..14cbed511 100755 --- a/packages/grpc-js-xds/scripts/xds.sh +++ b/packages/grpc-js-xds/scripts/xds.sh @@ -59,7 +59,7 @@ GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weigh --gcp_suffix=$(date '+%s') \ --verbose \ ${XDS_V3_OPT-} \ - --client_cmd="$(which node) --enable-source-maps --prof --logfile=grpc/reports/prof.log grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client \ + --client_cmd="$(which node) --enable-source-maps --prof --logfile=${KOKORO_ARTIFACTS_DIR}/grpc/reports/prof.log grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client \ --server=xds:///{server_uri} \ --stats_port={stats_port} \ --qps={qps} \ From f844ca30bb3bf908fc0fc3a021b52398a861b359 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 8 Nov 2022 15:23:20 -0800 Subject: [PATCH 364/450] grpc-js-xds: interop: mkdir artifact directory before running tests --- packages/grpc-js-xds/scripts/xds.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/grpc-js-xds/scripts/xds.sh b/packages/grpc-js-xds/scripts/xds.sh index 14cbed511..f556b0e76 100755 --- a/packages/grpc-js-xds/scripts/xds.sh +++ b/packages/grpc-js-xds/scripts/xds.sh @@ -48,6 +48,8 @@ git clone -b master --single-branch --depth=1 https://github.com/grpc/grpc.git grpc/tools/run_tests/helper_scripts/prep_xds.sh +mkdir -p "${KOKORO_ARTIFACTS_DIR}/grpc/reports/prof.log" + GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weighted_target,round_robin,resolving_load_balancer,subchannel,keepalive,dns_resolver,fault_injection,http_filter,csds \ GRPC_NODE_VERBOSITY=DEBUG \ NODE_XDS_INTEROP_VERBOSITY=1 \ From e8396a5542ada132abfafe770fa065ea7a5cb09d Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 8 Nov 2022 15:47:09 -0800 Subject: [PATCH 365/450] Don't try to create the target file as a directory Co-authored-by: Sergii Tkachenko --- packages/grpc-js-xds/scripts/xds.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/scripts/xds.sh b/packages/grpc-js-xds/scripts/xds.sh index f556b0e76..96348e6ba 100755 --- a/packages/grpc-js-xds/scripts/xds.sh +++ b/packages/grpc-js-xds/scripts/xds.sh @@ -48,7 +48,7 @@ git clone -b master --single-branch --depth=1 https://github.com/grpc/grpc.git grpc/tools/run_tests/helper_scripts/prep_xds.sh -mkdir -p "${KOKORO_ARTIFACTS_DIR}/grpc/reports/prof.log" +mkdir -p "${KOKORO_ARTIFACTS_DIR}/grpc/reports" GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weighted_target,round_robin,resolving_load_balancer,subchannel,keepalive,dns_resolver,fault_injection,http_filter,csds \ GRPC_NODE_VERBOSITY=DEBUG \ From 02c48f426dd2be7b5faf2442f9b100ddfcb8af3d Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 9 Nov 2022 10:08:47 -0800 Subject: [PATCH 366/450] grpc-js-xds: interop: Fix target directory for profile log --- packages/grpc-js-xds/scripts/xds.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js-xds/scripts/xds.sh b/packages/grpc-js-xds/scripts/xds.sh index 96348e6ba..615b2a7c7 100755 --- a/packages/grpc-js-xds/scripts/xds.sh +++ b/packages/grpc-js-xds/scripts/xds.sh @@ -48,7 +48,7 @@ git clone -b master --single-branch --depth=1 https://github.com/grpc/grpc.git grpc/tools/run_tests/helper_scripts/prep_xds.sh -mkdir -p "${KOKORO_ARTIFACTS_DIR}/grpc/reports" +mkdir -p "${KOKORO_ARTIFACTS_DIR}/github/grpc/reports" GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weighted_target,round_robin,resolving_load_balancer,subchannel,keepalive,dns_resolver,fault_injection,http_filter,csds \ GRPC_NODE_VERBOSITY=DEBUG \ @@ -61,7 +61,7 @@ GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weigh --gcp_suffix=$(date '+%s') \ --verbose \ ${XDS_V3_OPT-} \ - --client_cmd="$(which node) --enable-source-maps --prof --logfile=${KOKORO_ARTIFACTS_DIR}/grpc/reports/prof.log grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client \ + --client_cmd="$(which node) --enable-source-maps --prof --logfile=${KOKORO_ARTIFACTS_DIR}/github/grpc/reports/prof.log grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client \ --server=xds:///{server_uri} \ --stats_port={stats_port} \ --qps={qps} \ From a42d6b4f5c7351f700149af1e845ee4105e50e6f Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 9 Nov 2022 14:53:19 -0800 Subject: [PATCH 367/450] grpc-js: Implement server connection management --- packages/grpc-js/src/channel-options.ts | 4 ++ packages/grpc-js/src/server.ts | 74 ++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/src/channel-options.ts b/packages/grpc-js/src/channel-options.ts index b7fc92fa9..c05253e9b 100644 --- a/packages/grpc-js/src/channel-options.ts +++ b/packages/grpc-js/src/channel-options.ts @@ -44,6 +44,8 @@ export interface ChannelOptions { 'grpc.default_compression_algorithm'?: CompressionAlgorithms; 'grpc.enable_channelz'?: number; 'grpc.dns_min_time_between_resolutions_ms'?: number; + 'grpc.max_connection_age_ms'?: number; + 'grpc.max_connection_age_grace_ms'?: number; 'grpc-node.max_session_memory'?: number; // eslint-disable-next-line @typescript-eslint/no-explicit-any [key: string]: any; @@ -71,6 +73,8 @@ export const recognizedOptions = { 'grpc.enable_http_proxy': true, 'grpc.enable_channelz': true, 'grpc.dns_min_time_between_resolutions_ms': true, + 'grpc.max_connection_age_ms': true, + 'grpc.max_connection_age_grace_ms': true, 'grpc-node.max_session_memory': true, }; diff --git a/packages/grpc-js/src/server.ts b/packages/grpc-js/src/server.ts index 9f7321408..d19186a75 100644 --- a/packages/grpc-js/src/server.ts +++ b/packages/grpc-js/src/server.ts @@ -63,6 +63,10 @@ import { ChannelzCallTracker, ChannelzChildrenTracker, ChannelzTrace, registerCh import { CipherNameAndProtocol, TLSSocket } from 'tls'; import { getErrorCode, getErrorMessage } from './error'; +const UNLIMITED_CONNECTION_AGE_MS = ~(1<<31); +const KEEPALIVE_MAX_TIME_MS = ~(1<<31); +const KEEPALIVE_TIMEOUT_MS = 20000; + const { HTTP2_HEADER_PATH } = http2.constants @@ -161,6 +165,12 @@ export class Server { private listenerChildrenTracker = new ChannelzChildrenTracker(); private sessionChildrenTracker = new ChannelzChildrenTracker(); + private readonly maxConnectionAgeMs: number; + private readonly maxConnectionAgeGraceMs: number; + + private readonly keepaliveTimeMs: number; + private readonly keepaliveTimeoutMs: number; + constructor(options?: ChannelOptions) { this.options = options ?? {}; if (this.options['grpc.enable_channelz'] === 0) { @@ -170,7 +180,10 @@ export class Server { if (this.channelzEnabled) { this.channelzTrace.addTrace('CT_INFO', 'Server created'); } - + this.maxConnectionAgeMs = this.options['grpc.max_connection_age_ms'] ?? UNLIMITED_CONNECTION_AGE_MS; + this.maxConnectionAgeGraceMs = this.options['grpc.max_connection_age_grace_ms'] ?? UNLIMITED_CONNECTION_AGE_MS; + this.keepaliveTimeMs = this.options['grpc.keepalive_time_ms'] ?? KEEPALIVE_MAX_TIME_MS; + this.keepaliveTimeoutMs = this.options['grpc.keepalive_timeout_ms'] ?? KEEPALIVE_TIMEOUT_MS; this.trace('Server constructed'); } @@ -970,12 +983,69 @@ export class Server { this.channelzTrace.addTrace('CT_INFO', 'Connection established by client ' + clientAddress); this.sessionChildrenTracker.refChild(channelzRef); } + let connectionAgeTimer: NodeJS.Timer | null = null; + let connectionAgeGraceTimer: NodeJS.Timer | null = null; + let sessionClosedByServer = false; + 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); + } + 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(); + /* 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?.(); + } + const keeapliveTimeTimer: NodeJS.Timer | null = setInterval(() => { + const timeoutTImer = setTimeout(() => { + sessionClosedByServer = true; + if (this.channelzEnabled) { + 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); + }); + } 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) { - this.channelzTrace.addTrace('CT_INFO', 'Connection dropped by client ' + clientAddress); + if (!sessionClosedByServer) { + this.channelzTrace.addTrace('CT_INFO', 'Connection dropped by client ' + clientAddress); + } this.sessionChildrenTracker.unrefChild(channelzRef); unregisterChannelzRef(channelzRef); } + if (connectionAgeTimer) { + clearTimeout(connectionAgeTimer); + } + if (connectionAgeGraceTimer) { + clearTimeout(connectionAgeGraceTimer); + } + if (keeapliveTimeTimer) { + clearTimeout(keeapliveTimeTimer); + } this.sessions.delete(session); }); }); From 0de2aad269e4a27669aaada0f71ae20f5209c426 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 10 Nov 2022 10:54:19 -0800 Subject: [PATCH 368/450] grpc-js: Fix reuse of channel filter stack factory --- packages/grpc-js/src/filter-stack.ts | 4 ++++ packages/grpc-js/src/internal-channel.ts | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/src/filter-stack.ts b/packages/grpc-js/src/filter-stack.ts index f44c43839..622f3dd0a 100644 --- a/packages/grpc-js/src/filter-stack.ts +++ b/packages/grpc-js/src/filter-stack.ts @@ -88,6 +88,10 @@ export class FilterStackFactory implements FilterFactory { this.factories.unshift(...filterFactories); } + clone(): FilterStackFactory { + return new FilterStackFactory(this.factories); + } + createFilter(): FilterStack { return new FilterStack( this.factories.map((factory) => factory.createFilter()) diff --git a/packages/grpc-js/src/internal-channel.ts b/packages/grpc-js/src/internal-channel.ts index 16f4b9832..a8c6dc964 100644 --- a/packages/grpc-js/src/internal-channel.ts +++ b/packages/grpc-js/src/internal-channel.ts @@ -439,7 +439,7 @@ export class InternalChannel { parentCall: parentCall, }; - const call = new ResolvingCall(this, method, finalOptions, this.filterStackFactory, this.credentials._getCallCredentials(), getNextCallNumber()); + const call = new ResolvingCall(this, method, finalOptions, this.filterStackFactory.clone(), this.credentials._getCallCredentials(), getNextCallNumber()); if (this.channelzEnabled) { this.callTracker.addCallStarted(); From 38f2497daeabe49c7377c168cd9df4531f98a618 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 11 Nov 2022 09:24:15 -0800 Subject: [PATCH 369/450] grpc-js: Make filter stack factory clone with a copy of the array --- packages/grpc-js/src/filter-stack.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/src/filter-stack.ts b/packages/grpc-js/src/filter-stack.ts index 622f3dd0a..4733c8218 100644 --- a/packages/grpc-js/src/filter-stack.ts +++ b/packages/grpc-js/src/filter-stack.ts @@ -89,7 +89,7 @@ export class FilterStackFactory implements FilterFactory { } clone(): FilterStackFactory { - return new FilterStackFactory(this.factories); + return new FilterStackFactory([...this.factories]); } createFilter(): FilterStack { From f8f95ee9bbbfb867590879cc4b31c6db3e27d1bb Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 14 Nov 2022 09:50:33 -0800 Subject: [PATCH 370/450] grpc-js-xds: interop: Fix timestamp handling when config changes --- packages/grpc-js-xds/interop/xds-interop-client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/interop/xds-interop-client.ts b/packages/grpc-js-xds/interop/xds-interop-client.ts index 72bbec61d..0394c0ace 100644 --- a/packages/grpc-js-xds/interop/xds-interop-client.ts +++ b/packages/grpc-js-xds/interop/xds-interop-client.ts @@ -345,7 +345,7 @@ function makeSingleRequest(client: TestServiceClient, type: CallType, failOnFail function sendConstantQps(client: TestServiceClient, qps: number, failOnFailedRpcs: boolean, callStatsTracker: CallStatsTracker) { const callStartTimestampsTrackers: {[callType: string]: RecentTimestampList} = {}; - for (const callType of currentConfig.callTypes) { + for (const callType of ['EmptyCall', 'UnaryCall']) { callStartTimestampsTrackers[callType] = new RecentTimestampList(qps); } setInterval(() => { From c7125fbdb5590511c4b88aa5d939e6904db6a283 Mon Sep 17 00:00:00 2001 From: install <1994052+install@users.noreply.github.com> Date: Tue, 15 Nov 2022 16:44:52 -0500 Subject: [PATCH 371/450] proto-loader-gen-types Avoid TS enums --- .../bin/proto-loader-gen-types.ts | 51 ++++++--- .../google/api/FieldBehavior.ts | 77 +++++++++++-- .../google/protobuf/FieldDescriptorProto.ts | 108 +++++++++++++----- .../google/protobuf/FieldOptions.ts | 54 ++++++--- .../google/protobuf/FileOptions.ts | 24 ++-- .../google/showcase/v1beta1/EchoRequest.ts | 6 +- .../google/showcase/v1beta1/EchoResponse.ts | 6 +- .../google/showcase/v1beta1/Severity.ts | 30 ++++- 8 files changed, 266 insertions(+), 90 deletions(-) diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index bb5b35f81..64ec28ddb 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -135,20 +135,16 @@ function getImportLine(dependency: Protobuf.Type | Protobuf.Enum | Protobuf.Serv /* If the dependency is defined within a message, it will be generated in that * message's file and exported using its typeInterfaceName. */ if (dependency.parent instanceof Protobuf.Type) { - if (dependency instanceof Protobuf.Type) { + if (dependency instanceof Protobuf.Type || dependency instanceof Protobuf.Enum) { importedTypes = `${inputName(typeInterfaceName)}, ${outputName(typeInterfaceName)}`; - } else if (dependency instanceof Protobuf.Enum) { - importedTypes = `${typeInterfaceName}`; } else if (dependency instanceof Protobuf.Service) { importedTypes = `${typeInterfaceName}Client, ${typeInterfaceName}Definition`; } else { throw new Error('Invalid object passed to getImportLine'); } } else { - if (dependency instanceof Protobuf.Type) { + if (dependency instanceof Protobuf.Type || dependency instanceof Protobuf.Enum) { importedTypes = `${inputName(dependency.name)} as ${inputName(typeInterfaceName)}, ${outputName(dependency.name)} as ${outputName(typeInterfaceName)}`; - } else if (dependency instanceof Protobuf.Enum) { - importedTypes = `${dependency.name} as ${typeInterfaceName}`; } else if (dependency instanceof Protobuf.Service) { importedTypes = `${dependency.name}Client as ${typeInterfaceName}Client, ${dependency.name}Definition as ${typeInterfaceName}Definition`; } else { @@ -213,14 +209,14 @@ function getTypeNamePermissive(fieldType: string, resolvedType: Protobuf.Type | throw new Error('Found field with no usable type'); } const typeInterfaceName = getTypeInterfaceName(resolvedType); - if (resolvedType instanceof Protobuf.Type) { + if (resolvedType instanceof Protobuf.Type || resolvedType instanceof Protobuf.Enum) { if (repeated || map) { return inputName(typeInterfaceName); } else { return `${inputName(typeInterfaceName)} | null`; } } else { - return `${typeInterfaceName} | keyof typeof ${typeInterfaceName}`; + return ''; } } } @@ -315,7 +311,7 @@ function getTypeNameRestricted(fieldType: string, resolvedType: Protobuf.Type | throw new Error('Found field with no usable type'); } const typeInterfaceName = getTypeInterfaceName(resolvedType); - if (resolvedType instanceof Protobuf.Type) { + if (resolvedType instanceof Protobuf.Type || resolvedType instanceof Protobuf.Enum) { /* null is only used to represent absent message values if the defaults * option is set, and only for non-repeated, non-map fields. */ if (options.defaults && !repeated && !map) { @@ -324,11 +320,7 @@ function getTypeNameRestricted(fieldType: string, resolvedType: Protobuf.Type | return `${outputName(typeInterfaceName)}`; } } else { - if (options.enums == String) { - return `keyof typeof ${typeInterfaceName}`; - } else { - return typeInterfaceName; - } + return ''; } } } @@ -455,21 +447,46 @@ function generateMessageInterfaces(formatter: TextFormatter, messageType: Protob } function generateEnumInterface(formatter: TextFormatter, enumType: Protobuf.Enum, options: GeneratorOptions, nameOverride?: string) { + const {inputName, outputName} = useNameFmter(options); + const name = nameOverride ?? enumType.name; formatter.writeLine(`// Original file: ${(enumType.filename ?? 'null')?.replace(/\\/g, '/')}`); formatter.writeLine(''); if (options.includeComments) { formatComment(formatter, enumType.comment); } - formatter.writeLine(`export enum ${nameOverride ?? enumType.name} {`); + formatter.writeLine(`export const ${name} = {`); formatter.indent(); for (const key of Object.keys(enumType.values)) { if (options.includeComments) { formatComment(formatter, enumType.comments[key]); } - formatter.writeLine(`${key} = ${enumType.values[key]},`); + formatter.writeLine(`${key}: ${options.enums == String ? `'${key}'` : enumType.values[key]},`); } formatter.unindent(); - formatter.writeLine('}'); + formatter.writeLine('} as const;'); + + // Permissive Type + formatter.writeLine(''); + if (options.includeComments) { + formatComment(formatter, enumType.comment); + } + formatter.writeLine(`export type ${inputName(name)} =`) + formatter.indent(); + for (const key of Object.keys(enumType.values)) { + if (options.includeComments) { + formatComment(formatter, enumType.comments[key]); + } + formatter.writeLine(`| '${key}'`); + formatter.writeLine(`| ${enumType.values[key]}`); + } + formatter.unindent(); + + // Restrictive Type + formatter.writeLine(''); + if (options.includeComments) { + formatComment(formatter, enumType.comment); + } + formatter.writeLine(`export type ${outputName(name)} = typeof ${name}[keyof typeof ${name}]`) } /** diff --git a/packages/proto-loader/golden-generated/google/api/FieldBehavior.ts b/packages/proto-loader/golden-generated/google/api/FieldBehavior.ts index 8ab676709..189d25be5 100644 --- a/packages/proto-loader/golden-generated/google/api/FieldBehavior.ts +++ b/packages/proto-loader/golden-generated/google/api/FieldBehavior.ts @@ -8,40 +8,101 @@ * * Note: This enum **may** receive new values in the future. */ -export enum FieldBehavior { +export const FieldBehavior = { /** * Conventional default for enums. Do not use this. */ - FIELD_BEHAVIOR_UNSPECIFIED = 0, + FIELD_BEHAVIOR_UNSPECIFIED: 'FIELD_BEHAVIOR_UNSPECIFIED', /** * Specifically denotes a field as optional. * While all fields in protocol buffers are optional, this may be specified * for emphasis if appropriate. */ - OPTIONAL = 1, + OPTIONAL: 'OPTIONAL', /** * Denotes a field as required. * This indicates that the field **must** be provided as part of the request, * and failure to do so will cause an error (usually `INVALID_ARGUMENT`). */ - REQUIRED = 2, + REQUIRED: 'REQUIRED', /** * Denotes a field as output only. * This indicates that the field is provided in responses, but including the * field in a request does nothing (the server *must* ignore it and * *must not* throw an error as a result of the field's presence). */ - OUTPUT_ONLY = 3, + OUTPUT_ONLY: 'OUTPUT_ONLY', /** * Denotes a field as input only. * This indicates that the field is provided in requests, and the * corresponding field is not included in output. */ - INPUT_ONLY = 4, + INPUT_ONLY: 'INPUT_ONLY', /** * Denotes a field as immutable. * This indicates that the field may be set once in a request to create a * resource, but may not be changed thereafter. */ - IMMUTABLE = 5, -} + IMMUTABLE: 'IMMUTABLE', +} as const; + +/** + * An indicator of the behavior of a given field (for example, that a field + * is required in requests, or given as output but ignored as input). + * This **does not** change the behavior in protocol buffers itself; it only + * denotes the behavior and may affect how API tooling handles the field. + * + * Note: This enum **may** receive new values in the future. + */ +export type IFieldBehavior = + /** + * Conventional default for enums. Do not use this. + */ + | 'FIELD_BEHAVIOR_UNSPECIFIED' + | 0 + /** + * Specifically denotes a field as optional. + * While all fields in protocol buffers are optional, this may be specified + * for emphasis if appropriate. + */ + | 'OPTIONAL' + | 1 + /** + * Denotes a field as required. + * This indicates that the field **must** be provided as part of the request, + * and failure to do so will cause an error (usually `INVALID_ARGUMENT`). + */ + | 'REQUIRED' + | 2 + /** + * Denotes a field as output only. + * This indicates that the field is provided in responses, but including the + * field in a request does nothing (the server *must* ignore it and + * *must not* throw an error as a result of the field's presence). + */ + | 'OUTPUT_ONLY' + | 3 + /** + * Denotes a field as input only. + * This indicates that the field is provided in requests, and the + * corresponding field is not included in output. + */ + | 'INPUT_ONLY' + | 4 + /** + * Denotes a field as immutable. + * This indicates that the field may be set once in a request to create a + * resource, but may not be changed thereafter. + */ + | 'IMMUTABLE' + | 5 + +/** + * An indicator of the behavior of a given field (for example, that a field + * is required in requests, or given as output but ignored as input). + * This **does not** change the behavior in protocol buffers itself; it only + * denotes the behavior and may affect how API tooling handles the field. + * + * Note: This enum **may** receive new values in the future. + */ +export type OFieldBehavior = typeof FieldBehavior[keyof typeof FieldBehavior] diff --git a/packages/proto-loader/golden-generated/google/protobuf/FieldDescriptorProto.ts b/packages/proto-loader/golden-generated/google/protobuf/FieldDescriptorProto.ts index 0a713e9dc..3dbce5175 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/FieldDescriptorProto.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/FieldDescriptorProto.ts @@ -4,41 +4,91 @@ import type { IFieldOptions as I_google_protobuf_FieldOptions, OFieldOptions as // 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 I_google_protobuf_FieldDescriptorProto_Label = + | 'LABEL_OPTIONAL' + | 1 + | 'LABEL_REQUIRED' + | 2 + | 'LABEL_REPEATED' + | 3 + +export type O_google_protobuf_FieldDescriptorProto_Label = 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 I_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 O_google_protobuf_FieldDescriptorProto_Type = typeof _google_protobuf_FieldDescriptorProto_Type[keyof typeof _google_protobuf_FieldDescriptorProto_Type] export interface IFieldDescriptorProto { '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'?: (I_google_protobuf_FieldDescriptorProto_Label | null); + 'type'?: (I_google_protobuf_FieldDescriptorProto_Type | null); 'typeName'?: (string); 'defaultValue'?: (string); 'options'?: (I_google_protobuf_FieldOptions | null); @@ -50,8 +100,8 @@ export interface OFieldDescriptorProto { 'name': (string); 'extendee': (string); 'number': (number); - 'label': (keyof typeof _google_protobuf_FieldDescriptorProto_Label); - 'type': (keyof typeof _google_protobuf_FieldDescriptorProto_Type); + 'label': (O_google_protobuf_FieldDescriptorProto_Label | null); + 'type': (O_google_protobuf_FieldDescriptorProto_Type | null); 'typeName': (string); 'defaultValue': (string); 'options': (O_google_protobuf_FieldOptions | null); diff --git a/packages/proto-loader/golden-generated/google/protobuf/FieldOptions.ts b/packages/proto-loader/golden-generated/google/protobuf/FieldOptions.ts index 076b35983..daf307d64 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/FieldOptions.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/FieldOptions.ts @@ -1,42 +1,62 @@ // Original file: null import type { IUninterpretedOption as I_google_protobuf_UninterpretedOption, OUninterpretedOption as O_google_protobuf_UninterpretedOption } from '../../google/protobuf/UninterpretedOption'; -import type { FieldBehavior as _google_api_FieldBehavior } from '../../google/api/FieldBehavior'; +import type { IFieldBehavior as I_google_api_FieldBehavior, OFieldBehavior as O_google_api_FieldBehavior } from '../../google/api/FieldBehavior'; // 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 I_google_protobuf_FieldOptions_CType = + | 'STRING' + | 0 + | 'CORD' + | 1 + | 'STRING_PIECE' + | 2 + +export type O_google_protobuf_FieldOptions_CType = 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 I_google_protobuf_FieldOptions_JSType = + | 'JS_NORMAL' + | 0 + | 'JS_STRING' + | 1 + | 'JS_NUMBER' + | 2 + +export type O_google_protobuf_FieldOptions_JSType = typeof _google_protobuf_FieldOptions_JSType[keyof typeof _google_protobuf_FieldOptions_JSType] export interface IFieldOptions { - 'ctype'?: (_google_protobuf_FieldOptions_CType | keyof typeof _google_protobuf_FieldOptions_CType); + 'ctype'?: (I_google_protobuf_FieldOptions_CType | null); 'packed'?: (boolean); 'deprecated'?: (boolean); 'lazy'?: (boolean); - 'jstype'?: (_google_protobuf_FieldOptions_JSType | keyof typeof _google_protobuf_FieldOptions_JSType); + 'jstype'?: (I_google_protobuf_FieldOptions_JSType | null); 'weak'?: (boolean); 'uninterpretedOption'?: (I_google_protobuf_UninterpretedOption)[]; - '.google.api.field_behavior'?: (_google_api_FieldBehavior | keyof typeof _google_api_FieldBehavior)[]; + '.google.api.field_behavior'?: (I_google_api_FieldBehavior)[]; } export interface OFieldOptions { - 'ctype': (keyof typeof _google_protobuf_FieldOptions_CType); + 'ctype': (O_google_protobuf_FieldOptions_CType | null); 'packed': (boolean); 'deprecated': (boolean); 'lazy': (boolean); - 'jstype': (keyof typeof _google_protobuf_FieldOptions_JSType); + 'jstype': (O_google_protobuf_FieldOptions_JSType | null); 'weak': (boolean); 'uninterpretedOption': (O_google_protobuf_UninterpretedOption)[]; - '.google.api.field_behavior': (keyof typeof _google_api_FieldBehavior)[]; + '.google.api.field_behavior': (O_google_api_FieldBehavior)[]; } diff --git a/packages/proto-loader/golden-generated/google/protobuf/FileOptions.ts b/packages/proto-loader/golden-generated/google/protobuf/FileOptions.ts index 2b832e0f8..038ef4785 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/FileOptions.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/FileOptions.ts @@ -4,16 +4,26 @@ import type { IUninterpretedOption as I_google_protobuf_UninterpretedOption, OUn // 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 I_google_protobuf_FileOptions_OptimizeMode = + | 'SPEED' + | 1 + | 'CODE_SIZE' + | 2 + | 'LITE_RUNTIME' + | 3 + +export type O_google_protobuf_FileOptions_OptimizeMode = typeof _google_protobuf_FileOptions_OptimizeMode[keyof typeof _google_protobuf_FileOptions_OptimizeMode] export interface IFileOptions { 'javaPackage'?: (string); 'javaOuterClassname'?: (string); - 'optimizeFor'?: (_google_protobuf_FileOptions_OptimizeMode | keyof typeof _google_protobuf_FileOptions_OptimizeMode); + 'optimizeFor'?: (I_google_protobuf_FileOptions_OptimizeMode | null); 'javaMultipleFiles'?: (boolean); 'goPackage'?: (string); 'ccGenericServices'?: (boolean); @@ -31,7 +41,7 @@ export interface IFileOptions { export interface OFileOptions { 'javaPackage': (string); 'javaOuterClassname': (string); - 'optimizeFor': (keyof typeof _google_protobuf_FileOptions_OptimizeMode); + 'optimizeFor': (O_google_protobuf_FileOptions_OptimizeMode | null); 'javaMultipleFiles': (boolean); 'goPackage': (string); 'ccGenericServices': (boolean); diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoRequest.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoRequest.ts index 649a5d505..715fcb342 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoRequest.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoRequest.ts @@ -1,7 +1,7 @@ // Original file: deps/gapic-showcase/schema/google/showcase/v1beta1/echo.proto import type { IStatus as I_google_rpc_Status, OStatus as O_google_rpc_Status } from '../../../google/rpc/Status'; -import type { Severity as _google_showcase_v1beta1_Severity } from '../../../google/showcase/v1beta1/Severity'; +import type { ISeverity as I_google_showcase_v1beta1_Severity, OSeverity as O_google_showcase_v1beta1_Severity } from '../../../google/showcase/v1beta1/Severity'; /** * The request message used for the Echo, Collect and Chat methods. @@ -21,7 +21,7 @@ export interface IEchoRequest { /** * The severity to be echoed by the server. */ - 'severity'?: (_google_showcase_v1beta1_Severity | keyof typeof _google_showcase_v1beta1_Severity); + 'severity'?: (I_google_showcase_v1beta1_Severity | null); 'response'?: "content"|"error"; } @@ -43,6 +43,6 @@ export interface OEchoRequest { /** * The severity to be echoed by the server. */ - 'severity': (keyof typeof _google_showcase_v1beta1_Severity); + 'severity': (O_google_showcase_v1beta1_Severity | null); 'response': "content"|"error"; } diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoResponse.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoResponse.ts index 96b7ba25d..68e685967 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoResponse.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoResponse.ts @@ -1,6 +1,6 @@ // Original file: deps/gapic-showcase/schema/google/showcase/v1beta1/echo.proto -import type { Severity as _google_showcase_v1beta1_Severity } from '../../../google/showcase/v1beta1/Severity'; +import type { ISeverity as I_google_showcase_v1beta1_Severity, OSeverity as O_google_showcase_v1beta1_Severity } from '../../../google/showcase/v1beta1/Severity'; /** * The response message for the Echo methods. @@ -13,7 +13,7 @@ export interface IEchoResponse { /** * The severity specified in the request. */ - 'severity'?: (_google_showcase_v1beta1_Severity | keyof typeof _google_showcase_v1beta1_Severity); + 'severity'?: (I_google_showcase_v1beta1_Severity | null); } /** @@ -27,5 +27,5 @@ export interface OEchoResponse { /** * The severity specified in the request. */ - 'severity': (keyof typeof _google_showcase_v1beta1_Severity); + 'severity': (O_google_showcase_v1beta1_Severity | null); } diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/Severity.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/Severity.ts index fc3fe6415..d109fe1ce 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/Severity.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/Severity.ts @@ -3,9 +3,27 @@ /** * A severity enum used to test enum capabilities in GAPIC surfaces */ -export enum Severity { - UNNECESSARY = 0, - NECESSARY = 1, - URGENT = 2, - CRITICAL = 3, -} +export const Severity = { + UNNECESSARY: 'UNNECESSARY', + NECESSARY: 'NECESSARY', + URGENT: 'URGENT', + CRITICAL: 'CRITICAL', +} as const; + +/** + * A severity enum used to test enum capabilities in GAPIC surfaces + */ +export type ISeverity = + | 'UNNECESSARY' + | 0 + | 'NECESSARY' + | 1 + | 'URGENT' + | 2 + | 'CRITICAL' + | 3 + +/** + * A severity enum used to test enum capabilities in GAPIC surfaces + */ +export type OSeverity = typeof Severity[keyof typeof Severity] From ef7b8e8f14ca98dc7b2a04ebb64d660729b92494 Mon Sep 17 00:00:00 2001 From: install <1994052+install@users.noreply.github.com> Date: Wed, 16 Nov 2022 10:10:13 -0500 Subject: [PATCH 372/450] Don't allow `null` for enum field inputs/outputs --- packages/proto-loader/bin/proto-loader-gen-types.ts | 10 ++++++---- .../google/protobuf/FieldDescriptorProto.ts | 8 ++++---- .../golden-generated/google/protobuf/FieldOptions.ts | 8 ++++---- .../golden-generated/google/protobuf/FileOptions.ts | 4 ++-- .../google/showcase/v1beta1/EchoRequest.ts | 4 ++-- .../google/showcase/v1beta1/EchoResponse.ts | 4 ++-- 6 files changed, 20 insertions(+), 18 deletions(-) diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index 64ec28ddb..a9ee4a6ed 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -209,14 +209,15 @@ function getTypeNamePermissive(fieldType: string, resolvedType: Protobuf.Type | throw new Error('Found field with no usable type'); } const typeInterfaceName = getTypeInterfaceName(resolvedType); - if (resolvedType instanceof Protobuf.Type || resolvedType instanceof Protobuf.Enum) { + if (resolvedType instanceof Protobuf.Type) { if (repeated || map) { return inputName(typeInterfaceName); } else { return `${inputName(typeInterfaceName)} | null`; } } else { - return ''; + // Enum + return inputName(typeInterfaceName); } } } @@ -311,7 +312,7 @@ function getTypeNameRestricted(fieldType: string, resolvedType: Protobuf.Type | throw new Error('Found field with no usable type'); } const typeInterfaceName = getTypeInterfaceName(resolvedType); - if (resolvedType instanceof Protobuf.Type || resolvedType instanceof Protobuf.Enum) { + if (resolvedType instanceof Protobuf.Type) { /* null is only used to represent absent message values if the defaults * option is set, and only for non-repeated, non-map fields. */ if (options.defaults && !repeated && !map) { @@ -320,7 +321,8 @@ function getTypeNameRestricted(fieldType: string, resolvedType: Protobuf.Type | return `${outputName(typeInterfaceName)}`; } } else { - return ''; + // Enum + return outputName(typeInterfaceName); } } } diff --git a/packages/proto-loader/golden-generated/google/protobuf/FieldDescriptorProto.ts b/packages/proto-loader/golden-generated/google/protobuf/FieldDescriptorProto.ts index 3dbce5175..1bcb69abe 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/FieldDescriptorProto.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/FieldDescriptorProto.ts @@ -87,8 +87,8 @@ export interface IFieldDescriptorProto { 'name'?: (string); 'extendee'?: (string); 'number'?: (number); - 'label'?: (I_google_protobuf_FieldDescriptorProto_Label | null); - 'type'?: (I_google_protobuf_FieldDescriptorProto_Type | null); + 'label'?: (I_google_protobuf_FieldDescriptorProto_Label); + 'type'?: (I_google_protobuf_FieldDescriptorProto_Type); 'typeName'?: (string); 'defaultValue'?: (string); 'options'?: (I_google_protobuf_FieldOptions | null); @@ -100,8 +100,8 @@ export interface OFieldDescriptorProto { 'name': (string); 'extendee': (string); 'number': (number); - 'label': (O_google_protobuf_FieldDescriptorProto_Label | null); - 'type': (O_google_protobuf_FieldDescriptorProto_Type | null); + 'label': (O_google_protobuf_FieldDescriptorProto_Label); + 'type': (O_google_protobuf_FieldDescriptorProto_Type); 'typeName': (string); 'defaultValue': (string); 'options': (O_google_protobuf_FieldOptions | null); diff --git a/packages/proto-loader/golden-generated/google/protobuf/FieldOptions.ts b/packages/proto-loader/golden-generated/google/protobuf/FieldOptions.ts index daf307d64..16e532d95 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/FieldOptions.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/FieldOptions.ts @@ -40,22 +40,22 @@ export type I_google_protobuf_FieldOptions_JSType = export type O_google_protobuf_FieldOptions_JSType = typeof _google_protobuf_FieldOptions_JSType[keyof typeof _google_protobuf_FieldOptions_JSType] export interface IFieldOptions { - 'ctype'?: (I_google_protobuf_FieldOptions_CType | null); + 'ctype'?: (I_google_protobuf_FieldOptions_CType); 'packed'?: (boolean); 'deprecated'?: (boolean); 'lazy'?: (boolean); - 'jstype'?: (I_google_protobuf_FieldOptions_JSType | null); + 'jstype'?: (I_google_protobuf_FieldOptions_JSType); 'weak'?: (boolean); 'uninterpretedOption'?: (I_google_protobuf_UninterpretedOption)[]; '.google.api.field_behavior'?: (I_google_api_FieldBehavior)[]; } export interface OFieldOptions { - 'ctype': (O_google_protobuf_FieldOptions_CType | null); + 'ctype': (O_google_protobuf_FieldOptions_CType); 'packed': (boolean); 'deprecated': (boolean); 'lazy': (boolean); - 'jstype': (O_google_protobuf_FieldOptions_JSType | null); + 'jstype': (O_google_protobuf_FieldOptions_JSType); 'weak': (boolean); 'uninterpretedOption': (O_google_protobuf_UninterpretedOption)[]; '.google.api.field_behavior': (O_google_api_FieldBehavior)[]; diff --git a/packages/proto-loader/golden-generated/google/protobuf/FileOptions.ts b/packages/proto-loader/golden-generated/google/protobuf/FileOptions.ts index 038ef4785..fdeac9cd4 100644 --- a/packages/proto-loader/golden-generated/google/protobuf/FileOptions.ts +++ b/packages/proto-loader/golden-generated/google/protobuf/FileOptions.ts @@ -23,7 +23,7 @@ export type O_google_protobuf_FileOptions_OptimizeMode = typeof _google_protobuf export interface IFileOptions { 'javaPackage'?: (string); 'javaOuterClassname'?: (string); - 'optimizeFor'?: (I_google_protobuf_FileOptions_OptimizeMode | null); + 'optimizeFor'?: (I_google_protobuf_FileOptions_OptimizeMode); 'javaMultipleFiles'?: (boolean); 'goPackage'?: (string); 'ccGenericServices'?: (boolean); @@ -41,7 +41,7 @@ export interface IFileOptions { export interface OFileOptions { 'javaPackage': (string); 'javaOuterClassname': (string); - 'optimizeFor': (O_google_protobuf_FileOptions_OptimizeMode | null); + 'optimizeFor': (O_google_protobuf_FileOptions_OptimizeMode); 'javaMultipleFiles': (boolean); 'goPackage': (string); 'ccGenericServices': (boolean); diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoRequest.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoRequest.ts index 715fcb342..a5fb8f766 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoRequest.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoRequest.ts @@ -21,7 +21,7 @@ export interface IEchoRequest { /** * The severity to be echoed by the server. */ - 'severity'?: (I_google_showcase_v1beta1_Severity | null); + 'severity'?: (I_google_showcase_v1beta1_Severity); 'response'?: "content"|"error"; } @@ -43,6 +43,6 @@ export interface OEchoRequest { /** * The severity to be echoed by the server. */ - 'severity': (O_google_showcase_v1beta1_Severity | null); + 'severity': (O_google_showcase_v1beta1_Severity); 'response': "content"|"error"; } diff --git a/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoResponse.ts b/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoResponse.ts index 68e685967..ac50115bf 100644 --- a/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoResponse.ts +++ b/packages/proto-loader/golden-generated/google/showcase/v1beta1/EchoResponse.ts @@ -13,7 +13,7 @@ export interface IEchoResponse { /** * The severity specified in the request. */ - 'severity'?: (I_google_showcase_v1beta1_Severity | null); + 'severity'?: (I_google_showcase_v1beta1_Severity); } /** @@ -27,5 +27,5 @@ export interface OEchoResponse { /** * The severity specified in the request. */ - 'severity': (O_google_showcase_v1beta1_Severity | null); + 'severity': (O_google_showcase_v1beta1_Severity); } From 5a5e42498ce1ce2de7b14dc02c14985ce7770b4a Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 16 Nov 2022 14:09:40 -0800 Subject: [PATCH 373/450] grpc-js: Enable servers to send trailers-only responses --- packages/grpc-js/README.md | 3 + packages/grpc-js/src/load-balancing-call.ts | 3 + packages/grpc-js/src/retrying-call.ts | 21 +- packages/grpc-js/src/server-call.ts | 40 ++- packages/grpc-js/src/service-config.ts | 39 ++- packages/grpc-js/test/test-retry-config.ts | 292 +++++++++++++++++++ packages/grpc-js/test/test-retry.ts | 301 ++++++++++++++++++++ 7 files changed, 666 insertions(+), 33 deletions(-) create mode 100644 packages/grpc-js/test/test-retry-config.ts create mode 100644 packages/grpc-js/test/test-retry.ts diff --git a/packages/grpc-js/README.md b/packages/grpc-js/README.md index 11a8ca9aa..3d698dfd8 100644 --- a/packages/grpc-js/README.md +++ b/packages/grpc-js/README.md @@ -59,6 +59,9 @@ Many channel arguments supported in `grpc` are not supported in `@grpc/grpc-js`. - `grpc.default_compression_algorithm` - `grpc.enable_channelz` - `grpc.dns_min_time_between_resolutions_ms` + - `grpc.enable_retries` + - `grpc.per_rpc_retry_buffer_size` + - `grpc.retry_buffer_size` - `grpc-node.max_session_memory` - `channelOverride` - `channelFactoryOverride` diff --git a/packages/grpc-js/src/load-balancing-call.ts b/packages/grpc-js/src/load-balancing-call.ts index 23b9a9174..a7af83d6d 100644 --- a/packages/grpc-js/src/load-balancing-call.ts +++ b/packages/grpc-js/src/load-balancing-call.ts @@ -150,12 +150,15 @@ export class LoadBalancingCall implements Call { try { this.child = pickResult.subchannel!.getRealSubchannel().createCall(finalMetadata, this.host, this.methodName, { onReceiveMetadata: metadata => { + this.trace('Received metadata'); this.listener!.onReceiveMetadata(metadata); }, onReceiveMessage: message => { + this.trace('Received message'); this.listener!.onReceiveMessage(message); }, onReceiveStatus: status => { + this.trace('Received status'); if (status.code === http2.constants.NGHTTP2_REFUSED_STREAM) { this.outputStatus(status, 'REFUSED'); } else { diff --git a/packages/grpc-js/src/retrying-call.ts b/packages/grpc-js/src/retrying-call.ts index 7c15023d5..71dedd46f 100644 --- a/packages/grpc-js/src/retrying-call.ts +++ b/packages/grpc-js/src/retrying-call.ts @@ -145,6 +145,13 @@ export class RetryingCall implements Call { private initialMetadata: Metadata | null = null; private underlyingCalls: UnderlyingCall[] = []; private writeBuffer: WriteBufferEntry[] = []; + /** + * Tracks whether a read has been started, so that we know whether to start + * reads on new child calls. This only matters for the first read, because + * once a message comes in the child call becomes committed and there will + * be no new child calls. + */ + private readStarted = false; private transparentRetryUsed: boolean = false; /** * Number of attempts so far @@ -319,7 +326,7 @@ export class RetryingCall implements Call { this.reportStatus(status); break; case 'HEDGING': - if (this.isStatusCodeInList(this.callConfig!.methodConfig.hedgingPolicy!.nonFatalStatusCodes, status.code)) { + if (this.isStatusCodeInList(this.callConfig!.methodConfig.hedgingPolicy!.nonFatalStatusCodes ?? [], status.code)) { this.retryThrottler?.addCallFailed(); let delayMs: number; if (pushback === null) { @@ -378,6 +385,7 @@ export class RetryingCall implements Call { if (this.underlyingCalls[callIndex].state === 'COMPLETED') { return; } + this.trace('state=' + this.state + ' handling status from child [' + this.underlyingCalls[callIndex].call.getCallNumber() + '] in state ' + this.underlyingCalls[callIndex].state); this.underlyingCalls[callIndex].state = 'COMPLETED'; if (status.code === Status.OK) { this.retryThrottler?.addCallSucceeded(); @@ -465,6 +473,7 @@ export class RetryingCall implements Call { let receivedMetadata = false; child.start(initialMetadata, { onReceiveMetadata: metadata => { + this.trace('Received metadata from child [' + child.getCallNumber() + ']'); this.commitCall(index); receivedMetadata = true; if (previousAttempts > 0) { @@ -475,19 +484,24 @@ export class RetryingCall implements Call { } }, onReceiveMessage: message => { + this.trace('Received message from child [' + child.getCallNumber() + ']'); this.commitCall(index); if (this.underlyingCalls[index].state === 'ACTIVE') { this.listener!.onReceiveMessage(message); } }, onReceiveStatus: status => { + this.trace('Received status from child [' + child.getCallNumber() + ']'); if (!receivedMetadata && previousAttempts > 0) { status.metadata.set(PREVIONS_RPC_ATTEMPTS_METADATA_KEY, `${previousAttempts}`); } - this.commitCall(index); this.handleChildStatus(status, index); } - }) + }); + this.sendNextChildMessage(index); + if (this.readStarted) { + child.startRead(); + } } start(metadata: Metadata, listener: InterceptingListener): void { @@ -559,6 +573,7 @@ export class RetryingCall implements Call { } startRead(): void { this.trace('startRead called'); + this.readStarted = true; for (const underlyingCall of this.underlyingCalls) { if (underlyingCall?.state === 'ACTIVE') { underlyingCall.call.startRead(); diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index 38b4379ea..e48d20441 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -673,21 +673,31 @@ export class Http2ServerCallStream< clearTimeout(this.deadlineTimer); - if (!this.wantTrailers) { - this.wantTrailers = true; - this.stream.once('wantTrailers', () => { - const trailersToSend = Object.assign( - { - [GRPC_STATUS_HEADER]: statusObj.code, - [GRPC_MESSAGE_HEADER]: encodeURI(statusObj.details as string), - }, - statusObj.metadata.toHttp2Headers() - ); - - this.stream.sendTrailers(trailersToSend); - }); - this.sendMetadata(); - this.stream.end(); + if (this.stream.headersSent) { + if (!this.wantTrailers) { + this.wantTrailers = true; + this.stream.once('wantTrailers', () => { + const trailersToSend = Object.assign( + { + [GRPC_STATUS_HEADER]: statusObj.code, + [GRPC_MESSAGE_HEADER]: encodeURI(statusObj.details as string), + }, + statusObj.metadata.toHttp2Headers() + ); + + this.stream.sendTrailers(trailersToSend); + }); + this.stream.end(); + } + } else { + const trailersToSend = Object.assign( + { + [GRPC_STATUS_HEADER]: statusObj.code, + [GRPC_MESSAGE_HEADER]: encodeURI(statusObj.details as string), + }, + statusObj.metadata.toHttp2Headers() + ); + this.stream.respond(trailersToSend, {endStream: true}); } } diff --git a/packages/grpc-js/src/service-config.ts b/packages/grpc-js/src/service-config.ts index a45355ace..2b8c0a7eb 100644 --- a/packages/grpc-js/src/service-config.ts +++ b/packages/grpc-js/src/service-config.ts @@ -50,7 +50,7 @@ export interface RetryPolicy { export interface HedgingPolicy { maxAttempts: number; hedgingDelay?: string; - nonFatalStatusCodes: (Status | string)[]; + nonFatalStatusCodes?: (Status | string)[]; } export interface MethodConfig { @@ -124,19 +124,23 @@ function validateRetryPolicy(obj: any): RetryPolicy { if (!('backoffMultiplier' in obj) || typeof obj.backoffMultiplier !== 'number' || obj.backoffMultiplier <= 0) { throw new Error('Invalid method config retry policy: backoffMultiplier must be a number greater than 0'); } - if (('retryableStatusCodes' in obj) && Array.isArray(obj.retryableStatusCodes)) { - for (const value of obj.retryableStatusCodes) { - if (typeof value === 'number') { - if (!Object.values(Status).includes(value)) { - throw new Error('Invlid method config retry policy: retryableStatusCodes value not in status code range'); - } - } else if (typeof value === 'string') { - if (!Object.values(Status).includes(value.toUpperCase())) { - throw new Error('Invlid method config retry policy: retryableStatusCodes value not a status code name'); - } - } else { - throw new Error('Invlid method config retry policy: retryableStatusCodes value must be a string or number'); + if (!(('retryableStatusCodes' in obj) && Array.isArray(obj.retryableStatusCodes))) { + throw new Error('Invalid method config retry policy: retryableStatusCodes is required'); + } + if (obj.retryableStatusCodes.length === 0) { + throw new Error('Invalid method config retry policy: retryableStatusCodes must be non-empty'); + } + for (const value of obj.retryableStatusCodes) { + if (typeof value === 'number') { + if (!Object.values(Status).includes(value)) { + throw new Error('Invlid method config retry policy: retryableStatusCodes value not in status code range'); } + } else if (typeof value === 'string') { + if (!Object.values(Status).includes(value.toUpperCase())) { + throw new Error('Invlid method config retry policy: retryableStatusCodes value not a status code name'); + } + } else { + throw new Error('Invlid method config retry policy: retryableStatusCodes value must be a string or number'); } } return { @@ -171,12 +175,14 @@ function validateHedgingPolicy(obj: any): HedgingPolicy { } } const result: HedgingPolicy = { - maxAttempts: obj.maxAttempts, - nonFatalStatusCodes: obj.nonFatalStatusCodes + maxAttempts: obj.maxAttempts } if (obj.hedgingDelay) { result.hedgingDelay = obj.hedgingDelay; } + if (obj.nonFatalStatusCodes) { + result.nonFatalStatusCodes = obj.nonFatalStatusCodes; + } return result; } @@ -291,6 +297,9 @@ export function validateServiceConfig(obj: any): ServiceConfig { } } } + if ('retryThrottling' in obj) { + result.retryThrottling = validateRetryThrottling(obj.retryThrottling); + } // Validate method name uniqueness const seenMethodNames: MethodConfigName[] = []; for (const methodConfig of result.methodConfig) { diff --git a/packages/grpc-js/test/test-retry-config.ts b/packages/grpc-js/test/test-retry-config.ts new file mode 100644 index 000000000..e27f236e2 --- /dev/null +++ b/packages/grpc-js/test/test-retry-config.ts @@ -0,0 +1,292 @@ +/* + * 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. + * + */ + +import assert = require("assert"); +import { validateServiceConfig } from "../src/service-config"; + +function createRetryServiceConfig(retryConfig: object): object { + return { + loadBalancingConfig: [], + methodConfig: [ + { + name: [{ + service: 'A', + method: 'B' + }], + + retryPolicy: retryConfig + } + ] + }; +} + +function createHedgingServiceConfig(hedgingConfig: object): object { + return { + loadBalancingConfig: [], + methodConfig: [ + { + name: [{ + service: 'A', + method: 'B' + }], + + hedgingPolicy: hedgingConfig + } + ] + }; +} + +function createThrottlingServiceConfig(retryThrottling: object): object { + return { + loadBalancingConfig: [], + methodConfig: [], + retryThrottling: retryThrottling + }; +} + +interface TestCase { + description: string; + config: object; + error: RegExp; +} + +const validRetryConfig = { + maxAttempts: 2, + initialBackoff: '1s', + maxBackoff: '1s', + backoffMultiplier: 1, + retryableStatusCodes: [14, 'RESOURCE_EXHAUSTED'] +}; + +const RETRY_TEST_CASES: TestCase[] = [ + { + description: 'omitted maxAttempts', + config: { + initialBackoff: '1s', + maxBackoff: '1s', + backoffMultiplier: 1, + retryableStatusCodes: [14] + }, + error: /retry policy: maxAttempts must be an integer at least 2/ + }, + { + description: 'a low maxAttempts', + config: {...validRetryConfig, maxAttempts: 1}, + error: /retry policy: maxAttempts must be an integer at least 2/ + }, + { + description: 'omitted initialBackoff', + config: { + maxAttempts: 2, + maxBackoff: '1s', + backoffMultiplier: 1, + retryableStatusCodes: [14] + }, + error: /retry policy: initialBackoff must be a string consisting of a positive integer followed by s/ + }, + { + description: 'a non-numeric initialBackoff', + config: {...validRetryConfig, initialBackoff: 'abcs'}, + error: /retry policy: initialBackoff must be a string consisting of a positive integer followed by s/ + }, + { + description: 'an initialBackoff without an s', + config: {...validRetryConfig, initialBackoff: '123'}, + error: /retry policy: initialBackoff must be a string consisting of a positive integer followed by s/ + }, + { + description: 'omitted maxBackoff', + config: { + maxAttempts: 2, + initialBackoff: '1s', + backoffMultiplier: 1, + retryableStatusCodes: [14] + }, + error: /retry policy: maxBackoff must be a string consisting of a positive integer followed by s/ + }, + { + description: 'a non-numeric maxBackoff', + config: {...validRetryConfig, maxBackoff: 'abcs'}, + error: /retry policy: maxBackoff must be a string consisting of a positive integer followed by s/ + }, + { + description: 'an maxBackoff without an s', + config: {...validRetryConfig, maxBackoff: '123'}, + error: /retry policy: maxBackoff must be a string consisting of a positive integer followed by s/ + }, + { + description: 'omitted backoffMultiplier', + config: { + maxAttempts: 2, + initialBackoff: '1s', + maxBackoff: '1s', + retryableStatusCodes: [14] + }, + error: /retry policy: backoffMultiplier must be a number greater than 0/ + }, + { + description: 'a negative backoffMultiplier', + config: {...validRetryConfig, backoffMultiplier: -1}, + error: /retry policy: backoffMultiplier must be a number greater than 0/ + }, + { + description: 'omitted retryableStatusCodes', + config: { + maxAttempts: 2, + initialBackoff: '1s', + maxBackoff: '1s', + backoffMultiplier: 1 + }, + error: /retry policy: retryableStatusCodes is required/ + }, + { + description: 'empty retryableStatusCodes', + config: {...validRetryConfig, retryableStatusCodes: []}, + error: /retry policy: retryableStatusCodes must be non-empty/ + }, + { + description: 'unknown status code name', + config: {...validRetryConfig, retryableStatusCodes: ['abcd']}, + error: /retry policy: retryableStatusCodes value not a status code name/ + }, + { + description: 'out of range status code number', + config: {...validRetryConfig, retryableStatusCodes: [12345]}, + error: /retry policy: retryableStatusCodes value not in status code range/ + } +]; + +const validHedgingConfig = { + maxAttempts: 2 +}; + +const HEDGING_TEST_CASES: TestCase[] = [ + { + description: 'omitted maxAttempts', + config: {}, + error: /hedging policy: maxAttempts must be an integer at least 2/ + }, + { + description: 'a low maxAttempts', + config: {...validHedgingConfig, maxAttempts: 1}, + error: /hedging policy: maxAttempts must be an integer at least 2/ + }, + { + description: 'a non-numeric hedgingDelay', + config: {...validHedgingConfig, hedgingDelay: 'abcs'}, + error: /hedging policy: hedgingDelay must be a string consisting of a positive integer followed by s/ + }, + { + description: 'a hedgingDelay without an s', + config: {...validHedgingConfig, hedgingDelay: '123'}, + error: /hedging policy: hedgingDelay must be a string consisting of a positive integer followed by s/ + }, + { + description: 'unknown status code name', + config: {...validHedgingConfig, nonFatalStatusCodes: ['abcd']}, + error: /hedging policy: nonFatalStatusCodes value not a status code name/ + }, + { + description: 'out of range status code number', + config: {...validHedgingConfig, nonFatalStatusCodes: [12345]}, + error: /hedging policy: nonFatalStatusCodes value not in status code range/ + } +]; + +const validThrottlingConfig = { + maxTokens: 100, + tokenRatio: 0.1 +}; + +const THROTTLING_TEST_CASES: TestCase[] = [ + { + description: 'omitted maxTokens', + config: {tokenRatio: 0.1}, + error: /retryThrottling: maxTokens must be a number in \(0, 1000\]/ + }, + { + description: 'a large maxTokens', + config: {...validThrottlingConfig, maxTokens: 1001}, + error: /retryThrottling: maxTokens must be a number in \(0, 1000\]/ + }, + { + description: 'zero maxTokens', + config: {...validThrottlingConfig, maxTokens: 0}, + error: /retryThrottling: maxTokens must be a number in \(0, 1000\]/ + }, + { + description: 'omitted tokenRatio', + config: {maxTokens: 100}, + error: /retryThrottling: tokenRatio must be a number greater than 0/ + }, + { + description: 'zero tokenRatio', + config: {...validThrottlingConfig, tokenRatio: 0}, + error: /retryThrottling: tokenRatio must be a number greater than 0/ + } +]; + +describe('Retry configs', () => { + describe('Retry', () => { + it('Should accept a valid config', () => { + assert.doesNotThrow(() => { + validateServiceConfig(createRetryServiceConfig(validRetryConfig)); + }); + }); + for (const testCase of RETRY_TEST_CASES) { + it(`Should reject ${testCase.description}`, () => { + assert.throws(() => { + validateServiceConfig(createRetryServiceConfig(testCase.config)); + }, testCase.error); + }); + } + }); + describe('Hedging', () => { + it('Should accept valid configs', () => { + assert.doesNotThrow(() => { + validateServiceConfig(createHedgingServiceConfig(validHedgingConfig)); + }); + assert.doesNotThrow(() => { + validateServiceConfig(createHedgingServiceConfig({...validHedgingConfig, hedgingDelay: '1s'})); + }); + assert.doesNotThrow(() => { + validateServiceConfig(createHedgingServiceConfig({...validHedgingConfig, nonFatalStatusCodes: [14, 'RESOURCE_EXHAUSTED']})); + }); + }); + for (const testCase of HEDGING_TEST_CASES) { + it(`Should reject ${testCase.description}`, () => { + assert.throws(() => { + validateServiceConfig(createHedgingServiceConfig(testCase.config)); + }, testCase.error); + }); + } + }); + describe('Throttling', () => { + it('Should accept a valid config', () => { + assert.doesNotThrow(() => { + validateServiceConfig(createThrottlingServiceConfig(validThrottlingConfig)); + }); + }); + for (const testCase of THROTTLING_TEST_CASES) { + it(`Should reject ${testCase.description}`, () => { + assert.throws(() => { + validateServiceConfig(createThrottlingServiceConfig(testCase.config)); + }, testCase.error); + }); + } + }); +}); \ No newline at end of file diff --git a/packages/grpc-js/test/test-retry.ts b/packages/grpc-js/test/test-retry.ts new file mode 100644 index 000000000..4dd96cc43 --- /dev/null +++ b/packages/grpc-js/test/test-retry.ts @@ -0,0 +1,301 @@ +/* + * 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. + * + */ + +import * as assert from 'assert'; +import * as path from 'path'; +import * as grpc from '../src'; +import { loadProtoFile } from './common'; + +const protoFile = path.join(__dirname, 'fixtures', 'echo_service.proto'); +const EchoService = loadProtoFile(protoFile) + .EchoService as grpc.ServiceClientConstructor; + +const serviceImpl = { + echo: (call: grpc.ServerUnaryCall, callback: grpc.sendUnaryData) => { + const succeedOnRetryAttempt = call.metadata.get('succeed-on-retry-attempt'); + const previousAttempts = call.metadata.get('grpc-previous-rpc-attempts'); + if (succeedOnRetryAttempt.length === 0 || (previousAttempts.length > 0 && previousAttempts[0] === succeedOnRetryAttempt[0])) { + callback(null, call.request); + } else { + const statusCode = call.metadata.get('respond-with-status'); + const code = statusCode[0] ? Number.parseInt(statusCode[0] as string) : grpc.status.UNKNOWN; + callback({ + code: code, + details: `Failed on retry ${previousAttempts[0] ?? 0}` + }); + } + } +} + +describe('Retries', () => { + let server: grpc.Server; + let port: number; + before((done) => { + server = new grpc.Server(); + server.addService(EchoService.service, serviceImpl); + server.bindAsync('localhost:0', grpc.ServerCredentials.createInsecure(), (error, portNumber) => { + if (error) { + done(error); + return; + } + port = portNumber; + server.start(); + done(); + }); + }); + + after(() => { + server.forceShutdown(); + }); + + describe('Client with retries disabled', () => { + let client: InstanceType; + before(() => { + client = new EchoService(`localhost:${port}`, grpc.credentials.createInsecure(), {'grpc.enable_retries': 0}); + }); + + after(() =>{ + client.close(); + }); + + it('Should be able to make a basic request', (done) => { + client.echo( + { value: 'test value', value2: 3 }, + (error: grpc.ServiceError, response: any) => { + assert.ifError(error); + assert.deepStrictEqual(response, { value: 'test value', value2: 3 }); + done(); + } + ); + }); + + it('Should fail if the server fails the first request', (done) =>{ + const metadata = new grpc.Metadata(); + metadata.set('succeed-on-retry-attempt', '1'); + client.echo( + { value: 'test value', value2: 3 }, + metadata, + (error: grpc.ServiceError, response: any) => { + assert(error); + assert.strictEqual(error.details, 'Failed on retry 0'); + done(); + } + ); + }); + }); + + describe('Client with retries enabled but not configured', () => { + let client: InstanceType; + before(() => { + client = new EchoService(`localhost:${port}`, grpc.credentials.createInsecure()); + }); + + after(() =>{ + client.close(); + }); + + it('Should be able to make a basic request', (done) => { + client.echo( + { value: 'test value', value2: 3 }, + (error: grpc.ServiceError, response: any) => { + assert.ifError(error); + assert.deepStrictEqual(response, { value: 'test value', value2: 3 }); + done(); + } + ); + }); + + it('Should fail if the server fails the first request', (done) =>{ + const metadata = new grpc.Metadata(); + metadata.set('succeed-on-retry-attempt', '1'); + client.echo( + { value: 'test value', value2: 3 }, + metadata, + (error: grpc.ServiceError, response: any) => { + assert(error); + assert.strictEqual(error.details, 'Failed on retry 0'); + done(); + } + ); + }); + }); + + describe('Client with retries configured', () => { + let client: InstanceType; + before(() => { + const serviceConfig = { + loadBalancingConfig: [], + methodConfig: [ + { + name: [{ + service: 'EchoService' + }], + retryPolicy: { + maxAttempts: 3, + initialBackoff: '0.1s', + maxBackoff: '10s', + backoffMultiplier: 1.2, + retryableStatusCodes: [14, 'RESOURCE_EXHAUSTED'] + } + } + ] + } + client = new EchoService(`localhost:${port}`, grpc.credentials.createInsecure(), {'grpc.service_config': JSON.stringify(serviceConfig)}); + }); + + after(() =>{ + client.close(); + }); + + it('Should be able to make a basic request', (done) => { + client.echo( + { value: 'test value', value2: 3 }, + (error: grpc.ServiceError, response: any) => { + assert.ifError(error); + assert.deepStrictEqual(response, { value: 'test value', value2: 3 }); + done(); + } + ); + }); + + it('Should succeed with few required attempts', (done) => { + const metadata = new grpc.Metadata(); + metadata.set('succeed-on-retry-attempt', '2'); + metadata.set('respond-with-status', `${grpc.status.RESOURCE_EXHAUSTED}`); + client.echo( + { value: 'test value', value2: 3 }, + metadata, + (error: grpc.ServiceError, response: any) => { + assert.ifError(error); + assert.deepStrictEqual(response, { value: 'test value', value2: 3 }); + done(); + } + ); + }); + + it('Should fail with many required attempts', (done) => { + const metadata = new grpc.Metadata(); + metadata.set('succeed-on-retry-attempt', '4'); + metadata.set('respond-with-status', `${grpc.status.RESOURCE_EXHAUSTED}`); + client.echo( + { value: 'test value', value2: 3 }, + metadata, + (error: grpc.ServiceError, response: any) => { + assert(error); + assert.strictEqual(error.details, 'Failed on retry 2'); + done(); + } + ); + }); + + it('Should fail with a fatal status code', (done) => { + const metadata = new grpc.Metadata(); + metadata.set('succeed-on-retry-attempt', '2'); + metadata.set('respond-with-status', `${grpc.status.NOT_FOUND}`); + client.echo( + { value: 'test value', value2: 3 }, + metadata, + (error: grpc.ServiceError, response: any) => { + assert(error); + assert.strictEqual(error.details, 'Failed on retry 0'); + done(); + } + ); + }); + }); + + describe('Client with hedging configured', () => { + let client: InstanceType; + before(() => { + const serviceConfig = { + loadBalancingConfig: [], + methodConfig: [ + { + name: [{ + service: 'EchoService' + }], + hedgingPolicy: { + maxAttempts: 3, + nonFatalStatusCodes: [14, 'RESOURCE_EXHAUSTED'] + } + } + ] + } + client = new EchoService(`localhost:${port}`, grpc.credentials.createInsecure(), {'grpc.service_config': JSON.stringify(serviceConfig)}); + }); + + after(() =>{ + client.close(); + }); + + it('Should be able to make a basic request', (done) => { + client.echo( + { value: 'test value', value2: 3 }, + (error: grpc.ServiceError, response: any) => { + assert.ifError(error); + assert.deepStrictEqual(response, { value: 'test value', value2: 3 }); + done(); + } + ); + }); + + it('Should succeed with few required attempts', (done) => { + const metadata = new grpc.Metadata(); + metadata.set('succeed-on-retry-attempt', '2'); + metadata.set('respond-with-status', `${grpc.status.RESOURCE_EXHAUSTED}`); + client.echo( + { value: 'test value', value2: 3 }, + metadata, + (error: grpc.ServiceError, response: any) => { + assert.ifError(error); + assert.deepStrictEqual(response, { value: 'test value', value2: 3 }); + done(); + } + ); + }); + + it('Should fail with many required attempts', (done) => { + const metadata = new grpc.Metadata(); + metadata.set('succeed-on-retry-attempt', '4'); + metadata.set('respond-with-status', `${grpc.status.RESOURCE_EXHAUSTED}`); + client.echo( + { value: 'test value', value2: 3 }, + metadata, + (error: grpc.ServiceError, response: any) => { + assert(error); + assert(error.details.startsWith('Failed on retry')); + done(); + } + ); + }); + + it('Should fail with a fatal status code', (done) => { + const metadata = new grpc.Metadata(); + metadata.set('succeed-on-retry-attempt', '2'); + metadata.set('respond-with-status', `${grpc.status.NOT_FOUND}`); + client.echo( + { value: 'test value', value2: 3 }, + metadata, + (error: grpc.ServiceError, response: any) => { + assert(error); + assert(error.details.startsWith('Failed on retry')); + done(); + } + ); + }); + }); +}); \ No newline at end of file From e19a7737051d055d77482b0e4bc1947e6f22c208 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 16 Nov 2022 14:10:26 -0800 Subject: [PATCH 374/450] grpc-js: Add retry tests, and fix bugs and add tracing --- .../generated/grpc/channelz/v1/Channelz.ts | 104 +++++++++--------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/packages/grpc-js/src/generated/grpc/channelz/v1/Channelz.ts b/packages/grpc-js/src/generated/grpc/channelz/v1/Channelz.ts index ace712454..4c8c18aa7 100644 --- a/packages/grpc-js/src/generated/grpc/channelz/v1/Channelz.ts +++ b/packages/grpc-js/src/generated/grpc/channelz/v1/Channelz.ts @@ -25,102 +25,102 @@ export interface ChannelzClient extends grpc.Client { /** * Returns a single Channel, or else a NOT_FOUND code. */ - GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetChannelResponse__Output) => void): grpc.ClientUnaryCall; - GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetChannelResponse__Output) => void): grpc.ClientUnaryCall; - GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetChannelResponse__Output) => void): grpc.ClientUnaryCall; - GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetChannelResponse__Output) => void): grpc.ClientUnaryCall; + GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetChannelResponse__Output>): grpc.ClientUnaryCall; + GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetChannelResponse__Output>): grpc.ClientUnaryCall; + GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetChannelResponse__Output>): grpc.ClientUnaryCall; + GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetChannelResponse__Output>): grpc.ClientUnaryCall; /** * Returns a single Server, or else a NOT_FOUND code. */ - GetServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; - GetServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; - GetServer(argument: _grpc_channelz_v1_GetServerRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; - GetServer(argument: _grpc_channelz_v1_GetServerRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; + GetServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall; + GetServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall; + GetServer(argument: _grpc_channelz_v1_GetServerRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall; + GetServer(argument: _grpc_channelz_v1_GetServerRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall; /** * Returns a single Server, or else a NOT_FOUND code. */ - getServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; - getServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; - getServer(argument: _grpc_channelz_v1_GetServerRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; - getServer(argument: _grpc_channelz_v1_GetServerRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerResponse__Output) => void): grpc.ClientUnaryCall; + getServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall; + getServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall; + getServer(argument: _grpc_channelz_v1_GetServerRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall; + getServer(argument: _grpc_channelz_v1_GetServerRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall; /** * Gets all server sockets that exist in the process. */ - GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; - GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; - GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; - GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; + GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall; + GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall; + GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall; + GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall; /** * Gets all server sockets that exist in the process. */ - getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; - getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; - getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; - getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServerSocketsResponse__Output) => void): grpc.ClientUnaryCall; + getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall; + getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall; + getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall; + getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall; /** * Gets all servers that exist in the process. */ - GetServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; - GetServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; - GetServers(argument: _grpc_channelz_v1_GetServersRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; - GetServers(argument: _grpc_channelz_v1_GetServersRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; + GetServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall; + GetServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall; + GetServers(argument: _grpc_channelz_v1_GetServersRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall; + GetServers(argument: _grpc_channelz_v1_GetServersRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall; /** * Gets all servers that exist in the process. */ - getServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; - getServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; - getServers(argument: _grpc_channelz_v1_GetServersRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; - getServers(argument: _grpc_channelz_v1_GetServersRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetServersResponse__Output) => void): grpc.ClientUnaryCall; + getServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall; + getServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall; + getServers(argument: _grpc_channelz_v1_GetServersRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall; + getServers(argument: _grpc_channelz_v1_GetServersRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall; /** * Returns a single Socket or else a NOT_FOUND code. */ - GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; - GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; - GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; - GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; + GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall; + GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall; + GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall; + GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall; /** * Returns a single Socket or else a NOT_FOUND code. */ - getSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; - getSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; - getSocket(argument: _grpc_channelz_v1_GetSocketRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; - getSocket(argument: _grpc_channelz_v1_GetSocketRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSocketResponse__Output) => void): grpc.ClientUnaryCall; + getSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall; + getSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall; + getSocket(argument: _grpc_channelz_v1_GetSocketRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall; + getSocket(argument: _grpc_channelz_v1_GetSocketRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall; /** * Returns a single Subchannel, or else a NOT_FOUND code. */ - GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; - GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; - GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; - GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; + GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall; + GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall; + GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall; + GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall; /** * Returns a single Subchannel, or else a NOT_FOUND code. */ - getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; - getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; - getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; - getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetSubchannelResponse__Output) => void): grpc.ClientUnaryCall; + getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall; + getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall; + getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall; + getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall; /** * Gets all root channels (i.e. channels the application has directly * created). This does not include subchannels nor non-top level channels. */ - GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; - GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; - GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; - GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; + GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall; + GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall; + GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall; + GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall; /** * Gets all root channels (i.e. channels the application has directly * created). This does not include subchannels nor non-top level channels. */ - getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; - getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; - getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; - getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, callback: (error?: grpc.ServiceError, result?: _grpc_channelz_v1_GetTopChannelsResponse__Output) => void): grpc.ClientUnaryCall; + getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall; + getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall; + getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall; + getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall; } From 95516b66a089fbce15dedfcd30d263f6fa5687ef Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 16 Nov 2022 14:37:31 -0800 Subject: [PATCH 375/450] Fix detection of refused streams --- packages/grpc-js/src/load-balancing-call.ts | 2 +- packages/grpc-js/src/retrying-call.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/src/load-balancing-call.ts b/packages/grpc-js/src/load-balancing-call.ts index a7af83d6d..48aaf48ac 100644 --- a/packages/grpc-js/src/load-balancing-call.ts +++ b/packages/grpc-js/src/load-balancing-call.ts @@ -159,7 +159,7 @@ export class LoadBalancingCall implements Call { }, onReceiveStatus: status => { this.trace('Received status'); - if (status.code === http2.constants.NGHTTP2_REFUSED_STREAM) { + if (status.rstCode === http2.constants.NGHTTP2_REFUSED_STREAM) { this.outputStatus(status, 'REFUSED'); } else { this.outputStatus(status, 'PROCESSED'); diff --git a/packages/grpc-js/src/retrying-call.ts b/packages/grpc-js/src/retrying-call.ts index 71dedd46f..a85fac67c 100644 --- a/packages/grpc-js/src/retrying-call.ts +++ b/packages/grpc-js/src/retrying-call.ts @@ -385,7 +385,7 @@ export class RetryingCall implements Call { if (this.underlyingCalls[callIndex].state === 'COMPLETED') { return; } - this.trace('state=' + this.state + ' handling status from child [' + this.underlyingCalls[callIndex].call.getCallNumber() + '] in state ' + this.underlyingCalls[callIndex].state); + this.trace('state=' + this.state + ' handling status with progress ' + status.progress + ' from child [' + this.underlyingCalls[callIndex].call.getCallNumber() + '] in state ' + this.underlyingCalls[callIndex].state); this.underlyingCalls[callIndex].state = 'COMPLETED'; if (status.code === Status.OK) { this.retryThrottler?.addCallSucceeded(); From 47ba3578610db38c0b8c4dff1ddc009d0054a9ed Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 17 Nov 2022 09:34:16 -0800 Subject: [PATCH 376/450] Fix typo in service config validation error messages --- packages/grpc-js/src/service-config.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/grpc-js/src/service-config.ts b/packages/grpc-js/src/service-config.ts index 2b8c0a7eb..201c0c648 100644 --- a/packages/grpc-js/src/service-config.ts +++ b/packages/grpc-js/src/service-config.ts @@ -133,14 +133,14 @@ function validateRetryPolicy(obj: any): RetryPolicy { for (const value of obj.retryableStatusCodes) { if (typeof value === 'number') { if (!Object.values(Status).includes(value)) { - throw new Error('Invlid method config retry policy: retryableStatusCodes value not in status code range'); + throw new Error('Invalid method config retry policy: retryableStatusCodes value not in status code range'); } } else if (typeof value === 'string') { if (!Object.values(Status).includes(value.toUpperCase())) { - throw new Error('Invlid method config retry policy: retryableStatusCodes value not a status code name'); + throw new Error('Invalid method config retry policy: retryableStatusCodes value not a status code name'); } } else { - throw new Error('Invlid method config retry policy: retryableStatusCodes value must be a string or number'); + throw new Error('Invalid method config retry policy: retryableStatusCodes value must be a string or number'); } } return { From f1f351f3cde6c2975785d622de63cdf9a7132984 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 17 Nov 2022 11:09:16 -0800 Subject: [PATCH 377/450] Fix handling of messages that overflow the buffer limit --- packages/grpc-js/src/retrying-call.ts | 64 ++++++++++++++++++++------- 1 file changed, 49 insertions(+), 15 deletions(-) diff --git a/packages/grpc-js/src/retrying-call.ts b/packages/grpc-js/src/retrying-call.ts index a85fac67c..8d3bb6579 100644 --- a/packages/grpc-js/src/retrying-call.ts +++ b/packages/grpc-js/src/retrying-call.ts @@ -135,6 +135,12 @@ interface WriteBufferEntry { * state. */ callback?: WriteCallback; + /** + * Indicates whether the message is allocated in the buffer tracker. Ignored + * if entryType is not MESSAGE. Should be the return value of + * bufferTracker.allocate. + */ + allocated: boolean; } const PREVIONS_RPC_ATTEMPTS_METADATA_KEY = 'grpc-previous-rpc-attempts'; @@ -216,6 +222,22 @@ export class RetryingCall implements Call { } } + private maybefreeMessageBufferEntry(messageIndex: number) { + if (this.state !== 'COMMITTED') { + return; + } + const bufferEntry = this.writeBuffer[messageIndex]; + if (bufferEntry.entryType === 'MESSAGE') { + if (bufferEntry.allocated) { + this.bufferTracker.free(bufferEntry.message!.message.length, this.callNumber); + } + this.writeBuffer[messageIndex] = { + entryType: 'FREED', + allocated: false + }; + } + } + private commitCall(index: number) { if (this.state === 'COMMITTED') { return; @@ -237,13 +259,7 @@ export class RetryingCall implements Call { this.underlyingCalls[i].call.cancelWithStatus(Status.CANCELLED, 'Discarded in favor of other hedged attempt'); } for (let messageIndex = 0; messageIndex < this.underlyingCalls[index].nextMessageToSend - 1; messageIndex += 1) { - const bufferEntry = this.writeBuffer[messageIndex]; - if (bufferEntry.entryType === 'MESSAGE') { - this.bufferTracker.free(bufferEntry.message!.message.length, this.callNumber); - this.writeBuffer[messageIndex] = { - entryType: 'FREED' - }; - } + this.maybefreeMessageBufferEntry(messageIndex); } } @@ -513,6 +529,15 @@ export class RetryingCall implements Call { this.maybeStartHedgingTimer(); } + private handleChildWriteCompleted(childIndex: number) { + const childCall = this.underlyingCalls[childIndex]; + const messageIndex = childCall.nextMessageToSend; + this.writeBuffer[messageIndex].callback?.(); + this.maybefreeMessageBufferEntry(messageIndex); + childCall.nextMessageToSend += 1; + this.sendNextChildMessage(childIndex); + } + private sendNextChildMessage(childIndex: number) { const childCall = this.underlyingCalls[childIndex]; if (childCall.state === 'COMPLETED') { @@ -525,8 +550,7 @@ export class RetryingCall implements Call { childCall.call.sendMessageWithContext({ callback: (error) => { // Ignore error - childCall.nextMessageToSend += 1; - this.sendNextChildMessage(childIndex); + this.handleChildWriteCompleted(childIndex); } }, bufferEntry.message!.message); break; @@ -550,25 +574,34 @@ export class RetryingCall implements Call { const messageIndex = this.writeBuffer.length; const bufferEntry: WriteBufferEntry = { entryType: 'MESSAGE', - message: writeObj + message: writeObj, + allocated: this.bufferTracker.allocate(message.length, this.callNumber) }; this.writeBuffer[messageIndex] = bufferEntry; - if (this.bufferTracker.allocate(message.length, this.callNumber)) { + if (bufferEntry.allocated) { context.callback?.(); for (const [callIndex, call] of this.underlyingCalls.entries()) { if (call.state === 'ACTIVE' && call.nextMessageToSend === messageIndex) { call.call.sendMessageWithContext({ callback: (error) => { // Ignore error - call.nextMessageToSend += 1; - this.sendNextChildMessage(callIndex); + this.handleChildWriteCompleted(callIndex); } }, message); } } } else { this.commitCallWithMostMessages(); - bufferEntry.callback = context.callback; + const call = this.underlyingCalls[this.committedCallIndex!]; + bufferEntry.callback = context.callback; + if (call.state === 'ACTIVE' && call.nextMessageToSend === messageIndex) { + call.call.sendMessageWithContext({ + callback: (error) => { + // Ignore error + this.handleChildWriteCompleted(this.committedCallIndex!); + } + }, message); + } } } startRead(): void { @@ -584,7 +617,8 @@ export class RetryingCall implements Call { this.trace('halfClose called'); const halfCloseIndex = this.writeBuffer.length; this.writeBuffer[halfCloseIndex] = { - entryType: 'HALF_CLOSE' + entryType: 'HALF_CLOSE', + allocated: false }; for (const call of this.underlyingCalls) { if (call?.state === 'ACTIVE' && call.nextMessageToSend === halfCloseIndex) { From fa21e13ef38dd7cbc44fd1156fd97169c876025e Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 17 Nov 2022 11:51:49 -0800 Subject: [PATCH 378/450] Limit maxAttempts to 5 for retries and hedging --- packages/grpc-js/src/retrying-call.ts | 6 +-- packages/grpc-js/test/test-retry.ts | 63 +++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/packages/grpc-js/src/retrying-call.ts b/packages/grpc-js/src/retrying-call.ts index 8d3bb6579..f9bda9eb5 100644 --- a/packages/grpc-js/src/retrying-call.ts +++ b/packages/grpc-js/src/retrying-call.ts @@ -296,7 +296,7 @@ export class RetryingCall implements Call { return; } const retryPolicy = this.callConfig!.methodConfig.retryPolicy!; - if (this.attempts >= retryPolicy.maxAttempts) { + if (this.attempts >= Math.min(retryPolicy.maxAttempts, 5)) { callback(false); return; } @@ -446,7 +446,7 @@ export class RetryingCall implements Call { return; } const hedgingPolicy = this.callConfig.methodConfig.hedgingPolicy; - if (this.attempts >= hedgingPolicy.maxAttempts) { + if (this.attempts >= Math.min(hedgingPolicy.maxAttempts, 5)) { return; } this.attempts += 1; @@ -465,7 +465,7 @@ export class RetryingCall implements Call { return; } const hedgingPolicy = this.callConfig.methodConfig.hedgingPolicy; - if (this.attempts >= hedgingPolicy.maxAttempts) { + if (this.attempts >= Math.min(hedgingPolicy.maxAttempts, 5)) { return; } const hedgingDelayString = hedgingPolicy.hedgingDelay ?? '0s'; diff --git a/packages/grpc-js/test/test-retry.ts b/packages/grpc-js/test/test-retry.ts index 4dd96cc43..66c0f7941 100644 --- a/packages/grpc-js/test/test-retry.ts +++ b/packages/grpc-js/test/test-retry.ts @@ -216,6 +216,39 @@ describe('Retries', () => { } ); }); + + it('Should not be able to make more than 5 attempts', (done) => { + const serviceConfig = { + loadBalancingConfig: [], + methodConfig: [ + { + name: [{ + service: 'EchoService' + }], + retryPolicy: { + maxAttempts: 10, + initialBackoff: '0.1s', + maxBackoff: '10s', + backoffMultiplier: 1.2, + retryableStatusCodes: [14, 'RESOURCE_EXHAUSTED'] + } + } + ] + } + const client2 = new EchoService(`localhost:${port}`, grpc.credentials.createInsecure(), {'grpc.service_config': JSON.stringify(serviceConfig)}); + const metadata = new grpc.Metadata(); + metadata.set('succeed-on-retry-attempt', '6'); + metadata.set('respond-with-status', `${grpc.status.RESOURCE_EXHAUSTED}`); + client2.echo( + { value: 'test value', value2: 3 }, + metadata, + (error: grpc.ServiceError, response: any) => { + assert(error); + assert.strictEqual(error.details, 'Failed on retry 4'); + done(); + } + ); + }) }); describe('Client with hedging configured', () => { @@ -297,5 +330,35 @@ describe('Retries', () => { } ); }); + + it('Should not be able to make more than 5 attempts', (done) => { + const serviceConfig = { + loadBalancingConfig: [], + methodConfig: [ + { + name: [{ + service: 'EchoService' + }], + hedgingPolicy: { + maxAttempts: 10, + nonFatalStatusCodes: [14, 'RESOURCE_EXHAUSTED'] + } + } + ] + } + const client2 = new EchoService(`localhost:${port}`, grpc.credentials.createInsecure(), {'grpc.service_config': JSON.stringify(serviceConfig)}); + const metadata = new grpc.Metadata(); + metadata.set('succeed-on-retry-attempt', '6'); + metadata.set('respond-with-status', `${grpc.status.RESOURCE_EXHAUSTED}`); + client2.echo( + { value: 'test value', value2: 3 }, + metadata, + (error: grpc.ServiceError, response: any) => { + assert(error); + assert(error.details.startsWith('Failed on retry')); + done(); + } + ); + }) }); }); \ No newline at end of file From 641ed45d489811740dc84dccc2fbf9d460a96b7a Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 18 Nov 2022 15:06:41 -0800 Subject: [PATCH 379/450] grpc-js-xds: Update failure mode behavior --- packages/grpc-js-xds/src/xds-client.ts | 42 +++++++++++++++---- .../src/xds-stream-state/xds-stream-state.ts | 3 ++ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index 439ed80ea..2dfa41236 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -18,7 +18,7 @@ import * as protoLoader from '@grpc/proto-loader'; // This is a non-public, unstable API, but it's very convenient import { loadProtosWithOptionsSync } from '@grpc/proto-loader/build/src/util'; -import { loadPackageDefinition, StatusObject, status, logVerbosity, Metadata, experimental, ChannelOptions, ClientDuplexStream, ServiceError, ChannelCredentials, Channel } from '@grpc/grpc-js'; +import { loadPackageDefinition, StatusObject, status, logVerbosity, Metadata, experimental, ChannelOptions, ClientDuplexStream, ServiceError, ChannelCredentials, Channel, connectivityState } from '@grpc/grpc-js'; import * as adsTypes from './generated/ads'; import * as lrsTypes from './generated/lrs'; import { loadBootstrapInfo } from './xds-bootstrap'; @@ -255,6 +255,7 @@ export class XdsClient { DiscoveryRequest, DiscoveryResponse__Output > | null = null; + private receivedAdsResponseOnCurrentStream = false; private lrsNode: Node | null = null; private lrsClient: LoadReportingServiceClient | null = null; @@ -373,6 +374,9 @@ export class XdsClient { {channelOverride: channel} ); this.maybeStartAdsStream(); + channel.watchConnectivityState(channel.getConnectivityState(false), Infinity, () => { + this.handleAdsConnectivityStateUpdate(); + }) this.lrsClient = new protoDefinitions.envoy.service.load_stats.v3.LoadReportingService( serverUri, @@ -394,7 +398,29 @@ export class XdsClient { clearInterval(this.statsTimer); } + private handleAdsConnectivityStateUpdate() { + if (!this.adsClient) { + return; + } + const state = this.adsClient.getChannel().getConnectivityState(false); + if (state === connectivityState.READY && this.adsCall) { + this.reportAdsStreamStarted(); + } + if (state === connectivityState.TRANSIENT_FAILURE) { + this.reportStreamError({ + code: status.UNAVAILABLE, + details: 'No connection established to xDS server', + metadata: new Metadata() + }); + } + this.adsClient.getChannel().watchConnectivityState(state, Infinity, () => { + this.handleAdsConnectivityStateUpdate(); + }); + } + private handleAdsResponse(message: DiscoveryResponse__Output) { + this.receivedAdsResponseOnCurrentStream = true; + this.adsBackoff.reset(); let handleResponseResult: { result: HandleResponseResult; serviceKind: AdsServiceKind; @@ -466,7 +492,7 @@ export class XdsClient { 'ADS stream ended. code=' + streamStatus.code + ' details= ' + streamStatus.details ); this.adsCall = null; - if (streamStatus.code !== status.OK) { + if (streamStatus.code !== status.OK && !this.receivedAdsResponseOnCurrentStream) { this.reportStreamError(streamStatus); } /* If the backoff timer is no longer running, we do not need to wait any @@ -496,7 +522,9 @@ export class XdsClient { if (this.adsCall !== null) { return; } - this.adsCall = this.adsClient.StreamAggregatedResources(); + this.receivedAdsResponseOnCurrentStream = false; + const metadata = new Metadata({waitForReady: true}); + this.adsCall = this.adsClient.StreamAggregatedResources(metadata); this.adsCall.on('data', (message: DiscoveryResponse__Output) => { this.handleAdsResponse(message); }); @@ -515,7 +543,9 @@ export class XdsClient { this.updateNames(service); } } - this.reportAdsStreamStarted(); + if (this.adsClient.getChannel().getConnectivityState(false) === connectivityState.READY) { + this.reportAdsStreamStarted(); + } } private maybeSendAdsMessage(typeUrl: string, resourceNames: string[], responseNonce: string, versionInfo: string, errorMessage?: string) { @@ -547,10 +577,6 @@ export class XdsClient { * version info are updated so that it sends the post-update values. */ ack(serviceKind: AdsServiceKind) { - /* An ack is the best indication of a successful interaction between the - * client and the server, so we can reset the backoff timer here. */ - this.adsBackoff.reset(); - this.updateNames(serviceKind); } diff --git a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts index 86c2cea4b..e20bc7e9b 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts @@ -213,6 +213,9 @@ export abstract class BaseXdsStreamState implements XdsStreamState } reportAdsStreamStart() { + if (this.isAdsStreamRunning) { + return; + } this.isAdsStreamRunning = true; for (const subscriptionEntry of this.subscriptions.values()) { if (subscriptionEntry.cachedResponse === null) { From 6b4dd60f1130f1f8aea6c4df111666cb3965f024 Mon Sep 17 00:00:00 2001 From: natiz Date: Sun, 27 Nov 2022 23:37:56 +0200 Subject: [PATCH 380/450] fix: windows build --- packages/grpc-tools/CMakeLists.txt | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/grpc-tools/CMakeLists.txt b/packages/grpc-tools/CMakeLists.txt index 9d6690ba7..14fb3c943 100644 --- a/packages/grpc-tools/CMakeLists.txt +++ b/packages/grpc-tools/CMakeLists.txt @@ -1,17 +1,21 @@ -cmake_minimum_required(VERSION 3.6) +cmake_minimum_required(VERSION 3.15) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) +# MSVC runtime library flags are selected by an abstraction. +if(COMMAND cmake_policy AND POLICY CMP0091) + cmake_policy(SET CMP0091 NEW) +endif() + set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) -set(PROTOBUF_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/protobuf) -add_subdirectory(${PROTOBUF_ROOT_DIR}/cmake deps/protobuf) - set(protobuf_BUILD_TESTS OFF CACHE BOOL "Build protobuf tests") set(protobuf_WITH_ZLIB OFF CACHE BOOL "Build protobuf with zlib.") +set(PROTOBUF_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/deps/protobuf) +add_subdirectory(${PROTOBUF_ROOT_DIR}/cmake deps/protobuf) set(CMAKE_EXE_LINKER_FLAGS "-static-libstdc++") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-stack-protector") @@ -22,7 +26,7 @@ add_executable(grpc_node_plugin ) if (MSVC) - add_definitions(/MTd) + set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$:Debug>) endif (MSVC) target_include_directories(grpc_node_plugin @@ -34,4 +38,4 @@ target_include_directories(grpc_node_plugin target_link_libraries(grpc_node_plugin libprotoc libprotobuf -) \ No newline at end of file +) From edf612a56af58b3f8829bb78741639d75b19db3e Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 29 Nov 2022 14:29:47 -0500 Subject: [PATCH 381/450] grpc-js-xds: Implement retry support --- packages/grpc-js-xds/src/environment.ts | 3 +- packages/grpc-js-xds/src/resolver-xds.ts | 54 +++++++++++++++++-- packages/grpc-js-xds/src/route-action.ts | 31 ++++------- .../src/xds-stream-state/rds-state.ts | 43 ++++++++++++++- packages/grpc-js/src/experimental.ts | 2 +- 5 files changed, 104 insertions(+), 29 deletions(-) diff --git a/packages/grpc-js-xds/src/environment.ts b/packages/grpc-js-xds/src/environment.ts index 250f791ac..47222f8a4 100644 --- a/packages/grpc-js-xds/src/environment.ts +++ b/packages/grpc-js-xds/src/environment.ts @@ -16,4 +16,5 @@ */ export const EXPERIMENTAL_FAULT_INJECTION = (process.env.GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION ?? 'true') === 'true'; -export const EXPERIMENTAL_OUTLIER_DETECTION = (process.env.GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION ?? 'true') === 'true'; \ No newline at end of file +export const EXPERIMENTAL_OUTLIER_DETECTION = (process.env.GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION ?? 'true') === 'true'; +export const EXPERIMENTAL_RETRY = process.env.GRPC_XDS_EXPERIMENTAL_ENABLE_RETRY === 'true'; \ No newline at end of file diff --git a/packages/grpc-js-xds/src/resolver-xds.ts b/packages/grpc-js-xds/src/resolver-xds.ts index 496c37094..401465be6 100644 --- a/packages/grpc-js-xds/src/resolver-xds.ts +++ b/packages/grpc-js-xds/src/resolver-xds.ts @@ -44,9 +44,10 @@ import { decodeSingleResource, HTTP_CONNECTION_MANGER_TYPE_URL } from './resourc import Duration = experimental.Duration; import { Duration__Output } from './generated/google/protobuf/Duration'; import { createHttpFilter, HttpFilterConfig, parseOverrideFilterConfig, parseTopLevelFilterConfig } from './http-filter'; -import { EXPERIMENTAL_FAULT_INJECTION } from './environment'; +import { EXPERIMENTAL_FAULT_INJECTION, EXPERIMENTAL_RETRY } from './environment'; import Filter = experimental.Filter; import FilterFactory = experimental.FilterFactory; +import RetryPolicy = experimental.RetryPolicy; const TRACER_NAME = 'xds_resolver'; @@ -199,6 +200,24 @@ function protoDurationToDuration(duration: Duration__Output): Duration { } } +function protoDurationToSecondsString(duration: Duration__Output): string { + return `${duration.seconds + duration.nanos / 1_000_000_000}s`; +} + +const DEFAULT_RETRY_BASE_INTERVAL = '0.025s' + +function getDefaultRetryMaxInterval(baseInterval: string): string { + return `${Number.parseFloat(baseInterval.substring(0, baseInterval.length - 1)) * 10}s`; +} + +const RETRY_CODES: {[key: string]: status} = { + 'cancelled': status.CANCELLED, + 'deadline-exceeded': status.DEADLINE_EXCEEDED, + 'internal': status.INTERNAL, + 'resource-exhausted': status.RESOURCE_EXHAUSTED, + 'unavailable': status.UNAVAILABLE +}; + class XdsResolver implements Resolver { private hasReportedSuccess = false; @@ -363,6 +382,33 @@ class XdsResolver implements Resolver { } } } + let retryPolicy: RetryPolicy | undefined = undefined; + if (EXPERIMENTAL_RETRY) { + const retryConfig = route.route!.retry_policy ?? virtualHost.retry_policy; + if (retryConfig) { + const retryableStatusCodes = []; + for (const code of retryConfig.retry_on.split(',')) { + if (RETRY_CODES[code]) { + retryableStatusCodes.push(RETRY_CODES[code]); + } + } + if (retryableStatusCodes.length > 0) { + const baseInterval = retryConfig.retry_back_off?.base_interval ? + protoDurationToSecondsString(retryConfig.retry_back_off.base_interval) : + DEFAULT_RETRY_BASE_INTERVAL; + const maxInterval = retryConfig.retry_back_off?.max_interval ? + protoDurationToSecondsString(retryConfig.retry_back_off.max_interval) : + getDefaultRetryMaxInterval(baseInterval); + retryPolicy = { + backoffMultiplier: 2, + initialBackoff: baseInterval, + maxBackoff: maxInterval, + maxAttempts: (retryConfig.num_retries?.value ?? 1) + 1, + retryableStatusCodes: retryableStatusCodes + }; + } + } + } switch (route.route!.cluster_specifier) { case 'cluster_header': continue; @@ -390,7 +436,7 @@ class XdsResolver implements Resolver { } } } - routeAction = new SingleClusterRouteAction(cluster, timeout, extraFilterFactories); + routeAction = new SingleClusterRouteAction(cluster, {name: [], timeout: timeout, retryPolicy: retryPolicy}, extraFilterFactories); break; } case 'weighted_clusters': { @@ -432,7 +478,7 @@ class XdsResolver implements Resolver { } weightedClusters.push({name: clusterWeight.name, weight: clusterWeight.weight?.value ?? 0, dynamicFilterFactories: extraFilterFactories}); } - routeAction = new WeightedClusterRouteAction(weightedClusters, route.route!.weighted_clusters!.total_weight?.value ?? 100, timeout); + routeAction = new WeightedClusterRouteAction(weightedClusters, route.route!.weighted_clusters!.total_weight?.value ?? 100, {name: [], timeout: timeout, retryPolicy: retryPolicy}); break; } default: @@ -470,7 +516,7 @@ class XdsResolver implements Resolver { this.unrefCluster(clusterResult.name); } return { - methodConfig: {name: [], timeout: action.getTimeout()}, + methodConfig: clusterResult.methodConfig, onCommitted: onCommitted, pickInformation: {cluster: clusterResult.name}, status: status.OK, diff --git a/packages/grpc-js-xds/src/route-action.ts b/packages/grpc-js-xds/src/route-action.ts index d29e67b9b..5ae5885af 100644 --- a/packages/grpc-js-xds/src/route-action.ts +++ b/packages/grpc-js-xds/src/route-action.ts @@ -18,16 +18,17 @@ import { experimental } from '@grpc/grpc-js'; import Duration = experimental.Duration; import Filter = experimental.Filter; import FilterFactory = experimental.FilterFactory; +import MethodConfig = experimental.MethodConfig; export interface ClusterResult { name: string; + methodConfig: MethodConfig; dynamicFilterFactories: FilterFactory[]; } export interface RouteAction { toString(): string; getCluster(): ClusterResult; - getTimeout(): Duration | undefined; } function durationToLogString(duration: Duration) { @@ -40,25 +41,18 @@ function durationToLogString(duration: Duration) { } export class SingleClusterRouteAction implements RouteAction { - constructor(private cluster: string, private timeout: Duration | undefined, private extraFilterFactories: FilterFactory[]) {} + constructor(private cluster: string, private methodConfig: MethodConfig, private extraFilterFactories: FilterFactory[]) {} getCluster() { return { name: this.cluster, + methodConfig: this.methodConfig, dynamicFilterFactories: this.extraFilterFactories }; } toString() { - if (this.timeout) { - return 'SingleCluster(' + this.cluster + ', ' + 'timeout=' + durationToLogString(this.timeout) + 's)'; - } else { - return 'SingleCluster(' + this.cluster + ')'; - } - } - - getTimeout() { - return this.timeout; + return 'SingleCluster(' + this.cluster + ', ' + JSON.stringify(this.methodConfig) + ')'; } } @@ -79,7 +73,7 @@ export class WeightedClusterRouteAction implements RouteAction { * The weighted cluster choices represented as a CDF */ private clusterChoices: ClusterChoice[]; - constructor(private clusters: WeightedCluster[], private totalWeight: number, private timeout: Duration | undefined) { + constructor(private clusters: WeightedCluster[], private totalWeight: number, private methodConfig: MethodConfig) { this.clusterChoices = []; let lastNumerator = 0; for (const clusterWeight of clusters) { @@ -94,24 +88,17 @@ export class WeightedClusterRouteAction implements RouteAction { if (randomNumber < choice.numerator) { return { name: choice.name, + methodConfig: this.methodConfig, dynamicFilterFactories: choice.dynamicFilterFactories }; } } // This should be prevented by the validation rules - return {name: '', dynamicFilterFactories: []}; + return {name: '', methodConfig: this.methodConfig, dynamicFilterFactories: []}; } toString() { const clusterListString = this.clusters.map(({name, weight}) => '(' + name + ':' + weight + ')').join(', ') - if (this.timeout) { - return 'WeightedCluster(' + clusterListString + ', ' + 'timeout=' + durationToLogString(this.timeout) + 's)'; - } else { - return 'WeightedCluster(' + clusterListString + ')'; - } - } - - getTimeout() { - return this.timeout; + return 'WeightedCluster(' + clusterListString + ', ' + JSON.stringify(this.methodConfig) + ')'; } } \ No newline at end of file diff --git a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts index 119ac6b92..891eb7c8e 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts @@ -15,8 +15,10 @@ * */ -import { EXPERIMENTAL_FAULT_INJECTION } from "../environment"; +import { EXPERIMENTAL_FAULT_INJECTION, EXPERIMENTAL_RETRY } from "../environment"; +import { RetryPolicy__Output } from "../generated/envoy/config/route/v3/RetryPolicy"; import { RouteConfiguration__Output } from "../generated/envoy/config/route/v3/RouteConfiguration"; +import { Duration__Output } from "../generated/google/protobuf/Duration"; import { validateOverrideFilter } from "../http-filter"; import { BaseXdsStreamState, XdsStreamState } from "./xds-stream-state"; @@ -30,6 +32,13 @@ const SUPPPORTED_HEADER_MATCH_SPECIFIERS = [ 'suffix_match']; const SUPPORTED_CLUSTER_SPECIFIERS = ['cluster', 'weighted_clusters', 'cluster_header']; +function durationToMs(duration: Duration__Output | null): number | null { + if (duration === null) { + return null; + } + return (Number.parseInt(duration.seconds) * 1000 + duration.nanos / 1_000_000) | 0; +} + export class RdsState extends BaseXdsStreamState implements XdsStreamState { protected isStateOfTheWorld(): boolean { return false; @@ -40,6 +49,28 @@ export class RdsState extends BaseXdsStreamState imp protected getProtocolName(): string { return 'RDS'; } + + private validateRetryPolicy(policy: RetryPolicy__Output | null): boolean { + if (policy === null) { + return true; + } + const numRetries = policy.num_retries?.value ?? 1 + if (numRetries < 1) { + return false; + } + if (policy.retry_back_off) { + if (!policy.retry_back_off.base_interval) { + return false; + } + const baseInterval = durationToMs(policy.retry_back_off.base_interval)!; + const maxInterval = durationToMs(policy.retry_back_off.max_interval) ?? (10 * baseInterval); + if (!(maxInterval >= baseInterval) && (baseInterval > 0)) { + return false; + } + } + return true; + } + validateResponse(message: RouteConfiguration__Output): boolean { // https://github.com/grpc/proposal/blob/master/A28-xds-traffic-splitting-and-routing.md#response-validation for (const virtualHost of message.virtual_hosts) { @@ -62,6 +93,11 @@ export class RdsState extends BaseXdsStreamState imp } } } + if (EXPERIMENTAL_RETRY) { + if (!this.validateRetryPolicy(virtualHost.retry_policy)) { + return false; + } + } for (const route of virtualHost.routes) { const match = route.match; if (!match) { @@ -88,6 +124,11 @@ export class RdsState extends BaseXdsStreamState imp } } } + if (EXPERIMENTAL_RETRY) { + if (!this.validateRetryPolicy(route.route.retry_policy)) { + return false; + } + } if (route.route!.cluster_specifier === 'weighted_clusters') { if (route.route.weighted_clusters!.total_weight?.value === 0) { return false; diff --git a/packages/grpc-js/src/experimental.ts b/packages/grpc-js/src/experimental.ts index 92d6d44c6..a7c28219b 100644 --- a/packages/grpc-js/src/experimental.ts +++ b/packages/grpc-js/src/experimental.ts @@ -7,7 +7,7 @@ export { } from './resolver'; export { GrpcUri, uriToString } from './uri-parser'; export { Duration, durationToMs } from './duration'; -export { ServiceConfig } from './service-config'; +export { ServiceConfig, MethodConfig, RetryPolicy } from './service-config'; export { BackoffTimeout } from './backoff-timeout'; export { LoadBalancer, From 6f755fe3469b888e7c0bca775f8eac430d0c8fb7 Mon Sep 17 00:00:00 2001 From: Taegeun Moon Date: Wed, 30 Nov 2022 22:31:22 +0900 Subject: [PATCH 382/450] add branded option for proto-loader-gen-types --- packages/proto-loader/bin/proto-loader-gen-types.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index a9ee4a6ed..ae7e147b5 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -45,6 +45,7 @@ type GeneratorOptions = Protobuf.IParseOptions & Protobuf.IConversionOptions & { includeComments?: boolean; inputTemplate: string; outputTemplate: string; + branded: boolean; } class TextFormatter { @@ -263,6 +264,9 @@ function generatePermissiveMessageInterface(formatter: TextFormatter, messageTyp } formatter.writeLine(`'${oneof.name}'?: ${typeString};`); } + if (options.branded) { + formatter.writeLine(`__type: '${messageType.fullName}'`) + } formatter.unindent(); formatter.writeLine('}'); } @@ -383,6 +387,9 @@ function generateRestrictedMessageInterface(formatter: TextFormatter, messageTyp formatter.writeLine(`'${oneof.name}': ${typeString};`); } } + if (options.branded) { + formatter.writeLine(`__type: '${messageType.fullName}'`) + } formatter.unindent(); formatter.writeLine('}'); } @@ -815,7 +822,7 @@ async function runScript() { .string(['includeDirs', 'grpcLib']) .normalize(['includeDirs', 'outDir']) .array('includeDirs') - .boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs', 'json', 'verbose', 'includeComments']) + .boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs', 'json', 'verbose', 'includeComments', 'branded']) .string(['longs', 'enums', 'bytes', 'inputTemplate', 'outputTemplate']) .default('keepCase', false) .default('defaults', false) @@ -829,6 +836,7 @@ async function runScript() { .default('bytes', 'Buffer') .default('inputTemplate', `${templateStr}`) .default('outputTemplate', `${templateStr}__Output`) + .default('branded', false) .coerce('longs', value => { switch (value) { case 'String': return String; @@ -868,6 +876,7 @@ async function runScript() { grpcLib: 'The gRPC implementation library that these types will be used with', inputTemplate: 'Template for mapping input or "permissive" type names', outputTemplate: 'Template for mapping output or "restricted" type names', + branded: 'Emit property for branded type whose value is fullName of the Message', }).demandOption(['outDir', 'grpcLib']) .demand(1) .usage('$0 [options] filenames...') From 9e548d4d87c55f2710aa5a62968fa1df565da5d4 Mon Sep 17 00:00:00 2001 From: Taegeun Moon Date: Wed, 30 Nov 2022 22:34:15 +0900 Subject: [PATCH 383/450] update readme --- packages/proto-loader/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/proto-loader/README.md b/packages/proto-loader/README.md index 818f0efda..740658786 100644 --- a/packages/proto-loader/README.md +++ b/packages/proto-loader/README.md @@ -92,6 +92,8 @@ Options: [string] [default: "%s"] --outputTemplate Template for mapping output or "restricted" type names [string] [default: "%s__Output"] + --branded Emit property for branded type whose value is fullName + of the Message [boolean] [default: false] ``` ### Example Usage From 87e70e890bc37c50791c03fb6dd18d1728f1448e Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 30 Nov 2022 13:59:03 -0500 Subject: [PATCH 384/450] grpc-tools: Update native build docker image --- tools/release/native/Dockerfile | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tools/release/native/Dockerfile b/tools/release/native/Dockerfile index d065bddbe..7346d9aff 100644 --- a/tools/release/native/Dockerfile +++ b/tools/release/native/Dockerfile @@ -1,11 +1,7 @@ -FROM debian:jessie +FROM debian:stretch -RUN echo "deb http://archive.debian.org/debian jessie-backports main" > /etc/apt/sources.list.d/backports.list -RUN echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf -RUN sed -i '/deb http:\/\/deb.debian.org\/debian jessie-updates main/d' /etc/apt/sources.list RUN apt-get update -RUN apt-get -t jessie-backports install -y cmake -RUN apt-get install -y curl build-essential python libc6-dev-i386 lib32stdc++-4.9-dev jq +RUN apt-get install -y cmake curl build-essential python libc6-dev-i386 lib32stdc++-6-dev jq RUN mkdir /usr/local/nvm ENV NVM_DIR /usr/local/nvm From b07b74bfd4c1e6886b046371772fc14b98c34e63 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 30 Nov 2022 15:40:49 -0500 Subject: [PATCH 385/450] Update information in README and PACKAGE-COMPARISON docs --- PACKAGE-COMPARISON.md | 10 +++++----- README.md | 16 ++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/PACKAGE-COMPARISON.md b/PACKAGE-COMPARISON.md index f0c444195..cd6308892 100644 --- a/PACKAGE-COMPARISON.md +++ b/PACKAGE-COMPARISON.md @@ -1,6 +1,6 @@ # Feature comparison of `grpc` and `@grpc/grpc-js` packages -Feature | `grpc` | `@grpc/grpc-js` +Feature | `grpc` (deprecated) | `@grpc/grpc-js` --------|--------|---------- Client | :heavy_check_mark: | :heavy_check_mark: Server | :heavy_check_mark: | :heavy_check_mark: @@ -9,7 +9,7 @@ Streaming RPCs | :heavy_check_mark: | :heavy_check_mark: Deadlines | :heavy_check_mark: | :heavy_check_mark: Cancellation | :heavy_check_mark: | :heavy_check_mark: Automatic Reconnection | :heavy_check_mark: | :heavy_check_mark: -Per-message Compression | :heavy_check_mark: | only for response messages +Per-message Compression | :heavy_check_mark: | :heavy_check_mark: (except messages sent by the server) Channel State | :heavy_check_mark: | :heavy_check_mark: JWT Access and Service Account Credentials | provided by the [Google Auth Library](https://www.npmjs.com/package/google-auth-library) | provided by the [Google Auth Library](https://www.npmjs.com/package/google-auth-library) Interceptors | :heavy_check_mark: | :heavy_check_mark: @@ -17,14 +17,14 @@ Connection Keepalives | :heavy_check_mark: | :heavy_check_mark: HTTP Connect Support | :heavy_check_mark: | :heavy_check_mark: Retries | :heavy_check_mark: | :x: Stats/tracing/monitoring | :heavy_check_mark: | :x: -Load Balancing | :heavy_check_mark: | Pick first and round robin +Load Balancing | :heavy_check_mark: | :heavy_check_mark: Initial Metadata Options | :heavy_check_mark: | only `waitForReady` Other Properties | `grpc` | `@grpc/grpc-js` -----------------|--------|---------------- Pure JavaScript Code | :x: | :heavy_check_mark: -Supported Node Versions | >= 4 | ^8.13.0 or >=10.10.0 -Supported Electron Versions | All | >= 3 +Supported Node Versions | >= 4 and <=14 | ^8.13.0 or >=10.10.0 +Supported Electron Versions | <=11.2 | >= 3 Supported Platforms | Linux, Windows, MacOS | All Supported Architectures | x86, x86-64, ARM7+ | All diff --git a/README.md b/README.md index 159fbab4f..f0f215ce3 100644 --- a/README.md +++ b/README.md @@ -5,21 +5,21 @@ For a comparison of the features available in these two libraries, see [this document](https://github.com/grpc/grpc-node/tree/master/PACKAGE-COMPARISON.md) -### C-based Client and Server +### Pure JavaScript Client and Server -Directory: [`packages/grpc-native-core`](https://github.com/grpc/grpc-node/tree/grpc@1.24.x/packages/grpc-native-core) (lives in the `grpc@1.24.x` branch) (see here for installation information) +Directory: [`packages/grpc-js`](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js) -npm package: [grpc](https://www.npmjs.com/package/grpc). +npm package: [@grpc/grpc-js](https://www.npmjs.com/package/@grpc/grpc-js) -This is the existing, feature-rich implementation of gRPC using a C++ addon. It works on all LTS versions of Node.js on most platforms that Node.js runs on. +This library implements the core functionality of gRPC purely in JavaScript, without a C++ addon. It works on the latest versions of Node.js on all platforms that Node.js runs on. -### Pure JavaScript Client +### C-based Client and Server (deprecated) -Directory: [`packages/grpc-js`](https://github.com/grpc/grpc-node/tree/master/packages/grpc-js) +Directory: [`packages/grpc-native-core`](https://github.com/grpc/grpc-node/tree/grpc@1.24.x/packages/grpc-native-core) (lives in the `grpc@1.24.x` branch) (see here for installation information) -npm package: [@grpc/grpc-js](https://www.npmjs.com/package/@grpc/grpc-js) +npm package: [grpc](https://www.npmjs.com/package/grpc). -This library implements the core functionality of gRPC purely in JavaScript, without a C++ addon. It works on the latest version of Node.js on all platforms that Node.js runs on. +This is the deprecated implementation of gRPC using a C++ addon. It works on versions of Node.js up to 14 on most platforms that Node.js runs on. ## Other Packages From e955c47bd51332e5cf08ac3b3b02c396ebe124f0 Mon Sep 17 00:00:00 2001 From: Taegeun Moon Date: Thu, 1 Dec 2022 11:09:09 +0900 Subject: [PATCH 386/450] rename as outputBranded --- .../bin/proto-loader-gen-types.ts | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index ae7e147b5..6327da951 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -37,6 +37,9 @@ const useNameFmter = ({outputTemplate, inputTemplate}: GeneratorOptions) => { }; } +const typeBrandHint = `This field is a type brand and is not populated at runtime. Instances of this type should be created using type assertions. +https://github.com/grpc/grpc-node/pull/2281`; + type GeneratorOptions = Protobuf.IParseOptions & Protobuf.IConversionOptions & { includeDirs?: string[]; grpcLib: string; @@ -45,7 +48,7 @@ type GeneratorOptions = Protobuf.IParseOptions & Protobuf.IConversionOptions & { includeComments?: boolean; inputTemplate: string; outputTemplate: string; - branded: boolean; + outputBranded: boolean; } class TextFormatter { @@ -179,6 +182,11 @@ function formatComment(formatter: TextFormatter, comment?: string | null) { formatter.writeLine(' */'); } +function formatTypeBrand(formatter: TextFormatter, messageType: Protobuf.Type) { + formatComment(formatter, typeBrandHint); + formatter.writeLine(`__type: '${messageType.fullName}'`); +} + // GENERATOR FUNCTIONS function getTypeNamePermissive(fieldType: string, resolvedType: Protobuf.Type | Protobuf.Enum | null, repeated: boolean, map: boolean, options: GeneratorOptions): string { @@ -264,9 +272,9 @@ function generatePermissiveMessageInterface(formatter: TextFormatter, messageTyp } formatter.writeLine(`'${oneof.name}'?: ${typeString};`); } - if (options.branded) { - formatter.writeLine(`__type: '${messageType.fullName}'`) - } + // if (options.inputBranded) { + // formatTypeBrand(formatter, messageType); + // } formatter.unindent(); formatter.writeLine('}'); } @@ -387,8 +395,8 @@ function generateRestrictedMessageInterface(formatter: TextFormatter, messageTyp formatter.writeLine(`'${oneof.name}': ${typeString};`); } } - if (options.branded) { - formatter.writeLine(`__type: '${messageType.fullName}'`) + if (options.outputBranded) { + formatTypeBrand(formatter, messageType); } formatter.unindent(); formatter.writeLine('}'); @@ -822,7 +830,7 @@ async function runScript() { .string(['includeDirs', 'grpcLib']) .normalize(['includeDirs', 'outDir']) .array('includeDirs') - .boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs', 'json', 'verbose', 'includeComments', 'branded']) + .boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs', 'json', 'verbose', 'includeComments', 'outputBranded']) .string(['longs', 'enums', 'bytes', 'inputTemplate', 'outputTemplate']) .default('keepCase', false) .default('defaults', false) @@ -836,7 +844,7 @@ async function runScript() { .default('bytes', 'Buffer') .default('inputTemplate', `${templateStr}`) .default('outputTemplate', `${templateStr}__Output`) - .default('branded', false) + .default('outputBranded', false) .coerce('longs', value => { switch (value) { case 'String': return String; @@ -876,7 +884,7 @@ async function runScript() { grpcLib: 'The gRPC implementation library that these types will be used with', inputTemplate: 'Template for mapping input or "permissive" type names', outputTemplate: 'Template for mapping output or "restricted" type names', - branded: 'Emit property for branded type whose value is fullName of the Message', + outputBranded: 'Output property for branded type for "restricted" types with fullName of the Message as its value', }).demandOption(['outDir', 'grpcLib']) .demand(1) .usage('$0 [options] filenames...') From 927c29de4ad8ac3f8642b6468fdd59d0cf587361 Mon Sep 17 00:00:00 2001 From: Taegeun Moon Date: Thu, 1 Dec 2022 12:37:48 +0900 Subject: [PATCH 387/450] support both input and output update readme update readme --- packages/proto-loader/README.md | 8 ++++++-- packages/proto-loader/bin/proto-loader-gen-types.ts | 13 +++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/packages/proto-loader/README.md b/packages/proto-loader/README.md index 740658786..99b34a05e 100644 --- a/packages/proto-loader/README.md +++ b/packages/proto-loader/README.md @@ -92,8 +92,12 @@ Options: [string] [default: "%s"] --outputTemplate Template for mapping output or "restricted" type names [string] [default: "%s__Output"] - --branded Emit property for branded type whose value is fullName - of the Message [boolean] [default: false] + --inputBranded Output property for branded type for "permissive" + types with fullName of the Message as its value + [boolean] + --outputBranded Output property for branded type for "restricted" + types with fullName of the Message as its value + [boolean] ``` ### Example Usage diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index 6327da951..dc9da1a9d 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -48,7 +48,8 @@ type GeneratorOptions = Protobuf.IParseOptions & Protobuf.IConversionOptions & { includeComments?: boolean; inputTemplate: string; outputTemplate: string; - outputBranded: boolean; + inputBranded?: boolean; + outputBranded?: boolean; } class TextFormatter { @@ -272,9 +273,9 @@ function generatePermissiveMessageInterface(formatter: TextFormatter, messageTyp } formatter.writeLine(`'${oneof.name}'?: ${typeString};`); } - // if (options.inputBranded) { - // formatTypeBrand(formatter, messageType); - // } + if (options.inputBranded) { + formatTypeBrand(formatter, messageType); + } formatter.unindent(); formatter.writeLine('}'); } @@ -830,7 +831,7 @@ async function runScript() { .string(['includeDirs', 'grpcLib']) .normalize(['includeDirs', 'outDir']) .array('includeDirs') - .boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs', 'json', 'verbose', 'includeComments', 'outputBranded']) + .boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs', 'json', 'verbose', 'includeComments', 'inputBranded', 'outputBranded']) .string(['longs', 'enums', 'bytes', 'inputTemplate', 'outputTemplate']) .default('keepCase', false) .default('defaults', false) @@ -844,7 +845,6 @@ async function runScript() { .default('bytes', 'Buffer') .default('inputTemplate', `${templateStr}`) .default('outputTemplate', `${templateStr}__Output`) - .default('outputBranded', false) .coerce('longs', value => { switch (value) { case 'String': return String; @@ -884,6 +884,7 @@ async function runScript() { grpcLib: 'The gRPC implementation library that these types will be used with', inputTemplate: 'Template for mapping input or "permissive" type names', outputTemplate: 'Template for mapping output or "restricted" type names', + inputBranded: 'Output property for branded type for "permissive" types with fullName of the Message as its value', outputBranded: 'Output property for branded type for "restricted" types with fullName of the Message as its value', }).demandOption(['outDir', 'grpcLib']) .demand(1) From 256fbd89150e1f69e96a5d631c97745d5f51b169 Mon Sep 17 00:00:00 2001 From: Taegeun Moon Date: Thu, 1 Dec 2022 13:27:04 +0900 Subject: [PATCH 388/450] set defaults for brand option --- packages/proto-loader/README.md | 12 ++++++------ .../proto-loader/bin/proto-loader-gen-types.ts | 14 +++++++++++--- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/proto-loader/README.md b/packages/proto-loader/README.md index 99b34a05e..f10831eeb 100644 --- a/packages/proto-loader/README.md +++ b/packages/proto-loader/README.md @@ -63,6 +63,12 @@ proto-loader-gen-types.js [options] filenames... Options: --help Show help [boolean] --version Show version number [boolean] + --inputBranded Output property for branded type for "permissive" + types with fullName of the Message as its value + [boolean] [default: false] + --outputBranded Output property for branded type for "restricted" + types with fullName of the Message as its value + [boolean] [default: false] --keepCase Preserve the case of field names [boolean] [default: false] --longs The type that should be used to output 64 bit integer @@ -92,12 +98,6 @@ Options: [string] [default: "%s"] --outputTemplate Template for mapping output or "restricted" type names [string] [default: "%s__Output"] - --inputBranded Output property for branded type for "permissive" - types with fullName of the Message as its value - [boolean] - --outputBranded Output property for branded type for "restricted" - types with fullName of the Message as its value - [boolean] ``` ### Example Usage diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index dc9da1a9d..465f362fe 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -48,8 +48,8 @@ type GeneratorOptions = Protobuf.IParseOptions & Protobuf.IConversionOptions & { includeComments?: boolean; inputTemplate: string; outputTemplate: string; - inputBranded?: boolean; - outputBranded?: boolean; + inputBranded: boolean; + outputBranded: boolean; } class TextFormatter { @@ -831,7 +831,7 @@ async function runScript() { .string(['includeDirs', 'grpcLib']) .normalize(['includeDirs', 'outDir']) .array('includeDirs') - .boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs', 'json', 'verbose', 'includeComments', 'inputBranded', 'outputBranded']) + .boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs', 'json', 'verbose', 'includeComments']) .string(['longs', 'enums', 'bytes', 'inputTemplate', 'outputTemplate']) .default('keepCase', false) .default('defaults', false) @@ -864,6 +864,14 @@ async function runScript() { default: return undefined; } }) + .option('inputBranded', { + boolean: true, + default: false, + }) + .option('outputBranded', { + boolean: true, + default: false, + }) .alias({ includeDirs: 'I', outDir: 'O', From 80332044c73ba0789efc563b329fd9c9257cad6b Mon Sep 17 00:00:00 2001 From: Taegeun Moon Date: Thu, 1 Dec 2022 14:12:10 +0900 Subject: [PATCH 389/450] update typeBrandHint location --- packages/proto-loader/bin/proto-loader-gen-types.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index 465f362fe..5a9a32f88 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -37,9 +37,6 @@ const useNameFmter = ({outputTemplate, inputTemplate}: GeneratorOptions) => { }; } -const typeBrandHint = `This field is a type brand and is not populated at runtime. Instances of this type should be created using type assertions. -https://github.com/grpc/grpc-node/pull/2281`; - type GeneratorOptions = Protobuf.IParseOptions & Protobuf.IConversionOptions & { includeDirs?: string[]; grpcLib: string; @@ -183,6 +180,9 @@ function formatComment(formatter: TextFormatter, comment?: string | null) { formatter.writeLine(' */'); } +const typeBrandHint = `This field is a type brand and is not populated at runtime. Instances of this type should be created using type assertions. +https://github.com/grpc/grpc-node/pull/2281`; + function formatTypeBrand(formatter: TextFormatter, messageType: Protobuf.Type) { formatComment(formatter, typeBrandHint); formatter.writeLine(`__type: '${messageType.fullName}'`); From 8ce5bf8c247fa41cba94e4134b44f9001358b227 Mon Sep 17 00:00:00 2001 From: natiz Date: Thu, 1 Dec 2022 14:21:22 +0200 Subject: [PATCH 390/450] fix: lower cmake version to 3.7 --- packages/grpc-tools/CMakeLists.txt | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/grpc-tools/CMakeLists.txt b/packages/grpc-tools/CMakeLists.txt index 14fb3c943..555346912 100644 --- a/packages/grpc-tools/CMakeLists.txt +++ b/packages/grpc-tools/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.7) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) @@ -26,8 +26,21 @@ add_executable(grpc_node_plugin ) if (MSVC) - set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$:Debug>) -endif (MSVC) + if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.15) + set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$:Debug>) + else () + foreach (flag_var + CMAKE_CXX_FLAGS + CMAKE_CXX_FLAGS_DEBUG + CMAKE_CXX_FLAGS_RELEASE + CMAKE_CXX_FLAGS_MINSIZEREL + CMAKE_CXX_FLAGS_RELWITHDEBINFO) + if (${flag_var} MATCHES "/MD") + string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") + endif (${flag_var} MATCHES "/MD") + endforeach (flag_var) + endif () +endif (MVC) target_include_directories(grpc_node_plugin PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} From df8c719ceb881488026a56147d5d4072c816cf25 Mon Sep 17 00:00:00 2001 From: natiz Date: Thu, 1 Dec 2022 18:30:49 +0200 Subject: [PATCH 391/450] chore: bump to 1.12.0 --- packages/grpc-tools/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-tools/package.json b/packages/grpc-tools/package.json index 1c7deb250..333ef1eb1 100644 --- a/packages/grpc-tools/package.json +++ b/packages/grpc-tools/package.json @@ -1,6 +1,6 @@ { "name": "grpc-tools", - "version": "1.11.3", + "version": "1.12.0", "author": "Google Inc.", "description": "Tools for developing with gRPC on Node.js", "homepage": "https://grpc.io/", From 161af8ca7b174e96c4703a6c83d75c43fbd05ffc Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 1 Dec 2022 15:53:10 -0500 Subject: [PATCH 392/450] grpc-js: Prepare for 1.8.0 release De-experimentalize xDS retry support, and update versions and documentation --- PACKAGE-COMPARISON.md | 2 +- packages/grpc-js-xds/README.md | 3 ++- packages/grpc-js-xds/package.json | 4 ++-- packages/grpc-js-xds/src/environment.ts | 2 +- packages/grpc-js/package.json | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/PACKAGE-COMPARISON.md b/PACKAGE-COMPARISON.md index cd6308892..e6cee8934 100644 --- a/PACKAGE-COMPARISON.md +++ b/PACKAGE-COMPARISON.md @@ -15,7 +15,7 @@ JWT Access and Service Account Credentials | provided by the [Google Auth Librar Interceptors | :heavy_check_mark: | :heavy_check_mark: Connection Keepalives | :heavy_check_mark: | :heavy_check_mark: HTTP Connect Support | :heavy_check_mark: | :heavy_check_mark: -Retries | :heavy_check_mark: | :x: +Retries | :heavy_check_mark: (without hedging) | :heavy_check_mark: (including hedging) Stats/tracing/monitoring | :heavy_check_mark: | :x: Load Balancing | :heavy_check_mark: | :heavy_check_mark: Initial Metadata Options | :heavy_check_mark: | only `waitForReady` diff --git a/packages/grpc-js-xds/README.md b/packages/grpc-js-xds/README.md index bbdd98863..793e0c0d7 100644 --- a/packages/grpc-js-xds/README.md +++ b/packages/grpc-js-xds/README.md @@ -28,4 +28,5 @@ const client = new MyServiceClient('xds:///example.com:123'); - [xDS Circuit Breaking](https://github.com/grpc/proposal/blob/master/A32-xds-circuit-breaking.md) - [xDS Client-Side Fault Injection](https://github.com/grpc/proposal/blob/master/A33-Fault-Injection.md) - [Client Status Discovery Service](https://github.com/grpc/proposal/blob/master/A40-csds-support.md) - - [Outlier Detection](https://github.com/grpc/proposal/blob/master/A50-xds-outlier-detection.md) \ No newline at end of file + - [Outlier Detection](https://github.com/grpc/proposal/blob/master/A50-xds-outlier-detection.md) + - [xDS Retry Support](https://github.com/grpc/proposal/blob/master/A44-xds-retry.md) \ No newline at end of file diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index 124c3ed7d..c0c3200f5 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.7.0", + "version": "1.8.0", "description": "Plugin for @grpc/grpc-js. Adds the xds:// URL scheme and associated features.", "main": "build/src/index.js", "scripts": { @@ -47,7 +47,7 @@ "re2-wasm": "^1.0.1" }, "peerDependencies": { - "@grpc/grpc-js": "~1.7.0" + "@grpc/grpc-js": "~1.8.0" }, "engines": { "node": ">=10.10.0" diff --git a/packages/grpc-js-xds/src/environment.ts b/packages/grpc-js-xds/src/environment.ts index 47222f8a4..7ec0fd187 100644 --- a/packages/grpc-js-xds/src/environment.ts +++ b/packages/grpc-js-xds/src/environment.ts @@ -17,4 +17,4 @@ export const EXPERIMENTAL_FAULT_INJECTION = (process.env.GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION ?? 'true') === 'true'; export const EXPERIMENTAL_OUTLIER_DETECTION = (process.env.GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION ?? 'true') === 'true'; -export const EXPERIMENTAL_RETRY = process.env.GRPC_XDS_EXPERIMENTAL_ENABLE_RETRY === 'true'; \ No newline at end of file +export const EXPERIMENTAL_RETRY = (process.env.GRPC_XDS_EXPERIMENTAL_ENABLE_RETRY ?? 'true') === 'true'; \ No newline at end of file diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index cd1c74bb5..9aa685748 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.7.3", + "version": "1.8.0", "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 f1e3f6d7d3a291ec47b93f726591ca0c46883f44 Mon Sep 17 00:00:00 2001 From: Taegeun Moon Date: Fri, 2 Dec 2022 23:57:22 +0900 Subject: [PATCH 393/450] use option method --- packages/proto-loader/README.md | 12 ++-- .../bin/proto-loader-gen-types.ts | 56 ++++++++++--------- 2 files changed, 35 insertions(+), 33 deletions(-) diff --git a/packages/proto-loader/README.md b/packages/proto-loader/README.md index f10831eeb..2a7af61e3 100644 --- a/packages/proto-loader/README.md +++ b/packages/proto-loader/README.md @@ -63,12 +63,6 @@ proto-loader-gen-types.js [options] filenames... Options: --help Show help [boolean] --version Show version number [boolean] - --inputBranded Output property for branded type for "permissive" - types with fullName of the Message as its value - [boolean] [default: false] - --outputBranded Output property for branded type for "restricted" - types with fullName of the Message as its value - [boolean] [default: false] --keepCase Preserve the case of field names [boolean] [default: false] --longs The type that should be used to output 64 bit integer @@ -98,6 +92,12 @@ Options: [string] [default: "%s"] --outputTemplate Template for mapping output or "restricted" type names [string] [default: "%s__Output"] + --inputBranded Output property for branded type for "permissive" + types with fullName of the Message as its value + [boolean] [default: false] + --outputBranded Output property for branded type for "restricted" + types with fullName of the Message as its value + [boolean] [default: false] ``` ### Example Usage diff --git a/packages/proto-loader/bin/proto-loader-gen-types.ts b/packages/proto-loader/bin/proto-loader-gen-types.ts index 5a9a32f88..f75822084 100644 --- a/packages/proto-loader/bin/proto-loader-gen-types.ts +++ b/packages/proto-loader/bin/proto-loader-gen-types.ts @@ -824,27 +824,39 @@ async function writeAllFiles(protoFiles: string[], options: GeneratorOptions) { } async function runScript() { + const boolDefaultFalseOption = { + boolean: true, + default: false, + }; const argv = yargs .parserConfiguration({ 'parse-positional-numbers': false }) - .string(['includeDirs', 'grpcLib']) - .normalize(['includeDirs', 'outDir']) - .array('includeDirs') - .boolean(['keepCase', 'defaults', 'arrays', 'objects', 'oneofs', 'json', 'verbose', 'includeComments']) - .string(['longs', 'enums', 'bytes', 'inputTemplate', 'outputTemplate']) - .default('keepCase', false) - .default('defaults', false) - .default('arrays', false) - .default('objects', false) - .default('oneofs', false) - .default('json', false) - .default('includeComments', false) - .default('longs', 'Long') - .default('enums', 'number') - .default('bytes', 'Buffer') - .default('inputTemplate', `${templateStr}`) - .default('outputTemplate', `${templateStr}__Output`) + .option('keepCase', boolDefaultFalseOption) + .option('longs', { string: true, default: 'Long' }) + .option('enums', { string: true, default: 'number' }) + .option('bytes', { string: true, default: 'Buffer' }) + .option('defaults', boolDefaultFalseOption) + .option('arrays', boolDefaultFalseOption) + .option('objects', boolDefaultFalseOption) + .option('oneofs', boolDefaultFalseOption) + .option('json', boolDefaultFalseOption) + .boolean('verbose') + .option('includeComments', boolDefaultFalseOption) + .option('includeDirs', { + normalize: true, + array: true, + alias: 'I' + }) + .option('outDir', { + alias: 'O', + normalize: true, + }) + .option('grpcLib', { string: true }) + .option('inputTemplate', { string: true, default: `${templateStr}` }) + .option('outputTemplate', { string: true, default: `${templateStr}__Output` }) + .option('inputBranded', boolDefaultFalseOption) + .option('outputBranded', boolDefaultFalseOption) .coerce('longs', value => { switch (value) { case 'String': return String; @@ -864,17 +876,7 @@ async function runScript() { default: return undefined; } }) - .option('inputBranded', { - boolean: true, - default: false, - }) - .option('outputBranded', { - boolean: true, - default: false, - }) .alias({ - includeDirs: 'I', - outDir: 'O', verbose: 'v' }).describe({ keepCase: 'Preserve the case of field names', From 488803740e69ea3594c5e60be00d780aa4fab58f Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 5 Dec 2022 10:59:50 -0500 Subject: [PATCH 394/450] grpc-tools: Force GNU format for artifact tarballs --- packages/grpc-tools/build_binaries.sh | 2 +- packages/grpc-tools/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grpc-tools/build_binaries.sh b/packages/grpc-tools/build_binaries.sh index e44881083..e25eb1f51 100755 --- a/packages/grpc-tools/build_binaries.sh +++ b/packages/grpc-tools/build_binaries.sh @@ -47,7 +47,7 @@ artifacts() { arch=$2 dir=$3 - tar -czf $out_dir/$platform-$arch.tar.gz -C $(dirname $dir) $(basename $dir) + tar --format=gnu -czf $out_dir/$platform-$arch.tar.gz -C $(dirname $dir) $(basename $dir) } case $(uname -s) in diff --git a/packages/grpc-tools/package.json b/packages/grpc-tools/package.json index 333ef1eb1..2d10b9272 100644 --- a/packages/grpc-tools/package.json +++ b/packages/grpc-tools/package.json @@ -1,6 +1,6 @@ { "name": "grpc-tools", - "version": "1.12.0", + "version": "1.12.1", "author": "Google Inc.", "description": "Tools for developing with gRPC on Node.js", "homepage": "https://grpc.io/", From 2ddd628747c676302d56db86d5ce73eb00d32777 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 5 Dec 2022 11:24:33 -0500 Subject: [PATCH 395/450] Use BSD tar-specific options on Mac --- packages/grpc-tools/build_binaries.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/grpc-tools/build_binaries.sh b/packages/grpc-tools/build_binaries.sh index e25eb1f51..c05d7da86 100755 --- a/packages/grpc-tools/build_binaries.sh +++ b/packages/grpc-tools/build_binaries.sh @@ -46,8 +46,14 @@ artifacts() { platform=$1 arch=$2 dir=$3 - - tar --format=gnu -czf $out_dir/$platform-$arch.tar.gz -C $(dirname $dir) $(basename $dir) + case $(uname -s) in + Linux) + tar -czf $out_dir/$platform-$arch.tar.gz -C $(dirname $dir) $(basename $dir) + ;; + Darwin) + tar --format=gnutar -czf $out_dir/$platform-$arch.tar.gz -C $(dirname $dir) $(basename $dir) + ;; + esac } case $(uname -s) in From 45adf24cf0a99a9d199041214b132f41c27d7045 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 5 Dec 2022 13:46:55 -0500 Subject: [PATCH 396/450] grpc-tools: Build for older Mac version --- packages/grpc-tools/CMakeLists.txt | 1 + packages/grpc-tools/package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/grpc-tools/CMakeLists.txt b/packages/grpc-tools/CMakeLists.txt index 555346912..1849ac1af 100644 --- a/packages/grpc-tools/CMakeLists.txt +++ b/packages/grpc-tools/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_minimum_required(VERSION 3.7) +set(CMAKE_OSX_DEPLOYMENT_TARGET "11.7" CACHE STRING "Minimum OS X deployment version") if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) diff --git a/packages/grpc-tools/package.json b/packages/grpc-tools/package.json index 2d10b9272..673c2cf90 100644 --- a/packages/grpc-tools/package.json +++ b/packages/grpc-tools/package.json @@ -1,6 +1,6 @@ { "name": "grpc-tools", - "version": "1.12.1", + "version": "1.12.2", "author": "Google Inc.", "description": "Tools for developing with gRPC on Node.js", "homepage": "https://grpc.io/", From 11aa7226d882095954aac0dc049f70ef0bade41c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 5 Dec 2022 15:10:42 -0500 Subject: [PATCH 397/450] grpc-tools: Build for an older Mac version (attempt 2) --- packages/grpc-tools/CMakeLists.txt | 2 +- packages/grpc-tools/build_binaries.sh | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/grpc-tools/CMakeLists.txt b/packages/grpc-tools/CMakeLists.txt index 1849ac1af..60dcdb675 100644 --- a/packages/grpc-tools/CMakeLists.txt +++ b/packages/grpc-tools/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.7) -set(CMAKE_OSX_DEPLOYMENT_TARGET "11.7" CACHE STRING "Minimum OS X deployment version") +set(CMAKE_OSX_DEPLOYMENT_TARGET "11.7" CACHE STRING "Minimum OS X deployment version" FORCE) if(COMMAND cmake_policy) cmake_policy(SET CMP0003 NEW) endif(COMMAND cmake_policy) diff --git a/packages/grpc-tools/build_binaries.sh b/packages/grpc-tools/build_binaries.sh index c05d7da86..d22bbc4ff 100755 --- a/packages/grpc-tools/build_binaries.sh +++ b/packages/grpc-tools/build_binaries.sh @@ -70,6 +70,7 @@ case $(uname -s) in mkdir $base/build/bin/$arch for bin in protoc grpc_node_plugin; do lipo -extract x86_64 $base/build/bin/$bin -o $base/build/bin/$arch/$bin + otool -l $base/build/bin/$arch/$bin | grep minos done artifacts darwin $arch $base/build/bin/$arch/ done From b735abf544bf22afc69f1761b4f06c6a97da3b57 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 5 Dec 2022 15:44:24 -0500 Subject: [PATCH 398/450] grpc-tools: Bump to version 1.12.3 --- packages/grpc-tools/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-tools/package.json b/packages/grpc-tools/package.json index 673c2cf90..d4ac74ea1 100644 --- a/packages/grpc-tools/package.json +++ b/packages/grpc-tools/package.json @@ -1,6 +1,6 @@ { "name": "grpc-tools", - "version": "1.12.2", + "version": "1.12.3", "author": "Google Inc.", "description": "Tools for developing with gRPC on Node.js", "homepage": "https://grpc.io/", From 677c0093855b9234c501ba510bfbc83bafa3320c Mon Sep 17 00:00:00 2001 From: Nick Kleinschmidt Date: Sat, 17 Dec 2022 15:19:32 -0700 Subject: [PATCH 399/450] grpc-js: Add support for grpc.service_config_disable_resolution --- packages/grpc-js/README.md | 1 + packages/grpc-js/src/channel-options.ts | 2 + packages/grpc-js/src/resolver-dns.ts | 7 ++- packages/grpc-js/test/test-resolver.ts | 58 +++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/README.md b/packages/grpc-js/README.md index 3d698dfd8..652ce5fef 100644 --- a/packages/grpc-js/README.md +++ b/packages/grpc-js/README.md @@ -62,6 +62,7 @@ Many channel arguments supported in `grpc` are not supported in `@grpc/grpc-js`. - `grpc.enable_retries` - `grpc.per_rpc_retry_buffer_size` - `grpc.retry_buffer_size` + - `grpc.service_config_disable_resolution` - `grpc-node.max_session_memory` - `channelOverride` - `channelFactoryOverride` diff --git a/packages/grpc-js/src/channel-options.ts b/packages/grpc-js/src/channel-options.ts index 8830ed43d..a41b89e9b 100644 --- a/packages/grpc-js/src/channel-options.ts +++ b/packages/grpc-js/src/channel-options.ts @@ -55,6 +55,7 @@ export interface ChannelOptions { 'grpc.max_connection_age_ms'?: number; 'grpc.max_connection_age_grace_ms'?: number; 'grpc-node.max_session_memory'?: number; + 'grpc.service_config_disable_resolution'?: number; // eslint-disable-next-line @typescript-eslint/no-explicit-any [key: string]: any; } @@ -87,6 +88,7 @@ export const recognizedOptions = { 'grpc.max_connection_age_ms': true, 'grpc.max_connection_age_grace_ms': true, 'grpc-node.max_session_memory': true, + 'grpc.service_config_disable_resolution': true, }; export function channelOptionsEqual( diff --git a/packages/grpc-js/src/resolver-dns.ts b/packages/grpc-js/src/resolver-dns.ts index 4b7cb2fec..355ce2dfd 100644 --- a/packages/grpc-js/src/resolver-dns.ts +++ b/packages/grpc-js/src/resolver-dns.ts @@ -98,6 +98,7 @@ class DnsResolver implements Resolver { private continueResolving = false; private nextResolutionTimer: NodeJS.Timer; private isNextResolutionTimerRunning = false; + private isServiceConfigEnabled = true; constructor( private target: GrpcUri, private listener: ResolverListener, @@ -127,6 +128,10 @@ class DnsResolver implements Resolver { } this.percentage = Math.random() * 100; + if (channelOptions['grpc.service_config_disable_resolution'] === 1) { + this.isServiceConfigEnabled = false; + } + this.defaultResolutionError = { code: Status.UNAVAILABLE, details: `Name resolution failed for target ${uriToString(this.target)}`, @@ -255,7 +260,7 @@ class DnsResolver implements Resolver { ); /* If there already is a still-pending TXT resolution, we can just use * that result when it comes in */ - if (this.pendingTxtPromise === null) { + if (this.isServiceConfigEnabled && this.pendingTxtPromise === null) { /* We handle the TXT query promise differently than the others because * the name resolution attempt as a whole is a success even if the TXT * lookup fails */ diff --git a/packages/grpc-js/test/test-resolver.ts b/packages/grpc-js/test/test-resolver.ts index a3e6793f1..1d458125b 100644 --- a/packages/grpc-js/test/test-resolver.ts +++ b/packages/grpc-js/test/test-resolver.ts @@ -207,6 +207,64 @@ describe('Name Resolver', () => { const resolver = resolverManager.createResolver(target, listener, {}); resolver.updateResolution(); }); + // Created DNS TXT record using TXT sample from https://github.com/grpc/proposal/blob/master/A2-service-configs-in-dns.md + // "grpc_config=[{\"serviceConfig\":{\"loadBalancingPolicy\":\"round_robin\",\"methodConfig\":[{\"name\":[{\"service\":\"MyService\",\"method\":\"Foo\"}],\"waitForReady\":true}]}}]" + it.skip('Should resolve a name with TXT service config', done => { + const target = resolverManager.mapUriDefaultScheme(parseUri('grpctest.kleinsch.com')!)!; + const listener: resolverManager.ResolverListener = { + onSuccessfulResolution: ( + addressList: SubchannelAddress[], + serviceConfig: ServiceConfig | null, + serviceConfigError: StatusObject | null + ) => { + if (serviceConfig !== null) { + assert( + serviceConfig.loadBalancingPolicy === 'round_robin', + 'Should have found round robin LB policy' + ); + done(); + } + }, + onError: (error: StatusObject) => { + done(new Error(`Failed with status ${error.details}`)); + }, + }; + const resolver = resolverManager.createResolver(target, listener, {}); + resolver.updateResolution(); + }); + it.skip( + 'Should not resolve TXT service config if we disabled service config', + (done) => { + const target = resolverManager.mapUriDefaultScheme( + parseUri('grpctest.kleinsch.com')! + )!; + let count = 0; + const listener: resolverManager.ResolverListener = { + onSuccessfulResolution: ( + addressList: SubchannelAddress[], + serviceConfig: ServiceConfig | null, + serviceConfigError: StatusObject | null + ) => { + assert( + serviceConfig === null, + 'Should not have found service config' + ); + count++; + }, + onError: (error: StatusObject) => { + done(new Error(`Failed with status ${error.details}`)); + }, + }; + const resolver = resolverManager.createResolver(target, listener, { + 'grpc.service_config_disable_resolution': 1, + }); + resolver.updateResolution(); + setTimeout(() => { + assert(count === 1, 'Should have only resolved once'); + done(); + }, 2_000); + } + ); /* The DNS entry for loopback4.unittest.grpc.io only has a single A record * with the address 127.0.0.1, but the Mac DNS resolver appears to use * NAT64 to create an IPv6 address in that case, so it instead returns From a1b9464de8c63831a6053525039f3077f618ac6f Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 3 Jan 2023 09:35:43 -0800 Subject: [PATCH 400/450] grpc-js: Add HTTP status and content type headers to trailers-only responses --- packages/grpc-js/src/server-call.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index 631ec7675..8dcf6be33 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -63,11 +63,13 @@ const deadlineUnitsToMs: DeadlineUnitIndexSignature = { u: 0.001, n: 0.000001, }; -const defaultResponseHeaders = { +const defaultCompressionHeaders = { // TODO(cjihrig): Remove these encoding headers from the default response // once compression is integrated. [GRPC_ACCEPT_ENCODING_HEADER]: 'identity,deflate,gzip', [GRPC_ENCODING_HEADER]: 'identity', +} +const defaultResponseHeaders = { [http2.constants.HTTP2_HEADER_STATUS]: http2.constants.HTTP_STATUS_OK, [http2.constants.HTTP2_HEADER_CONTENT_TYPE]: 'application/grpc+proto', }; @@ -500,7 +502,7 @@ export class Http2ServerCallStream< this.metadataSent = true; const custom = customMetadata ? customMetadata.toHttp2Headers() : null; // TODO(cjihrig): Include compression headers. - const headers = { ...defaultResponseHeaders, ...custom }; + const headers = { ...defaultResponseHeaders, ...defaultCompressionHeaders, ...custom }; this.stream.respond(headers, defaultResponseOptions); } @@ -725,9 +727,11 @@ export class Http2ServerCallStream< this.stream.end(); } } else { + // Trailers-only response const trailersToSend = { [GRPC_STATUS_HEADER]: statusObj.code, [GRPC_MESSAGE_HEADER]: encodeURI(statusObj.details), + ...defaultResponseHeaders, ...statusObj.metadata?.toHttp2Headers(), }; this.stream.respond(trailersToSend, {endStream: true}); From c62d41623b361d793586d930f47b5e44829e29f2 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 3 Jan 2023 09:53:00 -0800 Subject: [PATCH 401/450] grpc-js: Discard buffer tracker entry when RetryingCall ends --- packages/grpc-js/src/retrying-call.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/grpc-js/src/retrying-call.ts b/packages/grpc-js/src/retrying-call.ts index f9bda9eb5..8daf5ba70 100644 --- a/packages/grpc-js/src/retrying-call.ts +++ b/packages/grpc-js/src/retrying-call.ts @@ -202,6 +202,15 @@ export class RetryingCall implements Call { private reportStatus(statusObject: StatusObject) { this.trace('ended with status: code=' + statusObject.code + ' details="' + statusObject.details + '"'); + this.bufferTracker.freeAll(this.callNumber); + for (let i = 0; i < this.writeBuffer.length; i++) { + if (this.writeBuffer[i].entryType === 'MESSAGE') { + this.writeBuffer[i] = { + entryType: 'FREED', + allocated: false + }; + } + } process.nextTick(() => { this.listener?.onReceiveStatus(statusObject); }); From 5006c14d729bc65e558bfdbd4864467b7a1f7473 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 3 Jan 2023 13:43:55 -0800 Subject: [PATCH 402/450] grpc-js: Bump to version 1.8.1 --- 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 9aa685748..06707c2c4 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.8.0", + "version": "1.8.1", "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 df8b8976dcb1d2fb17f826f7ceb930eb83c6885a Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 7 Dec 2022 10:19:07 -0500 Subject: [PATCH 403/450] grpc-js: Refactor Transport and SubchannelConnector out of Subchannel --- packages/grpc-js/src/subchannel-call.ts | 30 +- packages/grpc-js/src/subchannel-pool.ts | 4 +- packages/grpc-js/src/subchannel.ts | 693 ++---------------------- packages/grpc-js/src/transport.ts | 634 ++++++++++++++++++++++ 4 files changed, 714 insertions(+), 647 deletions(-) create mode 100644 packages/grpc-js/src/transport.ts diff --git a/packages/grpc-js/src/subchannel-call.ts b/packages/grpc-js/src/subchannel-call.ts index 2bc6fb0c7..6556bc460 100644 --- a/packages/grpc-js/src/subchannel-call.ts +++ b/packages/grpc-js/src/subchannel-call.ts @@ -21,12 +21,12 @@ import * as os from 'os'; import { Status } from './constants'; import { Metadata } from './metadata'; import { StreamDecoder } from './stream-decoder'; -import { SubchannelCallStatsTracker, Subchannel } from './subchannel'; import * as logging from './logging'; import { LogVerbosity } from './constants'; import { ServerSurfaceCall } from './server-call'; import { Deadline } from './deadline'; import { InterceptingListener, MessageContext, StatusObject, WriteCallback } from './call-interface'; +import { CallEventTracker } from './transport'; const TRACER_NAME = 'subchannel_call'; @@ -110,9 +110,9 @@ export class Http2SubchannelCall implements SubchannelCall { constructor( private readonly http2Stream: http2.ClientHttp2Stream, - private readonly callStatsTracker: SubchannelCallStatsTracker, + private readonly callEventTracker: CallEventTracker, private readonly listener: SubchannelCallInterceptingListener, - private readonly subchannel: Subchannel, + private readonly peerName: string, private readonly callId: number ) { this.disconnectListener = () => { @@ -122,8 +122,6 @@ export class Http2SubchannelCall implements SubchannelCall { metadata: new Metadata(), }); }; - subchannel.addDisconnectListener(this.disconnectListener); - subchannel.callRef(); http2Stream.on('response', (headers, flags) => { let headersString = ''; for (const header of Object.keys(headers)) { @@ -185,7 +183,7 @@ export class Http2SubchannelCall implements SubchannelCall { for (const message of messages) { this.trace('parsed message of length ' + message.length); - this.callStatsTracker!.addMessageReceived(); + this.callEventTracker!.addMessageReceived(); this.tryPush(message); } }); @@ -289,7 +287,15 @@ export class Http2SubchannelCall implements SubchannelCall { ); this.internalError = err; } - this.callStatsTracker.onStreamEnd(false); + this.callEventTracker.onStreamEnd(false); + }); + } + + public onDisconnect() { + this.endCall({ + code: Status.UNAVAILABLE, + details: 'Connection dropped', + metadata: new Metadata(), }); } @@ -304,7 +310,7 @@ export class Http2SubchannelCall implements SubchannelCall { this.finalStatus!.details + '"' ); - this.callStatsTracker.onCallEnd(this.finalStatus!); + this.callEventTracker.onCallEnd(this.finalStatus!); /* We delay the actual action of bubbling up the status to insulate the * cleanup code in this class from any errors that may be thrown in the * upper layers as a result of bubbling up the status. In particular, @@ -319,8 +325,6 @@ export class Http2SubchannelCall implements SubchannelCall { * not push more messages after the status is output, so the messages go * nowhere either way. */ this.http2Stream.resume(); - this.subchannel.callUnref(); - this.subchannel.removeDisconnectListener(this.disconnectListener); } } @@ -395,7 +399,7 @@ export class Http2SubchannelCall implements SubchannelCall { } private handleTrailers(headers: http2.IncomingHttpHeaders) { - this.callStatsTracker.onStreamEnd(true); + this.callEventTracker.onStreamEnd(true); let headersString = ''; for (const header of Object.keys(headers)) { headersString += '\t\t' + header + ': ' + headers[header] + '\n'; @@ -467,7 +471,7 @@ export class Http2SubchannelCall implements SubchannelCall { } getPeer(): string { - return this.subchannel.getAddress(); + return this.peerName; } getCallNumber(): number { @@ -506,7 +510,7 @@ export class Http2SubchannelCall implements SubchannelCall { context.callback?.(); }; this.trace('sending data chunk of length ' + message.length); - this.callStatsTracker.addMessageSent(); + this.callEventTracker.addMessageSent(); try { this.http2Stream!.write(message, cb); } catch (error) { diff --git a/packages/grpc-js/src/subchannel-pool.ts b/packages/grpc-js/src/subchannel-pool.ts index b7ef362c3..bbfbea02b 100644 --- a/packages/grpc-js/src/subchannel-pool.ts +++ b/packages/grpc-js/src/subchannel-pool.ts @@ -23,6 +23,7 @@ import { } from './subchannel-address'; import { ChannelCredentials } from './channel-credentials'; import { GrpcUri, uriToString } from './uri-parser'; +import { Http2SubchannelConnector } from './transport'; // 10 seconds in milliseconds. This value is arbitrary. /** @@ -143,7 +144,8 @@ export class SubchannelPool { channelTargetUri, subchannelTarget, channelArguments, - channelCredentials + channelCredentials, + new Http2SubchannelConnector(channelTargetUri) ); if (!(channelTarget in this.pool)) { this.pool[channelTarget] = []; diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index 0d9773b30..b4876f178 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -15,60 +15,30 @@ * */ -import * as http2 from 'http2'; import { ChannelCredentials } from './channel-credentials'; import { Metadata } from './metadata'; import { ChannelOptions } from './channel-options'; -import { PeerCertificate, checkServerIdentity, TLSSocket, CipherNameAndProtocol } from 'tls'; import { ConnectivityState } from './connectivity-state'; import { BackoffTimeout, BackoffOptions } from './backoff-timeout'; -import { getDefaultAuthority } from './resolver'; import * as logging from './logging'; import { LogVerbosity, Status } from './constants'; -import { getProxiedConnection, ProxyConnectionResult } from './http_proxy'; -import * as net from 'net'; -import { GrpcUri, parseUri, splitHostPort, uriToString } from './uri-parser'; -import { ConnectionOptions } from 'tls'; +import { GrpcUri, uriToString } from './uri-parser'; import { - stringToSubchannelAddress, SubchannelAddress, subchannelAddressToString, } from './subchannel-address'; -import { SubchannelRef, ChannelzTrace, ChannelzChildrenTracker, SubchannelInfo, registerChannelzSubchannel, ChannelzCallTracker, SocketInfo, SocketRef, unregisterChannelzRef, registerChannelzSocket, TlsInfo } from './channelz'; +import { SubchannelRef, ChannelzTrace, ChannelzChildrenTracker, SubchannelInfo, registerChannelzSubchannel, ChannelzCallTracker, unregisterChannelzRef } from './channelz'; import { ConnectivityStateListener } from './subchannel-interface'; -import { Http2SubchannelCall, SubchannelCallInterceptingListener } from './subchannel-call'; -import { getNextCallNumber } from './call-number'; +import { SubchannelCallInterceptingListener } from './subchannel-call'; import { SubchannelCall } from './subchannel-call'; -import { InterceptingListener, StatusObject } from './call-interface'; - -const clientVersion = require('../../package.json').version; +import { CallEventTracker, SubchannelConnector, Transport } from './transport'; const TRACER_NAME = 'subchannel'; -const FLOW_CONTROL_TRACER_NAME = 'subchannel_flowctrl'; /* setInterval and setTimeout only accept signed 32 bit integers. JS doesn't * have a constant for the max signed 32 bit integer, so this is a simple way * to calculate it */ const KEEPALIVE_MAX_TIME_MS = ~(1 << 31); -const KEEPALIVE_TIMEOUT_MS = 20000; - -export interface SubchannelCallStatsTracker { - addMessageSent(): void; - addMessageReceived(): void; - onCallEnd(status: StatusObject): void; - onStreamEnd(success: boolean): void; -} - -const { - HTTP2_HEADER_AUTHORITY, - HTTP2_HEADER_CONTENT_TYPE, - HTTP2_HEADER_METHOD, - HTTP2_HEADER_PATH, - HTTP2_HEADER_TE, - HTTP2_HEADER_USER_AGENT, -} = http2.constants; - -const tooManyPingsData: Buffer = Buffer.from('too_many_pings', 'ascii'); export class Subchannel { /** @@ -79,7 +49,7 @@ export class Subchannel { /** * The underlying http2 session used to make requests. */ - private session: http2.ClientHttp2Session | null = null; + private transport: Transport | null = null; /** * Indicates that the subchannel should transition from TRANSIENT_FAILURE to * CONNECTING instead of IDLE when the backoff timeout ends. @@ -92,45 +62,9 @@ export class Subchannel { */ private stateListeners: ConnectivityStateListener[] = []; - /** - * A list of listener functions that will be called when the underlying - * socket disconnects. Used for ending active calls with an UNAVAILABLE - * status. - */ - private disconnectListeners: Set<() => void> = new Set(); - private backoffTimeout: BackoffTimeout; - /** - * The complete user agent string constructed using channel args. - */ - private userAgent: string; - - /** - * The amount of time in between sending pings - */ - private keepaliveTimeMs: number = KEEPALIVE_MAX_TIME_MS; - /** - * The amount of time to wait for an acknowledgement after sending a ping - */ - private keepaliveTimeoutMs: number = KEEPALIVE_TIMEOUT_MS; - /** - * Timer reference for timeout that indicates when to send the next ping - */ - private keepaliveIntervalId: NodeJS.Timer; - /** - * Timer reference tracking when the most recent ping will be considered lost - */ - private keepaliveTimeoutId: NodeJS.Timer; - /** - * Indicates whether keepalive pings should be sent without any active calls - */ - private keepaliveWithoutCalls = false; - - /** - * Tracks calls with references to this subchannel - */ - private callRefcount = 0; + private keepaliveTimeMultiplier = 1; /** * Tracks channels and subchannel pools with references to this subchannel */ @@ -149,18 +83,7 @@ export class Subchannel { private childrenTracker = new ChannelzChildrenTracker(); // Channelz socket info - private channelzSocketRef: SocketRef | null = null; - /** - * Name of the remote server, if it is not the same as the subchannel - * address, i.e. if connecting through an HTTP CONNECT proxy. - */ - private remoteName: string | null = null; private streamTracker = new ChannelzCallTracker(); - private keepalivesSent = 0; - private messagesSent = 0; - private messagesReceived = 0; - private lastMessageSentTimestamp: Date | null = null; - private lastMessageReceivedTimestamp: Date | null = null; /** * A class representing a connection to a single backend. @@ -176,33 +99,9 @@ export class Subchannel { private channelTarget: GrpcUri, private subchannelAddress: SubchannelAddress, private options: ChannelOptions, - private credentials: ChannelCredentials + private credentials: ChannelCredentials, + private connector: SubchannelConnector ) { - // Build user-agent string. - this.userAgent = [ - options['grpc.primary_user_agent'], - `grpc-node-js/${clientVersion}`, - options['grpc.secondary_user_agent'], - ] - .filter((e) => e) - .join(' '); // remove falsey values first - - if ('grpc.keepalive_time_ms' in options) { - this.keepaliveTimeMs = options['grpc.keepalive_time_ms']!; - } - if ('grpc.keepalive_timeout_ms' in options) { - this.keepaliveTimeoutMs = options['grpc.keepalive_timeout_ms']!; - } - if ('grpc.keepalive_permit_without_calls' in options) { - this.keepaliveWithoutCalls = - options['grpc.keepalive_permit_without_calls'] === 1; - } else { - this.keepaliveWithoutCalls = false; - } - this.keepaliveIntervalId = setTimeout(() => {}, 0); - clearTimeout(this.keepaliveIntervalId); - this.keepaliveTimeoutId = setTimeout(() => {}, 0); - clearTimeout(this.keepaliveTimeoutId); const backoffOptions: BackoffOptions = { initialDelay: options['grpc.initial_reconnect_backoff_ms'], maxDelay: options['grpc.max_reconnect_backoff_ms'], @@ -233,67 +132,6 @@ export class Subchannel { }; } - private getChannelzSocketInfo(): SocketInfo | null { - if (this.session === null) { - return null; - } - const sessionSocket = this.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 (this.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: this.remoteName, - streamsStarted: this.streamTracker.callsStarted, - streamsSucceeded: this.streamTracker.callsSucceeded, - streamsFailed: this.streamTracker.callsFailed, - messagesSent: this.messagesSent, - messagesReceived: this.messagesReceived, - keepAlivesSent: this.keepalivesSent, - lastLocalStreamCreatedTimestamp: this.streamTracker.lastCallStartedTimestamp, - lastRemoteStreamCreatedTimestamp: null, - lastMessageSentTimestamp: this.lastMessageSentTimestamp, - lastMessageReceivedTimestamp: this.lastMessageReceivedTimestamp, - localFlowControlWindow: this.session.state.localWindowSize ?? null, - remoteFlowControlWindow: this.session.state.remoteWindowSize ?? null - }; - return socketInfo; - } - - private resetChannelzSocketInfo() { - if (!this.channelzEnabled) { - return; - } - if (this.channelzSocketRef) { - unregisterChannelzRef(this.channelzSocketRef); - this.childrenTracker.unrefChild(this.channelzSocketRef); - this.channelzSocketRef = null; - } - this.remoteName = null; - this.streamTracker = new ChannelzCallTracker(); - this.keepalivesSent = 0; - this.messagesSent = 0; - this.messagesReceived = 0; - this.lastMessageSentTimestamp = null; - this.lastMessageReceivedTimestamp = null; - } - private trace(text: string): void { logging.trace(LogVerbosity.DEBUG, TRACER_NAME, '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' ' + text); } @@ -302,18 +140,6 @@ export class Subchannel { logging.trace(LogVerbosity.DEBUG, 'subchannel_refcount', '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' ' + text); } - private flowControlTrace(text: string): void { - logging.trace(LogVerbosity.DEBUG, FLOW_CONTROL_TRACER_NAME, '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' ' + text); - } - - private internalsTrace(text: string): void { - logging.trace(LogVerbosity.DEBUG, 'subchannel_internals', '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' ' + text); - } - - private keepaliveTrace(text: string): void { - logging.trace(LogVerbosity.DEBUG, 'keepalive', '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' ' + text); - } - private handleBackoffTimer() { if (this.continueConnecting) { this.transitionToState( @@ -340,313 +166,39 @@ export class Subchannel { this.backoffTimeout.reset(); } - private sendPing() { - if (this.channelzEnabled) { - this.keepalivesSent += 1; - } - this.keepaliveTrace('Sending ping with timeout ' + this.keepaliveTimeoutMs + 'ms'); - 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) => { - this.keepaliveTrace('Received ping response'); - clearTimeout(this.keepaliveTimeoutId); - } - ); - } catch (e) { - /* If we fail to send a ping, the connection is no longer functional, so - * we should discard it. */ - this.transitionToState( - [ConnectivityState.READY], - ConnectivityState.TRANSIENT_FAILURE - ); - } - } - - private startKeepalivePings() { - this.keepaliveIntervalId = setInterval(() => { - this.sendPing(); - }, this.keepaliveTimeMs); - this.keepaliveIntervalId.unref?.(); - /* Don't send a ping immediately because whatever caused us to start - * sending pings should also involve some network activity. */ - } - - /** - * Stop keepalive pings when terminating a connection. This discards the - * outstanding ping timeout, so it should not be called if the same - * connection will still be used. - */ - private stopKeepalivePings() { - clearInterval(this.keepaliveIntervalId); - clearTimeout(this.keepaliveTimeoutId); - } - - private createSession(proxyConnectionResult: ProxyConnectionResult) { - if (proxyConnectionResult.realTarget) { - this.remoteName = uriToString(proxyConnectionResult.realTarget); - this.trace('creating HTTP/2 session through proxy to ' + proxyConnectionResult.realTarget); - } else { - this.remoteName = null; - this.trace('creating HTTP/2 session'); - } - const targetAuthority = getDefaultAuthority( - proxyConnectionResult.realTarget ?? this.channelTarget - ); - let connectionOptions: http2.SecureClientSessionOptions = - this.credentials._getConnectionOptions() || {}; - connectionOptions.maxSendHeaderBlockLength = Number.MAX_SAFE_INTEGER; - if ('grpc-node.max_session_memory' in this.options) { - connectionOptions.maxSessionMemory = this.options[ - 'grpc-node.max_session_memory' - ]; - } else { - /* By default, set a very large max session memory limit, to effectively - * disable enforcement of the limit. Some testing indicates that Node's - * behavior degrades badly when this limit is reached, so we solve that - * by disabling the check entirely. */ - connectionOptions.maxSessionMemory = Number.MAX_SAFE_INTEGER; - } - let addressScheme = 'http://'; - if ('secureContext' in connectionOptions) { - addressScheme = 'https://'; - // If provided, the value of grpc.ssl_target_name_override should be used - // to override the target hostname when checking server identity. - // This option is used for testing only. - if (this.options['grpc.ssl_target_name_override']) { - const sslTargetNameOverride = this.options[ - 'grpc.ssl_target_name_override' - ]!; - connectionOptions.checkServerIdentity = ( - host: string, - cert: PeerCertificate - ): Error | undefined => { - return checkServerIdentity(sslTargetNameOverride, cert); - }; - connectionOptions.servername = sslTargetNameOverride; - } else { - const authorityHostname = - splitHostPort(targetAuthority)?.host ?? 'localhost'; - // We want to always set servername to support SNI - connectionOptions.servername = authorityHostname; - } - if (proxyConnectionResult.socket) { - /* This is part of the workaround for - * https://github.com/nodejs/node/issues/32922. Without that bug, - * proxyConnectionResult.socket would always be a plaintext socket and - * this would say - * connectionOptions.socket = proxyConnectionResult.socket; */ - connectionOptions.createConnection = (authority, option) => { - return proxyConnectionResult.socket!; - }; - } - } else { - /* In all but the most recent versions of Node, http2.connect does not use - * the options when establishing plaintext connections, so we need to - * establish that connection explicitly. */ - connectionOptions.createConnection = (authority, option) => { - if (proxyConnectionResult.socket) { - return proxyConnectionResult.socket; - } else { - /* net.NetConnectOpts is declared in a way that is more restrictive - * than what net.connect will actually accept, so we use the type - * assertion to work around that. */ - return net.connect(this.subchannelAddress); - } - }; - } - - connectionOptions = { - ...connectionOptions, - ...this.subchannelAddress, - }; - - /* http2.connect uses the options here: - * https://github.com/nodejs/node/blob/70c32a6d190e2b5d7b9ff9d5b6a459d14e8b7d59/lib/internal/http2/core.js#L3028-L3036 - * The spread operator overides earlier values with later ones, so any port - * or host values in the options will be used rather than any values extracted - * from the first argument. In addition, the path overrides the host and port, - * as documented for plaintext connections here: - * https://nodejs.org/api/net.html#net_socket_connect_options_connectlistener - * and for TLS connections here: - * https://nodejs.org/api/tls.html#tls_tls_connect_options_callback. In - * earlier versions of Node, http2.connect passes these options to - * tls.connect but not net.connect, so in the insecure case we still need - * to set the createConnection option above to create the connection - * explicitly. We cannot do that in the TLS case because http2.connect - * passes necessary additional options to tls.connect. - * The first argument just needs to be parseable as a URL and the scheme - * determines whether the connection will be established over TLS or not. - */ - const session = http2.connect( - addressScheme + targetAuthority, - connectionOptions - ); - this.session = session; - this.channelzSocketRef = registerChannelzSocket(this.subchannelAddressString, () => this.getChannelzSocketInfo()!, this.channelzEnabled); - if (this.channelzEnabled) { - this.childrenTracker.refChild(this.channelzSocketRef); + private startConnectingInternal() { + let options = this.options; + if (options['grpc.keepalive_time_ms']) { + const adjustedKeepaliveTime = Math.min(options['grpc.keepalive_time_ms'] * this.keepaliveTimeMultiplier, KEEPALIVE_MAX_TIME_MS); + options = {...options, 'grpc.keepalive_time_ms': adjustedKeepaliveTime}; } - session.unref(); - /* For all of these events, check if the session at the time of the event - * is the same one currently attached to this subchannel, to ensure that - * old events from previous connection attempts cannot cause invalid state - * transitions. */ - session.once('connect', () => { - if (this.session === session) { - this.transitionToState( - [ConnectivityState.CONNECTING], - ConnectivityState.READY - ); - } - }); - session.once('close', () => { - if (this.session === session) { - this.trace('connection closed'); - this.transitionToState( - [ConnectivityState.CONNECTING], - ConnectivityState.TRANSIENT_FAILURE - ); - /* Transitioning directly to IDLE here should be OK because we are not - * doing any backoff, because a connection was established at some - * point */ - this.transitionToState( - [ConnectivityState.READY], - ConnectivityState.IDLE - ); - } - }); - session.once( - 'goaway', - (errorCode: number, lastStreamID: number, opaqueData: Buffer) => { - if (this.session === session) { - /* See the last paragraph of - * https://github.com/grpc/proposal/blob/master/A8-client-side-keepalive.md#basic-keepalive */ - if ( - errorCode === http2.constants.NGHTTP2_ENHANCE_YOUR_CALM && - opaqueData.equals(tooManyPingsData) - ) { - this.keepaliveTimeMs = Math.min( - 2 * this.keepaliveTimeMs, - KEEPALIVE_MAX_TIME_MS - ); - logging.log( - LogVerbosity.ERROR, - `Connection to ${uriToString(this.channelTarget)} at ${ - this.subchannelAddressString - } rejected by server because of excess pings. Increasing ping interval to ${ - this.keepaliveTimeMs - } ms` - ); + this.connector.connect(this.subchannelAddress, this.credentials, options).then( + transport => { + if (this.transitionToState([ConnectivityState.CONNECTING], ConnectivityState.READY)) { + this.transport = transport; + if (this.channelzEnabled) { + this.childrenTracker.refChild(transport.getChannelzRef()); } - this.trace( - 'connection closed by GOAWAY with code ' + - errorCode - ); - this.transitionToState( - [ConnectivityState.CONNECTING, ConnectivityState.READY], - ConnectivityState.IDLE - ); - } - } - ); - 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( - 'new settings received' + - (this.session !== session ? ' on the old connection' : '') + - ': ' + - JSON.stringify(settings) - ); - }); - session.on('localSettings', (settings: http2.Settings) => { - this.trace( - 'local settings acknowledged by remote' + - (this.session !== session ? ' on the old connection' : '') + - ': ' + - JSON.stringify(settings) - ); - }); - } - } - - private startConnectingInternal() { - /* Pass connection options through to the proxy so that it's able to - * upgrade it's connection to support tls if needed. - * This is a workaround for https://github.com/nodejs/node/issues/32922 - * See https://github.com/grpc/grpc-node/pull/1369 for more info. */ - const connectionOptions: ConnectionOptions = - this.credentials._getConnectionOptions() || {}; - - if ('secureContext' in connectionOptions) { - connectionOptions.ALPNProtocols = ['h2']; - // If provided, the value of grpc.ssl_target_name_override should be used - // to override the target hostname when checking server identity. - // This option is used for testing only. - if (this.options['grpc.ssl_target_name_override']) { - const sslTargetNameOverride = this.options[ - 'grpc.ssl_target_name_override' - ]!; - connectionOptions.checkServerIdentity = ( - host: string, - cert: PeerCertificate - ): Error | undefined => { - return checkServerIdentity(sslTargetNameOverride, cert); - }; - connectionOptions.servername = sslTargetNameOverride; - } else { - if ('grpc.http_connect_target' in this.options) { - /* This is more or less how servername will be set in createSession - * if a connection is successfully established through the proxy. - * If the proxy is not used, these connectionOptions are discarded - * anyway */ - const targetPath = getDefaultAuthority( - parseUri(this.options['grpc.http_connect_target'] as string) ?? { - path: 'localhost', + transport.addDisconnectListener((tooManyPings) => { + this.transitionToState([ConnectivityState.READY], ConnectivityState.IDLE); + if (tooManyPings) { + this.keepaliveTimeMultiplier *= 2; + logging.log( + LogVerbosity.ERROR, + `Connection to ${uriToString(this.channelTarget)} at ${ + this.subchannelAddressString + } rejected by server because of excess pings. Increasing ping interval multiplier to ${ + this.keepaliveTimeMultiplier + } ms` + ); } - ); - const hostPort = splitHostPort(targetPath); - connectionOptions.servername = hostPort?.host ?? targetPath; + }); } - } - } - - getProxiedConnection( - this.subchannelAddress, - this.options, - connectionOptions - ).then( - (result) => { - this.createSession(result); }, - (reason) => { - this.transitionToState( - [ConnectivityState.CONNECTING], - ConnectivityState.TRANSIENT_FAILURE - ); + error => { + this.transitionToState([ConnectivityState.CONNECTING], ConnectivityState.TRANSIENT_FAILURE); } - ); - } - - private handleDisconnect() { - this.transitionToState( - [ConnectivityState.READY], - ConnectivityState.TRANSIENT_FAILURE); - for (const listener of this.disconnectListeners.values()) { - listener(); - } + ) } /** @@ -676,15 +228,6 @@ export class Subchannel { switch (newState) { case ConnectivityState.READY: this.stopBackoff(); - const session = this.session!; - session.socket.once('close', () => { - if (this.session === session) { - this.handleDisconnect(); - } - }); - if (this.keepaliveWithoutCalls) { - this.startKeepalivePings(); - } break; case ConnectivityState.CONNECTING: this.startBackoff(); @@ -692,12 +235,11 @@ export class Subchannel { this.continueConnecting = false; break; case ConnectivityState.TRANSIENT_FAILURE: - if (this.session) { - this.session.close(); + if (this.channelzEnabled && this.transport) { + this.childrenTracker.unrefChild(this.transport.getChannelzRef()); } - this.session = null; - this.resetChannelzSocketInfo(); - this.stopKeepalivePings(); + this.transport?.shutdown(); + this.transport = null; /* If the backoff timer has already ended by the time we get to the * TRANSIENT_FAILURE state, we want to immediately transition out of * TRANSIENT_FAILURE as though the backoff timer is ending right now */ @@ -708,12 +250,11 @@ export class Subchannel { } break; case ConnectivityState.IDLE: - if (this.session) { - this.session.close(); + if (this.channelzEnabled && this.transport) { + this.childrenTracker.unrefChild(this.transport.getChannelzRef()); } - this.session = null; - this.resetChannelzSocketInfo(); - this.stopKeepalivePings(); + this.transport?.shutdown(); + this.transport = null; break; default: throw new Error(`Invalid state: unknown ConnectivityState ${newState}`); @@ -726,66 +267,6 @@ export class Subchannel { return true; } - /** - * Check if the subchannel associated with zero calls and with zero channels. - * If so, shut it down. - */ - private checkBothRefcounts() { - /* If no calls, channels, or subchannel pools have any more references to - * this subchannel, we can be sure it will never be used again. */ - if (this.callRefcount === 0 && this.refcount === 0) { - if (this.channelzEnabled) { - this.channelzTrace.addTrace('CT_INFO', 'Shutting down'); - } - this.transitionToState( - [ConnectivityState.CONNECTING, ConnectivityState.READY], - ConnectivityState.IDLE - ); - if (this.channelzEnabled) { - unregisterChannelzRef(this.channelzRef); - } - } - } - - callRef() { - this.refTrace( - 'callRefcount ' + - this.callRefcount + - ' -> ' + - (this.callRefcount + 1) - ); - if (this.callRefcount === 0) { - if (this.session) { - this.session.ref(); - } - this.backoffTimeout.ref(); - if (!this.keepaliveWithoutCalls) { - this.startKeepalivePings(); - } - } - this.callRefcount += 1; - } - - callUnref() { - this.refTrace( - 'callRefcount ' + - this.callRefcount + - ' -> ' + - (this.callRefcount - 1) - ); - this.callRefcount -= 1; - if (this.callRefcount === 0) { - if (this.session) { - this.session.unref(); - } - this.backoffTimeout.unref(); - if (!this.keepaliveWithoutCalls) { - clearInterval(this.keepaliveIntervalId); - } - this.checkBothRefcounts(); - } - } - ref() { this.refTrace( 'refcount ' + @@ -804,7 +285,18 @@ export class Subchannel { (this.refcount - 1) ); this.refcount -= 1; - this.checkBothRefcounts(); + if (this.refcount === 0) { + if (this.channelzEnabled) { + this.channelzTrace.addTrace('CT_INFO', 'Shutting down'); + } + this.transitionToState( + [ConnectivityState.CONNECTING, ConnectivityState.READY], + ConnectivityState.IDLE + ); + if (this.channelzEnabled) { + unregisterChannelzRef(this.channelzRef); + } + } } unrefIfOneRef(): boolean { @@ -816,83 +308,26 @@ export class Subchannel { } createCall(metadata: Metadata, host: string, method: string, listener: SubchannelCallInterceptingListener): SubchannelCall { - const headers = metadata.toHttp2Headers(); - headers[HTTP2_HEADER_AUTHORITY] = host; - headers[HTTP2_HEADER_USER_AGENT] = this.userAgent; - headers[HTTP2_HEADER_CONTENT_TYPE] = 'application/grpc'; - headers[HTTP2_HEADER_METHOD] = 'POST'; - headers[HTTP2_HEADER_PATH] = method; - headers[HTTP2_HEADER_TE] = 'trailers'; - let http2Stream: http2.ClientHttp2Stream; - /* In theory, if an error is thrown by session.request because session has - * become unusable (e.g. because it has received a goaway), this subchannel - * should soon see the corresponding close or goaway event anyway and leave - * READY. But we have seen reports that this does not happen - * (https://github.com/googleapis/nodejs-firestore/issues/1023#issuecomment-653204096) - * so for defense in depth, we just discard the session when we see an - * error here. - */ - try { - http2Stream = this.session!.request(headers); - } catch (e) { - this.transitionToState( - [ConnectivityState.READY], - ConnectivityState.TRANSIENT_FAILURE - ); - throw e; + if (!this.transport) { + throw new Error('Cannot create call, subchannel not READY'); } - this.flowControlTrace( - 'local window size: ' + - this.session!.state.localWindowSize + - ' remote window size: ' + - this.session!.state.remoteWindowSize - ); - const streamSession = this.session; - this.internalsTrace( - 'session.closed=' + - streamSession!.closed + - ' session.destroyed=' + - streamSession!.destroyed + - ' session.socket.destroyed=' + - streamSession!.socket.destroyed); - let statsTracker: SubchannelCallStatsTracker; + let statsTracker: Partial; if (this.channelzEnabled) { this.callTracker.addCallStarted(); this.streamTracker.addCallStarted(); statsTracker = { - addMessageSent: () => { - this.messagesSent += 1; - this.lastMessageSentTimestamp = new Date(); - }, - addMessageReceived: () => { - this.messagesReceived += 1; - }, onCallEnd: status => { if (status.code === Status.OK) { this.callTracker.addCallSucceeded(); } else { this.callTracker.addCallFailed(); } - }, - onStreamEnd: success => { - if (streamSession === this.session) { - if (success) { - this.streamTracker.addCallSucceeded(); - } else { - this.streamTracker.addCallFailed(); - } - } } } } else { - statsTracker = { - addMessageSent: () => {}, - addMessageReceived: () => {}, - onCallEnd: () => {}, - onStreamEnd: () => {} - } + statsTracker = {}; } - return new Http2SubchannelCall(http2Stream, statsTracker, listener, this, getNextCallNumber()); + return this.transport.createCall(metadata, host, method, listener, statsTracker); } /** @@ -946,14 +381,6 @@ export class Subchannel { } } - addDisconnectListener(listener: () => void) { - this.disconnectListeners.add(listener); - } - - removeDisconnectListener(listener: () => void) { - this.disconnectListeners.delete(listener); - } - /** * Reset the backoff timeout, and immediately start connecting if in backoff. */ diff --git a/packages/grpc-js/src/transport.ts b/packages/grpc-js/src/transport.ts new file mode 100644 index 000000000..e713ed6ef --- /dev/null +++ b/packages/grpc-js/src/transport.ts @@ -0,0 +1,634 @@ +/* + * Copyright 2023 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 * as http2 from 'http2'; +import { checkServerIdentity, CipherNameAndProtocol, ConnectionOptions, PeerCertificate, TLSSocket } from 'tls'; +import { StatusObject } from './call-interface'; +import { ChannelCredentials } from './channel-credentials'; +import { ChannelOptions } from './channel-options'; +import { ChannelzCallTracker, registerChannelzSocket, SocketInfo, SocketRef, TlsInfo } from './channelz'; +import { LogVerbosity } from './constants'; +import { getProxiedConnection, ProxyConnectionResult } from './http_proxy'; +import * as logging from './logging'; +import { getDefaultAuthority } from './resolver'; +import { stringToSubchannelAddress, SubchannelAddress, subchannelAddressToString } from './subchannel-address'; +import { GrpcUri, parseUri, splitHostPort, uriToString } from './uri-parser'; +import * as net from 'net'; +import { Http2SubchannelCall, SubchannelCall, SubchannelCallInterceptingListener } from './subchannel-call'; +import { Metadata } from './metadata'; +import { getNextCallNumber } from './call-number'; + +const TRACER_NAME = 'transport'; +const FLOW_CONTROL_TRACER_NAME = 'transport_flowctrl'; + +const clientVersion = require('../../package.json').version; + +const { + HTTP2_HEADER_AUTHORITY, + HTTP2_HEADER_CONTENT_TYPE, + HTTP2_HEADER_METHOD, + HTTP2_HEADER_PATH, + HTTP2_HEADER_TE, + HTTP2_HEADER_USER_AGENT, +} = http2.constants; + +/* setInterval and setTimeout only accept signed 32 bit integers. JS doesn't + * have a constant for the max signed 32 bit integer, so this is a simple way + * to calculate it */ +const KEEPALIVE_MAX_TIME_MS = ~(1 << 31); +const KEEPALIVE_TIMEOUT_MS = 20000; + +export interface CallEventTracker { + addMessageSent(): void; + addMessageReceived(): void; + onCallEnd(status: StatusObject): void; + onStreamEnd(success: boolean): void; +} + +export interface TransportDisconnectListener { + (tooManyPings: boolean): void; +} + +export interface Transport { + getChannelzRef(): SocketRef; + createCall(metadata: Metadata, host: string, method: string, listener: SubchannelCallInterceptingListener, subchannelCallStatsTracker: Partial): SubchannelCall; + addDisconnectListener(listener: TransportDisconnectListener): void; + shutdown(): void; +} + +const tooManyPingsData: Buffer = Buffer.from('too_many_pings', 'ascii'); + +class Http2Transport implements Transport { + /** + * The amount of time in between sending pings + */ + private keepaliveTimeMs: number = KEEPALIVE_MAX_TIME_MS; + /** + * The amount of time to wait for an acknowledgement after sending a ping + */ + private keepaliveTimeoutMs: number = KEEPALIVE_TIMEOUT_MS; + /** + * Timer reference for timeout that indicates when to send the next ping + */ + private keepaliveIntervalId: NodeJS.Timer; + /** + * Timer reference tracking when the most recent ping will be considered lost + */ + private keepaliveTimeoutId: NodeJS.Timer | null = null; + /** + * Indicates whether keepalive pings should be sent without any active calls + */ + private keepaliveWithoutCalls = false; + + private userAgent: string; + + private activeCalls: Set = new Set(); + + private subchannelAddressString: string; + + private disconnectListeners: TransportDisconnectListener[] = []; + + private disconnectHandled = false; + + // Channelz info + private channelzRef: SocketRef; + private readonly channelzEnabled: boolean = true; + /** + * Name of the remote server, if it is not the same as the subchannel + * address, i.e. if connecting through an HTTP CONNECT proxy. + */ + private remoteName: string | null = null; + private streamTracker = new ChannelzCallTracker(); + private keepalivesSent = 0; + private messagesSent = 0; + private messagesReceived = 0; + private lastMessageSentTimestamp: Date | null = null; + private lastMessageReceivedTimestamp: Date | null = null; + + constructor( + private session: http2.ClientHttp2Session, + subchannelAddress: SubchannelAddress, + options: ChannelOptions + ) { + // Build user-agent string. + this.userAgent = [ + options['grpc.primary_user_agent'], + `grpc-node-js/${clientVersion}`, + options['grpc.secondary_user_agent'], + ] + .filter((e) => e) + .join(' '); // remove falsey values first + + if ('grpc.keepalive_time_ms' in options) { + this.keepaliveTimeMs = options['grpc.keepalive_time_ms']!; + } + if ('grpc.keepalive_timeout_ms' in options) { + this.keepaliveTimeoutMs = options['grpc.keepalive_timeout_ms']!; + } + if ('grpc.keepalive_permit_without_calls' in options) { + this.keepaliveWithoutCalls = + options['grpc.keepalive_permit_without_calls'] === 1; + } else { + this.keepaliveWithoutCalls = false; + } + this.keepaliveIntervalId = setTimeout(() => {}, 0); + clearTimeout(this.keepaliveIntervalId); + if (this.keepaliveWithoutCalls) { + this.startKeepalivePings(); + } + + this.subchannelAddressString = subchannelAddressToString(subchannelAddress); + + if (options['grpc.enable_channelz'] === 0) { + this.channelzEnabled = false; + } + this.channelzRef = registerChannelzSocket(this.subchannelAddressString, () => this.getChannelzInfo(), this.channelzEnabled); + + session.once('close', () => { + this.trace('session closed'); + this.stopKeepalivePings(); + this.handleDisconnect(false); + }); + session.once('goaway', (errorCode: number, lastStreamID: number, opaqueData: Buffer) => { + let tooManyPings = false; + /* See the last paragraph of + * https://github.com/grpc/proposal/blob/master/A8-client-side-keepalive.md#basic-keepalive */ + if ( + errorCode === http2.constants.NGHTTP2_ENHANCE_YOUR_CALM && + opaqueData.equals(tooManyPingsData) + ) { + tooManyPings = true; + } + this.trace( + 'connection closed by GOAWAY with code ' + + errorCode + ); + this.handleDisconnect(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( + 'new settings received' + + (this.session !== session ? ' on the old connection' : '') + + ': ' + + JSON.stringify(settings) + ); + }); + session.on('localSettings', (settings: http2.Settings) => { + this.trace( + 'local settings acknowledged by remote' + + (this.session !== session ? ' on the old connection' : '') + + ': ' + + JSON.stringify(settings) + ); + }); + } + } + + private getChannelzInfo(): SocketInfo { + const sessionSocket = this.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 (this.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: this.remoteName, + streamsStarted: this.streamTracker.callsStarted, + streamsSucceeded: this.streamTracker.callsSucceeded, + streamsFailed: this.streamTracker.callsFailed, + messagesSent: this.messagesSent, + messagesReceived: this.messagesReceived, + keepAlivesSent: this.keepalivesSent, + lastLocalStreamCreatedTimestamp: this.streamTracker.lastCallStartedTimestamp, + lastRemoteStreamCreatedTimestamp: null, + lastMessageSentTimestamp: this.lastMessageSentTimestamp, + lastMessageReceivedTimestamp: this.lastMessageReceivedTimestamp, + localFlowControlWindow: this.session.state.localWindowSize ?? null, + remoteFlowControlWindow: this.session.state.remoteWindowSize ?? null + }; + return socketInfo; + } + + private trace(text: string): void { + logging.trace(LogVerbosity.DEBUG, TRACER_NAME, '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' ' + text); + } + + private keepaliveTrace(text: string): void { + logging.trace(LogVerbosity.DEBUG, 'keepalive', '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' ' + text); + } + + private flowControlTrace(text: string): void { + logging.trace(LogVerbosity.DEBUG, FLOW_CONTROL_TRACER_NAME, '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' ' + text); + } + + private internalsTrace(text: string): void { + logging.trace(LogVerbosity.DEBUG, 'transport_internals', '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' ' + text); + } + + private handleDisconnect(tooManyPings: boolean) { + if (this.disconnectHandled) { + return; + } + this.disconnectHandled = true; + this.disconnectListeners.forEach(listener => listener(tooManyPings)); + for (const call of this.activeCalls) { + call.onDisconnect(); + } + } + + addDisconnectListener(listener: TransportDisconnectListener): void { + this.disconnectListeners.push(listener); + } + + private clearKeepaliveTimeout() { + if (!this.keepaliveTimeoutId) { + return; + } + clearTimeout(this.keepaliveTimeoutId); + this.keepaliveTimeoutId = null; + } + + private sendPing() { + 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(false); + }, this.keepaliveTimeoutMs); + this.keepaliveTimeoutId.unref?.(); + } + try { + this.session!.ping( + (err: Error | null, duration: number, payload: Buffer) => { + this.keepaliveTrace('Received ping response'); + this.clearKeepaliveTimeout(); + } + ); + } catch (e) { + /* If we fail to send a ping, the connection is no longer functional, so + * we should discard it. */ + this.handleDisconnect(false); + } + } + + private startKeepalivePings() { + this.keepaliveIntervalId = setInterval(() => { + this.sendPing(); + }, this.keepaliveTimeMs); + this.keepaliveIntervalId.unref?.(); + /* Don't send a ping immediately because whatever caused us to start + * sending pings should also involve some network activity. */ + } + + /** + * Stop keepalive pings when terminating a connection. This discards the + * outstanding ping timeout, so it should not be called if the same + * connection will still be used. + */ + private stopKeepalivePings() { + clearInterval(this.keepaliveIntervalId); + this.clearKeepaliveTimeout(); + } + + private removeActiveCall(call: Http2SubchannelCall) { + this.activeCalls.delete(call); + if (this.activeCalls.size === 0 && !this.keepaliveWithoutCalls) { + this.stopKeepalivePings(); + } + } + + private addActiveCall(call: Http2SubchannelCall) { + if (this.activeCalls.size === 0 && !this.keepaliveWithoutCalls) { + this.startKeepalivePings(); + } + this.activeCalls.add(call); + } + + createCall(metadata: Metadata, host: string, method: string, listener: SubchannelCallInterceptingListener, subchannelCallStatsTracker: Partial): Http2SubchannelCall { + const headers = metadata.toHttp2Headers(); + headers[HTTP2_HEADER_AUTHORITY] = host; + headers[HTTP2_HEADER_USER_AGENT] = this.userAgent; + headers[HTTP2_HEADER_CONTENT_TYPE] = 'application/grpc'; + headers[HTTP2_HEADER_METHOD] = 'POST'; + headers[HTTP2_HEADER_PATH] = method; + headers[HTTP2_HEADER_TE] = 'trailers'; + let http2Stream: http2.ClientHttp2Stream; + /* In theory, if an error is thrown by session.request because session has + * become unusable (e.g. because it has received a goaway), this subchannel + * should soon see the corresponding close or goaway event anyway and leave + * READY. But we have seen reports that this does not happen + * (https://github.com/googleapis/nodejs-firestore/issues/1023#issuecomment-653204096) + * so for defense in depth, we just discard the session when we see an + * error here. + */ + try { + http2Stream = this.session!.request(headers); + } catch (e) { + this.handleDisconnect(false); + throw e; + } + this.flowControlTrace( + 'local window size: ' + + this.session.state.localWindowSize + + ' remote window size: ' + + this.session.state.remoteWindowSize + ); + this.internalsTrace( + 'session.closed=' + + this.session.closed + + ' session.destroyed=' + + this.session.destroyed + + ' session.socket.destroyed=' + + this.session.socket.destroyed); + let eventTracker: CallEventTracker; + let call: Http2SubchannelCall; + if (this.channelzEnabled) { + this.streamTracker.addCallStarted(); + eventTracker = { + addMessageSent: () => { + this.messagesSent += 1; + this.lastMessageSentTimestamp = new Date(); + subchannelCallStatsTracker.addMessageSent?.(); + }, + addMessageReceived: () => { + this.messagesReceived += 1; + this.lastMessageReceivedTimestamp = new Date(); + subchannelCallStatsTracker.addMessageReceived?.(); + }, + onCallEnd: status => { + subchannelCallStatsTracker.onCallEnd?.(status); + }, + onStreamEnd: success => { + if (success) { + this.streamTracker.addCallSucceeded(); + } else { + this.streamTracker.addCallFailed(); + } + this.removeActiveCall(call); + subchannelCallStatsTracker.onStreamEnd?.(success); + } + } + } else { + eventTracker = { + addMessageSent: () => { + subchannelCallStatsTracker.addMessageSent?.(); + }, + addMessageReceived: () => { + subchannelCallStatsTracker.addMessageReceived?.(); + }, + onCallEnd: (status) => { + subchannelCallStatsTracker.onCallEnd?.(status); + this.removeActiveCall(call); + }, + onStreamEnd: (success) => { + subchannelCallStatsTracker.onStreamEnd?.(success); + } + } + } + call = new Http2SubchannelCall(http2Stream, eventTracker, listener, this.subchannelAddressString, getNextCallNumber()); + this.addActiveCall(call); + return call; + } + + getChannelzRef(): SocketRef { + return this.channelzRef; + } + + shutdown() { + this.session.close(); + } +} + +export interface SubchannelConnector { + connect(address: SubchannelAddress, credentials: ChannelCredentials, options: ChannelOptions): Promise; + shutdown(): void; +} + +export class Http2SubchannelConnector implements SubchannelConnector { + private session: http2.ClientHttp2Session | null = null; + private isShutdown = false; + constructor(private channelTarget: GrpcUri) {} + private trace(text: string) { + + } + private createSession(address: SubchannelAddress, credentials: ChannelCredentials, options: ChannelOptions, proxyConnectionResult: ProxyConnectionResult): Promise { + if (this.isShutdown) { + return Promise.reject(); + } + return new Promise((resolve, reject) => { + let remoteName: string | null; + if (proxyConnectionResult.realTarget) { + remoteName = uriToString(proxyConnectionResult.realTarget); + this.trace('creating HTTP/2 session through proxy to ' + uriToString(proxyConnectionResult.realTarget)); + } else { + remoteName = null; + this.trace('creating HTTP/2 session to ' + subchannelAddressToString(address)); + } + const targetAuthority = getDefaultAuthority( + proxyConnectionResult.realTarget ?? this.channelTarget + ); + let connectionOptions: http2.SecureClientSessionOptions = + credentials._getConnectionOptions() || {}; + connectionOptions.maxSendHeaderBlockLength = Number.MAX_SAFE_INTEGER; + if ('grpc-node.max_session_memory' in options) { + connectionOptions.maxSessionMemory = options[ + 'grpc-node.max_session_memory' + ]; + } else { + /* By default, set a very large max session memory limit, to effectively + * disable enforcement of the limit. Some testing indicates that Node's + * behavior degrades badly when this limit is reached, so we solve that + * by disabling the check entirely. */ + connectionOptions.maxSessionMemory = Number.MAX_SAFE_INTEGER; + } + let addressScheme = 'http://'; + if ('secureContext' in connectionOptions) { + addressScheme = 'https://'; + // If provided, the value of grpc.ssl_target_name_override should be used + // to override the target hostname when checking server identity. + // This option is used for testing only. + if (options['grpc.ssl_target_name_override']) { + const sslTargetNameOverride = options[ + 'grpc.ssl_target_name_override' + ]!; + connectionOptions.checkServerIdentity = ( + host: string, + cert: PeerCertificate + ): Error | undefined => { + return checkServerIdentity(sslTargetNameOverride, cert); + }; + connectionOptions.servername = sslTargetNameOverride; + } else { + const authorityHostname = + splitHostPort(targetAuthority)?.host ?? 'localhost'; + // We want to always set servername to support SNI + connectionOptions.servername = authorityHostname; + } + if (proxyConnectionResult.socket) { + /* This is part of the workaround for + * https://github.com/nodejs/node/issues/32922. Without that bug, + * proxyConnectionResult.socket would always be a plaintext socket and + * this would say + * connectionOptions.socket = proxyConnectionResult.socket; */ + connectionOptions.createConnection = (authority, option) => { + return proxyConnectionResult.socket!; + }; + } + } else { + /* In all but the most recent versions of Node, http2.connect does not use + * the options when establishing plaintext connections, so we need to + * establish that connection explicitly. */ + connectionOptions.createConnection = (authority, option) => { + if (proxyConnectionResult.socket) { + return proxyConnectionResult.socket; + } else { + /* net.NetConnectOpts is declared in a way that is more restrictive + * than what net.connect will actually accept, so we use the type + * assertion to work around that. */ + return net.connect(address); + } + }; + } + + connectionOptions = { + ...connectionOptions, + ...address, + }; + + /* http2.connect uses the options here: + * https://github.com/nodejs/node/blob/70c32a6d190e2b5d7b9ff9d5b6a459d14e8b7d59/lib/internal/http2/core.js#L3028-L3036 + * The spread operator overides earlier values with later ones, so any port + * or host values in the options will be used rather than any values extracted + * from the first argument. In addition, the path overrides the host and port, + * as documented for plaintext connections here: + * https://nodejs.org/api/net.html#net_socket_connect_options_connectlistener + * and for TLS connections here: + * https://nodejs.org/api/tls.html#tls_tls_connect_options_callback. In + * earlier versions of Node, http2.connect passes these options to + * tls.connect but not net.connect, so in the insecure case we still need + * to set the createConnection option above to create the connection + * explicitly. We cannot do that in the TLS case because http2.connect + * passes necessary additional options to tls.connect. + * The first argument just needs to be parseable as a URL and the scheme + * determines whether the connection will be established over TLS or not. + */ + const session = http2.connect( + addressScheme + targetAuthority, + connectionOptions + ); + this.session = session; + session.unref(); + session.once('connect', () => { + session.removeAllListeners(); + resolve(new Http2Transport(session, address, options)); + this.session = null; + }); + session.once('close', () => { + this.session = null; + reject(); + }); + session.once('error', error => { + this.trace('connection failed with error ' + (error as Error).message) + }); + }); + } + connect(address: SubchannelAddress, credentials: ChannelCredentials, options: ChannelOptions): Promise { + if (this.isShutdown) { + return Promise.reject(); + } + /* Pass connection options through to the proxy so that it's able to + * upgrade it's connection to support tls if needed. + * This is a workaround for https://github.com/nodejs/node/issues/32922 + * See https://github.com/grpc/grpc-node/pull/1369 for more info. */ + const connectionOptions: ConnectionOptions = + credentials._getConnectionOptions() || {}; + + if ('secureContext' in connectionOptions) { + connectionOptions.ALPNProtocols = ['h2']; + // If provided, the value of grpc.ssl_target_name_override should be used + // to override the target hostname when checking server identity. + // This option is used for testing only. + if (options['grpc.ssl_target_name_override']) { + const sslTargetNameOverride = options[ + 'grpc.ssl_target_name_override' + ]!; + connectionOptions.checkServerIdentity = ( + host: string, + cert: PeerCertificate + ): Error | undefined => { + return checkServerIdentity(sslTargetNameOverride, cert); + }; + connectionOptions.servername = sslTargetNameOverride; + } else { + if ('grpc.http_connect_target' in options) { + /* This is more or less how servername will be set in createSession + * if a connection is successfully established through the proxy. + * If the proxy is not used, these connectionOptions are discarded + * anyway */ + const targetPath = getDefaultAuthority( + parseUri(options['grpc.http_connect_target'] as string) ?? { + path: 'localhost', + } + ); + const hostPort = splitHostPort(targetPath); + connectionOptions.servername = hostPort?.host ?? targetPath; + } + } + } + + return getProxiedConnection( + address, + options, + connectionOptions + ).then( + result => this.createSession(address, credentials, options, result) + ); + } + + shutdown(): void { + this.isShutdown = true; + this.session?.close(); + this.session = null; + } +} \ No newline at end of file From b72e1fc665824d096255e4a95e541517b7822df2 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 6 Jan 2023 14:31:23 -0800 Subject: [PATCH 404/450] Merge pull request #2310 from grpc/reduce-gce-xds-interop-tests grpc-js-xds: Reduce GCE xDS interop tests to ping_pong and circuit_breaking --- packages/grpc-js-xds/scripts/xds.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/scripts/xds.sh b/packages/grpc-js-xds/scripts/xds.sh index 615b2a7c7..d4490c5ef 100755 --- a/packages/grpc-js-xds/scripts/xds.sh +++ b/packages/grpc-js-xds/scripts/xds.sh @@ -54,7 +54,7 @@ GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weigh GRPC_NODE_VERBOSITY=DEBUG \ NODE_XDS_INTEROP_VERBOSITY=1 \ python3 grpc/tools/run_tests/run_xds_tests.py \ - --test_case="all,timeout,circuit_breaking,fault_injection,csds" \ + --test_case="ping_pong,circuit_breaking" \ --project_id=grpc-testing \ --source_image=projects/grpc-testing/global/images/xds-test-server-5 \ --path_to_server_binary=/java_server/grpc-java/interop-testing/build/install/grpc-interop-testing/bin/xds-test-server \ From 2d37686a1a0e0f028acb455a630fa65e122db7ad Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 9 Jan 2023 10:18:43 -0800 Subject: [PATCH 405/450] grpc-js: Ensure ordering between status and final message --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/subchannel-call.ts | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 06707c2c4..c11b4dc42 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.8.1", + "version": "1.8.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", diff --git a/packages/grpc-js/src/subchannel-call.ts b/packages/grpc-js/src/subchannel-call.ts index 6556bc460..a560ed4d7 100644 --- a/packages/grpc-js/src/subchannel-call.ts +++ b/packages/grpc-js/src/subchannel-call.ts @@ -87,6 +87,7 @@ export class Http2SubchannelCall implements SubchannelCall { private decoder = new StreamDecoder(); private isReadFilterPending = false; + private isPushPending = false; private canPush = false; /** * Indicates that an 'end' event has come from the http2 stream, so there @@ -360,7 +361,8 @@ export class Http2SubchannelCall implements SubchannelCall { this.finalStatus.code !== Status.OK || (this.readsClosed && this.unpushedReadMessages.length === 0 && - !this.isReadFilterPending) + !this.isReadFilterPending && + !this.isPushPending) ) { this.outputStatus(); } @@ -373,7 +375,9 @@ export class Http2SubchannelCall implements SubchannelCall { (message instanceof Buffer ? message.length : null) ); this.canPush = false; + this.isPushPending = true; process.nextTick(() => { + this.isPushPending = false; /* If we have already output the status any later messages should be * ignored, and can cause out-of-order operation errors higher up in the * stack. Checking as late as possible here to avoid any race conditions. From b3b6310f041aef2770f4a7945453e4db2b5cd113 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 10 Jan 2023 15:24:22 -0800 Subject: [PATCH 406/450] grpc-js: Don't end calls when receiving GOAWAY --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/transport.ts | 38 ++++++++++++---- packages/grpc-js/test/test-server.ts | 67 +++++++++++++++++++++++----- 3 files changed, 87 insertions(+), 20 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index c11b4dc42..700c7b773 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.8.2", + "version": "1.8.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", diff --git a/packages/grpc-js/src/transport.ts b/packages/grpc-js/src/transport.ts index e713ed6ef..64f770945 100644 --- a/packages/grpc-js/src/transport.ts +++ b/packages/grpc-js/src/transport.ts @@ -161,7 +161,7 @@ class Http2Transport implements Transport { session.once('close', () => { this.trace('session closed'); this.stopKeepalivePings(); - this.handleDisconnect(false); + this.handleDisconnect(); }); session.once('goaway', (errorCode: number, lastStreamID: number, opaqueData: Buffer) => { let tooManyPings = false; @@ -177,7 +177,7 @@ class Http2Transport implements Transport { 'connection closed by GOAWAY with code ' + errorCode ); - this.handleDisconnect(tooManyPings); + this.reportDisconnectToOwner(tooManyPings); }); session.once('error', error => { /* Do nothing here. Any error should also trigger a close event, which is @@ -263,15 +263,35 @@ class Http2Transport implements Transport { logging.trace(LogVerbosity.DEBUG, 'transport_internals', '(' + this.channelzRef.id + ') ' + this.subchannelAddressString + ' ' + text); } - private handleDisconnect(tooManyPings: boolean) { + /** + * Indicate to the owner of this object that this transport should no longer + * be used. That happens if the connection drops, or if the server sends a + * GOAWAY. + * @param tooManyPings If true, this was triggered by a GOAWAY with data + * indicating that the session was closed becaues the client sent too many + * pings. + * @returns + */ + private reportDisconnectToOwner(tooManyPings: boolean) { if (this.disconnectHandled) { return; } this.disconnectHandled = true; this.disconnectListeners.forEach(listener => listener(tooManyPings)); - for (const call of this.activeCalls) { - call.onDisconnect(); - } + } + + /** + * Handle connection drops, but not GOAWAYs. + */ + private handleDisconnect() { + this.reportDisconnectToOwner(false); + /* Give calls an event loop cycle to finish naturally before reporting the + * disconnnection to them. */ + setImmediate(() => { + for (const call of this.activeCalls) { + call.onDisconnect(); + } + }); } addDisconnectListener(listener: TransportDisconnectListener): void { @@ -294,7 +314,7 @@ class Http2Transport implements Transport { if (!this.keepaliveTimeoutId) { this.keepaliveTimeoutId = setTimeout(() => { this.keepaliveTrace('Ping timeout passed without response'); - this.handleDisconnect(false); + this.handleDisconnect(); }, this.keepaliveTimeoutMs); this.keepaliveTimeoutId.unref?.(); } @@ -308,7 +328,7 @@ class Http2Transport implements Transport { } catch (e) { /* If we fail to send a ping, the connection is no longer functional, so * we should discard it. */ - this.handleDisconnect(false); + this.handleDisconnect(); } } @@ -365,7 +385,7 @@ class Http2Transport implements Transport { try { http2Stream = this.session!.request(headers); } catch (e) { - this.handleDisconnect(false); + this.handleDisconnect(); throw e; } this.flowControlTrace( diff --git a/packages/grpc-js/test/test-server.ts b/packages/grpc-js/test/test-server.ts index 0c0ba168e..c67ebc4d6 100644 --- a/packages/grpc-js/test/test-server.ts +++ b/packages/grpc-js/test/test-server.ts @@ -27,9 +27,9 @@ import * as grpc from '../src'; import { Server, ServerCredentials } from '../src'; import { ServiceError } from '../src/call'; import { ServiceClient, ServiceClientConstructor } from '../src/make-client'; -import { sendUnaryData, ServerUnaryCall } from '../src/server-call'; +import { sendUnaryData, ServerUnaryCall, ServerDuplexStream } from '../src/server-call'; -import { loadProtoFile } from './common'; +import { assert2, loadProtoFile } from './common'; import { TestServiceClient, TestServiceHandlers } from './generated/TestService'; import { ProtoGrpcType as TestServiceGrpcType } from './generated/test_service'; import { Request__Output } from './generated/Request'; @@ -458,18 +458,28 @@ describe('Server', () => { describe('Echo service', () => { let server: Server; let client: ServiceClient; + const protoFile = path.join(__dirname, 'fixtures', 'echo_service.proto'); + const echoService = loadProtoFile(protoFile) + .EchoService as ServiceClientConstructor; + + const serviceImplementation = { + echo(call: ServerUnaryCall, callback: sendUnaryData) { + callback(null, call.request); + }, + echoBidiStream(call: ServerDuplexStream) { + call.on('data', data => { + call.write(data); + }); + call.on('end', () => { + call.end(); + }); + } + }; before(done => { - const protoFile = path.join(__dirname, 'fixtures', 'echo_service.proto'); - const echoService = loadProtoFile(protoFile) - .EchoService as ServiceClientConstructor; server = new Server(); - server.addService(echoService.service, { - echo(call: ServerUnaryCall, callback: sendUnaryData) { - callback(null, call.request); - }, - }); + server.addService(echoService.service, serviceImplementation); server.bindAsync( 'localhost:0', @@ -501,6 +511,43 @@ describe('Echo service', () => { } ); }); + + /* This test passes on Node 18 but fails on Node 16. The failure appears to + * be caused by https://github.com/nodejs/node/issues/42713 */ + it.skip('should continue a stream after server shutdown', done => { + const server2 = new Server(); + server2.addService(echoService.service, serviceImplementation); + server2.bindAsync('localhost:0', ServerCredentials.createInsecure(), (err, port) => { + if (err) { + done(err); + return; + } + const client2 = new echoService(`localhost:${port}`, grpc.credentials.createInsecure()); + server2.start(); + const stream = client2.echoBidiStream(); + const totalMessages = 5; + let messagesSent = 0; + stream.write({ value: 'test value', value2: messagesSent}); + messagesSent += 1; + stream.on('data', () => { + if (messagesSent === 1) { + server2.tryShutdown(assert2.mustCall(() => {})); + } + if (messagesSent >= totalMessages) { + stream.end(); + } else { + stream.write({ value: 'test value', value2: messagesSent}); + messagesSent += 1; + } + }); + stream.on('status', assert2.mustCall((status: grpc.StatusObject) => { + assert.strictEqual(status.code, grpc.status.OK); + assert.strictEqual(messagesSent, totalMessages); + })); + stream.on('error', () => {}); + assert2.afterMustCallsSatisfied(done); + }); + }); }); describe('Generic client and server', () => { From b342001b38237f337af23d9f81fed25b3e6507d6 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 12 Jan 2023 09:24:21 -0800 Subject: [PATCH 407/450] grpc-js: Reference session in transport when there are active calls --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/transport.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 700c7b773..d9ef213db 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.8.3", + "version": "1.8.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/transport.ts b/packages/grpc-js/src/transport.ts index 64f770945..314971029 100644 --- a/packages/grpc-js/src/transport.ts +++ b/packages/grpc-js/src/transport.ts @@ -354,12 +354,14 @@ class Http2Transport implements Transport { private removeActiveCall(call: Http2SubchannelCall) { this.activeCalls.delete(call); if (this.activeCalls.size === 0 && !this.keepaliveWithoutCalls) { + this.session.unref(); this.stopKeepalivePings(); } } private addActiveCall(call: Http2SubchannelCall) { if (this.activeCalls.size === 0 && !this.keepaliveWithoutCalls) { + this.session.ref(); this.startKeepalivePings(); } this.activeCalls.add(call); From fade30bd0a27bfa32395a35a1bf61ab15cb62f8e Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 12 Jan 2023 09:47:19 -0800 Subject: [PATCH 408/450] grpc-js: Make call and stream tracking more consistent --- packages/grpc-js/src/subchannel-call.ts | 3 +-- packages/grpc-js/src/transport.ts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/grpc-js/src/subchannel-call.ts b/packages/grpc-js/src/subchannel-call.ts index a560ed4d7..16ac35b5e 100644 --- a/packages/grpc-js/src/subchannel-call.ts +++ b/packages/grpc-js/src/subchannel-call.ts @@ -198,6 +198,7 @@ export class Http2SubchannelCall implements SubchannelCall { * we can bubble up the error message from that event. */ process.nextTick(() => { this.trace('HTTP/2 stream closed with code ' + http2Stream.rstCode); + this.callEventTracker.onStreamEnd(this.finalStatus?.code === Status.OK); /* If we have a final status with an OK status code, that means that * we have received all of the messages and we have processed the * trailers and the call completed successfully, so it doesn't matter @@ -288,7 +289,6 @@ export class Http2SubchannelCall implements SubchannelCall { ); this.internalError = err; } - this.callEventTracker.onStreamEnd(false); }); } @@ -403,7 +403,6 @@ export class Http2SubchannelCall implements SubchannelCall { } private handleTrailers(headers: http2.IncomingHttpHeaders) { - this.callEventTracker.onStreamEnd(true); let headersString = ''; for (const header of Object.keys(headers)) { headersString += '\t\t' + header + ': ' + headers[header] + '\n'; diff --git a/packages/grpc-js/src/transport.ts b/packages/grpc-js/src/transport.ts index 314971029..fc9042278 100644 --- a/packages/grpc-js/src/transport.ts +++ b/packages/grpc-js/src/transport.ts @@ -420,6 +420,7 @@ class Http2Transport implements Transport { }, onCallEnd: status => { subchannelCallStatsTracker.onCallEnd?.(status); + this.removeActiveCall(call); }, onStreamEnd: success => { if (success) { @@ -427,7 +428,6 @@ class Http2Transport implements Transport { } else { this.streamTracker.addCallFailed(); } - this.removeActiveCall(call); subchannelCallStatsTracker.onStreamEnd?.(success); } } From 7eaebaf1ed601b16c988702cf420a9aeb24a7130 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 12 Jan 2023 10:00:28 -0800 Subject: [PATCH 409/450] grpc-js: Undo changes to stream tracking --- packages/grpc-js/src/subchannel-call.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/src/subchannel-call.ts b/packages/grpc-js/src/subchannel-call.ts index 16ac35b5e..a560ed4d7 100644 --- a/packages/grpc-js/src/subchannel-call.ts +++ b/packages/grpc-js/src/subchannel-call.ts @@ -198,7 +198,6 @@ export class Http2SubchannelCall implements SubchannelCall { * we can bubble up the error message from that event. */ process.nextTick(() => { this.trace('HTTP/2 stream closed with code ' + http2Stream.rstCode); - this.callEventTracker.onStreamEnd(this.finalStatus?.code === Status.OK); /* If we have a final status with an OK status code, that means that * we have received all of the messages and we have processed the * trailers and the call completed successfully, so it doesn't matter @@ -289,6 +288,7 @@ export class Http2SubchannelCall implements SubchannelCall { ); this.internalError = err; } + this.callEventTracker.onStreamEnd(false); }); } @@ -403,6 +403,7 @@ export class Http2SubchannelCall implements SubchannelCall { } private handleTrailers(headers: http2.IncomingHttpHeaders) { + this.callEventTracker.onStreamEnd(true); let headersString = ''; for (const header of Object.keys(headers)) { headersString += '\t\t' + header + ': ' + headers[header] + '\n'; From d441aa687d52032877ab46b4a44efd2251d8fe05 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 17 Jan 2023 09:58:24 -0800 Subject: [PATCH 410/450] Merge pull request #2323 from sergiitk/xds-interop-fix-buildscript-suites xds interop: Fix buildscripts not continuing on a failed test suite --- packages/grpc-js-xds/scripts/xds_k8s_lb.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh index ca747f7ea..b87e3306c 100755 --- a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh @@ -167,7 +167,7 @@ main() { local failed_tests=0 test_suites=("baseline_test" "api_listener_test" "change_backend_service_test" "failover_test" "remove_neg_test" "round_robin_test" "outlier_detection_test") for test in "${test_suites[@]}"; do - run_test $test || (( failed_tests++ )) + run_test $test || (( ++failed_tests )) done echo "Failed test suites: ${failed_tests}" if (( failed_tests > 0 )); then From 7a6fa275fe5204f54a606a34f97cd6df7161be00 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 18 Jan 2023 10:54:07 -0800 Subject: [PATCH 411/450] grpc-js-xds: weighted clusters: stop checking total_weight, check weight sum <= uint32 max --- packages/grpc-js-xds/src/xds-stream-state/rds-state.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts index 891eb7c8e..fef694517 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/rds-state.ts @@ -32,6 +32,8 @@ const SUPPPORTED_HEADER_MATCH_SPECIFIERS = [ 'suffix_match']; const SUPPORTED_CLUSTER_SPECIFIERS = ['cluster', 'weighted_clusters', 'cluster_header']; +const UINT32_MAX = 0xFFFFFFFF; + function durationToMs(duration: Duration__Output | null): number | null { if (duration === null) { return null; @@ -130,14 +132,11 @@ export class RdsState extends BaseXdsStreamState imp } } if (route.route!.cluster_specifier === 'weighted_clusters') { - if (route.route.weighted_clusters!.total_weight?.value === 0) { - return false; - } let weightSum = 0; for (const clusterWeight of route.route.weighted_clusters!.clusters) { weightSum += clusterWeight.weight?.value ?? 0; } - if (weightSum !== route.route.weighted_clusters!.total_weight?.value ?? 100) { + if (weightSum === 0 || weightSum > UINT32_MAX) { return false; } if (EXPERIMENTAL_FAULT_INJECTION) { From ba405cf35e8f96390889f383189dd4bbe014e85f Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 23 Jan 2023 11:36:24 -0800 Subject: [PATCH 412/450] grpc-js: Clear deadline timer when call ends --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/resolving-call.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index d9ef213db..e9a181795 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.8.4", + "version": "1.8.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/resolving-call.ts b/packages/grpc-js/src/resolving-call.ts index fe29a4f7a..f1fecd1d2 100644 --- a/packages/grpc-js/src/resolving-call.ts +++ b/packages/grpc-js/src/resolving-call.ts @@ -103,6 +103,7 @@ export class ResolvingCall implements Call { if (!this.filterStack) { this.filterStack = this.filterStackFactory.createFilter(); } + clearTimeout(this.deadlineTimer); const filteredStatus = this.filterStack.receiveTrailers(status); this.trace('ended with status: code=' + filteredStatus.code + ' details="' + filteredStatus.details + '"'); this.statusWatchers.forEach(watcher => watcher(filteredStatus)); From 6d98dc5bbfe0d01025c210c80e4f88533679b34a Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 25 Jan 2023 10:01:45 -0800 Subject: [PATCH 413/450] grpc-js: Hold a reference to transport in SubchannelCall --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/subchannel-call.ts | 15 +++------------ packages/grpc-js/src/transport.ts | 7 ++++++- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index e9a181795..c17d5e6ba 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.8.5", + "version": "1.8.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/subchannel-call.ts b/packages/grpc-js/src/subchannel-call.ts index a560ed4d7..969282e19 100644 --- a/packages/grpc-js/src/subchannel-call.ts +++ b/packages/grpc-js/src/subchannel-call.ts @@ -26,7 +26,7 @@ import { LogVerbosity } from './constants'; import { ServerSurfaceCall } from './server-call'; import { Deadline } from './deadline'; import { InterceptingListener, MessageContext, StatusObject, WriteCallback } from './call-interface'; -import { CallEventTracker } from './transport'; +import { CallEventTracker, Transport } from './transport'; const TRACER_NAME = 'subchannel_call'; @@ -105,24 +105,15 @@ export class Http2SubchannelCall implements SubchannelCall { // This is populated (non-null) if and only if the call has ended private finalStatus: StatusObject | null = null; - private disconnectListener: () => void; - private internalError: SystemError | null = null; constructor( private readonly http2Stream: http2.ClientHttp2Stream, private readonly callEventTracker: CallEventTracker, private readonly listener: SubchannelCallInterceptingListener, - private readonly peerName: string, + private readonly transport: Transport, private readonly callId: number ) { - this.disconnectListener = () => { - this.endCall({ - code: Status.UNAVAILABLE, - details: 'Connection dropped', - metadata: new Metadata(), - }); - }; http2Stream.on('response', (headers, flags) => { let headersString = ''; for (const header of Object.keys(headers)) { @@ -475,7 +466,7 @@ export class Http2SubchannelCall implements SubchannelCall { } getPeer(): string { - return this.peerName; + return this.transport.getPeerName(); } getCallNumber(): number { diff --git a/packages/grpc-js/src/transport.ts b/packages/grpc-js/src/transport.ts index fc9042278..a5bf59b3f 100644 --- a/packages/grpc-js/src/transport.ts +++ b/packages/grpc-js/src/transport.ts @@ -65,6 +65,7 @@ export interface TransportDisconnectListener { export interface Transport { getChannelzRef(): SocketRef; + getPeerName(): string; createCall(metadata: Metadata, host: string, method: string, listener: SubchannelCallInterceptingListener, subchannelCallStatsTracker: Partial): SubchannelCall; addDisconnectListener(listener: TransportDisconnectListener): void; shutdown(): void; @@ -448,7 +449,7 @@ class Http2Transport implements Transport { } } } - call = new Http2SubchannelCall(http2Stream, eventTracker, listener, this.subchannelAddressString, getNextCallNumber()); + call = new Http2SubchannelCall(http2Stream, eventTracker, listener, this, getNextCallNumber()); this.addActiveCall(call); return call; } @@ -457,6 +458,10 @@ class Http2Transport implements Transport { return this.channelzRef; } + getPeerName() { + return this.subchannelAddressString; + } + shutdown() { this.session.close(); } From 0d177a818f83cd9de6fc1f5e4bd343de4538e35a Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 25 Jan 2023 11:52:24 -0800 Subject: [PATCH 414/450] grpc-js: Fix tracking of active calls in transport --- packages/grpc-js/src/transport.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js/src/transport.ts b/packages/grpc-js/src/transport.ts index a5bf59b3f..a9308471b 100644 --- a/packages/grpc-js/src/transport.ts +++ b/packages/grpc-js/src/transport.ts @@ -354,16 +354,20 @@ class Http2Transport implements Transport { private removeActiveCall(call: Http2SubchannelCall) { this.activeCalls.delete(call); - if (this.activeCalls.size === 0 && !this.keepaliveWithoutCalls) { + if (this.activeCalls.size === 0) { this.session.unref(); - this.stopKeepalivePings(); + if (!this.keepaliveWithoutCalls) { + this.stopKeepalivePings(); + } } } private addActiveCall(call: Http2SubchannelCall) { - if (this.activeCalls.size === 0 && !this.keepaliveWithoutCalls) { + if (this.activeCalls.size === 0) { this.session.ref(); - this.startKeepalivePings(); + if (!this.keepaliveWithoutCalls) { + this.startKeepalivePings(); + } } this.activeCalls.add(call); } From 3efdc7b58c0910075659982603e850cc883e019b Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 25 Jan 2023 11:56:09 -0800 Subject: [PATCH 415/450] grpc-js: Bump version to 1.8.7 --- 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 c17d5e6ba..9e1dfcba6 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.8.6", + "version": "1.8.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", From cf090c7f5075452d322ead84496b7f0ed0bb1868 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 7 Feb 2023 13:44:22 -0800 Subject: [PATCH 416/450] grpc-js: Fix commitCallWithMostMessages trying to commit completed attempts --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/retrying-call.ts | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 9e1dfcba6..290d80b75 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.8.7", + "version": "1.8.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/retrying-call.ts b/packages/grpc-js/src/retrying-call.ts index 8daf5ba70..05e5f40c1 100644 --- a/packages/grpc-js/src/retrying-call.ts +++ b/packages/grpc-js/src/retrying-call.ts @@ -273,15 +273,24 @@ export class RetryingCall implements Call { } private commitCallWithMostMessages() { + if (this.state === 'COMMITTED') { + return; + } let mostMessages = -1; let callWithMostMessages = -1; for (const [index, childCall] of this.underlyingCalls.entries()) { - if (childCall.nextMessageToSend > mostMessages) { + if (childCall.state === 'ACTIVE' && childCall.nextMessageToSend > mostMessages) { mostMessages = childCall.nextMessageToSend; callWithMostMessages = index; } } - this.commitCall(callWithMostMessages); + if (callWithMostMessages === -1) { + /* There are no active calls, disable retries to force the next call that + * is started to be committed. */ + this.state = 'TRANSPARENT_ONLY'; + } else { + this.commitCall(callWithMostMessages); + } } private isStatusCodeInList(list: (Status | string)[], code: Status) { @@ -601,7 +610,11 @@ export class RetryingCall implements Call { } } else { this.commitCallWithMostMessages(); - const call = this.underlyingCalls[this.committedCallIndex!]; + // commitCallWithMostMessages can fail if we are between ping attempts + if (this.committedCallIndex === null) { + return; + } + const call = this.underlyingCalls[this.committedCallIndex]; bufferEntry.callback = context.callback; if (call.state === 'ACTIVE' && call.nextMessageToSend === messageIndex) { call.call.sendMessageWithContext({ From 3596c4f65518b1f0e8aae841b255a98e68dfe608 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 7 Feb 2023 14:52:20 -0800 Subject: [PATCH 417/450] grpc-js: Remove progress field in status from retrying call --- packages/grpc-js/src/retrying-call.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/src/retrying-call.ts b/packages/grpc-js/src/retrying-call.ts index 8daf5ba70..351678965 100644 --- a/packages/grpc-js/src/retrying-call.ts +++ b/packages/grpc-js/src/retrying-call.ts @@ -212,7 +212,12 @@ export class RetryingCall implements Call { } } process.nextTick(() => { - this.listener?.onReceiveStatus(statusObject); + // Explicitly construct status object to remove progress field + this.listener?.onReceiveStatus({ + code: statusObject.code, + details: statusObject.details, + metadata: statusObject.metadata + }); }); } From 18c803e6dd458b762fa5fe7361b4abc59d263382 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 8 Feb 2023 09:55:32 -0800 Subject: [PATCH 418/450] grpc-js: Export InterceptingListener and NextCall types --- packages/grpc-js/src/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/src/index.ts b/packages/grpc-js/src/index.ts index 786fa9925..51f394785 100644 --- a/packages/grpc-js/src/index.ts +++ b/packages/grpc-js/src/index.ts @@ -237,7 +237,7 @@ export const getClientChannel = (client: Client) => { export { StatusBuilder }; -export { Listener } from './call-interface'; +export { Listener, InterceptingListener } from './call-interface'; export { Requester, @@ -248,6 +248,7 @@ export { InterceptorProvider, InterceptingCall, InterceptorConfigurationError, + NextCall } from './client-interceptors'; export { From 37eb5ed2fabb4a3831f0a506bf44cd6e1ae3da5a Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 9 Feb 2023 10:18:24 -0800 Subject: [PATCH 419/450] grpc-js: Improve timeout handling and deadline logging --- packages/grpc-js/src/deadline.ts | 39 +++++++++++++++++++++++- packages/grpc-js/src/internal-channel.ts | 4 +-- packages/grpc-js/src/resolving-call.ts | 8 ++--- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/packages/grpc-js/src/deadline.ts b/packages/grpc-js/src/deadline.ts index 58ea0a805..be1f3c3b0 100644 --- a/packages/grpc-js/src/deadline.ts +++ b/packages/grpc-js/src/deadline.ts @@ -51,8 +51,45 @@ export function getDeadlineTimeoutString(deadline: Deadline) { throw new Error('Deadline is too far in the future') } +/** + * See https://nodejs.org/api/timers.html#settimeoutcallback-delay-args + * In particular, "When delay is larger than 2147483647 or less than 1, the + * delay will be set to 1. Non-integer delays are truncated to an integer." + * This number of milliseconds is almost 25 days. + */ +const MAX_TIMEOUT_TIME = 2147483647; + +/** + * Get the timeout value that should be passed to setTimeout now for the timer + * to end at the deadline. For any deadline before now, the timer should end + * immediately, represented by a value of 0. For any deadline more than + * MAX_TIMEOUT_TIME milliseconds in the future, a timer cannot be set that will + * end at that time, so it is treated as infinitely far in the future. + * @param deadline + * @returns + */ export function getRelativeTimeout(deadline: Deadline) { const deadlineMs = deadline instanceof Date ? deadline.getTime() : deadline; const now = new Date().getTime(); - return deadlineMs - now; + const timeout = deadlineMs - now; + if (timeout < 0) { + return 0; + } else if (timeout > MAX_TIMEOUT_TIME) { + return Infinity + } else { + return timeout; + } +} + +export function deadlineToString(deadline: Deadline): string { + if (deadline instanceof Date) { + return deadline.toISOString(); + } else { + const dateDeadline = new Date(deadline); + if (Number.isNaN(dateDeadline.getTime())) { + return '' + deadline; + } else { + return dateDeadline.toISOString(); + } + } } \ No newline at end of file diff --git a/packages/grpc-js/src/internal-channel.ts b/packages/grpc-js/src/internal-channel.ts index 9137be272..2a1d00f53 100644 --- a/packages/grpc-js/src/internal-channel.ts +++ b/packages/grpc-js/src/internal-channel.ts @@ -46,7 +46,7 @@ import { LoadBalancingCall } from './load-balancing-call'; import { CallCredentials } from './call-credentials'; import { Call, CallStreamOptions, InterceptingListener, MessageContext, StatusObject } from './call-interface'; import { SubchannelCall } from './subchannel-call'; -import { Deadline, getDeadlineTimeoutString } from './deadline'; +import { Deadline, deadlineToString, getDeadlineTimeoutString } from './deadline'; import { ResolvingCall } from './resolving-call'; import { getNextCallNumber } from './call-number'; import { restrictControlPlaneStatusCode } from './control-plane-status'; @@ -469,7 +469,7 @@ export class InternalChannel { '] method="' + method + '", deadline=' + - deadline + deadlineToString(deadline) ); const finalOptions: CallStreamOptions = { deadline: deadline, diff --git a/packages/grpc-js/src/resolving-call.ts b/packages/grpc-js/src/resolving-call.ts index f1fecd1d2..b6398126c 100644 --- a/packages/grpc-js/src/resolving-call.ts +++ b/packages/grpc-js/src/resolving-call.ts @@ -18,7 +18,7 @@ import { CallCredentials } from "./call-credentials"; import { Call, CallStreamOptions, InterceptingListener, MessageContext, StatusObject } from "./call-interface"; import { LogVerbosity, Propagate, Status } from "./constants"; -import { Deadline, getDeadlineTimeoutString, getRelativeTimeout, minDeadline } from "./deadline"; +import { Deadline, deadlineToString, getDeadlineTimeoutString, getRelativeTimeout, minDeadline } from "./deadline"; import { FilterStack, FilterStackFactory } from "./filter-stack"; import { InternalChannel } from "./internal-channel"; import { Metadata } from "./metadata"; @@ -79,9 +79,9 @@ export class ResolvingCall implements Call { private runDeadlineTimer() { clearTimeout(this.deadlineTimer); - this.trace('Deadline: ' + this.deadline); - if (this.deadline !== Infinity) { - const timeout = getRelativeTimeout(this.deadline); + 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( From 2ed8e71ba17052e3c36d37a04cbbe6a6c1f246a9 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 14 Feb 2023 13:47:50 -0800 Subject: [PATCH 420/450] grpc-js: Propagate keepalive throttling throughout channel --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/internal-channel.ts | 53 +++++++++++++++++-- .../src/load-balancer-outlier-detection.ts | 8 +-- packages/grpc-js/src/subchannel-interface.ts | 7 ++- packages/grpc-js/src/subchannel.ts | 22 +++++--- packages/grpc-js/src/transport.ts | 7 ++- 6 files changed, 81 insertions(+), 18 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 290d80b75..aafd2803a 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.8.8", + "version": "1.8.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", diff --git a/packages/grpc-js/src/internal-channel.ts b/packages/grpc-js/src/internal-channel.ts index 9137be272..8b4536ae5 100644 --- a/packages/grpc-js/src/internal-channel.ts +++ b/packages/grpc-js/src/internal-channel.ts @@ -51,6 +51,7 @@ import { ResolvingCall } from './resolving-call'; import { getNextCallNumber } from './call-number'; import { restrictControlPlaneStatusCode } from './control-plane-status'; import { MessageBufferTracker, RetryingCall, RetryThrottler } from './retrying-call'; +import { BaseSubchannelWrapper, ConnectivityStateListener, SubchannelInterface } from './subchannel-interface'; /** * See https://nodejs.org/api/timers.html#timers_setinterval_callback_delay_args @@ -84,6 +85,33 @@ const RETRY_THROTTLER_MAP: Map = new Map(); const DEFAULT_RETRY_BUFFER_SIZE_BYTES = 1<<24; // 16 MB const DEFAULT_PER_RPC_RETRY_BUFFER_SIZE_BYTES = 1<<20; // 1 MB +class ChannelSubchannelWrapper extends BaseSubchannelWrapper implements SubchannelInterface { + private stateListeners: ConnectivityStateListener[] = []; + private refCount = 0; + constructor(childSubchannel: SubchannelInterface, private channel: InternalChannel) { + super(childSubchannel); + childSubchannel.addConnectivityStateListener((subchannel, previousState, newState, keepaliveTime) => { + channel.throttleKeepalive(keepaliveTime); + for (const listener of this.stateListeners) { + listener(this, previousState, newState, keepaliveTime); + } + }); + } + + ref(): void { + this.child.ref(); + this.refCount += 1; + } + + unref(): void { + this.child.unref(); + this.refCount -= 1; + if (this.refCount <= 0) { + this.channel.removeWrappedSubchannel(this); + } + } +} + export class InternalChannel { private resolvingLoadBalancer: ResolvingLoadBalancer; @@ -116,8 +144,10 @@ export class InternalChannel { * configSelector becomes set or the channel state becomes anything other * than TRANSIENT_FAILURE. */ - private currentResolutionError: StatusObject | null = null; - private retryBufferTracker: MessageBufferTracker; + private currentResolutionError: StatusObject | null = null; + private retryBufferTracker: MessageBufferTracker; + private keepaliveTime: number; + private wrappedSubchannels: Set = new Set(); // Channelz info private readonly channelzEnabled: boolean = true; @@ -190,6 +220,7 @@ export class InternalChannel { options['grpc.retry_buffer_size'] ?? DEFAULT_RETRY_BUFFER_SIZE_BYTES, options['grpc.per_rpc_retry_buffer_size'] ?? DEFAULT_PER_RPC_RETRY_BUFFER_SIZE_BYTES ); + this.keepaliveTime = options['grpc.keepalive_time_ms'] ?? -1; const channelControlHelper: ChannelControlHelper = { createSubchannel: ( subchannelAddress: SubchannelAddress, @@ -201,10 +232,13 @@ export class InternalChannel { Object.assign({}, this.options, subchannelArgs), this.credentials ); + subchannel.throttleKeepalive(this.keepaliveTime); if (this.channelzEnabled) { this.channelzTrace.addTrace('CT_INFO', 'Created subchannel or used existing subchannel', subchannel.getChannelzRef()); } - return subchannel; + const wrappedSubchannel = new ChannelSubchannelWrapper(subchannel, this); + this.wrappedSubchannels.add(wrappedSubchannel); + return wrappedSubchannel; }, updateState: (connectivityState: ConnectivityState, picker: Picker) => { this.currentPicker = picker; @@ -369,6 +403,19 @@ export class InternalChannel { } } + throttleKeepalive(newKeepaliveTime: number) { + if (newKeepaliveTime > this.keepaliveTime) { + this.keepaliveTime = newKeepaliveTime; + for (const wrappedSubchannel of this.wrappedSubchannels) { + wrappedSubchannel.throttleKeepalive(newKeepaliveTime); + } + } + } + + removeWrappedSubchannel(wrappedSubchannel: ChannelSubchannelWrapper) { + this.wrappedSubchannels.delete(wrappedSubchannel); + } + doPick(metadata: Metadata, extraPickInfo: {[key: string]: string}) { return this.currentPicker.pick({metadata: metadata, extraPickInfo: extraPickInfo}); } diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index cdf580523..2f72a9625 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -205,11 +205,11 @@ class OutlierDetectionSubchannelWrapper extends BaseSubchannelWrapper implements constructor(childSubchannel: SubchannelInterface, private mapEntry?: MapEntry) { super(childSubchannel); this.childSubchannelState = childSubchannel.getConnectivityState(); - childSubchannel.addConnectivityStateListener((subchannel, previousState, newState) => { + childSubchannel.addConnectivityStateListener((subchannel, previousState, newState, keepaliveTime) => { this.childSubchannelState = newState; if (!this.ejected) { for (const listener of this.stateListeners) { - listener(this, previousState, newState); + listener(this, previousState, newState, keepaliveTime); } } }); @@ -265,14 +265,14 @@ class OutlierDetectionSubchannelWrapper extends BaseSubchannelWrapper implements eject() { this.ejected = true; for (const listener of this.stateListeners) { - listener(this, this.childSubchannelState, ConnectivityState.TRANSIENT_FAILURE); + listener(this, this.childSubchannelState, ConnectivityState.TRANSIENT_FAILURE, -1); } } uneject() { this.ejected = false; for (const listener of this.stateListeners) { - listener(this, ConnectivityState.TRANSIENT_FAILURE, this.childSubchannelState); + listener(this, ConnectivityState.TRANSIENT_FAILURE, this.childSubchannelState, -1); } } diff --git a/packages/grpc-js/src/subchannel-interface.ts b/packages/grpc-js/src/subchannel-interface.ts index 082a8b3c0..165ebc3e1 100644 --- a/packages/grpc-js/src/subchannel-interface.ts +++ b/packages/grpc-js/src/subchannel-interface.ts @@ -22,7 +22,8 @@ import { Subchannel } from "./subchannel"; export type ConnectivityStateListener = ( subchannel: SubchannelInterface, previousState: ConnectivityState, - newState: ConnectivityState + newState: ConnectivityState, + keepaliveTime: number ) => void; /** @@ -40,6 +41,7 @@ export interface SubchannelInterface { removeConnectivityStateListener(listener: ConnectivityStateListener): void; startConnecting(): void; getAddress(): string; + throttleKeepalive(newKeepaliveTime: number): void; ref(): void; unref(): void; getChannelzRef(): SubchannelRef; @@ -67,6 +69,9 @@ export abstract class BaseSubchannelWrapper implements SubchannelInterface { getAddress(): string { return this.child.getAddress(); } + throttleKeepalive(newKeepaliveTime: number): void { + this.child.throttleKeepalive(newKeepaliveTime); + } ref(): void { this.child.ref(); } diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index b4876f178..c93e0c451 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -64,7 +64,7 @@ export class Subchannel { private backoffTimeout: BackoffTimeout; - private keepaliveTimeMultiplier = 1; + private keepaliveTime: number; /** * Tracks channels and subchannel pools with references to this subchannel */ @@ -111,6 +111,8 @@ export class Subchannel { }, backoffOptions); this.subchannelAddressString = subchannelAddressToString(subchannelAddress); + this.keepaliveTime = options['grpc.keepalive_time_ms'] ?? -1; + if (options['grpc.enable_channelz'] === 0) { this.channelzEnabled = false; } @@ -169,7 +171,7 @@ export class Subchannel { private startConnectingInternal() { let options = this.options; if (options['grpc.keepalive_time_ms']) { - const adjustedKeepaliveTime = Math.min(options['grpc.keepalive_time_ms'] * this.keepaliveTimeMultiplier, KEEPALIVE_MAX_TIME_MS); + const adjustedKeepaliveTime = Math.min(this.keepaliveTime, KEEPALIVE_MAX_TIME_MS); options = {...options, 'grpc.keepalive_time_ms': adjustedKeepaliveTime}; } this.connector.connect(this.subchannelAddress, this.credentials, options).then( @@ -181,14 +183,14 @@ export class Subchannel { } transport.addDisconnectListener((tooManyPings) => { this.transitionToState([ConnectivityState.READY], ConnectivityState.IDLE); - if (tooManyPings) { - this.keepaliveTimeMultiplier *= 2; + if (tooManyPings && this.keepaliveTime > 0) { + this.keepaliveTime *= 2; logging.log( LogVerbosity.ERROR, `Connection to ${uriToString(this.channelTarget)} at ${ this.subchannelAddressString - } rejected by server because of excess pings. Increasing ping interval multiplier to ${ - this.keepaliveTimeMultiplier + } rejected by server because of excess pings. Increasing ping interval to ${ + this.keepaliveTime } ms` ); } @@ -262,7 +264,7 @@ export class Subchannel { /* We use a shallow copy of the stateListeners array in case a listener * is removed during this iteration */ for (const listener of [...this.stateListeners]) { - listener(this, previousState, newState); + listener(this, previousState, newState, this.keepaliveTime); } return true; } @@ -403,4 +405,10 @@ export class Subchannel { getRealSubchannel(): this { return this; } + + throttleKeepalive(newKeepaliveTime: number) { + if (newKeepaliveTime > this.keepaliveTime) { + this.keepaliveTime = newKeepaliveTime; + } + } } diff --git a/packages/grpc-js/src/transport.ts b/packages/grpc-js/src/transport.ts index a9308471b..3c9163d13 100644 --- a/packages/grpc-js/src/transport.ts +++ b/packages/grpc-js/src/transport.ts @@ -77,7 +77,7 @@ class Http2Transport implements Transport { /** * The amount of time in between sending pings */ - private keepaliveTimeMs: number = KEEPALIVE_MAX_TIME_MS; + private keepaliveTimeMs: number = -1; /** * The amount of time to wait for an acknowledgement after sending a ping */ @@ -133,7 +133,7 @@ class Http2Transport implements Transport { ] .filter((e) => e) .join(' '); // remove falsey values first - + if ('grpc.keepalive_time_ms' in options) { this.keepaliveTimeMs = options['grpc.keepalive_time_ms']!; } @@ -334,6 +334,9 @@ class Http2Transport implements Transport { } private startKeepalivePings() { + if (this.keepaliveTimeMs < 0) { + return; + } this.keepaliveIntervalId = setInterval(() => { this.sendPing(); }, this.keepaliveTimeMs); From 6862af2350cceed9b39ebda1b03020c9353ec03e Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 21 Feb 2023 15:26:09 -0800 Subject: [PATCH 421/450] grpc-js: Fix bugs in pick first LB policy and channel subchannel wrapper --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/internal-channel.ts | 11 +++++------ packages/grpc-js/src/load-balancer-pick-first.ts | 5 +++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index aafd2803a..0ae2d6742 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.8.9", + "version": "1.8.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", diff --git a/packages/grpc-js/src/internal-channel.ts b/packages/grpc-js/src/internal-channel.ts index 4f4c879fc..14038bd3f 100644 --- a/packages/grpc-js/src/internal-channel.ts +++ b/packages/grpc-js/src/internal-channel.ts @@ -86,16 +86,14 @@ const DEFAULT_RETRY_BUFFER_SIZE_BYTES = 1<<24; // 16 MB const DEFAULT_PER_RPC_RETRY_BUFFER_SIZE_BYTES = 1<<20; // 1 MB class ChannelSubchannelWrapper extends BaseSubchannelWrapper implements SubchannelInterface { - private stateListeners: ConnectivityStateListener[] = []; private refCount = 0; + private subchannelStateListener: ConnectivityStateListener; constructor(childSubchannel: SubchannelInterface, private channel: InternalChannel) { super(childSubchannel); - childSubchannel.addConnectivityStateListener((subchannel, previousState, newState, keepaliveTime) => { + this.subchannelStateListener = (subchannel, previousState, newState, keepaliveTime) => { channel.throttleKeepalive(keepaliveTime); - for (const listener of this.stateListeners) { - listener(this, previousState, newState, keepaliveTime); - } - }); + }; + childSubchannel.addConnectivityStateListener(this.subchannelStateListener); } ref(): void { @@ -107,6 +105,7 @@ class ChannelSubchannelWrapper extends BaseSubchannelWrapper implements Subchann this.child.unref(); this.refCount -= 1; if (this.refCount <= 0) { + this.child.removeConnectivityStateListener(this.subchannelStateListener); this.channel.removeWrappedSubchannel(this); } } diff --git a/packages/grpc-js/src/load-balancer-pick-first.ts b/packages/grpc-js/src/load-balancer-pick-first.ts index 027eae074..1f6530e44 100644 --- a/packages/grpc-js/src/load-balancer-pick-first.ts +++ b/packages/grpc-js/src/load-balancer-pick-first.ts @@ -33,6 +33,7 @@ import { } from './picker'; import { SubchannelAddress, + subchannelAddressEqual, subchannelAddressToString, } from './subchannel-address'; import * as logging from './logging'; @@ -168,7 +169,7 @@ export class PickFirstLoadBalancer implements LoadBalancer { * connecting to the next one instead of waiting for the connection * delay timer. */ if ( - subchannel === this.subchannels[this.currentSubchannelIndex] && + subchannel.getRealSubchannel() === this.subchannels[this.currentSubchannelIndex].getRealSubchannel() && newState === ConnectivityState.TRANSIENT_FAILURE ) { this.startNextSubchannelConnecting(); @@ -420,7 +421,7 @@ export class PickFirstLoadBalancer implements LoadBalancer { if ( this.subchannels.length === 0 || !this.latestAddressList.every( - (value, index) => addressList[index] === value + (value, index) => subchannelAddressEqual(addressList[index], value) ) ) { this.latestAddressList = addressList; From 1f14d1c138b9e6297ee097264185b24498f3059b Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 23 Feb 2023 17:49:03 -0800 Subject: [PATCH 422/450] grpc-js: Stop leaking freed message buffer placeholder objects --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/retrying-call.ts | 61 +++++++++++++++------------ 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 0ae2d6742..f75f780db 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.8.10", + "version": "1.8.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", diff --git a/packages/grpc-js/src/retrying-call.ts b/packages/grpc-js/src/retrying-call.ts index a9424373e..5ae585b9e 100644 --- a/packages/grpc-js/src/retrying-call.ts +++ b/packages/grpc-js/src/retrying-call.ts @@ -151,6 +151,12 @@ export class RetryingCall implements Call { private initialMetadata: Metadata | null = null; private underlyingCalls: UnderlyingCall[] = []; private writeBuffer: WriteBufferEntry[] = []; + /** + * The offset of message indices in the writeBuffer. For example, if + * writeBufferOffset is 10, message 10 is in writeBuffer[0] and message 15 + * is in writeBuffer[5]. + */ + private writeBufferOffset = 0; /** * Tracks whether a read has been started, so that we know whether to start * reads on new child calls. This only matters for the first read, because @@ -203,14 +209,8 @@ export class RetryingCall implements Call { private reportStatus(statusObject: StatusObject) { this.trace('ended with status: code=' + statusObject.code + ' details="' + statusObject.details + '"'); this.bufferTracker.freeAll(this.callNumber); - for (let i = 0; i < this.writeBuffer.length; i++) { - if (this.writeBuffer[i].entryType === 'MESSAGE') { - this.writeBuffer[i] = { - entryType: 'FREED', - allocated: false - }; - } - } + this.writeBufferOffset = this.writeBufferOffset + this.writeBuffer.length; + this.writeBuffer = []; process.nextTick(() => { // Explicitly construct status object to remove progress field this.listener?.onReceiveStatus({ @@ -236,20 +236,27 @@ export class RetryingCall implements Call { } } - private maybefreeMessageBufferEntry(messageIndex: number) { + private getBufferEntry(messageIndex: number): WriteBufferEntry { + return this.writeBuffer[messageIndex - this.writeBufferOffset] ?? {entryType: 'FREED', allocated: false}; + } + + private getNextBufferIndex() { + return this.writeBufferOffset + this.writeBuffer.length; + } + + private clearSentMessages() { if (this.state !== 'COMMITTED') { return; } - const bufferEntry = this.writeBuffer[messageIndex]; - if (bufferEntry.entryType === 'MESSAGE') { + const earliestNeededMessageIndex = this.underlyingCalls[this.committedCallIndex!].nextMessageToSend; + for (let messageIndex = this.writeBufferOffset; messageIndex < earliestNeededMessageIndex; messageIndex++) { + const bufferEntry = this.getBufferEntry(messageIndex); if (bufferEntry.allocated) { this.bufferTracker.free(bufferEntry.message!.message.length, this.callNumber); } - this.writeBuffer[messageIndex] = { - entryType: 'FREED', - allocated: false - }; } + this.writeBuffer = this.writeBuffer.slice(earliestNeededMessageIndex - this.writeBufferOffset); + this.writeBufferOffset = earliestNeededMessageIndex; } private commitCall(index: number) { @@ -272,9 +279,7 @@ export class RetryingCall implements Call { this.underlyingCalls[i].state = 'COMPLETED'; this.underlyingCalls[i].call.cancelWithStatus(Status.CANCELLED, 'Discarded in favor of other hedged attempt'); } - for (let messageIndex = 0; messageIndex < this.underlyingCalls[index].nextMessageToSend - 1; messageIndex += 1) { - this.maybefreeMessageBufferEntry(messageIndex); - } + this.clearSentMessages(); } private commitCallWithMostMessages() { @@ -555,8 +560,8 @@ export class RetryingCall implements Call { private handleChildWriteCompleted(childIndex: number) { const childCall = this.underlyingCalls[childIndex]; const messageIndex = childCall.nextMessageToSend; - this.writeBuffer[messageIndex].callback?.(); - this.maybefreeMessageBufferEntry(messageIndex); + this.getBufferEntry(messageIndex).callback?.(); + this.clearSentMessages(); childCall.nextMessageToSend += 1; this.sendNextChildMessage(childIndex); } @@ -566,10 +571,10 @@ export class RetryingCall implements Call { if (childCall.state === 'COMPLETED') { return; } - if (this.writeBuffer[childCall.nextMessageToSend]) { - const bufferEntry = this.writeBuffer[childCall.nextMessageToSend]; + if (this.getBufferEntry(childCall.nextMessageToSend)) { + const bufferEntry = this.getBufferEntry(childCall.nextMessageToSend); switch (bufferEntry.entryType) { - case 'MESSAGE': + case 'MESSAGE': childCall.call.sendMessageWithContext({ callback: (error) => { // Ignore error @@ -594,13 +599,13 @@ export class RetryingCall implements Call { message, flags: context.flags, }; - const messageIndex = this.writeBuffer.length; + const messageIndex = this.getNextBufferIndex(); const bufferEntry: WriteBufferEntry = { entryType: 'MESSAGE', message: writeObj, allocated: this.bufferTracker.allocate(message.length, this.callNumber) }; - this.writeBuffer[messageIndex] = bufferEntry; + this.writeBuffer.push(bufferEntry); if (bufferEntry.allocated) { context.callback?.(); for (const [callIndex, call] of this.underlyingCalls.entries()) { @@ -642,11 +647,11 @@ export class RetryingCall implements Call { } halfClose(): void { this.trace('halfClose called'); - const halfCloseIndex = this.writeBuffer.length; - this.writeBuffer[halfCloseIndex] = { + const halfCloseIndex = this.getNextBufferIndex(); + this.writeBuffer.push({ entryType: 'HALF_CLOSE', allocated: false - }; + }); for (const call of this.underlyingCalls) { if (call?.state === 'ACTIVE' && call.nextMessageToSend === halfCloseIndex) { call.nextMessageToSend += 1; From 0726fdf290116faaae9c1aea36c30061983c284d Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 6 Mar 2023 10:11:46 -0800 Subject: [PATCH 423/450] grpc-js: Fix address equality check in pick-first --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/load-balancer-pick-first.ts | 3 ++- packages/grpc-js/src/subchannel-address.ts | 10 ++++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index f75f780db..722f9d866 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.8.11", + "version": "1.8.12", "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/load-balancer-pick-first.ts b/packages/grpc-js/src/load-balancer-pick-first.ts index 1f6530e44..a501b1f7d 100644 --- a/packages/grpc-js/src/load-balancer-pick-first.ts +++ b/packages/grpc-js/src/load-balancer-pick-first.ts @@ -420,8 +420,9 @@ export class PickFirstLoadBalancer implements LoadBalancer { * address list is different from the existing one */ if ( this.subchannels.length === 0 || + this.latestAddressList.length !== addressList.length || !this.latestAddressList.every( - (value, index) => subchannelAddressEqual(addressList[index], value) + (value, index) => addressList[index] && subchannelAddressEqual(addressList[index], value) ) ) { this.latestAddressList = addressList; diff --git a/packages/grpc-js/src/subchannel-address.ts b/packages/grpc-js/src/subchannel-address.ts index 29022caa5..e542e645e 100644 --- a/packages/grpc-js/src/subchannel-address.ts +++ b/packages/grpc-js/src/subchannel-address.ts @@ -41,9 +41,15 @@ export function isTcpSubchannelAddress( } export function subchannelAddressEqual( - address1: SubchannelAddress, - address2: SubchannelAddress + address1?: SubchannelAddress, + address2?: SubchannelAddress ): boolean { + if (!address1 && !address2) { + return true; + } + if (!address1 || !address2) { + return false; + } if (isTcpSubchannelAddress(address1)) { return ( isTcpSubchannelAddress(address2) && From c23c67cd4fa4b327503b5247584ed96d078a7a97 Mon Sep 17 00:00:00 2001 From: Ulrich Van Den Hekke Date: Sun, 26 Feb 2023 13:14:32 +0100 Subject: [PATCH 424/450] grpc-js: add await/async on method that return promise add await/async on method that return promise to ensure that the order of message (and of the end of stream) are preserved --- packages/grpc-js/src/server-call.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/grpc-js/src/server-call.ts b/packages/grpc-js/src/server-call.ts index 8dcf6be33..48186bc29 100644 --- a/packages/grpc-js/src/server-call.ts +++ b/packages/grpc-js/src/server-call.ts @@ -812,10 +812,10 @@ export class Http2ServerCallStream< let pushedEnd = false; - const maybePushEnd = () => { + const maybePushEnd = async () => { if (!pushedEnd && readsDone && !pendingMessageProcessing) { pushedEnd = true; - this.pushOrBufferMessage(readable, null); + await this.pushOrBufferMessage(readable, null); } }; @@ -848,16 +848,16 @@ export class Http2ServerCallStream< // Just return early if (!decompressedMessage) return; - this.pushOrBufferMessage(readable, decompressedMessage); + await this.pushOrBufferMessage(readable, decompressedMessage); } pendingMessageProcessing = false; this.stream.resume(); - maybePushEnd(); + await maybePushEnd(); }); - this.stream.once('end', () => { + this.stream.once('end', async () => { readsDone = true; - maybePushEnd(); + await maybePushEnd(); }); } @@ -881,16 +881,16 @@ export class Http2ServerCallStream< return this.canPush; } - private pushOrBufferMessage( + private async pushOrBufferMessage( readable: | ServerReadableStream | ServerDuplexStream, messageBytes: Buffer | null - ): void { + ): Promise { if (this.isPushPending) { this.bufferedMessages.push(messageBytes); } else { - this.pushMessage(readable, messageBytes); + await this.pushMessage(readable, messageBytes); } } @@ -943,7 +943,7 @@ export class Http2ServerCallStream< this.isPushPending = false; if (this.bufferedMessages.length > 0) { - this.pushMessage( + await this.pushMessage( readable, this.bufferedMessages.shift() as Buffer | null ); From c525025f06647d022d5201a08fc179eff1b6bcc1 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 6 Mar 2023 15:10:29 -0800 Subject: [PATCH 425/450] grpc-js: Trace before call to LB policy picker --- packages/grpc-js/src/load-balancing-call.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/grpc-js/src/load-balancing-call.ts b/packages/grpc-js/src/load-balancing-call.ts index 48aaf48ac..f74933983 100644 --- a/packages/grpc-js/src/load-balancing-call.ts +++ b/packages/grpc-js/src/load-balancing-call.ts @@ -102,6 +102,7 @@ export class LoadBalancingCall implements Call { if (!this.metadata) { throw new Error('doPick called before start'); } + this.trace('Pick called') const pickResult = this.channel.doPick(this.metadata, this.callConfig.pickInformation); const subchannelString = pickResult.subchannel ? '(' + pickResult.subchannel.getChannelzRef().id + ') ' + pickResult.subchannel.getAddress() : From 79161816e6b76d5fea787d8329f038d00fb156c5 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 7 Mar 2023 14:58:58 -0800 Subject: [PATCH 426/450] grpc-js: Add more logging to trace handling of received messages --- packages/grpc-js/src/resolving-call.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/grpc-js/src/resolving-call.ts b/packages/grpc-js/src/resolving-call.ts index b6398126c..f29fb7fd7 100644 --- a/packages/grpc-js/src/resolving-call.ts +++ b/packages/grpc-js/src/resolving-call.ts @@ -178,13 +178,17 @@ export class ResolvingCall implements Call { this.filterStack = this.filterStackFactory.createFilter(); this.filterStack.sendMetadata(Promise.resolve(this.metadata)).then(filteredMetadata => { this.child = this.channel.createInnerCall(config, this.method, this.host, this.credentials, this.deadline); + this.trace('Created child [' + this.child.getCallNumber() + ']') this.child.start(filteredMetadata, { onReceiveMetadata: metadata => { + this.trace('Received metadata') this.listener!.onReceiveMetadata(this.filterStack!.receiveMetadata(metadata)); }, onReceiveMessage: message => { + this.trace('Received message'); this.readFilterPending = true; this.filterStack!.receiveMessage(message).then(filteredMesssage => { + this.trace('Finished filtering received message'); this.readFilterPending = false; this.listener!.onReceiveMessage(filteredMesssage); if (this.pendingChildStatus) { @@ -195,6 +199,7 @@ export class ResolvingCall implements Call { }); }, onReceiveStatus: status => { + this.trace('Received status'); if (this.readFilterPending) { this.pendingChildStatus = status; } else { From 481f704c775d78de363a7311a28b087c124c97c0 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 9 Mar 2023 16:37:04 -0800 Subject: [PATCH 427/450] grpc-js-xds: Populate Node message field user_agent_version --- packages/grpc-js-xds/package.json | 2 +- packages/grpc-js-xds/src/xds-client.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index c0c3200f5..0d8080f96 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.8.0", + "version": "1.8.1", "description": "Plugin for @grpc/grpc-js. Adds the xds:// URL scheme and associated features.", "main": "build/src/index.js", "scripts": { diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index 2dfa41236..bd4bd84cb 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -334,11 +334,13 @@ export class XdsClient { this.adsNode = { ...bootstrapInfo.node, user_agent_name: userAgentName, + user_agent_version: clientVersion, client_features: ['envoy.lb.does_not_support_overprovisioning'], }; this.lrsNode = { ...bootstrapInfo.node, user_agent_name: userAgentName, + user_agent_version: clientVersion, client_features: ['envoy.lrs.supports_send_all_clusters'], }; setCsdsClientNode(this.adsNode); From 6bc6b8665bef8e158121fc5ce5608dd2da748bb1 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 25 Jan 2023 09:50:49 -0800 Subject: [PATCH 428/450] grpc-js-xds: Add unit test framework --- packages/grpc-js-xds/package.json | 3 +- .../grpc-js-xds/proto/grpc/testing/echo.proto | 70 ++++ .../proto/grpc/testing/echo_messages.proto | 74 ++++ .../proto/grpc/testing/simple_messages.proto | 26 ++ .../testing/xds/v3/orca_load_report.proto | 44 +++ packages/grpc-js-xds/test/backend.ts | 105 ++++++ packages/grpc-js-xds/test/client.ts | 72 ++++ packages/grpc-js-xds/test/framework.ts | 208 +++++++++++ packages/grpc-js-xds/test/generated/echo.ts | 46 +++ .../test/generated/grpc/testing/DebugInfo.ts | 18 + .../generated/grpc/testing/EchoRequest.ts | 13 + .../generated/grpc/testing/EchoResponse.ts | 13 + .../grpc/testing/EchoTest1Service.ts | 117 ++++++ .../grpc/testing/EchoTest2Service.ts | 117 ++++++ .../generated/grpc/testing/EchoTestService.ts | 150 ++++++++ .../generated/grpc/testing/ErrorStatus.ts | 20 + .../generated/grpc/testing/NoRpcService.ts | 19 + .../generated/grpc/testing/RequestParams.ts | 75 ++++ .../generated/grpc/testing/ResponseParams.ts | 15 + .../generated/grpc/testing/SimpleRequest.ts | 8 + .../generated/grpc/testing/SimpleResponse.ts | 8 + .../generated/grpc/testing/StringValue.ts | 10 + .../grpc/testing/UnimplementedEchoService.ts | 27 ++ .../xds/data/orca/v3/OrcaLoadReport.ts | 59 +++ packages/grpc-js-xds/test/test-core.ts | 63 ++++ packages/grpc-js-xds/test/xds-server.ts | 342 ++++++++++++++++++ 26 files changed, 1721 insertions(+), 1 deletion(-) create mode 100644 packages/grpc-js-xds/proto/grpc/testing/echo.proto create mode 100644 packages/grpc-js-xds/proto/grpc/testing/echo_messages.proto create mode 100644 packages/grpc-js-xds/proto/grpc/testing/simple_messages.proto create mode 100644 packages/grpc-js-xds/proto/grpc/testing/xds/v3/orca_load_report.proto create mode 100644 packages/grpc-js-xds/test/backend.ts create mode 100644 packages/grpc-js-xds/test/client.ts create mode 100644 packages/grpc-js-xds/test/framework.ts create mode 100644 packages/grpc-js-xds/test/generated/echo.ts create mode 100644 packages/grpc-js-xds/test/generated/grpc/testing/DebugInfo.ts create mode 100644 packages/grpc-js-xds/test/generated/grpc/testing/EchoRequest.ts create mode 100644 packages/grpc-js-xds/test/generated/grpc/testing/EchoResponse.ts create mode 100644 packages/grpc-js-xds/test/generated/grpc/testing/EchoTest1Service.ts create mode 100644 packages/grpc-js-xds/test/generated/grpc/testing/EchoTest2Service.ts create mode 100644 packages/grpc-js-xds/test/generated/grpc/testing/EchoTestService.ts create mode 100644 packages/grpc-js-xds/test/generated/grpc/testing/ErrorStatus.ts create mode 100644 packages/grpc-js-xds/test/generated/grpc/testing/NoRpcService.ts create mode 100644 packages/grpc-js-xds/test/generated/grpc/testing/RequestParams.ts create mode 100644 packages/grpc-js-xds/test/generated/grpc/testing/ResponseParams.ts create mode 100644 packages/grpc-js-xds/test/generated/grpc/testing/SimpleRequest.ts create mode 100644 packages/grpc-js-xds/test/generated/grpc/testing/SimpleResponse.ts create mode 100644 packages/grpc-js-xds/test/generated/grpc/testing/StringValue.ts create mode 100644 packages/grpc-js-xds/test/generated/grpc/testing/UnimplementedEchoService.ts create mode 100644 packages/grpc-js-xds/test/generated/xds/data/orca/v3/OrcaLoadReport.ts create mode 100644 packages/grpc-js-xds/test/test-core.ts create mode 100644 packages/grpc-js-xds/test/xds-server.ts diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index c0c3200f5..bd1511e5a 100644 --- a/packages/grpc-js-xds/package.json +++ b/packages/grpc-js-xds/package.json @@ -13,7 +13,8 @@ "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", - "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-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" }, "repository": { "type": "git", diff --git a/packages/grpc-js-xds/proto/grpc/testing/echo.proto b/packages/grpc-js-xds/proto/grpc/testing/echo.proto new file mode 100644 index 000000000..7f444b43f --- /dev/null +++ b/packages/grpc-js-xds/proto/grpc/testing/echo.proto @@ -0,0 +1,70 @@ + +// Copyright 2015 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. + +syntax = "proto3"; + +package grpc.testing; + +import "grpc/testing/echo_messages.proto"; +import "grpc/testing/simple_messages.proto"; + +service EchoTestService { + rpc Echo(EchoRequest) returns (EchoResponse); + rpc Echo1(EchoRequest) returns (EchoResponse); + rpc Echo2(EchoRequest) returns (EchoResponse); + rpc CheckDeadlineUpperBound(SimpleRequest) returns (StringValue); + rpc CheckDeadlineSet(SimpleRequest) returns (StringValue); + // A service which checks that the initial metadata sent over contains some + // expected key value pair + rpc CheckClientInitialMetadata(SimpleRequest) returns (SimpleResponse); + rpc RequestStream(stream EchoRequest) returns (EchoResponse); + rpc ResponseStream(EchoRequest) returns (stream EchoResponse); + rpc BidiStream(stream EchoRequest) returns (stream EchoResponse); + rpc Unimplemented(EchoRequest) returns (EchoResponse); + rpc UnimplementedBidi(stream EchoRequest) returns (stream EchoResponse); +} + +service EchoTest1Service { + rpc Echo(EchoRequest) returns (EchoResponse); + rpc Echo1(EchoRequest) returns (EchoResponse); + rpc Echo2(EchoRequest) returns (EchoResponse); + // A service which checks that the initial metadata sent over contains some + // expected key value pair + rpc CheckClientInitialMetadata(SimpleRequest) returns (SimpleResponse); + rpc RequestStream(stream EchoRequest) returns (EchoResponse); + rpc ResponseStream(EchoRequest) returns (stream EchoResponse); + rpc BidiStream(stream EchoRequest) returns (stream EchoResponse); + rpc Unimplemented(EchoRequest) returns (EchoResponse); +} + +service EchoTest2Service { + rpc Echo(EchoRequest) returns (EchoResponse); + rpc Echo1(EchoRequest) returns (EchoResponse); + rpc Echo2(EchoRequest) returns (EchoResponse); + // A service which checks that the initial metadata sent over contains some + // expected key value pair + rpc CheckClientInitialMetadata(SimpleRequest) returns (SimpleResponse); + rpc RequestStream(stream EchoRequest) returns (EchoResponse); + rpc ResponseStream(EchoRequest) returns (stream EchoResponse); + rpc BidiStream(stream EchoRequest) returns (stream EchoResponse); + rpc Unimplemented(EchoRequest) returns (EchoResponse); +} + +service UnimplementedEchoService { + rpc Unimplemented(EchoRequest) returns (EchoResponse); +} + +// A service without any rpc defined to test coverage. +service NoRpcService {} diff --git a/packages/grpc-js-xds/proto/grpc/testing/echo_messages.proto b/packages/grpc-js-xds/proto/grpc/testing/echo_messages.proto new file mode 100644 index 000000000..44f22133e --- /dev/null +++ b/packages/grpc-js-xds/proto/grpc/testing/echo_messages.proto @@ -0,0 +1,74 @@ + +// Copyright 2015 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. + +syntax = "proto3"; + +package grpc.testing; + +option cc_enable_arenas = true; + +import "grpc/testing/xds/v3/orca_load_report.proto"; + +// Message to be echoed back serialized in trailer. +message DebugInfo { + repeated string stack_entries = 1; + string detail = 2; +} + +// Error status client expects to see. +message ErrorStatus { + int32 code = 1; + string error_message = 2; + string binary_error_details = 3; +} + +message RequestParams { + bool echo_deadline = 1; + int32 client_cancel_after_us = 2; + int32 server_cancel_after_us = 3; + bool echo_metadata = 4; + bool check_auth_context = 5; + int32 response_message_length = 6; + bool echo_peer = 7; + string expected_client_identity = 8; // will force check_auth_context. + bool skip_cancelled_check = 9; + string expected_transport_security_type = 10; + DebugInfo debug_info = 11; + bool server_die = 12; // Server should not see a request with this set. + string binary_error_details = 13; + ErrorStatus expected_error = 14; + int32 server_sleep_us = 15; // sleep when invoking server for deadline tests + int32 backend_channel_idx = 16; // which backend to send request to + bool echo_metadata_initially = 17; + bool server_notify_client_when_started = 18; + xds.data.orca.v3.OrcaLoadReport backend_metrics = 19; + bool echo_host_from_authority_header = 20; +} + +message EchoRequest { + string message = 1; + RequestParams param = 2; +} + +message ResponseParams { + int64 request_deadline = 1; + string host = 2; + string peer = 3; +} + +message EchoResponse { + string message = 1; + ResponseParams param = 2; +} diff --git a/packages/grpc-js-xds/proto/grpc/testing/simple_messages.proto b/packages/grpc-js-xds/proto/grpc/testing/simple_messages.proto new file mode 100644 index 000000000..3afe236b4 --- /dev/null +++ b/packages/grpc-js-xds/proto/grpc/testing/simple_messages.proto @@ -0,0 +1,26 @@ + +// Copyright 2018 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. + +syntax = "proto3"; + +package grpc.testing; + +message SimpleRequest {} + +message SimpleResponse {} + +message StringValue { + string message = 1; +} diff --git a/packages/grpc-js-xds/proto/grpc/testing/xds/v3/orca_load_report.proto b/packages/grpc-js-xds/proto/grpc/testing/xds/v3/orca_load_report.proto new file mode 100644 index 000000000..033e64ba4 --- /dev/null +++ b/packages/grpc-js-xds/proto/grpc/testing/xds/v3/orca_load_report.proto @@ -0,0 +1,44 @@ +// Copyright 2020 The 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. + +// Local copy of Envoy xDS proto file, used for testing only. + +syntax = "proto3"; + +package xds.data.orca.v3; + +// See section `ORCA load report format` of the design document in +// :ref:`https://github.com/envoyproxy/envoy/issues/6614`. + +message OrcaLoadReport { + // CPU utilization expressed as a fraction of available CPU resources. This + // should be derived from the latest sample or measurement. + double cpu_utilization = 1; + + // Memory utilization expressed as a fraction of available memory + // resources. This should be derived from the latest sample or measurement. + double mem_utilization = 2; + + // Total RPS being served by an endpoint. This should cover all services that an endpoint is + // responsible for. + uint64 rps = 3; + + // Application specific requests costs. Each value is an absolute cost (e.g. 3487 bytes of + // storage) associated with the request. + map request_cost = 4; + + // Resource utilization values. Each value is expressed as a fraction of total resources + // available, derived from the latest sample or measurement. + map utilization = 5; +} diff --git a/packages/grpc-js-xds/test/backend.ts b/packages/grpc-js-xds/test/backend.ts new file mode 100644 index 000000000..ce509c556 --- /dev/null +++ b/packages/grpc-js-xds/test/backend.ts @@ -0,0 +1,105 @@ +/* + * Copyright 2023 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 { loadPackageDefinition, sendUnaryData, Server, ServerCredentials, ServerUnaryCall, UntypedServiceImplementation } from "@grpc/grpc-js"; +import { loadSync } from "@grpc/proto-loader"; +import { ProtoGrpcType } from "./generated/echo"; +import { EchoRequest__Output } from "./generated/grpc/testing/EchoRequest"; +import { EchoResponse } from "./generated/grpc/testing/EchoResponse"; + +const loadedProtos = loadPackageDefinition(loadSync( + [ + 'grpc/testing/echo.proto' + ], + { + keepCase: true, + longs: String, + enums: String, + defaults: true, + oneofs: true, + json: true, + includeDirs: [ + // Paths are relative to build/test + __dirname + '/../../proto/' + ], + })) as unknown as ProtoGrpcType; + +export class Backend { + private server: Server; + private receivedCallCount = 0; + private callListeners: (() => void)[] = []; + private port: number | null = null; + constructor() { + this.server = new Server(); + this.server.addService(loadedProtos.grpc.testing.EchoTestService.service, this as unknown as UntypedServiceImplementation); + } + Echo(call: ServerUnaryCall, callback: sendUnaryData) { + // call.request.params is currently ignored + this.addCall(); + callback(null, {message: call.request.message}); + } + + addCall() { + this.receivedCallCount++; + this.callListeners.forEach(listener => listener()); + } + + onCall(listener: () => void) { + this.callListeners.push(listener); + } + + start(callback: (error: Error | null, port: number) => void) { + this.server.bindAsync('localhost:0', ServerCredentials.createInsecure(), (error, port) => { + if (!error) { + this.port = port; + this.server.start(); + } + callback(error, port); + }) + } + + startAsync(): Promise { + return new Promise((resolve, reject) => { + this.start((error, port) => { + if (error) { + reject(error); + } else { + resolve(port); + } + }); + }); + } + + getPort(): number { + if (this.port === null) { + throw new Error('Port not set. Backend not yet started.'); + } + return this.port; + } + + getCallCount() { + return this.receivedCallCount; + } + + resetCallCount() { + this.receivedCallCount = 0; + } + + shutdown(callback: (error?: Error) => void) { + this.server.tryShutdown(callback); + } +} \ No newline at end of file diff --git a/packages/grpc-js-xds/test/client.ts b/packages/grpc-js-xds/test/client.ts new file mode 100644 index 000000000..6404a3eb2 --- /dev/null +++ b/packages/grpc-js-xds/test/client.ts @@ -0,0 +1,72 @@ +/* + * Copyright 2023 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 { credentials, loadPackageDefinition } from "@grpc/grpc-js"; +import { loadSync } from "@grpc/proto-loader"; +import { ProtoGrpcType } from "./generated/echo"; +import { EchoTestServiceClient } from "./generated/grpc/testing/EchoTestService"; +import { XdsServer } from "./xds-server"; + +const loadedProtos = loadPackageDefinition(loadSync( + [ + 'grpc/testing/echo.proto' + ], + { + keepCase: true, + longs: String, + enums: String, + defaults: true, + oneofs: true, + json: true, + includeDirs: [ + // Paths are relative to build/test + __dirname + '/../../proto/' + ], + })) as unknown as ProtoGrpcType; + +const BOOTSTRAP_CONFIG_KEY = 'grpc.TEST_ONLY_DO_NOT_USE_IN_PROD.xds_bootstrap_config'; + +export class XdsTestClient { + private client: EchoTestServiceClient; + private callInterval: NodeJS.Timer; + + constructor(targetName: string, xdsServer: XdsServer) { + this.client = new loadedProtos.grpc.testing.EchoTestService(`xds:///${targetName}`, credentials.createInsecure(), {[BOOTSTRAP_CONFIG_KEY]: xdsServer.getBootstrapInfoString()}); + this.callInterval = setInterval(() => {}, 0); + clearInterval(this.callInterval); + } + + startCalls(interval: number) { + clearInterval(this.callInterval); + this.callInterval = setInterval(() => { + this.client.echo({message: 'test'}, (error, value) => { + if (error) { + throw error; + } + }); + }, interval); + } + + stopCalls() { + clearInterval(this.callInterval); + } + + close() { + this.stopCalls(); + this.client.close(); + } +} \ No newline at end of file diff --git a/packages/grpc-js-xds/test/framework.ts b/packages/grpc-js-xds/test/framework.ts new file mode 100644 index 000000000..945b08a3a --- /dev/null +++ b/packages/grpc-js-xds/test/framework.ts @@ -0,0 +1,208 @@ +/* + * Copyright 2023 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 { ClusterLoadAssignment } from "../src/generated/envoy/config/endpoint/v3/ClusterLoadAssignment"; +import { Cluster } from "../src/generated/envoy/config/cluster/v3/Cluster"; +import { Backend } from "./backend"; +import { Locality } from "../src/generated/envoy/config/core/v3/Locality"; +import { RouteConfiguration } from "../src/generated/envoy/config/route/v3/RouteConfiguration"; +import { Route } from "../src/generated/envoy/config/route/v3/Route"; +import { Listener } from "../src/generated/envoy/config/listener/v3/Listener"; +import { HttpConnectionManager } from "../src/generated/envoy/extensions/filters/network/http_connection_manager/v3/HttpConnectionManager"; +import { AnyExtension } from "@grpc/proto-loader"; +import { HTTP_CONNECTION_MANGER_TYPE_URL } from "../src/resources"; +import { LocalityLbEndpoints } from "../src/generated/envoy/config/endpoint/v3/LocalityLbEndpoints"; +import { LbEndpoint } from "../src/generated/envoy/config/endpoint/v3/LbEndpoint"; + +interface Endpoint { + locality: Locality; + backends: Backend[]; + weight?: number; + priority?: number; +} + +function getLbEndpoint(backend: Backend): LbEndpoint { + return { + health_status: "HEALTHY", + endpoint: { + address: { + socket_address: { + address: '::1', + port_value: backend.getPort() + } + } + } + }; +} + +function getLocalityLbEndpoints(endpoint: Endpoint): LocalityLbEndpoints { + return { + lb_endpoints: endpoint.backends.map(getLbEndpoint), + locality: endpoint.locality, + load_balancing_weight: {value: endpoint.weight ?? 1}, + priority: endpoint.priority ?? 0 + } +} + +export class FakeCluster { + constructor(private name: string, private endpoints: Endpoint[]) {} + + getEndpointConfig(): ClusterLoadAssignment { + return { + cluster_name: this.name, + endpoints: this.endpoints.map(getLocalityLbEndpoints) + }; + } + + getClusterConfig(): Cluster { + return { + name: this.name, + type: 'EDS', + eds_cluster_config: {eds_config: {ads: {}}}, + lb_policy: 'ROUND_ROBIN' + } + } + + getName() { + return this.name; + } + + startAllBackends(): Promise { + return Promise.all(this.endpoints.map(endpoint => Promise.all(endpoint.backends.map(backend => backend.startAsync())))); + } + + private haveAllBackendsReceivedTraffic(): boolean { + for (const endpoint of this.endpoints) { + for (const backend of endpoint.backends) { + if (backend.getCallCount() < 1) { + return false; + } + } + } + return true; + } + + waitForAllBackendsToReceiveTraffic(): Promise { + for (const endpoint of this.endpoints) { + for (const backend of endpoint.backends) { + backend.resetCallCount(); + } + } + return new Promise((resolve, reject) => { + let finishedPromise = false; + for (const endpoint of this.endpoints) { + for (const backend of endpoint.backends) { + backend.onCall(() => { + if (finishedPromise) { + return; + } + if (this.haveAllBackendsReceivedTraffic()) { + finishedPromise = true; + resolve(); + } + }); + } + } + }); + } +} + +interface FakeRoute { + cluster?: FakeCluster; + weightedClusters?: [{cluster: FakeCluster, weight: number}]; +} + +function createRouteConfig(route: FakeRoute): Route { + if (route.cluster) { + return { + match: { + prefix: '' + }, + route: { + cluster: route.cluster.getName() + } + }; + } else { + return { + match: { + prefix: '' + }, + route: { + weighted_clusters: { + clusters: route.weightedClusters!.map(clusterWeight => ({ + name: clusterWeight.cluster.getName(), + weight: {value: clusterWeight.weight} + })) + } + } + } + } +} + +export class FakeRouteGroup { + constructor(private name: string, private routes: FakeRoute[]) {} + + getRouteConfiguration(): RouteConfiguration { + return { + name: this.name, + virtual_hosts: [{ + domains: ['*'], + routes: this.routes.map(createRouteConfig) + }] + }; + } + + getListener(): Listener { + const httpConnectionManager: HttpConnectionManager & AnyExtension = { + '@type': HTTP_CONNECTION_MANGER_TYPE_URL, + rds: { + route_config_name: this.name, + config_source: {ads: {}} + } + } + return { + name: this.name, + api_listener: { + api_listener: httpConnectionManager + } + }; + } + + startAllBackends(): Promise { + return Promise.all(this.routes.map(route => { + if (route.cluster) { + return route.cluster.startAllBackends(); + } else if (route.weightedClusters) { + return Promise.all(route.weightedClusters.map(clusterWeight => clusterWeight.cluster.startAllBackends())); + } else { + return Promise.resolve(); + } + })); + } + + waitForAllBackendsToReceiveTraffic(): Promise { + return Promise.all(this.routes.map(route => { + if (route.cluster) { + return route.cluster.waitForAllBackendsToReceiveTraffic(); + } else if (route.weightedClusters) { + return Promise.all(route.weightedClusters.map(clusterWeight => clusterWeight.cluster.waitForAllBackendsToReceiveTraffic())).then(() => {}); + } else { + return Promise.resolve(); + } + })); + } +} \ No newline at end of file diff --git a/packages/grpc-js-xds/test/generated/echo.ts b/packages/grpc-js-xds/test/generated/echo.ts new file mode 100644 index 000000000..537a49cfa --- /dev/null +++ b/packages/grpc-js-xds/test/generated/echo.ts @@ -0,0 +1,46 @@ +import type * as grpc from '@grpc/grpc-js'; +import type { MessageTypeDefinition } from '@grpc/proto-loader'; + +import type { EchoTest1ServiceClient as _grpc_testing_EchoTest1ServiceClient, EchoTest1ServiceDefinition as _grpc_testing_EchoTest1ServiceDefinition } from './grpc/testing/EchoTest1Service'; +import type { EchoTest2ServiceClient as _grpc_testing_EchoTest2ServiceClient, EchoTest2ServiceDefinition as _grpc_testing_EchoTest2ServiceDefinition } from './grpc/testing/EchoTest2Service'; +import type { EchoTestServiceClient as _grpc_testing_EchoTestServiceClient, EchoTestServiceDefinition as _grpc_testing_EchoTestServiceDefinition } from './grpc/testing/EchoTestService'; +import type { NoRpcServiceClient as _grpc_testing_NoRpcServiceClient, NoRpcServiceDefinition as _grpc_testing_NoRpcServiceDefinition } from './grpc/testing/NoRpcService'; +import type { UnimplementedEchoServiceClient as _grpc_testing_UnimplementedEchoServiceClient, UnimplementedEchoServiceDefinition as _grpc_testing_UnimplementedEchoServiceDefinition } from './grpc/testing/UnimplementedEchoService'; + +type SubtypeConstructor any, Subtype> = { + new(...args: ConstructorParameters): Subtype; +}; + +export interface ProtoGrpcType { + grpc: { + testing: { + DebugInfo: MessageTypeDefinition + EchoRequest: MessageTypeDefinition + EchoResponse: MessageTypeDefinition + EchoTest1Service: SubtypeConstructor & { service: _grpc_testing_EchoTest1ServiceDefinition } + EchoTest2Service: SubtypeConstructor & { service: _grpc_testing_EchoTest2ServiceDefinition } + EchoTestService: SubtypeConstructor & { service: _grpc_testing_EchoTestServiceDefinition } + ErrorStatus: MessageTypeDefinition + /** + * A service without any rpc defined to test coverage. + */ + NoRpcService: SubtypeConstructor & { service: _grpc_testing_NoRpcServiceDefinition } + RequestParams: MessageTypeDefinition + ResponseParams: MessageTypeDefinition + SimpleRequest: MessageTypeDefinition + SimpleResponse: MessageTypeDefinition + StringValue: MessageTypeDefinition + UnimplementedEchoService: SubtypeConstructor & { service: _grpc_testing_UnimplementedEchoServiceDefinition } + } + } + xds: { + data: { + orca: { + v3: { + OrcaLoadReport: MessageTypeDefinition + } + } + } + } +} + diff --git a/packages/grpc-js-xds/test/generated/grpc/testing/DebugInfo.ts b/packages/grpc-js-xds/test/generated/grpc/testing/DebugInfo.ts new file mode 100644 index 000000000..123188fe3 --- /dev/null +++ b/packages/grpc-js-xds/test/generated/grpc/testing/DebugInfo.ts @@ -0,0 +1,18 @@ +// Original file: proto/grpc/testing/echo_messages.proto + + +/** + * Message to be echoed back serialized in trailer. + */ +export interface DebugInfo { + 'stack_entries'?: (string)[]; + 'detail'?: (string); +} + +/** + * Message to be echoed back serialized in trailer. + */ +export interface DebugInfo__Output { + 'stack_entries': (string)[]; + 'detail': (string); +} diff --git a/packages/grpc-js-xds/test/generated/grpc/testing/EchoRequest.ts b/packages/grpc-js-xds/test/generated/grpc/testing/EchoRequest.ts new file mode 100644 index 000000000..cadf04f7a --- /dev/null +++ b/packages/grpc-js-xds/test/generated/grpc/testing/EchoRequest.ts @@ -0,0 +1,13 @@ +// Original file: proto/grpc/testing/echo_messages.proto + +import type { RequestParams as _grpc_testing_RequestParams, RequestParams__Output as _grpc_testing_RequestParams__Output } from '../../grpc/testing/RequestParams'; + +export interface EchoRequest { + 'message'?: (string); + 'param'?: (_grpc_testing_RequestParams | null); +} + +export interface EchoRequest__Output { + 'message': (string); + 'param': (_grpc_testing_RequestParams__Output | null); +} diff --git a/packages/grpc-js-xds/test/generated/grpc/testing/EchoResponse.ts b/packages/grpc-js-xds/test/generated/grpc/testing/EchoResponse.ts new file mode 100644 index 000000000..d54beaf4f --- /dev/null +++ b/packages/grpc-js-xds/test/generated/grpc/testing/EchoResponse.ts @@ -0,0 +1,13 @@ +// Original file: proto/grpc/testing/echo_messages.proto + +import type { ResponseParams as _grpc_testing_ResponseParams, ResponseParams__Output as _grpc_testing_ResponseParams__Output } from '../../grpc/testing/ResponseParams'; + +export interface EchoResponse { + 'message'?: (string); + 'param'?: (_grpc_testing_ResponseParams | null); +} + +export interface EchoResponse__Output { + 'message': (string); + 'param': (_grpc_testing_ResponseParams__Output | null); +} diff --git a/packages/grpc-js-xds/test/generated/grpc/testing/EchoTest1Service.ts b/packages/grpc-js-xds/test/generated/grpc/testing/EchoTest1Service.ts new file mode 100644 index 000000000..a2b1947f6 --- /dev/null +++ b/packages/grpc-js-xds/test/generated/grpc/testing/EchoTest1Service.ts @@ -0,0 +1,117 @@ +// Original file: proto/grpc/testing/echo.proto + +import type * as grpc from '@grpc/grpc-js' +import type { MethodDefinition } from '@grpc/proto-loader' +import type { EchoRequest as _grpc_testing_EchoRequest, EchoRequest__Output as _grpc_testing_EchoRequest__Output } from '../../grpc/testing/EchoRequest'; +import type { EchoResponse as _grpc_testing_EchoResponse, EchoResponse__Output as _grpc_testing_EchoResponse__Output } from '../../grpc/testing/EchoResponse'; +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'; + +export interface EchoTest1ServiceClient extends grpc.Client { + BidiStream(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse__Output>; + BidiStream(options?: grpc.CallOptions): grpc.ClientDuplexStream<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse__Output>; + bidiStream(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse__Output>; + bidiStream(options?: grpc.CallOptions): grpc.ClientDuplexStream<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse__Output>; + + /** + * A service which checks that the initial metadata sent over contains some + * expected key value pair + */ + CheckClientInitialMetadata(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + CheckClientInitialMetadata(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + CheckClientInitialMetadata(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + CheckClientInitialMetadata(argument: _grpc_testing_SimpleRequest, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + /** + * A service which checks that the initial metadata sent over contains some + * expected key value pair + */ + checkClientInitialMetadata(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + checkClientInitialMetadata(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + checkClientInitialMetadata(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + checkClientInitialMetadata(argument: _grpc_testing_SimpleRequest, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + + Echo(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + + Echo1(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo1(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo1(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo1(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo1(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo1(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo1(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo1(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + + Echo2(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo2(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo2(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo2(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo2(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo2(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo2(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo2(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + + RequestStream(metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + RequestStream(metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + RequestStream(options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + RequestStream(callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + requestStream(metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + requestStream(metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + requestStream(options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + requestStream(callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + + ResponseStream(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientReadableStream<_grpc_testing_EchoResponse__Output>; + ResponseStream(argument: _grpc_testing_EchoRequest, options?: grpc.CallOptions): grpc.ClientReadableStream<_grpc_testing_EchoResponse__Output>; + responseStream(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientReadableStream<_grpc_testing_EchoResponse__Output>; + responseStream(argument: _grpc_testing_EchoRequest, options?: grpc.CallOptions): grpc.ClientReadableStream<_grpc_testing_EchoResponse__Output>; + + Unimplemented(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Unimplemented(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Unimplemented(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Unimplemented(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + unimplemented(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + unimplemented(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + unimplemented(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + unimplemented(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + +} + +export interface EchoTest1ServiceHandlers extends grpc.UntypedServiceImplementation { + BidiStream: grpc.handleBidiStreamingCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + + /** + * A service which checks that the initial metadata sent over contains some + * expected key value pair + */ + CheckClientInitialMetadata: grpc.handleUnaryCall<_grpc_testing_SimpleRequest__Output, _grpc_testing_SimpleResponse>; + + Echo: grpc.handleUnaryCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + + Echo1: grpc.handleUnaryCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + + Echo2: grpc.handleUnaryCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + + RequestStream: grpc.handleClientStreamingCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + + ResponseStream: grpc.handleServerStreamingCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + + Unimplemented: grpc.handleUnaryCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + +} + +export interface EchoTest1ServiceDefinition extends grpc.ServiceDefinition { + BidiStream: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> + CheckClientInitialMetadata: MethodDefinition<_grpc_testing_SimpleRequest, _grpc_testing_SimpleResponse, _grpc_testing_SimpleRequest__Output, _grpc_testing_SimpleResponse__Output> + Echo: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> + Echo1: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> + Echo2: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> + RequestStream: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> + ResponseStream: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> + Unimplemented: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> +} diff --git a/packages/grpc-js-xds/test/generated/grpc/testing/EchoTest2Service.ts b/packages/grpc-js-xds/test/generated/grpc/testing/EchoTest2Service.ts new file mode 100644 index 000000000..033e70143 --- /dev/null +++ b/packages/grpc-js-xds/test/generated/grpc/testing/EchoTest2Service.ts @@ -0,0 +1,117 @@ +// Original file: proto/grpc/testing/echo.proto + +import type * as grpc from '@grpc/grpc-js' +import type { MethodDefinition } from '@grpc/proto-loader' +import type { EchoRequest as _grpc_testing_EchoRequest, EchoRequest__Output as _grpc_testing_EchoRequest__Output } from '../../grpc/testing/EchoRequest'; +import type { EchoResponse as _grpc_testing_EchoResponse, EchoResponse__Output as _grpc_testing_EchoResponse__Output } from '../../grpc/testing/EchoResponse'; +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'; + +export interface EchoTest2ServiceClient extends grpc.Client { + BidiStream(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse__Output>; + BidiStream(options?: grpc.CallOptions): grpc.ClientDuplexStream<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse__Output>; + bidiStream(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse__Output>; + bidiStream(options?: grpc.CallOptions): grpc.ClientDuplexStream<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse__Output>; + + /** + * A service which checks that the initial metadata sent over contains some + * expected key value pair + */ + CheckClientInitialMetadata(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + CheckClientInitialMetadata(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + CheckClientInitialMetadata(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + CheckClientInitialMetadata(argument: _grpc_testing_SimpleRequest, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + /** + * A service which checks that the initial metadata sent over contains some + * expected key value pair + */ + checkClientInitialMetadata(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + checkClientInitialMetadata(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + checkClientInitialMetadata(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + checkClientInitialMetadata(argument: _grpc_testing_SimpleRequest, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + + Echo(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + + Echo1(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo1(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo1(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo1(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo1(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo1(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo1(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo1(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + + Echo2(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo2(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo2(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo2(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo2(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo2(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo2(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo2(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + + RequestStream(metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + RequestStream(metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + RequestStream(options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + RequestStream(callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + requestStream(metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + requestStream(metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + requestStream(options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + requestStream(callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + + ResponseStream(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientReadableStream<_grpc_testing_EchoResponse__Output>; + ResponseStream(argument: _grpc_testing_EchoRequest, options?: grpc.CallOptions): grpc.ClientReadableStream<_grpc_testing_EchoResponse__Output>; + responseStream(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientReadableStream<_grpc_testing_EchoResponse__Output>; + responseStream(argument: _grpc_testing_EchoRequest, options?: grpc.CallOptions): grpc.ClientReadableStream<_grpc_testing_EchoResponse__Output>; + + Unimplemented(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Unimplemented(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Unimplemented(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Unimplemented(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + unimplemented(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + unimplemented(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + unimplemented(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + unimplemented(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + +} + +export interface EchoTest2ServiceHandlers extends grpc.UntypedServiceImplementation { + BidiStream: grpc.handleBidiStreamingCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + + /** + * A service which checks that the initial metadata sent over contains some + * expected key value pair + */ + CheckClientInitialMetadata: grpc.handleUnaryCall<_grpc_testing_SimpleRequest__Output, _grpc_testing_SimpleResponse>; + + Echo: grpc.handleUnaryCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + + Echo1: grpc.handleUnaryCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + + Echo2: grpc.handleUnaryCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + + RequestStream: grpc.handleClientStreamingCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + + ResponseStream: grpc.handleServerStreamingCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + + Unimplemented: grpc.handleUnaryCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + +} + +export interface EchoTest2ServiceDefinition extends grpc.ServiceDefinition { + BidiStream: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> + CheckClientInitialMetadata: MethodDefinition<_grpc_testing_SimpleRequest, _grpc_testing_SimpleResponse, _grpc_testing_SimpleRequest__Output, _grpc_testing_SimpleResponse__Output> + Echo: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> + Echo1: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> + Echo2: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> + RequestStream: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> + ResponseStream: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> + Unimplemented: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> +} diff --git a/packages/grpc-js-xds/test/generated/grpc/testing/EchoTestService.ts b/packages/grpc-js-xds/test/generated/grpc/testing/EchoTestService.ts new file mode 100644 index 000000000..d1fa2d075 --- /dev/null +++ b/packages/grpc-js-xds/test/generated/grpc/testing/EchoTestService.ts @@ -0,0 +1,150 @@ +// Original file: proto/grpc/testing/echo.proto + +import type * as grpc from '@grpc/grpc-js' +import type { MethodDefinition } from '@grpc/proto-loader' +import type { EchoRequest as _grpc_testing_EchoRequest, EchoRequest__Output as _grpc_testing_EchoRequest__Output } from '../../grpc/testing/EchoRequest'; +import type { EchoResponse as _grpc_testing_EchoResponse, EchoResponse__Output as _grpc_testing_EchoResponse__Output } from '../../grpc/testing/EchoResponse'; +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'; +import type { StringValue as _grpc_testing_StringValue, StringValue__Output as _grpc_testing_StringValue__Output } from '../../grpc/testing/StringValue'; + +export interface EchoTestServiceClient extends grpc.Client { + BidiStream(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse__Output>; + BidiStream(options?: grpc.CallOptions): grpc.ClientDuplexStream<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse__Output>; + bidiStream(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse__Output>; + bidiStream(options?: grpc.CallOptions): grpc.ClientDuplexStream<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse__Output>; + + /** + * A service which checks that the initial metadata sent over contains some + * expected key value pair + */ + CheckClientInitialMetadata(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + CheckClientInitialMetadata(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + CheckClientInitialMetadata(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + CheckClientInitialMetadata(argument: _grpc_testing_SimpleRequest, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + /** + * A service which checks that the initial metadata sent over contains some + * expected key value pair + */ + checkClientInitialMetadata(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + checkClientInitialMetadata(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + checkClientInitialMetadata(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + checkClientInitialMetadata(argument: _grpc_testing_SimpleRequest, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall; + + CheckDeadlineSet(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_StringValue__Output>): grpc.ClientUnaryCall; + CheckDeadlineSet(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_StringValue__Output>): grpc.ClientUnaryCall; + CheckDeadlineSet(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_StringValue__Output>): grpc.ClientUnaryCall; + CheckDeadlineSet(argument: _grpc_testing_SimpleRequest, callback: grpc.requestCallback<_grpc_testing_StringValue__Output>): grpc.ClientUnaryCall; + checkDeadlineSet(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_StringValue__Output>): grpc.ClientUnaryCall; + checkDeadlineSet(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_StringValue__Output>): grpc.ClientUnaryCall; + checkDeadlineSet(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_StringValue__Output>): grpc.ClientUnaryCall; + checkDeadlineSet(argument: _grpc_testing_SimpleRequest, callback: grpc.requestCallback<_grpc_testing_StringValue__Output>): grpc.ClientUnaryCall; + + CheckDeadlineUpperBound(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_StringValue__Output>): grpc.ClientUnaryCall; + CheckDeadlineUpperBound(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_StringValue__Output>): grpc.ClientUnaryCall; + CheckDeadlineUpperBound(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_StringValue__Output>): grpc.ClientUnaryCall; + CheckDeadlineUpperBound(argument: _grpc_testing_SimpleRequest, callback: grpc.requestCallback<_grpc_testing_StringValue__Output>): grpc.ClientUnaryCall; + checkDeadlineUpperBound(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_StringValue__Output>): grpc.ClientUnaryCall; + checkDeadlineUpperBound(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_StringValue__Output>): grpc.ClientUnaryCall; + checkDeadlineUpperBound(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_StringValue__Output>): grpc.ClientUnaryCall; + checkDeadlineUpperBound(argument: _grpc_testing_SimpleRequest, callback: grpc.requestCallback<_grpc_testing_StringValue__Output>): grpc.ClientUnaryCall; + + Echo(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + + Echo1(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo1(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo1(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo1(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo1(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo1(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo1(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo1(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + + Echo2(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo2(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo2(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Echo2(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo2(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo2(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo2(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + echo2(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + + RequestStream(metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + RequestStream(metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + RequestStream(options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + RequestStream(callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + requestStream(metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + requestStream(metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + requestStream(options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + requestStream(callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientWritableStream<_grpc_testing_EchoRequest>; + + ResponseStream(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientReadableStream<_grpc_testing_EchoResponse__Output>; + ResponseStream(argument: _grpc_testing_EchoRequest, options?: grpc.CallOptions): grpc.ClientReadableStream<_grpc_testing_EchoResponse__Output>; + responseStream(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientReadableStream<_grpc_testing_EchoResponse__Output>; + responseStream(argument: _grpc_testing_EchoRequest, options?: grpc.CallOptions): grpc.ClientReadableStream<_grpc_testing_EchoResponse__Output>; + + Unimplemented(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Unimplemented(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Unimplemented(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Unimplemented(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + unimplemented(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + unimplemented(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + unimplemented(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + unimplemented(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + + UnimplementedBidi(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse__Output>; + UnimplementedBidi(options?: grpc.CallOptions): grpc.ClientDuplexStream<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse__Output>; + unimplementedBidi(metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientDuplexStream<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse__Output>; + unimplementedBidi(options?: grpc.CallOptions): grpc.ClientDuplexStream<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse__Output>; + +} + +export interface EchoTestServiceHandlers extends grpc.UntypedServiceImplementation { + BidiStream: grpc.handleBidiStreamingCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + + /** + * A service which checks that the initial metadata sent over contains some + * expected key value pair + */ + CheckClientInitialMetadata: grpc.handleUnaryCall<_grpc_testing_SimpleRequest__Output, _grpc_testing_SimpleResponse>; + + CheckDeadlineSet: grpc.handleUnaryCall<_grpc_testing_SimpleRequest__Output, _grpc_testing_StringValue>; + + CheckDeadlineUpperBound: grpc.handleUnaryCall<_grpc_testing_SimpleRequest__Output, _grpc_testing_StringValue>; + + Echo: grpc.handleUnaryCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + + Echo1: grpc.handleUnaryCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + + Echo2: grpc.handleUnaryCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + + RequestStream: grpc.handleClientStreamingCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + + ResponseStream: grpc.handleServerStreamingCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + + Unimplemented: grpc.handleUnaryCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + + UnimplementedBidi: grpc.handleBidiStreamingCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + +} + +export interface EchoTestServiceDefinition extends grpc.ServiceDefinition { + BidiStream: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> + CheckClientInitialMetadata: MethodDefinition<_grpc_testing_SimpleRequest, _grpc_testing_SimpleResponse, _grpc_testing_SimpleRequest__Output, _grpc_testing_SimpleResponse__Output> + CheckDeadlineSet: MethodDefinition<_grpc_testing_SimpleRequest, _grpc_testing_StringValue, _grpc_testing_SimpleRequest__Output, _grpc_testing_StringValue__Output> + CheckDeadlineUpperBound: MethodDefinition<_grpc_testing_SimpleRequest, _grpc_testing_StringValue, _grpc_testing_SimpleRequest__Output, _grpc_testing_StringValue__Output> + Echo: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> + Echo1: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> + Echo2: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> + RequestStream: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> + ResponseStream: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> + Unimplemented: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> + UnimplementedBidi: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> +} diff --git a/packages/grpc-js-xds/test/generated/grpc/testing/ErrorStatus.ts b/packages/grpc-js-xds/test/generated/grpc/testing/ErrorStatus.ts new file mode 100644 index 000000000..42ff36d9a --- /dev/null +++ b/packages/grpc-js-xds/test/generated/grpc/testing/ErrorStatus.ts @@ -0,0 +1,20 @@ +// Original file: proto/grpc/testing/echo_messages.proto + + +/** + * Error status client expects to see. + */ +export interface ErrorStatus { + 'code'?: (number); + 'error_message'?: (string); + 'binary_error_details'?: (string); +} + +/** + * Error status client expects to see. + */ +export interface ErrorStatus__Output { + 'code': (number); + 'error_message': (string); + 'binary_error_details': (string); +} diff --git a/packages/grpc-js-xds/test/generated/grpc/testing/NoRpcService.ts b/packages/grpc-js-xds/test/generated/grpc/testing/NoRpcService.ts new file mode 100644 index 000000000..7427c8097 --- /dev/null +++ b/packages/grpc-js-xds/test/generated/grpc/testing/NoRpcService.ts @@ -0,0 +1,19 @@ +// Original file: proto/grpc/testing/echo.proto + +import type * as grpc from '@grpc/grpc-js' +import type { MethodDefinition } from '@grpc/proto-loader' + +/** + * A service without any rpc defined to test coverage. + */ +export interface NoRpcServiceClient extends grpc.Client { +} + +/** + * A service without any rpc defined to test coverage. + */ +export interface NoRpcServiceHandlers extends grpc.UntypedServiceImplementation { +} + +export interface NoRpcServiceDefinition extends grpc.ServiceDefinition { +} diff --git a/packages/grpc-js-xds/test/generated/grpc/testing/RequestParams.ts b/packages/grpc-js-xds/test/generated/grpc/testing/RequestParams.ts new file mode 100644 index 000000000..e8c5ef1d1 --- /dev/null +++ b/packages/grpc-js-xds/test/generated/grpc/testing/RequestParams.ts @@ -0,0 +1,75 @@ +// Original file: proto/grpc/testing/echo_messages.proto + +import type { DebugInfo as _grpc_testing_DebugInfo, DebugInfo__Output as _grpc_testing_DebugInfo__Output } from '../../grpc/testing/DebugInfo'; +import type { ErrorStatus as _grpc_testing_ErrorStatus, ErrorStatus__Output as _grpc_testing_ErrorStatus__Output } from '../../grpc/testing/ErrorStatus'; +import type { OrcaLoadReport as _xds_data_orca_v3_OrcaLoadReport, OrcaLoadReport__Output as _xds_data_orca_v3_OrcaLoadReport__Output } from '../../xds/data/orca/v3/OrcaLoadReport'; + +export interface RequestParams { + 'echo_deadline'?: (boolean); + 'client_cancel_after_us'?: (number); + 'server_cancel_after_us'?: (number); + 'echo_metadata'?: (boolean); + 'check_auth_context'?: (boolean); + 'response_message_length'?: (number); + 'echo_peer'?: (boolean); + /** + * will force check_auth_context. + */ + 'expected_client_identity'?: (string); + 'skip_cancelled_check'?: (boolean); + 'expected_transport_security_type'?: (string); + 'debug_info'?: (_grpc_testing_DebugInfo | null); + /** + * Server should not see a request with this set. + */ + 'server_die'?: (boolean); + 'binary_error_details'?: (string); + 'expected_error'?: (_grpc_testing_ErrorStatus | null); + /** + * sleep when invoking server for deadline tests + */ + 'server_sleep_us'?: (number); + /** + * which backend to send request to + */ + 'backend_channel_idx'?: (number); + 'echo_metadata_initially'?: (boolean); + 'server_notify_client_when_started'?: (boolean); + 'backend_metrics'?: (_xds_data_orca_v3_OrcaLoadReport | null); + 'echo_host_from_authority_header'?: (boolean); +} + +export interface RequestParams__Output { + 'echo_deadline': (boolean); + 'client_cancel_after_us': (number); + 'server_cancel_after_us': (number); + 'echo_metadata': (boolean); + 'check_auth_context': (boolean); + 'response_message_length': (number); + 'echo_peer': (boolean); + /** + * will force check_auth_context. + */ + 'expected_client_identity': (string); + 'skip_cancelled_check': (boolean); + 'expected_transport_security_type': (string); + 'debug_info': (_grpc_testing_DebugInfo__Output | null); + /** + * Server should not see a request with this set. + */ + 'server_die': (boolean); + 'binary_error_details': (string); + 'expected_error': (_grpc_testing_ErrorStatus__Output | null); + /** + * sleep when invoking server for deadline tests + */ + 'server_sleep_us': (number); + /** + * which backend to send request to + */ + 'backend_channel_idx': (number); + 'echo_metadata_initially': (boolean); + 'server_notify_client_when_started': (boolean); + 'backend_metrics': (_xds_data_orca_v3_OrcaLoadReport__Output | null); + 'echo_host_from_authority_header': (boolean); +} diff --git a/packages/grpc-js-xds/test/generated/grpc/testing/ResponseParams.ts b/packages/grpc-js-xds/test/generated/grpc/testing/ResponseParams.ts new file mode 100644 index 000000000..588e463c2 --- /dev/null +++ b/packages/grpc-js-xds/test/generated/grpc/testing/ResponseParams.ts @@ -0,0 +1,15 @@ +// Original file: proto/grpc/testing/echo_messages.proto + +import type { Long } from '@grpc/proto-loader'; + +export interface ResponseParams { + 'request_deadline'?: (number | string | Long); + 'host'?: (string); + 'peer'?: (string); +} + +export interface ResponseParams__Output { + 'request_deadline': (string); + 'host': (string); + 'peer': (string); +} diff --git a/packages/grpc-js-xds/test/generated/grpc/testing/SimpleRequest.ts b/packages/grpc-js-xds/test/generated/grpc/testing/SimpleRequest.ts new file mode 100644 index 000000000..292a2020c --- /dev/null +++ b/packages/grpc-js-xds/test/generated/grpc/testing/SimpleRequest.ts @@ -0,0 +1,8 @@ +// Original file: proto/grpc/testing/simple_messages.proto + + +export interface SimpleRequest { +} + +export interface SimpleRequest__Output { +} diff --git a/packages/grpc-js-xds/test/generated/grpc/testing/SimpleResponse.ts b/packages/grpc-js-xds/test/generated/grpc/testing/SimpleResponse.ts new file mode 100644 index 000000000..3e8735e5e --- /dev/null +++ b/packages/grpc-js-xds/test/generated/grpc/testing/SimpleResponse.ts @@ -0,0 +1,8 @@ +// Original file: proto/grpc/testing/simple_messages.proto + + +export interface SimpleResponse { +} + +export interface SimpleResponse__Output { +} diff --git a/packages/grpc-js-xds/test/generated/grpc/testing/StringValue.ts b/packages/grpc-js-xds/test/generated/grpc/testing/StringValue.ts new file mode 100644 index 000000000..4a779ae2b --- /dev/null +++ b/packages/grpc-js-xds/test/generated/grpc/testing/StringValue.ts @@ -0,0 +1,10 @@ +// Original file: proto/grpc/testing/simple_messages.proto + + +export interface StringValue { + 'message'?: (string); +} + +export interface StringValue__Output { + 'message': (string); +} diff --git a/packages/grpc-js-xds/test/generated/grpc/testing/UnimplementedEchoService.ts b/packages/grpc-js-xds/test/generated/grpc/testing/UnimplementedEchoService.ts new file mode 100644 index 000000000..48128976e --- /dev/null +++ b/packages/grpc-js-xds/test/generated/grpc/testing/UnimplementedEchoService.ts @@ -0,0 +1,27 @@ +// Original file: proto/grpc/testing/echo.proto + +import type * as grpc from '@grpc/grpc-js' +import type { MethodDefinition } from '@grpc/proto-loader' +import type { EchoRequest as _grpc_testing_EchoRequest, EchoRequest__Output as _grpc_testing_EchoRequest__Output } from '../../grpc/testing/EchoRequest'; +import type { EchoResponse as _grpc_testing_EchoResponse, EchoResponse__Output as _grpc_testing_EchoResponse__Output } from '../../grpc/testing/EchoResponse'; + +export interface UnimplementedEchoServiceClient extends grpc.Client { + Unimplemented(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Unimplemented(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Unimplemented(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + Unimplemented(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + unimplemented(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + unimplemented(argument: _grpc_testing_EchoRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + unimplemented(argument: _grpc_testing_EchoRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + unimplemented(argument: _grpc_testing_EchoRequest, callback: grpc.requestCallback<_grpc_testing_EchoResponse__Output>): grpc.ClientUnaryCall; + +} + +export interface UnimplementedEchoServiceHandlers extends grpc.UntypedServiceImplementation { + Unimplemented: grpc.handleUnaryCall<_grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse>; + +} + +export interface UnimplementedEchoServiceDefinition extends grpc.ServiceDefinition { + Unimplemented: MethodDefinition<_grpc_testing_EchoRequest, _grpc_testing_EchoResponse, _grpc_testing_EchoRequest__Output, _grpc_testing_EchoResponse__Output> +} diff --git a/packages/grpc-js-xds/test/generated/xds/data/orca/v3/OrcaLoadReport.ts b/packages/grpc-js-xds/test/generated/xds/data/orca/v3/OrcaLoadReport.ts new file mode 100644 index 000000000..d66c42713 --- /dev/null +++ b/packages/grpc-js-xds/test/generated/xds/data/orca/v3/OrcaLoadReport.ts @@ -0,0 +1,59 @@ +// Original file: proto/grpc/testing/xds/v3/orca_load_report.proto + +import type { Long } from '@grpc/proto-loader'; + +export interface OrcaLoadReport { + /** + * CPU utilization expressed as a fraction of available CPU resources. This + * should be derived from the latest sample or measurement. + */ + 'cpu_utilization'?: (number | string); + /** + * Memory utilization expressed as a fraction of available memory + * resources. This should be derived from the latest sample or measurement. + */ + 'mem_utilization'?: (number | string); + /** + * Total RPS being served by an endpoint. This should cover all services that an endpoint is + * responsible for. + */ + 'rps'?: (number | string | Long); + /** + * Application specific requests costs. Each value is an absolute cost (e.g. 3487 bytes of + * storage) associated with the request. + */ + 'request_cost'?: ({[key: string]: number | string}); + /** + * Resource utilization values. Each value is expressed as a fraction of total resources + * available, derived from the latest sample or measurement. + */ + 'utilization'?: ({[key: string]: number | string}); +} + +export interface OrcaLoadReport__Output { + /** + * CPU utilization expressed as a fraction of available CPU resources. This + * should be derived from the latest sample or measurement. + */ + 'cpu_utilization': (number | string); + /** + * Memory utilization expressed as a fraction of available memory + * resources. This should be derived from the latest sample or measurement. + */ + 'mem_utilization': (number | string); + /** + * Total RPS being served by an endpoint. This should cover all services that an endpoint is + * responsible for. + */ + 'rps': (string); + /** + * Application specific requests costs. Each value is an absolute cost (e.g. 3487 bytes of + * storage) associated with the request. + */ + 'request_cost': ({[key: string]: number | string}); + /** + * Resource utilization values. Each value is expressed as a fraction of total resources + * available, derived from the latest sample or measurement. + */ + 'utilization': ({[key: string]: number | string}); +} diff --git a/packages/grpc-js-xds/test/test-core.ts b/packages/grpc-js-xds/test/test-core.ts new file mode 100644 index 000000000..d0d1b6031 --- /dev/null +++ b/packages/grpc-js-xds/test/test-core.ts @@ -0,0 +1,63 @@ +/* + * Copyright 2023 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 { Backend } from "./backend"; +import { XdsTestClient } from "./client"; +import { FakeCluster, FakeRouteGroup } from "./framework"; +import { XdsServer } from "./xds-server"; + +import { register } from "../src"; +import assert = require("assert"); + +register(); + +describe('core xDS functionality', () => { + let xdsServer: XdsServer; + let client: XdsTestClient; + beforeEach(done => { + xdsServer = new XdsServer(); + xdsServer.startServer(error => { + done(error); + }); + }); + afterEach(() => { + client?.close(); + xdsServer?.shutdownServer(); + }) + it('should route requests to the single backend', done => { + const cluster = new FakeCluster('cluster1', [{backends: [new Backend()], locality:{region: 'region1'}}]); + const routeGroup = new FakeRouteGroup('route1', [{cluster: cluster}]); + routeGroup.startAllBackends().then(() => { + xdsServer.setEdsResource(cluster.getEndpointConfig()); + xdsServer.setCdsResource(cluster.getClusterConfig()); + xdsServer.setRdsResource(routeGroup.getRouteConfiguration()); + xdsServer.setLdsResource(routeGroup.getListener()); + xdsServer.addResponseListener((typeUrl, responseState) => { + if (responseState.state === 'NACKED') { + client.stopCalls(); + assert.fail(`Client NACKED ${typeUrl} resource with message ${responseState.errorMessage}`); + } + }) + client = new XdsTestClient('route1', xdsServer); + client.startCalls(100); + routeGroup.waitForAllBackendsToReceiveTraffic().then(() => { + client.stopCalls(); + done(); + }, reason => done(reason)); + }, reason => done(reason)); + }); +}); \ No newline at end of file diff --git a/packages/grpc-js-xds/test/xds-server.ts b/packages/grpc-js-xds/test/xds-server.ts new file mode 100644 index 000000000..b82a3a673 --- /dev/null +++ b/packages/grpc-js-xds/test/xds-server.ts @@ -0,0 +1,342 @@ +/* + * Copyright 2023 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 { ServerDuplexStream, Server, UntypedServiceImplementation, ServerCredentials, loadPackageDefinition } from "@grpc/grpc-js"; +import { AnyExtension, loadSync } from "@grpc/proto-loader"; +import { EventEmitter } from "stream"; +import { Cluster } from "../src/generated/envoy/config/cluster/v3/Cluster"; +import { ClusterLoadAssignment } from "../src/generated/envoy/config/endpoint/v3/ClusterLoadAssignment"; +import { Listener } from "../src/generated/envoy/config/listener/v3/Listener"; +import { RouteConfiguration } from "../src/generated/envoy/config/route/v3/RouteConfiguration"; +import { AggregatedDiscoveryServiceHandlers } from "../src/generated/envoy/service/discovery/v3/AggregatedDiscoveryService"; +import { DiscoveryRequest__Output } from "../src/generated/envoy/service/discovery/v3/DiscoveryRequest"; +import { DiscoveryResponse } from "../src/generated/envoy/service/discovery/v3/DiscoveryResponse"; +import { Any } from "../src/generated/google/protobuf/Any"; +import { LDS_TYPE_URL, RDS_TYPE_URL, CDS_TYPE_URL, EDS_TYPE_URL, LdsTypeUrl, RdsTypeUrl, CdsTypeUrl, EdsTypeUrl, AdsTypeUrl } from "../src/resources" +import * as adsTypes from '../src/generated/ads'; +import * as lrsTypes from '../src/generated/lrs'; +import { LoadStatsRequest__Output } from "../src/generated/envoy/service/load_stats/v3/LoadStatsRequest"; +import { LoadStatsResponse } from "../src/generated/envoy/service/load_stats/v3/LoadStatsResponse"; + +const loadedProtos = loadPackageDefinition(loadSync( + [ + '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' + ], + { + keepCase: true, + longs: String, + enums: String, + defaults: true, + oneofs: true, + json: true, + includeDirs: [ + // Paths are relative to src/build + __dirname + '/../../deps/envoy-api/', + __dirname + '/../../deps/xds/', + __dirname + '/../../deps/googleapis/', + __dirname + '/../../deps/protoc-gen-validate/', + ], + })) as unknown as adsTypes.ProtoGrpcType & lrsTypes.ProtoGrpcType; + +type AdsInputType = T extends EdsTypeUrl + ? ClusterLoadAssignment + : T extends CdsTypeUrl + ? Cluster + : T extends RdsTypeUrl + ? RouteConfiguration + : Listener; + +const ADS_TYPE_URLS = new Set([LDS_TYPE_URL, RDS_TYPE_URL, CDS_TYPE_URL, EDS_TYPE_URL]); + +interface ResponseState { + state: 'ACKED' | 'NACKED'; + errorMessage?: string; +} + +interface ResponseListener { + (typeUrl: AdsTypeUrl, responseState: ResponseState): void; +} + +type ResourceAny = AdsInputType & {'@type': T}; + +interface ResourceState { + resource?: ResourceAny; + resourceTypeVersion: number; + subscriptions: Set; +} + +interface ResourceTypeState { + resourceTypeVersion: number; + /** + * Key type is type URL + */ + resourceNameMap: Map>; +} + +interface ResourceMap { + [EDS_TYPE_URL]: ResourceTypeState; + [CDS_TYPE_URL]: ResourceTypeState; + [RDS_TYPE_URL]: ResourceTypeState; + [LDS_TYPE_URL]: ResourceTypeState; +} + +function isAdsTypeUrl(value: string): value is AdsTypeUrl { + return ADS_TYPE_URLS.has(value); +} + +export class XdsServer { + private resourceMap: ResourceMap = { + [EDS_TYPE_URL]: { + resourceTypeVersion: 0, + resourceNameMap: new Map() + }, + [CDS_TYPE_URL]: { + resourceTypeVersion: 0, + resourceNameMap: new Map() + }, + [RDS_TYPE_URL]: { + resourceTypeVersion: 0, + resourceNameMap: new Map() + }, + [LDS_TYPE_URL]: { + resourceTypeVersion: 0, + resourceNameMap: new Map() + }, + }; + private responseListeners = new Set(); + private resourceTypesToIgnore = new Set(); + private clients = new Map>(); + private server: Server | null = null; + private port: number | null = null; + + addResponseListener(listener: ResponseListener) { + this.responseListeners.add(listener); + } + + removeResponseListener(listener: ResponseListener) { + this.responseListeners.delete(listener); + } + + setResource(resource: ResourceAny, name: string) { + const resourceTypeState = this.resourceMap[resource["@type"]] as ResourceTypeState; + resourceTypeState.resourceTypeVersion += 1; + let resourceState: ResourceState | undefined = resourceTypeState.resourceNameMap.get(name); + if (!resourceState) { + resourceState = { + resourceTypeVersion: 0, + subscriptions: new Set() + }; + resourceTypeState.resourceNameMap.set(name, resourceState); + } + resourceState.resourceTypeVersion = resourceTypeState.resourceTypeVersion; + resourceState.resource = resource; + this.sendResourceUpdates(resource['@type'], resourceState.subscriptions, new Set([name])); + } + + setLdsResource(resource: Listener) { + this.setResource({...resource, '@type': LDS_TYPE_URL}, resource.name!); + } + + setRdsResource(resource: RouteConfiguration) { + this.setResource({...resource, '@type': RDS_TYPE_URL}, resource.name!); + } + + setCdsResource(resource: Cluster) { + this.setResource({...resource, '@type': CDS_TYPE_URL}, resource.name!); + } + + setEdsResource(resource: ClusterLoadAssignment) { + this.setResource({...resource, '@type': EDS_TYPE_URL}, resource.cluster_name!); + } + + unsetResource(typeUrl: T, name: string) { + const resourceTypeState = this.resourceMap[typeUrl] as ResourceTypeState; + resourceTypeState.resourceTypeVersion += 1; + let resourceState: ResourceState | undefined = resourceTypeState.resourceNameMap.get(name); + if (resourceState) { + resourceState.resourceTypeVersion = resourceTypeState.resourceTypeVersion; + delete resourceState.resource; + this.sendResourceUpdates(typeUrl, resourceState.subscriptions, new Set([name])); + } + } + + ignoreResourceType(typeUrl: AdsTypeUrl) { + this.resourceTypesToIgnore.add(typeUrl); + } + + private sendResourceUpdates(typeUrl: T, clients: Set, includeResources: Set) { + const resourceTypeState = this.resourceMap[typeUrl] as ResourceTypeState; + const clientResources = new Map(); + for (const [resourceName, resourceState] of resourceTypeState.resourceNameMap) { + /* For RDS and EDS, only send updates for the listed updated resources. + * Otherwise include all resources. */ + if ((typeUrl === RDS_TYPE_URL || typeUrl === EDS_TYPE_URL) && !includeResources.has(resourceName)) { + continue; + } + if (!resourceState.resource) { + continue; + } + for (const clientName of clients) { + if (!resourceState.subscriptions.has(clientName)) { + continue; + } + let resourcesList = clientResources.get(clientName); + if (!resourcesList) { + resourcesList = []; + clientResources.set(clientName, resourcesList); + } + resourcesList.push(resourceState.resource); + } + } + for (const [clientName, resourceList] of clientResources) { + this.clients.get(clientName)?.write({ + resources: resourceList, + version_info: resourceTypeState.resourceTypeVersion.toString(), + nonce: resourceTypeState.resourceTypeVersion.toString(), + type_url: typeUrl + }); + } + } + + private updateResponseListeners(typeUrl: AdsTypeUrl, responseState: ResponseState) { + for (const listener of this.responseListeners) { + listener(typeUrl, responseState); + } + } + + private maybeSubscribe(typeUrl: T, client: string, resourceName: string): boolean { + const resourceTypeState = this.resourceMap[typeUrl] as ResourceTypeState; + let resourceState = resourceTypeState.resourceNameMap.get(resourceName); + if (!resourceState) { + resourceState = { + resourceTypeVersion: 0, + subscriptions: new Set() + }; + resourceTypeState.resourceNameMap.set(resourceName, resourceState); + } + const newlySubscribed = !resourceState.subscriptions.has(client); + resourceState.subscriptions.add(client); + return newlySubscribed; + } + + private handleUnsubscriptions(typeUrl: AdsTypeUrl, client: string, requestedResourceNames?: Set) { + const resourceTypeState = this.resourceMap[typeUrl]; + for (const [resourceName, resourceState] of resourceTypeState.resourceNameMap) { + if (!requestedResourceNames || !requestedResourceNames.has(resourceName)) { + resourceState.subscriptions.delete(client); + if (!resourceState.resource && resourceState.subscriptions.size === 0) { + resourceTypeState.resourceNameMap.delete(resourceName) + } + } + } + } + + private handleRequest(clientName: string, request: DiscoveryRequest__Output) { + if (!isAdsTypeUrl(request.type_url)) { + console.error(`Received ADS request with unsupported type_url ${request.type_url}`); + return; + } + const clientResourceVersion = request.version_info === '' ? 0 : Number.parseInt(request.version_info); + if (request.error_detail) { + this.updateResponseListeners(request.type_url, {state: 'NACKED', errorMessage: request.error_detail.message}); + } else { + this.updateResponseListeners(request.type_url, {state: 'ACKED'}); + } + const requestedResourceNames = new Set(request.resource_names); + const resourceTypeState = this.resourceMap[request.type_url]; + const updatedResources = new Set(); + for (const resourceName of requestedResourceNames) { + if (this.maybeSubscribe(request.type_url, clientName, resourceName) || resourceTypeState.resourceNameMap.get(resourceName)!.resourceTypeVersion > clientResourceVersion) { + updatedResources.add(resourceName); + } + } + this.handleUnsubscriptions(request.type_url, clientName, requestedResourceNames); + if (updatedResources.size > 0) { + this.sendResourceUpdates(request.type_url, new Set([clientName]), updatedResources); + } + } + + StreamAggregatedResources(call: ServerDuplexStream) { + const clientName = call.getPeer(); + this.clients.set(clientName, call); + call.on('data', (request: DiscoveryRequest__Output) => { + this.handleRequest(clientName, request); + }); + call.on('end', () => { + this.clients.delete(clientName); + for (const typeUrl of ADS_TYPE_URLS) { + this.handleUnsubscriptions(typeUrl as AdsTypeUrl, clientName); + } + call.end(); + }); + } + + StreamLoadStats(call: ServerDuplexStream) { + const statsResponse = {load_reporting_interval: {seconds: 30}}; + call.write(statsResponse); + call.on('data', (request: LoadStatsRequest__Output) => { + call.write(statsResponse); + }); + call.on('end', () => { + call.end(); + }); + } + + startServer(callback: (error: Error | null, port: number) => void) { + if (this.server) { + return; + } + const server = new Server(); + server.addService(loadedProtos.envoy.service.discovery.v3.AggregatedDiscoveryService.service, this as unknown as UntypedServiceImplementation); + server.addService(loadedProtos.envoy.service.load_stats.v3.LoadReportingService.service, this as unknown as UntypedServiceImplementation); + server.bindAsync('localhost:0', ServerCredentials.createInsecure(), (error, port) => { + if (!error) { + this.server = server; + this.port = port; + server.start(); + } + callback(error, port); + }); + } + + shutdownServer() { + this.server?.forceShutdown(); + } + + getBootstrapInfoString(): string { + if (this.port === null) { + throw new Error('Bootstrap info unavailable; server not started'); + } + const bootstrapInfo = { + xds_servers: [{ + server_uri: `localhost:${this.port}`, + channel_creds: [{type: 'insecure'}] + }], + node: { + id: 'test', + locality: {} + } + } + return JSON.stringify(bootstrapInfo); + } +} \ No newline at end of file From e32bbc7aacdca42bd4690471449c43d6c29ffec1 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 27 Jan 2023 13:39:44 -0800 Subject: [PATCH 429/450] grpc-js-xds: Allow tests to set bootstrap info in channel args --- packages/grpc-js-xds/src/load-balancer-cds.ts | 8 +++--- packages/grpc-js-xds/src/load-balancer-eds.ts | 10 ++++--- packages/grpc-js-xds/src/load-balancer-lrs.ts | 2 +- packages/grpc-js-xds/src/resolver-xds.ts | 26 ++++++++++++++----- packages/grpc-js-xds/src/xds-bootstrap.ts | 6 ++--- packages/grpc-js-xds/src/xds-client.ts | 14 +++++++--- .../src/xds-stream-state/eds-state.ts | 8 ++++++ 7 files changed, 53 insertions(+), 21 deletions(-) diff --git a/packages/grpc-js-xds/src/load-balancer-cds.ts b/packages/grpc-js-xds/src/load-balancer-cds.ts index 4d47b2546..243a1e967 100644 --- a/packages/grpc-js-xds/src/load-balancer-cds.ts +++ b/packages/grpc-js-xds/src/load-balancer-cds.ts @@ -125,6 +125,7 @@ export class CdsLoadBalancer implements LoadBalancer { private latestConfig: CdsLoadBalancingConfig | null = null; private latestAttributes: { [key: string]: unknown } = {}; + private xdsClient: XdsClient | null = null; constructor(private readonly channelControlHelper: ChannelControlHelper) { this.childBalancer = new ChildLoadBalancerHandler(channelControlHelper); @@ -188,6 +189,7 @@ export class CdsLoadBalancer implements LoadBalancer { } trace('Received update with config ' + JSON.stringify(lbConfig, undefined, 2)); this.latestAttributes = attributes; + this.xdsClient = attributes.xdsClient as XdsClient; /* If the cluster is changing, disable the old watcher before adding the new * one */ @@ -196,7 +198,7 @@ export class CdsLoadBalancer implements LoadBalancer { this.latestConfig?.getCluster() !== lbConfig.getCluster() ) { trace('Removing old cluster watcher for cluster name ' + this.latestConfig!.getCluster()); - getSingletonXdsClient().removeClusterWatcher( + this.xdsClient.removeClusterWatcher( this.latestConfig!.getCluster(), this.watcher ); @@ -212,7 +214,7 @@ export class CdsLoadBalancer implements LoadBalancer { if (!this.isWatcherActive) { trace('Adding new cluster watcher for cluster name ' + lbConfig.getCluster()); - getSingletonXdsClient().addClusterWatcher(lbConfig.getCluster(), this.watcher); + this.xdsClient.addClusterWatcher(lbConfig.getCluster(), this.watcher); this.isWatcherActive = true; } } @@ -226,7 +228,7 @@ export class CdsLoadBalancer implements LoadBalancer { trace('Destroying load balancer with cluster name ' + this.latestConfig?.getCluster()); this.childBalancer.destroy(); if (this.isWatcherActive) { - getSingletonXdsClient().removeClusterWatcher( + this.xdsClient?.removeClusterWatcher( this.latestConfig!.getCluster(), this.watcher ); diff --git a/packages/grpc-js-xds/src/load-balancer-eds.ts b/packages/grpc-js-xds/src/load-balancer-eds.ts index b0bd3f030..03a4078ac 100644 --- a/packages/grpc-js-xds/src/load-balancer-eds.ts +++ b/packages/grpc-js-xds/src/load-balancer-eds.ts @@ -167,6 +167,7 @@ export class EdsLoadBalancer implements LoadBalancer { private lastestConfig: EdsLoadBalancingConfig | null = null; private latestAttributes: { [key: string]: unknown } = {}; + private xdsClient: XdsClient | null = null; private latestEdsUpdate: ClusterLoadAssignment__Output | null = null; /** @@ -488,13 +489,14 @@ export class EdsLoadBalancer implements LoadBalancer { trace('Received update with config: ' + JSON.stringify(lbConfig, undefined, 2)); this.lastestConfig = lbConfig; this.latestAttributes = attributes; + this.xdsClient = attributes.xdsClient as XdsClient; const newEdsServiceName = lbConfig.getEdsServiceName() ?? lbConfig.getCluster(); /* If the name is changing, disable the old watcher before adding the new * one */ if (this.isWatcherActive && this.edsServiceName !== newEdsServiceName) { trace('Removing old endpoint watcher for edsServiceName ' + this.edsServiceName) - getSingletonXdsClient().removeEndpointWatcher(this.edsServiceName!, this.watcher); + this.xdsClient.removeEndpointWatcher(this.edsServiceName!, this.watcher); /* Setting isWatcherActive to false here lets us have one code path for * calling addEndpointWatcher */ this.isWatcherActive = false; @@ -507,12 +509,12 @@ export class EdsLoadBalancer implements LoadBalancer { if (!this.isWatcherActive) { trace('Adding new endpoint watcher for edsServiceName ' + this.edsServiceName); - getSingletonXdsClient().addEndpointWatcher(this.edsServiceName, this.watcher); + this.xdsClient.addEndpointWatcher(this.edsServiceName, this.watcher); this.isWatcherActive = true; } if (lbConfig.getLrsLoadReportingServerName()) { - this.clusterDropStats = getSingletonXdsClient().addClusterDropStats( + this.clusterDropStats = this.xdsClient.addClusterDropStats( lbConfig.getLrsLoadReportingServerName()!, lbConfig.getCluster(), lbConfig.getEdsServiceName() ?? '' @@ -533,7 +535,7 @@ export class EdsLoadBalancer implements LoadBalancer { destroy(): void { trace('Destroying load balancer with edsServiceName ' + this.edsServiceName); if (this.edsServiceName) { - getSingletonXdsClient().removeEndpointWatcher(this.edsServiceName, this.watcher); + this.xdsClient?.removeEndpointWatcher(this.edsServiceName, this.watcher); } this.childBalancer.destroy(); } diff --git a/packages/grpc-js-xds/src/load-balancer-lrs.ts b/packages/grpc-js-xds/src/load-balancer-lrs.ts index 745b21c5c..9610ea834 100644 --- a/packages/grpc-js-xds/src/load-balancer-lrs.ts +++ b/packages/grpc-js-xds/src/load-balancer-lrs.ts @@ -169,7 +169,7 @@ export class LrsLoadBalancer implements LoadBalancer { if (!(lbConfig instanceof LrsLoadBalancingConfig)) { return; } - this.localityStatsReporter = getSingletonXdsClient().addClusterLocalityStats( + this.localityStatsReporter = (attributes.xdsClient as XdsClient).addClusterLocalityStats( lbConfig.getLrsLoadReportingServerName(), lbConfig.getClusterName(), lbConfig.getEdsServiceName(), diff --git a/packages/grpc-js-xds/src/resolver-xds.ts b/packages/grpc-js-xds/src/resolver-xds.ts index 401465be6..9879a2c6e 100644 --- a/packages/grpc-js-xds/src/resolver-xds.ts +++ b/packages/grpc-js-xds/src/resolver-xds.ts @@ -48,6 +48,7 @@ import { EXPERIMENTAL_FAULT_INJECTION, EXPERIMENTAL_RETRY } from './environment' import Filter = experimental.Filter; import FilterFactory = experimental.FilterFactory; import RetryPolicy = experimental.RetryPolicy; +import { validateBootstrapConfig } from './xds-bootstrap'; const TRACER_NAME = 'xds_resolver'; @@ -210,6 +211,8 @@ function getDefaultRetryMaxInterval(baseInterval: string): string { return `${Number.parseFloat(baseInterval.substring(0, baseInterval.length - 1)) * 10}s`; } +const BOOTSTRAP_CONFIG_KEY = 'grpc.TEST_ONLY_DO_NOT_USE_IN_PROD.xds_bootstrap_config'; + const RETRY_CODES: {[key: string]: status} = { 'cancelled': status.CANCELLED, 'deadline-exceeded': status.DEADLINE_EXCEEDED, @@ -238,11 +241,20 @@ class XdsResolver implements Resolver { private ldsHttpFilterConfigs: {name: string, config: HttpFilterConfig}[] = []; + private xdsClient: XdsClient; + constructor( private target: GrpcUri, private listener: ResolverListener, private channelOptions: ChannelOptions ) { + if (channelOptions[BOOTSTRAP_CONFIG_KEY]) { + const parsedConfig = JSON.parse(channelOptions[BOOTSTRAP_CONFIG_KEY]); + const validatedConfig = validateBootstrapConfig(parsedConfig); + this.xdsClient = new XdsClient(validatedConfig); + } else { + this.xdsClient = getSingletonXdsClient(); + } this.ldsWatcher = { onValidUpdate: (update: Listener__Output) => { const httpConnectionManager = decodeSingleResource(HTTP_CONNECTION_MANGER_TYPE_URL, update.api_listener!.api_listener!.value); @@ -267,16 +279,16 @@ class XdsResolver implements Resolver { const routeConfigName = httpConnectionManager.rds!.route_config_name; if (this.latestRouteConfigName !== routeConfigName) { if (this.latestRouteConfigName !== null) { - getSingletonXdsClient().removeRouteWatcher(this.latestRouteConfigName, this.rdsWatcher); + this.xdsClient.removeRouteWatcher(this.latestRouteConfigName, this.rdsWatcher); } - getSingletonXdsClient().addRouteWatcher(httpConnectionManager.rds!.route_config_name, this.rdsWatcher); + this.xdsClient.addRouteWatcher(httpConnectionManager.rds!.route_config_name, this.rdsWatcher); this.latestRouteConfigName = routeConfigName; } break; } case 'route_config': if (this.latestRouteConfigName) { - getSingletonXdsClient().removeRouteWatcher(this.latestRouteConfigName, this.rdsWatcher); + this.xdsClient.removeRouteWatcher(this.latestRouteConfigName, this.rdsWatcher); } this.handleRouteConfig(httpConnectionManager.route_config!); break; @@ -546,7 +558,7 @@ class XdsResolver implements Resolver { methodConfig: [], loadBalancingConfig: [lbPolicyConfig] } - this.listener.onSuccessfulResolution([], serviceConfig, null, configSelector, {}); + this.listener.onSuccessfulResolution([], serviceConfig, null, configSelector, {xdsClient: this.xdsClient}); } private reportResolutionError(reason: string) { @@ -563,15 +575,15 @@ class XdsResolver implements Resolver { // Wait until updateResolution is called once to start the xDS requests if (!this.isLdsWatcherActive) { trace('Starting resolution for target ' + uriToString(this.target)); - getSingletonXdsClient().addListenerWatcher(this.target.path, this.ldsWatcher); + this.xdsClient.addListenerWatcher(this.target.path, this.ldsWatcher); this.isLdsWatcherActive = true; } } destroy() { - getSingletonXdsClient().removeListenerWatcher(this.target.path, this.ldsWatcher); + this.xdsClient.removeListenerWatcher(this.target.path, this.ldsWatcher); if (this.latestRouteConfigName) { - getSingletonXdsClient().removeRouteWatcher(this.latestRouteConfigName, this.rdsWatcher); + this.xdsClient.removeRouteWatcher(this.latestRouteConfigName, this.rdsWatcher); } } diff --git a/packages/grpc-js-xds/src/xds-bootstrap.ts b/packages/grpc-js-xds/src/xds-bootstrap.ts index 876b6d958..72a0ca375 100644 --- a/packages/grpc-js-xds/src/xds-bootstrap.ts +++ b/packages/grpc-js-xds/src/xds-bootstrap.ts @@ -231,7 +231,7 @@ function validateNode(obj: any): Node { return result; } -function validateBootstrapFile(obj: any): BootstrapInfo { +export function validateBootstrapConfig(obj: any): BootstrapInfo { return { xdsServers: obj.xds_servers.map(validateXdsServerConfig), node: validateNode(obj.node), @@ -265,7 +265,7 @@ export async function loadBootstrapInfo(): Promise { } try { const parsedFile = JSON.parse(data); - resolve(validateBootstrapFile(parsedFile)); + resolve(validateBootstrapConfig(parsedFile)); } catch (e) { reject( new Error( @@ -290,7 +290,7 @@ export async function loadBootstrapInfo(): Promise { if (bootstrapConfig) { try { const parsedConfig = JSON.parse(bootstrapConfig); - const loadedBootstrapInfoValue = validateBootstrapFile(parsedConfig); + const loadedBootstrapInfoValue = validateBootstrapConfig(parsedConfig); loadedBootstrapInfo = Promise.resolve(loadedBootstrapInfoValue); } catch (e) { throw new Error( diff --git a/packages/grpc-js-xds/src/xds-client.ts b/packages/grpc-js-xds/src/xds-client.ts index 2dfa41236..a2d33d1a5 100644 --- a/packages/grpc-js-xds/src/xds-client.ts +++ b/packages/grpc-js-xds/src/xds-client.ts @@ -21,7 +21,7 @@ import { loadProtosWithOptionsSync } from '@grpc/proto-loader/build/src/util'; import { loadPackageDefinition, StatusObject, status, logVerbosity, Metadata, experimental, ChannelOptions, ClientDuplexStream, ServiceError, ChannelCredentials, Channel, connectivityState } from '@grpc/grpc-js'; import * as adsTypes from './generated/ads'; import * as lrsTypes from './generated/lrs'; -import { loadBootstrapInfo } from './xds-bootstrap'; +import { BootstrapInfo, loadBootstrapInfo } from './xds-bootstrap'; import { Node } from './generated/envoy/config/core/v3/Node'; import { AggregatedDiscoveryServiceClient } from './generated/envoy/service/discovery/v3/AggregatedDiscoveryService'; import { DiscoveryRequest } from './generated/envoy/service/discovery/v3/DiscoveryRequest'; @@ -276,7 +276,7 @@ export class XdsClient { private adsBackoff: BackoffTimeout; private lrsBackoff: BackoffTimeout; - constructor() { + constructor(bootstrapInfoOverride?: BootstrapInfo) { const edsState = new EdsState(() => { this.updateNames('eds'); }); @@ -310,7 +310,15 @@ export class XdsClient { }); this.lrsBackoff.unref(); - Promise.all([loadBootstrapInfo(), loadAdsProtos()]).then( + async function getBootstrapInfo(): Promise { + if (bootstrapInfoOverride) { + return bootstrapInfoOverride; + } else { + return loadBootstrapInfo(); + } + } + + Promise.all([getBootstrapInfo(), loadAdsProtos()]).then( ([bootstrapInfo, protoDefinitions]) => { if (this.hasShutdown) { return; diff --git a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts index cec6a4764..b043ebbc0 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/eds-state.ts @@ -61,10 +61,12 @@ export class EdsState extends BaseXdsStreamState const priorityTotalWeights: Map = new Map(); for (const endpoint of message.endpoints) { if (!endpoint.locality) { + trace('EDS validation: endpoint locality unset'); return false; } for (const {locality, priority} of seenLocalities) { if (localitiesEqual(endpoint.locality, locality) && endpoint.priority === priority) { + trace('EDS validation: endpoint locality duplicated: ' + JSON.stringify(locality) + ', priority=' + priority); return false; } } @@ -72,16 +74,20 @@ export class EdsState extends BaseXdsStreamState for (const lb of endpoint.lb_endpoints) { const socketAddress = lb.endpoint?.address?.socket_address; if (!socketAddress) { + trace('EDS validation: endpoint socket_address not set'); return false; } if (socketAddress.port_specifier !== 'port_value') { + trace('EDS validation: socket_address.port_specifier !== "port_value"'); return false; } if (!(isIPv4(socketAddress.address) || isIPv6(socketAddress.address))) { + trace('EDS validation: address not a valid IPv4 or IPv6 address: ' + socketAddress.address); return false; } for (const address of seenAddresses) { if (addressesEqual(socketAddress, address)) { + trace('EDS validation: duplicate address seen: ' + address); return false; } } @@ -91,11 +97,13 @@ export class EdsState extends BaseXdsStreamState } for (const totalWeight of priorityTotalWeights.values()) { if (totalWeight > UINT32_MAX) { + trace('EDS validation: total weight > UINT32_MAX') return false; } } for (const priority of priorityTotalWeights.keys()) { if (priority > 0 && !priorityTotalWeights.has(priority - 1)) { + trace('EDS validation: priorities not contiguous'); return false; } } From 056dc8e56ea4b59444700ac407f247e5128b6d0c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 10 Mar 2023 13:58:02 -0800 Subject: [PATCH 430/450] grpc-js: Unregister socket from channelz when closing transport --- packages/grpc-js/src/transport.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/grpc-js/src/transport.ts b/packages/grpc-js/src/transport.ts index 3c9163d13..8abc13aba 100644 --- a/packages/grpc-js/src/transport.ts +++ b/packages/grpc-js/src/transport.ts @@ -20,7 +20,7 @@ import { checkServerIdentity, CipherNameAndProtocol, ConnectionOptions, PeerCert import { StatusObject } from './call-interface'; import { ChannelCredentials } from './channel-credentials'; import { ChannelOptions } from './channel-options'; -import { ChannelzCallTracker, registerChannelzSocket, SocketInfo, SocketRef, TlsInfo } from './channelz'; +import { ChannelzCallTracker, registerChannelzSocket, SocketInfo, SocketRef, TlsInfo, unregisterChannelzRef } from './channelz'; import { LogVerbosity } from './constants'; import { getProxiedConnection, ProxyConnectionResult } from './http_proxy'; import * as logging from './logging'; @@ -471,6 +471,7 @@ class Http2Transport implements Transport { shutdown() { this.session.close(); + unregisterChannelzRef(this.channelzRef); } } From 3fbdf0d337aa88b70c0a055ff7fafcff91541b3b Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 10 Mar 2023 14:05:39 -0800 Subject: [PATCH 431/450] grpc-js: Bump version to 1.8.13 --- 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 722f9d866..815dabeb0 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.8.12", + "version": "1.8.13", "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 e5e6731917ed646f3d2bcc25304943de11758b46 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 24 Feb 2023 09:55:45 -0800 Subject: [PATCH 432/450] grpc-js-xds: Use simpler search algorithm in weighted target picker --- .../src/load-balancer-weighted-target.ts | 29 +++++-------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/packages/grpc-js-xds/src/load-balancer-weighted-target.ts b/packages/grpc-js-xds/src/load-balancer-weighted-target.ts index 5d7cfa04e..7cd92d98b 100644 --- a/packages/grpc-js-xds/src/load-balancer-weighted-target.ts +++ b/packages/grpc-js-xds/src/load-balancer-weighted-target.ts @@ -119,31 +119,16 @@ class WeightedTargetPicker implements Picker { pick(pickArgs: PickArgs): PickResult { // num | 0 is equivalent to floor(num) const selection = (Math.random() * this.rangeTotal) | 0; - - /* Binary search for the element of the list such that - * pickerList[index - 1].rangeEnd <= selection < pickerList[index].rangeEnd - */ - let mid = 0; - let startIndex = 0; - let endIndex = this.pickerList.length - 1; - let index = 0; - while (endIndex > startIndex) { - mid = ((startIndex + endIndex) / 2) | 0; - if (this.pickerList[mid].rangeEnd > selection) { - endIndex = mid; - } else if (this.pickerList[mid].rangeEnd < selection) { - startIndex = mid + 1; - } else { - // + 1 here because the range is exclusive at the top end - index = mid + 1; - break; + + for (const entry of this.pickerList) { + if (selection < entry.rangeEnd) { + return entry.picker.pick(pickArgs); } } - if (index === 0) { - index = startIndex; - } - return this.pickerList[index].picker.pick(pickArgs); + /* Default to first element if the iteration doesn't find anything for some + * reason. */ + return this.pickerList[0].picker.pick(pickArgs); } } From 7840a108d3eb9e614dee413f54df9a3b66ee600b Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 3 Apr 2023 09:54:38 -0700 Subject: [PATCH 433/450] grpc-js-xds: Use Debian and Node 18 in interop Dockerfile (1.8.x) --- packages/grpc-js-xds/interop/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js-xds/interop/Dockerfile b/packages/grpc-js-xds/interop/Dockerfile index b93e309d7..5987f1ee4 100644 --- a/packages/grpc-js-xds/interop/Dockerfile +++ b/packages/grpc-js-xds/interop/Dockerfile @@ -16,7 +16,7 @@ # following command from grpc-node directory: # docker build -t -f packages/grpc-js-xds/interop/Dockerfile . -FROM node:16-alpine as build +FROM node:18-slim as build # Make a grpc-node directory and copy the repo into it. WORKDIR /node/src/grpc-node @@ -27,7 +27,7 @@ RUN npm install WORKDIR /node/src/grpc-node/packages/grpc-js-xds RUN npm install -FROM node:16-alpine +FROM node:18-slim WORKDIR /node/src/grpc-node COPY --from=build /node/src/grpc-node/packages/grpc-js ./packages/grpc-js/ COPY --from=build /node/src/grpc-node/packages/grpc-js-xds ./packages/grpc-js-xds/ From 43d42dcf3f2409c53a623b46ab72c89af353e4e8 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 11 Apr 2023 14:24:25 -0700 Subject: [PATCH 434/450] grpc-js: Fix connectivity state change event sequencing --- .../grpc-js/src/load-balancer-pick-first.ts | 2 +- packages/grpc-js/src/subchannel.ts | 65 ++++----- .../test/test-global-subchannel-pool.ts | 130 ++++++++++++++++++ 3 files changed, 165 insertions(+), 32 deletions(-) create mode 100644 packages/grpc-js/test/test-global-subchannel-pool.ts diff --git a/packages/grpc-js/src/load-balancer-pick-first.ts b/packages/grpc-js/src/load-balancer-pick-first.ts index a501b1f7d..41d21a2ea 100644 --- a/packages/grpc-js/src/load-balancer-pick-first.ts +++ b/packages/grpc-js/src/load-balancer-pick-first.ts @@ -322,12 +322,12 @@ export class PickFirstLoadBalancer implements LoadBalancer { ); } this.currentPick = subchannel; - this.updateState(ConnectivityState.READY, new PickFirstPicker(subchannel)); subchannel.addConnectivityStateListener(this.pickedSubchannelStateListener); subchannel.ref(); this.channelControlHelper.addChannelzChild(subchannel.getChannelzRef()); this.resetSubchannelList(); clearTimeout(this.connectionDelayTimeout); + this.updateState(ConnectivityState.READY, new PickFirstPicker(subchannel)); } private updateState(newState: ConnectivityState, picker: Picker) { diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index c93e0c451..de420cc97 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -60,7 +60,7 @@ export class Subchannel { * state changes. Will be modified by `addConnectivityStateListener` and * `removeConnectivityStateListener` */ - private stateListeners: ConnectivityStateListener[] = []; + private stateListeners: Set = new Set(); private backoffTimeout: BackoffTimeout; @@ -227,6 +227,8 @@ export class Subchannel { } const previousState = this.connectivityState; this.connectivityState = newState; + process.nextTick(() => { + }); switch (newState) { case ConnectivityState.READY: this.stopBackoff(); @@ -261,9 +263,7 @@ export class Subchannel { default: throw new Error(`Invalid state: unknown ConnectivityState ${newState}`); } - /* We use a shallow copy of the stateListeners array in case a listener - * is removed during this iteration */ - for (const listener of [...this.stateListeners]) { + for (const listener of this.stateListeners) { listener(this, previousState, newState, this.keepaliveTime); } return true; @@ -291,13 +291,15 @@ export class Subchannel { if (this.channelzEnabled) { this.channelzTrace.addTrace('CT_INFO', 'Shutting down'); } - this.transitionToState( - [ConnectivityState.CONNECTING, ConnectivityState.READY], - ConnectivityState.IDLE - ); if (this.channelzEnabled) { unregisterChannelzRef(this.channelzRef); } + process.nextTick(() => { + this.transitionToState( + [ConnectivityState.CONNECTING, ConnectivityState.READY], + ConnectivityState.IDLE + ); + }); } } @@ -339,20 +341,22 @@ export class Subchannel { * Otherwise, do nothing. */ startConnecting() { - /* First, try to transition from IDLE to connecting. If that doesn't happen - * because the state is not currently IDLE, check if it is - * TRANSIENT_FAILURE, and if so indicate that it should go back to - * connecting after the backoff timer ends. Otherwise do nothing */ - if ( - !this.transitionToState( - [ConnectivityState.IDLE], - ConnectivityState.CONNECTING - ) - ) { - if (this.connectivityState === ConnectivityState.TRANSIENT_FAILURE) { - this.continueConnecting = true; + process.nextTick(() => { + /* First, try to transition from IDLE to connecting. If that doesn't happen + * because the state is not currently IDLE, check if it is + * TRANSIENT_FAILURE, and if so indicate that it should go back to + * connecting after the backoff timer ends. Otherwise do nothing */ + if ( + !this.transitionToState( + [ConnectivityState.IDLE], + ConnectivityState.CONNECTING + ) + ) { + if (this.connectivityState === ConnectivityState.TRANSIENT_FAILURE) { + this.continueConnecting = true; + } } - } + }); } /** @@ -368,7 +372,7 @@ export class Subchannel { * @param listener */ addConnectivityStateListener(listener: ConnectivityStateListener) { - this.stateListeners.push(listener); + this.stateListeners.add(listener); } /** @@ -377,21 +381,20 @@ export class Subchannel { * `addConnectivityStateListener` */ removeConnectivityStateListener(listener: ConnectivityStateListener) { - const listenerIndex = this.stateListeners.indexOf(listener); - if (listenerIndex > -1) { - this.stateListeners.splice(listenerIndex, 1); - } + this.stateListeners.delete(listener); } /** * Reset the backoff timeout, and immediately start connecting if in backoff. */ resetBackoff() { - this.backoffTimeout.reset(); - this.transitionToState( - [ConnectivityState.TRANSIENT_FAILURE], - ConnectivityState.CONNECTING - ); + process.nextTick(() => { + this.backoffTimeout.reset(); + this.transitionToState( + [ConnectivityState.TRANSIENT_FAILURE], + ConnectivityState.CONNECTING + ); + }); } getAddress(): string { diff --git a/packages/grpc-js/test/test-global-subchannel-pool.ts b/packages/grpc-js/test/test-global-subchannel-pool.ts new file mode 100644 index 000000000..c19125687 --- /dev/null +++ b/packages/grpc-js/test/test-global-subchannel-pool.ts @@ -0,0 +1,130 @@ +/* + * Copyright 2023 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 * as assert from 'assert'; +import * as path from 'path'; + +import * as grpc from '../src'; +import {sendUnaryData, Server, ServerCredentials, ServerUnaryCall, ServiceClientConstructor, ServiceError} from '../src'; + +import {loadProtoFile} from './common'; + +const protoFile = path.join(__dirname, 'fixtures', 'echo_service.proto'); +const echoService = + loadProtoFile(protoFile).EchoService as ServiceClientConstructor; + +describe.only('Global subchannel pool', () => { + let server: Server; + let serverPort: number; + + let client1: InstanceType; + let client2: InstanceType; + + let promises: Promise[]; + + before(done => { + server = new Server(); + server.addService(echoService.service, { + echo(call: ServerUnaryCall, callback: sendUnaryData) { + callback(null, call.request); + }, + }); + + server.bindAsync( + 'localhost:0', ServerCredentials.createInsecure(), (err, port) => { + assert.ifError(err); + serverPort = port; + server.start(); + done(); + }); + }); + + beforeEach(() => { + promises = []; + }) + + after(done => { + server.tryShutdown(done); + }); + + function callService(client: InstanceType) { + return new Promise((resolve) => { + const request = {value: 'test value', value2: 3}; + + client.echo(request, (error: ServiceError, response: any) => { + assert.ifError(error); + assert.deepStrictEqual(response, request); + resolve(); + }); + }) + } + + function connect() { + const grpcOptions = { + 'grpc.use_local_subchannel_pool': 0, + } + + client1 = new echoService( + `127.0.0.1:${serverPort}`, grpc.credentials.createInsecure(), + grpcOptions); + + client2 = new echoService( + `127.0.0.1:${serverPort}`, grpc.credentials.createInsecure(), + grpcOptions); + } + + /* This is a regression test for a bug where client1.close in the + * waitForReady callback would cause the subchannel to transition to IDLE + * even though client2 is also using it. */ + it('Should handle client.close calls in waitForReady', + done => { + connect(); + + promises.push(new Promise((resolve) => { + client1.waitForReady(Date.now() + 50, (error) => { + assert.ifError(error); + client1.close(); + resolve(); + }); + })) + + promises.push(new Promise((resolve) => { + client2.waitForReady(Date.now() + 50, (error) => { + assert.ifError(error); + resolve(); + }); + })) + + Promise.all(promises).then(() => {done()}); + }) + + it('Call the service', done => { + promises.push(callService(client2)); + + Promise.all(promises).then(() => { + done(); + }); + }) + + it('Should complete the client lifecycle without error', done => { + setTimeout(() => { + client1.close(); + client2.close(); + done() + }, 500); + }); +}); From 6bc85716cd65bea8e532341efaf1e0331ec9328c Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 12 Apr 2023 14:46:27 -0700 Subject: [PATCH 435/450] grpc-js: Bump version to 1.8.14 --- 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 815dabeb0..dd341ef03 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.8.13", + "version": "1.8.14", "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 37099980127e05a83c9f3d609879c0af6ca4e66b Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 13 Apr 2023 09:25:38 -0700 Subject: [PATCH 436/450] grpc-js: Fix a couple of errors from a previous PR --- packages/grpc-js/src/subchannel.ts | 2 -- packages/grpc-js/test/test-global-subchannel-pool.ts | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/grpc-js/src/subchannel.ts b/packages/grpc-js/src/subchannel.ts index de420cc97..307f6b81e 100644 --- a/packages/grpc-js/src/subchannel.ts +++ b/packages/grpc-js/src/subchannel.ts @@ -227,8 +227,6 @@ export class Subchannel { } const previousState = this.connectivityState; this.connectivityState = newState; - process.nextTick(() => { - }); switch (newState) { case ConnectivityState.READY: this.stopBackoff(); diff --git a/packages/grpc-js/test/test-global-subchannel-pool.ts b/packages/grpc-js/test/test-global-subchannel-pool.ts index c19125687..999a11bf7 100644 --- a/packages/grpc-js/test/test-global-subchannel-pool.ts +++ b/packages/grpc-js/test/test-global-subchannel-pool.ts @@ -27,7 +27,7 @@ const protoFile = path.join(__dirname, 'fixtures', 'echo_service.proto'); const echoService = loadProtoFile(protoFile).EchoService as ServiceClientConstructor; -describe.only('Global subchannel pool', () => { +describe('Global subchannel pool', () => { let server: Server; let serverPort: number; From 2cb6ef86d4debde64e440d53ddb0f5ae10f228c7 Mon Sep 17 00:00:00 2001 From: Sergii Tkachenko Date: Fri, 7 Apr 2023 14:45:21 -0700 Subject: [PATCH 437/450] PSM Interop: experiment with qps affect on circuit_breaking ref b/232859415 --- packages/grpc-js-xds/scripts/xds.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/grpc-js-xds/scripts/xds.sh b/packages/grpc-js-xds/scripts/xds.sh index d4490c5ef..af22f584f 100755 --- a/packages/grpc-js-xds/scripts/xds.sh +++ b/packages/grpc-js-xds/scripts/xds.sh @@ -60,6 +60,7 @@ GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weigh --path_to_server_binary=/java_server/grpc-java/interop-testing/build/install/grpc-interop-testing/bin/xds-test-server \ --gcp_suffix=$(date '+%s') \ --verbose \ + --qps=50 \ ${XDS_V3_OPT-} \ --client_cmd="$(which node) --enable-source-maps --prof --logfile=${KOKORO_ARTIFACTS_DIR}/github/grpc/reports/prof.log grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client \ --server=xds:///{server_uri} \ From 856559cce1d27771d50dc97d130f5dc423dd4723 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 20 Apr 2023 14:34:06 -0700 Subject: [PATCH 438/450] grpc-js-xds: Fix handling of resource validation errors --- .../src/xds-stream-state/xds-stream-state.ts | 46 +++--- packages/grpc-js-xds/test/test-nack.ts | 156 ++++++++++++++++++ 2 files changed, 182 insertions(+), 20 deletions(-) create mode 100644 packages/grpc-js-xds/test/test-nack.ts diff --git a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts index e20bc7e9b..b2d7b2279 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts @@ -15,7 +15,7 @@ * */ -import { experimental, logVerbosity, StatusObject } from "@grpc/grpc-js"; +import { experimental, logVerbosity, Metadata, status, StatusObject } from "@grpc/grpc-js"; import { Any__Output } from "../generated/google/protobuf/Any"; const TRACER_NAME = 'xds_client'; @@ -157,19 +157,32 @@ export abstract class BaseXdsStreamState implements XdsStreamState return Array.from(this.subscriptions.keys()); } handleResponses(responses: ResourcePair[]): HandleResponseResult { - const validResponses: ResponseType[] = []; let result: HandleResponseResult = { accepted: [], rejected: [], missing: [] } + const allResourceNames = new Set(); for (const {resource, raw} of responses) { const resourceName = this.getResourceName(resource); + allResourceNames.add(resourceName); + const subscriptionEntry = this.subscriptions.get(resourceName); if (this.validateResponse(resource)) { - validResponses.push(resource); result.accepted.push({ name: resourceName, raw: raw}); + if (subscriptionEntry) { + const watchers = subscriptionEntry.watchers; + for (const watcher of watchers) { + watcher.onValidUpdate(resource); + } + clearTimeout(subscriptionEntry.resourceTimer); + subscriptionEntry.cachedResponse = resource; + if (subscriptionEntry.deletionIgnored) { + experimental.log(logVerbosity.INFO, 'Received resource with previously ignored deletion: ' + resourceName); + subscriptionEntry.deletionIgnored = false; + } + } } else { this.trace('Validation failed for message ' + JSON.stringify(resource)); result.rejected.push({ @@ -177,23 +190,16 @@ export abstract class BaseXdsStreamState implements XdsStreamState raw: raw, error: `Validation failed for resource ${resourceName}` }); - } - } - const allResourceNames = new Set(); - for (const resource of validResponses) { - const resourceName = this.getResourceName(resource); - allResourceNames.add(resourceName); - const subscriptionEntry = this.subscriptions.get(resourceName); - if (subscriptionEntry) { - const watchers = subscriptionEntry.watchers; - for (const watcher of watchers) { - watcher.onValidUpdate(resource); - } - clearTimeout(subscriptionEntry.resourceTimer); - subscriptionEntry.cachedResponse = resource; - if (subscriptionEntry.deletionIgnored) { - experimental.log(logVerbosity.INFO, 'Received resource with previously ignored deletion: ' + resourceName); - subscriptionEntry.deletionIgnored = false; + if (subscriptionEntry) { + const watchers = subscriptionEntry.watchers; + for (const watcher of watchers) { + watcher.onTransientError({ + code: status.UNAVAILABLE, + details: `Validation failed for resource ${resourceName}`, + metadata: new Metadata() + }); + } + clearTimeout(subscriptionEntry.resourceTimer); } } } diff --git a/packages/grpc-js-xds/test/test-nack.ts b/packages/grpc-js-xds/test/test-nack.ts new file mode 100644 index 000000000..ad1aad448 --- /dev/null +++ b/packages/grpc-js-xds/test/test-nack.ts @@ -0,0 +1,156 @@ +/* + * Copyright 2023 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 * as assert from 'assert'; +import { register } from "../src"; +import { Backend } from "./backend"; +import { XdsTestClient } from "./client"; +import { FakeCluster, FakeRouteGroup } from "./framework"; +import { XdsServer } from "./xds-server"; + +register(); + +describe('Validation errors', () => { + let xdsServer: XdsServer; + let client: XdsTestClient; + beforeEach(done => { + xdsServer = new XdsServer(); + xdsServer.startServer(error => { + done(error); + }); + }); + afterEach(() => { + client?.close(); + xdsServer?.shutdownServer(); + }); + it('Should continue to use a valid resource after receiving an invalid EDS update', done => { + const cluster = new FakeCluster('cluster1', [{backends: [new Backend()], locality:{region: 'region1'}}]); + const routeGroup = new FakeRouteGroup('route1', [{cluster: cluster}]); + routeGroup.startAllBackends().then(() => { + xdsServer.setEdsResource(cluster.getEndpointConfig()); + xdsServer.setCdsResource(cluster.getClusterConfig()); + xdsServer.setRdsResource(routeGroup.getRouteConfiguration()); + xdsServer.setLdsResource(routeGroup.getListener()); + client = new XdsTestClient('route1', xdsServer); + client.startCalls(100); + routeGroup.waitForAllBackendsToReceiveTraffic().then(() => { + // After backends receive calls, set invalid EDS resource + xdsServer.setEdsResource({cluster_name: cluster.getEndpointConfig().cluster_name, endpoints: [{}]}); + let seenNack = false; + xdsServer.addResponseListener((typeUrl, responseState) => { + if (responseState.state === 'NACKED') { + if (seenNack) { + return; + } + seenNack = true; + routeGroup.waitForAllBackendsToReceiveTraffic().then(() => { + client.stopCalls(); + done(); + }); + } + }); + }, reason => done(reason)); + }, reason => done(reason)); + }); + it('Should continue to use a valid resource after receiving an invalid CDS update', done => { + const cluster = new FakeCluster('cluster1', [{backends: [new Backend()], locality:{region: 'region1'}}]); + const routeGroup = new FakeRouteGroup('route1', [{cluster: cluster}]); + routeGroup.startAllBackends().then(() => { + xdsServer.setEdsResource(cluster.getEndpointConfig()); + xdsServer.setCdsResource(cluster.getClusterConfig()); + xdsServer.setRdsResource(routeGroup.getRouteConfiguration()); + xdsServer.setLdsResource(routeGroup.getListener()); + client = new XdsTestClient('route1', xdsServer); + client.startCalls(100); + routeGroup.waitForAllBackendsToReceiveTraffic().then(() => { + // After backends receive calls, set invalid CDS resource + xdsServer.setCdsResource({name: cluster.getClusterConfig().name}); + let seenNack = false; + xdsServer.addResponseListener((typeUrl, responseState) => { + if (responseState.state === 'NACKED') { + if (seenNack) { + return; + } + seenNack = true; + routeGroup.waitForAllBackendsToReceiveTraffic().then(() => { + client.stopCalls(); + done(); + }); + } + }); + }, reason => done(reason)); + }, reason => done(reason)); + }); + it('Should continue to use a valid resource after receiving an invalid RDS update', done => { + const cluster = new FakeCluster('cluster1', [{backends: [new Backend()], locality:{region: 'region1'}}]); + const routeGroup = new FakeRouteGroup('route1', [{cluster: cluster}]); + routeGroup.startAllBackends().then(() => { + xdsServer.setEdsResource(cluster.getEndpointConfig()); + xdsServer.setCdsResource(cluster.getClusterConfig()); + xdsServer.setRdsResource(routeGroup.getRouteConfiguration()); + xdsServer.setLdsResource(routeGroup.getListener()); + client = new XdsTestClient('route1', xdsServer); + client.startCalls(100); + routeGroup.waitForAllBackendsToReceiveTraffic().then(() => { + // After backends receive calls, set invalid RDS resource + xdsServer.setRdsResource({name: routeGroup.getRouteConfiguration().name, virtual_hosts: [{domains: ['**']}]}); + let seenNack = false; + xdsServer.addResponseListener((typeUrl, responseState) => { + if (responseState.state === 'NACKED') { + if (seenNack) { + return; + } + seenNack = true; + routeGroup.waitForAllBackendsToReceiveTraffic().then(() => { + client.stopCalls(); + done(); + }); + } + }); + }, reason => done(reason)); + }, reason => done(reason)); + }); + it('Should continue to use a valid resource after receiving an invalid LDS update', done => { + const cluster = new FakeCluster('cluster1', [{backends: [new Backend()], locality:{region: 'region1'}}]); + const routeGroup = new FakeRouteGroup('route1', [{cluster: cluster}]); + routeGroup.startAllBackends().then(() => { + xdsServer.setEdsResource(cluster.getEndpointConfig()); + xdsServer.setCdsResource(cluster.getClusterConfig()); + xdsServer.setRdsResource(routeGroup.getRouteConfiguration()); + xdsServer.setLdsResource(routeGroup.getListener()); + client = new XdsTestClient('route1', xdsServer); + client.startCalls(100); + routeGroup.waitForAllBackendsToReceiveTraffic().then(() => { + // After backends receive calls, set invalid LDS resource + xdsServer.setLdsResource({name: routeGroup.getListener().name}); + let seenNack = false; + xdsServer.addResponseListener((typeUrl, responseState) => { + if (responseState.state === 'NACKED') { + if (seenNack) { + return; + } + seenNack = true; + routeGroup.waitForAllBackendsToReceiveTraffic().then(() => { + client.stopCalls(); + done(); + }); + } + }); + }, reason => done(reason)); + }, reason => done(reason)); + }); +}); \ No newline at end of file From 48ef1ed202e19c36e934015b6b1ed039cf7d2f00 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 20 Apr 2023 14:35:39 -0700 Subject: [PATCH 439/450] grpc-js-xds: Bump version to 1.8.2 --- packages/grpc-js-xds/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/package.json b/packages/grpc-js-xds/package.json index 9511776c3..7c735b652 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.8.1", + "version": "1.8.2", "description": "Plugin for @grpc/grpc-js. Adds the xds:// URL scheme and associated features.", "main": "build/src/index.js", "scripts": { From dfccd687f0bc1df7d8d7dd599249b098a772cf53 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 24 Apr 2023 16:21:12 -0700 Subject: [PATCH 440/450] Address review comments --- .../src/xds-stream-state/xds-stream-state.ts | 8 +++----- packages/grpc-js-xds/test/test-nack.ts | 20 +++++++++++-------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts index b2d7b2279..b04adb79a 100644 --- a/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts +++ b/packages/grpc-js-xds/src/xds-stream-state/xds-stream-state.ts @@ -172,14 +172,13 @@ export abstract class BaseXdsStreamState implements XdsStreamState name: resourceName, raw: raw}); if (subscriptionEntry) { - const watchers = subscriptionEntry.watchers; - for (const watcher of watchers) { + for (const watcher of subscriptionEntry.watchers) { watcher.onValidUpdate(resource); } clearTimeout(subscriptionEntry.resourceTimer); subscriptionEntry.cachedResponse = resource; if (subscriptionEntry.deletionIgnored) { - experimental.log(logVerbosity.INFO, 'Received resource with previously ignored deletion: ' + resourceName); + experimental.log(logVerbosity.INFO, `Received resource with previously ignored deletion: ${resourceName}`); subscriptionEntry.deletionIgnored = false; } } @@ -191,8 +190,7 @@ export abstract class BaseXdsStreamState implements XdsStreamState error: `Validation failed for resource ${resourceName}` }); if (subscriptionEntry) { - const watchers = subscriptionEntry.watchers; - for (const watcher of watchers) { + for (const watcher of subscriptionEntry.watchers) { watcher.onTransientError({ code: status.UNAVAILABLE, details: `Validation failed for resource ${resourceName}`, diff --git a/packages/grpc-js-xds/test/test-nack.ts b/packages/grpc-js-xds/test/test-nack.ts index ad1aad448..b5bfb773e 100644 --- a/packages/grpc-js-xds/test/test-nack.ts +++ b/packages/grpc-js-xds/test/test-nack.ts @@ -38,7 +38,7 @@ describe('Validation errors', () => { xdsServer?.shutdownServer(); }); it('Should continue to use a valid resource after receiving an invalid EDS update', done => { - const cluster = new FakeCluster('cluster1', [{backends: [new Backend()], locality:{region: 'region1'}}]); + const cluster = new FakeCluster('cluster1', [{backends: [new Backend()], locality: {region: 'region1'}}]); const routeGroup = new FakeRouteGroup('route1', [{cluster: cluster}]); routeGroup.startAllBackends().then(() => { xdsServer.setEdsResource(cluster.getEndpointConfig()); @@ -49,7 +49,8 @@ describe('Validation errors', () => { client.startCalls(100); routeGroup.waitForAllBackendsToReceiveTraffic().then(() => { // After backends receive calls, set invalid EDS resource - xdsServer.setEdsResource({cluster_name: cluster.getEndpointConfig().cluster_name, endpoints: [{}]}); + const invalidEdsResource = {cluster_name: cluster.getEndpointConfig().cluster_name, endpoints: [{}]}; + xdsServer.setEdsResource(invalidEdsResource); let seenNack = false; xdsServer.addResponseListener((typeUrl, responseState) => { if (responseState.state === 'NACKED') { @@ -67,7 +68,7 @@ describe('Validation errors', () => { }, reason => done(reason)); }); it('Should continue to use a valid resource after receiving an invalid CDS update', done => { - const cluster = new FakeCluster('cluster1', [{backends: [new Backend()], locality:{region: 'region1'}}]); + const cluster = new FakeCluster('cluster1', [{backends: [new Backend()], locality: {region: 'region1'}}]); const routeGroup = new FakeRouteGroup('route1', [{cluster: cluster}]); routeGroup.startAllBackends().then(() => { xdsServer.setEdsResource(cluster.getEndpointConfig()); @@ -78,7 +79,8 @@ describe('Validation errors', () => { client.startCalls(100); routeGroup.waitForAllBackendsToReceiveTraffic().then(() => { // After backends receive calls, set invalid CDS resource - xdsServer.setCdsResource({name: cluster.getClusterConfig().name}); + const invalidCdsResource = {name: cluster.getClusterConfig().name}; + xdsServer.setCdsResource(invalidCdsResource); let seenNack = false; xdsServer.addResponseListener((typeUrl, responseState) => { if (responseState.state === 'NACKED') { @@ -96,7 +98,7 @@ describe('Validation errors', () => { }, reason => done(reason)); }); it('Should continue to use a valid resource after receiving an invalid RDS update', done => { - const cluster = new FakeCluster('cluster1', [{backends: [new Backend()], locality:{region: 'region1'}}]); + const cluster = new FakeCluster('cluster1', [{backends: [new Backend()], locality: {region: 'region1'}}]); const routeGroup = new FakeRouteGroup('route1', [{cluster: cluster}]); routeGroup.startAllBackends().then(() => { xdsServer.setEdsResource(cluster.getEndpointConfig()); @@ -107,7 +109,8 @@ describe('Validation errors', () => { client.startCalls(100); routeGroup.waitForAllBackendsToReceiveTraffic().then(() => { // After backends receive calls, set invalid RDS resource - xdsServer.setRdsResource({name: routeGroup.getRouteConfiguration().name, virtual_hosts: [{domains: ['**']}]}); + const invalidRdsResource = {name: routeGroup.getRouteConfiguration().name, virtual_hosts: [{domains: ['**']}]}; + xdsServer.setRdsResource(invalidRdsResource); let seenNack = false; xdsServer.addResponseListener((typeUrl, responseState) => { if (responseState.state === 'NACKED') { @@ -125,7 +128,7 @@ describe('Validation errors', () => { }, reason => done(reason)); }); it('Should continue to use a valid resource after receiving an invalid LDS update', done => { - const cluster = new FakeCluster('cluster1', [{backends: [new Backend()], locality:{region: 'region1'}}]); + const cluster = new FakeCluster('cluster1', [{backends: [new Backend()], locality: {region: 'region1'}}]); const routeGroup = new FakeRouteGroup('route1', [{cluster: cluster}]); routeGroup.startAllBackends().then(() => { xdsServer.setEdsResource(cluster.getEndpointConfig()); @@ -136,7 +139,8 @@ describe('Validation errors', () => { client.startCalls(100); routeGroup.waitForAllBackendsToReceiveTraffic().then(() => { // After backends receive calls, set invalid LDS resource - xdsServer.setLdsResource({name: routeGroup.getListener().name}); + const invalidLdsResource = {name: routeGroup.getListener().name}; + xdsServer.setLdsResource(invalidLdsResource); let seenNack = false; xdsServer.addResponseListener((typeUrl, responseState) => { if (responseState.state === 'NACKED') { From edeeda6424d568b80eb4478b63afba05c51904a5 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Mon, 24 Apr 2023 16:22:49 -0700 Subject: [PATCH 441/450] Add trailing newline in packages/grpc-js-xds/test/test-nack.ts Co-authored-by: Sergii Tkachenko --- packages/grpc-js-xds/test/test-nack.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/test/test-nack.ts b/packages/grpc-js-xds/test/test-nack.ts index b5bfb773e..9395628a6 100644 --- a/packages/grpc-js-xds/test/test-nack.ts +++ b/packages/grpc-js-xds/test/test-nack.ts @@ -157,4 +157,4 @@ describe('Validation errors', () => { }, reason => done(reason)); }, reason => done(reason)); }); -}); \ No newline at end of file +}); From 0933633424b5eeec56d047d5e9fd2dd09dff4ac9 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 28 Apr 2023 15:00:05 -0700 Subject: [PATCH 442/450] PSM Interop: Increase old driver QPS to 75 --- packages/grpc-js-xds/scripts/xds.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/scripts/xds.sh b/packages/grpc-js-xds/scripts/xds.sh index af22f584f..7e6794a31 100755 --- a/packages/grpc-js-xds/scripts/xds.sh +++ b/packages/grpc-js-xds/scripts/xds.sh @@ -60,7 +60,7 @@ GRPC_NODE_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weigh --path_to_server_binary=/java_server/grpc-java/interop-testing/build/install/grpc-interop-testing/bin/xds-test-server \ --gcp_suffix=$(date '+%s') \ --verbose \ - --qps=50 \ + --qps=75 \ ${XDS_V3_OPT-} \ --client_cmd="$(which node) --enable-source-maps --prof --logfile=${KOKORO_ARTIFACTS_DIR}/github/grpc/reports/prof.log grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client \ --server=xds:///{server_uri} \ From 2b455e7d18d1c108bd1ca901678c757434c054b7 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 31 May 2023 14:05:10 -0700 Subject: [PATCH 443/450] grpc-js: Fix a couple of minor issues --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/client.ts | 36 ++++++++++++++------- packages/grpc-js/src/load-balancing-call.ts | 8 +++-- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index dd341ef03..7d8c1a597 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.8.14", + "version": "1.8.15", "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/client.ts b/packages/grpc-js/src/client.ts index f96f8fdf0..bdbdc6e97 100644 --- a/packages/grpc-js/src/client.ts +++ b/packages/grpc-js/src/client.ts @@ -323,7 +323,7 @@ export class Client { emitter.call = call; let responseMessage: ResponseType | null = null; let receivedStatus = false; - const callerStackError = new Error(); + let callerStackError: Error | null = new Error(); call.start(callProperties.metadata, { onReceiveMetadata: (metadata) => { emitter.emit('metadata', metadata); @@ -342,19 +342,22 @@ export class Client { receivedStatus = true; if (status.code === Status.OK) { if (responseMessage === null) { - const callerStack = getErrorStackString(callerStackError); + const callerStack = getErrorStackString(callerStackError!); callProperties.callback!(callErrorFromStatus({ code: Status.INTERNAL, details: 'No message received', metadata: status.metadata - }, callerStack)); + }, /*callerStack*/'')); } else { callProperties.callback!(null, responseMessage); } } else { - const callerStack = getErrorStackString(callerStackError); - callProperties.callback!(callErrorFromStatus(status, callerStack)); + const callerStack = getErrorStackString(callerStackError!); + callProperties.callback!(callErrorFromStatus(status, /*callerStack*/'')); } + /* Avoid retaining the callerStackError object in the call context of + * the status event handler. */ + callerStackError = null; emitter.emit('status', status); }, }); @@ -448,7 +451,7 @@ export class Client { emitter.call = call; let responseMessage: ResponseType | null = null; let receivedStatus = false; - const callerStackError = new Error(); + let callerStackError: Error | null = new Error(); call.start(callProperties.metadata, { onReceiveMetadata: (metadata) => { emitter.emit('metadata', metadata); @@ -467,7 +470,7 @@ export class Client { receivedStatus = true; if (status.code === Status.OK) { if (responseMessage === null) { - const callerStack = getErrorStackString(callerStackError); + const callerStack = getErrorStackString(callerStackError!); callProperties.callback!(callErrorFromStatus({ code: Status.INTERNAL, details: 'No message received', @@ -477,9 +480,12 @@ export class Client { callProperties.callback!(null, responseMessage); } } else { - const callerStack = getErrorStackString(callerStackError); + const callerStack = getErrorStackString(callerStackError!); callProperties.callback!(callErrorFromStatus(status, callerStack)); } + /* Avoid retaining the callerStackError object in the call context of + * the status event handler. */ + callerStackError = null; emitter.emit('status', status); }, }); @@ -577,7 +583,7 @@ export class Client { * call after that. */ stream.call = call; let receivedStatus = false; - const callerStackError = new Error(); + let callerStackError: Error | null = new Error(); call.start(callProperties.metadata, { onReceiveMetadata(metadata: Metadata) { stream.emit('metadata', metadata); @@ -593,9 +599,12 @@ export class Client { receivedStatus = true; stream.push(null); if (status.code !== Status.OK) { - const callerStack = getErrorStackString(callerStackError); + const callerStack = getErrorStackString(callerStackError!); stream.emit('error', callErrorFromStatus(status, callerStack)); } + /* Avoid retaining the callerStackError object in the call context of + * the status event handler. */ + callerStackError = null; stream.emit('status', status); }, }); @@ -673,7 +682,7 @@ export class Client { * call after that. */ stream.call = call; let receivedStatus = false; - const callerStackError = new Error(); + let callerStackError: Error | null = new Error(); call.start(callProperties.metadata, { onReceiveMetadata(metadata: Metadata) { stream.emit('metadata', metadata); @@ -688,9 +697,12 @@ export class Client { receivedStatus = true; stream.push(null); if (status.code !== Status.OK) { - const callerStack = getErrorStackString(callerStackError); + const callerStack = getErrorStackString(callerStackError!); stream.emit('error', callErrorFromStatus(status, callerStack)); } + /* Avoid retaining the callerStackError object in the call context of + * the status event handler. */ + callerStackError = null; stream.emit('status', status); }, }); diff --git a/packages/grpc-js/src/load-balancing-call.ts b/packages/grpc-js/src/load-balancing-call.ts index f74933983..d88bdb809 100644 --- a/packages/grpc-js/src/load-balancing-call.ts +++ b/packages/grpc-js/src/load-balancing-call.ts @@ -216,14 +216,18 @@ export class LoadBalancingCall implements Call { break; case PickResultType.DROP: const {code, details} = restrictControlPlaneStatusCode(pickResult.status!.code, pickResult.status!.details); - this.outputStatus({code, details, metadata: pickResult.status!.metadata}, 'DROP'); + setImmediate(() => { + this.outputStatus({code, details, metadata: pickResult.status!.metadata}, 'DROP'); + }); break; case PickResultType.TRANSIENT_FAILURE: if (this.metadata.getOptions().waitForReady) { this.channel.queueCallForPick(this); } else { const {code, details} = restrictControlPlaneStatusCode(pickResult.status!.code, pickResult.status!.details); - this.outputStatus({code, details, metadata: pickResult.status!.metadata}, 'PROCESSED'); + setImmediate(() => { + this.outputStatus({code, details, metadata: pickResult.status!.metadata}, 'PROCESSED'); + }); } break; case PickResultType.QUEUE: From 039032cdfb87b455d883e813002b4ed52fb472c9 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 1 Jun 2023 09:43:16 -0700 Subject: [PATCH 444/450] Merge pull request #2457 from XuanWang-Amos/xds_duplicate_bugs PSM Interop: Don't fail target if sub-target already failed --- packages/grpc-js-xds/scripts/xds_k8s_lb.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh index b87e3306c..4a83d44d5 100755 --- a/packages/grpc-js-xds/scripts/xds_k8s_lb.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_lb.sh @@ -170,9 +170,6 @@ main() { run_test $test || (( ++failed_tests )) done echo "Failed test suites: ${failed_tests}" - if (( failed_tests > 0 )); then - exit 1 - fi } main "$@" From 87b5466b1b5e6d269a9750305c5842c9e30e56e8 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 20 Jun 2023 10:25:59 -0700 Subject: [PATCH 445/450] grpc-js: Implement trace function in Http2SubchannelConnector --- packages/grpc-js/package.json | 2 +- packages/grpc-js/src/transport.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index 7d8c1a597..f0331f1fc 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.8.15", + "version": "1.8.16", "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 8abc13aba..2f89d8f28 100644 --- a/packages/grpc-js/src/transport.ts +++ b/packages/grpc-js/src/transport.ts @@ -485,7 +485,7 @@ export class Http2SubchannelConnector implements SubchannelConnector { private isShutdown = false; constructor(private channelTarget: GrpcUri) {} private trace(text: string) { - + logging.trace(LogVerbosity.DEBUG, TRACER_NAME, this.channelTarget + ' ' + text); } private createSession(address: SubchannelAddress, credentials: ChannelCredentials, options: ChannelOptions, proxyConnectionResult: ProxyConnectionResult): Promise { if (this.isShutdown) { From b53f5882f13a5cb3c599804e96304bf5b8407ea6 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 22 Jun 2023 14:26:31 -0700 Subject: [PATCH 446/450] grpc-js: Disallow pick_first as child of outlier_detection --- packages/grpc-js/package.json | 2 +- .../grpc-js/src/load-balancer-outlier-detection.ts | 11 +++++++---- packages/grpc-js/src/resolver-dns.ts | 4 ++-- packages/grpc-js/test/test-outlier-detection.ts | 12 +++++++++++- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/packages/grpc-js/package.json b/packages/grpc-js/package.json index f0331f1fc..d4b822600 100644 --- a/packages/grpc-js/package.json +++ b/packages/grpc-js/package.json @@ -1,6 +1,6 @@ { "name": "@grpc/grpc-js", - "version": "1.8.16", + "version": "1.8.17", "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/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index 2f72a9625..885c4feb9 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -113,6 +113,9 @@ export class OutlierDetectionLoadBalancingConfig implements LoadBalancingConfig failurePercentageEjection: Partial | null, private readonly childPolicy: LoadBalancingConfig[] ) { + if (childPolicy[0].getLoadBalancerName() === 'pick_first') { + throw new Error('outlier_detection LB policy cannot have a pick_first child policy'); + } this.intervalMs = intervalMs ?? 10_000; this.baseEjectionTimeMs = baseEjectionTimeMs ?? 30_000; this.maxEjectionTimeMs = maxEjectionTimeMs ?? 300_000; @@ -395,8 +398,8 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { } private isCountingEnabled(): boolean { - return this.latestConfig !== null && - (this.latestConfig.getSuccessRateEjectionConfig() !== null || + return this.latestConfig !== null && + (this.latestConfig.getSuccessRateEjectionConfig() !== null || this.latestConfig.getFailurePercentageEjectionConfig() !== null); } @@ -496,7 +499,7 @@ export class OutlierDetectionLoadBalancer implements LoadBalancer { if (addressesWithTargetVolume < failurePercentageConfig.minimum_hosts) { return; } - + // Step 2 for (const [address, mapEntry] of this.addressMap.entries()) { // Step 2.i @@ -656,4 +659,4 @@ export function setup() { if (OUTLIER_DETECTION_ENABLED) { registerLoadBalancerType(TYPE_NAME, OutlierDetectionLoadBalancer, OutlierDetectionLoadBalancingConfig); } -} \ No newline at end of file +} diff --git a/packages/grpc-js/src/resolver-dns.ts b/packages/grpc-js/src/resolver-dns.ts index 355ce2dfd..b20b7a543 100644 --- a/packages/grpc-js/src/resolver-dns.ts +++ b/packages/grpc-js/src/resolver-dns.ts @@ -137,7 +137,7 @@ class DnsResolver implements Resolver { details: `Name resolution failed for target ${uriToString(this.target)}`, metadata: new Metadata(), }; - + const backoffOptions: BackoffOptions = { initialDelay: channelOptions['grpc.initial_reconnect_backoff_ms'], maxDelay: channelOptions['grpc.max_reconnect_backoff_ms'], @@ -276,7 +276,7 @@ class DnsResolver implements Resolver { } catch (err) { this.latestServiceConfigError = { code: Status.UNAVAILABLE, - details: 'Parsing service config failed', + details: `Parsing service config failed with error ${(err as Error).message}`, metadata: new Metadata(), }; } diff --git a/packages/grpc-js/test/test-outlier-detection.ts b/packages/grpc-js/test/test-outlier-detection.ts index c9021e605..d51ccf3fd 100644 --- a/packages/grpc-js/test/test-outlier-detection.ts +++ b/packages/grpc-js/test/test-outlier-detection.ts @@ -360,6 +360,16 @@ describe('Outlier detection config validation', () => { }, /failure_percentage_ejection\.enforcement_percentage parse error: value out of range for percentage/); }); }); + describe('child_policy', () => { + it('Should reject a pick_first child_policy', () => { + const loadBalancingConfig = { + child_policy: [{pick_first: {}}] + }; + assert.throws(() => { + OutlierDetectionLoadBalancingConfig.createFromJson(loadBalancingConfig); + }, /outlier_detection LB policy cannot have a pick_first child policy/); + }); + }); }); describe('Outlier detection', () => { @@ -533,4 +543,4 @@ describe('Outlier detection', () => { }) }); }); -}); \ No newline at end of file +}); From 9441de78f655ada34ada0dc1a8057122eb21f229 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Thu, 22 Jun 2023 16:52:53 -0700 Subject: [PATCH 447/450] grpc-js-xds: Use distroless Node image for interop Dockerfile --- packages/grpc-js-xds/interop/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/interop/Dockerfile b/packages/grpc-js-xds/interop/Dockerfile index 5987f1ee4..2986eb3e5 100644 --- a/packages/grpc-js-xds/interop/Dockerfile +++ b/packages/grpc-js-xds/interop/Dockerfile @@ -27,7 +27,7 @@ RUN npm install WORKDIR /node/src/grpc-node/packages/grpc-js-xds RUN npm install -FROM node:18-slim +FROM gcr.io/distroless/nodejs18-debian11:latest WORKDIR /node/src/grpc-node COPY --from=build /node/src/grpc-node/packages/grpc-js ./packages/grpc-js/ COPY --from=build /node/src/grpc-node/packages/grpc-js-xds ./packages/grpc-js-xds/ From a62d2b027bf91e5084c9134305e88a645dc5f1c1 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 23 Jun 2023 09:34:29 -0700 Subject: [PATCH 448/450] Use entrypoint /nodejs/bin/node --- packages/grpc-js-xds/interop/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js-xds/interop/Dockerfile b/packages/grpc-js-xds/interop/Dockerfile index 2986eb3e5..5ff12a433 100644 --- a/packages/grpc-js-xds/interop/Dockerfile +++ b/packages/grpc-js-xds/interop/Dockerfile @@ -35,4 +35,4 @@ COPY --from=build /node/src/grpc-node/packages/grpc-js-xds ./packages/grpc-js-xd ENV GRPC_VERBOSITY="DEBUG" ENV GRPC_TRACE=xds_client,xds_resolver,cds_balancer,eds_balancer,priority,weighted_target,round_robin,resolving_load_balancer,subchannel,keepalive,dns_resolver,fault_injection,http_filter,csds,outlier_detection -ENTRYPOINT [ "node", "/node/src/grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client" ] +ENTRYPOINT [ "/nodejs/bin/node", "/node/src/grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client" ] From a6aa7ea43e1458a578cf9ab81ed492a760c43a78 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Fri, 23 Jun 2023 10:37:01 -0700 Subject: [PATCH 449/450] Merge pull request #2475 from XuanWang-Amos/file_multiple_url_map [PSM interop] Don't fail target if sub-target already failed --- packages/grpc-js-xds/scripts/xds_k8s_url_map.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 69126c72b..fc74718f2 100644 --- a/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh +++ b/packages/grpc-js-xds/scripts/xds_k8s_url_map.sh @@ -156,7 +156,7 @@ main() { build_docker_images_if_needed # Run tests cd "${TEST_DRIVER_FULL_DIR}" - run_test url_map + run_test url_map || echo "Failed url_map test" } main "$@" From ed70a0b381144b387698f2d57001f5a7bc82cbe9 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Tue, 27 Jun 2023 10:11:45 -0700 Subject: [PATCH 450/450] Fix handling of OD policy with no child --- packages/grpc-js/src/load-balancer-outlier-detection.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/grpc-js/src/load-balancer-outlier-detection.ts b/packages/grpc-js/src/load-balancer-outlier-detection.ts index 885c4feb9..ce8668f18 100644 --- a/packages/grpc-js/src/load-balancer-outlier-detection.ts +++ b/packages/grpc-js/src/load-balancer-outlier-detection.ts @@ -113,7 +113,7 @@ export class OutlierDetectionLoadBalancingConfig implements LoadBalancingConfig failurePercentageEjection: Partial | null, private readonly childPolicy: LoadBalancingConfig[] ) { - if (childPolicy[0].getLoadBalancerName() === 'pick_first') { + if (childPolicy.length > 0 && childPolicy[0].getLoadBalancerName() === 'pick_first') { throw new Error('outlier_detection LB policy cannot have a pick_first child policy'); } this.intervalMs = intervalMs ?? 10_000;