Merge branch 'master' into grpc-js-xds_aggregate_logical_dns_clusters

This commit is contained in:
Michael Lumish 2023-01-27 15:13:22 -08:00
commit 1cbadd7db0
36 changed files with 1779 additions and 25 deletions

View File

@ -12,8 +12,9 @@
"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/v3/ads.proto envoy/service/load_stats/v3/lrs.proto envoy/config/listener/v3/listener.proto envoy/config/route/v3/route.proto envoy/config/cluster/v3/cluster.proto envoy/config/endpoint/v3/endpoint.proto envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto udpa/type/v1/typed_struct.proto xds/type/v3/typed_struct.proto envoy/extensions/filters/http/fault/v3/fault.proto envoy/service/status/v3/csds.proto envoy/extensions/clusters/aggregate/v3/cluster.proto",
"generate-interop-types": "proto-loader-gen-types --keep-case --longs String --enums String --defaults --oneofs --json --includeComments --includeDirs proto/ -O interop/generated --grpcLib @grpc/grpc-js grpc/testing/test.proto"
"generate-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-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",

View File

@ -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 {}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<string, double> 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<string, double> utilization = 5;
}

View File

@ -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 \

View File

@ -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

View File

@ -209,6 +209,7 @@ export class CdsLoadBalancer implements LoadBalancer {
private latestConfig: CdsLoadBalancingConfig | null = null;
private latestAttributes: { [key: string]: unknown } = {};
private xdsClient: XdsClient | null = null;
private clusterTree: ClusterTree = {};
@ -271,14 +272,14 @@ export class CdsLoadBalancer implements LoadBalancer {
watcher: watcher,
children: []
};
getSingletonXdsClient().addClusterWatcher(cluster, watcher);
this.xdsClient?.addClusterWatcher(cluster, watcher);
}
private removeCluster(cluster: string) {
if (!(cluster in this.clusterTree)) {
return;
}
getSingletonXdsClient().removeClusterWatcher(cluster, this.clusterTree[cluster].watcher);
this.xdsClient?.removeClusterWatcher(cluster, this.clusterTree[cluster].watcher);
delete this.clusterTree[cluster];
}
@ -299,6 +300,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 */

View File

@ -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(),

View File

@ -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);
}
}

View File

