mirror of https://github.com/grpc/grpc-node.git
Merge branch 'master' into grpc-js-xds_aggregate_logical_dns_clusters
This commit is contained in:
commit
1cbadd7db0
|
@ -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",
|
||||
|
|
|
@ -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 {}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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() ?? ''
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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>
|
||||
}
|
|
@ -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>
|
||||
}
|
|
@ -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>
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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 {
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
// Original file: proto/grpc/testing/simple_messages.proto
|
||||
|
||||
|
||||
export interface SimpleRequest {
|
||||
}
|
||||
|
||||
export interface SimpleRequest__Output {
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
// Original file: proto/grpc/testing/simple_messages.proto
|
||||
|
||||
|
||||
export interface SimpleResponse {
|
||||
}
|
||||
|
||||
export interface SimpleResponse__Output {
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
// Original file: proto/grpc/testing/simple_messages.proto
|
||||
|
||||
|
||||
export interface StringValue {
|
||||
'message'?: (string);
|
||||
}
|
||||
|
||||
export interface StringValue__Output {
|
||||
'message': (string);
|
||||
}
|
|
@ -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>
|
||||
}
|
|
@ -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});
|
||||
}
|
|
@ -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));
|
||||
});
|
||||
});
|
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue