Compare commits

...

548 Commits

Author SHA1 Message Date
Michael Lumish 179dbfaecc
Merge pull request #2969 from murgatroid99/debugging_example
Add debugging example
2025-06-24 13:51:43 -07:00
Michael Lumish d22becc98e Add debugging example 2025-06-24 11:05:41 -07:00
Michael Lumish 987735920e
Merge pull request #2966 from murgatroid99/load_balancing_example
Add load balancing example
2025-06-17 10:36:36 -07:00
Michael Lumish 972bb23101 Add load balancing example 2025-06-16 15:36:50 -07:00
Michael Lumish 7548f413a5
Merge pull request #2965 from murgatroid99/grpc-js-xds_dns_no_special_case
grpc-js-xds: Combine endpoints for LOGICAL_DNS clusters
2025-06-13 14:28:56 -07:00
Michael Lumish 110a273a06 grpc-js-xds: Combine endpoints for LOGICAL_DNS clusters 2025-06-13 11:29:34 -07:00
Michael Lumish 7ab3da2431
Merge pull request #2963 from murgatroid99/proto-loader_update_golden
proto-loader: Update golden generated files with editions updates
2025-06-12 16:43:49 -07:00
Michael Lumish 5756fe7672 proto-loader: Update golden generated files with editions updates 2025-06-12 16:07:45 -07:00
Michael Lumish eef4b080f5
Merge pull request #2960 from ekscentrysytet/fix_retry_jitter
fix(grpc-js): fix jitter for client retries
2025-06-11 11:03:08 -07:00
Nazar Ilkiv 82b331d9e1 fix(grpc-js): fix jitter for client retries 2025-06-04 11:14:07 +03:00
Michael Lumish 21d40b0247
Merge pull request #2951 from MatiasManevi/health_list_js
Add List method to Health service
2025-05-08 15:30:15 -07:00
MatiasManevi 1605b71a02 Add List method to Health service 2025-05-02 17:17:10 -03:00
Michael Lumish 0157776059
Merge pull request #2945 from murgatroid99/grpc-js-xds_rbac_filter
grpc-js-xds: Implement RBAC HTTP filter
2025-04-21 10:48:23 -07:00
Michael Lumish 537b32f116
Merge pull request #2946 from murgatroid99/proto-loader_root_file_extension
proto-loader: Apply targetFileExtension to root files
2025-04-18 13:59:49 -07:00
Michael Lumish 7905a76494 proto-loader: Apply targetFileExtension to root files 2025-04-18 11:14:06 -07:00
Michael Lumish c2b914d4fd
Merge pull request #2944 from murgatroid99/proto-loader_0.7.14
proto-loader: Bump to 0.7.14
2025-04-17 11:20:24 -07:00
Michael Lumish 38e00726f4 proto-loader: Bump to 0.7.14 2025-04-17 10:32:36 -07:00
Michael Lumish 9843648afb Include previously skipped changes, fix auth context with no peer cert 2025-04-17 10:04:48 -07:00
Michael Lumish 9b7402ffab grpc-js-xds: Implement RBAC HTTP filter 2025-04-16 14:08:31 -07:00
Michael Lumish af53efcb85
Merge pull request #2939 from murgatroid99/grpc-js-xds_rbac_engine
grpc-js-xds: Implement RBAC engine
2025-04-10 15:10:46 -07:00
Michael Lumish 2e39783b36 grpc-js-xds: Implement RBAC engine 2025-04-10 10:59:02 -07:00
Michael Lumish 6f81b4ef9b
Merge pull request #2935 from murgatroid99/grpc-js-xds_server_http_filters
grpc-js-xds: Add support for server http filters
2025-04-04 14:14:37 -07:00
Michael Lumish ff679ae473 grpc-js-xds: Add support for server http filters 2025-04-04 10:31:47 -07:00
Michael Lumish c4580fa80b
Merge pull request #2929 from murgatroid99/grpc-js-xds_dependency_manager_watcher_updates
grpc-js-xds: Implement updated xds dependency manager watcher API
2025-03-25 09:44:56 -07:00
Michael Lumish 4a0f4cf5c8 Merge branch 'master' into grpc-js-xds_dependency_manager_watcher_updates 2025-03-21 12:43:44 -07:00
Michael Lumish e6da4ad1d8
Merge pull request #2925 from murgatroid99/grpc-js_channel_spec_resolver_update
grpc-js(-xds): Implement specified resolver and LB policy API changes
2025-03-21 11:22:55 -07:00
Michael Lumish 024d5d8fdf grpc-js(-xds): Implement specified resolver and LB policy API changes 2025-03-20 16:14:54 -07:00
Michael Lumish 86aa0f2f8b
Merge pull request #2912 from tenkirin/feat/file-extension-options
feat(proto-loader-gen-types): add options for specifying file extensions
2025-03-17 10:15:08 -07:00
Michael Lumish 9e35cacfe5 grpc-js-xds: Implement updated xds dependency manager watcher API 2025-03-13 14:31:52 -07:00
Michael Lumish 7a735ce062
Merge pull request #2922 from murgatroid99/grpc-js_server_interceptor_connection_info
grpc-js: `ServerInterceptingCall`: add `getConnectionInfo` method
2025-03-13 11:19:28 -07:00
Michael Lumish b74de954cf grpc-js: ServerInterceptingCall: add getConnectionInfo method 2025-03-12 17:38:21 -07:00
Michael Lumish 4f0610338f
Merge pull request #2920 from murgatroid99/grpc-js_getAuthContext
grpc-js: Add getAuthContext call method
2025-03-11 09:14:24 -07:00
Michael Lumish 78f194be6e grpc-js: Add getAuthContext call method 2025-03-10 16:40:37 -07:00
Michael Lumish 6c7abfe4a8
Merge pull request #2917 from grpc/@grpc/grpc-js@1.13.x
Merge 1.13.x into master
2025-03-05 10:06:00 -08:00
Michael Lumish a8142c2bcb
Merge pull request #2916 from murgatroid99/grpc-js-xds_ring_hash_fix
grpc-js-xds: ring_hash: Fix proactive connect logic when already connecting
2025-03-04 15:21:44 -08:00
Michael Lumish abcf4306d6 grpc-js-xds: ring_hash: Fix proactive connect logic when already connecting 2025-03-04 14:44:57 -08:00
tenkirin 68bfa3b5e7 chore(proto-loader-gen-types): update option descriptions for consistency 2025-03-05 07:21:07 +09:00
Michael Lumish fbd13e8474
Merge pull request #2914 from murgatroid99/grpc-js_1.13.0_bump
grpc-js: Update to 1.13.0
2025-03-04 10:46:49 -08:00
Michael Lumish 9691f0eb0e grpc-js: Update to 1.13.0 2025-03-03 15:58:43 -08:00
tenkirin c5b96a9054 refactor(proto-loader-gen-types): refactor for more consistent code style 2025-03-04 07:21:07 +09:00
Michael Lumish daa5127a95
Merge pull request #2913 from murgatroid99/grpc-js_generated_update
grpc-js: Update generated code with generator changes
2025-03-03 11:27:49 -08:00
Michael Lumish 4132581c19 grpc-js: Update generated code with generator changes 2025-03-03 09:41:16 -08:00
tenkirin b43225d6a6 docs(proto-loader-gen-types): update option description of `proto-loader-gen-types` in README.md 2025-03-01 12:56:32 +09:00
tenkirin 8499c7b20f feat(proto-loader-gen-types): add options for specifying file extensions 2025-03-01 12:38:33 +09:00
Michael Lumish 55b31f60d9
Merge pull request #2911 from murgatroid99/proto-loader_optional_oneof
proto-loader: declare oneof fields as optional
2025-02-28 15:53:59 -08:00
Michael Lumish 7133635f1a Update golden and xds generated code for generator changes 2025-02-28 14:35:16 -08:00
Michael Lumish 7d39d52b77 proto-loader: declare oneof fields as optional 2025-02-28 14:31:45 -08:00
Michael Lumish 46a5e517ec
Merge pull request #2910 from murgatroid99/grpc-js_1.12_upmerge
Merge 1.12.x into master
2025-02-28 11:16:06 -08:00
Michael Lumish d58144dfff Merge remote-tracking branch 'upstream/@grpc/grpc-js@1.12.x' into grpc-js_1.12_upmerge 2025-02-28 10:34:54 -08:00
Michael Lumish 5eded95069
Merge pull request #2909 from murgatroid99/grpc-js-xds_security_tests
grpc-js-xds: Implement and enable security interop tests
2025-02-27 15:37:10 -08:00
Michael Lumish 6094ebed61 Handle unset validation_config_type at use time 2025-02-27 13:05:16 -08:00
Michael Lumish 0ebb571bb7 Don't unregister the xds server's channelz ref when destroying the connection injector 2025-02-27 10:51:00 -08:00
Michael Lumish 510d68140b Apparently unset oneof is allowed 2025-02-26 17:47:02 -08:00
Michael Lumish 6965250011 Handle secure context errors, fix server constructor argument handling 2025-02-26 16:24:29 -08:00
Michael Lumish 36c9a4fd40 Represent IPv6-mapped IPv4 addresses as IPv4 in channelz 2025-02-25 15:14:51 -08:00
Michael Lumish 822af6817f Only register once, add admin service response logging 2025-02-25 13:49:49 -08:00
Michael Lumish a9cfd7a533 Register listener as child properly 2025-02-25 10:35:18 -08:00
Michael Lumish 1e28a04330 Register xds listener with channelz 2025-02-24 15:12:31 -08:00
Michael Lumish 7d99c4a7aa Fix handling of subject alternative names with colons 2025-02-21 12:55:09 -08:00
Michael Lumish 65f4d76f15 Add SAN matcher trace logging 2025-02-21 09:42:17 -08:00
Michael Lumish 5cf1a876e5 Handle missing filter_chain_match differently, plus other fixes 2025-02-20 12:55:38 -08:00
Michael Lumish 87f703403c Fix Listener resource validation 2025-02-19 17:23:42 -08:00
Michael Lumish e883425ef3 Wait for secure connectors to be usable before TCP connect 2025-02-19 17:22:59 -08:00
Michael Lumish 1fe3f7406c Use xDS creds in interop client, remove verbose TLS logging 2025-02-19 13:40:20 -08:00
Michael Lumish bdd0dc8499 Fix a bug that caused HTTP2 sessions to be considered connected early 2025-02-19 13:39:02 -08:00
Michael Lumish 5f12dc233f Add more trace logging 2025-02-19 11:29:03 -08:00
Michael Lumish 0c093b0b7f
Merge pull request #2904 from murgatroid99/grpc-js-xds_ring_hash_proactive_connect_fix
grpc-js-xds: ring_hash: proactively connect in more cases
2025-02-19 09:10:34 -08:00
Michael Lumish da5cca4156 grpc-js-xds: ring_hash: proactively connect in more cases 2025-02-14 14:59:42 -08:00
Michael Lumish a8f981aefd Enable heavy-duty TLS tracing in interop client and server 2025-02-14 14:29:06 -08:00
Michael Lumish b44b14d831 Handle unauthorized TLS connections correctly 2025-02-14 13:06:08 -08:00
Michael Lumish bb6fff7ff5 Change connection handler to prependListener, add more trace logging 2025-02-13 10:55:12 -08:00
Michael Lumish 6e901c1511 Add more transport trace lines 2025-02-12 18:03:20 -08:00
Michael Lumish 2979fa706d Enable transport and certificate_provider tracers 2025-02-12 17:44:31 -08:00
Michael Lumish 613c832aad
Merge pull request #2903 from murgatroid99/grpc-js_server_custom_error_code
grpc-js: Add test for custom error code
2025-02-12 17:06:16 -08:00
Michael Lumish e55e596b29 grpc-js: Add test for custom error code 2025-02-12 16:15:22 -08:00
Michael Lumish f6631f5162 Call xds library register function in interop server 2025-02-12 15:34:09 -08:00
Michael Lumish eed4d54537 Don't require api_listener when validating Listener 2025-02-12 15:33:52 -08:00
Michael Lumish 564e80f736 Enable http_filter tracer on server 2025-02-12 13:45:13 -08:00
Michael Lumish e5fa6b7c05 Merge branch 'master' into grpc-js-xds_security_tests 2025-02-12 09:58:19 -08:00
Michael Lumish 189bef2177
Merge pull request #2902 from murgatroid99/grpc-js-xds_rich_validation_errors
grpc-js-xds: NACK with detailed validation errors
2025-02-12 09:57:33 -08:00
Michael Lumish fced35a7d1 Fix ring_hash validation 2025-02-11 15:22:06 -08:00
Michael Lumish 61349e09ab grpc-js-xds: NACK with detailed validation errors 2025-02-11 14:37:25 -08:00
Michael Lumish d008d1e3c3
Merge pull request #2901 from murgatroid99/grpc-js-xds_legacy_interop_install_fix
grpc-js-xds: Install new dependencies in legacy interop script
2025-02-06 17:12:59 -08:00
Michael Lumish 0f0314f1ad grpc-js-xds: Install new dependencies in legacy interop script 2025-02-06 16:44:26 -08:00
Michael Lumish a7219808db xds interop server: bind IPv4 in secure mode 2025-02-06 16:34:50 -08:00
Michael Lumish bf26f6e3a6
Merge pull request #2900 from murgatroid99/grpc-tools_1.13
grpc-tools: Bump to version 1.13.0
2025-02-06 15:30:00 -08:00
Michael Lumish 1d9887224b grpc-tools: Bump to version 1.13.0 2025-02-06 14:59:47 -08:00
Michael Lumish 7a255395bc Make secure_mode parsing case-insensitive 2025-02-06 14:26:33 -08:00
Michael Lumish 0b6e2a3275 Add kokoro config for PSM interop security tests 2025-02-05 14:40:44 -08:00
Michael Lumish 06a05a4200
Merge pull request #2897 from murgatroid99/grpc-js-xds_interop_server
grpc-js-xds: Add interop server implementation
2025-02-05 13:51:08 -08:00
Michael Lumish 1ed46a1ae5 Allow binding some IPv6 ports to fail 2025-02-05 10:32:56 -08:00
Michael Lumish 8fea44d2d5 Fix IPv6 address formatting 2025-02-05 09:53:35 -08:00
Michael Lumish 77dc658b46 Case insensitive address type matching 2025-02-04 14:58:08 -08:00
Michael Lumish 656ca0c00e
Merge pull request #2898 from murgatroid99/grpc-js-xds_memory_leak_backport_1.12.x
grpc-js-xds: fix LrsCallState statsTimer memory leak
2025-02-04 14:47:29 -08:00
Michael Lumish 6bd791d254
Merge pull request #2896 from murgatroid99/grpc-js_reduce_channel_leak
grpc-js: Allow garbage collection of IDLE channels
2025-02-04 14:17:02 -08:00
Michael Lumish f1f2b2dd83 grpc-js-xds: Bump to version 1.12.2 2025-02-04 14:14:37 -08:00
gfrancz 588b69c12c Fix type issue by setting the attribute separately
Co-authored-by: ws-gregm <55088361+ws-gregm@users.noreply.github.com>
2025-02-04 14:13:49 -08:00
gfrancz 621f401e34 fix: xds-client LrsCallState statsTimer memory leak 2025-02-04 14:13:49 -08:00
Michael Lumish d2a6dda689
Merge pull request #2891 from gfrancz/xds-lrscallstate-memory-leak
fix: xds-client LrsCallState statsTimer memory leak
2025-02-04 14:12:19 -08:00
Michael Lumish 5f889b2dd2 Install reflection before xds library 2025-02-04 12:55:13 -08:00
gfrancz 6dc3abe798
Fix type issue by setting the attribute separately
Co-authored-by: ws-gregm <55088361+ws-gregm@users.noreply.github.com>
2025-02-04 13:55:16 -05:00
Michael Lumish 0e6bfcc1a7 Merge branch 'master' into grpc-js-xds_interop_server 2025-02-04 10:21:56 -08:00
Michael Lumish e1a9f1275e Use tini in server interop dockerfile 2025-02-03 15:26:35 -08:00
Michael Lumish 33fcde929f Add logging for non-data-plane requests in the interop server 2025-01-31 15:38:19 -08:00
Michael Lumish ca21e4ab1f grpc-js: Allow garbage collection of IDLE channels 2025-01-31 11:24:19 -08:00
Michael Lumish d2462cad64
Merge pull request #2895 from murgatroid99/grpc-js_interop_fix
grpc-js: Connect with https scheme when using TLS
2025-01-30 14:52:18 -08:00
Michael Lumish 9569f20fc6 grpc-js: Connect with https scheme when using TLS 2025-01-30 14:22:09 -08:00
Michael Lumish cacace75a0 Add some more logging in the interop server 2025-01-30 10:54:57 -08:00
Michael Lumish 023b0862f0
Merge pull request #2894 from murgatroid99/retry_example
Add retry example
2025-01-29 13:22:48 -08:00
Michael Lumish b1fd52d566 Add retry example 2025-01-29 12:40:24 -08:00
Michael Lumish 23e6dd7d14 grpc-js: Ensure server sendMetadata interceptors are called 2025-01-29 10:35:55 -08:00
Michael Lumish 8b64c8144c Increase xDS interop client log verbosity 2025-01-28 13:33:36 -08:00
Michael Lumish 0396cb92e4 Build both docker images in one function call 2025-01-28 09:24:37 -08:00
gfrancz fdb6064721
fix: xds-client LrsCallState statsTimer memory leak 2025-01-27 21:46:34 -05:00
Michael Lumish 94781c9cc9 Fix server argument parsing 2025-01-27 18:09:43 -08:00
Michael Lumish 7068708e93 Add @types/mocha dev dependency in reflection package 2025-01-27 15:37:43 -08:00
Michael Lumish ffcb67cfa4 Add @types/mocha dev dependency in health check 2025-01-27 15:26:06 -08:00
Michael Lumish 854c15e113 Fix docker image build sequencing 2025-01-27 15:08:21 -08:00
Michael Lumish 73dea90052 Build new required packages in Dockerfiles 2025-01-27 14:55:35 -08:00
Michael Lumish a3d99e3554 grpc-js-xds: Implement xDS server 2025-01-22 14:53:19 -08:00
Michael Lumish 34b82cbf7f
Merge pull request #2876 from melkouri/malak.elkouri/fix-grpc-js-no-proxy-cidr-support
fix: support CIDR blocks in no_proxy env variable
2025-01-15 13:17:11 -08:00
Michael Lumish 908c22a3e3
Merge pull request #2884 from murgatroid99/grpc-js_call_committed_consistency
grpc-js: Always use RetryingCall, always call onCommitted
2025-01-15 10:46:24 -08:00
Malak El Kouri 5e7cd85290 remove trace 2025-01-15 10:02:14 +01:00
Michael Lumish a5b6178d99 grpc-js: Always use RetryingCall, always call onCommitted 2025-01-14 18:09:58 -08:00
Michael Lumish 5a942ed648
Merge pull request #2883 from murgatroid99/grpc-js-xds_config_selector_cluster_ref
grpc-js-xds: Reference clusters for ConfigSelector lifetime
2025-01-14 17:27:02 -08:00
Michael Lumish bfd87a9bf6 grpc-js-xds: Reference clusters for ConfigSelector lifetime 2025-01-14 15:36:33 -08:00
Michael Lumish 22bbe8a315
Merge pull request #2874 from DefangLabs/lio/omit_request_instanceof
feat(grpc-tools): add omit_serialize_instanceof generator option
2025-01-14 14:07:13 -08:00
Michael Lumish d9b677a74a
Merge pull request #2882 from murgatroid99/grpc-js-xds_missing_cluster_handling
grpc-js-xds: Start resource timers for resources requested after stream start
2025-01-14 14:03:52 -08:00
Michael Lumish 198ff4e9ea grpc-js-xds: Start resource timers for resources requested after stream start 2025-01-14 13:35:36 -08:00
Malak El Kouri 5f20dc91f0 fix case where serverHost is not an IP address + refactor 2025-01-10 10:39:20 +01:00
Michael Lumish bfebbe7047
Merge pull request #2881 from murgatroid99/grpc-js-xds_dependency_manager_logging
grpc-js-xds: Add more detailed xDS dependency manager logging
2025-01-09 17:10:44 -08:00
Michael Lumish 2a6ce92a55 grpc-js-xds: Add more detailed xDS dependency manager logging 2025-01-09 16:13:13 -08:00
Lionello Lunesu 0a20c2df64 Add omit_serialize_instanceof generator option 2025-01-09 05:59:04 -08:00
Malak El Kouri 2fa886109b define no_proxy cases in hostMatchesNoProxyList 2025-01-09 12:11:12 +01:00
Malak El Kouri ef510d9e9a refactor 2025-01-09 10:06:37 +01:00
Michael Lumish c6c69df25b
Merge pull request #2880 from murgatroid99/grpc-js-xds_preserve_type_state_1.12.x
grpc-js-xds: Preserve resource type version and nonce when unsubscribing (1.12.x)
2025-01-08 15:27:36 -08:00
Michael Lumish b396b7d5ae grpc-js-xds: Bump to version 1.12.1 2025-01-08 14:56:38 -08:00
Michael Lumish 5b0956a9df
Merge pull request #2864 from rickihastings/patch/configurable-http2-initial-window-size
feat(grpc-js): allow configurable http2 initial window size
2025-01-08 14:42:46 -08:00
Michael Lumish bb6bb4a5ca grpc-js-xds: Preserve resource type version and nonce when unsubscribing 2025-01-08 12:24:38 -08:00
Michael Lumish 137f476040
Merge pull request #2879 from murgatroid99/grpc-js-xds_preserve_stream_type_state
grpc-js-xds: Preserve resource type version and nonce when unsubscribing
2025-01-07 15:48:25 -08:00
Michael Lumish 9620806dcd grpc-js-xds: Preserve resource type version and nonce when unsubscribing 2025-01-07 14:24:25 -08:00
Michael Lumish 7346a186e3
Merge pull request #2877 from grpc/@grpc/grpc-js@1.12.x
Merge grpc-js 1.12.x into master
2025-01-07 10:25:06 -08:00
Malak El Kouri ca07343b78 fix: support CIDR blocks in no_proxy env variable 2025-01-06 18:33:37 +01:00
Ricki Hastings c591c2a268 fix: update channel-options.ts 2025-01-02 08:57:44 +00:00
Ricki Hastings a0914c6cda fix: rename variable and use nullish coalesce 2025-01-02 08:56:53 +00:00
Michael Lumish bae98b3d2f
Merge pull request #2873 from murgatroid99/grpc-js_http_error_resource_exhausted_fix
grpc-js: Prioritize HTTP status errors over message decoding errors
2024-12-18 12:45:37 -08:00
Michael Lumish 63d97170da grpc-js: Prioritize HTTP status errors over message decoding errors 2024-12-18 15:14:22 -05:00
Michael Lumish daaa1c37b3 grpc-js-xds: Add interop server implementation 2024-12-18 15:05:22 -05:00
Michael Lumish 263c478c9a
Merge pull request #2869 from murgatroid99/grpc-tools_workflow_fix
bump actions/download-artifact and actions/upload-artifact from 2 to 4 in grpc-tools build workflow
2024-12-11 07:38:51 -08:00
Michael Lumish 2a48d2689c bump actions/download-artifact and actions/upload-artifact from 2 to 4 in grpc-tools build workflow 2024-12-11 10:21:08 -05:00
Michael Lumish 5cd30ae4b8
Merge pull request #2868 from murgatroid99/grpc-js_error_propagation
grpc-js: Propagate error messages through LB policy tree
2024-12-10 12:56:26 -08:00
Michael Lumish fad797fd92 Improve round robin error message 2024-12-10 15:27:49 -05:00
Michael Lumish 2a4cd42f82 grpc-js: Propagate error messages through LB policy tree 2024-12-10 14:20:55 -05:00
Michael Lumish 614e5f948c
Merge pull request #2866 from murgatroid99/grpc-js-xds_channel_credentials
grpc-js-xds: Add XdsChannelCredentials
2024-12-10 08:39:08 -08:00
Michael Lumish 41f3fc096d Remove test that became invalid 2024-12-09 14:52:12 -05:00
Michael Lumish b84940ef0c grpc-js-xds: Add XdsChannelCredentials 2024-12-09 14:12:24 -05:00
Ricki Hastings d08318d8c1 fix: allow configurable http2 initial window size. fixes #2429 2024-12-06 11:48:31 +00:00
Michael Lumish e9359efc24
Merge pull request #2862 from murgatroid99/grpc-js_connection_drop_reporting_changes
grpc-js: Improve event sequencing when handling connection drops
2024-12-04 08:39:42 -08:00
Michael Lumish 5e3b0fb8e0 grpc-js: Improve event sequencing when handling connection drops 2024-12-04 10:54:50 -05:00
Michael Lumish a524d15488
Merge pull request #2861 from murgatroid99/grpc-js_handle_socket_close
grpc-js: Restore socket disconnect handling
2024-12-02 12:49:58 -08:00
Michael Lumish 848e00e54c grpc-js: Restore socket disconnect handling 2024-12-02 15:14:40 -05:00
Michael Lumish f0c58f79c5
Merge pull request #2858 from murgatroid99/grpc-js-xds_update_node_types_1.12
grpc-js-xds: Update @types/node and update code for compatibility (1.12.x)
2024-12-02 08:49:05 -08:00
Michael Lumish bc749acad8 grpc-js-xds: Update @types/node and update code for compatibility 2024-12-02 08:18:00 -08:00
Michael Lumish 8f08bbe621
Merge pull request #2855 from murgatroid99/grpc-js_credentials_secure_connector
grpc-js: Add security connector, rework connection establishment
2024-11-22 17:42:29 -08:00
Michael Lumish 165732467d Merge branch 'master' into grpc-js_credentials_secure_connector 2024-11-22 16:05:22 -08:00
Michael Lumish f5133e4822
Merge pull request #2856 from murgatroid99/grpc-js-xds_update_node_types
grpc-js-xds: Update `@types/node` and update code for compatibility
2024-11-22 15:18:40 -08:00
Michael Lumish bd00ccf5f3 grpc-js-xds: Update @types/node and update code for compatibility 2024-11-22 14:35:40 -08:00
Michael Lumish f154954854 grpc-js: Add security connector, rework connection establishment 2024-11-22 14:17:29 -08:00
Michael Lumish f44b5e50e8
Merge pull request #2854 from murgatroid99/grpc-js_lb_child_helper_channel_args
grpc-js: Pass channel args to LB policies with updates
2024-11-20 13:56:06 -08:00
Michael Lumish 86e62f2426 grpc-js: Pass channel args to LB policies with updates 2024-11-20 09:24:00 -08:00
Michael Lumish f621dc6c48
Merge pull request #2848 from murgatroid99/grpc-js_revert_lb_policy_creds_arg
Revert "grpc-js: Enable LB policies to override subchannel credentials"
2024-11-14 11:10:05 -08:00
Michael Lumish b6fbfa3bfc
Merge pull request #2850 from murgatroid99/grpc-js_cert_refresh_1.12
grpc-js{,-xds}: Renew self-signed certificates used in tests (1.12.x)
2024-11-14 11:09:52 -08:00
Michael Lumish 2ed62c1b76 grpc-js{,-xds}: Renew self-signed certificates used in tests 2024-11-14 10:30:53 -08:00
Michael Lumish f003315809
Merge pull request #2849 from murgatroid99/grpc-js_renew_test_certs
grpc-js{,-xds}: Renew self-signed certificates used in tests
2024-11-14 10:27:30 -08:00
Michael Lumish c405404d96 grpc-js{,-xds}: Renew self-signed certificates used in tests 2024-11-13 17:37:33 -08:00
Michael Lumish 7a6107f7d3 Revert "grpc-js: Enable LB policies to override subchannel credentials"
This reverts commit 57f0a71399.
2024-11-13 16:28:22 -08:00
Michael Lumish 77c5e768a7
Merge pull request #2846 from murgatroid99/grpc-js-xds_config_tears_fixes_2
grpc-js-xds: xds_cluster_manager: pass along updates to existing children
2024-11-07 13:40:44 -08:00
Michael Lumish ec9b3cfbb0 Add a test 2024-11-07 12:03:04 -08:00
Michael Lumish ac9ad67f0a grpc-js-xds: xds_cluster_manager: pass along updates to existing children 2024-11-07 11:32:28 -08:00
Michael Lumish 361c42f8da
Merge pull request #2842 from MasterOdin/patch-1
Remove broken build badge from README
2024-11-07 10:47:25 -08:00
Matthew Peveler 969a0e00fd
Merge branch 'master' into patch-1 2024-11-07 11:42:09 -07:00
Matthew Peveler 67f47c9cbb
remove badge 2024-11-07 18:41:41 +00:00
Michael Lumish 83b6e60cde
Merge pull request #2845 from murgatroid99/grpc-js-xds_config_tears_fixes
grpc-js-xds: Fix a couple of bugs with the config tears change
2024-11-06 17:30:10 -08:00
Michael Lumish eee7030a28 grpc-js-xds: Fix a couple of bugs with the config tears change 2024-11-06 16:24:39 -08:00
Michael Lumish 8a314311f8
Merge pull request #2844 from murgatroid99/grpc-js-xds_config_tears
grpc-js-xds: Implement relevant parts of A74 and A75
2024-11-05 11:21:18 -08:00
Michael Lumish 6e907b3153 grpc-js-xds: Implement relevant parts of A74 and A75 2024-11-04 17:30:19 -08:00
Matthew Peveler 26265a36cc
Update build badge in README
Signed-off-by: Matthew Peveler <matt.peveler@gmail.com>
2024-10-28 16:22:14 +00:00
Michael Lumish 912beea1d9
Merge pull request #2819 from orwoods/master
Fixed generation of grpc services
2024-10-15 14:54:25 -07:00
Michael Lumish aec0c9bd95
Merge pull request #2837 from murgatroid99/grpc-js-xds_server_creds
grpc-js-xds: Implement `XdsServerCredentials`
2024-10-15 10:34:38 -07:00
Michael Lumish 1a1024aa1e Add tests and fix bugs 2024-10-14 15:08:49 -07:00
Michael Lumish c87767e029 Merge branch 'master' into grpc-js-xds_server_creds 2024-10-14 11:14:16 -07:00
Michael Lumish d8f4343958 Add xds credentials tests 2024-10-14 11:13:54 -07:00
Michael Lumish 1ce0143220 Add support for testing with alternate credentials 2024-10-11 15:20:30 -07:00
Michael Lumish 0e39b261b1
Merge pull request #2838 from murgatroid99/grpc-js_node_12_fix
grpc-js: Use util.promisify instead of fs/promises for Node 12 compatibility
2024-10-09 13:19:27 -07:00
Michael Lumish e907d199c5 grpc-js: Use util.promisify instead of fs/promises for Node 12 compatibility 2024-10-09 11:12:20 -07:00
Michael Lumish 08172ba9d9 grpc-js-xds: Implement XdsServerCredentials 2024-10-08 15:52:11 -07:00
Michael Lumish dce2272362
Merge pull request #2836 from murgatroid99/grpc-js_1.12_1.11_bugfix_merge
grpc-js: Port bugfixes from 1.11.x into 1.12.x
2024-10-08 10:44:15 -07:00
Michael Lumish 67322057b2
Merge pull request #2835 from murgatroid99/grpc-js_1.12_1.11_bugfix_merge
grpc-js: Port bugfixes from 1.11.x into 1.12.x
2024-10-08 10:09:37 -07:00
Michael Lumish 65cd9b678e grpc-js: Bump to 1.12.1 2024-10-08 09:24:58 -07:00
Michael Lumish f21855d882 Merge remote-tracking branch 'upstream/@grpc/grpc-js@1.11.x' into grpc-js_1.12_1.11_bugfix_merge 2024-10-08 09:24:32 -07:00
Michael Lumish 8aacdfd1f3
Merge pull request #2833 from murgatroid99/grpc-js_1.12.0_bump
grpc-js: Bump to 1.12.0
2024-10-03 13:39:36 -07:00
Michael Lumish 051c0480f5 grpc-js: Bump to 1.12.0 2024-10-01 10:32:21 -07:00
Michael Lumish 707f6cb30d
Merge pull request #2832 from murgatroid99/grpc-js-xds_enable_dualstack
grpc-js-xds: Enable dualstack support by default
2024-09-30 15:10:28 -07:00
Michael Lumish 50668f7164 grpc-js-xds: Enable dualstack support by default 2024-09-30 14:38:32 -07:00
Michael Lumish 3c9436be8e
Merge pull request #2812 from vinothsa4891/bugfix/support-reject-unauthorized
Adding fix to ignore self-signed certificates verification
2024-09-23 22:26:01 -07:00
Michael Lumish 0430dc5523
Merge pull request #2828 from murgatroid99/grpc-js_parse_duration_fix
grpc-js: Fix duration parsing bug
2024-09-19 10:02:09 -07:00
Michael Lumish 6d09389f95 grpc-js: Fix duration parsing bug 2024-09-19 09:36:48 -07:00
Vinoth Sermakani Alagendran 7121f27bb0 Changed condition 2024-09-19 12:22:35 +05:30
Vinoth Sermakani Alagendran 9e6887368c Moved rejectUnauthorized from channel option to connectionOptions 2024-09-19 11:55:31 +05:30
Michael Lumish d95ea3074d
Merge pull request #2823 from murgatroid99/grpc-js-xds_file_watcher_plugin
grpc-js-xds: Add bootstrap certificate provider config handling
2024-09-17 10:50:10 -07:00
Michael Lumish 3f84a73d93
Merge pull request #2821 from murgatroid99/grpc-js_subchannel_credentials_override
grpc-js: Construct LB policies with credentials and enable them to override subchannel credentials
2024-09-17 10:49:58 -07:00
Michael Lumish e0ab3c34b3
Merge pull request #2827 from murgatroid99/kokoro_psm-dualstack
Add dualstack kokoro test job config
2024-09-17 09:47:44 -07:00
Michael Lumish 4500c06e11
Fix copyright year
Co-authored-by: Sergii Tkachenko <sergiitk@google.com>
2024-09-16 15:42:16 -07:00
Michael Lumish 8841efee5e
Merge pull request #2825 from murgatroid99/grpc-js_round_robin_reresolve
grpc-js: round_robin: Request resolution on connection drop
2024-09-16 15:26:56 -07:00
Michael Lumish a1b897206e
Merge pull request #2806 from murgatroid99/grpc-js_connectivity_management_fixes
grpc-js: Simplify pick_first behavior
2024-09-16 14:28:56 -07:00
Michael Lumish 94f62ddf7b Add dualstack kokoro test job config 2024-09-13 14:41:13 -07:00
Michael Lumish b3c24d080f grpc-js: round_robin: Request resolution on connection drop 2024-09-12 14:31:01 -07:00
Michael Lumish b16e1c9fe4 grpc-js-xds: Add bootstrap certificate provider config handling 2024-09-11 17:31:41 -07:00
Michael Lumish 605f14a0b5
Merge pull request #2814 from becoded/call-credential-generate-metadata-method-name
Provide the method_name for the CallCredentials callback generateMetadata
2024-09-10 14:28:48 -07:00
Michael Lumish 57f0a71399 grpc-js: Enable LB policies to override subchannel credentials 2024-09-09 11:19:50 -07:00
Michael Lumish 21f470824c
Merge pull request #2802 from murgatroid99/grpc-js_certificate_provider
grpc-js: Add file watcher certificate provider, and credentials that use them
2024-09-06 10:30:44 -07:00
Ivan Pakhomov 6a4e2dba98
Fixed generation of grpc services 2024-09-06 11:28:55 +02:00
Michael Lumish 0c5ab9876b
Merge pull request #2803 from murgatroid99/grpc-js_1.11.2
grpc-js: Bump to 1.11.2
2024-09-05 13:56:12 -07:00
Michael Lumish bb4496b482
Merge pull request #2817 from ygalbel/tracer-slow
made the call to trace to be called only when tracer is enabled
2024-09-05 11:14:44 -07:00
Ygal Bellaiche 90e472e4a1 made the call to trace to be called only when tracer is enabled 2024-09-05 10:44:36 +03:00
Michael Lumish c63bdae8da
Merge pull request #2808 from murgatroid99/grpc-js_transport_error_reporting
grpc-js: Report session error events instead of waiting for close
2024-09-04 17:56:24 -07:00
Bert Van Hauwaert 268d7eb42b Provide the method_name for the CallCredentials callback generateMetadata 2024-08-29 15:30:07 +02:00
Vinoth ca9f8c78e1 Adding fix to ignore self-signed certificates verification 2024-08-25 17:10:36 +05:30
Michael Lumish 3d43b1a7be Further reduce pick_first state space 2024-08-02 15:44:07 -07:00
Michael Lumish d409311bf2 grpc-js: Report session error events instead of waiting for close 2024-08-01 15:39:13 -07:00
Michael Lumish a6575c3e73 grpc-js: Simplify pick_first behavior 2024-07-30 17:59:08 -07:00
Michael Lumish b763f98e07 grpc-js: Bump to 1.11.2 2024-07-26 14:50:13 -07:00
Michael Lumish f5ea6ce271
Merge pull request #2801 from hastom/master
fix(grpc-js): client crash on custom error code
2024-07-26 14:47:45 -07:00
Michael Lumish ef7368263a Don't use AbortController 2024-07-25 16:27:53 -07:00
Michael Lumish ed53ea644c grpc-js: Add file watcher certificate provider, and credentials that use them 2024-07-25 15:42:52 -07:00
hastom 33073d0db2 Fix test case 2024-07-19 13:24:07 +03:00
hastom 15d422d5bb Fix client crash on custom error code 2024-07-18 12:57:40 +03:00
Michael Lumish 43032b1855
Merge pull request #2800 from murgatroid99/grpc-js_1.11.1
grpc-js: Bump to 1.11.1
2024-07-16 10:54:35 -07:00
Michael Lumish 2ecd53d815 grpc-js: Bump to 1.11.1 2024-07-16 10:15:16 -07:00
Michael Lumish 4da4fdc830
Merge pull request #2799 from xqin/master
support node v14.16 again
2024-07-16 10:14:16 -07:00
xqin 996a6375c6
support node v14 again 2024-07-16 16:06:59 +08:00
Michael Lumish 87ea7ce106
Merge pull request #2797 from murgatroid99/grpc-js_1.11.0_real
grpc-js: Bump packages to 1.11.0, and update documentation (actually on 1.11.x this time)
2024-07-15 13:43:18 -07:00
Michael Lumish 2ee8911dc4 grpc-js: Bump packages to 1.11.0, and update documentation 2024-07-15 11:00:25 -07:00
Michael Lumish 7e4c8f058c
Merge pull request #2796 from murgatroid99/grpc-js_1.11.0
grpc-js: Bump packages to 1.11.0, and update documentation
2024-07-15 10:56:27 -07:00
Michael Lumish bf8e071efd grpc-js: Bump packages to 1.11.0, and update documentation 2024-07-12 14:02:18 -07:00
Michael Lumish e13d5e7006
Merge pull request #2793 from murgatroid99/grpc-js_server_call_get_host
grpc-js: Add `getHost` to surface server call classes
2024-07-12 10:33:29 -07:00
Michael Lumish d60f5166b2
Merge pull request #2795 from murgatroid99/grpc-js_retry_limit_option
grpc-js: Add a channel option to configure retry attempt limits
2024-07-12 10:29:50 -07:00
Michael Lumish b35896be52
Merge pull request #2792 from murgatroid99/grpc-js_1.10.11_upmerge
grpc-js: Merge 1.10.x branch into master
2024-07-12 10:04:41 -07:00
Michael Lumish 8ee8e99d99 grpc-js: Add a channel option to configure retry attempt limits 2024-07-11 15:14:56 -07:00
Michael Lumish ebdf52f3f2 grpc-js: Add getHost to surface server call classes 2024-07-11 11:28:43 -07:00
Michael Lumish 9ea4187849 Merge remote-tracking branch 'upstream/@grpc/grpc-js@1.10.x' into grpc-js_1.10.11_upmerge 2024-07-10 11:14:55 -07:00
Michael Lumish f8338c55c2
Merge pull request #2784 from murgatroid99/grpc-js_pick_first_reconnection_fix
grpc-js: Fix pick_first reconnecting without active calls
2024-07-10 10:49:06 -07:00
Michael Lumish 023c1d0532
Merge pull request #2791 from murgatroid99/grpc-js_channel_close_pick_fix
grpc-js: Ensure pending calls end after channel close
2024-07-10 10:27:47 -07:00
Michael Lumish fbbc78d978
Merge pull request #2790 from murgatroid99/grpc-js_server_idle_test_deflake
grpc-js: Increase state change deadline in server idle tests
2024-07-10 10:26:27 -07:00
Michael Lumish f867643d8e
Merge pull request #2776 from gkampitakis/gkampitakis/patch_dns_lookup
fix: support authority overrides in the DNS resolver
2024-07-10 10:19:46 -07:00
gkampitakis 201595c665
run tests in series 2024-07-10 08:57:37 +01:00
Michael Lumish 810e9e6a40 grpc-js: Ensure pending calls end after channel close 2024-07-09 15:14:44 -07:00
gkampitakis a9aea45570
reset process env and add trace log 2024-07-09 22:36:20 +01:00
gkampitakis 3aaf0c6e52
reject lookup when all resolutions reject 2024-07-09 19:57:47 +01:00
gkampitakis 2a9f8f4c40
address comments for testing 2024-07-09 19:30:23 +01:00
Michael Lumish 395de4b333 grpc-js: Refresh server idle timer if not enough time has passed 2024-07-09 11:23:19 -07:00
Michael Lumish 745a451e4c grpc-js: Increase state change deadline in server idle tests 2024-07-09 11:03:15 -07:00
gkampitakis f0afe6946f
add tests for test-resolver with alternative resolver 2024-07-09 17:43:51 +01:00
Michael Lumish a5fac6f056 grpc-js: pick-first: Fix short circuit READY subchannel handling 2024-07-08 15:08:30 -07:00
gkampitakis 717725caf1
chore: update environment.md doc 2024-07-05 14:15:40 +01:00
Michael Lumish e804ad65b6 grpc-js: Bump to 1.10.11 2024-07-03 15:37:40 -07:00
Michael Lumish c1815e09e2 grpc-js: Fix pick_first reconnecting without active calls 2024-07-03 15:36:38 -07:00
gkampitakis c9fc8b2e0c
fix import node:dns promises 2024-07-03 18:29:01 +01:00
Michael Lumish da54e75638
Merge pull request #2783 from murgatroid99/grpc-js-xds_server2
grpc-js-xds: Implement xDS Server
2024-07-03 09:20:36 -07:00
George Kampitakis cb58fbc5b0
fix: use GRPC_NODE_USE_ALTERNATIVE_RESOLVER for enabling new alternative resolver 2024-07-02 09:35:45 +01:00
Michael Lumish f2dcb21a77 Merge branch 'master' into grpc-js-xds_server2 2024-07-01 11:19:12 -07:00
Michael Lumish bac66ad291 grpc-js-xds: Implement xDS Server 2024-07-01 10:45:44 -07:00
Michael Lumish d83355ba1c
Merge pull request #2782 from matthewbinshtok/binshtok/fix-validate-retry-config-error-msg
[grpc-js] Fix error messages in `serviceConfig` validation
2024-06-27 09:48:15 -07:00
gkampitakis 7f27b32245
resolve both ipv4 and ipv6 2024-06-27 13:32:40 +01:00
Matthew Binshtok d6925d9141 fix tests 2024-06-26 14:17:03 -04:00
Michael Lumish 1faf6ced97
Merge pull request #2780 from aranjans/patch-1
xds_k8s_lb test: Increase the timeout
2024-06-26 10:03:08 -07:00
Matthew Binshtok fc5bee791d fix error msgs in service config validation 2024-06-26 10:15:30 -04:00
Abhishek Ranjan 65d8ef1b69
xds_k8s_lb test: Increase the timeout
Increased the timeout from 3hrs to 6hrs.
2024-06-26 12:17:28 +05:30
Michael Lumish 1e31c0f47f
Merge pull request #2770 from subhraOffGit/master
[vote]Added Active maintainers into MAINTAINERS.md.
2024-06-24 15:15:36 -07:00
Michael Lumish f3aa040df3
Fix typo 2024-06-24 14:50:59 -07:00
Michael Lumish c9342572aa
Merge pull request #2778 from murgatroid99/grpc-js_1.10.10
grpc-js: Bump to 1.10.10
2024-06-24 14:09:55 -07:00
Michael Lumish 3c55b5b7b5
Merge pull request #2777 from murgatroid99/grpc-js_1.10_backports
Backport #2746 and #2761 to 1.10.x
2024-06-24 10:59:09 -07:00
Michael Lumish 97c4cdac48
Merge pull request #2779 from murgatroid99/grpc-js_max_send_message_size_fix
grpc-js: Re-add client-side max send message size checking
2024-06-24 10:35:08 -07:00
Michael Lumish 42844cffd2 grpc-js: Re-add client-side max send message size checking 2024-06-20 13:15:12 -07:00
George Kampitakis 6278da6aec
support selecting resolver via env 2024-06-19 09:45:40 +01:00
George Kampitakis c3d073b0cc
update per comments 2024-06-19 09:45:26 +01:00
Michael Lumish cbab4e51cd grpc-js: Bump to 1.10.10 2024-06-18 15:42:59 -07:00
Brendan Myers 5ae5514454 fix: add decoding for url encoded user credentials 2024-06-18 15:38:59 -07:00
James Watkins-Harvey e759029532 HTTP CONNECT: handle early server packets 2024-06-18 15:38:45 -07:00
Michael Lumish c447875796
Merge pull request #2761 from brendan-myers/url-encoding
fix: add decoding for url encoded user credentials
2024-06-18 15:36:48 -07:00
Michael Lumish d90ca240fc
Merge pull request #2746 from mjameswh/http-connect-proxy-early-server-packet
HTTP CONNECT: handle early server packets
2024-06-18 15:36:28 -07:00
Michael Lumish 5c0226d0db
Merge pull request #2760 from davidfiala/@grpc/grpc-js@1.10.x
Keepalive bugfixes and unify timers strategies between client and server
2024-06-18 15:27:11 -07:00
Michael Lumish 52fe8e94e7
Merge pull request #2772 from murgatroid99/grpc-js_cardinality_error_hang
grpc-js: Fix client hang when receiving extra messages for a unary response
2024-06-18 15:25:59 -07:00
George Kampitakis e2a93d188a
fix: support authority overrides in the DNS resolver 2024-06-18 18:41:47 +01:00
Michael Lumish 674f4e351a
Merge pull request from GHSA-7v5v-9h63-cj86
grpc-js: Avoid buffering significantly more than max_receive_message_size per received message
2024-06-10 10:33:47 -07:00
Michael Lumish 7ecaa2d2dc grpc-js: Bump to 1.10.9 2024-06-07 10:52:50 -07:00
David Fiala 98cd87f751
ensure that client keepalive timers are always cleared when they trigger. this is a necessary change to fit with having removed keepaliveDisabled boolean. manually inspected test logs for both server.ts and transport.ts to verify both types of keepalives are operating correctly. 2024-06-06 22:57:13 -07:00
Michael Lumish e64d816d7d grpc-js: Avoid buffering significantly more than max_receive_message_size per received message (1.10.x) 2024-06-06 15:00:23 -07:00
David Fiala 3c5ab229b1 per discussion, avoid tracking keepalive disabled state and instead depend on whether the session is destroyed 2024-06-05 19:01:02 -07:00
Michael Lumish 7719e37c83 grpc-js: Fix client hang when receiving extra messages for a unary response 2024-06-05 17:55:56 -07:00
subhraOffGit 6957c6c4ec
[vote]Added Active maintainers into MAINTAINERS.md.
[vote] Added sergiitk, gnossen, temawi into grpc/node active maintainers list. Removed  @jtattermusch, @nicolasnoble, @srini100 from active maintainers list and moved them to emeritus. Added @nimf to emeritus
Please comment as "Agree" if you agree to the change, if not please comment as "Disagree". Your comment will be counted as a vote.
The PR needs to stay open for 14 days, I.e. till 15th June 2024 as per governance guidelines
2024-06-01 20:28:10 +05:30
David Fiala c2da436a8e remove keepaliveDisabled from server.ts. rename keepaliveTimer. 2024-05-29 15:09:55 -07:00
David Fiala a77d94f7c6 Based on grpc/grpc-node#2139 I wrapped http2session.ping in a try-catch block again 2024-05-29 10:37:40 -07:00
Brendan Myers 8e2dc274a3 fix: add decoding for url encoded user credentials 2024-05-29 19:24:48 +10:00
David Fiala d325b5fff3 hoist in second location 2024-05-28 22:46:48 -07:00
David Fiala bed5e85af9 resolve hoisting 2024-05-28 22:43:51 -07:00
David Fiala 19cdc1233c another missing trace message for parity 2024-05-28 22:37:24 -07:00
David Fiala 7883164137 return imports back to original order 2024-05-28 22:35:40 -07:00
David Fiala 577b4b4748 add keepalive server trace back in to match channelz vs non-channelz trace behavior 2024-05-28 22:32:09 -07:00
David Fiala d799a7a5bd unify server and client keepalive matching comments and discussion on first round of review from https://github.com/grpc/grpc-node/pull/2760 2024-05-28 22:26:25 -07:00
David Fiala 334f0dcdb5 remove comment 2024-05-28 14:58:59 -07:00
Michael Lumish a4c2106e63
Merge pull request #2758 from murgatroid99/grpc-js_1.10.x_upmerge
Merge 1.10.x branch into master
2024-05-28 14:58:13 -07:00
David Fiala ad598ecbe4 Serverside keepalive error detection and cleanups
- Bugfix: Ensure that if session.ping returns false we correctly identify fail the keepalive and connection
- Bugfix: Ensure that if the interval between keepalives being sent occurs faster than the prior keepalive's timeout that we do not overwrite the reference to the prior timeout. Prior implementation could have in theory prevented a valid keepalive timeout from clearing itself. This rewrite keeps every timeout as a local (vs a shared state per session). Even if the timeout outlives the lifetime of a session, we still guard against errors by checking that the parent interval is not false-y. I reckon this could result in a short-term memory leak per session which is bounded for a maximum of keepaliveTimeoutMs. On the other hand even with that potential for a short reference hold, this implementation proposed here is more correct I think. One alternative we could do is keep a list of pending timeouts.. which is complex for a rare situation that will self resolve anyhow when keepaliveTimeoutMs is reached.
- Bug Fix: keepalive intervals were being cleared with an incorrect clearTimeout before. Not sure if this was causing intervals leaks in some nodejs impls or not. (v20.13.1 seems to accept this mismatch without issue)
- Rename variables for clarity, to prevent future bugs like swapping clearInterval vs clearTimeout.
- Implementation is repeated in two places, per warning from https://github.com/grpc/grpc-node/pull/2756#issuecomment-2136031256
- This commit supercedes the prior PR on a master branch which was out of date. https://github.com/grpc/grpc-node/pull/2756
2024-05-28 14:53:46 -07:00
Michael Lumish 71853407a4 Merge remote-tracking branch 'upstream/@grpc/grpc-js@1.10.x' into grpc-js_1.10.x_upmerge 2024-05-28 13:34:05 -07:00
Michael Lumish 45e5fe5462
Merge pull request #2750 from murgatroid99/grpc-js_idle_uds_fix
grpc-js: Fix UDS channels not reconnecting after going idle
2024-05-15 09:17:41 -07:00
Michael Lumish 87a3541402 grpc-js: Fix UDS channels not reconnecting after going idle 2024-05-14 14:47:53 -07:00
James Watkins-Harvey 3e89fdcec1 HTTP CONNECT: handle early server packets 2024-05-10 16:17:06 -04:00
Michael Lumish 3105791fbe
Merge pull request #2740 from sergiitk/backport-1.10-psm-interop-common-prod-tests
PSM Interop: simplify Kokoro buildscripts (@grpc/grpc-js@1.10.x backport)
2024-05-07 10:10:48 -07:00
Michael Lumish fec135a980 Merge pull request #2729 from sergiitk/psm-interop-common-prod-tests
PSM Interop: simplify Kokoro buildscripts
2024-05-06 15:26:17 -07:00
Michael Lumish 15b7d4dcd4
Merge pull request #2729 from sergiitk/psm-interop-common-prod-tests
PSM Interop: simplify Kokoro buildscripts
2024-05-06 15:20:11 -07:00
Sergii Tkachenko 1495b020f5 PSM Interop: move test suite lists to psm_interop_kokoro_lib.sh 2024-05-06 14:05:54 -07:00
Michael Lumish 76fe802309
Merge pull request #2739 from murgatroid99/backport-1.10-grpc-js_linkify-it_fix
root: Update dependency on jsdoc to avoid linkify-it compilation error (@grpc/grpc-js@1.10.x backport)
2024-05-06 09:37:50 -07:00
Michael Lumish d5edf49f6c Merge pull request #2735 from murgatroid99/grpc-js_linkify-it_fix
root: Update dependency on jsdoc to avoid linkify-it compilation error
2024-05-03 14:28:01 -07:00
Michael Lumish 1a8678e493
Merge pull request #2735 from murgatroid99/grpc-js_linkify-it_fix
root: Update dependency on jsdoc to avoid linkify-it compilation error
2024-05-03 14:24:44 -07:00
Michael Lumish 5b76d7dfe8 root: Update dependency on jsdoc to avoid linkify-it compilation error 2024-05-03 14:05:38 -07:00
Michael Lumish 23c05fca84
Merge pull request #2732 from murgatroid99/grpc-js_proto-loader_update
grpc-js(-xds): Pick up proto-loader update
2024-05-01 11:03:57 -07:00
Michael Lumish 0ae86b13f0
Merge pull request #2731 from murgatroid99/proto-loader_dependency_update
proto-loader: Update dependency on protobufjs
2024-05-01 10:31:13 -07:00
Michael Lumish 0bbfb920d1
Merge pull request #2723 from murgatroid99/grpc-js_http2_error_reporting
grpc-js: Improve reporting of HTTP error codes
2024-05-01 10:27:59 -07:00
Michael Lumish 5e1ab3ecf8
Merge pull request #2717 from murgatroid99/proto-loader_duplicate_method_declarations
proto-loader: Avoid generating duplicate method declarations in some cases
2024-05-01 10:26:49 -07:00
Michael Lumish e4f2ecd053 grpc-js(-xds): Pick up proto-loader update 2024-04-30 15:49:20 -07:00
Michael Lumish cf9cba6142 proto-loader: Update dependency on protobufjs 2024-04-30 10:35:48 -07:00
Michael Lumish 8754ccb7db grpc-js: Improve reporting of HTTP error codes 2024-04-11 10:56:18 -07:00
Michael Lumish b292946de7 proto-loader: Avoid generating duplicate method declarations in some cases 2024-04-09 14:45:35 -07:00
Michael Lumish 567449875d
Merge pull request #2711 from n0v1/feat/method-options
grpc-loader: Expose method options
2024-04-09 14:36:19 -07:00
n0v1 6c7225f3ba make method options required 2024-04-09 18:21:33 +00:00
Sergii Tkachenko db1c05eb09
Merge pull request #2713 from sergiitk/backport-1.10-psm-interop-pkg-dev
PSM Interop: Migrate to Artifact Registry (@grpc/grpc-js@1.10.x backport)
2024-04-08 18:07:32 -07:00
Michael Lumish 2af21a55f3 Merge pull request #2712 from sergiitk/psm-interop-pkg-dev
PSM Interop: Migrate to Artifact Registry
2024-04-08 18:04:43 -07:00
Michael Lumish b2e9d04cec
Merge pull request #2712 from sergiitk/psm-interop-pkg-dev
PSM Interop: Migrate to Artifact Registry
2024-04-08 17:47:26 -07:00
Sergii Tkachenko ade39e8baa PSM Interop: Migrate to Artifact Registry
Migrate PSM Interop images from Container Registry (gcr.io) to
Artifact Registry (pkg.dev).
2024-04-08 16:13:44 -07:00
Christopher Fenn e6ac1a49ed return uninterpreted options as an array 2024-04-05 17:12:04 +02:00
Christopher Fenn 6e441a8d03 use single quotes consistently 2024-04-05 16:38:04 +02:00
Christopher Fenn 1e37caadfc add test case for partially set options 2024-04-05 16:37:03 +02:00
Christopher Fenn 27d608763b adjust implementation to always return default options 2024-04-05 16:23:29 +02:00
Christopher Fenn 99e8a060f6 make uninterpreted_option an array 2024-04-05 16:19:04 +02:00
Christopher Fenn 5bd37a9de1 narrow down type of idempotency_level 2024-04-05 16:00:28 +02:00
Christopher Fenn 260966c070 predefined options should always be returned with their default value 2024-04-05 16:00:04 +02:00
hiepthai 4c185fa2e6 grpc-loader: update interfaces & add new test 2024-04-05 15:32:26 +02:00
hiepthai d335428458 grpc-loader: cleanup MethodOptions interfaces 2024-04-05 15:32:26 +02:00
hiepthai 68ea1f43e2 grpc-loader: update & correct interface types 2024-04-05 15:32:26 +02:00
Hiep Thai ae33e8797a grpc-loader: export interfaces and fix minor issue 2024-04-05 15:32:26 +02:00
Hiep Thai dfb10f9ac4 grpc-loader: add method options test 2024-04-05 15:32:26 +02:00
Hiep Thai fc9db761a9 grpc-loader: map method options and add MethodOptions interface 2024-04-05 15:32:26 +02:00
Hiep Thai c8b5e05366 grpc-loader: update MethodDefinition interface 2024-04-05 15:32:26 +02:00
hiepthai c7d4566353 grpc-loader: add method options in MethodDefinition 2024-04-05 15:32:26 +02:00
Michael Lumish dac9321e97
Merge pull request #2708 from murgatroid99/grpc-js_trailers_only_fix2
grpc-js: Fix check for whether to send a trailers-only response
2024-04-03 10:11:45 -07:00
Michael Lumish 0d9a8c1dcf grpc-js: Fix check for whether to send a trailers-only response 2024-04-03 09:40:22 -07:00
Michael Lumish be40682090
Merge pull request #2706 from murgatroid99/build_order_fix
Fix build order in root gulpfile to handle cross dependency
2024-04-01 15:40:07 -07:00
Michael Lumish c3c7cc4d75
Merge pull request #2704 from murgatroid99/grpc-js_check_server_identity
grpc-js: Call custom `checkServerIdentity` when target name override is set
2024-04-01 15:26:15 -07:00
Michael Lumish cc44d785c9
Merge pull request #2692 from murgatroid99/grpc-js_deadline_info
grpc-js: Add more info to deadline exceeded errors
2024-04-01 15:25:48 -07:00
Michael Lumish 06ff52596d
Merge pull request #2705 from murgatroid99/grpc-js_stacktrace_fix_backport
Backport #2701: Resolve exception when Error.stackTraceLimit is undefined
2024-04-01 15:24:33 -07:00
Michael Lumish f7c3b3a3d8 Fix build order in root gulpfile to handle cross dependency 2024-04-01 15:22:23 -07:00
David Fiala 213230c73b Resolve exception when Error.stackTraceLimit is undefined
Some applications may explicitly set Error.stackTraceLimit = undefined. In this case it is not safe to assume new Error().stack is available.
2024-04-01 15:05:25 -07:00
Michael Lumish 74e4da5cc6
Merge pull request #2701 from davidfiala/patch-1
Resolve exception when Error.stackTraceLimit is undefined
2024-04-01 15:04:09 -07:00
Michael Lumish e1f831a57b grpc-js: Call custom checkServerIdentity when target name override is set 2024-04-01 10:03:51 -07:00
Michael Lumish 77dca7a2a9
Merge pull request #2702 from murgatroid99/grpc-js-xds_legacy_proto-loader_fix
grpc-js-xds: Make legacy interop script use proto-loader correctly
2024-03-29 13:31:13 -07:00
Michael Lumish 8e0f0abdb0 grpc-js-xds: Make legacy interop script use proto-loader correctly 2024-03-29 10:50:10 -07:00
Michael Lumish 9f83845adc
Merge pull request #2700 from murgatroid99/grpc-js-xds_typescript_5
grpc-js-xds: Use TypeScript 5
2024-03-28 12:43:01 -07:00
Michael Lumish e6f13e015c Copy proto-loader from build image to final image 2024-03-28 10:35:57 -07:00
Michael Lumish 5d8d5b513e Fix proto-loader declaration in grpc-js devDependencies 2024-03-28 09:29:30 -07:00
Michael Lumish dfd8f0f7ea
Merge pull request #2699 from murgatroid99/proto-loader_revert_extension
proto-loader: Revert 'Import internal files with extension'
2024-03-28 09:28:34 -07:00
David Fiala 2099f540d2
Resolve exception when Error.stackTraceLimit is undefined
Some applications may explicitly set Error.stackTraceLimit = undefined. In this case it is not safe to assume new Error().stack is available.
2024-03-27 16:39:45 -07:00
Michael Lumish 7b74d51a6f grpc-js-xds: use local proto-loader, build proto-loader in interop Dockerfile 2024-03-27 11:10:14 -07:00
Michael Lumish 7b4509ec47 grpc-js-xds: Use TypeScript 5 2024-03-27 10:37:19 -07:00
Michael Lumish 3b0e4ac8ff grpc-js: Use local proto-loader, and regenerate protobuf types 2024-03-27 10:36:54 -07:00
Michael Lumish d3e16a43ea proto-loader: Revert 'Import internal files with extension' 2024-03-27 10:09:27 -07:00
Michael Lumish 6f5a955d8c
Merge pull request #2697 from murgatroid99/example_interceptors
Add interceptors example
2024-03-26 11:05:24 -07:00
Michael Lumish 729a3f52cf
Merge pull request #2695 from murgatroid99/grpc-js_avoid_extra_rst_stream
grpc-js: Avoid sending redundant RST_STREAMs from the client
2024-03-26 11:01:00 -07:00
Michael Lumish c1df94edb2
Merge pull request #2696 from murgatroid99/grpc-js_server_interceptors_fix
grpc-js: Ensure server interceptors work with builder utility classes
2024-03-26 10:58:59 -07:00
Michael Lumish f2c5facba6
Merge pull request #2698 from murgatroid99/proto-loader_0.7.11
proto-loader: Bump version to 0.7.11
2024-03-26 10:04:21 -07:00
Michael Lumish eccccd9e8c proto-loader: Bump version to 0.7.11 2024-03-25 10:45:11 -07:00
Michael Lumish d9c26724a5
Merge pull request #2693 from atjn/import-extension
`proto-loader-gen-types`: Import internal files with extension
2024-03-25 10:43:44 -07:00
Anton 055282a140 Update docs with recommended import method 2024-03-25 09:03:50 +01:00
Anton 8d69e9fa7a Fix tests 2024-03-25 08:58:28 +01:00
Michael Lumish 9948aea5a5 grpc-js: Ensure server interceptors work with builder utility classes 2024-03-21 14:58:37 -07:00
Michael Lumish 443992bd04 Add interceptors example 2024-03-21 14:47:42 -07:00
Michael Lumish f4330f72c9 Use call start times in some trace logs 2024-03-21 09:49:58 -07:00
Anton 83d9f1c8b9 Import files with extension 2024-03-21 09:06:58 +01:00
Michael Lumish 14f1d02c9a grpc-js: Avoid sending redundant RST_STREAMs from the client 2024-03-20 15:46:59 -07:00
Michael Lumish d7d171776d grpc-js: Add more info to deadline exceeded errors 2024-03-15 15:43:57 -07:00
Michael Lumish 649412f1ea
Merge pull request #2691 from murgatroid99/grpc-js_pick_first_disconnect_fix_revert
Revert #2680 "grpc-js: pick_first: Don't automatically reconnect after connection drop"
2024-03-15 10:07:32 -07:00
Michael Lumish a8c6c33daa grpc-js: Bump version to 1.10.3 2024-03-15 09:24:01 -07:00
Michael Lumish d0c2026887 Revert "grpc-js: pick_first: Don't automatically reconnect after connection drop"
This reverts commit 4a3fefa2b3.
2024-03-15 09:23:08 -07:00
Michael Lumish bcea4b40bf
Merge pull request #2688 from murgatroid99/example_keepalive
Add keepalive example
2024-03-14 09:15:13 -07:00
Michael Lumish f794b77934 Address review comments 2024-03-13 15:16:42 -07:00
Michael Lumish c3e9fbe538 Add keepalive example 2024-03-13 15:04:16 -07:00
Michael Lumish 0edd1948ab
Merge pull request #2684 from murgatroid99/grpc-js_1.10.2
grpc-js: Bump to 1.10.2
2024-03-07 10:53:27 -08:00
Michael Lumish 55b98529f8
Merge pull request #2683 from murgatroid99/grpc-js_server_event_order
grpc-js: Rearrange some function calls to revert event order changes
2024-03-07 10:53:02 -08:00
Michael Lumish cb966dfcd6
Merge pull request #2680 from murgatroid99/grpc-js_pick_first_disconnect_fix
grpc-js: pick_first: Don't automatically reconnect after connection drop
2024-03-07 10:52:57 -08:00
Michael Lumish 4d235c339b grpc-js: Bump to 1.10.2 2024-03-07 09:24:04 -08:00
Michael Lumish 400147c501
Merge pull request #2677 from AVVS/feat/channelz-perf+stream-idle-timeout
feat: channelz improvements, idle timeout implementation
2024-03-06 15:28:31 -08:00
AVVS 74ddb3bd6f
chore: address ts errors 2024-03-05 15:34:29 -08:00
Michael Lumish 07ee52acb0 grpc-js: Rearrange some function calls to revert event order changes 2024-03-05 10:27:21 -08:00
AVVS cf321a80b1
chore: use iterators for tracking map, const for default values 2024-03-04 18:25:23 -08:00
Michael Lumish 4a3fefa2b3 grpc-js: pick_first: Don't automatically reconnect after connection drop 2024-03-04 09:33:41 -08:00
AVVS 62e8ea97e6
chore: tests & cleanup of unref?.() 2024-03-02 07:58:54 -08:00
AVVS b873dce908
chore: simplify idle timeout further, fix wrong ref 2024-02-28 14:26:42 -08:00
AVVS bedb5055e8
refactor: no clearTimeout/null timers, use .refresh() + count refs 2024-02-28 13:36:24 -08:00
AVVS 11a98b5f37
chore: updated docs, cached onStreamClose per session 2024-02-27 16:49:20 -08:00
AVVS 74102fcc87
chore: extraneous closure, dont need server ref 2024-02-27 14:39:24 -08:00
AVVS 0b79b7420a
chore: cleanup traces 2024-02-27 14:35:02 -08:00
AVVS b8f157ed21
chore: revert interface -> type change in channelz 2024-02-27 14:30:55 -08:00
AVVS a4a676d378
chore: move new functions towards the end of the class 2024-02-27 14:17:32 -08:00
AVVS e0b900dd69
feat: channelz improvements, idle timeout implementation 2024-02-27 13:28:05 -08:00
Michael Lumish cfa8072099
Merge pull request #2678 from murgatroid99/reflection_no_package_fix
reflection: Fix references to symbols with no package
2024-02-27 13:10:30 -08:00
Michael Lumish 210967ffa3
Merge pull request #2679 from murgatroid99/grpc-js_1.10_format
grpc-js: Run code formatter, fix one lint error
2024-02-27 13:08:17 -08:00
Michael Lumish 6c2bc599e5 grpc-js: Run code formatter, fix one lint error 2024-02-27 12:51:38 -08:00
Michael Lumish 0207979a4d reflection: Fix references to symbols with no package 2024-02-27 12:43:28 -08:00
Michael Lumish c10d973d38
Merge pull request #2676 from murgatroid99/grpc-reflection_1.0.2
grpc-reflection: Bump to 1.0.2
2024-02-23 11:00:50 -08:00
Michael Lumish 3f527fbdf9
Merge pull request #2675 from murgatroid99/grpc-js_connection_injection
grpc-js: Add Server#createConnectionInjector API
2024-02-23 10:59:54 -08:00
Michael Lumish 7e5f58b112 grpc-reflection: Bump to 1.0.2 2024-02-22 16:56:28 -08:00
Michael Lumish 9886ee2da7
Merge pull request #2673 from jtimmons/fix/reflection-root-package-refs
fix(grpc-reflection): [#2671] handle references to root-level message types in default package
2024-02-22 16:55:23 -08:00
Michael Lumish 321b6603b0 grpc-js: Add Server#createConnectionInjector API 2024-02-22 16:52:56 -08:00
Justin Timmons 7c0511f2df fix(grpc-reflection): handle references to root-level message types in default package 2024-02-21 22:19:37 -05:00
Michael Lumish 0ba7d70fb9
Merge pull request #2661 from murgatroid99/grpc-js_watchable_server_creds
grpc-js: Expand ServerCredentials API to support watchers
2024-02-15 15:46:18 -08:00
Michael Lumish 1bc1cd573c
Merge pull request #2665 from murgatroid99/grpc-js-xds_eds_dualstack
grpc-js-xds: Implement EDS dualstack support
2024-02-15 15:46:08 -08:00
Michael Lumish 513a61a730
Merge pull request #2667 from murgatroid99/grpc-js_round_robin_idle_fix
grpc-js: round_robin: always have children reconnect immediately
2024-02-15 10:03:42 -08:00
Michael Lumish 429a66d1cb grpc-js: round_robin: always have children reconnect immediately 2024-02-14 11:05:26 -08:00
Michael Lumish 9b61f4adc0 grpc-js-xds: Implement EDS dualstack support 2024-02-13 14:02:50 -08:00
Michael Lumish a114b9f152 grpc-js-xds: Update envoy-api dep to match grpc/grpc reference 2024-02-13 11:12:09 -08:00
Michael Lumish 5e2fa71713
Merge pull request #2663 from Ileriayo/fix-deprecation-node-example
Fix deprecated code
2024-02-12 13:29:47 -08:00
Ileriayo Adebiyi 76717f88a6 Fix missing import 2024-02-12 21:09:43 +01:00
Ileriayo Adebiyi 300a23698c Fix deprecated statement 2024-02-12 21:09:18 +01:00
Ileriayo Adebiyi 9c3291eeaa Fix deprecated code 2024-02-12 14:48:05 +01:00
Michael Lumish a1fde62101 grpc-js: Expand ServerCredentials API to support watchers 2024-02-09 14:33:13 -08:00
Michael Lumish 1b753af868
Merge pull request #2656 from murgatroid99/grpc-js_1.10.0
grpc-js/grpc-js-xds: Bump version to 1.10.0
2024-02-06 14:45:17 -08:00
Michael Lumish 25557253c2
Merge pull request #2655 from murgatroid99/grpc-js-xds_1.10_deexperimentalize
grpc-js-xds: De-experimentalize tested features and update feature list
2024-02-06 14:45:09 -08:00
Michael Lumish 5b44a4428f
Merge pull request #2654 from murgatroid99/grpc-health-check_2.0.1
grpc-health-check: Bump version to 2.0.1
2024-02-05 16:07:14 -08:00
Michael Lumish b1c45a819f grpc-js/grpc-js-xds: Bump version to 1.10.0 2024-02-01 13:44:07 -08:00
Michael Lumish 322b165c85 grpc-js-xds: De-experimentalize tested features and update feature list 2024-02-01 13:25:38 -08:00
Michael Lumish f70c322e57
Merge pull request #2650 from murgatroid99/grpc-js_server_interceptors
grpc-js: Implement server interceptors
2024-02-01 10:06:17 -08:00
Michael Lumish c2e72e833b grpc-health-check: Bump version to 2.0.1 2024-01-31 13:28:26 -08:00
Michael Lumish 4d7a7fbca1
Merge pull request #2651 from satazor/support/remove-typescript-as-dep
grpc-health-check: Move `typescript` as a dev dependency
2024-01-31 13:25:52 -08:00
Michael Lumish 7c9a5e7147 Make extra trailer behavior consistent with old code 2024-01-31 10:41:01 -08:00
André Cruz 24c258ad58 grpc-health-check: Move `typescript` as a dev dependency 2024-01-30 14:53:34 +00:00
Michael Lumish f52d1429fb grpc-js: Implement server interceptors 2024-01-26 14:36:18 -08:00
Michael Lumish 666a374457
Merge pull request #2645 from murgatroid99/master_merge_1.9.x
Merge 1.9.x into master
2024-01-18 09:39:57 -08:00
Michael Lumish 3915f579f2 Merge 1.9.x into master 2024-01-17 14:28:31 -08:00
Michael Lumish 2a7c9062b8
Merge pull request #2637 from chakhsu/master
fix: export type VerifyOptions
2024-01-04 13:14:13 -08:00
Michael Lumish 9b68bceb74
Merge pull request #2635 from XuanWang-Amos/psm-interop-shared-build
buildscripts: Use the Kokoro shared install lib from the new repo
2024-01-04 13:11:54 -08:00
Chakhsu.Lau 3cdaebdd0c fix: export type VerifyOptions 2024-01-04 21:19:02 +08:00
Xuan Wang 493f9bfa67 buildscripts: Use the Kokoro shared install lib from the new repo 2023-12-18 20:51:23 +00:00
Michael Lumish c5d35fe22d
Merge pull request #2634 from Spinny03/master
fix grpc-reflection README: rename import
2023-12-14 14:25:03 -05:00
Filippo Spinella bda01f97f4 fix README 2023-12-14 18:56:05 +01:00
Michael Lumish 7eb9f42af5
Merge pull request #2633 from murgatroid99/grpc-reflection_1.0.1
grpc-reflection: Increment version to 1.0.1
2023-12-14 11:22:37 -05:00
Michael Lumish 5fe8afc4e7 grpc-reflection: Increment version to 1.0.1 2023-12-14 10:38:11 -05:00
Michael Lumish 2116df0f01
Merge pull request #2632 from gawsoftpl/master
Fix issue #2631 [@grpc/grpc-reflection] Issue with proto file dependencies only on second or next request
2023-12-14 10:33:58 -05:00
Pitos 3f2217e220 Fix issue #2631 2023-12-14 13:53:18 +01:00
Michael Lumish d46360df74
Merge pull request #2613 from jtimmons/feat/grpc-reflection-package
feat(grpc-reflection): created new @grpc/reflection package
2023-12-01 07:44:51 -08:00
Justin Timmons 6a88cf21f4 docs(grpc-reflection): added helloworld implementation for reflection example 2023-11-28 22:04:24 -05:00
Justin Timmons 674a6716d0 Revert "docs(grpc-reflection): updated reflection example to reflect on the reflection API itself"
This reverts commit 8016d8758b.
2023-11-28 21:13:52 -05:00
Justin Timmons 8016d8758b docs(grpc-reflection): updated reflection example to reflect on the reflection API itself 2023-11-27 21:20:02 -05:00
Justin Timmons c53656d67b refactor(grpc-reflection): precompute service list and file encodings 2023-11-18 19:44:48 -05:00
Justin Timmons 234f7f0a0c refactor(grpc-reflection): switch to using protobufjs library for message encoding/decoding 2023-11-18 19:13:59 -05:00
Justin Timmons bc8f2ead26 docs(grpc-reflection): fixed link to example image 2023-11-15 20:52:17 -05:00
Justin Timmons 7a15a1cccb build(grpc-reflection): moved reflection tests to proper job and added test coverage 2023-11-15 20:51:48 -05:00
Justin Timmons 87e1f79846 docs(grpc-reflection): moved example to common directory and match grpc-go server 2023-11-15 20:49:03 -05:00
Michael Lumish f04db5b87a
Merge pull request #2616 from murgatroid99/grpc-js_server_drain
grpc-js: Implement `Server#drain`
2023-11-15 10:26:43 -08:00
Justin Timmons 2449abe398 refactor(grpc-reflection): simplified request handling and file dependency logic 2023-11-15 08:28:47 -05:00
Justin Timmons 89a5cbbdf4 chore(grpc-reflection): cleaned up package dependencies 2023-11-14 22:28:08 -05:00
Michael Lumish 3a16187451 grpc-js: Implement server drain method 2023-11-14 14:37:13 -08:00
Michael Lumish 58b13ac6df
Merge pull request #2612 from murgatroid99/grpc-js_server_unbind
grpc-js: Implement `Server#unbind`
2023-11-14 13:08:11 -08:00
Michael Lumish 66f972cb87 grpc-js: Implement unbind 2023-11-10 14:58:21 -08:00
Justin Timmons 3b4f92ee62 refactor(grpc-reflection): file cleanup and enabled ts strict mode 2023-11-08 22:43:18 -05:00
Justin Timmons 215078f49a feat(grpc-reflection): added reflection service to add capability to a users server 2023-11-08 22:39:06 -05:00
Justin Timmons 54df17727f feat(grpc-reflection): created new grpc-reflection package ported from nestjs-grpc-reflection library 2023-11-08 22:39:06 -05:00
Michael Lumish 779e970099
Merge pull request #2597 from murgatroid99/grpc-js_server_deprecate_start
grpc-js: Deprecate Server#start
2023-10-17 14:55:33 -07:00
Michael Lumish 976567395e grpc-js: Deprecate Server#start 2023-10-16 15:16:58 -07:00
Michael Lumish 4342f60671
Merge pull request #2596 from anuraaga/clean-insecure-constructor
chore(grpc-js): remove unused callcredentials parameter from insecure impl
2023-10-12 10:10:34 -07:00
Anuraag Agrawal abac01a9cf chore(grpc-js): remove unused callcredentials parameter from insecure impl 2023-10-11 17:43:14 +09:00
Michael Lumish 83743646cf
Merge pull request #2592 from murgatroid99/example_cancellation_fix
Cancellation example: corrected information
2023-10-02 10:44:29 -07:00
Michael Lumish 2003c8859c Cancellation example: corrected information 2023-10-02 10:12:03 -07:00
Michael Lumish f7d9baaf25
Merge pull request #2585 from murgatroid99/example_error_handling
Add error handling example
2023-09-26 16:37:41 -07:00
Michael Lumish 220ee8b771
Merge pull request #2584 from murgatroid99/example_cancellation
Add cancellation example
2023-09-26 16:36:57 -07:00
Michael Lumish 0ebfe60bf2 Add error handling example 2023-09-26 09:46:56 -07:00
Michael Lumish 86debcd83b Add cancellation example 2023-09-25 17:20:36 -07:00
Michael Lumish 71936fab74
Merge pull request #2575 from murgatroid99/health-check_2.0
grpc-health-check: Version 2.0
2023-09-25 14:43:56 -07:00
Michael Lumish 32c816c9d1
Merge pull request #2572 from murgatroid99/grpc-js-xds_pick_first
grpc-js-xds: Add support for pick_first in xDS config
2023-09-21 10:19:03 -07:00
Michael Lumish 47c54ec88f
Merge pull request #2576 from murgatroid99/grpc-js_picker_propagation_fix
grpc-js: Delegate to child picker in ResolvingLoadBalancer#updateResolution
2023-09-21 10:18:44 -07:00
Michael Lumish 5be024f060 grpc-js: Delegate to child picker in ResolvingLoadBalancer#updateResolution 2023-09-18 17:32:29 -07:00
Michael Lumish ddb8de2992
Merge pull request #2573 from murgatroid99/proto-loader_no_grpc_library
proto-loader: Allow the `grpcLib` option to be omitted in the type generator
2023-09-18 15:06:29 -07:00
Michael Lumish 524bb7d341 grpc-health-check: Implement version 2.0 update 2023-09-18 14:59:31 -07:00
Michael Lumish afbdbdeec3 grpc-health-check: Add generated code for version 2.0 2023-09-18 13:50:42 -07:00
Michael Lumish ab02dc0be4 proto-loader: Allow the grpcLib option to be omitted in the type generator 2023-09-13 16:57:45 -07:00
Michael Lumish fe74b60440 grpc-js-xds: Add support for pick_first in xDS config 2023-09-13 14:27:25 -07:00
Michael Lumish 6567f8d7cd Update code generation with PickFirst message 2023-09-13 14:07:22 -07:00
Michael Lumish f68ceaa44e
Merge pull request #2568 from murgatroid99/grpc-js-xds_ring_hash
grpc-js-xds: Implement ring_hash LB policy
2023-09-13 12:56:39 -07:00
Michael Lumish a02622572a Improve Listener resource log formatting 2023-09-12 13:00:15 -07:00
Michael Lumish 506748b8a4 Enable ring_hash tracing in interop tests 2023-09-12 12:41:35 -07:00
Michael Lumish 8df1bd712f Treat ring_hash_lb_config field as optional 2023-09-12 10:08:25 -07:00
Michael Lumish 57c1bd2ede grpc-js-xds: interop client: reduce periodic logging 2023-09-11 17:32:41 -07:00
Michael Lumish e570a99d6d Improve unvalidated resource log formatting 2023-09-11 17:29:01 -07:00
Michael Lumish 5c8b11b0be Trace parsed unvalidated resources 2023-09-11 15:39:19 -07:00
Michael Lumish c41c3dae7b Test ring_hash fallback on dropped connection 2023-09-08 14:51:58 -07:00
Michael Lumish 0b2281b028 Revert version support change, run ring_hash tests conditionallly 2023-09-08 10:12:14 -07:00
Michael Lumish 9e487e44ab grpc-js-xds: Update gts dependency for compatibility with TypeScript update 2023-09-07 18:07:20 -07:00
Michael Lumish 9974f7704d grpc-js-xds: Drop support for Node versions below 16 2023-09-07 17:59:35 -07:00
Michael Lumish 4bff372df7 grpc-js: Remove logging in QueuePicker 2023-09-07 17:24:17 -07:00
Michael Lumish 036e0e1b7f grpc-js-xds: Enable xDS affinity test 2023-09-07 17:15:20 -07:00
Michael Lumish 3a43cba3a3 grpc-js-xds: Implement ring_hash LB policy 2023-09-07 17:14:39 -07:00
Michael Lumish 3096f22ba6 grpc-js-xds: Add xxhash-wasm dependency, generate ring_hash code 2023-09-07 17:12:58 -07:00
Michael Lumish 71d8118cc7
Merge pull request #2566 from murgatroid99/grpc-js_load_balancer_channel_args
grpc-js: Pass channel options to LoadBalancer constructors
2023-09-06 11:28:22 -07:00
Michael Lumish 00e1ac46a8 grpc-js: Pass channel options to LoadBalancer constructors 2023-09-06 10:39:56 -07:00
Michael Lumish 092d1e96e2
Merge pull request #2561 from murgatroid99/grpc-js_pick_first_leaf
grpc-js: Make pick_first the universal leaf policy, plus related changes
2023-08-31 15:46:22 -07:00
Michael Lumish 266af4c19f Add pick_first tests 2023-08-30 15:16:25 -07:00
Michael Lumish 3ff8b674bb Export HealthListener type in experimental 2023-08-30 14:57:52 -07:00
Michael Lumish e919aa7aa3 grpc-js-xds: Update LB policies to handle grpc-js changes 2023-08-30 14:47:06 -07:00
Michael Lumish 49b7c6af34 grpc-js: Make pick_first the universal leaf policy, switch to endpoint lists 2023-08-30 14:46:08 -07:00
Michael Lumish 8d532f95db
Merge pull request #2559 from gusumuzhe/fix/load-balancer-infinite-loop
Fix pick-first-load-balancer pick subchannel lost state listener
2023-08-29 10:06:28 -07:00
gusumuzhe 613c9144d9 fix: pick first load balancer call doPick infinite 2023-08-29 17:39:38 +08:00
Michael Lumish 9272aee975
Merge pull request #2557 from murgatroid99/grpc-js-xds_run_custom_lb_test
grpc-js-xds: interop: add custom_lb test, reformat test list
2023-08-28 09:18:10 -07:00
Michael Lumish 04ef12518d Add custom LB test from interop test, fix a bug 2023-08-25 10:19:01 -07:00
Michael Lumish d1f0d9f80d grpc-js-xds: interop: add custom_lb test, reformat test list 2023-08-24 13:38:56 -07:00
Michael Lumish 354bd2d5c3
Merge pull request #2555 from murgatroid99/grpc-js-xds_custom_lb_policy
grpc-js-xds: Implement custom LB policies
2023-08-24 11:22:39 -07:00
Michael Lumish 91631ba11c Update XdsClusterImpl LB policy to accept unset LRS config 2023-08-24 10:02:30 -07:00
Michael Lumish c8b5d3119b Fix missing proto file references 2023-08-23 16:13:00 -07:00
Michael Lumish fa26f4f70f Add spec links 2023-08-23 14:36:49 -07:00
Michael Lumish 9ca8302725 Add tests and fix bugs 2023-08-23 14:32:15 -07:00
Michael Lumish 4daa6dc6b0
Merge pull request #2554 from murgatroid99/proto-loader_0.7.9
proto-loader: Bump version to 0.7.9
2023-08-23 09:37:57 -07:00
Michael Lumish 7326035363 Fix tests 2023-08-23 09:37:47 -07:00
Michael Lumish a417e9bc3b proto-loader: Bump version to 0.7.9 2023-08-22 13:49:52 -07:00
Michael Lumish c679726246 Add custom LB interop test support 2023-08-22 09:53:19 -07:00
Michael Lumish 13a6e6d273 grpc-js-xds: Update envoy-api dependency and code generation 2023-08-16 10:24:47 -07:00
Michael Lumish eb6f1338ab grpc-js-xds: Implement custom LB policies 2023-08-16 10:22:41 -07:00
Michael Lumish 089a8a881e
Merge pull request #2544 from murgatroid99/grpc-js_timer_types_update
grpc-js: Switch Timer type to Timeout
2023-08-14 14:42:58 -07:00
Michael Lumish ea5c18d232 grpc-js: Switch Timer type to Timeout 2023-08-14 10:15:46 -07:00
Michael Lumish 004a5063d2
Merge pull request #2543 from murgatroid99/grpc-js_outlier_detection_config_parsing
grpc-js: Add config parsing tests and fix outlier detection config parsing
2023-08-11 13:26:06 -07:00
Michael Lumish d7c27fb3aa grpc-js: Add config parsing tests and fix outlier detection config parsing 2023-08-11 11:09:55 -07:00
Michael Lumish aa905bf289
Merge pull request #2542 from murgatroid99/grpc-js-xds_config_parsing_tests
grpc-js-xds: Add config parsing tests
2023-08-10 14:56:33 -07:00
Michael Lumish b2ad73a0f3 grpc-js-xds: Add config parsing tests 2023-08-10 13:54:43 -07:00
Michael Lumish b979cbd16c
Merge pull request #2541 from murgatroid99/grpc-js-xds_xds_cluster_impl_config_fix
grpc-js-xds: Fix a typo in xds_cluster_impl parsing code
2023-08-10 11:01:06 -07:00
Michael Lumish 4f8db6907e grpc-js-xds: Fix a typo in xds_cluster_impl parsing code 2023-08-10 09:40:37 -07:00
Michael Lumish 1137102cc7
Merge pull request #2540 from murgatroid99/grpc-js-xds_lrs_config_handling_fix
grpc-js-xds: Fix handling of LRS server configs
2023-08-09 13:01:02 -07:00
Michael Lumish 7ae331bd93 Also enable LRS for LOGICAL_DNS test cluster resources 2023-08-09 11:07:34 -07:00
Michael Lumish 11e19fb450 Enable LRS in local tests and fix LRS config generation bugs 2023-08-09 11:02:33 -07:00
Michael Lumish 8f9bd7a9ee grpc-js-xds: Fix handling of LRS server configs 2023-08-09 10:45:07 -07:00
Michael Lumish 4d288dec0a
Merge pull request #2538 from murgatroid99/grpc-js_lb_policy_config_refactor
grpc-js: Return LB policy configs from resolvers in JSON form
2023-08-08 14:36:02 -07:00
Michael Lumish 08bcbfc677 grpc-js-xds: Adjust LB policy config handling for grpc-js changes 2023-08-07 17:25:39 -07:00
Michael Lumish d28b9e8c37 grpc-js: Return LB policy configs from resolvers in JSON form 2023-08-07 17:23:57 -07:00
567 changed files with 38091 additions and 11404 deletions

View File

@ -8,9 +8,9 @@ on:
branches:
- master
permissions:
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
linux_build:
name: Linux grpc-tools Build
@ -23,7 +23,7 @@ jobs:
run: |
docker build -t kokoro-native-image tools/release/native
docker run -v /var/run/docker.sock:/var/run/docker.sock -v $GITHUB_WORKSPACE:$GITHUB_WORKSPACE kokoro-native-image $GITHUB_WORKSPACE/packages/grpc-tools/build_binaries.sh
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: grpc-tools_linux
path: artifacts/
@ -36,7 +36,7 @@ jobs:
submodules: recursive
- name: Build
run: packages/grpc-tools/build_binaries.sh
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: grpc-tools_macos
path: artifacts/
@ -55,7 +55,7 @@ jobs:
- name: Build
run: powershell -File ./packages/grpc-tools/build_binaries.ps1
shell: cmd
- uses: actions/upload-artifact@v1
- uses: actions/upload-artifact@v4
with:
name: grpc-tools_windows_${{matrix.arch}}
path: artifacts/
@ -64,12 +64,12 @@ jobs:
runs-on: ubuntu-latest
needs: [linux_build, macos_build, windows_build]
steps:
- uses: actions/download-artifact@v2
- uses: actions/download-artifact@v4
- name: Copy
run: |
mkdir artifacts
cp -r ./**/* artifacts/
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v4
with:
name: combined-artifacts
path: artifacts/

View File

@ -8,17 +8,21 @@ See [CONTRIBUTING.md](https://github.com/grpc/grpc-community/blob/master/CONTRIB
for general contribution guidelines.
## Maintainers (in alphabetical order)
- [jtattermusch](https://github.com/jtattermusch), Google Inc.
- [gnossen](https://github.com/gnossen), Google Inc.
- [murgatroid99](https://github.com/murgatroid99), Google Inc.
- [nicolasnoble](https://github.com/nicolasnoble), Google Inc.
- [srini100](https://github.com/srini100), Google Inc.
- [sergiitk](https://github.com/sergiitk), Google Inc.
- [temawi](https://github.com/temawi), Google Inc.
- [wenbozhu](https://github.com/wenbozhu), Google Inc.
## Emeritus Maintainers (in alphabetical order)
- [jiangtaoli2016](https://github.com/jiangtaoli2016), Google Inc.
- [kjin](https://github.com/kjin), Google Inc.
- [matt-kwong](https://github.com/matt-kwong), Google Inc.
- [ofrobots](https://github.com/ofrobots), Google Inc.
- [WeiranFang](https://github.com/WeiranFang), Google Inc.
- [jiangtaoli2016](https://github.com/jiangtaoli2016)
- [jtattermusch](https://github.com/jtattermusch)
- [kjin](https://github.com/kjin)
- [matt-kwong](https://github.com/matt-kwong)
- [nicolasnoble](https://github.com/nicolasnoble)
- [nimf](https://github.com/nimf)
- [ofrobots](https://github.com/ofrobots)
- [srini100](https://github.com/srini100)
- [WeiranFang](https://github.com/WeiranFang)

View File

@ -1,4 +1,3 @@
[![Build Status](https://travis-ci.org/grpc/grpc-node.svg?branch=master)](https://travis-ci.org/grpc/grpc-node)
# gRPC on Node.js
## Implementations
@ -46,3 +45,11 @@ Directory: [`packages/grpc-health-check`](https://github.com/grpc/grpc-node/tree
npm package: [grpc-health-check](https://www.npmjs.com/package/grpc-health-check)
Health check service for gRPC servers.
### gRPC Reflection API Service
Directory: [`packages/grpc-reflection`](https://github.com/grpc/grpc-node/tree/master/packages/grpc-reflection)
npm package: [@grpc/reflection](https://www.npmjs.com/package/@grpc/reflection)
Reflection API service for gRPC servers.

View File

@ -11,8 +11,10 @@ can be set.
checked in order, and the first one that has a value is used.
* no_grpc_proxy, no_proxy
A comma separated list of hostnames to connect to without using a proxy even
if a proxy is set. These variables are checked in order, and the first one
A comma separated list of hostnames, IP addresses,
or CIDR blocks to connect to without using a proxy even
if a proxy is set, for example: no_proxy=example.com,192.168.0.1,192.168.0.0/16.
These variables are checked in order, and the first one
that has a value is used.
* GRPC_SSL_CIPHER_SUITES
@ -62,3 +64,8 @@ can be set.
- INFO - log INFO and ERROR message
- ERROR - log only errors (default)
- NONE - won't log any
* GRPC_NODE_USE_ALTERNATIVE_RESOLVER
Allows changing dns resolve behavior and parse DNS server authority as described in https://github.com/grpc/grpc/blob/master/doc/naming.md
- true - use alternative resolver
- false - use default resolver (default)

View File

@ -0,0 +1,18 @@
# Cancellation
This example shows how clients can cancel in-flight RPCs by cancelling the
call object returned by the method invocation. The client will receive a status
with code `CANCELLED` and the server handler's call object will emit either a
`'cancelled'` event or an `'end'` event.
## Start the server
```
node server.js
```
## Run the client
```
node client.js
```

View File

@ -0,0 +1,64 @@
/*
*
* 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.
*
*/
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const parseArgs = require('minimist');
const PROTO_PATH = __dirname + '/../protos/echo.proto';
const packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
const echoProto = grpc.loadPackageDefinition(packageDefinition).grpc.examples.echo;
function main() {
let argv = parseArgs(process.argv.slice(2), {
string: 'target',
default: {target: 'localhost:50052'}
});
const client = new echoProto.Echo(argv.target, grpc.credentials.createInsecure());
const call = client.bidirectionalStreamingEcho();
const EXPECTED_MESSAGES = 2;
let receivedMessages = 0;
call.on('data', value => {
console.log(`received message "${value.message}"`)
receivedMessages += 1;
if (receivedMessages >= EXPECTED_MESSAGES) {
console.log('cancelling call');
call.cancel();
}
});
call.on('status', statusObject => {
console.log(`received call status with code ${grpc.status[statusObject.code]}`);
});
call.on('error', error => {
console.log(`received error ${error}`);
})
console.log('sending message "hello"');
call.write({message: 'hello'});
console.log('sending message "world"')
call.write({message: 'world'});
}
main();

View File

@ -0,0 +1,68 @@
/*
*
* 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.
*
*/
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const parseArgs = require('minimist');
const PROTO_PATH = __dirname + '/../protos/echo.proto';
const packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
const echoProto = grpc.loadPackageDefinition(packageDefinition).grpc.examples.echo;
function bidirectionalStreamingEcho(call) {
call.on('data', value => {
const message = value.message;
console.log(`echoing message "${message}"`);
call.write({message: message});
});
// Either 'end' or 'cancelled' will be emitted when the call is cancelled
call.on('end', () => {
console.log('server received end event')
call.end();
});
call.on('cancelled', () => {
console.log('server received cancelled event');
});
}
const serviceImplementation = {
bidirectionalStreamingEcho
}
function main() {
const argv = parseArgs(process.argv.slice(2), {
string: 'port',
default: {port: '50052'}
});
const server = new grpc.Server();
server.addService(echoProto.Echo.service, serviceImplementation);
server.bindAsync(`0.0.0.0:${argv.port}`, grpc.ServerCredentials.createInsecure(), () => {
server.start();
});
client = new echoProto.Echo(`localhost:${argv.port}`, grpc.credentials.createInsecure());
}
main();

View File

@ -100,8 +100,11 @@ function main() {
});
const server = new grpc.Server();
server.addService(echoProto.Echo.service, serviceImplementation);
server.bindAsync(`0.0.0.0:${argv.port}`, grpc.ServerCredentials.createInsecure(), () => {
server.start();
server.bindAsync(`0.0.0.0:${argv.port}`, grpc.ServerCredentials.createInsecure(), (err, port) => {
if (err != null) {
return console.error(err);
}
console.log(`gRPC listening on ${port}`)
});
client = new echoProto.Echo(`localhost:${argv.port}`, grpc.credentials.createInsecure());
}

View File

@ -0,0 +1,27 @@
# Debugging
Currently, grpc provides two major tools to help user debug issues, which are logging and channelz.
## Logs
gRPC has put substantial logging instruments on critical paths of gRPC to help users debug issues. The [Environment Variables](https://github.com/grpc/grpc-node/blob/master/doc/environment_variables.md) doc describes the environment variables that control debug logging.
To enable full debug logging, run the code with the following environment variables: `GRPC_TRACE=all GRPC_VERBOSITY=DEBUG`.
## Channelz
We also provide a runtime debugging tool, Channelz, to help users with live debugging.
See the channelz blog post here ([link](https://grpc.io/blog/a-short-introduction-to-channelz/)) for details about how to use channelz service to debug live program.
## Try it
The example is able to showcase how logging and channelz can help with debugging. See the channelz blog post linked above for full explanation.
```
node server.js
```
```
node client.js
```

View File

@ -0,0 +1,97 @@
/*
*
* Copyright 2025 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const parseArgs = require('minimist');
var PROTO_PATH = __dirname + '/../protos/helloworld.proto';
const packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
var helloProto = grpc.loadPackageDefinition(packageDefinition).helloworld;
function serverBindPort(server, port) {
return new Promise((resolve, reject) => {
server.bindAsync(port, grpc.ServerCredentials.createInsecure(), (error, port) => {
if (error) {
reject(error);
} else {
resolve(port);
}
})
});
}
const addressString = 'ipv4:///127.0.0.1:10001,127.0.0.1:10002,127.0.0.1:10003';
function callSayHello(client, name) {
return new Promise((resolve, reject) => {
const deadline = new Date();
deadline.setMilliseconds(deadline.getMilliseconds() + 150);
client.sayHello({name}, {deadline}, (error, response) => {
if (error) {
reject(error);
} else {
resolve(response);
}
});
});
}
async function main() {
const argv = parseArgs(process.argv.slice(2), {
string: ['addr', 'name'],
default: {addr: 'localhost:50051', name: 'world'}
});
// Set up the server serving channelz service.
const channelzServer = new grpc.Server();
grpc.addAdminServicesToServer(channelzServer);
await serverBindPort(channelzServer, argv.addr);
const roundRobinServiceConfig = {
methodConfig: [],
loadBalancingConfig: [{ round_robin: {} }]
};
const client = new helloProto.Greeter(addressString, grpc.credentials.createInsecure(), {'grpc.service_config': JSON.stringify(roundRobinServiceConfig)});
// Contact the server and print out its response
// Make 100 SayHello RPCs
for (let i = 0; i < 100; i++) {
try {
const response = await callSayHello(client, argv.name);
console.log(`Greeting: ${response.message}`);
} catch (e) {
console.log(`could not greet: ${e.message}`);
}
}
// Unless you exit the program (e.g. CTRL+C), channelz data will be available for querying.
// Users can take time to examine and learn about the info provided by channelz.
setInterval(() => {}, 10000);
}
main();

View File

@ -0,0 +1,79 @@
/*
*
* Copyright 2025 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
var PROTO_PATH = __dirname + '/../protos/helloworld.proto';
const packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
var helloProto = grpc.loadPackageDefinition(packageDefinition).helloworld;
const greeterImplementation = {
sayHello: (call, callback) => {
callback(null, { message: `Hello ${call.request.name}`});
}
};
const slowGreeterImplementation = {
sayHello: (call, callback) => {
const waitTimeMs = 100 + (Math.random() * 100)|0;
setTimeout(() => {
callback(null, { message: `Hello ${call.request.name}`});
}, waitTimeMs);
}
}
function serverBindPort(server, port) {
return new Promise((resolve, reject) => {
server.bindAsync(`0.0.0.0:${port}`, grpc.ServerCredentials.createInsecure(), (error, port) => {
if (error) {
reject(error);
} else {
resolve(port);
}
})
});
}
async function main() {
const channelzServer = new grpc.Server();
grpc.addAdminServicesToServer(channelzServer);
await serverBindPort(channelzServer, 50052);
const server1 = new grpc.Server();
server1.addService(helloProto.Greeter.service, greeterImplementation);
await serverBindPort(server1, 10001);
const server2 = new grpc.Server();
server2.addService(helloProto.Greeter.service, greeterImplementation);
await serverBindPort(server2, 10002);
const server3 = new grpc.Server();
server3.addService(helloProto.Greeter.service, slowGreeterImplementation);
await serverBindPort(server3, 10003);
}
main();

View File

@ -0,0 +1,23 @@
# Error Handling
This example demonstrates basic RPC error handling in gRPC for unary and
streaming response cardinalities.
## Start the server
Run the server, whcih returns an error if the RPC request's `name` field is
empty.
```
node server.js
```
## Run the client
Then run the client in another terminal, which makes two requests for each of
unary and streaming responses: one with an empty Name field and one with it
populated with the current username provided by os/user.
```
node client.js
```

View File

@ -0,0 +1,89 @@
/*
*
* 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.
*
*/
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const parseArgs = require('minimist');
const os = require('os');
const PROTO_PATH = __dirname + '/../protos/helloworld.proto';
const packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
const helloProto = grpc.loadPackageDefinition(packageDefinition).helloworld;
function unaryCall(client, requestId, name, expectedCode) {
console.log(`[${requestId}] Calling SayHello with name:"${name}"`);
return new Promise((resolve, reject) => {
client.sayHello({name: name}, (error, value) => {
if (error) {
if (error.code === expectedCode) {
console.log(`[${requestId}] Received error ${error.message}`);
} else {
console.log(`[${requestId}] Received unexpected error ${error.message}`);
}
}
if (value) {
console.log(`[${requestId}] Received response ${value.message}`);
}
resolve();
});
});
}
function streamingCall(client, requestId, name, expectedCode) {
console.log(`[${requestId}] Calling SayHelloStreamReply with name:"${name}"`);
return new Promise((resolve, reject) => {
const call = client.sayHelloStreamReply({name: name});
call.on('data', value => {
console.log(`[${requestId}] Received response ${value.message}`);
});
call.on('status', status => {
console.log(`[${requestId}] Received status with code=${grpc.status[status.code]} details=${status.details}`);
resolve();
});
call.on('error', error => {
if (error.code === expectedCode) {
console.log(`[${requestId}] Received expected error ${error.message}`);
} else {
console.log(`[${requestId}] Received unexpected error ${error.message}`);
}
});
});
}
async function main() {
let argv = parseArgs(process.argv.slice(2), {
string: 'target',
default: {target: 'localhost:50052'}
});
const client = new helloProto.Greeter(argv.target, grpc.credentials.createInsecure());
const name = os.userInfo().username ?? 'unknown';
await unaryCall(client, 1, '', grpc.status.INVALID_ARGUMENT);
await unaryCall(client, 2, name, grpc.status.OK);
await streamingCall(client, 3, '', grpc.status.INVALID_ARGUMENT);
await streamingCall(client, 4, name, grpc.status.OK);
}
main();

View File

@ -0,0 +1,68 @@
/*
*
* 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.
*
*/
var PROTO_PATH = __dirname + '/../protos/helloworld.proto';
var grpc = require('@grpc/grpc-js');
var protoLoader = require('@grpc/proto-loader');
var packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
var hello_proto = grpc.loadPackageDefinition(packageDefinition).helloworld;
/**
* Implements the SayHello RPC method.
*/
function sayHello(call, callback) {
if (call.request.name === '') {
callback({code: grpc.status.INVALID_ARGUMENT, details: 'request missing required field: name'});
}
callback(null, {message: 'Hello ' + call.request.name});
}
const REPLY_COUNT = 5;
function sayHelloStreamReply(call) {
if (call.request.name === '') {
call.emit('error', {code: grpc.status.INVALID_ARGUMENT, details: 'request missing required field: name'});
} else {
for (let i = 0; i < REPLY_COUNT; i++) {
call.write({message: 'Hello ' + call.request.name});
}
call.end();
}
}
/**
* Starts an RPC server that receives requests for the Greeter service at the
* sample server port
*/
function main() {
var server = new grpc.Server();
server.addService(hello_proto.Greeter.service, {sayHello: sayHello, sayHelloStreamReply: sayHelloStreamReply});
server.bindAsync('0.0.0.0:50052', grpc.ServerCredentials.createInsecure(), () => {
server.start();
});
}
main();

View File

@ -44,8 +44,11 @@ function sayHello(call, callback) {
function main() {
var server = new grpc.Server();
server.addService(hello_proto.Greeter.service, {sayHello: sayHello});
server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => {
server.start();
server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), (err, port) => {
if (err != null) {
return console.error(err);
}
console.log(`gRPC listening on ${port}`)
});
}

View File

@ -37,8 +37,11 @@ function sayHello(call, callback) {
function main() {
var server = new grpc.Server();
server.addService(services.GreeterService, {sayHello: sayHello});
server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), () => {
server.start();
server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), (err, port) => {
if (err != null) {
return console.error(err);
}
console.log(`gRPC listening on ${port}`)
});
}

View File

@ -0,0 +1,120 @@
# Interceptor
Node gRPC provides simple APIs to implement and install interceptors on clients
and servers. An interceptor intercepts the execution of each incoming/outgoing
RPC call on the client or server where it is installed. Users can use
interceptors to do logging, authentication/authorization, metrics collection,
and many other functions that can be shared across RPCs.
## Run the server
```
node server.js
```
## Run the client
```
node client.js
```
# Explanation
In Node gRPC, clients and servers each have their own types of interceptors.
## Client
Node gRPC client interceptors are formally specified in [gRFC L5](https://github.com/grpc/proposal/blob/master/L5-node-client-interceptors.md).
An interceptor is a function that can wrap a call object with an
`InterceptingCall`, with intercepting functions for individual call operations.
To illustrate, the following is a trivial interceptor with all interception
methods:
```js
const interceptor = function(options, nextCall) {
const requester = {
start: function(metadata, listener, next) {
const listener = {
onReceiveMetadata: function(metadata, next) {
next(metadata);
},
onReceiveMessage: function(message, next) {
next(message);
},
onReceiveStatus: function(status, next) {
next(status);
}
};
next(metadata, listener);
},
sendMessage: function(message, next) {
next(messasge);
},
halfClose: function(next) {
next();
},
cancel: function(message, next) {
next();
}
};
return new InterceptingCall(nextCall(options), requester);
};
```
The requester intercepts outgoing operations, and the listener intercepts
incoming operations. Each intercepting method can read or modify the data for
that operation before passing it along to the `next` callback.
The `RequesterBuilder` and `ListenerBuilder` utility classes provide an
alternative way to construct requester and listener objects
## Server
Node gRPC server interceptors are formally specified in [gRFC L112](https://github.com/grpc/proposal/blob/master/L112-node-server-interceptors.md).
Similar to client interceptors, a server interceptor is a function that can
wrap a call object with a `ServerInterceptingCall`, with intercepting functions
for individual call operations. Server intercepting functions broadly mirror
the client intercepting functions, with sending and receiving switched. To
illustrate, the following is a trivial server interceptor with all interception
methods:
```js
const interceptor = function(methodDescriptor, call) {
const responder = {
start: function(next) {
const listener = {
onReceiveMetadata: function(metadata, next) {
next(metadata);
},
onReceiveMessage: function(message, next) {
next(message);
},
onReceiveHalfClose: function(next) {
next();
},
onCancel: function() {
}
};
next(listener);
},
sendMetadata: function(metadata, next) {
next(metadata);
},
sendMessage: function(message, next) {
next(message);
},
sendStatus: function(status, next) {
next(status);
}
};
return new ServerInterceptingCall(call, responder);
}
```
As with client interceptors, the responder intercepts outgoing operations and
the listener intercepts incoming operations. Each intercepting method can read
or modify the data for that operation before passing it along to the `next`
callback.
The `ResponderBuilder` and `ServerListenerBuilder` utility classes provide an
alternative way to build responder and server listener objects.

View File

@ -0,0 +1,113 @@
/*
*
* Copyright 2024 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const parseArgs = require('minimist');
const PROTO_PATH = __dirname + '/../protos/echo.proto';
const packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
const echoProto = grpc.loadPackageDefinition(packageDefinition).grpc.examples.echo;
function authInterceptor(options, nextCall) {
const requester = (new grpc.RequesterBuilder())
.withStart((metadata, listener, next) => {
metadata.set('authorization', 'some-secret-token');
next(metadata, listener);
}).build();
return new grpc.InterceptingCall(nextCall(options), requester);
}
// logger is to mock a sophisticated logging system. To simplify the example, we just print out the content.
function logger(format, ...args) {
console.log(`LOG (client):\t${format}\n`, ...args);
}
function loggingInterceptor(options, nextCall) {
const listener = (new grpc.ListenerBuilder())
.withOnReceiveMessage((message, next) => {
logger(`Receive a message ${JSON.stringify(message)} at ${(new Date()).toISOString()}`);
next(message);
}).build();
const requester = (new grpc.RequesterBuilder())
.withSendMessage((message, next) => {
logger(`Send a message ${JSON.stringify(message)} at ${(new Date()).toISOString()}`);
next(message);
}).build();
return new grpc.InterceptingCall(nextCall(options), requester);
}
function callUnaryEcho(client, message) {
return new Promise((resolve, reject) => {
const deadline = new Date();
deadline.setSeconds(deadline.getSeconds() + 10);
client.unaryEcho({message: message}, {deadline}, (error, value) => {
if (error) {
reject(error);
return;
}
console.log(`UnaryEcho: ${JSON.stringify(value)}`);
resolve();
});
});
}
function callBidiStreamingEcho(client) {
return new Promise((resolve, reject) => {
const deadline = new Date();
deadline.setSeconds(deadline.getSeconds() + 10);
const call = client.bidirectionalStreamingEcho({deadline});
call.on('data', value => {
console.log(`BidiStreamingEcho: ${JSON.stringify(value)}`);
});
call.on('status', status => {
if (status.code === grpc.status.OK) {
resolve();
} else {
reject(status);
}
});
call.on('error', () => {
// Ignore error event
});
for (let i = 0; i < 5; i++) {
call.write({message: `Request ${i + 1}`});
}
call.end();
});
}
async function main() {
let argv = parseArgs(process.argv.slice(2), {
string: 'target',
default: {target: 'localhost:50051'}
});
const client = new echoProto.Echo(argv.target, grpc.credentials.createInsecure(), {interceptors: [authInterceptor, loggingInterceptor]});
await callUnaryEcho(client, 'hello world');
await callBidiStreamingEcho(client);
}
main();

View File

@ -0,0 +1,120 @@
/*
*
* Copyright 2024 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const parseArgs = require('minimist');
const PROTO_PATH = __dirname + '/../protos/echo.proto';
const packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
const echoProto = grpc.loadPackageDefinition(packageDefinition).grpc.examples.echo;
function unaryEcho(call, callback) {
console.log(`unary echoing message ${call.request.message}`);
callback(null, call.request);
}
function bidirectionalStreamingEcho(call) {
call.on('data', request => {
console.log(`bidi echoing message ${request.message}`);
call.write(request);
});
call.on('end', () => {
call.end();
});
}
const serviceImplementation = {
unaryEcho,
bidirectionalStreamingEcho
}
function validateAuthorizationMetadata(metadata) {
const authorization = metadata.get('authorization');
if (authorization.length < 1) {
return false;
}
return authorization[0] === 'some-secret-token';
}
function authInterceptor(methodDescriptor, call) {
const listener = (new grpc.ServerListenerBuilder())
.withOnReceiveMetadata((metadata, next) => {
if (validateAuthorizationMetadata(metadata)) {
next(metadata);
} else {
call.sendStatus({
code: grpc.status.UNAUTHENTICATED,
details: 'Auth metadata not correct'
});
}
}).build();
const responder = (new grpc.ResponderBuilder())
.withStart(next => {
next(listener);
}).build();
return new grpc.ServerInterceptingCall(call, responder);
}
// logger is to mock a sophisticated logging system. To simplify the example, we just print out the content.
function logger(format, ...args) {
console.log(`LOG (server):\t${format}\n`, ...args);
}
function loggingInterceptor(methodDescriptor, call) {
const listener = new grpc.ServerListenerBuilder()
.withOnReceiveMessage((message, next) => {
logger(`Receive a message ${JSON.stringify(message)} at ${(new Date()).toISOString()}`);
next(message);
}).build();
const responder = new grpc.ResponderBuilder()
.withStart(next => {
next(listener);
})
.withSendMessage((message, next) => {
logger(`Send a message ${JSON.stringify(message)} at ${(new Date()).toISOString()}`);
next(message);
}).build();
return new grpc.ServerInterceptingCall(call, responder);
}
function main() {
const argv = parseArgs(process.argv.slice(2), {
string: 'port',
default: {port: '50051'}
});
const server = new grpc.Server({interceptors: [authInterceptor, loggingInterceptor]});
server.addService(echoProto.Echo.service, serviceImplementation);
server.bindAsync(`0.0.0.0:${argv.port}`, grpc.ServerCredentials.createInsecure(), (err, port) => {
if (err != null) {
return console.error(err);
}
console.log(`gRPC listening on ${port}`)
});
client = new echoProto.Echo(`localhost:${argv.port}`, grpc.credentials.createInsecure());
}
main();

View File

@ -0,0 +1,16 @@
# Keepalive
This example illustrates how to set up client-side keepalive pings and
server-side keepalive pings and connection age and idleness settings.
## Start the server
```
node server.js
```
## Start the client
```
GRPC_TRACE=transport,keepalive GRPC_VERBOSITY=DEBUG node client.js
```

View File

@ -0,0 +1,61 @@
/*
*
* Copyright 2024 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const parseArgs = require('minimist');
const PROTO_PATH = __dirname + '/../protos/echo.proto';
const packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
const echoProto = grpc.loadPackageDefinition(packageDefinition).grpc.examples.echo;
const keepaliveOptions = {
// Ping the server every 10 seconds to ensure the connection is still active
'grpc.keepalive_time_ms': 10_000,
// Wait 1 second for the ping ack before assuming the connection is dead
'grpc.keepalive_timeout_ms': 1_000,
// send pings even without active streams
'grpc.keepalive_permit_without_calls': 1
}
function main() {
let argv = parseArgs(process.argv.slice(2), {
string: 'target',
default: {target: 'localhost:50052'}
});
const client = new echoProto.Echo(argv.target, grpc.credentials.createInsecure(), keepaliveOptions);
client.unaryEcho({message: 'keepalive demo'}, (error, value) => {
if (error) {
console.log(`Unexpected error from UnaryEcho: ${error}`);
return;
}
console.log(`RPC response: ${JSON.stringify(value)}`);
});
// Keep process alive forever; run with GRPC_TRACE=transport,keepalive GRPC_VERBOSITY=DEBUG to observe ping frames and GOAWAYs due to idleness.
setInterval(() => {}, 1000);
}
main();

View File

@ -0,0 +1,71 @@
/*
*
* Copyright 2024 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const parseArgs = require('minimist');
const PROTO_PATH = __dirname + '/../protos/echo.proto';
const packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
const echoProto = grpc.loadPackageDefinition(packageDefinition).grpc.examples.echo;
const keepaliveOptions = {
// If a client is idle for 15 seconds, send a GOAWAY
'grpc.max_connection_idle_ms': 15_000,
// If any connection is alive for more than 30 seconds, send a GOAWAY
'grpc.max_connection_age_ms': 30_000,
// Allow 5 seconds for pending RPCs to complete before forcibly closing connections
'grpc.max_connection_age_grace_ms': 5_000,
// Ping the client every 5 seconds to ensure the connection is still active
'grpc.keepalive_time_ms': 5_000,
// Wait 1 second for the ping ack before assuming the connection is dead
'grpc.keepalive_timeout_ms': 1_000
}
function unaryEcho(call, callback) {
callback(null, call.request);
}
const serviceImplementation = {
unaryEcho
};
function main() {
const argv = parseArgs(process.argv.slice(2), {
string: 'port',
default: {port: '50052'}
});
const server = new grpc.Server(keepaliveOptions);
server.addService(echoProto.Echo.service, serviceImplementation);
server.bindAsync(`0.0.0.0:${argv.port}`, grpc.ServerCredentials.createInsecure(), (err, port) => {
if (err != null) {
return console.error(err);
}
console.log(`gRPC listening on ${port}`)
});
}
main();

View File

@ -0,0 +1,57 @@
# Load balancing
This examples shows how `Client` can pick different load balancing policies.
## Try it
```
node server.js
```
```
node client.js
```
## Explanation
Two echo servers are serving on "0.0.0.0:50051" and "0.0.0.0:50052". They will include their serving address in the response. So the server on "0.0.0.0:50051" will reply to the RPC with this is examples/load_balancing (from 0.0.0.0:50051).
Two clients are created, to connect to both of these servers. Each client picks a different load balancer (using the `grpc.service_config` option): `pick_first` or `round_robin`.
Note that balancers can also be switched using service config, which allows service owners (instead of client owners) to pick the balancer to use. Service config doc is available at https://github.com/grpc/grpc/blob/master/doc/service_config.md.
### pick_first
The first client is configured to use `pick_first`. `pick_first` tries to connect to the first address, uses it for all RPCs if it connects, or try the next address if it fails (and keep doing that until one connection is successful). Because of this, all the RPCs will be sent to the same backend. The responses received all show the same backend address.
```
this is examples/load_balancing (from 0.0.0.0:50051)
this is examples/load_balancing (from 0.0.0.0:50051)
this is examples/load_balancing (from 0.0.0.0:50051)
this is examples/load_balancing (from 0.0.0.0:50051)
this is examples/load_balancing (from 0.0.0.0:50051)
this is examples/load_balancing (from 0.0.0.0:50051)
this is examples/load_balancing (from 0.0.0.0:50051)
this is examples/load_balancing (from 0.0.0.0:50051)
this is examples/load_balancing (from 0.0.0.0:50051)
this is examples/load_balancing (from 0.0.0.0:50051)
```
### round_robin
The second client is configured to use `round_robin`. `round_robin` connects to all the addresses it sees, and sends an RPC to each backend one at a time in order. E.g. the first RPC will be sent to backend-1, the second RPC will be sent to backend-2, and the third RPC will be sent to backend-1 again.
```
this is examples/load_balancing (from 0.0.0.0:50051)
this is examples/load_balancing (from 0.0.0.0:50051)
this is examples/load_balancing (from 0.0.0.0:50052)
this is examples/load_balancing (from 0.0.0.0:50051)
this is examples/load_balancing (from 0.0.0.0:50052)
this is examples/load_balancing (from 0.0.0.0:50051)
this is examples/load_balancing (from 0.0.0.0:50052)
this is examples/load_balancing (from 0.0.0.0:50051)
this is examples/load_balancing (from 0.0.0.0:50052)
this is examples/load_balancing (from 0.0.0.0:50051)
```
Note that it's possible to see two consecutive RPC sent to the same backend. That's because `round_robin` only picks the connections ready for RPCs. So if one of the two connections is not ready for some reason, all RPCs will be sent to the ready connection.

View File

@ -0,0 +1,75 @@
/*
*
* Copyright 2025 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const PROTO_PATH = __dirname + '/../protos/echo.proto';
const packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
const echoProto = grpc.loadPackageDefinition(packageDefinition).grpc.examples.echo;
const addressString = 'ipv4:///127.0.0.1:50051,127.0.0.1:50052';
function callUnaryEcho(client, message) {
return new Promise((resolve, reject) => {
const deadline = new Date();
deadline.setSeconds(deadline.getSeconds() + 1);
client.unaryEcho({message}, {deadline}, (error, response) => {
if (error) {
reject(error);
} else {
console.log(response.message);
resolve(response);
}
});
});
}
async function makeRPCs(client, count) {
for (let i = 0; i < count; i++) {
await callUnaryEcho(client, "this is examples/load_balancing");
}
}
async function main() {
// "pick_first" is the default, so there's no need to set the load balancing policy.
const pickFirstClient = new echoProto.Echo(addressString, grpc.credentials.createInsecure());
console.log("--- calling helloworld.Greeter/SayHello with pick_first ---");
await makeRPCs(pickFirstClient, 10);
console.log();
const roundRobinServiceConfig = {
methodConfig: [],
loadBalancingConfig: [{ round_robin: {} }]
};
const roundRobinClient = new echoProto.Echo(addressString, grpc.credentials.createInsecure(), {'grpc.service_config': JSON.stringify(roundRobinServiceConfig)});
console.log("--- calling helloworld.Greeter/SayHello with round_robin ---");
await makeRPCs(roundRobinClient, 10);
pickFirstClient.close();
roundRobinClient.close();
}
main();

View File

@ -0,0 +1,60 @@
/*
*
* Copyright 2025 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const PROTO_PATH = __dirname + '/../protos/echo.proto';
const packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
const echoProto = grpc.loadPackageDefinition(packageDefinition).grpc.examples.echo;
function startServer(address) {
return new Promise((resolve, reject) => {
const server = new grpc.Server();
server.addService(echoProto.Echo.service, {
unaryEcho: (call, callback) => {
callback(null, {message: `${call.request.message} (from ${address})`});
}
});
server.bindAsync(address, grpc.ServerCredentials.createInsecure(), (error, port) => {
if (error) {
reject(error);
} else {
resolve(server);
}
});
});
}
const addresses = ['0.0.0.0:50051', '0.0.0.0:50052'];
async function main() {
for (const address of addresses) {
await startServer(address)
}
}
main();

View File

@ -18,6 +18,7 @@
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const parseArgs = require('minimist');
const PROTO_PATH = __dirname + '/../protos/echo.proto';
@ -148,8 +149,11 @@ function main() {
});
const server = new grpc.Server();
server.addService(echoProto.Echo.service, serviceImplementation);
server.bindAsync(`0.0.0.0:${argv.port}`, grpc.ServerCredentials.createInsecure(), () => {
server.start();
server.bindAsync(`0.0.0.0:${argv.port}`, grpc.ServerCredentials.createInsecure(), (err, port) => {
if (err != null) {
return console.error(err);
}
console.log(`gRPC listening on ${port}`)
});
}

View File

@ -5,8 +5,9 @@
"@grpc/proto-loader": "^0.6.0",
"async": "^1.5.2",
"google-protobuf": "^3.0.0",
"@grpc/grpc-js": "^1.8.0",
"@grpc/grpc-js-xds": "^1.8.0",
"@grpc/grpc-js": "^1.10.2",
"@grpc/grpc-js-xds": "^1.10.0",
"@grpc/reflection": "^1.0.0",
"lodash": "^4.6.1",
"minimist": "^1.2.0"
}

View File

@ -0,0 +1,20 @@
var path = require('path');
var grpc = require('@grpc/grpc-js');
var protoLoader = require('@grpc/proto-loader');
var reflection = require('@grpc/reflection');
var PROTO_PATH = path.join(__dirname, '../protos/helloworld.proto');
var server = new grpc.Server();
var packageDefinition = protoLoader.loadSync(PROTO_PATH);
var proto = grpc.loadPackageDefinition(packageDefinition);
var reflection = new reflection.ReflectionService(packageDefinition);
reflection.addToServer(server);
server.addService(proto.helloworld.Greeter.service, {
sayHello: (call, callback) => { callback(null, { message: 'Hello' }) }
});
server.bindAsync('localhost:5000', grpc.ServerCredentials.createInsecure(), () => {
server.start();
});

57
examples/retry/README.md Normal file
View File

@ -0,0 +1,57 @@
# Retry
This example shows how to enable and configure retry on gRPC clients.
## Documentation
[gRFC for client-side retry support](https://github.com/grpc/proposal/blob/master/A6-client-retries.md)
## Try it
This example includes a service implementation that fails requests three times with status code Unavailable, then passes the fourth. The client is configured to make four retry attempts when receiving an Unavailable status code.
First start the server:
```
node server.js
```
Then run the client:
```
node client.js
```
## Usage
### Define your retry policy
Retry is configured via the service config, which can be provided by the name resolver, or as a channel option (described below). In the below example, we set the retry policy for the "grpc.example.echo.Echo" method.
```js
const serviceConfig = {
loadBalancingConfig: [],
methodConfig: [
{
name: [
{
service: 'grpc.examples.echo.Echo',
},
],
retryPolicy: {
maxAttempts: 4,
initialBackoff: '0.01s',
maxBackoff: '0.01s',
backoffMultiplier: 1.0,
retryableStatusCodes: ['UNAVAILABLE'],
},
},
],
};
```
### Providing the retry policy as a channel option
```js
const client = new Echo('localhost:50052', grpc.credentials.createInsecure(), { 'grpc.service_config': JSON.stringify(serviceConfig) });
```

75
examples/retry/client.js Normal file
View File

@ -0,0 +1,75 @@
/*
*
* Copyright 2025 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const parseArgs = require('minimist');
const PROTO_PATH = __dirname + '/../protos/echo.proto';
const packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
const echoProto = grpc.loadPackageDefinition(packageDefinition).grpc.examples.echo;
const serviceConfig = {
loadBalancingConfig: [],
methodConfig: [
{
name: [
{
service: 'grpc.examples.echo.Echo',
},
],
retryPolicy: {
maxAttempts: 4,
initialBackoff: '0.01s',
maxBackoff: '0.01s',
backoffMultiplier: 1.0,
retryableStatusCodes: ['UNAVAILABLE'],
},
},
],
};
function main() {
let argv = parseArgs(process.argv.slice(2), {
string: 'target',
default: {target: 'localhost:50052'}
});
// Set up a connection to the server with service config and create the channel.
// However, the recommended approach is to fetch the retry configuration
// (which is part of the service config) from the name resolver rather than
// defining it on the client side.
const client = new echoProto.Echo('localhost:50052', grpc.credentials.createInsecure(), { 'grpc.service_config': JSON.stringify(serviceConfig) });
client.unaryEcho({message: 'Try and Success'}, (error, value) => {
if (error) {
console.log(`Unexpected error from UnaryEcho: ${error}`);
return;
}
console.log(`RPC response: ${JSON.stringify(value)}`);
});
}
main();

73
examples/retry/server.js Normal file
View File

@ -0,0 +1,73 @@
/*
*
* Copyright 2025 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const parseArgs = require('minimist');
const PROTO_PATH = __dirname + '/../protos/echo.proto';
const packageDefinition = protoLoader.loadSync(
PROTO_PATH,
{keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
});
const echoProto = grpc.loadPackageDefinition(packageDefinition).grpc.examples.echo;
const SUCCEED_EVERY = 4
let callCount = 0;
/* This method will succeed every SUCCEED_EVERY calls, and fail all others with status code
* UNAVAILABLE. */
function unaryEcho(call, callback) {
callCount++;
if (callCount % SUCCEED_EVERY === 0) {
console.log(`Request succeeded count: ${callCount}`);
callback(null, call.request);
} else {
console.log(`Request failed count: ${callCount}`);
callback({
code: grpc.status.UNAVAILABLE,
details: 'Request failed by policy'
});
}
}
const serviceImplementation = {
unaryEcho
};
function main() {
const argv = parseArgs(process.argv.slice(2), {
string: 'port',
default: {port: '50052'}
});
const server = new grpc.Server();
server.addService(echoProto.Echo.service, serviceImplementation);
server.bindAsync(`0.0.0.0:${argv.port}`, grpc.ServerCredentials.createInsecure(), (err, port) => {
if (err != null) {
return console.error(err);
}
console.log(`gRPC listening on ${port}`)
});
}
main();

View File

@ -19,18 +19,19 @@ import * as gulp from 'gulp';
import * as healthCheck from './packages/grpc-health-check/gulpfile';
import * as jsCore from './packages/grpc-js/gulpfile';
import * as jsXds from './packages/grpc-js-xds/gulpfile';
import * as reflection from './packages/grpc-reflection/gulpfile';
import * as protobuf from './packages/proto-loader/gulpfile';
import * as internalTest from './test/gulpfile';
const installAll = gulp.series(jsCore.install, healthCheck.install, protobuf.install, internalTest.install, jsXds.install);
const installAll = gulp.series(protobuf.install, jsCore.install, healthCheck.install, reflection.install, internalTest.install, jsXds.install);
const lint = gulp.parallel(jsCore.lint);
const build = gulp.series(jsCore.compile, protobuf.compile, jsXds.compile);
const build = gulp.series(protobuf.compile, jsCore.compile, jsXds.compile);
const setup = gulp.series(installAll);
const setupPureJSInterop = gulp.series(jsCore.install, protobuf.install, internalTest.install);
const setupPureJSInterop = gulp.series(protobuf.install, jsCore.install, internalTest.install);
const clean = gulp.series(jsCore.clean, protobuf.clean, jsXds.clean);
@ -40,7 +41,7 @@ const nativeTestOnly = gulp.parallel(healthCheck.test);
const nativeTest = gulp.series(build, nativeTestOnly);
const testOnly = gulp.parallel(jsCore.test, nativeTestOnly, protobuf.test, jsXds.test);
const testOnly = gulp.series(jsCore.test, nativeTestOnly, protobuf.test, jsXds.test, reflection.test);
const test = gulp.series(build, testOnly, internalTest.test);

View File

@ -20,14 +20,13 @@
"del": "^3.0.0",
"execa": "^0.8.0",
"gulp": "^4.0.1",
"gulp-jsdoc3": "^1.0.1",
"gulp-jshint": "^2.0.4",
"gulp-mocha": "^4.3.1",
"gulp-sourcemaps": "^2.6.1",
"gulp-tslint": "^8.1.1",
"gulp-typescript": "^3.2.2",
"gulp-util": "^3.0.8",
"jsdoc": "^3.3.2",
"jsdoc": "^4.0.3",
"jshint": "^2.9.5",
"make-dir": "^1.1.0",
"merge2": "^1.1.0",
@ -54,7 +53,8 @@
"include": [
"packages/grpc-health-check/health.js",
"packages/grpc-js/build/src/*",
"packages/proto-loader/build/src/*"
"packages/proto-loader/build/src/*",
"packages/grpc-reflection/build/src/*"
],
"cache": true,
"all": true

View File

@ -4,11 +4,7 @@ Health check client and service for use with gRPC-node.
## Background
This package exports both a client and server that adhere to the [gRPC Health Checking Protocol](https://github.com/grpc/grpc/blob/master/doc/health-checking.md).
By using this package, clients and servers can rely on common proto and service definitions. This means:
- Clients can use the generated stubs to health check _any_ server that adheres to the protocol.
- Servers do not reimplement common logic for publishing health statuses.
This package provides an implementation of the [gRPC Health Checking Protocol](https://github.com/grpc/grpc/blob/master/doc/health-checking.md) service, as described in [gRFC L106](https://github.com/grpc/proposal/blob/master/L106-node-heath-check-library.md).
## Installation
@ -22,33 +18,39 @@ npm install grpc-health-check
### Server
Any gRPC-node server can use `grpc-health-check` to adhere to the gRPC Health Checking Protocol.
Any gRPC-node server can use `grpc-health-check` to adhere to the gRPC Health Checking Protocol.
The following shows how this package can be added to a pre-existing gRPC server.
```javascript 1.8
```typescript
// Import package
let health = require('grpc-health-check');
import { HealthImplementation, ServingStatusMap } from 'grpc-health-check';
// Define service status map. Key is the service name, value is the corresponding status.
// By convention, the empty string "" key represents that status of the entire server.
// By convention, the empty string '' key represents that status of the entire server.
const statusMap = {
"ServiceFoo": proto.grpc.health.v1.HealthCheckResponse.ServingStatus.SERVING,
"ServiceBar": proto.grpc.health.v1.HealthCheckResponse.ServingStatus.NOT_SERVING,
"": proto.grpc.health.v1.HealthCheckResponse.ServingStatus.NOT_SERVING,
'ServiceFoo': 'SERVING',
'ServiceBar': 'NOT_SERVING',
'': 'NOT_SERVING',
};
// Construct the service implementation
let healthImpl = new health.Implementation(statusMap);
const healthImpl = new HealthImplementation(statusMap);
// Add the service and implementation to your pre-existing gRPC-node server
server.addService(health.service, healthImpl);
healthImpl.addToServer(server);
// When ServiceBar comes up
healthImpl.setStatus('serviceBar', 'SERVING');
```
Congrats! Your server now allows any client to run a health check against it.
### Client
Any gRPC-node client can use `grpc-health-check` to run health checks against other servers that follow the protocol.
Any gRPC-node client can use the `service` object exported by `grpc-health-check` to generate clients that can make health check requests.
### Command Line Usage
The absolute path to `health.proto` can be obtained on the command line with `node -p 'require("grpc-health-check").protoPath'`.
## Contributing

View File

@ -19,22 +19,32 @@ import * as gulp from 'gulp';
import * as mocha from 'gulp-mocha';
import * as execa from 'execa';
import * as path from 'path';
import * as del from 'del';
import {linkSync} from '../../util';
const healthCheckDir = __dirname;
const baseDir = path.resolve(healthCheckDir, '..', '..');
const testDir = path.resolve(healthCheckDir, 'test');
const outDir = path.resolve(healthCheckDir, 'build');
const runInstall = () => execa('npm', ['install', '--unsafe-perm'], {cwd: healthCheckDir, stdio: 'inherit'});
const execNpmVerb = (verb: string, ...args: string[]) =>
execa('npm', [verb, ...args], {cwd: healthCheckDir, stdio: 'inherit'});
const execNpmCommand = execNpmVerb.bind(null, 'run');
const runRebuild = () => execa('npm', ['rebuild', '--unsafe-perm'], {cwd: healthCheckDir, stdio: 'inherit'});
const install = () => execNpmVerb('install', '--unsafe-perm');
const install = gulp.series(runInstall, runRebuild);
/**
* Transpiles TypeScript files in src/ to JavaScript according to the settings
* found in tsconfig.json.
*/
const compile = () => execNpmCommand('compile');
const test = () => gulp.src(`${testDir}/*.js`).pipe(mocha({reporter: 'mocha-jenkins-reporter'}));
const runTests = () => {
return gulp.src(`${outDir}/test/**/*.js`)
.pipe(mocha({reporter: 'mocha-jenkins-reporter',
require: ['ts-node/register']}));
};
const test = gulp.series(install, runTests);
export {
install,
compile,
test
}
}

View File

@ -1,55 +0,0 @@
/*
*
* 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.
*
*/
'use strict';
var grpc = require('grpc');
var _get = require('lodash.get');
var _clone = require('lodash.clone')
var health_messages = require('./v1/health_pb');
var health_service = require('./v1/health_grpc_pb');
function HealthImplementation(statusMap) {
this.statusMap = _clone(statusMap);
}
HealthImplementation.prototype.setStatus = function(service, status) {
this.statusMap[service] = status;
};
HealthImplementation.prototype.check = function(call, callback){
var service = call.request.getService();
var status = _get(this.statusMap, service, null);
if (status === null) {
// TODO(murgatroid99): Do this without an explicit reference to grpc.
callback({code:grpc.status.NOT_FOUND});
} else {
var response = new health_messages.HealthCheckResponse();
response.setStatus(status);
callback(null, response);
}
};
module.exports = {
Client: health_service.HealthClient,
messages: health_messages,
service: health_service.HealthService,
Implementation: HealthImplementation
};

View File

@ -1,6 +1,6 @@
{
"name": "grpc-health-check",
"version": "1.8.0",
"version": "2.0.2",
"author": "Google Inc.",
"description": "Health check client and service for use with gRPC-node",
"repository": {
@ -14,18 +14,28 @@
"email": "mlumish@google.com"
}
],
"scripts": {
"compile": "tsc -p .",
"prepare": "npm run generate-types && npm run compile",
"generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs proto/ -O src/generated health/v1/health.proto",
"generate-test-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs proto/ -O test/generated --grpcLib=@grpc/grpc-js health/v1/health.proto"
},
"dependencies": {
"google-protobuf": "^3.4.0",
"grpc": "^1.6.0",
"lodash.clone": "^4.5.0",
"lodash.get": "^4.4.2"
"@grpc/proto-loader": "^0.7.13"
},
"files": [
"LICENSE",
"README.md",
"health.js",
"v1"
"src",
"build",
"proto"
],
"main": "health.js",
"license": "Apache-2.0"
"main": "build/src/health.js",
"types": "build/src/health.d.ts",
"license": "Apache-2.0",
"devDependencies": {
"@grpc/grpc-js": "file:../grpc-js",
"@types/mocha": "^10.0.10",
"typescript": "^5.2.2"
}
}

View File

@ -0,0 +1,93 @@
// Copyright 2015 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.
// The canonical version of this proto can be found at
// https://github.com/grpc/grpc-proto/blob/master/grpc/health/v1/health.proto
syntax = "proto3";
package grpc.health.v1;
option csharp_namespace = "Grpc.Health.V1";
option go_package = "google.golang.org/grpc/health/grpc_health_v1";
option java_multiple_files = true;
option java_outer_classname = "HealthProto";
option java_package = "io.grpc.health.v1";
message HealthListRequest {}
message HealthListResponse {
// statuses contains all the services and their respective status.
map<string, HealthCheckResponse> statuses = 1;
}
message HealthCheckRequest {
string service = 1;
}
message HealthCheckResponse {
enum ServingStatus {
UNKNOWN = 0;
SERVING = 1;
NOT_SERVING = 2;
SERVICE_UNKNOWN = 3; // Used only by the Watch method.
}
ServingStatus status = 1;
}
// Health is gRPC's mechanism for checking whether a server is able to handle
// RPCs. Its semantics are documented in
// https://github.com/grpc/grpc/blob/master/doc/health-checking.md.
service Health {
// Check gets the health of the specified service. If the requested service
// is unknown, the call will fail with status NOT_FOUND. If the caller does
// not specify a service name, the server should respond with its overall
// health status.
//
// Clients should set a deadline when calling Check, and can declare the
// server unhealthy if they do not receive a timely response.
//
// Check implementations should be idempotent and side effect free.
rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
// Performs a watch for the serving status of the requested service.
// The server will immediately send back a message indicating the current
// serving status. It will then subsequently send a new message whenever
// the service's serving status changes.
//
// If the requested service is unknown when the call is received, the
// server will send a message setting the serving status to
// SERVICE_UNKNOWN but will *not* terminate the call. If at some
// future point, the serving status of the service becomes known, the
// server will send a new message with the service's serving status.
//
// If the call terminates with status UNIMPLEMENTED, then clients
// should assume this method is not supported and should not retry the
// call. If the call terminates with any other status (including OK),
// clients should retry the call with appropriate exponential backoff.
rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse);
// List provides a non-atomic snapshot of the health of all the available
// services.
//
// The server may respond with a RESOURCE_EXHAUSTED error if too many services
// exist.
//
// Clients should set a deadline when calling List, and can declare the server
// unhealthy if they do not receive a timely response.
//
// Clients should keep in mind that the list of health services exposed by an
// application can change over the lifetime of the process.
rpc List(HealthListRequest) returns (HealthListResponse);
}

View File

@ -0,0 +1,10 @@
// Original file: proto/health/v1/health.proto
import type { MethodDefinition } from '@grpc/proto-loader'
import type { HealthCheckRequest as _grpc_health_v1_HealthCheckRequest, HealthCheckRequest__Output as _grpc_health_v1_HealthCheckRequest__Output } from '../../../grpc/health/v1/HealthCheckRequest';
import type { HealthCheckResponse as _grpc_health_v1_HealthCheckResponse, HealthCheckResponse__Output as _grpc_health_v1_HealthCheckResponse__Output } from '../../../grpc/health/v1/HealthCheckResponse';
export interface HealthDefinition {
Check: MethodDefinition<_grpc_health_v1_HealthCheckRequest, _grpc_health_v1_HealthCheckResponse, _grpc_health_v1_HealthCheckRequest__Output, _grpc_health_v1_HealthCheckResponse__Output>
Watch: MethodDefinition<_grpc_health_v1_HealthCheckRequest, _grpc_health_v1_HealthCheckResponse, _grpc_health_v1_HealthCheckRequest__Output, _grpc_health_v1_HealthCheckResponse__Output>
}

View File

@ -0,0 +1,10 @@
// Original file: proto/health/v1/health.proto
export interface HealthCheckRequest {
'service'?: (string);
}
export interface HealthCheckRequest__Output {
'service': (string);
}

View File

@ -0,0 +1,37 @@
// Original file: proto/health/v1/health.proto
// Original file: proto/health/v1/health.proto
export const _grpc_health_v1_HealthCheckResponse_ServingStatus = {
UNKNOWN: 'UNKNOWN',
SERVING: 'SERVING',
NOT_SERVING: 'NOT_SERVING',
/**
* Used only by the Watch method.
*/
SERVICE_UNKNOWN: 'SERVICE_UNKNOWN',
} as const;
export type _grpc_health_v1_HealthCheckResponse_ServingStatus =
| 'UNKNOWN'
| 0
| 'SERVING'
| 1
| 'NOT_SERVING'
| 2
/**
* Used only by the Watch method.
*/
| 'SERVICE_UNKNOWN'
| 3
export type _grpc_health_v1_HealthCheckResponse_ServingStatus__Output = typeof _grpc_health_v1_HealthCheckResponse_ServingStatus[keyof typeof _grpc_health_v1_HealthCheckResponse_ServingStatus]
export interface HealthCheckResponse {
'status'?: (_grpc_health_v1_HealthCheckResponse_ServingStatus);
}
export interface HealthCheckResponse__Output {
'status': (_grpc_health_v1_HealthCheckResponse_ServingStatus__Output);
}

View File

@ -0,0 +1,112 @@
/*
*
* Copyright 2023 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import * as path from 'path';
import { loadSync, ServiceDefinition } from '@grpc/proto-loader';
import { HealthCheckRequest__Output } from './generated/grpc/health/v1/HealthCheckRequest';
import { HealthCheckResponse } from './generated/grpc/health/v1/HealthCheckResponse';
import { sendUnaryData, Server, ServerUnaryCall, ServerWritableStream } from './server-type';
const loadedProto = loadSync('health/v1/health.proto', {
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true,
includeDirs: [`${__dirname}/../../proto`],
});
export const service = loadedProto['grpc.health.v1.Health'] as ServiceDefinition;
const GRPC_STATUS_NOT_FOUND = 5;
export type ServingStatus = 'UNKNOWN' | 'SERVING' | 'NOT_SERVING';
export interface ServingStatusMap {
[serviceName: string]: ServingStatus;
}
interface StatusWatcher {
(status: ServingStatus): void;
}
export class HealthImplementation {
private statusMap: Map<string, ServingStatus> = new Map();
private watchers: Map<string, Set<StatusWatcher>> = new Map();
constructor(initialStatusMap?: ServingStatusMap) {
if (initialStatusMap) {
for (const [serviceName, status] of Object.entries(initialStatusMap)) {
this.statusMap.set(serviceName, status);
}
}
}
setStatus(service: string, status: ServingStatus) {
this.statusMap.set(service, status);
for (const watcher of this.watchers.get(service) ?? []) {
watcher(status);
}
}
private addWatcher(service: string, watcher: StatusWatcher) {
const existingWatcherSet = this.watchers.get(service);
if (existingWatcherSet) {
existingWatcherSet.add(watcher);
} else {
const newWatcherSet = new Set<StatusWatcher>();
newWatcherSet.add(watcher);
this.watchers.set(service, newWatcherSet);
}
}
private removeWatcher(service: string, watcher: StatusWatcher) {
this.watchers.get(service)?.delete(watcher);
}
addToServer(server: Server) {
server.addService(service, {
check: (call: ServerUnaryCall<HealthCheckRequest__Output, HealthCheckResponse>, callback: sendUnaryData<HealthCheckResponse>) => {
const serviceName = call.request.service;
const status = this.statusMap.get(serviceName);
if (status) {
callback(null, {status: status});
} else {
callback({code: GRPC_STATUS_NOT_FOUND, details: `Health status unknown for service ${serviceName}`});
}
},
watch: (call: ServerWritableStream<HealthCheckRequest__Output, HealthCheckResponse>) => {
const serviceName = call.request.service;
const statusWatcher = (status: ServingStatus) => {
call.write({status: status});
};
this.addWatcher(serviceName, statusWatcher);
call.on('cancelled', () => {
this.removeWatcher(serviceName, statusWatcher);
});
const currentStatus = this.statusMap.get(serviceName);
if (currentStatus) {
call.write({status: currentStatus});
} else {
call.write({status: 'SERVICE_UNKNOWN'});
}
}
});
}
}
export const protoPath = path.resolve(__dirname, '../../proto/health/v1/health.proto');

View File

@ -0,0 +1,75 @@
/*
* 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 { Readable, Writable } from 'stream';
interface EmitterAugmentation1<Name extends string | symbol, Arg> {
addListener(event: Name, listener: (arg1: Arg) => void): this;
emit(event: Name, arg1: Arg): boolean;
on(event: Name, listener: (arg1: Arg) => void): this;
once(event: Name, listener: (arg1: Arg) => void): this;
prependListener(event: Name, listener: (arg1: Arg) => void): this;
prependOnceListener(event: Name, listener: (arg1: Arg) => void): this;
removeListener(event: Name, listener: (arg1: Arg) => void): this;
}
/* eslint-disable @typescript-eslint/no-explicit-any */
export type WriteCallback = (error: Error | null | undefined) => void;
export interface IntermediateObjectReadable<T> extends Readable {
read(size?: number): any & T;
}
export type ObjectReadable<T> = {
read(size?: number): T;
} & EmitterAugmentation1<'data', T> &
IntermediateObjectReadable<T>;
export interface IntermediateObjectWritable<T> extends Writable {
_write(chunk: any & T, encoding: string, callback: Function): void;
write(chunk: any & T, cb?: WriteCallback): boolean;
write(chunk: any & T, encoding?: any, cb?: WriteCallback): boolean;
setDefaultEncoding(encoding: string): this;
end(): ReturnType<Writable['end']> extends Writable ? this : void;
end(
chunk: any & T,
cb?: Function
): ReturnType<Writable['end']> extends Writable ? this : void;
end(
chunk: any & T,
encoding?: any,
cb?: Function
): ReturnType<Writable['end']> extends Writable ? this : void;
}
export interface ObjectWritable<T> extends IntermediateObjectWritable<T> {
_write(chunk: T, encoding: string, callback: Function): void;
write(chunk: T, cb?: Function): boolean;
write(chunk: T, encoding?: any, cb?: Function): boolean;
setDefaultEncoding(encoding: string): this;
end(): ReturnType<Writable['end']> extends Writable ? this : void;
end(
chunk: T,
cb?: Function
): ReturnType<Writable['end']> extends Writable ? this : void;
end(
chunk: T,
encoding?: any,
cb?: Function
): ReturnType<Writable['end']> extends Writable ? this : void;
}

View File

@ -0,0 +1,103 @@
/*
* 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 { ServiceDefinition } from '@grpc/proto-loader';
import { ObjectReadable, ObjectWritable } from './object-stream';
import { EventEmitter } from 'events';
type Metadata = any;
interface StatusObject {
code: number;
details: string;
metadata: Metadata;
}
type Deadline = Date | number;
type ServerStatusResponse = Partial<StatusObject>;
type ServerErrorResponse = ServerStatusResponse & Error;
type ServerSurfaceCall = {
cancelled: boolean;
readonly metadata: Metadata;
getPeer(): string;
sendMetadata(responseMetadata: Metadata): void;
getDeadline(): Deadline;
getPath(): string;
} & EventEmitter;
export type ServerUnaryCall<RequestType, ResponseType> = ServerSurfaceCall & {
request: RequestType;
};
type ServerReadableStream<RequestType, ResponseType> =
ServerSurfaceCall & ObjectReadable<RequestType>;
export type ServerWritableStream<RequestType, ResponseType> =
ServerSurfaceCall &
ObjectWritable<ResponseType> & {
request: RequestType;
end: (metadata?: Metadata) => void;
};
type ServerDuplexStream<RequestType, ResponseType> = ServerSurfaceCall &
ObjectReadable<RequestType> &
ObjectWritable<ResponseType> & { end: (metadata?: Metadata) => void };
// Unary response callback signature.
export type sendUnaryData<ResponseType> = (
error: ServerErrorResponse | ServerStatusResponse | null,
value?: ResponseType | null,
trailer?: Metadata,
flags?: number
) => void;
// User provided handler for unary calls.
type handleUnaryCall<RequestType, ResponseType> = (
call: ServerUnaryCall<RequestType, ResponseType>,
callback: sendUnaryData<ResponseType>
) => void;
// User provided handler for client streaming calls.
type handleClientStreamingCall<RequestType, ResponseType> = (
call: ServerReadableStream<RequestType, ResponseType>,
callback: sendUnaryData<ResponseType>
) => void;
// User provided handler for server streaming calls.
type handleServerStreamingCall<RequestType, ResponseType> = (
call: ServerWritableStream<RequestType, ResponseType>
) => void;
// User provided handler for bidirectional streaming calls.
type handleBidiStreamingCall<RequestType, ResponseType> = (
call: ServerDuplexStream<RequestType, ResponseType>
) => void;
export type HandleCall<RequestType, ResponseType> =
| handleUnaryCall<RequestType, ResponseType>
| handleClientStreamingCall<RequestType, ResponseType>
| handleServerStreamingCall<RequestType, ResponseType>
| handleBidiStreamingCall<RequestType, ResponseType>;
export type UntypedHandleCall = HandleCall<any, any>;
export interface UntypedServiceImplementation {
[name: string]: UntypedHandleCall;
}
export interface Server {
addService(service: ServiceDefinition, implementation: UntypedServiceImplementation): void;
}

View File

@ -0,0 +1,129 @@
// Original file: proto/health/v1/health.proto
import type * as grpc from '@grpc/grpc-js'
import type { MethodDefinition } from '@grpc/proto-loader'
import type { HealthCheckRequest as _grpc_health_v1_HealthCheckRequest, HealthCheckRequest__Output as _grpc_health_v1_HealthCheckRequest__Output } from '../../../grpc/health/v1/HealthCheckRequest';
import type { HealthCheckResponse as _grpc_health_v1_HealthCheckResponse, HealthCheckResponse__Output as _grpc_health_v1_HealthCheckResponse__Output } from '../../../grpc/health/v1/HealthCheckResponse';
/**
* Health is gRPC's mechanism for checking whether a server is able to handle
* RPCs. Its semantics are documented in
* https://github.com/grpc/grpc/blob/master/doc/health-checking.md.
*/
export interface HealthClient extends grpc.Client {
/**
* Check gets the health of the specified service. If the requested service
* is unknown, the call will fail with status NOT_FOUND. If the caller does
* not specify a service name, the server should respond with its overall
* health status.
*
* Clients should set a deadline when calling Check, and can declare the
* server unhealthy if they do not receive a timely response.
*
* Check implementations should be idempotent and side effect free.
*/
Check(argument: _grpc_health_v1_HealthCheckRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_health_v1_HealthCheckResponse__Output>): grpc.ClientUnaryCall;
Check(argument: _grpc_health_v1_HealthCheckRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_health_v1_HealthCheckResponse__Output>): grpc.ClientUnaryCall;
Check(argument: _grpc_health_v1_HealthCheckRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_health_v1_HealthCheckResponse__Output>): grpc.ClientUnaryCall;
Check(argument: _grpc_health_v1_HealthCheckRequest, callback: grpc.requestCallback<_grpc_health_v1_HealthCheckResponse__Output>): grpc.ClientUnaryCall;
/**
* Check gets the health of the specified service. If the requested service
* is unknown, the call will fail with status NOT_FOUND. If the caller does
* not specify a service name, the server should respond with its overall
* health status.
*
* Clients should set a deadline when calling Check, and can declare the
* server unhealthy if they do not receive a timely response.
*
* Check implementations should be idempotent and side effect free.
*/
check(argument: _grpc_health_v1_HealthCheckRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_health_v1_HealthCheckResponse__Output>): grpc.ClientUnaryCall;
check(argument: _grpc_health_v1_HealthCheckRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_health_v1_HealthCheckResponse__Output>): grpc.ClientUnaryCall;
check(argument: _grpc_health_v1_HealthCheckRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_health_v1_HealthCheckResponse__Output>): grpc.ClientUnaryCall;
check(argument: _grpc_health_v1_HealthCheckRequest, callback: grpc.requestCallback<_grpc_health_v1_HealthCheckResponse__Output>): grpc.ClientUnaryCall;
/**
* Performs a watch for the serving status of the requested service.
* The server will immediately send back a message indicating the current
* serving status. It will then subsequently send a new message whenever
* the service's serving status changes.
*
* If the requested service is unknown when the call is received, the
* server will send a message setting the serving status to
* SERVICE_UNKNOWN but will *not* terminate the call. If at some
* future point, the serving status of the service becomes known, the
* server will send a new message with the service's serving status.
*
* If the call terminates with status UNIMPLEMENTED, then clients
* should assume this method is not supported and should not retry the
* call. If the call terminates with any other status (including OK),
* clients should retry the call with appropriate exponential backoff.
*/
Watch(argument: _grpc_health_v1_HealthCheckRequest, metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientReadableStream<_grpc_health_v1_HealthCheckResponse__Output>;
Watch(argument: _grpc_health_v1_HealthCheckRequest, options?: grpc.CallOptions): grpc.ClientReadableStream<_grpc_health_v1_HealthCheckResponse__Output>;
/**
* Performs a watch for the serving status of the requested service.
* The server will immediately send back a message indicating the current
* serving status. It will then subsequently send a new message whenever
* the service's serving status changes.
*
* If the requested service is unknown when the call is received, the
* server will send a message setting the serving status to
* SERVICE_UNKNOWN but will *not* terminate the call. If at some
* future point, the serving status of the service becomes known, the
* server will send a new message with the service's serving status.
*
* If the call terminates with status UNIMPLEMENTED, then clients
* should assume this method is not supported and should not retry the
* call. If the call terminates with any other status (including OK),
* clients should retry the call with appropriate exponential backoff.
*/
watch(argument: _grpc_health_v1_HealthCheckRequest, metadata: grpc.Metadata, options?: grpc.CallOptions): grpc.ClientReadableStream<_grpc_health_v1_HealthCheckResponse__Output>;
watch(argument: _grpc_health_v1_HealthCheckRequest, options?: grpc.CallOptions): grpc.ClientReadableStream<_grpc_health_v1_HealthCheckResponse__Output>;
}
/**
* Health is gRPC's mechanism for checking whether a server is able to handle
* RPCs. Its semantics are documented in
* https://github.com/grpc/grpc/blob/master/doc/health-checking.md.
*/
export interface HealthHandlers extends grpc.UntypedServiceImplementation {
/**
* Check gets the health of the specified service. If the requested service
* is unknown, the call will fail with status NOT_FOUND. If the caller does
* not specify a service name, the server should respond with its overall
* health status.
*
* Clients should set a deadline when calling Check, and can declare the
* server unhealthy if they do not receive a timely response.
*
* Check implementations should be idempotent and side effect free.
*/
Check: grpc.handleUnaryCall<_grpc_health_v1_HealthCheckRequest__Output, _grpc_health_v1_HealthCheckResponse>;
/**
* Performs a watch for the serving status of the requested service.
* The server will immediately send back a message indicating the current
* serving status. It will then subsequently send a new message whenever
* the service's serving status changes.
*
* If the requested service is unknown when the call is received, the
* server will send a message setting the serving status to
* SERVICE_UNKNOWN but will *not* terminate the call. If at some
* future point, the serving status of the service becomes known, the
* server will send a new message with the service's serving status.
*
* If the call terminates with status UNIMPLEMENTED, then clients
* should assume this method is not supported and should not retry the
* call. If the call terminates with any other status (including OK),
* clients should retry the call with appropriate exponential backoff.
*/
Watch: grpc.handleServerStreamingCall<_grpc_health_v1_HealthCheckRequest__Output, _grpc_health_v1_HealthCheckResponse>;
}
export interface HealthDefinition extends grpc.ServiceDefinition {
Check: MethodDefinition<_grpc_health_v1_HealthCheckRequest, _grpc_health_v1_HealthCheckResponse, _grpc_health_v1_HealthCheckRequest__Output, _grpc_health_v1_HealthCheckResponse__Output>
Watch: MethodDefinition<_grpc_health_v1_HealthCheckRequest, _grpc_health_v1_HealthCheckResponse, _grpc_health_v1_HealthCheckRequest__Output, _grpc_health_v1_HealthCheckResponse__Output>
}

View File

@ -0,0 +1,10 @@
// Original file: proto/health/v1/health.proto
export interface HealthCheckRequest {
'service'?: (string);
}
export interface HealthCheckRequest__Output {
'service': (string);
}

View File

@ -0,0 +1,37 @@
// Original file: proto/health/v1/health.proto
// Original file: proto/health/v1/health.proto
export const _grpc_health_v1_HealthCheckResponse_ServingStatus = {
UNKNOWN: 'UNKNOWN',
SERVING: 'SERVING',
NOT_SERVING: 'NOT_SERVING',
/**
* Used only by the Watch method.
*/
SERVICE_UNKNOWN: 'SERVICE_UNKNOWN',
} as const;
export type _grpc_health_v1_HealthCheckResponse_ServingStatus =
| 'UNKNOWN'
| 0
| 'SERVING'
| 1
| 'NOT_SERVING'
| 2
/**
* Used only by the Watch method.
*/
| 'SERVICE_UNKNOWN'
| 3
export type _grpc_health_v1_HealthCheckResponse_ServingStatus__Output = typeof _grpc_health_v1_HealthCheckResponse_ServingStatus[keyof typeof _grpc_health_v1_HealthCheckResponse_ServingStatus]
export interface HealthCheckResponse {
'status'?: (_grpc_health_v1_HealthCheckResponse_ServingStatus);
}
export interface HealthCheckResponse__Output {
'status': (_grpc_health_v1_HealthCheckResponse_ServingStatus__Output);
}

View File

@ -0,0 +1,26 @@
import type * as grpc from '@grpc/grpc-js';
import type { MessageTypeDefinition } from '@grpc/proto-loader';
import type { HealthClient as _grpc_health_v1_HealthClient, HealthDefinition as _grpc_health_v1_HealthDefinition } from './grpc/health/v1/Health';
type SubtypeConstructor<Constructor extends new (...args: any) => any, Subtype> = {
new(...args: ConstructorParameters<Constructor>): Subtype;
};
export interface ProtoGrpcType {
grpc: {
health: {
v1: {
/**
* Health is gRPC's mechanism for checking whether a server is able to handle
* RPCs. Its semantics are documented in
* https://github.com/grpc/grpc/blob/master/doc/health-checking.md.
*/
Health: SubtypeConstructor<typeof grpc.Client, _grpc_health_v1_HealthClient> & { service: _grpc_health_v1_HealthDefinition }
HealthCheckRequest: MessageTypeDefinition
HealthCheckResponse: MessageTypeDefinition
}
}
}
}

View File

@ -1,103 +0,0 @@
/*
*
* 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.
*
*/
'use strict';
var assert = require('assert');
var health = require('../health');
var health_messages = require('../v1/health_pb');
var ServingStatus = health_messages.HealthCheckResponse.ServingStatus;
var grpc = require('grpc');
describe('Health Checking', function() {
var statusMap = {
'': ServingStatus.SERVING,
'grpc.test.TestServiceNotServing': ServingStatus.NOT_SERVING,
'grpc.test.TestServiceServing': ServingStatus.SERVING
};
var healthServer;
var healthImpl;
var healthClient;
before(function() {
healthServer = new grpc.Server();
healthImpl = new health.Implementation(statusMap);
healthServer.addService(health.service, healthImpl);
var port_num = healthServer.bind('0.0.0.0:0',
grpc.ServerCredentials.createInsecure());
healthServer.start();
healthClient = new health.Client('localhost:' + port_num,
grpc.credentials.createInsecure());
});
after(function() {
healthServer.forceShutdown();
});
it('should say an enabled service is SERVING', function(done) {
var request = new health_messages.HealthCheckRequest();
request.setService('');
healthClient.check(request, function(err, response) {
assert.ifError(err);
assert.strictEqual(response.getStatus(), ServingStatus.SERVING);
done();
});
});
it('should say that a disabled service is NOT_SERVING', function(done) {
var request = new health_messages.HealthCheckRequest();
request.setService('grpc.test.TestServiceNotServing');
healthClient.check(request, function(err, response) {
assert.ifError(err);
assert.strictEqual(response.getStatus(), ServingStatus.NOT_SERVING);
done();
});
});
it('should say that an enabled service is SERVING', function(done) {
var request = new health_messages.HealthCheckRequest();
request.setService('grpc.test.TestServiceServing');
healthClient.check(request, function(err, response) {
assert.ifError(err);
assert.strictEqual(response.getStatus(), ServingStatus.SERVING);
done();
});
});
it('should get NOT_FOUND if the service is not registered', function(done) {
var request = new health_messages.HealthCheckRequest();
request.setService('not_registered');
healthClient.check(request, function(err, response) {
assert(err);
assert.strictEqual(err.code, grpc.status.NOT_FOUND);
done();
});
});
it('should get a different response if the status changes', function(done) {
var request = new health_messages.HealthCheckRequest();
request.setService('transient');
healthClient.check(request, function(err, response) {
assert(err);
assert.strictEqual(err.code, grpc.status.NOT_FOUND);
healthImpl.setStatus('transient', ServingStatus.SERVING);
healthClient.check(request, function(err, response) {
assert.ifError(err);
assert.strictEqual(response.getStatus(), ServingStatus.SERVING);
done();
});
});
});
});

View File

@ -0,0 +1,152 @@
/*
*
* Copyright 2023 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import * as assert from 'assert';
import * as grpc from '@grpc/grpc-js';
import { HealthImplementation, ServingStatusMap, service as healthServiceDefinition } from '../src/health';
import { HealthClient } from './generated/grpc/health/v1/Health';
import { HealthCheckResponse__Output, _grpc_health_v1_HealthCheckResponse_ServingStatus__Output } from './generated/grpc/health/v1/HealthCheckResponse';
describe('Health checking', () => {
const statusMap: ServingStatusMap = {
'': 'SERVING',
'grpc.test.TestServiceNotServing': 'NOT_SERVING',
'grpc.test.TestServiceServing': 'SERVING'
};
let healthServer: grpc.Server;
let healthClient: HealthClient;
let healthImpl: HealthImplementation;
beforeEach(done => {
healthServer = new grpc.Server();
healthImpl = new HealthImplementation(statusMap);
healthImpl.addToServer(healthServer);
healthServer.bindAsync('localhost:0', grpc.ServerCredentials.createInsecure(), (error, port) => {
if (error) {
done(error);
return;
}
const HealthClientConstructor = grpc.makeClientConstructor(healthServiceDefinition, 'grpc.health.v1.HealthService');
healthClient = new HealthClientConstructor(`localhost:${port}`, grpc.credentials.createInsecure()) as unknown as HealthClient;
healthServer.start();
done();
});
});
afterEach((done) => {
healthClient.close();
healthServer.tryShutdown(done);
});
describe('check', () => {
it('Should say that an enabled service is SERVING', done => {
healthClient.check({service: ''}, (error, value) => {
assert.ifError(error);
assert.strictEqual(value?.status, 'SERVING');
done();
});
});
it('Should say that a disabled service is NOT_SERVING', done => {
healthClient.check({service: 'grpc.test.TestServiceNotServing'}, (error, value) => {
assert.ifError(error);
assert.strictEqual(value?.status, 'NOT_SERVING');
done();
});
});
it('Should get NOT_FOUND if the service is not registered', done => {
healthClient.check({service: 'not_registered'}, (error, value) => {
assert(error);
assert.strictEqual(error.code, grpc.status.NOT_FOUND);
done();
});
});
it('Should get a different response if the health status changes', done => {
healthClient.check({service: 'transient'}, (error, value) => {
assert(error);
assert.strictEqual(error.code, grpc.status.NOT_FOUND);
healthImpl.setStatus('transient', 'SERVING');
healthClient.check({service: 'transient'}, (error, value) => {
assert.ifError(error);
assert.strictEqual(value?.status, 'SERVING');
done();
});
});
});
});
describe('watch', () => {
it('Should respond with the health status for an existing service', done => {
const call = healthClient.watch({service: ''});
call.on('data', (response: HealthCheckResponse__Output) => {
assert.strictEqual(response.status, 'SERVING');
call.cancel();
});
call.on('error', () => {});
call.on('status', status => {
assert.strictEqual(status.code, grpc.status.CANCELLED);
done();
});
});
it('Should send a new update when the status changes', done => {
const receivedStatusList: _grpc_health_v1_HealthCheckResponse_ServingStatus__Output[] = [];
const call = healthClient.watch({service: 'grpc.test.TestServiceServing'});
call.on('data', (response: HealthCheckResponse__Output) => {
switch (receivedStatusList.length) {
case 0:
assert.strictEqual(response.status, 'SERVING');
healthImpl.setStatus('grpc.test.TestServiceServing', 'NOT_SERVING');
break;
case 1:
assert.strictEqual(response.status, 'NOT_SERVING');
call.cancel();
break;
default:
assert.fail(`Unexpected third status update ${response.status}`);
}
receivedStatusList.push(response.status);
});
call.on('error', () => {});
call.on('status', status => {
assert.deepStrictEqual(receivedStatusList, ['SERVING', 'NOT_SERVING']);
assert.strictEqual(status.code, grpc.status.CANCELLED);
done();
});
});
it('Should update when a service that did not exist is added', done => {
const receivedStatusList: _grpc_health_v1_HealthCheckResponse_ServingStatus__Output[] = [];
const call = healthClient.watch({service: 'transient'});
call.on('data', (response: HealthCheckResponse__Output) => {
switch (receivedStatusList.length) {
case 0:
assert.strictEqual(response.status, 'SERVICE_UNKNOWN');
healthImpl.setStatus('transient', 'SERVING');
break;
case 1:
assert.strictEqual(response.status, 'SERVING');
call.cancel();
break;
default:
assert.fail(`Unexpected third status update ${response.status}`);
}
receivedStatusList.push(response.status);
});
call.on('error', () => {});
call.on('status', status => {
assert.deepStrictEqual(receivedStatusList, ['SERVICE_UNKNOWN', 'SERVING']);
assert.strictEqual(status.code, grpc.status.CANCELLED);
done();
});
})
});
});

View File

@ -0,0 +1,29 @@
{
"compilerOptions": {
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"declaration": true,
"forceConsistentCasingInFileNames": true,
"noEmitOnError": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"pretty": true,
"sourceMap": true,
"strict": true,
"lib": ["es2017"],
"outDir": "build",
"target": "es2017",
"module": "commonjs",
"resolveJsonModule": true,
"incremental": true,
"types": ["mocha"],
"noUnusedLocals": true
},
"include": [
"src/**/*.ts",
"test/**/*.ts"
],
"exclude": [
"node_modules"
]
}

View File

@ -1,6 +1,6 @@
# @grpc/grpc-js xDS plugin
This package provides support for the `xds://` URL scheme to the `@grpc/grpc-js` library. The latest version of this package is compatible with `@grpc/grpc-js` version 1.9.x.
This package provides support for the `xds://` URL scheme to the `@grpc/grpc-js` library. The latest version of this package is compatible with `@grpc/grpc-js` version 1.13.x.
## Installation
@ -30,5 +30,10 @@ const client = new MyServiceClient('xds:///example.com:123');
- [Client Status Discovery Service](https://github.com/grpc/proposal/blob/master/A40-csds-support.md)
- [Outlier Detection](https://github.com/grpc/proposal/blob/master/A50-xds-outlier-detection.md)
- [xDS Retry Support](https://github.com/grpc/proposal/blob/master/A44-xds-retry.md)
- [xDS Aggregate and Logical DNS Clusters](https://github.com/grpc/proposal/blob/master/A37-xds-aggregate-and-logical-dns-clusters.md)'
- [xDS Aggregate and Logical DNS Clusters](https://github.com/grpc/proposal/blob/master/A37-xds-aggregate-and-logical-dns-clusters.md)
- [xDS Federation](https://github.com/grpc/proposal/blob/master/A47-xds-federation.md) (Currently experimental, enabled by environment variable `GRPC_EXPERIMENTAL_XDS_FEDERATION`)
- [xDS Custom Load Balancer Configuration](https://github.com/grpc/proposal/blob/master/A52-xds-custom-lb-policies.md) (Custom load balancer registration not currently supported)
- [xDS Ring Hash LB Policy](https://github.com/grpc/proposal/blob/master/A42-xds-ring-hash-lb-policy.md)
- [`pick_first` via xDS](https://github.com/grpc/proposal/blob/master/A62-pick-first.md#pick_first-via-xds-1) (Currently experimental, enabled by environment variable `GRPC_EXPERIMENTAL_PICKFIRST_LB_CONFIG`)
- [xDS-Enabled Servers](https://github.com/grpc/proposal/blob/master/A36-xds-for-servers.md)
- [xDS-Based Security for gRPC Clients and Servers](https://github.com/grpc/proposal/blob/master/A29-xds-tls-security.md)

@ -1 +1 @@
Subproject commit 20b1b5fcee88a20a08b71051a961181839ec7268
Subproject commit f8b75d1efa92bbf534596a013d9ca5873f79dd30

View File

@ -21,6 +21,10 @@ import * as mocha from 'gulp-mocha';
import * as path from 'path';
import * as execa from 'execa';
import * as semver from 'semver';
import { ncp } from 'ncp';
import { promisify } from 'util';
const ncpP = promisify(ncp);
Error.stackTraceLimit = Infinity;
@ -60,14 +64,23 @@ const cleanAll = gulp.parallel(clean);
*/
const compile = checkTask(() => execNpmCommand('compile'));
const copyTestFixtures = checkTask(() =>
ncpP(`${jsCoreDir}/test/fixtures`, `${outDir}/test/fixtures`)
);
const runTests = checkTask(() => {
process.env.GRPC_EXPERIMENTAL_XDS_FEDERATION = 'true';
process.env.GRPC_EXPERIMENTAL_PICKFIRST_LB_CONFIG = 'true';
process.env.GRPC_XDS_EXPERIMENTAL_RBAC = 'true';
if (Number(process.versions.node.split('.')[0]) <= 14) {
process.env.GRPC_XDS_EXPERIMENTAL_ENABLE_RING_HASH = 'false';
}
return gulp.src(`${outDir}/test/**/*.js`)
.pipe(mocha({reporter: 'mocha-jenkins-reporter',
require: ['ts-node/register']}));
});
const test = gulp.series(install, runTests);
const test = gulp.series(install, copyTestFixtures, runTests);
export {
install,

View File

@ -5,7 +5,7 @@
* Metadata to be attached for the given type of RPCs.
*/
export interface _grpc_testing_ClientConfigureRequest_Metadata {
'type'?: (_grpc_testing_ClientConfigureRequest_RpcType | keyof typeof _grpc_testing_ClientConfigureRequest_RpcType);
'type'?: (_grpc_testing_ClientConfigureRequest_RpcType);
'key'?: (string);
'value'?: (string);
}
@ -14,7 +14,7 @@ export interface _grpc_testing_ClientConfigureRequest_Metadata {
* Metadata to be attached for the given type of RPCs.
*/
export interface _grpc_testing_ClientConfigureRequest_Metadata__Output {
'type': (keyof typeof _grpc_testing_ClientConfigureRequest_RpcType);
'type': (_grpc_testing_ClientConfigureRequest_RpcType__Output);
'key': (string);
'value': (string);
}
@ -24,10 +24,24 @@ export interface _grpc_testing_ClientConfigureRequest_Metadata__Output {
/**
* Type of RPCs to send.
*/
export enum _grpc_testing_ClientConfigureRequest_RpcType {
EMPTY_CALL = 0,
UNARY_CALL = 1,
}
export const _grpc_testing_ClientConfigureRequest_RpcType = {
EMPTY_CALL: 'EMPTY_CALL',
UNARY_CALL: 'UNARY_CALL',
} as const;
/**
* Type of RPCs to send.
*/
export type _grpc_testing_ClientConfigureRequest_RpcType =
| 'EMPTY_CALL'
| 0
| 'UNARY_CALL'
| 1
/**
* Type of RPCs to send.
*/
export type _grpc_testing_ClientConfigureRequest_RpcType__Output = typeof _grpc_testing_ClientConfigureRequest_RpcType[keyof typeof _grpc_testing_ClientConfigureRequest_RpcType]
/**
* Configurations for a test client.
@ -36,7 +50,7 @@ export interface ClientConfigureRequest {
/**
* The types of RPCs the client sends.
*/
'types'?: (_grpc_testing_ClientConfigureRequest_RpcType | keyof typeof _grpc_testing_ClientConfigureRequest_RpcType)[];
'types'?: (_grpc_testing_ClientConfigureRequest_RpcType)[];
/**
* The collection of custom metadata to be attached to RPCs sent by the client.
*/
@ -55,7 +69,7 @@ export interface ClientConfigureRequest__Output {
/**
* The types of RPCs the client sends.
*/
'types': (keyof typeof _grpc_testing_ClientConfigureRequest_RpcType)[];
'types': (_grpc_testing_ClientConfigureRequest_RpcType__Output)[];
/**
* The collection of custom metadata to be attached to RPCs sent by the client.
*/

View File

@ -8,17 +8,52 @@
* the address of this server from the gRPCLB server BalanceLoad RPC). Exactly
* how this detection is done is context and server dependent.
*/
export enum GrpclbRouteType {
export const GrpclbRouteType = {
/**
* Server didn't detect the route that a client took to reach it.
*/
GRPCLB_ROUTE_TYPE_UNKNOWN = 0,
GRPCLB_ROUTE_TYPE_UNKNOWN: 'GRPCLB_ROUTE_TYPE_UNKNOWN',
/**
* Indicates that a client reached a server via gRPCLB fallback.
*/
GRPCLB_ROUTE_TYPE_FALLBACK = 1,
GRPCLB_ROUTE_TYPE_FALLBACK: 'GRPCLB_ROUTE_TYPE_FALLBACK',
/**
* Indicates that a client reached a server as a gRPCLB-given backend.
*/
GRPCLB_ROUTE_TYPE_BACKEND = 2,
}
GRPCLB_ROUTE_TYPE_BACKEND: 'GRPCLB_ROUTE_TYPE_BACKEND',
} as const;
/**
* The type of route that a client took to reach a server w.r.t. gRPCLB.
* The server must fill in "fallback" if it detects that the RPC reached
* the server via the "gRPCLB fallback" path, and "backend" if it detects
* that the RPC reached the server via "gRPCLB backend" path (i.e. if it got
* the address of this server from the gRPCLB server BalanceLoad RPC). Exactly
* how this detection is done is context and server dependent.
*/
export type GrpclbRouteType =
/**
* Server didn't detect the route that a client took to reach it.
*/
| 'GRPCLB_ROUTE_TYPE_UNKNOWN'
| 0
/**
* Indicates that a client reached a server via gRPCLB fallback.
*/
| 'GRPCLB_ROUTE_TYPE_FALLBACK'
| 1
/**
* Indicates that a client reached a server as a gRPCLB-given backend.
*/
| 'GRPCLB_ROUTE_TYPE_BACKEND'
| 2
/**
* The type of route that a client took to reach a server w.r.t. gRPCLB.
* The server must fill in "fallback" if it detects that the RPC reached
* the server via the "gRPCLB fallback" path, and "backend" if it detects
* that the RPC reached the server via "gRPCLB backend" path (i.e. if it got
* the address of this server from the gRPCLB server BalanceLoad RPC). Exactly
* how this detection is done is context and server dependent.
*/
export type GrpclbRouteType__Output = typeof GrpclbRouteType[keyof typeof GrpclbRouteType]

View File

@ -32,16 +32,19 @@ export interface LoadBalancerAccumulatedStatsResponse {
/**
* The total number of RPCs have ever issued for each type.
* Deprecated: use stats_per_method.rpcs_started instead.
* @deprecated
*/
'num_rpcs_started_by_method'?: ({[key: string]: number});
/**
* The total number of RPCs have ever completed successfully for each type.
* Deprecated: use stats_per_method.result instead.
* @deprecated
*/
'num_rpcs_succeeded_by_method'?: ({[key: string]: number});
/**
* The total number of RPCs have ever failed for each type.
* Deprecated: use stats_per_method.result instead.
* @deprecated
*/
'num_rpcs_failed_by_method'?: ({[key: string]: number});
/**
@ -58,21 +61,24 @@ export interface LoadBalancerAccumulatedStatsResponse__Output {
/**
* The total number of RPCs have ever issued for each type.
* Deprecated: use stats_per_method.rpcs_started instead.
* @deprecated
*/
'num_rpcs_started_by_method': ({[key: string]: number});
/**
* The total number of RPCs have ever completed successfully for each type.
* Deprecated: use stats_per_method.result instead.
* @deprecated
*/
'num_rpcs_succeeded_by_method': ({[key: string]: number});
/**
* The total number of RPCs have ever failed for each type.
* Deprecated: use stats_per_method.result instead.
* @deprecated
*/
'num_rpcs_failed_by_method': ({[key: string]: number});
/**
* Per-method RPC statistics. The key is the RpcType in string form; e.g.
* 'EMPTY_CALL' or 'UNARY_CALL'
*/
'stats_per_method'?: ({[key: string]: _grpc_testing_LoadBalancerAccumulatedStatsResponse_MethodStats__Output});
'stats_per_method': ({[key: string]: _grpc_testing_LoadBalancerAccumulatedStatsResponse_MethodStats__Output});
}

View File

@ -36,5 +36,5 @@ export interface LoadBalancerStatsResponse__Output {
* The number of RPCs that failed to record a remote peer.
*/
'num_failures': (number);
'rpcs_by_method'?: ({[key: string]: _grpc_testing_LoadBalancerStatsResponse_RpcsByPeer__Output});
'rpcs_by_method': ({[key: string]: _grpc_testing_LoadBalancerStatsResponse_RpcsByPeer__Output});
}

View File

@ -1,6 +1,7 @@
// Original file: proto/grpc/testing/test.proto
import type * as grpc from '@grpc/grpc-js'
import type { MethodDefinition } from '@grpc/proto-loader'
import type { LoadBalancerAccumulatedStatsRequest as _grpc_testing_LoadBalancerAccumulatedStatsRequest, LoadBalancerAccumulatedStatsRequest__Output as _grpc_testing_LoadBalancerAccumulatedStatsRequest__Output } from '../../grpc/testing/LoadBalancerAccumulatedStatsRequest';
import type { LoadBalancerAccumulatedStatsResponse as _grpc_testing_LoadBalancerAccumulatedStatsResponse, LoadBalancerAccumulatedStatsResponse__Output as _grpc_testing_LoadBalancerAccumulatedStatsResponse__Output } from '../../grpc/testing/LoadBalancerAccumulatedStatsResponse';
import type { LoadBalancerStatsRequest as _grpc_testing_LoadBalancerStatsRequest, LoadBalancerStatsRequest__Output as _grpc_testing_LoadBalancerStatsRequest__Output } from '../../grpc/testing/LoadBalancerStatsRequest';
@ -13,32 +14,32 @@ export interface LoadBalancerStatsServiceClient extends grpc.Client {
/**
* Gets the accumulated stats for RPCs sent by a test client.
*/
GetClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerAccumulatedStatsResponse__Output) => void): grpc.ClientUnaryCall;
GetClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerAccumulatedStatsResponse__Output) => void): grpc.ClientUnaryCall;
GetClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerAccumulatedStatsResponse__Output) => void): grpc.ClientUnaryCall;
GetClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerAccumulatedStatsResponse__Output) => void): grpc.ClientUnaryCall;
GetClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_LoadBalancerAccumulatedStatsResponse__Output>): grpc.ClientUnaryCall;
GetClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_LoadBalancerAccumulatedStatsResponse__Output>): grpc.ClientUnaryCall;
GetClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_LoadBalancerAccumulatedStatsResponse__Output>): grpc.ClientUnaryCall;
GetClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, callback: grpc.requestCallback<_grpc_testing_LoadBalancerAccumulatedStatsResponse__Output>): grpc.ClientUnaryCall;
/**
* Gets the accumulated stats for RPCs sent by a test client.
*/
getClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerAccumulatedStatsResponse__Output) => void): grpc.ClientUnaryCall;
getClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerAccumulatedStatsResponse__Output) => void): grpc.ClientUnaryCall;
getClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerAccumulatedStatsResponse__Output) => void): grpc.ClientUnaryCall;
getClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerAccumulatedStatsResponse__Output) => void): grpc.ClientUnaryCall;
getClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_LoadBalancerAccumulatedStatsResponse__Output>): grpc.ClientUnaryCall;
getClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_LoadBalancerAccumulatedStatsResponse__Output>): grpc.ClientUnaryCall;
getClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_LoadBalancerAccumulatedStatsResponse__Output>): grpc.ClientUnaryCall;
getClientAccumulatedStats(argument: _grpc_testing_LoadBalancerAccumulatedStatsRequest, callback: grpc.requestCallback<_grpc_testing_LoadBalancerAccumulatedStatsResponse__Output>): grpc.ClientUnaryCall;
/**
* Gets the backend distribution for RPCs sent by a test client.
*/
GetClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerStatsResponse__Output) => void): grpc.ClientUnaryCall;
GetClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerStatsResponse__Output) => void): grpc.ClientUnaryCall;
GetClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerStatsResponse__Output) => void): grpc.ClientUnaryCall;
GetClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerStatsResponse__Output) => void): grpc.ClientUnaryCall;
GetClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_LoadBalancerStatsResponse__Output>): grpc.ClientUnaryCall;
GetClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_LoadBalancerStatsResponse__Output>): grpc.ClientUnaryCall;
GetClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_LoadBalancerStatsResponse__Output>): grpc.ClientUnaryCall;
GetClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, callback: grpc.requestCallback<_grpc_testing_LoadBalancerStatsResponse__Output>): grpc.ClientUnaryCall;
/**
* Gets the backend distribution for RPCs sent by a test client.
*/
getClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerStatsResponse__Output) => void): grpc.ClientUnaryCall;
getClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerStatsResponse__Output) => void): grpc.ClientUnaryCall;
getClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerStatsResponse__Output) => void): grpc.ClientUnaryCall;
getClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, callback: (error?: grpc.ServiceError, result?: _grpc_testing_LoadBalancerStatsResponse__Output) => void): grpc.ClientUnaryCall;
getClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_LoadBalancerStatsResponse__Output>): grpc.ClientUnaryCall;
getClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_LoadBalancerStatsResponse__Output>): grpc.ClientUnaryCall;
getClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_LoadBalancerStatsResponse__Output>): grpc.ClientUnaryCall;
getClientStats(argument: _grpc_testing_LoadBalancerStatsRequest, callback: grpc.requestCallback<_grpc_testing_LoadBalancerStatsResponse__Output>): grpc.ClientUnaryCall;
}
@ -57,3 +58,8 @@ export interface LoadBalancerStatsServiceHandlers extends grpc.UntypedServiceImp
GetClientStats: grpc.handleUnaryCall<_grpc_testing_LoadBalancerStatsRequest__Output, _grpc_testing_LoadBalancerStatsResponse>;
}
export interface LoadBalancerStatsServiceDefinition extends grpc.ServiceDefinition {
GetClientAccumulatedStats: MethodDefinition<_grpc_testing_LoadBalancerAccumulatedStatsRequest, _grpc_testing_LoadBalancerAccumulatedStatsResponse, _grpc_testing_LoadBalancerAccumulatedStatsRequest__Output, _grpc_testing_LoadBalancerAccumulatedStatsResponse__Output>
GetClientStats: MethodDefinition<_grpc_testing_LoadBalancerStatsRequest, _grpc_testing_LoadBalancerStatsResponse, _grpc_testing_LoadBalancerStatsRequest__Output, _grpc_testing_LoadBalancerStatsResponse__Output>
}

View File

@ -1,6 +1,6 @@
// Original file: proto/grpc/testing/messages.proto
import type { PayloadType as _grpc_testing_PayloadType } from '../../grpc/testing/PayloadType';
import type { PayloadType as _grpc_testing_PayloadType, PayloadType__Output as _grpc_testing_PayloadType__Output } from '../../grpc/testing/PayloadType';
/**
* A block of data, to simply increase gRPC message size.
@ -9,7 +9,7 @@ export interface Payload {
/**
* The type of data in body.
*/
'type'?: (_grpc_testing_PayloadType | keyof typeof _grpc_testing_PayloadType);
'type'?: (_grpc_testing_PayloadType);
/**
* Primary contents of payload.
*/
@ -23,7 +23,7 @@ export interface Payload__Output {
/**
* The type of data in body.
*/
'type': (keyof typeof _grpc_testing_PayloadType);
'type': (_grpc_testing_PayloadType__Output);
/**
* Primary contents of payload.
*/

View File

@ -3,9 +3,24 @@
/**
* The type of payload that should be returned.
*/
export enum PayloadType {
export const PayloadType = {
/**
* Compressable text format.
*/
COMPRESSABLE = 0,
}
COMPRESSABLE: 'COMPRESSABLE',
} as const;
/**
* The type of payload that should be returned.
*/
export type PayloadType =
/**
* Compressable text format.
*/
| 'COMPRESSABLE'
| 0
/**
* The type of payload that should be returned.
*/
export type PayloadType__Output = typeof PayloadType[keyof typeof PayloadType]

View File

@ -1,6 +1,7 @@
// Original file: proto/grpc/testing/test.proto
import type * as grpc from '@grpc/grpc-js'
import type { MethodDefinition } from '@grpc/proto-loader'
import type { Empty as _grpc_testing_Empty, Empty__Output as _grpc_testing_Empty__Output } from '../../grpc/testing/Empty';
import type { ReconnectInfo as _grpc_testing_ReconnectInfo, ReconnectInfo__Output as _grpc_testing_ReconnectInfo__Output } from '../../grpc/testing/ReconnectInfo';
import type { ReconnectParams as _grpc_testing_ReconnectParams, ReconnectParams__Output as _grpc_testing_ReconnectParams__Output } from '../../grpc/testing/ReconnectParams';
@ -9,23 +10,23 @@ import type { ReconnectParams as _grpc_testing_ReconnectParams, ReconnectParams_
* A service used to control reconnect server.
*/
export interface ReconnectServiceClient extends grpc.Client {
Start(argument: _grpc_testing_ReconnectParams, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
Start(argument: _grpc_testing_ReconnectParams, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
Start(argument: _grpc_testing_ReconnectParams, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
Start(argument: _grpc_testing_ReconnectParams, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
start(argument: _grpc_testing_ReconnectParams, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
start(argument: _grpc_testing_ReconnectParams, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
start(argument: _grpc_testing_ReconnectParams, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
start(argument: _grpc_testing_ReconnectParams, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
Start(argument: _grpc_testing_ReconnectParams, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
Start(argument: _grpc_testing_ReconnectParams, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
Start(argument: _grpc_testing_ReconnectParams, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
Start(argument: _grpc_testing_ReconnectParams, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
start(argument: _grpc_testing_ReconnectParams, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
start(argument: _grpc_testing_ReconnectParams, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
start(argument: _grpc_testing_ReconnectParams, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
start(argument: _grpc_testing_ReconnectParams, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
Stop(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ReconnectInfo__Output) => void): grpc.ClientUnaryCall;
Stop(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ReconnectInfo__Output) => void): grpc.ClientUnaryCall;
Stop(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ReconnectInfo__Output) => void): grpc.ClientUnaryCall;
Stop(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ReconnectInfo__Output) => void): grpc.ClientUnaryCall;
stop(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ReconnectInfo__Output) => void): grpc.ClientUnaryCall;
stop(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ReconnectInfo__Output) => void): grpc.ClientUnaryCall;
stop(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ReconnectInfo__Output) => void): grpc.ClientUnaryCall;
stop(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ReconnectInfo__Output) => void): grpc.ClientUnaryCall;
Stop(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_ReconnectInfo__Output>): grpc.ClientUnaryCall;
Stop(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_ReconnectInfo__Output>): grpc.ClientUnaryCall;
Stop(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_ReconnectInfo__Output>): grpc.ClientUnaryCall;
Stop(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_ReconnectInfo__Output>): grpc.ClientUnaryCall;
stop(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_ReconnectInfo__Output>): grpc.ClientUnaryCall;
stop(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_ReconnectInfo__Output>): grpc.ClientUnaryCall;
stop(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_ReconnectInfo__Output>): grpc.ClientUnaryCall;
stop(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_ReconnectInfo__Output>): grpc.ClientUnaryCall;
}
@ -38,3 +39,8 @@ export interface ReconnectServiceHandlers extends grpc.UntypedServiceImplementat
Stop: grpc.handleUnaryCall<_grpc_testing_Empty__Output, _grpc_testing_ReconnectInfo>;
}
export interface ReconnectServiceDefinition extends grpc.ServiceDefinition {
Start: MethodDefinition<_grpc_testing_ReconnectParams, _grpc_testing_Empty, _grpc_testing_ReconnectParams__Output, _grpc_testing_Empty__Output>
Stop: MethodDefinition<_grpc_testing_Empty, _grpc_testing_ReconnectInfo, _grpc_testing_Empty__Output, _grpc_testing_ReconnectInfo__Output>
}

View File

@ -21,7 +21,7 @@ export interface ResponseParameters {
* implement the full compression tests by introspecting the call to verify
* the response's compression status.
*/
'compressed'?: (_grpc_testing_BoolValue);
'compressed'?: (_grpc_testing_BoolValue | null);
}
/**
@ -43,5 +43,5 @@ export interface ResponseParameters__Output {
* implement the full compression tests by introspecting the call to verify
* the response's compression status.
*/
'compressed'?: (_grpc_testing_BoolValue__Output);
'compressed': (_grpc_testing_BoolValue__Output | null);
}

View File

@ -1,6 +1,6 @@
// Original file: proto/grpc/testing/messages.proto
import type { PayloadType as _grpc_testing_PayloadType } from '../../grpc/testing/PayloadType';
import type { PayloadType as _grpc_testing_PayloadType, PayloadType__Output as _grpc_testing_PayloadType__Output } from '../../grpc/testing/PayloadType';
import type { Payload as _grpc_testing_Payload, Payload__Output as _grpc_testing_Payload__Output } from '../../grpc/testing/Payload';
import type { BoolValue as _grpc_testing_BoolValue, BoolValue__Output as _grpc_testing_BoolValue__Output } from '../../grpc/testing/BoolValue';
import type { EchoStatus as _grpc_testing_EchoStatus, EchoStatus__Output as _grpc_testing_EchoStatus__Output } from '../../grpc/testing/EchoStatus';
@ -13,7 +13,7 @@ export interface SimpleRequest {
* Desired payload type in the response from the server.
* If response_type is RANDOM, server randomly chooses one from other formats.
*/
'response_type'?: (_grpc_testing_PayloadType | keyof typeof _grpc_testing_PayloadType);
'response_type'?: (_grpc_testing_PayloadType);
/**
* Desired payload size in the response from the server.
*/
@ -21,7 +21,7 @@ export interface SimpleRequest {
/**
* Optional input payload sent along with the request.
*/
'payload'?: (_grpc_testing_Payload);
'payload'?: (_grpc_testing_Payload | null);
/**
* Whether SimpleResponse should include username.
*/
@ -36,15 +36,15 @@ export interface SimpleRequest {
* implement the full compression tests by introspecting the call to verify
* the response's compression status.
*/
'response_compressed'?: (_grpc_testing_BoolValue);
'response_compressed'?: (_grpc_testing_BoolValue | null);
/**
* Whether server should return a given status
*/
'response_status'?: (_grpc_testing_EchoStatus);
'response_status'?: (_grpc_testing_EchoStatus | null);
/**
* Whether the server should expect this request to be compressed.
*/
'expect_compressed'?: (_grpc_testing_BoolValue);
'expect_compressed'?: (_grpc_testing_BoolValue | null);
/**
* Whether SimpleResponse should include server_id.
*/
@ -63,7 +63,7 @@ export interface SimpleRequest__Output {
* Desired payload type in the response from the server.
* If response_type is RANDOM, server randomly chooses one from other formats.
*/
'response_type': (keyof typeof _grpc_testing_PayloadType);
'response_type': (_grpc_testing_PayloadType__Output);
/**
* Desired payload size in the response from the server.
*/
@ -71,7 +71,7 @@ export interface SimpleRequest__Output {
/**
* Optional input payload sent along with the request.
*/
'payload'?: (_grpc_testing_Payload__Output);
'payload': (_grpc_testing_Payload__Output | null);
/**
* Whether SimpleResponse should include username.
*/
@ -86,15 +86,15 @@ export interface SimpleRequest__Output {
* implement the full compression tests by introspecting the call to verify
* the response's compression status.
*/
'response_compressed'?: (_grpc_testing_BoolValue__Output);
'response_compressed': (_grpc_testing_BoolValue__Output | null);
/**
* Whether server should return a given status
*/
'response_status'?: (_grpc_testing_EchoStatus__Output);
'response_status': (_grpc_testing_EchoStatus__Output | null);
/**
* Whether the server should expect this request to be compressed.
*/
'expect_compressed'?: (_grpc_testing_BoolValue__Output);
'expect_compressed': (_grpc_testing_BoolValue__Output | null);
/**
* Whether SimpleResponse should include server_id.
*/

View File

@ -1,7 +1,7 @@
// Original file: proto/grpc/testing/messages.proto
import type { Payload as _grpc_testing_Payload, Payload__Output as _grpc_testing_Payload__Output } from '../../grpc/testing/Payload';
import type { GrpclbRouteType as _grpc_testing_GrpclbRouteType } from '../../grpc/testing/GrpclbRouteType';
import type { GrpclbRouteType as _grpc_testing_GrpclbRouteType, GrpclbRouteType__Output as _grpc_testing_GrpclbRouteType__Output } from '../../grpc/testing/GrpclbRouteType';
/**
* Unary response, as configured by the request.
@ -10,7 +10,7 @@ export interface SimpleResponse {
/**
* Payload to increase message size.
*/
'payload'?: (_grpc_testing_Payload);
'payload'?: (_grpc_testing_Payload | null);
/**
* The user the request came from, for verifying authentication was
* successful when the client expected it.
@ -28,7 +28,7 @@ export interface SimpleResponse {
/**
* gRPCLB Path.
*/
'grpclb_route_type'?: (_grpc_testing_GrpclbRouteType | keyof typeof _grpc_testing_GrpclbRouteType);
'grpclb_route_type'?: (_grpc_testing_GrpclbRouteType);
/**
* Server hostname.
*/
@ -42,7 +42,7 @@ export interface SimpleResponse__Output {
/**
* Payload to increase message size.
*/
'payload'?: (_grpc_testing_Payload__Output);
'payload': (_grpc_testing_Payload__Output | null);
/**
* The user the request came from, for verifying authentication was
* successful when the client expected it.
@ -60,7 +60,7 @@ export interface SimpleResponse__Output {
/**
* gRPCLB Path.
*/
'grpclb_route_type': (keyof typeof _grpc_testing_GrpclbRouteType);
'grpclb_route_type': (_grpc_testing_GrpclbRouteType__Output);
/**
* Server hostname.
*/

View File

@ -10,14 +10,14 @@ export interface StreamingInputCallRequest {
/**
* Optional input payload sent along with the request.
*/
'payload'?: (_grpc_testing_Payload);
'payload'?: (_grpc_testing_Payload | null);
/**
* Whether the server should expect this request to be compressed. This field
* is "nullable" in order to interoperate seamlessly with servers not able to
* implement the full compression tests by introspecting the call to verify
* the request's compression status.
*/
'expect_compressed'?: (_grpc_testing_BoolValue);
'expect_compressed'?: (_grpc_testing_BoolValue | null);
}
/**
@ -27,12 +27,12 @@ export interface StreamingInputCallRequest__Output {
/**
* Optional input payload sent along with the request.
*/
'payload'?: (_grpc_testing_Payload__Output);
'payload': (_grpc_testing_Payload__Output | null);
/**
* Whether the server should expect this request to be compressed. This field
* is "nullable" in order to interoperate seamlessly with servers not able to
* implement the full compression tests by introspecting the call to verify
* the request's compression status.
*/
'expect_compressed'?: (_grpc_testing_BoolValue__Output);
'expect_compressed': (_grpc_testing_BoolValue__Output | null);
}

View File

@ -1,6 +1,6 @@
// Original file: proto/grpc/testing/messages.proto
import type { PayloadType as _grpc_testing_PayloadType } from '../../grpc/testing/PayloadType';
import type { PayloadType as _grpc_testing_PayloadType, PayloadType__Output as _grpc_testing_PayloadType__Output } from '../../grpc/testing/PayloadType';
import type { ResponseParameters as _grpc_testing_ResponseParameters, ResponseParameters__Output as _grpc_testing_ResponseParameters__Output } from '../../grpc/testing/ResponseParameters';
import type { Payload as _grpc_testing_Payload, Payload__Output as _grpc_testing_Payload__Output } from '../../grpc/testing/Payload';
import type { EchoStatus as _grpc_testing_EchoStatus, EchoStatus__Output as _grpc_testing_EchoStatus__Output } from '../../grpc/testing/EchoStatus';
@ -15,7 +15,7 @@ export interface StreamingOutputCallRequest {
* might be of different types. This is to simulate a mixed type of payload
* stream.
*/
'response_type'?: (_grpc_testing_PayloadType | keyof typeof _grpc_testing_PayloadType);
'response_type'?: (_grpc_testing_PayloadType);
/**
* Configuration for each expected response message.
*/
@ -23,11 +23,11 @@ export interface StreamingOutputCallRequest {
/**
* Optional input payload sent along with the request.
*/
'payload'?: (_grpc_testing_Payload);
'payload'?: (_grpc_testing_Payload | null);
/**
* Whether server should return a given status
*/
'response_status'?: (_grpc_testing_EchoStatus);
'response_status'?: (_grpc_testing_EchoStatus | null);
}
/**
@ -40,7 +40,7 @@ export interface StreamingOutputCallRequest__Output {
* might be of different types. This is to simulate a mixed type of payload
* stream.
*/
'response_type': (keyof typeof _grpc_testing_PayloadType);
'response_type': (_grpc_testing_PayloadType__Output);
/**
* Configuration for each expected response message.
*/
@ -48,9 +48,9 @@ export interface StreamingOutputCallRequest__Output {
/**
* Optional input payload sent along with the request.
*/
'payload'?: (_grpc_testing_Payload__Output);
'payload': (_grpc_testing_Payload__Output | null);
/**
* Whether server should return a given status
*/
'response_status'?: (_grpc_testing_EchoStatus__Output);
'response_status': (_grpc_testing_EchoStatus__Output | null);
}

View File

@ -9,7 +9,7 @@ export interface StreamingOutputCallResponse {
/**
* Payload to increase response size.
*/
'payload'?: (_grpc_testing_Payload);
'payload'?: (_grpc_testing_Payload | null);
}
/**
@ -19,5 +19,5 @@ export interface StreamingOutputCallResponse__Output {
/**
* Payload to increase response size.
*/
'payload'?: (_grpc_testing_Payload__Output);
'payload': (_grpc_testing_Payload__Output | null);
}

View File

@ -1,6 +1,7 @@
// Original file: proto/grpc/testing/test.proto
import type * as grpc from '@grpc/grpc-js'
import type { MethodDefinition } from '@grpc/proto-loader'
import type { Empty as _grpc_testing_Empty, Empty__Output as _grpc_testing_Empty__Output } from '../../grpc/testing/Empty';
import type { SimpleRequest as _grpc_testing_SimpleRequest, SimpleRequest__Output as _grpc_testing_SimpleRequest__Output } from '../../grpc/testing/SimpleRequest';
import type { SimpleResponse as _grpc_testing_SimpleResponse, SimpleResponse__Output as _grpc_testing_SimpleResponse__Output } from '../../grpc/testing/SimpleResponse';
@ -19,34 +20,34 @@ export interface TestServiceClient extends grpc.Client {
* headers set such that a caching HTTP proxy (such as GFE) can
* satisfy subsequent requests.
*/
CacheableUnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall;
CacheableUnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall;
CacheableUnaryCall(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall;
CacheableUnaryCall(argument: _grpc_testing_SimpleRequest, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall;
CacheableUnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall;
CacheableUnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall;
CacheableUnaryCall(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall;
CacheableUnaryCall(argument: _grpc_testing_SimpleRequest, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall;
/**
* One request followed by one response. Response has cache control
* headers set such that a caching HTTP proxy (such as GFE) can
* satisfy subsequent requests.
*/
cacheableUnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall;
cacheableUnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall;
cacheableUnaryCall(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall;
cacheableUnaryCall(argument: _grpc_testing_SimpleRequest, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall;
cacheableUnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall;
cacheableUnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall;
cacheableUnaryCall(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall;
cacheableUnaryCall(argument: _grpc_testing_SimpleRequest, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall;
/**
* One empty request followed by one empty response.
*/
EmptyCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
EmptyCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
EmptyCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
EmptyCall(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
EmptyCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
EmptyCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
EmptyCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
EmptyCall(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
/**
* One empty request followed by one empty response.
*/
emptyCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
emptyCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
emptyCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
emptyCall(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
emptyCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
emptyCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
emptyCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
emptyCall(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
/**
* A sequence of requests with each request served by the server immediately.
@ -84,18 +85,18 @@ export interface TestServiceClient extends grpc.Client {
* A sequence of requests followed by one response (streamed upload).
* The server returns the aggregated size of client payload as the result.
*/
StreamingInputCall(metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_StreamingInputCallResponse__Output) => void): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>;
StreamingInputCall(metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_StreamingInputCallResponse__Output) => void): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>;
StreamingInputCall(options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_StreamingInputCallResponse__Output) => void): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>;
StreamingInputCall(callback: (error?: grpc.ServiceError, result?: _grpc_testing_StreamingInputCallResponse__Output) => void): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>;
StreamingInputCall(metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_StreamingInputCallResponse__Output>): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>;
StreamingInputCall(metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_StreamingInputCallResponse__Output>): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>;
StreamingInputCall(options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_StreamingInputCallResponse__Output>): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>;
StreamingInputCall(callback: grpc.requestCallback<_grpc_testing_StreamingInputCallResponse__Output>): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>;
/**
* A sequence of requests followed by one response (streamed upload).
* The server returns the aggregated size of client payload as the result.
*/
streamingInputCall(metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_StreamingInputCallResponse__Output) => void): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>;
streamingInputCall(metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_StreamingInputCallResponse__Output) => void): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>;
streamingInputCall(options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_StreamingInputCallResponse__Output) => void): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>;
streamingInputCall(callback: (error?: grpc.ServiceError, result?: _grpc_testing_StreamingInputCallResponse__Output) => void): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>;
streamingInputCall(metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_StreamingInputCallResponse__Output>): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>;
streamingInputCall(metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_StreamingInputCallResponse__Output>): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>;
streamingInputCall(options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_StreamingInputCallResponse__Output>): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>;
streamingInputCall(callback: grpc.requestCallback<_grpc_testing_StreamingInputCallResponse__Output>): grpc.ClientWritableStream<_grpc_testing_StreamingInputCallRequest>;
/**
* One request followed by a sequence of responses (streamed download).
@ -113,34 +114,34 @@ export interface TestServiceClient extends grpc.Client {
/**
* One request followed by one response.
*/
UnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall;
UnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall;
UnaryCall(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall;
UnaryCall(argument: _grpc_testing_SimpleRequest, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall;
UnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall;
UnaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall;
UnaryCall(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall;
UnaryCall(argument: _grpc_testing_SimpleRequest, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall;
/**
* One request followed by one response.
*/
unaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall;
unaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall;
unaryCall(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall;
unaryCall(argument: _grpc_testing_SimpleRequest, callback: (error?: grpc.ServiceError, result?: _grpc_testing_SimpleResponse__Output) => void): grpc.ClientUnaryCall;
unaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall;
unaryCall(argument: _grpc_testing_SimpleRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall;
unaryCall(argument: _grpc_testing_SimpleRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall;
unaryCall(argument: _grpc_testing_SimpleRequest, callback: grpc.requestCallback<_grpc_testing_SimpleResponse__Output>): grpc.ClientUnaryCall;
/**
* The test server will not implement this method. It will be used
* to test the behavior when clients call unimplemented methods.
*/
UnimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
UnimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
UnimplementedCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
UnimplementedCall(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
UnimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
UnimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
UnimplementedCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
UnimplementedCall(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
/**
* The test server will not implement this method. It will be used
* to test the behavior when clients call unimplemented methods.
*/
unimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
unimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
unimplementedCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
unimplementedCall(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
unimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
unimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
unimplementedCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
unimplementedCall(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
}
@ -200,3 +201,14 @@ export interface TestServiceHandlers extends grpc.UntypedServiceImplementation {
UnimplementedCall: grpc.handleUnaryCall<_grpc_testing_Empty__Output, _grpc_testing_Empty>;
}
export interface TestServiceDefinition extends grpc.ServiceDefinition {
CacheableUnaryCall: MethodDefinition<_grpc_testing_SimpleRequest, _grpc_testing_SimpleResponse, _grpc_testing_SimpleRequest__Output, _grpc_testing_SimpleResponse__Output>
EmptyCall: MethodDefinition<_grpc_testing_Empty, _grpc_testing_Empty, _grpc_testing_Empty__Output, _grpc_testing_Empty__Output>
FullDuplexCall: MethodDefinition<_grpc_testing_StreamingOutputCallRequest, _grpc_testing_StreamingOutputCallResponse, _grpc_testing_StreamingOutputCallRequest__Output, _grpc_testing_StreamingOutputCallResponse__Output>
HalfDuplexCall: MethodDefinition<_grpc_testing_StreamingOutputCallRequest, _grpc_testing_StreamingOutputCallResponse, _grpc_testing_StreamingOutputCallRequest__Output, _grpc_testing_StreamingOutputCallResponse__Output>
StreamingInputCall: MethodDefinition<_grpc_testing_StreamingInputCallRequest, _grpc_testing_StreamingInputCallResponse, _grpc_testing_StreamingInputCallRequest__Output, _grpc_testing_StreamingInputCallResponse__Output>
StreamingOutputCall: MethodDefinition<_grpc_testing_StreamingOutputCallRequest, _grpc_testing_StreamingOutputCallResponse, _grpc_testing_StreamingOutputCallRequest__Output, _grpc_testing_StreamingOutputCallResponse__Output>
UnaryCall: MethodDefinition<_grpc_testing_SimpleRequest, _grpc_testing_SimpleResponse, _grpc_testing_SimpleRequest__Output, _grpc_testing_SimpleResponse__Output>
UnimplementedCall: MethodDefinition<_grpc_testing_Empty, _grpc_testing_Empty, _grpc_testing_Empty__Output, _grpc_testing_Empty__Output>
}

View File

@ -1,6 +1,7 @@
// Original file: proto/grpc/testing/test.proto
import type * as grpc from '@grpc/grpc-js'
import type { MethodDefinition } from '@grpc/proto-loader'
import type { Empty as _grpc_testing_Empty, Empty__Output as _grpc_testing_Empty__Output } from '../../grpc/testing/Empty';
/**
@ -11,17 +12,17 @@ export interface UnimplementedServiceClient extends grpc.Client {
/**
* A call that no server should implement
*/
UnimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
UnimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
UnimplementedCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
UnimplementedCall(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
UnimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
UnimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
UnimplementedCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
UnimplementedCall(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
/**
* A call that no server should implement
*/
unimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
unimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
unimplementedCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
unimplementedCall(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
unimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
unimplementedCall(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
unimplementedCall(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
unimplementedCall(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
}
@ -36,3 +37,7 @@ export interface UnimplementedServiceHandlers extends grpc.UntypedServiceImpleme
UnimplementedCall: grpc.handleUnaryCall<_grpc_testing_Empty__Output, _grpc_testing_Empty>;
}
export interface UnimplementedServiceDefinition extends grpc.ServiceDefinition {
UnimplementedCall: MethodDefinition<_grpc_testing_Empty, _grpc_testing_Empty, _grpc_testing_Empty__Output, _grpc_testing_Empty__Output>
}

View File

@ -1,6 +1,7 @@
// Original file: proto/grpc/testing/test.proto
import type * as grpc from '@grpc/grpc-js'
import type { MethodDefinition } from '@grpc/proto-loader'
import type { ClientConfigureRequest as _grpc_testing_ClientConfigureRequest, ClientConfigureRequest__Output as _grpc_testing_ClientConfigureRequest__Output } from '../../grpc/testing/ClientConfigureRequest';
import type { ClientConfigureResponse as _grpc_testing_ClientConfigureResponse, ClientConfigureResponse__Output as _grpc_testing_ClientConfigureResponse__Output } from '../../grpc/testing/ClientConfigureResponse';
@ -11,17 +12,17 @@ export interface XdsUpdateClientConfigureServiceClient extends grpc.Client {
/**
* Update the tes client's configuration.
*/
Configure(argument: _grpc_testing_ClientConfigureRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ClientConfigureResponse__Output) => void): grpc.ClientUnaryCall;
Configure(argument: _grpc_testing_ClientConfigureRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ClientConfigureResponse__Output) => void): grpc.ClientUnaryCall;
Configure(argument: _grpc_testing_ClientConfigureRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ClientConfigureResponse__Output) => void): grpc.ClientUnaryCall;
Configure(argument: _grpc_testing_ClientConfigureRequest, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ClientConfigureResponse__Output) => void): grpc.ClientUnaryCall;
Configure(argument: _grpc_testing_ClientConfigureRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_ClientConfigureResponse__Output>): grpc.ClientUnaryCall;
Configure(argument: _grpc_testing_ClientConfigureRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_ClientConfigureResponse__Output>): grpc.ClientUnaryCall;
Configure(argument: _grpc_testing_ClientConfigureRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_ClientConfigureResponse__Output>): grpc.ClientUnaryCall;
Configure(argument: _grpc_testing_ClientConfigureRequest, callback: grpc.requestCallback<_grpc_testing_ClientConfigureResponse__Output>): grpc.ClientUnaryCall;
/**
* Update the tes client's configuration.
*/
configure(argument: _grpc_testing_ClientConfigureRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ClientConfigureResponse__Output) => void): grpc.ClientUnaryCall;
configure(argument: _grpc_testing_ClientConfigureRequest, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ClientConfigureResponse__Output) => void): grpc.ClientUnaryCall;
configure(argument: _grpc_testing_ClientConfigureRequest, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ClientConfigureResponse__Output) => void): grpc.ClientUnaryCall;
configure(argument: _grpc_testing_ClientConfigureRequest, callback: (error?: grpc.ServiceError, result?: _grpc_testing_ClientConfigureResponse__Output) => void): grpc.ClientUnaryCall;
configure(argument: _grpc_testing_ClientConfigureRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_ClientConfigureResponse__Output>): grpc.ClientUnaryCall;
configure(argument: _grpc_testing_ClientConfigureRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_ClientConfigureResponse__Output>): grpc.ClientUnaryCall;
configure(argument: _grpc_testing_ClientConfigureRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_ClientConfigureResponse__Output>): grpc.ClientUnaryCall;
configure(argument: _grpc_testing_ClientConfigureRequest, callback: grpc.requestCallback<_grpc_testing_ClientConfigureResponse__Output>): grpc.ClientUnaryCall;
}
@ -35,3 +36,7 @@ export interface XdsUpdateClientConfigureServiceHandlers extends grpc.UntypedSer
Configure: grpc.handleUnaryCall<_grpc_testing_ClientConfigureRequest__Output, _grpc_testing_ClientConfigureResponse>;
}
export interface XdsUpdateClientConfigureServiceDefinition extends grpc.ServiceDefinition {
Configure: MethodDefinition<_grpc_testing_ClientConfigureRequest, _grpc_testing_ClientConfigureResponse, _grpc_testing_ClientConfigureRequest__Output, _grpc_testing_ClientConfigureResponse__Output>
}

View File

@ -1,29 +1,30 @@
// Original file: proto/grpc/testing/test.proto
import type * as grpc from '@grpc/grpc-js'
import type { MethodDefinition } from '@grpc/proto-loader'
import type { Empty as _grpc_testing_Empty, Empty__Output as _grpc_testing_Empty__Output } from '../../grpc/testing/Empty';
/**
* A service to remotely control health status of an xDS test server.
*/
export interface XdsUpdateHealthServiceClient extends grpc.Client {
SetNotServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
SetNotServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
SetNotServing(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
SetNotServing(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
setNotServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
setNotServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
setNotServing(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
setNotServing(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
SetNotServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
SetNotServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
SetNotServing(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
SetNotServing(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
setNotServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
setNotServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
setNotServing(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
setNotServing(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
SetServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
SetServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
SetServing(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
SetServing(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
setServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
setServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
setServing(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
setServing(argument: _grpc_testing_Empty, callback: (error?: grpc.ServiceError, result?: _grpc_testing_Empty__Output) => void): grpc.ClientUnaryCall;
SetServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
SetServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
SetServing(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
SetServing(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
setServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
setServing(argument: _grpc_testing_Empty, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
setServing(argument: _grpc_testing_Empty, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
setServing(argument: _grpc_testing_Empty, callback: grpc.requestCallback<_grpc_testing_Empty__Output>): grpc.ClientUnaryCall;
}
@ -36,3 +37,8 @@ export interface XdsUpdateHealthServiceHandlers extends grpc.UntypedServiceImple
SetServing: grpc.handleUnaryCall<_grpc_testing_Empty__Output, _grpc_testing_Empty>;
}
export interface XdsUpdateHealthServiceDefinition extends grpc.ServiceDefinition {
SetNotServing: MethodDefinition<_grpc_testing_Empty, _grpc_testing_Empty, _grpc_testing_Empty__Output, _grpc_testing_Empty__Output>
SetServing: MethodDefinition<_grpc_testing_Empty, _grpc_testing_Empty, _grpc_testing_Empty__Output, _grpc_testing_Empty__Output>
}

View File

@ -1,12 +1,12 @@
import type * as grpc from '@grpc/grpc-js';
import type { ServiceDefinition, EnumTypeDefinition, MessageTypeDefinition } from '@grpc/proto-loader';
import type { EnumTypeDefinition, MessageTypeDefinition } from '@grpc/proto-loader';
import type { LoadBalancerStatsServiceClient as _grpc_testing_LoadBalancerStatsServiceClient } from './grpc/testing/LoadBalancerStatsService';
import type { ReconnectServiceClient as _grpc_testing_ReconnectServiceClient } from './grpc/testing/ReconnectService';
import type { TestServiceClient as _grpc_testing_TestServiceClient } from './grpc/testing/TestService';
import type { UnimplementedServiceClient as _grpc_testing_UnimplementedServiceClient } from './grpc/testing/UnimplementedService';
import type { XdsUpdateClientConfigureServiceClient as _grpc_testing_XdsUpdateClientConfigureServiceClient } from './grpc/testing/XdsUpdateClientConfigureService';
import type { XdsUpdateHealthServiceClient as _grpc_testing_XdsUpdateHealthServiceClient } from './grpc/testing/XdsUpdateHealthService';
import type { LoadBalancerStatsServiceClient as _grpc_testing_LoadBalancerStatsServiceClient, LoadBalancerStatsServiceDefinition as _grpc_testing_LoadBalancerStatsServiceDefinition } from './grpc/testing/LoadBalancerStatsService';
import type { ReconnectServiceClient as _grpc_testing_ReconnectServiceClient, ReconnectServiceDefinition as _grpc_testing_ReconnectServiceDefinition } from './grpc/testing/ReconnectService';
import type { TestServiceClient as _grpc_testing_TestServiceClient, TestServiceDefinition as _grpc_testing_TestServiceDefinition } from './grpc/testing/TestService';
import type { UnimplementedServiceClient as _grpc_testing_UnimplementedServiceClient, UnimplementedServiceDefinition as _grpc_testing_UnimplementedServiceDefinition } from './grpc/testing/UnimplementedService';
import type { XdsUpdateClientConfigureServiceClient as _grpc_testing_XdsUpdateClientConfigureServiceClient, XdsUpdateClientConfigureServiceDefinition as _grpc_testing_XdsUpdateClientConfigureServiceDefinition } from './grpc/testing/XdsUpdateClientConfigureService';
import type { XdsUpdateHealthServiceClient as _grpc_testing_XdsUpdateHealthServiceClient, XdsUpdateHealthServiceDefinition as _grpc_testing_XdsUpdateHealthServiceDefinition } from './grpc/testing/XdsUpdateHealthService';
type SubtypeConstructor<Constructor extends new (...args: any) => any, Subtype> = {
new(...args: ConstructorParameters<Constructor>): Subtype;
@ -28,7 +28,7 @@ export interface ProtoGrpcType {
/**
* A service used to obtain stats for verifying LB behavior.
*/
LoadBalancerStatsService: SubtypeConstructor<typeof grpc.Client, _grpc_testing_LoadBalancerStatsServiceClient> & { service: ServiceDefinition }
LoadBalancerStatsService: SubtypeConstructor<typeof grpc.Client, _grpc_testing_LoadBalancerStatsServiceClient> & { service: _grpc_testing_LoadBalancerStatsServiceDefinition }
Payload: MessageTypeDefinition
PayloadType: EnumTypeDefinition
ReconnectInfo: MessageTypeDefinition
@ -36,7 +36,7 @@ export interface ProtoGrpcType {
/**
* A service used to control reconnect server.
*/
ReconnectService: SubtypeConstructor<typeof grpc.Client, _grpc_testing_ReconnectServiceClient> & { service: ServiceDefinition }
ReconnectService: SubtypeConstructor<typeof grpc.Client, _grpc_testing_ReconnectServiceClient> & { service: _grpc_testing_ReconnectServiceDefinition }
ResponseParameters: MessageTypeDefinition
SimpleRequest: MessageTypeDefinition
SimpleResponse: MessageTypeDefinition
@ -48,20 +48,20 @@ export interface ProtoGrpcType {
* A simple service to test the various types of RPCs and experiment with
* performance with various types of payload.
*/
TestService: SubtypeConstructor<typeof grpc.Client, _grpc_testing_TestServiceClient> & { service: ServiceDefinition }
TestService: SubtypeConstructor<typeof grpc.Client, _grpc_testing_TestServiceClient> & { service: _grpc_testing_TestServiceDefinition }
/**
* A simple service NOT implemented at servers so clients can test for
* that case.
*/
UnimplementedService: SubtypeConstructor<typeof grpc.Client, _grpc_testing_UnimplementedServiceClient> & { service: ServiceDefinition }
UnimplementedService: SubtypeConstructor<typeof grpc.Client, _grpc_testing_UnimplementedServiceClient> & { service: _grpc_testing_UnimplementedServiceDefinition }
/**
* A service to dynamically update the configuration of an xDS test client.
*/
XdsUpdateClientConfigureService: SubtypeConstructor<typeof grpc.Client, _grpc_testing_XdsUpdateClientConfigureServiceClient> & { service: ServiceDefinition }
XdsUpdateClientConfigureService: SubtypeConstructor<typeof grpc.Client, _grpc_testing_XdsUpdateClientConfigureServiceClient> & { service: _grpc_testing_XdsUpdateClientConfigureServiceDefinition }
/**
* A service to remotely control health status of an xDS test server.
*/
XdsUpdateHealthService: SubtypeConstructor<typeof grpc.Client, _grpc_testing_XdsUpdateHealthServiceClient> & { service: ServiceDefinition }
XdsUpdateHealthService: SubtypeConstructor<typeof grpc.Client, _grpc_testing_XdsUpdateHealthServiceClient> & { service: _grpc_testing_XdsUpdateHealthServiceDefinition }
}
}
}

View File

@ -14,7 +14,7 @@
# Dockerfile for building the xDS interop client. To build the image, run the
# following command from grpc-node directory:
# docker build -t <TAG> -f packages/grpc-js-xds/interop/Dockerfile .
# docker build -t <TAG> -f packages/grpc-js-xds/interop/test-client.Dockerfile .
FROM node:18-slim as build
@ -22,17 +22,27 @@ FROM node:18-slim as build
WORKDIR /node/src/grpc-node
COPY . .
WORKDIR /node/src/grpc-node/packages/proto-loader
RUN npm install
WORKDIR /node/src/grpc-node/packages/grpc-js
RUN npm install
WORKDIR /node/src/grpc-node/packages/grpc-health-check
RUN npm install
WORKDIR /node/src/grpc-node/packages/grpc-reflection
RUN npm install
WORKDIR /node/src/grpc-node/packages/grpc-js-xds
RUN npm install
FROM gcr.io/distroless/nodejs18-debian11:latest
WORKDIR /node/src/grpc-node
COPY --from=build /node/src/grpc-node/packages/proto-loader ./packages/proto-loader/
COPY --from=build /node/src/grpc-node/packages/grpc-health-check ./packages/grpc-health-check/
COPY --from=build /node/src/grpc-node/packages/grpc-reflection ./packages/grpc-reflection/
COPY --from=build /node/src/grpc-node/packages/grpc-js ./packages/grpc-js/
COPY --from=build /node/src/grpc-node/packages/grpc-js-xds ./packages/grpc-js-xds/
ENV GRPC_VERBOSITY="DEBUG"
ENV GRPC_TRACE=xds_client,xds_resolver,xds_cluster_manager,cds_balancer,xds_cluster_resolver,xds_cluster_impl,priority,weighted_target,round_robin,resolving_load_balancer,subchannel,keepalive,dns_resolver,fault_injection,http_filter,csds,outlier_detection,server,server_call
ENV GRPC_TRACE=xds_client,xds_resolver,xds_cluster_manager,cds_balancer,xds_cluster_resolver,xds_cluster_impl,priority,weighted_target,round_robin,resolving_load_balancer,subchannel,keepalive,dns_resolver,fault_injection,http_filter,csds,outlier_detection,server,server_call,ring_hash,transport,certificate_provider,xds_channel_credentials
ENV NODE_XDS_INTEROP_VERBOSITY=1
ENTRYPOINT [ "/nodejs/bin/node", "/node/src/grpc-node/packages/grpc-js-xds/build/interop/xds-interop-client" ]

View File

@ -0,0 +1,54 @@
# Copyright 2022 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Dockerfile for building the xDS interop client. To build the image, run the
# following command from grpc-node directory:
# docker build -t <TAG> -f packages/grpc-js-xds/interop/test-server.Dockerfile .
FROM node:18-slim as build
# Make a grpc-node directory and copy the repo into it.
WORKDIR /node/src/grpc-node
COPY . .
WORKDIR /node/src/grpc-node/packages/proto-loader
RUN npm install
WORKDIR /node/src/grpc-node/packages/grpc-js
RUN npm install
WORKDIR /node/src/grpc-node/packages/grpc-health-check
RUN npm install
WORKDIR /node/src/grpc-node/packages/grpc-reflection
RUN npm install
WORKDIR /node/src/grpc-node/packages/grpc-js-xds
RUN npm install
ENV TINI_VERSION v0.19.0
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
RUN chmod +x /tini
FROM gcr.io/distroless/nodejs18-debian11:latest
WORKDIR /node/src/grpc-node
COPY --from=build /node/src/grpc-node/packages/proto-loader ./packages/proto-loader/
COPY --from=build /node/src/grpc-node/packages/grpc-health-check ./packages/grpc-health-check/
COPY --from=build /node/src/grpc-node/packages/grpc-reflection ./packages/grpc-reflection/
COPY --from=build /node/src/grpc-node/packages/grpc-js ./packages/grpc-js/
COPY --from=build /node/src/grpc-node/packages/grpc-js-xds ./packages/grpc-js-xds/
ENV GRPC_VERBOSITY="DEBUG"
ENV GRPC_TRACE=xds_client,server,xds_server,http_filter,certificate_provider,rbac_filter
# tini serves as PID 1 and enables the server to properly respond to signals.
COPY --from=build /tini /tini
ENTRYPOINT [ "/tini", "-g", "-vv", "--", "/nodejs/bin/node", "/node/src/grpc-node/packages/grpc-js-xds/build/interop/xds-interop-server" ]

View File

@ -30,8 +30,100 @@ import { XdsUpdateClientConfigureServiceHandlers } from './generated/grpc/testin
import { Empty__Output } from './generated/grpc/testing/Empty';
import { LoadBalancerAccumulatedStatsResponse } from './generated/grpc/testing/LoadBalancerAccumulatedStatsResponse';
import TypedLoadBalancingConfig = grpc.experimental.TypedLoadBalancingConfig;
import LoadBalancer = grpc.experimental.LoadBalancer;
import ChannelControlHelper = grpc.experimental.ChannelControlHelper;
import ChildLoadBalancerHandler = grpc.experimental.ChildLoadBalancerHandler;
import Endpoint = grpc.experimental.Endpoint;
import Picker = grpc.experimental.Picker;
import PickArgs = grpc.experimental.PickArgs;
import PickResult = grpc.experimental.PickResult;
import PickResultType = grpc.experimental.PickResultType;
import createChildChannelControlHelper = grpc.experimental.createChildChannelControlHelper;
import parseLoadBalancingConfig = grpc.experimental.parseLoadBalancingConfig;
import StatusOr = grpc.experimental.StatusOr;
import { ChannelOptions } from '@grpc/grpc-js';
grpc_xds.register();
const LB_POLICY_NAME = 'test.RpcBehaviorLoadBalancer';
class RpcBehaviorLoadBalancingConfig implements TypedLoadBalancingConfig {
constructor(private rpcBehavior: string) {}
getLoadBalancerName(): string {
return LB_POLICY_NAME;
}
toJsonObject(): object {
return {
[LB_POLICY_NAME]: {
'rpcBehavior': this.rpcBehavior
}
};
}
getRpcBehavior() {
return this.rpcBehavior;
}
static createFromJson(obj: any): RpcBehaviorLoadBalancingConfig {
if (!('rpcBehavior' in obj && typeof obj.rpcBehavior === 'string')) {
throw new Error(`${LB_POLICY_NAME} parsing error: expected string field rpcBehavior`);
}
return new RpcBehaviorLoadBalancingConfig(obj.rpcBehavior);
}
}
class RpcBehaviorPicker implements Picker {
constructor(private wrappedPicker: Picker, private rpcBehavior: string) {}
pick(pickArgs: PickArgs): PickResult {
const wrappedPick = this.wrappedPicker.pick(pickArgs);
if (wrappedPick.pickResultType === PickResultType.COMPLETE) {
pickArgs.metadata.add('rpc-behavior', this.rpcBehavior);
}
return wrappedPick;
}
}
const RPC_BEHAVIOR_CHILD_CONFIG = parseLoadBalancingConfig({round_robin: {}});
/**
* Load balancer implementation for Custom LB policy test
*/
class RpcBehaviorLoadBalancer implements LoadBalancer {
private child: ChildLoadBalancerHandler;
private latestConfig: RpcBehaviorLoadBalancingConfig | null = null;
constructor(channelControlHelper: ChannelControlHelper) {
const childChannelControlHelper = createChildChannelControlHelper(channelControlHelper, {
updateState: (connectivityState, picker, errorMessage) => {
if (connectivityState === grpc.connectivityState.READY && this.latestConfig) {
picker = new RpcBehaviorPicker(picker, this.latestConfig.getRpcBehavior());
}
channelControlHelper.updateState(connectivityState, picker, errorMessage);
}
});
this.child = new ChildLoadBalancerHandler(childChannelControlHelper);
}
updateAddressList(endpointList: StatusOr<Endpoint[]>, lbConfig: TypedLoadBalancingConfig, options: ChannelOptions, resolutionNote: string): boolean {
if (!(lbConfig instanceof RpcBehaviorLoadBalancingConfig)) {
return false;
}
this.latestConfig = lbConfig;
return this.child.updateAddressList(endpointList, RPC_BEHAVIOR_CHILD_CONFIG, options, resolutionNote);
}
exitIdle(): void {
this.child.exitIdle();
}
resetBackoff(): void {
this.child.resetBackoff();
}
destroy(): void {
this.child.destroy();
}
getTypeName(): string {
return LB_POLICY_NAME;
}
}
grpc.experimental.registerLoadBalancerType(LB_POLICY_NAME, RpcBehaviorLoadBalancer, RpcBehaviorLoadBalancingConfig);
const packageDefinition = protoLoader.loadSync('grpc/testing/test.proto', {
keepCase: true,
defaults: true,
@ -91,7 +183,7 @@ class CallSubscriber {
}
if (peerName in this.callsSucceededByPeer) {
this.callsSucceededByPeer[peerName] += 1;
} else {
} else {
this.callsSucceededByPeer[peerName] = 1;
}
this.callsSucceeded += 1;
@ -308,7 +400,7 @@ function makeSingleRequest(client: TestServiceClient, type: CallType, failOnFail
const startTime = process.hrtime.bigint();
const deadline = new Date();
deadline.setSeconds(deadline.getSeconds() + currentConfig.timeoutSec);
const callback = (error: grpc.ServiceError | undefined, value: Empty__Output | undefined) => {
const callback = (error: grpc.ServiceError | null, value: Empty__Output | undefined) => {
const statusCode = error?.code ?? grpc.status.OK;
const duration = process.hrtime.bigint() - startTime;
const durationSeconds = Number(duration / TIMESTAMP_ONE_SECOND) | 0;
@ -377,9 +469,11 @@ function sendConstantQps(client: TestServiceClient, qps: number, failOnFailedRpc
makeSingleRequest(client, callType, failOnFailedRpcs, callStatsTracker, callStartTimestampsTrackers[callType]);
}
}, 1000/qps);
setInterval(() => {
console.log(`Accumulated stats: ${JSON.stringify(accumulatedStats, undefined, 2)}`);
}, 1000);
if (VERBOSITY >= 2) {
setInterval(() => {
console.log(`Accumulated stats: ${JSON.stringify(accumulatedStats, undefined, 2)}`);
}, 1000);
}
}
const callTypeEnumMap = {
@ -426,9 +520,11 @@ function main() {
* channels do not share any subchannels. It does not have any
* inherent function. */
console.log(`Interop client channel ${i} starting sending ${argv.qps} QPS to ${argv.server}`);
sendConstantQps(new loadedProto.grpc.testing.TestService(argv.server, grpc.credentials.createInsecure(), {'unique': i}),
argv.qps,
argv.fail_on_failed_rpcs === 'true',
const insecureCreds = grpc.credentials.createInsecure();
const creds = new grpc_xds.XdsChannelCredentials(insecureCreds);
sendConstantQps(new loadedProto.grpc.testing.TestService(argv.server, creds, {'unique': i}),
argv.qps,
argv.fail_on_failed_rpcs === 'true',
callStatsTracker);
}
@ -486,4 +582,4 @@ function main() {
if (require.main === module) {
main();
}
}

View File

@ -0,0 +1,314 @@
/*
* Copyright 2020 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import * as grpc from '@grpc/grpc-js';
import * as grpc_xds from '../src';
import { ProtoGrpcType } from './generated/test';
import * as protoLoader from '@grpc/proto-loader';
import * as yargs from 'yargs';
import * as os from 'os';
import { HealthImplementation } from 'grpc-health-check';
import { Empty__Output, Empty } from './generated/grpc/testing/Empty';
import { SimpleRequest__Output } from './generated/grpc/testing/SimpleRequest';
import { SimpleResponse } from './generated/grpc/testing/SimpleResponse';
import { ReflectionService } from '@grpc/reflection';
grpc_xds.register();
const packageDefinition = protoLoader.loadSync('grpc/testing/test.proto', {
keepCase: true,
defaults: true,
oneofs: true,
json: true,
longs: String,
enums: String,
includeDirs: [__dirname + '/../../proto']
});
const loadedProto = grpc.loadPackageDefinition(packageDefinition) as unknown as ProtoGrpcType;
function setAsyncTimeout(delayMs: number): Promise<void> {
return new Promise<void>(resolve => {
setTimeout(() => {
resolve();
}, delayMs);
});
}
const HOSTNAME = os.hostname();
const TEST_SERVICE_NAME = '/grpc.testing.TestService/';
function testInfoInterceptor(methodDescriptor: grpc.ServerMethodDefinition<any, any>, call: grpc.ServerInterceptingCallInterface) {
const listener: grpc.ServerListener = {
onReceiveMetadata: async (metadata, next) => {
let attemptNum = 0;
const attemptNumHeader = metadata.get('grpc-previous-rpc-attempts');
if (attemptNumHeader.length > 0) {
attemptNum = Number(attemptNumHeader[0]);
if (Number.isNaN(attemptNum)) {
call.sendStatus({
code: grpc.status.INVALID_ARGUMENT,
details: 'Invalid format for grpc-previous-rpc-attempts header: ' + attemptNumHeader[0]
});
return;
}
}
const rpcBehavior = metadata.get('rpc-behavior').filter(v => typeof v === 'string').join(',');
for (const value of rpcBehavior.split(',')) {
let behaviorEntry: string;
if (value.startsWith('hostname=')) {
const splitValue = value.split(' ');
if (splitValue.length > 1) {
if (splitValue[0].substring('hostname='.length) !== HOSTNAME) {
continue;
}
behaviorEntry = splitValue[1];
} else {
call.sendStatus({
code: grpc.status.INVALID_ARGUMENT,
details: 'Invalid format for rpc-behavior header: ' + value
});
return;
}
} else {
behaviorEntry = value;
}
if (behaviorEntry.startsWith('sleep-')) {
const delaySec = Number(behaviorEntry.substring('sleep-'.length));
if (Number.isNaN(delaySec)) {
call.sendStatus({
code: grpc.status.INVALID_ARGUMENT,
details: 'Invalid format for rpc-behavior header: ' + value
});
return;
}
await setAsyncTimeout(delaySec * 1000);
}
if (behaviorEntry === 'keep-open') {
return;
}
if (behaviorEntry.startsWith('error-code-')) {
const errorCode = Number(behaviorEntry.substring('error-code-'.length));
if (Number.isNaN(errorCode)) {
call.sendStatus({
code: grpc.status.INVALID_ARGUMENT,
details: 'Invalid format for rpc-behavior header: ' + value
});
return;
}
call.sendStatus({
code: errorCode,
details: 'RPC failed as directed by rpc-behavior header value ' + value
});
return;
}
if (behaviorEntry.startsWith('succeed-on-retry-attempt-')) {
const targetAttempt = Number(behaviorEntry.substring('succeed-on-retry-attempt-'.length));
if (Number.isNaN(targetAttempt)) {
call.sendStatus({
code: grpc.status.INVALID_ARGUMENT,
details: 'Invalid format for rpc-behavior header: ' + value
});
return;
}
if (attemptNum === targetAttempt) {
next(metadata);
return;
}
}
}
next(metadata);
}
};
const responder: grpc.Responder = {
start: next => {
next(listener);
},
sendMetadata: (metadata, next) => {
metadata.add('hostname', HOSTNAME);
next(metadata);
}
}
return new grpc.ServerInterceptingCall(call, responder);
};
function adminServiceInterceptor(methodDescriptor: grpc.ServerMethodDefinition<any, any>, call: grpc.ServerInterceptingCallInterface): grpc.ServerInterceptingCall {
const listener: grpc.ServerListener = {
onReceiveMessage: (message, next) => {
console.log(`Received request to method ${methodDescriptor.path}: ${JSON.stringify(message)}`);
next(message);
}
}
const responder: grpc.Responder = {
start: next => {
next(listener);
},
sendMessage: (message, next) => {
console.log(`Responded to request to method ${methodDescriptor.path}: ${JSON.stringify(message)}`);
next(message);
}
};
return new grpc.ServerInterceptingCall(call, responder);
}
function unifiedInterceptor(methodDescriptor: grpc.ServerMethodDefinition<any, any>, call: grpc.ServerInterceptingCallInterface): grpc.ServerInterceptingCall {
if (methodDescriptor.path.startsWith(TEST_SERVICE_NAME)) {
return testInfoInterceptor(methodDescriptor, call);
} else {
return adminServiceInterceptor(methodDescriptor, call);
}
}
const testServiceHandler = {
EmptyCall: (call: grpc.ServerUnaryCall<Empty__Output, Empty>, callback: grpc.sendUnaryData<Empty>) => {
callback(null, {});
},
UnaryCall: (call: grpc.ServerUnaryCall<SimpleRequest__Output, SimpleResponse>, callback: grpc.sendUnaryData<SimpleResponse>) => {
callback(null, {
hostname: HOSTNAME,
payload: {
body: Buffer.from('0'.repeat(call.request.response_size))
}
});
}
};
function serverBindPromise(server: grpc.Server, port: string, credentials: grpc.ServerCredentials): Promise<number> {
return new Promise((resolve, reject) => {
server.bindAsync(port, credentials, (error, port) => {
if (error) {
reject(error);
} else {
resolve(port);
}
})
})
}
function getIPv4Address(): string | null {
for (const [name, addressList] of Object.entries(os.networkInterfaces())) {
if (name === 'lo' || !addressList) {
continue;
}
for (const address of addressList) {
if (address.family === 'IPv4') {
return address.address;
}
}
}
return null;
}
function getIPv6Addresses(): string[] {
const ipv6Addresses: string[] = [];
for (const [name, addressList] of Object.entries(os.networkInterfaces())) {
if (name === 'lo' || !addressList) {
continue;
}
for (const address of addressList) {
if (address.family === 'IPv6') {
ipv6Addresses.push(address.address);
}
}
}
return ipv6Addresses;
}
async function main() {
const argv = yargs
.string(['port', 'maintenance_port', 'address_type', 'secure_mode'])
.demandOption(['port'])
.default('address_type', 'IPV4_IPV6')
.default('secure_mode', 'false')
.parse()
console.log('Starting xDS interop server. Args: ', argv);
const healthImpl = new HealthImplementation({'': 'NOT_SERVING'});
const xdsUpdateHealthServiceImpl = {
SetServing(call: grpc.ServerUnaryCall<Empty, Empty__Output>, callback: grpc.sendUnaryData<Empty__Output>) {
healthImpl.setStatus('', 'SERVING');
callback(null, {});
},
SetNotServing(call: grpc.ServerUnaryCall<Empty, Empty__Output>, callback: grpc.sendUnaryData<Empty__Output>) {
healthImpl.setStatus('', 'NOT_SERVING');
callback(null, {});
}
}
const reflection = new ReflectionService(packageDefinition, {
services: ['grpc.testing.TestService']
})
const addressType = argv.address_type.toUpperCase();
const secureMode = argv.secure_mode.toLowerCase() == 'true';
if (secureMode) {
if (addressType !== 'IPV4_IPV6') {
throw new Error('Secure mode only supports IPV4_IPV6 address type');
}
const maintenanceServer = new grpc.Server({interceptors: [adminServiceInterceptor]});
maintenanceServer.addService(loadedProto.grpc.testing.XdsUpdateHealthService.service, xdsUpdateHealthServiceImpl)
healthImpl.addToServer(maintenanceServer);
reflection.addToServer(maintenanceServer);
grpc.addAdminServicesToServer(maintenanceServer);
const server = new grpc_xds.XdsServer({interceptors: [testInfoInterceptor]});
server.addService(loadedProto.grpc.testing.TestService.service, testServiceHandler);
const xdsCreds = new grpc_xds.XdsServerCredentials(grpc.ServerCredentials.createInsecure());
await Promise.all([
serverBindPromise(maintenanceServer, `[::]:${argv.maintenance_port}`, grpc.ServerCredentials.createInsecure()),
serverBindPromise(server, `0.0.0.0:${argv.port}`, xdsCreds)
]);
} else {
const server = new grpc.Server({interceptors: [unifiedInterceptor]});
server.addService(loadedProto.grpc.testing.XdsUpdateHealthService.service, xdsUpdateHealthServiceImpl);
healthImpl.addToServer(server);
reflection.addToServer(server);
grpc.addAdminServicesToServer(server);
server.addService(loadedProto.grpc.testing.TestService.service, testServiceHandler);
const creds = grpc.ServerCredentials.createInsecure();
switch (addressType) {
case 'IPV4_IPV6':
await serverBindPromise(server, `[::]:${argv.port}`, creds);
break;
case 'IPV4':
await serverBindPromise(server, `127.0.0.1:${argv.port}`, creds);
const address = getIPv4Address();
if (address) {
await serverBindPromise(server, `${address}:${argv.port}`, creds);
}
break;
case 'IPV6':
await serverBindPromise(server, `[::1]:${argv.port}`, creds);
for (const address of getIPv6Addresses()) {
try {
await serverBindPromise(server, `[${address}]:${argv.port}`, creds);
} catch (e) {
console.log(`Binding ${address} failed with error ${(e as Error).message}`);
}
}
break;
default:
throw new Error(`Unknown address type: ${argv.address_type}`);
}
}
healthImpl.setStatus('', 'SERVING');
}
if (require.main === module) {
main();
}

View File

@ -1,6 +1,6 @@
{
"name": "@grpc/grpc-js-xds",
"version": "1.9.2",
"version": "1.13.0",
"description": "Plugin for @grpc/grpc-js. Adds the xds:// URL scheme and associated features.",
"main": "build/src/index.js",
"scripts": {
@ -12,7 +12,7 @@
"prepare": "npm run generate-types && npm run compile",
"pretest": "npm run compile",
"posttest": "npm run check",
"generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs deps/envoy-api/ deps/xds/ deps/googleapis/ deps/protoc-gen-validate/ -O src/generated/ --grpcLib @grpc/grpc-js envoy/service/discovery/v3/ads.proto envoy/service/load_stats/v3/lrs.proto envoy/config/listener/v3/listener.proto envoy/config/route/v3/route.proto envoy/config/cluster/v3/cluster.proto envoy/config/endpoint/v3/endpoint.proto envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto udpa/type/v1/typed_struct.proto xds/type/v3/typed_struct.proto envoy/extensions/filters/http/fault/v3/fault.proto envoy/service/status/v3/csds.proto",
"generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs deps/envoy-api/ deps/xds/ deps/googleapis/ deps/protoc-gen-validate/ -O src/generated/ --grpcLib @grpc/grpc-js envoy/service/discovery/v3/ads.proto envoy/service/load_stats/v3/lrs.proto envoy/config/listener/v3/listener.proto envoy/config/route/v3/route.proto envoy/config/cluster/v3/cluster.proto envoy/config/endpoint/v3/endpoint.proto envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto udpa/type/v1/typed_struct.proto xds/type/v3/typed_struct.proto envoy/extensions/filters/http/fault/v3/fault.proto envoy/service/status/v3/csds.proto envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.proto envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.proto envoy/extensions/load_balancing_policies/pick_first/v3/pick_first.proto envoy/extensions/clusters/aggregate/v3/cluster.proto envoy/extensions/transport_sockets/tls/v3/tls.proto envoy/config/rbac/v3/rbac.proto envoy/extensions/filters/http/rbac/v3/rbac.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"
},
@ -33,23 +33,29 @@
"homepage": "https://github.com/grpc/grpc-node#readme",
"devDependencies": {
"@grpc/grpc-js": "file:../grpc-js",
"@grpc/proto-loader": "file:../proto-loader",
"@types/gulp": "^4.0.6",
"@types/gulp-mocha": "0.0.32",
"@types/mocha": "^5.2.6",
"@types/node": "^13.11.1",
"@types/node": ">=20.11.20",
"@grpc/reflection": "file:../grpc-reflection",
"@types/yargs": "^15.0.5",
"gts": "^2.0.2",
"typescript": "^3.8.3",
"find-free-ports": "^3.1.1",
"grpc-health-check": "file:../grpc-health-check",
"gts": "^5.0.1",
"ncp": "^2.0.0",
"typescript": "^5.1.3",
"yargs": "^15.4.1"
},
"dependencies": {
"@grpc/proto-loader": "^0.6.0",
"@grpc/proto-loader": "^0.7.13",
"google-auth-library": "^7.0.2",
"re2-wasm": "^1.0.1",
"vscode-uri": "^3.0.7"
"vscode-uri": "^3.0.7",
"xxhash-wasm": "^1.0.2"
},
"peerDependencies": {
"@grpc/grpc-js": "~1.9.0"
"@grpc/grpc-js": "~1.13.0"
},
"engines": {
"node": ">=10.10.0"
@ -59,6 +65,7 @@
"build/src/**/*.{js,d.ts,js.map}",
"deps/envoy-api/envoy/admin/v3/**/*.proto",
"deps/envoy-api/envoy/config/**/*.proto",
"deps/envoy-api/envoy/data/**/*.proto",
"deps/envoy-api/envoy/service/**/*.proto",
"deps/envoy-api/envoy/type/**/*.proto",
"deps/envoy-api/envoy/annotations/**/*.proto",
@ -66,6 +73,7 @@
"deps/googleapis/google/api/**/*.proto",
"deps/googleapis/google/protobuf/**/*.proto",
"deps/googleapis/google/rpc/**/*.proto",
"deps/protoc-gen-validate/**/*.proto",
"deps/xds/udpa/annotations/**/*.proto",
"deps/xds/udpa/type/**/*.proto",
"deps/xds/xds/annotations/**/*.proto",

View File

@ -0,0 +1,39 @@
#!/usr/bin/env bash
# Copyright 2024 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -eo pipefail
#######################################
# Builds test app Docker images and pushes them to GCR.
# Called from psm_interop_kokoro_lib.sh.
#
# Globals:
# SRC_DIR: Absolute path to the source repo on Kokoro VM
# SERVER_IMAGE_NAME: Test server Docker image name
# CLIENT_IMAGE_NAME: Test client Docker image name
# GIT_COMMIT: SHA-1 of git commit being built
# DOCKER_REGISTRY: Docker registry to push to
# Outputs:
# Writes the output of docker image build stdout, stderr
#######################################
psm::lang::build_docker_images() {
local client_dockerfile="packages/grpc-js-xds/interop/test-client.Dockerfile"
local server_dockerfile="packages/grpc-js-xds/interop/test-server.Dockerfile"
cd "${SRC_DIR}"
psm::tools::run_verbose git submodule update --init --recursive
psm::tools::run_verbose git submodule status
psm::build::docker_images_generic "${client_dockerfile}" "${server_dockerfile}"
}

View File

@ -0,0 +1,40 @@
#!/usr/bin/env bash
# Copyright 2024 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -eo pipefail
# Input parameters to psm:: methods of the install script.
readonly GRPC_LANGUAGE="node"
readonly BUILD_SCRIPT_DIR="$(dirname "$0")"
# Used locally.
readonly TEST_DRIVER_INSTALL_SCRIPT_URL="https://raw.githubusercontent.com/${TEST_DRIVER_REPO_OWNER:-grpc}/psm-interop/${TEST_DRIVER_BRANCH:-main}/.kokoro/psm_interop_kokoro_lib.sh"
psm::lang::source_install_lib() {
echo "Sourcing test driver install script from: ${TEST_DRIVER_INSTALL_SCRIPT_URL}"
local install_lib
# Download to a tmp file.
install_lib="$(mktemp -d)/psm_interop_kokoro_lib.sh"
curl -s --retry-connrefused --retry 5 -o "${install_lib}" "${TEST_DRIVER_INSTALL_SCRIPT_URL}"
# Checksum.
if command -v sha256sum &> /dev/null; then
echo "Install script checksum:"
sha256sum "${install_lib}"
fi
source "${install_lib}"
}
psm::lang::source_install_lib
source "${BUILD_SCRIPT_DIR}/psm-interop-build-${GRPC_LANGUAGE}.sh"
psm::run "${PSM_TEST_SUITE}"

View File

@ -34,9 +34,18 @@ echo "source $NVM_DIR/nvm.sh" > ~/.profile
echo "source $NVM_DIR/nvm.sh" > ~/.shrc
export ENV=~/.shrc
cd $base/../proto-loader
npm install
cd $base/../grpc-js
npm install
cd $base/../grpc-health-check
npm install
cd $base/../grpc-reflection
npm install
# grpc-js-xds has a dev dependency on "../grpc-js", so it should pull that in automatically
cd $base
git submodule update --init --recursive

View File

@ -1,175 +0,0 @@
#!/usr/bin/env bash
# Copyright 2022 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -eo pipefail
# Constants
readonly GITHUB_REPOSITORY_NAME="grpc-node"
readonly TEST_DRIVER_INSTALL_SCRIPT_URL="https://raw.githubusercontent.com/${TEST_DRIVER_REPO_OWNER:-grpc}/psm-interop/${TEST_DRIVER_BRANCH:-main}/.kokoro/psm_interop_kokoro_lib.sh"
## xDS test client Docker images
readonly SERVER_IMAGE_NAME="gcr.io/grpc-testing/xds-interop/java-server:558b5b0bfac8e21755c223063274a779b3898afe"
readonly CLIENT_IMAGE_NAME="gcr.io/grpc-testing/xds-interop/node-client"
readonly FORCE_IMAGE_BUILD="${FORCE_IMAGE_BUILD:-0}"
readonly BUILD_APP_PATH="packages/grpc-js-xds/interop/Dockerfile"
readonly LANGUAGE_NAME="Node"
#######################################
# Builds test app Docker images and pushes them to GCR
# Globals:
# BUILD_APP_PATH
# CLIENT_IMAGE_NAME: Test client Docker image name
# GIT_COMMIT: SHA-1 of git commit being built
# TESTING_VERSION: version branch under test, f.e. v1.42.x, master
# Arguments:
# None
# Outputs:
# Writes the output of `gcloud builds submit` to stdout, stderr
#######################################
build_test_app_docker_images() {
echo "Building ${LANGUAGE_NAME} xDS interop test app Docker images"
pushd "${SRC_DIR}"
docker build \
-f "${BUILD_APP_PATH}" \
-t "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \
.
gcloud -q auth configure-docker
docker push "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}"
if is_version_branch "${TESTING_VERSION}"; then
tag_and_push_docker_image "${CLIENT_IMAGE_NAME}" "${GIT_COMMIT}" "${TESTING_VERSION}"
fi
popd
}
#######################################
# Builds test app and its docker images unless they already exist
# Globals:
# CLIENT_IMAGE_NAME: Test client Docker image name
# GIT_COMMIT: SHA-1 of git commit being built
# FORCE_IMAGE_BUILD
# Arguments:
# None
# Outputs:
# Writes the output to stdout, stderr
#######################################
build_docker_images_if_needed() {
# Check if images already exist
client_tags="$(gcloud_gcr_list_image_tags "${CLIENT_IMAGE_NAME}" "${GIT_COMMIT}")"
printf "Client image: %s:%s\n" "${CLIENT_IMAGE_NAME}" "${GIT_COMMIT}"
echo "${client_tags:-Client image not found}"
# Build if any of the images are missing, or FORCE_IMAGE_BUILD=1
if [[ "${FORCE_IMAGE_BUILD}" == "1" || -z "${client_tags}" ]]; then
build_test_app_docker_images
else
echo "Skipping ${LANGUAGE_NAME} test app build"
fi
}
#######################################
# Executes the test case
# Globals:
# TEST_DRIVER_FLAGFILE: Relative path to test driver flagfile
# KUBE_CONTEXT: The name of kubectl context with GKE cluster access
# SECONDARY_KUBE_CONTEXT: The name of kubectl context with secondary GKE cluster access, if any
# TEST_XML_OUTPUT_DIR: Output directory for the test xUnit XML report
# CLIENT_IMAGE_NAME: Test client Docker image name
# GIT_COMMIT: SHA-1 of git commit being built
# Arguments:
# Test case name
# Outputs:
# Writes the output of test execution to stdout, stderr
# Test xUnit report to ${TEST_XML_OUTPUT_DIR}/${test_name}/sponge_log.xml
#######################################
run_test() {
# Test driver usage:
# https://github.com/grpc/grpc/tree/master/tools/run_tests/xds_k8s_test_driver#basic-usage
local test_name="${1:?Usage: run_test test_name}"
local out_dir="${TEST_XML_OUTPUT_DIR}/${test_name}"
mkdir -pv "${out_dir}"
# testing_version is used by the framework to determine the supported PSM
# features. It's captured from Kokoro job name of the Node repo, which takes
# the form:
# grpc/node/<branch name>/<job name>
python3 -m "tests.${test_name}" \
--flagfile="${TEST_DRIVER_FLAGFILE}" \
--kube_context="${KUBE_CONTEXT}" \
--secondary_kube_context="${SECONDARY_KUBE_CONTEXT}" \
--client_image="${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \
--server_image="${SERVER_IMAGE_NAME}" \
--testing_version="${TESTING_VERSION}" \
--force_cleanup \
--collect_app_logs \
--log_dir="${out_dir}" \
--xml_output_file="${out_dir}/sponge_log.xml" \
|& tee "${out_dir}/sponge_log.log"
}
#######################################
# Main function: provision software necessary to execute tests, and run them
# Globals:
# KOKORO_ARTIFACTS_DIR
# GITHUB_REPOSITORY_NAME
# SRC_DIR: Populated with absolute path to the source repo
# TEST_DRIVER_REPO_DIR: Populated with the path to the repo containing
# the test driver
# TEST_DRIVER_FULL_DIR: Populated with the path to the test driver source code
# TEST_DRIVER_FLAGFILE: Populated with relative path to test driver flagfile
# TEST_XML_OUTPUT_DIR: Populated with the path to test xUnit XML report
# GIT_ORIGIN_URL: Populated with the origin URL of git repo used for the build
# GIT_COMMIT: Populated with the SHA-1 of git commit being built
# GIT_COMMIT_SHORT: Populated with the short SHA-1 of git commit being built
# KUBE_CONTEXT: Populated with name of kubectl context with GKE cluster access
# SECONDARY_KUBE_CONTEXT: Populated with name of kubectl context with secondary GKE cluster access, if any
# Arguments:
# None
# Outputs:
# Writes the output of test execution to stdout, stderr
#######################################
main() {
local script_dir
script_dir="$(dirname "$0")"
cd "${script_dir}"
git submodule update --init --recursive
# Source the test driver from the master branch.
echo "Sourcing test driver install script from: ${TEST_DRIVER_INSTALL_SCRIPT_URL}"
source /dev/stdin <<< "$(curl -s "${TEST_DRIVER_INSTALL_SCRIPT_URL}")"
activate_gke_cluster GKE_CLUSTER_PSM_LB
activate_secondary_gke_cluster GKE_CLUSTER_PSM_LB
set -x
if [[ -n "${KOKORO_ARTIFACTS_DIR}" ]]; then
kokoro_setup_test_driver "${GITHUB_REPOSITORY_NAME}"
else
local_setup_test_driver "${script_dir}"
fi
build_docker_images_if_needed
# Run tests
cd "${TEST_DRIVER_FULL_DIR}"
local failed_tests=0
test_suites=("baseline_test" "api_listener_test" "change_backend_service_test" "failover_test" "remove_neg_test" "round_robin_test" "outlier_detection_test")
for test in "${test_suites[@]}"; do
run_test $test || (( ++failed_tests ))
done
echo "Failed test suites: ${failed_tests}"
}
main "$@"

View File

@ -1,162 +0,0 @@
#!/usr/bin/env bash
# Copyright 2022 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -eo pipefail
# Constants
readonly GITHUB_REPOSITORY_NAME="grpc-node"
readonly TEST_DRIVER_INSTALL_SCRIPT_URL="https://raw.githubusercontent.com/${TEST_DRIVER_REPO_OWNER:-grpc}/psm-interop/${TEST_DRIVER_BRANCH:-main}/.kokoro/psm_interop_kokoro_lib.sh"
## xDS test client Docker images
readonly CLIENT_IMAGE_NAME="gcr.io/grpc-testing/xds-interop/node-client"
readonly FORCE_IMAGE_BUILD="${FORCE_IMAGE_BUILD:-0}"
readonly BUILD_APP_PATH="packages/grpc-js-xds/interop/Dockerfile"
readonly LANGUAGE_NAME="Node"
#######################################
# Builds test app Docker images and pushes them to GCR
# Globals:
# BUILD_APP_PATH
# CLIENT_IMAGE_NAME: Test client Docker image name
# GIT_COMMIT: SHA-1 of git commit being built
# TESTING_VERSION: version branch under test, f.e. v1.42.x, master
# Arguments:
# None
# Outputs:
# Writes the output of `gcloud builds submit` to stdout, stderr
#######################################
build_test_app_docker_images() {
echo "Building ${LANGUAGE_NAME} xDS interop test app Docker images"
pushd "${SRC_DIR}"
docker build \
-f "${BUILD_APP_PATH}" \
-t "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \
.
gcloud -q auth configure-docker
docker push "${CLIENT_IMAGE_NAME}:${GIT_COMMIT}"
if is_version_branch "${TESTING_VERSION}"; then
tag_and_push_docker_image "${CLIENT_IMAGE_NAME}" "${GIT_COMMIT}" "${TESTING_VERSION}"
fi
popd
}
#######################################
# Builds test app and its docker images unless they already exist
# Globals:
# CLIENT_IMAGE_NAME: Test client Docker image name
# GIT_COMMIT: SHA-1 of git commit being built
# FORCE_IMAGE_BUILD
# Arguments:
# None
# Outputs:
# Writes the output to stdout, stderr
#######################################
build_docker_images_if_needed() {
# Check if images already exist
client_tags="$(gcloud_gcr_list_image_tags "${CLIENT_IMAGE_NAME}" "${GIT_COMMIT}")"
printf "Client image: %s:%s\n" "${CLIENT_IMAGE_NAME}" "${GIT_COMMIT}"
echo "${client_tags:-Client image not found}"
# Build if any of the images are missing, or FORCE_IMAGE_BUILD=1
if [[ "${FORCE_IMAGE_BUILD}" == "1" || -z "${client_tags}" ]]; then
build_test_app_docker_images
else
echo "Skipping ${LANGUAGE_NAME} test app build"
fi
}
#######################################
# Executes the test case
# Globals:
# TEST_DRIVER_FLAGFILE: Relative path to test driver flagfile
# KUBE_CONTEXT: The name of kubectl context with GKE cluster access
# TEST_XML_OUTPUT_DIR: Output directory for the test xUnit XML report
# CLIENT_IMAGE_NAME: Test client Docker image name
# GIT_COMMIT: SHA-1 of git commit being built
# TESTING_VERSION: version branch under test: used by the framework to determine the supported PSM
# features.
# Arguments:
# Test case name
# Outputs:
# Writes the output of test execution to stdout, stderr
# Test xUnit report to ${TEST_XML_OUTPUT_DIR}/${test_name}/sponge_log.xml
#######################################
run_test() {
# Test driver usage:
# https://github.com/grpc/grpc/tree/master/tools/run_tests/xds_k8s_test_driver#basic-usage
local test_name="${1:?Usage: run_test test_name}"
local out_dir="${TEST_XML_OUTPUT_DIR}/${test_name}"
mkdir -pv "${out_dir}"
set -x
python3 -m "tests.${test_name}" \
--flagfile="${TEST_DRIVER_FLAGFILE}" \
--flagfile="config/url-map.cfg" \
--kube_context="${KUBE_CONTEXT}" \
--client_image="${CLIENT_IMAGE_NAME}:${GIT_COMMIT}" \
--testing_version="${TESTING_VERSION}" \
--collect_app_logs \
--log_dir="${out_dir}" \
--xml_output_file="${out_dir}/sponge_log.xml" \
|& tee "${out_dir}/sponge_log.log"
}
#######################################
# Main function: provision software necessary to execute tests, and run them
# Globals:
# KOKORO_ARTIFACTS_DIR
# GITHUB_REPOSITORY_NAME
# SRC_DIR: Populated with absolute path to the source repo
# TEST_DRIVER_REPO_DIR: Populated with the path to the repo containing
# the test driver
# TEST_DRIVER_FULL_DIR: Populated with the path to the test driver source code
# TEST_DRIVER_FLAGFILE: Populated with relative path to test driver flagfile
# TEST_XML_OUTPUT_DIR: Populated with the path to test xUnit XML report
# GIT_ORIGIN_URL: Populated with the origin URL of git repo used for the build
# GIT_COMMIT: Populated with the SHA-1 of git commit being built
# GIT_COMMIT_SHORT: Populated with the short SHA-1 of git commit being built
# KUBE_CONTEXT: Populated with name of kubectl context with GKE cluster access
# Arguments:
# None
# Outputs:
# Writes the output of test execution to stdout, stderr
#######################################
main() {
local script_dir
script_dir="$(dirname "$0")"
cd "${script_dir}"
git submodule update --init --recursive
# Source the test driver from the master branch.
echo "Sourcing test driver install script from: ${TEST_DRIVER_INSTALL_SCRIPT_URL}"
source /dev/stdin <<< "$(curl -s "${TEST_DRIVER_INSTALL_SCRIPT_URL}")"
activate_gke_cluster GKE_CLUSTER_PSM_BASIC
set -x
if [[ -n "${KOKORO_ARTIFACTS_DIR}" ]]; then
kokoro_setup_test_driver "${GITHUB_REPOSITORY_NAME}"
else
local_setup_test_driver "${script_dir}"
fi
build_docker_images_if_needed
# Run tests
cd "${TEST_DRIVER_FULL_DIR}"
run_test url_map || echo "Failed url_map test"
}
main "$@"

View File

@ -0,0 +1,192 @@
/*
* Copyright 2024 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as net from 'net';
import { CidrRange__Output } from './generated/envoy/config/core/v3/CidrRange';
const IPV4_COMPONENT_COUNT = 4n;
const IPV4_COMPONENT_SIZE = 8n;
const IPV4_COMPONENT_CAP = 1n << IPV4_COMPONENT_SIZE;
const IPV4_TOTAL_SIZE = IPV4_COMPONENT_COUNT * IPV4_COMPONENT_SIZE;
const IPV6_COMPONENT_SIZE = 16n;
const IPV6_COMPONENT_COUNT = 8n;
const IPV6_COMPONENT_CAP = 1n << IPV6_COMPONENT_SIZE;
const IPV6_TOTAL_SIZE = IPV6_COMPONENT_COUNT * IPV6_COMPONENT_SIZE;
export interface CidrRange {
addressPrefix: string;
prefixLen: number;
}
export function parseIPv4(address: string): bigint {
return address.split('.').map(component => BigInt(component)).reduce((accumulator, current) => accumulator * IPV4_COMPONENT_CAP + current, 0n);
}
export function parseIPv6(address: string): bigint {
/* If an IPv6 address contains two or more consecutive components with value
* which can be collectively represented with the string '::'. For example,
* the IPv6 adddress 0:0:0:0:0:0:0:1 can also be represented as ::1. Here we
* expand any :: into the correct number of individual components. */
const sections = address.split('::');
let components: string[];
if (sections.length === 1) {
components = sections[0].split(':');
} else if (sections.length === 2) {
const beginning = sections[0].split(':').filter(value => value !== '');
const end = sections[1].split(':').filter(value => value !== '');
components = beginning.concat(Array(8 - beginning.length - end.length).fill('0'), end);
} else {
throw new Error('Invalid IPv6 address contains more than one instance of ::');
}
return components.map(component => BigInt('0x' + component)).reduce((accumulator, current) => accumulator * 65536n + current, 0n);
}
function parseIP(address: string): bigint {
switch (net.isIP(address)) {
case 4:
return parseIPv4(address);
case 6:
return parseIPv6(address);
default:
throw new Error(`Invalid IP address ${address}`);
}
}
export function formatIPv4(address: bigint): string {
const reverseComponents: bigint[] = [];
for (let i = 0; i < IPV4_COMPONENT_COUNT; i++) {
reverseComponents.push(address % IPV4_COMPONENT_CAP);
address = address / IPV4_COMPONENT_CAP;
}
return reverseComponents.reverse().map(component => component.toString(10)).join('.');
}
export function formatIPv6(address: bigint): string {
const reverseComponents: bigint[] = [];
for (let i = 0; i < IPV6_COMPONENT_COUNT; i++) {
reverseComponents.push(address % IPV6_COMPONENT_CAP);
address = address / IPV6_COMPONENT_CAP;
}
const components = reverseComponents.reverse();
/* Find the longest run of consecutive 0 values in the list of components, to
* replace it with :: in the output */
let maxZeroRunIndex = 0;
let maxZeroRunLength = 0;
let inZeroRun = false;
let currentZeroRunIndex = 0;
let currentZeroRunLength = 0;
for (let i = 0; i < components.length; i++) {
if (components[i] === 0n) {
if (inZeroRun) {
currentZeroRunLength += 1;
} else {
inZeroRun = true;
currentZeroRunIndex = i;
currentZeroRunLength = 1;
}
if (currentZeroRunLength > maxZeroRunLength) {
maxZeroRunIndex = currentZeroRunIndex;
maxZeroRunLength = currentZeroRunLength;
}
} else {
currentZeroRunLength = 0;
inZeroRun = false;
}
}
if (maxZeroRunLength >= 2) {
const beginning = components.slice(0, maxZeroRunIndex);
const end = components.slice(maxZeroRunIndex + maxZeroRunLength);
return beginning.map(value => value.toString(16)).join(':') + '::' + end.map(value => value.toString(16)).join(':');
} else {
return components.map(value => value.toString(16)).join(':');
}
}
function getSubnetMaskIPv4(prefixLen: number) {
return ~((1n << (IPV4_TOTAL_SIZE - BigInt(prefixLen))) - 1n);
}
function getSubnetMaskIPv6(prefixLen: number) {
return ~((1n << (IPV6_TOTAL_SIZE - BigInt(prefixLen))) - 1n);
}
export function firstNBitsIPv4(address: string, prefixLen: number): string {
const addressNum = parseIPv4(address);
const prefixMask = getSubnetMaskIPv4(prefixLen);
return formatIPv4(addressNum & prefixMask);
}
export function firstNBitsIPv6(address: string, prefixLen: number): string {
const addressNum = parseIPv6(address);
const prefixMask = getSubnetMaskIPv6(prefixLen);
return formatIPv6(addressNum & prefixMask);
}
export function normalizeCidrRange(range: CidrRange): CidrRange {
switch (net.isIP(range.addressPrefix)) {
case 4: {
const prefixLen = Math.min(Math.max(range.prefixLen, 0), 32);
return {
addressPrefix: firstNBitsIPv4(range.addressPrefix, prefixLen),
prefixLen: prefixLen
};
}
case 6: {
const prefixLen = Math.min(Math.max(range.prefixLen, 0), 128);
return {
addressPrefix: firstNBitsIPv6(range.addressPrefix, prefixLen),
prefixLen: prefixLen
};
}
default:
throw new Error(`Invalid IP address prefix ${range.addressPrefix}`);
}
}
export function getCidrRangeSubnetMask(range: CidrRange): bigint {
switch (net.isIP(range.addressPrefix)) {
case 4:
return getSubnetMaskIPv4(range.prefixLen);
case 6:
return getSubnetMaskIPv6(range.prefixLen);
default:
throw new Error('Invalid CIDR range');
}
}
export function inCidrRange(range: CidrRange, address: string): boolean {
if (net.isIP(range.addressPrefix) !== net.isIP(address)) {
return false;
}
return (parseIP(address) & getCidrRangeSubnetMask(range)) === parseIP(range.addressPrefix);
}
export function cidrRangeEqual(range1: CidrRange | undefined, range2: CidrRange | undefined): boolean {
if (range1 === undefined && range2 === undefined) {
return true;
}
if (range1 === undefined || range2 === undefined) {
return false;
}
return range1.addressPrefix === range2.addressPrefix && range1.prefixLen === range2.prefixLen;
}
export function cidrRangeMessageToCidrRange(message: CidrRange__Output): CidrRange {
return {
addressPrefix: message.address_prefix,
prefixLen: message.prefix_len?.value ?? 0
};
}

View File

@ -0,0 +1,48 @@
/*
* Copyright 2024 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Types and function from https://stackoverflow.com/a/72059390/159388, with modifications
type ElementType<A> = A extends ReadonlyArray<infer T> ? T | undefined : never;
type ElementsOfAll<Inputs, R extends ReadonlyArray<unknown> = []> = Inputs extends readonly [infer F, ...infer M] ? ElementsOfAll<M, [...R, ElementType<F>]> : R;
type CartesianProduct<Inputs> = ElementsOfAll<Inputs>[];
/**
* Get the cross product or Cartesian product of a list of groups. The
* implementation is copied, with some modifications, from
* https://stackoverflow.com/a/72059390/159388.
* @param sets A list of groups of elements
* @returns A list of all possible combinations of one element from each group
* in sets. Empty groups will result in undefined in that slot in each
* combination.
*/
export function crossProduct<Sets extends ReadonlyArray<ReadonlyArray<unknown>>>(sets: Sets): CartesianProduct<Sets> {
/* The input is an array of arrays, and the expected output is an array of
* each possible combination of one element each of the input arrays, with
* the exception that if one of the input arrays is empty, each combination
* gets [undefined] in that slot.
*
* At each step in the reduce call, we start with the cross product of the
* first N groups, and the next group. For each combation, for each element
* of the next group, extend the combination with that element.
*
* The type assertion at the end is needed because TypeScript doesn't track
* the types well enough through the reduce calls to see that the result has
* the expected type.
*/
return sets.map(x => x.length === 0 ? [undefined] : x).reduce((combinations: unknown[][], nextGroup) => combinations.flatMap(combination => nextGroup.map(element => [...combination, element])), [[]] as unknown[][]) as CartesianProduct<Sets>;
}

View File

@ -0,0 +1,33 @@
/*
* 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 { experimental } from '@grpc/grpc-js';
import { Duration__Output } from './generated/google/protobuf/Duration';
import Duration = experimental.Duration;
/**
* Convert a Duration protobuf message object to a Duration object as used in
* the ServiceConfig definition. The difference is that the protobuf message
* defines seconds as a long, which is represented as a string in JavaScript,
* and the one used in the service config defines it as a number.
* @param duration
*/
export function protoDurationToDuration(duration: Duration__Output): Duration {
return {
seconds: Number.parseInt(duration.seconds),
nanos: duration.nanos
};
}

View File

@ -15,7 +15,16 @@
*
*/
/* Switches to enable or disable experimental features. If the default is
* 'true', the feature is enabled by default, if the default is 'false' the
* feature is disabled by default. */
export const EXPERIMENTAL_FAULT_INJECTION = (process.env.GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION ?? 'true') === 'true';
export const EXPERIMENTAL_OUTLIER_DETECTION = (process.env.GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION ?? 'true') === 'true';
export const EXPERIMENTAL_RETRY = (process.env.GRPC_XDS_EXPERIMENTAL_ENABLE_RETRY ?? 'true') === 'true';
export const EXPERIMENTAL_FEDERATION = (process.env.GRPC_EXPERIMENTAL_XDS_FEDERATION ?? 'false') === 'true';
export const EXPERIMENTAL_CUSTOM_LB_CONFIG = (process.env.GRPC_EXPERIMENTAL_XDS_CUSTOM_LB_CONFIG ?? 'true') === 'true';
export const EXPERIMENTAL_RING_HASH = (process.env.GRPC_XDS_EXPERIMENTAL_ENABLE_RING_HASH ?? 'true') === 'true';
export const EXPERIMENTAL_PICK_FIRST = (process.env.GRPC_EXPERIMENTAL_PICKFIRST_LB_CONFIG ?? 'false') === 'true';
export const EXPERIMENTAL_DUALSTACK_ENDPOINTS = (process.env.GRPC_EXPERIMENTAL_XDS_DUALSTACK_ENDPOINTS ?? 'true') === 'true';
export const AGGREGATE_CLUSTER_BACKWARDS_COMPAT = (process.env.GRPC_XDS_AGGREGATE_CLUSTER_BACKWARD_COMPAT ?? 'false') === 'true';
export const EXPERIMENTAL_RBAC = (process.env.GRPC_XDS_EXPERIMENTAL_RBAC ?? 'false') === 'true';

View File

@ -24,10 +24,14 @@ export interface ProtoGrpcType {
DataSource: MessageTypeDefinition
EnvoyInternalAddress: MessageTypeDefinition
Extension: MessageTypeDefinition
ExtraSourceAddress: MessageTypeDefinition
HeaderMap: MessageTypeDefinition
HeaderValue: MessageTypeDefinition
HeaderValueOption: MessageTypeDefinition
HttpUri: MessageTypeDefinition
KeyValue: MessageTypeDefinition
KeyValueAppend: MessageTypeDefinition
KeyValueMutation: MessageTypeDefinition
Locality: MessageTypeDefinition
Metadata: MessageTypeDefinition
Node: MessageTypeDefinition
@ -44,9 +48,11 @@ export interface ProtoGrpcType {
RuntimeUInt32: MessageTypeDefinition
SocketAddress: MessageTypeDefinition
SocketOption: MessageTypeDefinition
SocketOptionsOverride: MessageTypeDefinition
TcpKeepalive: MessageTypeDefinition
TrafficDirection: EnumTypeDefinition
TransportSocket: MessageTypeDefinition
TypedExtensionConfig: MessageTypeDefinition
WatchedDirectory: MessageTypeDefinition
}
}
@ -56,7 +62,7 @@ export interface ProtoGrpcType {
v3: {
AdsDummy: MessageTypeDefinition
/**
* See https://github.com/lyft/envoy-api#apis for a description of the role of
* See https://github.com/envoyproxy/envoy-api#apis for a description of the role of
* ADS and how it is intended to be used by a management server. ADS requests
* have the same structure as their singleton xDS counterparts, but can
* multiplex many resource types on a single stream. The type_url in the
@ -68,7 +74,10 @@ export interface ProtoGrpcType {
DeltaDiscoveryResponse: MessageTypeDefinition
DiscoveryRequest: MessageTypeDefinition
DiscoveryResponse: MessageTypeDefinition
DynamicParameterConstraints: MessageTypeDefinition
Resource: MessageTypeDefinition
ResourceLocator: MessageTypeDefinition
ResourceName: MessageTypeDefinition
}
}
}

View File

@ -20,7 +20,6 @@ export interface ProtoGrpcType {
LoadBalancingPolicy: MessageTypeDefinition
OutlierDetection: MessageTypeDefinition
TrackClusterStats: MessageTypeDefinition
UpstreamBindConfig: MessageTypeDefinition
UpstreamConnectionOptions: MessageTypeDefinition
}
}
@ -45,6 +44,7 @@ export interface ProtoGrpcType {
EventServiceConfig: MessageTypeDefinition
Extension: MessageTypeDefinition
ExtensionConfigSource: MessageTypeDefinition
ExtraSourceAddress: MessageTypeDefinition
GrpcProtocolOptions: MessageTypeDefinition
GrpcService: MessageTypeDefinition
HeaderMap: MessageTypeDefinition
@ -52,17 +52,25 @@ export interface ProtoGrpcType {
HeaderValueOption: MessageTypeDefinition
HealthCheck: MessageTypeDefinition
HealthStatus: EnumTypeDefinition
HealthStatusSet: MessageTypeDefinition
Http1ProtocolOptions: MessageTypeDefinition
Http2ProtocolOptions: MessageTypeDefinition
Http3ProtocolOptions: MessageTypeDefinition
HttpProtocolOptions: MessageTypeDefinition
HttpUri: MessageTypeDefinition
KeepaliveSettings: MessageTypeDefinition
KeyValue: MessageTypeDefinition
KeyValueAppend: MessageTypeDefinition
KeyValueMutation: MessageTypeDefinition
Locality: MessageTypeDefinition
Metadata: MessageTypeDefinition
Node: MessageTypeDefinition
PathConfigSource: MessageTypeDefinition
Pipe: MessageTypeDefinition
ProxyProtocolConfig: MessageTypeDefinition
ProxyProtocolPassThroughTLVs: MessageTypeDefinition
QueryParameter: MessageTypeDefinition
QuicKeepAliveSettings: MessageTypeDefinition
QuicProtocolOptions: MessageTypeDefinition
RateLimitSettings: MessageTypeDefinition
RemoteDataSource: MessageTypeDefinition
@ -78,6 +86,7 @@ export interface ProtoGrpcType {
SelfConfigSource: MessageTypeDefinition
SocketAddress: MessageTypeDefinition
SocketOption: MessageTypeDefinition
SocketOptionsOverride: MessageTypeDefinition
TcpKeepalive: MessageTypeDefinition
TcpProtocolOptions: MessageTypeDefinition
TrafficDirection: EnumTypeDefinition
@ -97,6 +106,15 @@ export interface ProtoGrpcType {
}
}
}
extensions: {
clusters: {
aggregate: {
v3: {
ClusterConfig: MessageTypeDefinition
}
}
}
}
type: {
matcher: {
v3: {
@ -106,6 +124,12 @@ export interface ProtoGrpcType {
StringMatcher: MessageTypeDefinition
}
}
metadata: {
v3: {
MetadataKey: MessageTypeDefinition
MetadataKind: MessageTypeDefinition
}
}
v3: {
CodecClientType: EnumTypeDefinition
DoubleRange: MessageTypeDefinition
@ -211,6 +235,7 @@ export interface ProtoGrpcType {
CollectionEntry: MessageTypeDefinition
ContextParams: MessageTypeDefinition
ResourceLocator: MessageTypeDefinition
TypedExtensionConfig: MessageTypeDefinition
}
}
}

View File

@ -11,109 +11,44 @@ export interface ProtoGrpcType {
envoy: {
admin: {
v3: {
BootstrapConfigDump: MessageTypeDefinition
ClientResourceStatus: EnumTypeDefinition
ClustersConfigDump: MessageTypeDefinition
ConfigDump: MessageTypeDefinition
EcdsConfigDump: MessageTypeDefinition
EndpointsConfigDump: MessageTypeDefinition
ListenersConfigDump: MessageTypeDefinition
RoutesConfigDump: MessageTypeDefinition
ScopedRoutesConfigDump: MessageTypeDefinition
SecretsConfigDump: MessageTypeDefinition
UpdateFailureState: MessageTypeDefinition
}
}
annotations: {
}
config: {
accesslog: {
v3: {
AccessLog: MessageTypeDefinition
AccessLogFilter: MessageTypeDefinition
AndFilter: MessageTypeDefinition
ComparisonFilter: MessageTypeDefinition
DurationFilter: MessageTypeDefinition
ExtensionFilter: MessageTypeDefinition
GrpcStatusFilter: MessageTypeDefinition
HeaderFilter: MessageTypeDefinition
MetadataFilter: MessageTypeDefinition
NotHealthCheckFilter: MessageTypeDefinition
OrFilter: MessageTypeDefinition
ResponseFlagFilter: MessageTypeDefinition
RuntimeFilter: MessageTypeDefinition
StatusCodeFilter: MessageTypeDefinition
TraceableFilter: MessageTypeDefinition
}
}
bootstrap: {
v3: {
Admin: MessageTypeDefinition
Bootstrap: MessageTypeDefinition
ClusterManager: MessageTypeDefinition
CustomInlineHeader: MessageTypeDefinition
FatalAction: MessageTypeDefinition
LayeredRuntime: MessageTypeDefinition
Runtime: MessageTypeDefinition
RuntimeLayer: MessageTypeDefinition
Watchdog: MessageTypeDefinition
Watchdogs: MessageTypeDefinition
}
}
cluster: {
v3: {
CircuitBreakers: MessageTypeDefinition
Cluster: MessageTypeDefinition
ClusterCollection: MessageTypeDefinition
Filter: MessageTypeDefinition
LoadBalancingPolicy: MessageTypeDefinition
OutlierDetection: MessageTypeDefinition
TrackClusterStats: MessageTypeDefinition
UpstreamBindConfig: MessageTypeDefinition
UpstreamConnectionOptions: MessageTypeDefinition
}
}
core: {
v3: {
Address: MessageTypeDefinition
AggregatedConfigSource: MessageTypeDefinition
AlternateProtocolsCacheOptions: MessageTypeDefinition
ApiConfigSource: MessageTypeDefinition
ApiVersion: EnumTypeDefinition
AsyncDataSource: MessageTypeDefinition
BackoffStrategy: MessageTypeDefinition
BindConfig: MessageTypeDefinition
BuildVersion: MessageTypeDefinition
CidrRange: MessageTypeDefinition
ConfigSource: MessageTypeDefinition
ControlPlane: MessageTypeDefinition
DataSource: MessageTypeDefinition
DnsResolutionConfig: MessageTypeDefinition
DnsResolverOptions: MessageTypeDefinition
EnvoyInternalAddress: MessageTypeDefinition
EventServiceConfig: MessageTypeDefinition
Extension: MessageTypeDefinition
ExtensionConfigSource: MessageTypeDefinition
GrpcProtocolOptions: MessageTypeDefinition
GrpcService: MessageTypeDefinition
ExtraSourceAddress: MessageTypeDefinition
HeaderMap: MessageTypeDefinition
HeaderValue: MessageTypeDefinition
HeaderValueOption: MessageTypeDefinition
HealthCheck: MessageTypeDefinition
HealthStatus: EnumTypeDefinition
Http1ProtocolOptions: MessageTypeDefinition
Http2ProtocolOptions: MessageTypeDefinition
Http3ProtocolOptions: MessageTypeDefinition
HttpProtocolOptions: MessageTypeDefinition
HttpUri: MessageTypeDefinition
KeepaliveSettings: MessageTypeDefinition
KeyValue: MessageTypeDefinition
KeyValueAppend: MessageTypeDefinition
KeyValueMutation: MessageTypeDefinition
Locality: MessageTypeDefinition
Metadata: MessageTypeDefinition
Node: MessageTypeDefinition
Pipe: MessageTypeDefinition
ProxyProtocolConfig: MessageTypeDefinition
QueryParameter: MessageTypeDefinition
QuicProtocolOptions: MessageTypeDefinition
RateLimitSettings: MessageTypeDefinition
RemoteDataSource: MessageTypeDefinition
RequestMethod: EnumTypeDefinition
RetryPolicy: MessageTypeDefinition
@ -123,114 +58,16 @@ export interface ProtoGrpcType {
RuntimeFractionalPercent: MessageTypeDefinition
RuntimePercent: MessageTypeDefinition
RuntimeUInt32: MessageTypeDefinition
SchemeHeaderTransformation: MessageTypeDefinition
SelfConfigSource: MessageTypeDefinition
SocketAddress: MessageTypeDefinition
SocketOption: MessageTypeDefinition
SocketOptionsOverride: MessageTypeDefinition
TcpKeepalive: MessageTypeDefinition
TcpProtocolOptions: MessageTypeDefinition
TrafficDirection: EnumTypeDefinition
TransportSocket: MessageTypeDefinition
TypedExtensionConfig: MessageTypeDefinition
UdpSocketConfig: MessageTypeDefinition
UpstreamHttpProtocolOptions: MessageTypeDefinition
WatchedDirectory: MessageTypeDefinition
}
}
endpoint: {
v3: {
ClusterLoadAssignment: MessageTypeDefinition
Endpoint: MessageTypeDefinition
LbEndpoint: MessageTypeDefinition
LedsClusterLocalityConfig: MessageTypeDefinition
LocalityLbEndpoints: MessageTypeDefinition
}
}
listener: {
v3: {
ActiveRawUdpListenerConfig: MessageTypeDefinition
ApiListener: MessageTypeDefinition
Filter: MessageTypeDefinition
FilterChain: MessageTypeDefinition
FilterChainMatch: MessageTypeDefinition
Listener: MessageTypeDefinition
ListenerCollection: MessageTypeDefinition
ListenerFilter: MessageTypeDefinition
ListenerFilterChainMatchPredicate: MessageTypeDefinition
QuicProtocolOptions: MessageTypeDefinition
UdpListenerConfig: MessageTypeDefinition
}
}
metrics: {
v3: {
DogStatsdSink: MessageTypeDefinition
HistogramBucketSettings: MessageTypeDefinition
HystrixSink: MessageTypeDefinition
StatsConfig: MessageTypeDefinition
StatsMatcher: MessageTypeDefinition
StatsSink: MessageTypeDefinition
StatsdSink: MessageTypeDefinition
TagSpecifier: MessageTypeDefinition
}
}
overload: {
v3: {
BufferFactoryConfig: MessageTypeDefinition
OverloadAction: MessageTypeDefinition
OverloadManager: MessageTypeDefinition
ResourceMonitor: MessageTypeDefinition
ScaleTimersOverloadActionConfig: MessageTypeDefinition
ScaledTrigger: MessageTypeDefinition
ThresholdTrigger: MessageTypeDefinition
Trigger: MessageTypeDefinition
}
}
route: {
v3: {
CorsPolicy: MessageTypeDefinition
Decorator: MessageTypeDefinition
DirectResponseAction: MessageTypeDefinition
FilterAction: MessageTypeDefinition
FilterConfig: MessageTypeDefinition
HeaderMatcher: MessageTypeDefinition
HedgePolicy: MessageTypeDefinition
InternalRedirectPolicy: MessageTypeDefinition
NonForwardingAction: MessageTypeDefinition
QueryParameterMatcher: MessageTypeDefinition
RateLimit: MessageTypeDefinition
RedirectAction: MessageTypeDefinition
RetryPolicy: MessageTypeDefinition
Route: MessageTypeDefinition
RouteAction: MessageTypeDefinition
RouteMatch: MessageTypeDefinition
Tracing: MessageTypeDefinition
VirtualCluster: MessageTypeDefinition
VirtualHost: MessageTypeDefinition
WeightedCluster: MessageTypeDefinition
}
}
trace: {
v3: {
Tracing: MessageTypeDefinition
}
}
}
extensions: {
transport_sockets: {
tls: {
v3: {
CertificateProviderPluginInstance: MessageTypeDefinition
CertificateValidationContext: MessageTypeDefinition
GenericSecret: MessageTypeDefinition
PrivateKeyProvider: MessageTypeDefinition
SdsSecretConfig: MessageTypeDefinition
Secret: MessageTypeDefinition
TlsCertificate: MessageTypeDefinition
TlsParameters: MessageTypeDefinition
TlsSessionTicketKeys: MessageTypeDefinition
}
}
}
}
service: {
status: {
@ -256,8 +93,8 @@ export interface ProtoGrpcType {
DoubleMatcher: MessageTypeDefinition
ListMatcher: MessageTypeDefinition
ListStringMatcher: MessageTypeDefinition
MetadataMatcher: MessageTypeDefinition
NodeMatcher: MessageTypeDefinition
OrMatcher: MessageTypeDefinition
RegexMatchAndSubstitute: MessageTypeDefinition
RegexMatcher: MessageTypeDefinition
StringMatcher: MessageTypeDefinition
@ -265,19 +102,7 @@ export interface ProtoGrpcType {
ValueMatcher: MessageTypeDefinition
}
}
metadata: {
v3: {
MetadataKey: MessageTypeDefinition
MetadataKind: MessageTypeDefinition
}
}
tracing: {
v3: {
CustomTag: MessageTypeDefinition
}
}
v3: {
CodecClientType: EnumTypeDefinition
DoubleRange: MessageTypeDefinition
FractionalPercent: MessageTypeDefinition
Int32Range: MessageTypeDefinition
@ -300,7 +125,6 @@ export interface ProtoGrpcType {
DescriptorProto: MessageTypeDefinition
DoubleValue: MessageTypeDefinition
Duration: MessageTypeDefinition
Empty: MessageTypeDefinition
EnumDescriptorProto: MessageTypeDefinition
EnumOptions: MessageTypeDefinition
EnumValueDescriptorProto: MessageTypeDefinition
@ -336,7 +160,6 @@ export interface ProtoGrpcType {
udpa: {
annotations: {
FieldMigrateAnnotation: MessageTypeDefinition
FieldSecurityAnnotation: MessageTypeDefinition
FileMigrateAnnotation: MessageTypeDefinition
MigrateAnnotation: MessageTypeDefinition
PackageVersionStatus: EnumTypeDefinition
@ -382,10 +205,8 @@ export interface ProtoGrpcType {
}
core: {
v3: {
Authority: MessageTypeDefinition
CollectionEntry: MessageTypeDefinition
ContextParams: MessageTypeDefinition
ResourceLocator: MessageTypeDefinition
TypedExtensionConfig: MessageTypeDefinition
}
}
}

View File

@ -28,17 +28,26 @@ export interface ProtoGrpcType {
EnvoyInternalAddress: MessageTypeDefinition
EventServiceConfig: MessageTypeDefinition
Extension: MessageTypeDefinition
ExtensionConfigSource: MessageTypeDefinition
ExtraSourceAddress: MessageTypeDefinition
GrpcService: MessageTypeDefinition
HeaderMap: MessageTypeDefinition
HeaderValue: MessageTypeDefinition
HeaderValueOption: MessageTypeDefinition
HealthCheck: MessageTypeDefinition
HealthStatus: EnumTypeDefinition
HealthStatusSet: MessageTypeDefinition
HttpUri: MessageTypeDefinition
KeyValue: MessageTypeDefinition
KeyValueAppend: MessageTypeDefinition
KeyValueMutation: MessageTypeDefinition
Locality: MessageTypeDefinition
Metadata: MessageTypeDefinition
Node: MessageTypeDefinition
PathConfigSource: MessageTypeDefinition
Pipe: MessageTypeDefinition
ProxyProtocolConfig: MessageTypeDefinition
ProxyProtocolPassThroughTLVs: MessageTypeDefinition
QueryParameter: MessageTypeDefinition
RateLimitSettings: MessageTypeDefinition
RemoteDataSource: MessageTypeDefinition
@ -53,9 +62,11 @@ export interface ProtoGrpcType {
SelfConfigSource: MessageTypeDefinition
SocketAddress: MessageTypeDefinition
SocketOption: MessageTypeDefinition
SocketOptionsOverride: MessageTypeDefinition
TcpKeepalive: MessageTypeDefinition
TrafficDirection: EnumTypeDefinition
TransportSocket: MessageTypeDefinition
TypedExtensionConfig: MessageTypeDefinition
WatchedDirectory: MessageTypeDefinition
}
}
@ -180,6 +191,7 @@ export interface ProtoGrpcType {
v3: {
Authority: MessageTypeDefinition
ContextParams: MessageTypeDefinition
TypedExtensionConfig: MessageTypeDefinition
}
}
}

View File

@ -1,32 +0,0 @@
// Original file: deps/envoy-api/envoy/admin/v3/config_dump.proto
import type { Bootstrap as _envoy_config_bootstrap_v3_Bootstrap, Bootstrap__Output as _envoy_config_bootstrap_v3_Bootstrap__Output } from '../../../envoy/config/bootstrap/v3/Bootstrap';
import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp';
/**
* This message describes the bootstrap configuration that Envoy was started with. This includes
* any CLI overrides that were merged. Bootstrap configuration information can be used to recreate
* the static portions of an Envoy configuration by reusing the output as the bootstrap
* configuration for another Envoy.
*/
export interface BootstrapConfigDump {
'bootstrap'?: (_envoy_config_bootstrap_v3_Bootstrap | null);
/**
* The timestamp when the BootstrapConfig was last updated.
*/
'last_updated'?: (_google_protobuf_Timestamp | null);
}
/**
* This message describes the bootstrap configuration that Envoy was started with. This includes
* any CLI overrides that were merged. Bootstrap configuration information can be used to recreate
* the static portions of an Envoy configuration by reusing the output as the bootstrap
* configuration for another Envoy.
*/
export interface BootstrapConfigDump__Output {
'bootstrap': (_envoy_config_bootstrap_v3_Bootstrap__Output | null);
/**
* The timestamp when the BootstrapConfig was last updated.
*/
'last_updated': (_google_protobuf_Timestamp__Output | null);
}

View File

@ -1,20 +1,20 @@
// Original file: deps/envoy-api/envoy/admin/v3/config_dump.proto
// Original file: deps/envoy-api/envoy/admin/v3/config_dump_shared.proto
/**
* Resource status from the view of a xDS client, which tells the synchronization
* status between the xDS client and the xDS server.
*/
export enum ClientResourceStatus {
export const ClientResourceStatus = {
/**
* Resource status is not available/unknown.
*/
UNKNOWN = 0,
UNKNOWN: 'UNKNOWN',
/**
* Client requested this resource but hasn't received any update from management
* server. The client will not fail requests, but will queue them until update
* arrives or the client times out waiting for the resource.
*/
REQUESTED = 1,
REQUESTED: 'REQUESTED',
/**
* This resource has been requested by the client but has either not been
* delivered by the server or was previously delivered by the server and then
@ -22,13 +22,56 @@ export enum ClientResourceStatus {
* information, please refer to the :ref:`"Knowing When a Requested Resource
* Does Not Exist" <xds_protocol_resource_not_existed>` section.
*/
DOES_NOT_EXIST = 2,
DOES_NOT_EXIST: 'DOES_NOT_EXIST',
/**
* Client received this resource and replied with ACK.
*/
ACKED = 3,
ACKED: 'ACKED',
/**
* Client received this resource and replied with NACK.
*/
NACKED = 4,
}
NACKED: 'NACKED',
} as const;
/**
* Resource status from the view of a xDS client, which tells the synchronization
* status between the xDS client and the xDS server.
*/
export type ClientResourceStatus =
/**
* Resource status is not available/unknown.
*/
| 'UNKNOWN'
| 0
/**
* Client requested this resource but hasn't received any update from management
* server. The client will not fail requests, but will queue them until update
* arrives or the client times out waiting for the resource.
*/
| 'REQUESTED'
| 1
/**
* This resource has been requested by the client but has either not been
* delivered by the server or was previously delivered by the server and then
* subsequently removed from resources provided by the server. For more
* information, please refer to the :ref:`"Knowing When a Requested Resource
* Does Not Exist" <xds_protocol_resource_not_existed>` section.
*/
| 'DOES_NOT_EXIST'
| 2
/**
* Client received this resource and replied with ACK.
*/
| 'ACKED'
| 3
/**
* Client received this resource and replied with NACK.
*/
| 'NACKED'
| 4
/**
* Resource status from the view of a xDS client, which tells the synchronization
* status between the xDS client and the xDS server.
*/
export type ClientResourceStatus__Output = typeof ClientResourceStatus[keyof typeof ClientResourceStatus]

View File

@ -1,9 +1,9 @@
// Original file: deps/envoy-api/envoy/admin/v3/config_dump.proto
// Original file: deps/envoy-api/envoy/admin/v3/config_dump_shared.proto
import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any';
import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp';
import type { UpdateFailureState as _envoy_admin_v3_UpdateFailureState, UpdateFailureState__Output as _envoy_admin_v3_UpdateFailureState__Output } from '../../../envoy/admin/v3/UpdateFailureState';
import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus } from '../../../envoy/admin/v3/ClientResourceStatus';
import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus, ClientResourceStatus__Output as _envoy_admin_v3_ClientResourceStatus__Output } from '../../../envoy/admin/v3/ClientResourceStatus';
/**
* Describes a dynamically loaded cluster via the CDS API.
@ -27,7 +27,7 @@ export interface _envoy_admin_v3_ClustersConfigDump_DynamicCluster {
'last_updated'?: (_google_protobuf_Timestamp | null);
/**
* Set if the last update failed, cleared after the next successful update.
* The *error_state* field contains the rejected version of this particular
* The ``error_state`` field contains the rejected version of this particular
* resource along with the reason and timestamp. For successfully updated or
* acknowledged resource, this field should be empty.
* [#not-implemented-hide:]
@ -37,7 +37,7 @@ export interface _envoy_admin_v3_ClustersConfigDump_DynamicCluster {
* The client status of this resource.
* [#not-implemented-hide:]
*/
'client_status'?: (_envoy_admin_v3_ClientResourceStatus | keyof typeof _envoy_admin_v3_ClientResourceStatus);
'client_status'?: (_envoy_admin_v3_ClientResourceStatus);
}
/**
@ -62,7 +62,7 @@ export interface _envoy_admin_v3_ClustersConfigDump_DynamicCluster__Output {
'last_updated': (_google_protobuf_Timestamp__Output | null);
/**
* Set if the last update failed, cleared after the next successful update.
* The *error_state* field contains the rejected version of this particular
* The ``error_state`` field contains the rejected version of this particular
* resource along with the reason and timestamp. For successfully updated or
* acknowledged resource, this field should be empty.
* [#not-implemented-hide:]
@ -72,7 +72,7 @@ export interface _envoy_admin_v3_ClustersConfigDump_DynamicCluster__Output {
* The client status of this resource.
* [#not-implemented-hide:]
*/
'client_status': (keyof typeof _envoy_admin_v3_ClientResourceStatus);
'client_status': (_envoy_admin_v3_ClientResourceStatus__Output);
}
/**

View File

@ -1,65 +0,0 @@
// Original file: deps/envoy-api/envoy/admin/v3/config_dump.proto
import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any';
/**
* The :ref:`/config_dump <operations_admin_interface_config_dump>` admin endpoint uses this wrapper
* message to maintain and serve arbitrary configuration information from any component in Envoy.
*/
export interface ConfigDump {
/**
* This list is serialized and dumped in its entirety at the
* :ref:`/config_dump <operations_admin_interface_config_dump>` endpoint.
*
* The following configurations are currently supported and will be dumped in the order given
* below:
*
* * *bootstrap*: :ref:`BootstrapConfigDump <envoy_v3_api_msg_admin.v3.BootstrapConfigDump>`
* * *clusters*: :ref:`ClustersConfigDump <envoy_v3_api_msg_admin.v3.ClustersConfigDump>`
* * *endpoints*: :ref:`EndpointsConfigDump <envoy_v3_api_msg_admin.v3.EndpointsConfigDump>`
* * *listeners*: :ref:`ListenersConfigDump <envoy_v3_api_msg_admin.v3.ListenersConfigDump>`
* * *scoped_routes*: :ref:`ScopedRoutesConfigDump <envoy_v3_api_msg_admin.v3.ScopedRoutesConfigDump>`
* * *routes*: :ref:`RoutesConfigDump <envoy_v3_api_msg_admin.v3.RoutesConfigDump>`
* * *secrets*: :ref:`SecretsConfigDump <envoy_v3_api_msg_admin.v3.SecretsConfigDump>`
*
* EDS Configuration will only be dumped by using parameter `?include_eds`
*
* You can filter output with the resource and mask query parameters.
* See :ref:`/config_dump?resource={} <operations_admin_interface_config_dump_by_resource>`,
* :ref:`/config_dump?mask={} <operations_admin_interface_config_dump_by_mask>`,
* or :ref:`/config_dump?resource={},mask={}
* <operations_admin_interface_config_dump_by_resource_and_mask>` for more information.
*/
'configs'?: (_google_protobuf_Any)[];
}
/**
* The :ref:`/config_dump <operations_admin_interface_config_dump>` admin endpoint uses this wrapper
* message to maintain and serve arbitrary configuration information from any component in Envoy.
*/
export interface ConfigDump__Output {
/**
* This list is serialized and dumped in its entirety at the
* :ref:`/config_dump <operations_admin_interface_config_dump>` endpoint.
*
* The following configurations are currently supported and will be dumped in the order given
* below:
*
* * *bootstrap*: :ref:`BootstrapConfigDump <envoy_v3_api_msg_admin.v3.BootstrapConfigDump>`
* * *clusters*: :ref:`ClustersConfigDump <envoy_v3_api_msg_admin.v3.ClustersConfigDump>`
* * *endpoints*: :ref:`EndpointsConfigDump <envoy_v3_api_msg_admin.v3.EndpointsConfigDump>`
* * *listeners*: :ref:`ListenersConfigDump <envoy_v3_api_msg_admin.v3.ListenersConfigDump>`
* * *scoped_routes*: :ref:`ScopedRoutesConfigDump <envoy_v3_api_msg_admin.v3.ScopedRoutesConfigDump>`
* * *routes*: :ref:`RoutesConfigDump <envoy_v3_api_msg_admin.v3.RoutesConfigDump>`
* * *secrets*: :ref:`SecretsConfigDump <envoy_v3_api_msg_admin.v3.SecretsConfigDump>`
*
* EDS Configuration will only be dumped by using parameter `?include_eds`
*
* You can filter output with the resource and mask query parameters.
* See :ref:`/config_dump?resource={} <operations_admin_interface_config_dump_by_resource>`,
* :ref:`/config_dump?mask={} <operations_admin_interface_config_dump_by_mask>`,
* or :ref:`/config_dump?resource={},mask={}
* <operations_admin_interface_config_dump_by_resource_and_mask>` for more information.
*/
'configs': (_google_protobuf_Any__Output)[];
}

View File

@ -0,0 +1,100 @@
// Original file: deps/envoy-api/envoy/admin/v3/config_dump_shared.proto
import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any';
import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp';
import type { UpdateFailureState as _envoy_admin_v3_UpdateFailureState, UpdateFailureState__Output as _envoy_admin_v3_UpdateFailureState__Output } from '../../../envoy/admin/v3/UpdateFailureState';
import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus, ClientResourceStatus__Output as _envoy_admin_v3_ClientResourceStatus__Output } from '../../../envoy/admin/v3/ClientResourceStatus';
/**
* [#next-free-field: 6]
*/
export interface _envoy_admin_v3_EcdsConfigDump_EcdsFilterConfig {
/**
* This is the per-resource version information. This version is currently
* taken from the :ref:`version_info
* <envoy_v3_api_field_service.discovery.v3.DiscoveryResponse.version_info>`
* field at the time that the ECDS filter was loaded.
*/
'version_info'?: (string);
/**
* The ECDS filter config.
*/
'ecds_filter'?: (_google_protobuf_Any | null);
/**
* The timestamp when the ECDS filter was last updated.
*/
'last_updated'?: (_google_protobuf_Timestamp | null);
/**
* Set if the last update failed, cleared after the next successful update.
* The ``error_state`` field contains the rejected version of this
* particular resource along with the reason and timestamp. For successfully
* updated or acknowledged resource, this field should be empty.
* [#not-implemented-hide:]
*/
'error_state'?: (_envoy_admin_v3_UpdateFailureState | null);
/**
* The client status of this resource.
* [#not-implemented-hide:]
*/
'client_status'?: (_envoy_admin_v3_ClientResourceStatus);
}
/**
* [#next-free-field: 6]
*/
export interface _envoy_admin_v3_EcdsConfigDump_EcdsFilterConfig__Output {
/**
* This is the per-resource version information. This version is currently
* taken from the :ref:`version_info
* <envoy_v3_api_field_service.discovery.v3.DiscoveryResponse.version_info>`
* field at the time that the ECDS filter was loaded.
*/
'version_info': (string);
/**
* The ECDS filter config.
*/
'ecds_filter': (_google_protobuf_Any__Output | null);
/**
* The timestamp when the ECDS filter was last updated.
*/
'last_updated': (_google_protobuf_Timestamp__Output | null);
/**
* Set if the last update failed, cleared after the next successful update.
* The ``error_state`` field contains the rejected version of this
* particular resource along with the reason and timestamp. For successfully
* updated or acknowledged resource, this field should be empty.
* [#not-implemented-hide:]
*/
'error_state': (_envoy_admin_v3_UpdateFailureState__Output | null);
/**
* The client status of this resource.
* [#not-implemented-hide:]
*/
'client_status': (_envoy_admin_v3_ClientResourceStatus__Output);
}
/**
* Envoy's ECDS service fills this message with all currently extension
* configuration. Extension configuration information can be used to recreate
* an Envoy ECDS listener and HTTP filters as static filters or by returning
* them in ECDS response.
*/
export interface EcdsConfigDump {
/**
* The ECDS filter configs.
*/
'ecds_filters'?: (_envoy_admin_v3_EcdsConfigDump_EcdsFilterConfig)[];
}
/**
* Envoy's ECDS service fills this message with all currently extension
* configuration. Extension configuration information can be used to recreate
* an Envoy ECDS listener and HTTP filters as static filters or by returning
* them in ECDS response.
*/
export interface EcdsConfigDump__Output {
/**
* The ECDS filter configs.
*/
'ecds_filters': (_envoy_admin_v3_EcdsConfigDump_EcdsFilterConfig__Output)[];
}

View File

@ -1,9 +1,9 @@
// Original file: deps/envoy-api/envoy/admin/v3/config_dump.proto
// Original file: deps/envoy-api/envoy/admin/v3/config_dump_shared.proto
import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any';
import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp';
import type { UpdateFailureState as _envoy_admin_v3_UpdateFailureState, UpdateFailureState__Output as _envoy_admin_v3_UpdateFailureState__Output } from '../../../envoy/admin/v3/UpdateFailureState';
import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus } from '../../../envoy/admin/v3/ClientResourceStatus';
import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus, ClientResourceStatus__Output as _envoy_admin_v3_ClientResourceStatus__Output } from '../../../envoy/admin/v3/ClientResourceStatus';
/**
* [#next-free-field: 6]
@ -25,7 +25,7 @@ export interface _envoy_admin_v3_EndpointsConfigDump_DynamicEndpointConfig {
'last_updated'?: (_google_protobuf_Timestamp | null);
/**
* Set if the last update failed, cleared after the next successful update.
* The *error_state* field contains the rejected version of this particular
* The ``error_state`` field contains the rejected version of this particular
* resource along with the reason and timestamp. For successfully updated or
* acknowledged resource, this field should be empty.
* [#not-implemented-hide:]
@ -35,7 +35,7 @@ export interface _envoy_admin_v3_EndpointsConfigDump_DynamicEndpointConfig {
* The client status of this resource.
* [#not-implemented-hide:]
*/
'client_status'?: (_envoy_admin_v3_ClientResourceStatus | keyof typeof _envoy_admin_v3_ClientResourceStatus);
'client_status'?: (_envoy_admin_v3_ClientResourceStatus);
}
/**
@ -58,7 +58,7 @@ export interface _envoy_admin_v3_EndpointsConfigDump_DynamicEndpointConfig__Outp
'last_updated': (_google_protobuf_Timestamp__Output | null);
/**
* Set if the last update failed, cleared after the next successful update.
* The *error_state* field contains the rejected version of this particular
* The ``error_state`` field contains the rejected version of this particular
* resource along with the reason and timestamp. For successfully updated or
* acknowledged resource, this field should be empty.
* [#not-implemented-hide:]
@ -68,7 +68,7 @@ export interface _envoy_admin_v3_EndpointsConfigDump_DynamicEndpointConfig__Outp
* The client status of this resource.
* [#not-implemented-hide:]
*/
'client_status': (keyof typeof _envoy_admin_v3_ClientResourceStatus);
'client_status': (_envoy_admin_v3_ClientResourceStatus__Output);
}
export interface _envoy_admin_v3_EndpointsConfigDump_StaticEndpointConfig {

View File

@ -1,9 +1,9 @@
// Original file: deps/envoy-api/envoy/admin/v3/config_dump.proto
// Original file: deps/envoy-api/envoy/admin/v3/config_dump_shared.proto
import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any';
import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp';
import type { UpdateFailureState as _envoy_admin_v3_UpdateFailureState, UpdateFailureState__Output as _envoy_admin_v3_UpdateFailureState__Output } from '../../../envoy/admin/v3/UpdateFailureState';
import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus } from '../../../envoy/admin/v3/ClientResourceStatus';
import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus, ClientResourceStatus__Output as _envoy_admin_v3_ClientResourceStatus__Output } from '../../../envoy/admin/v3/ClientResourceStatus';
/**
* Describes a dynamically loaded listener via the LDS API.
@ -35,7 +35,7 @@ export interface _envoy_admin_v3_ListenersConfigDump_DynamicListener {
'draining_state'?: (_envoy_admin_v3_ListenersConfigDump_DynamicListenerState | null);
/**
* Set if the last update failed, cleared after the next successful update.
* The *error_state* field contains the rejected version of this particular
* The ``error_state`` field contains the rejected version of this particular
* resource along with the reason and timestamp. For successfully updated or
* acknowledged resource, this field should be empty.
*/
@ -44,7 +44,7 @@ export interface _envoy_admin_v3_ListenersConfigDump_DynamicListener {
* The client status of this resource.
* [#not-implemented-hide:]
*/
'client_status'?: (_envoy_admin_v3_ClientResourceStatus | keyof typeof _envoy_admin_v3_ClientResourceStatus);
'client_status'?: (_envoy_admin_v3_ClientResourceStatus);
}
/**
@ -77,7 +77,7 @@ export interface _envoy_admin_v3_ListenersConfigDump_DynamicListener__Output {
'draining_state': (_envoy_admin_v3_ListenersConfigDump_DynamicListenerState__Output | null);
/**
* Set if the last update failed, cleared after the next successful update.
* The *error_state* field contains the rejected version of this particular
* The ``error_state`` field contains the rejected version of this particular
* resource along with the reason and timestamp. For successfully updated or
* acknowledged resource, this field should be empty.
*/
@ -86,7 +86,7 @@ export interface _envoy_admin_v3_ListenersConfigDump_DynamicListener__Output {
* The client status of this resource.
* [#not-implemented-hide:]
*/
'client_status': (keyof typeof _envoy_admin_v3_ClientResourceStatus);
'client_status': (_envoy_admin_v3_ClientResourceStatus__Output);
}
export interface _envoy_admin_v3_ListenersConfigDump_DynamicListenerState {

View File

@ -1,9 +1,9 @@
// Original file: deps/envoy-api/envoy/admin/v3/config_dump.proto
// Original file: deps/envoy-api/envoy/admin/v3/config_dump_shared.proto
import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any';
import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp';
import type { UpdateFailureState as _envoy_admin_v3_UpdateFailureState, UpdateFailureState__Output as _envoy_admin_v3_UpdateFailureState__Output } from '../../../envoy/admin/v3/UpdateFailureState';
import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus } from '../../../envoy/admin/v3/ClientResourceStatus';
import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus, ClientResourceStatus__Output as _envoy_admin_v3_ClientResourceStatus__Output } from '../../../envoy/admin/v3/ClientResourceStatus';
/**
* [#next-free-field: 6]
@ -25,7 +25,7 @@ export interface _envoy_admin_v3_RoutesConfigDump_DynamicRouteConfig {
'last_updated'?: (_google_protobuf_Timestamp | null);
/**
* Set if the last update failed, cleared after the next successful update.
* The *error_state* field contains the rejected version of this particular
* The ``error_state`` field contains the rejected version of this particular
* resource along with the reason and timestamp. For successfully updated or
* acknowledged resource, this field should be empty.
* [#not-implemented-hide:]
@ -35,7 +35,7 @@ export interface _envoy_admin_v3_RoutesConfigDump_DynamicRouteConfig {
* The client status of this resource.
* [#not-implemented-hide:]
*/
'client_status'?: (_envoy_admin_v3_ClientResourceStatus | keyof typeof _envoy_admin_v3_ClientResourceStatus);
'client_status'?: (_envoy_admin_v3_ClientResourceStatus);
}
/**
@ -58,7 +58,7 @@ export interface _envoy_admin_v3_RoutesConfigDump_DynamicRouteConfig__Output {
'last_updated': (_google_protobuf_Timestamp__Output | null);
/**
* Set if the last update failed, cleared after the next successful update.
* The *error_state* field contains the rejected version of this particular
* The ``error_state`` field contains the rejected version of this particular
* resource along with the reason and timestamp. For successfully updated or
* acknowledged resource, this field should be empty.
* [#not-implemented-hide:]
@ -68,7 +68,7 @@ export interface _envoy_admin_v3_RoutesConfigDump_DynamicRouteConfig__Output {
* The client status of this resource.
* [#not-implemented-hide:]
*/
'client_status': (keyof typeof _envoy_admin_v3_ClientResourceStatus);
'client_status': (_envoy_admin_v3_ClientResourceStatus__Output);
}
export interface _envoy_admin_v3_RoutesConfigDump_StaticRouteConfig {

View File

@ -1,9 +1,9 @@
// Original file: deps/envoy-api/envoy/admin/v3/config_dump.proto
// Original file: deps/envoy-api/envoy/admin/v3/config_dump_shared.proto
import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any';
import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp';
import type { UpdateFailureState as _envoy_admin_v3_UpdateFailureState, UpdateFailureState__Output as _envoy_admin_v3_UpdateFailureState__Output } from '../../../envoy/admin/v3/UpdateFailureState';
import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus } from '../../../envoy/admin/v3/ClientResourceStatus';
import type { ClientResourceStatus as _envoy_admin_v3_ClientResourceStatus, ClientResourceStatus__Output as _envoy_admin_v3_ClientResourceStatus__Output } from '../../../envoy/admin/v3/ClientResourceStatus';
/**
* [#next-free-field: 7]
@ -29,7 +29,7 @@ export interface _envoy_admin_v3_ScopedRoutesConfigDump_DynamicScopedRouteConfig
'last_updated'?: (_google_protobuf_Timestamp | null);
/**
* Set if the last update failed, cleared after the next successful update.
* The *error_state* field contains the rejected version of this particular
* The ``error_state`` field contains the rejected version of this particular
* resource along with the reason and timestamp. For successfully updated or
* acknowledged resource, this field should be empty.
* [#not-implemented-hide:]
@ -39,7 +39,7 @@ export interface _envoy_admin_v3_ScopedRoutesConfigDump_DynamicScopedRouteConfig
* The client status of this resource.
* [#not-implemented-hide:]
*/
'client_status'?: (_envoy_admin_v3_ClientResourceStatus | keyof typeof _envoy_admin_v3_ClientResourceStatus);
'client_status'?: (_envoy_admin_v3_ClientResourceStatus);
}
/**
@ -66,7 +66,7 @@ export interface _envoy_admin_v3_ScopedRoutesConfigDump_DynamicScopedRouteConfig
'last_updated': (_google_protobuf_Timestamp__Output | null);
/**
* Set if the last update failed, cleared after the next successful update.
* The *error_state* field contains the rejected version of this particular
* The ``error_state`` field contains the rejected version of this particular
* resource along with the reason and timestamp. For successfully updated or
* acknowledged resource, this field should be empty.
* [#not-implemented-hide:]
@ -76,7 +76,7 @@ export interface _envoy_admin_v3_ScopedRoutesConfigDump_DynamicScopedRouteConfig
* The client status of this resource.
* [#not-implemented-hide:]
*/
'client_status': (keyof typeof _envoy_admin_v3_ClientResourceStatus);
'client_status': (_envoy_admin_v3_ClientResourceStatus__Output);
}
export interface _envoy_admin_v3_ScopedRoutesConfigDump_InlineScopedRouteConfigs {

Some files were not shown because too many files have changed in this diff Show More