@ -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<BootstrapInfo> {
}
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<BootstrapInfo> {
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(

View File

@ -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<BootstrapInfo> {
if (bootstrapInfoOverride) {
return bootstrapInfoOverride;
} else {
return loadBootstrapInfo();
}
}
Promise.all([getBootstrapInfo(), loadAdsProtos()]).then(
([bootstrapInfo, protoDefinitions]) => {
if (this.hasShutdown) {
return;

View File

@ -16,7 +16,7 @@
*/
import { experimental, logVerbosity, status as Status, Metadata, connectivityState } from "@grpc/grpc-js";
import { getSingletonXdsClient, XdsClusterDropStats } from "./xds-client";
import { getSingletonXdsClient, XdsClient, XdsClusterDropStats } from "./xds-client";
import LoadBalancingConfig = experimental.LoadBalancingConfig;
import validateLoadBalancingConfig = experimental.validateLoadBalancingConfig;
@ -222,6 +222,7 @@ class XdsClusterImplBalancer implements LoadBalancer {
private childBalancer: ChildLoadBalancerHandler;
private latestConfig: XdsClusterImplLoadBalancingConfig | null = null;
private clusterDropStats: XdsClusterDropStats | null = null;
private xdsClient: XdsClient | null = null;
constructor(private readonly channelControlHelper: ChannelControlHelper) {
this.childBalancer = new ChildLoadBalancerHandler(createChildChannelControlHelper(channelControlHelper, {
@ -242,9 +243,10 @@ class XdsClusterImplBalancer implements LoadBalancer {
}
trace('Received update with config: ' + JSON.stringify(lbConfig, undefined, 2));
this.latestConfig = lbConfig;
this.xdsClient = attributes.xdsClient as XdsClient;
if (lbConfig.getLrsLoadReportingServerName()) {
this.clusterDropStats = getSingletonXdsClient().addClusterDropStats(
this.clusterDropStats = this.xdsClient.addClusterDropStats(
lbConfig.getLrsLoadReportingServerName()!,
lbConfig.getCluster(),
lbConfig.getEdsServiceName() ?? ''

View File

@ -22,7 +22,7 @@ import { ClusterLoadAssignment__Output } from "./generated/envoy/config/endpoint
import { LrsLoadBalancingConfig } from "./load-balancer-lrs";
import { LocalitySubchannelAddress, PriorityChild, PriorityLoadBalancingConfig } from "./load-balancer-priority";
import { WeightedTarget, WeightedTargetLoadBalancingConfig } from "./load-balancer-weighted-target";
import { getSingletonXdsClient } from "./xds-client";
import { getSingletonXdsClient, XdsClient } from "./xds-client";
import { DropCategory, XdsClusterImplLoadBalancingConfig } from "./xds-cluster-impl";
import { Watcher } from "./xds-stream-state/xds-stream-state";
@ -242,6 +242,7 @@ export class XdsClusterResolver implements LoadBalancer {
private discoveryMechanismList: DiscoveryMechanismEntry[] = [];
private latestConfig: XdsClusterResolverLoadBalancingConfig | null = null;
private latestAttributes: { [key: string]: unknown; } = {};
private xdsClient: XdsClient | null = null;
private childBalancer: ChildLoadBalancerHandler;
constructor(private readonly channelControlHelper: ChannelControlHelper) {
@ -363,6 +364,7 @@ export class XdsClusterResolver implements LoadBalancer {
}
trace('Received update with config ' + JSON.stringify(lbConfig, undefined, 2));
this.latestAttributes = attributes;
this.xdsClient = attributes.xdsClient as XdsClient;
if (this.discoveryMechanismList.length === 0) {
for (const mechanism of lbConfig.getDiscoveryMechanisms()) {
const mechanismEntry: DiscoveryMechanismEntry = {
@ -390,7 +392,7 @@ export class XdsClusterResolver implements LoadBalancer {
}
};
mechanismEntry.watcher = watcher;
getSingletonXdsClient().addEndpointWatcher(edsServiceName, watcher);
this.xdsClient?.addEndpointWatcher(edsServiceName, watcher);
} else {
const resolver = createResolver({scheme: 'dns', path: mechanism.dns_hostname!}, {
onSuccessfulResolution: addressList => {
@ -430,7 +432,7 @@ export class XdsClusterResolver implements LoadBalancer {
for (const mechanismEntry of this.discoveryMechanismList) {
if (mechanismEntry.watcher) {
const edsServiceName = mechanismEntry.discoveryMechanism.eds_service_name ?? mechanismEntry.discoveryMechanism.cluster;
getSingletonXdsClient().removeEndpointWatcher(edsServiceName, mechanismEntry.watcher);
this.xdsClient?.removeEndpointWatcher(edsServiceName, mechanismEntry.watcher);
}
mechanismEntry.resolver?.destroy();
}

View File

@ -61,10 +61,12 @@ export class EdsState extends BaseXdsStreamState<ClusterLoadAssignment__Output>
const priorityTotalWeights: Map<number, number> = 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<ClusterLoadAssignment__Output>
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<ClusterLoadAssignment__Output>
}
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;
}
}

View File

@ -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<EchoRequest__Output, EchoResponse>, callback: sendUnaryData<EchoResponse>) {
// 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<number> {
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);
}
}

View File

@ -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();
}
}

View File

@ -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<any> {
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<void> {
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<any> {
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<any> {
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();
}
}));
}
}

View File

@ -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<Constructor extends new (...args: any) => any, Subtype> = {
new(...args: ConstructorParameters<Constructor>): Subtype;
};
export interface ProtoGrpcType {
grpc: {
testing: {
DebugInfo: MessageTypeDefinition
EchoRequest: MessageTypeDefinition
EchoResponse: MessageTypeDefinition
EchoTest1Service: SubtypeConstructor<typeof grpc.Client, _grpc_testing_EchoTest1ServiceClient> & { service: _grpc_testing_EchoTest1ServiceDefinition }
EchoTest2Service: SubtypeConstructor<typeof grpc.Client, _grpc_testing_EchoTest2ServiceClient> & { service: _grpc_testing_EchoTest2ServiceDefinition }
EchoTestService: SubtypeConstructor<typeof grpc.Client, _grpc_testing_EchoTestServiceClient> & { service: _grpc_testing_EchoTestServiceDefinition }
ErrorStatus: MessageTypeDefinition
/**
* A service without any rpc defined to test coverage.
*/
NoRpcService: SubtypeConstructor<typeof grpc.Client, _grpc_testing_NoRpcServiceClient> & { service: _grpc_testing_NoRpcServiceDefinition }
RequestParams: MessageTypeDefinition
ResponseParams: MessageTypeDefinition
SimpleRequest: MessageTypeDefinition
SimpleResponse: MessageTypeDefinition
StringValue: MessageTypeDefinition
UnimplementedEchoService: SubtypeConstructor<typeof grpc.Client, _grpc_testing_UnimplementedEchoServiceClient> & { service: _grpc_testing_UnimplementedEchoServiceDefinition }
}
}
xds: {
data: {
orca: {
v3: {
OrcaLoadReport: MessageTypeDefinition
}
}
}
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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>
}

View File

@ -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>
}

View File

@ -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>
}

View File

@ -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);
}

View File

@ -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 {
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -0,0 +1,8 @@
// Original file: proto/grpc/testing/simple_messages.proto
export interface SimpleRequest {
}
export interface SimpleRequest__Output {
}

View File

@ -0,0 +1,8 @@
// Original file: proto/grpc/testing/simple_messages.proto
export interface SimpleResponse {
}
export interface SimpleResponse__Output {
}

View File

@ -0,0 +1,10 @@
// Original file: proto/grpc/testing/simple_messages.proto
export interface StringValue {
'message'?: (string);
}
export interface StringValue__Output {
'message': (string);
}

View File

@ -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>
}

View File

@ -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});
}

View File

@ -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));
});
});

View File

@ -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 AdsTypeUrl> = 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<T extends AdsTypeUrl> = AdsInputType<T> & {'@type': T};
interface ResourceState<T extends AdsTypeUrl> {
resource?: ResourceAny<T>;
resourceTypeVersion: number;
subscriptions: Set<string>;
}
interface ResourceTypeState<T extends AdsTypeUrl> {
resourceTypeVersion: number;
/**
* Key type is type URL
*/
resourceNameMap: Map<string, ResourceState<T>>;
}
interface ResourceMap {
[EDS_TYPE_URL]: ResourceTypeState<EdsTypeUrl>;
[CDS_TYPE_URL]: ResourceTypeState<CdsTypeUrl>;
[RDS_TYPE_URL]: ResourceTypeState<RdsTypeUrl>;
[LDS_TYPE_URL]: ResourceTypeState<LdsTypeUrl>;
}
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<ResponseListener>();
private resourceTypesToIgnore = new Set<AdsTypeUrl>();
private clients = new Map<string, ServerDuplexStream<DiscoveryRequest__Output, DiscoveryResponse>>();
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<T extends AdsTypeUrl>(resource: ResourceAny<T>, name: string) {
const resourceTypeState = this.resourceMap[resource["@type"]] as ResourceTypeState<T>;
resourceTypeState.resourceTypeVersion += 1;
let resourceState: ResourceState<T> | 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<T extends AdsTypeUrl>(typeUrl: T, name: string) {
const resourceTypeState = this.resourceMap[typeUrl] as ResourceTypeState<T>;
resourceTypeState.resourceTypeVersion += 1;
let resourceState: ResourceState<T> | 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<T extends AdsTypeUrl>(typeUrl: T, clients: Set<string>, includeResources: Set<string>) {
const resourceTypeState = this.resourceMap[typeUrl] as ResourceTypeState<T>;
const clientResources = new Map<string, Any[]>();
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<T extends AdsTypeUrl>(typeUrl: T, client: string, resourceName: string): boolean {
const resourceTypeState = this.resourceMap[typeUrl] as ResourceTypeState<T>;
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<string>) {
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<string>();
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<DiscoveryRequest__Output, DiscoveryResponse>) {
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<LoadStatsRequest__Output, LoadStatsResponse>) {
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);
}
}