Compare commits
6 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
315a1b0d68 | 3 months ago |
|
|
587ccda86a | 3 months ago |
|
|
67e0103d73 | 3 months ago |
|
|
4479c27035 | 4 months ago |
|
|
1748a485bc | 4 months ago |
|
|
db804407ff | 4 months ago |
@ -0,0 +1,3 @@
|
||||
{
|
||||
"CurrentProjectSetting": null
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
{
|
||||
"ExpandedNodes": [
|
||||
""
|
||||
],
|
||||
"PreviewInSolutionExplorer": false
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@ -0,0 +1,12 @@
|
||||
{
|
||||
"Version": 1,
|
||||
"WorkspaceRootPath": "C:\\Users\\11855\\Desktop\\\u674E\u5B66\u6210\\lvgl\\",
|
||||
"Documents": [],
|
||||
"DocumentGroupContainers": [
|
||||
{
|
||||
"Orientation": 0,
|
||||
"VerticalTabListWidth": 256,
|
||||
"DocumentGroups": []
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
@ -0,0 +1,39 @@
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
.kotlin
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/modules.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/compiler.xml
|
||||
.idea/libraries/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
||||
@ -0,0 +1,3 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" native2AsciiForPropertiesFiles="true" defaultCharsetForPropertiesFiles="UTF-8">
|
||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="ignoredFiles">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$/src/pom.xml" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="openjdk-21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,37 @@
|
||||
// 在后端API中使用
|
||||
const FabricClient = require('./fabric-client');
|
||||
|
||||
// 在评论发布API中调用
|
||||
app.post('/api/reviews', async (req, res) => {
|
||||
const { content, userId, spotId } = req.body;
|
||||
const reviewId = `review_${Date.now()}`;
|
||||
|
||||
const fabricClient = new FabricClient();
|
||||
const result = await fabricClient.submitReview(reviewId, userId, spotId, content);
|
||||
|
||||
if (result.success) {
|
||||
// 同时将评论原文存入传统数据库
|
||||
await saveToDatabase({
|
||||
reviewId,
|
||||
userId,
|
||||
spotId,
|
||||
content,
|
||||
blockchainHash: result.hash,
|
||||
timestamp: new Date()
|
||||
});
|
||||
|
||||
res.json({ success: true, reviewId, blockchainTx: result });
|
||||
} else {
|
||||
res.status(500).json({ success: false, error: result.error });
|
||||
}
|
||||
});
|
||||
|
||||
// 验证评论API
|
||||
app.get('/api/reviews/:reviewId/verify', async (req, res) => {
|
||||
const { reviewId } = req.params;
|
||||
|
||||
const fabricClient = new FabricClient();
|
||||
const result = await fabricClient.verifyReview(reviewId);
|
||||
|
||||
res.json(result);
|
||||
});
|
||||
Binary file not shown.
@ -0,0 +1,44 @@
|
||||
name: "test-network"
|
||||
version: "1.0.0"
|
||||
client:
|
||||
organization: Org1
|
||||
connection:
|
||||
timeout:
|
||||
peer:
|
||||
endorser: 300
|
||||
orderer: 300
|
||||
|
||||
organizations:
|
||||
Org1:
|
||||
mspid: Org1MSP
|
||||
peers:
|
||||
- peer0.org1.example.com
|
||||
|
||||
peers:
|
||||
peer0.org1.example.com:
|
||||
url: grpc://localhost:7051
|
||||
grpcOptions:
|
||||
ssl-target-name-override: peer0.org1.example.com
|
||||
hostnameOverride: peer0.org1.example.com
|
||||
tlsCACerts:
|
||||
path: /home/xwc/go/src/github.com/Pluto200407/fabric-samples/test-network/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
|
||||
|
||||
orderers:
|
||||
orderer.example.com:
|
||||
url: grpc://localhost:7050
|
||||
grpcOptions:
|
||||
ssl-target-name-override: orderer.example.com
|
||||
hostnameOverride: orderer.example.com
|
||||
tlsCACerts:
|
||||
path: /home/xwc/go/src/github.com/Pluto200407/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt
|
||||
|
||||
channels:
|
||||
mychannel:
|
||||
orderers:
|
||||
- orderer.example.com
|
||||
peers:
|
||||
peer0.org1.example.com:
|
||||
endorsingPeer: true
|
||||
chaincodeQuery: true
|
||||
ledgerQuery: true
|
||||
eventSource: true
|
||||
@ -0,0 +1,14 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICKDCCAc+gAwIBAgIQK9NVfDZOlmBcVyjUiapiUTAKBggqhkjOPQQDAjBzMQsw
|
||||
CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy
|
||||
YW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEcMBoGA1UEAxMTY2Eu
|
||||
b3JnMS5leGFtcGxlLmNvbTAeFw0yNTEwMjIxMzIxMDBaFw0zNTEwMjAxMzIxMDBa
|
||||
MGsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T
|
||||
YW4gRnJhbmNpc2NvMQ4wDAYDVQQLEwVhZG1pbjEfMB0GA1UEAwwWQWRtaW5Ab3Jn
|
||||
MS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABEaa37gepfav
|
||||
SVPEKe32Ht1wSKIC7hdgnsunTApTPzSlbIzm2nzMKa9D+F/LQpfis3EOP2papkwZ
|
||||
cAvgQ03SAHqjTTBLMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMCsGA1Ud
|
||||
IwQkMCKAIAYX4WiIwuqeErf3mPxfSCQ2wO0+BvyqHqJXWM0Z7CJaMAoGCCqGSM49
|
||||
BAMCA0cAMEQCIFT05wSs1cG9F/6HTjirylLh5wWJKomVCAJrZPT6v8uQAiBU1GPx
|
||||
3dw1Tb1UoWph4E6Dl2MQfnR0SotQNYzDuWmSdQ==
|
||||
-----END CERTIFICATE-----
|
||||
@ -0,0 +1,5 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8w7OdT3ZqZvP/CEB
|
||||
gkRenrKJClD0L5+s5DXRodoUQBihRANCAARGmt+4HqX2r0lTxCnt9h7dcEiiAu4X
|
||||
YJ7Lp0wKUz80pWyM5tp8zCmvQ/hfy0KX4rNxDj9qWqZMGXAL4ENN0gB6
|
||||
-----END PRIVATE KEY-----
|
||||
@ -0,0 +1,15 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICWTCCAf6gAwIBAgIRANHzUZ6pt3kNGhlU1P+gjSowCgYIKoZIzj0EAwIwdjEL
|
||||
MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG
|
||||
cmFuY2lzY28xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHzAdBgNVBAMTFnRs
|
||||
c2NhLm9yZzEuZXhhbXBsZS5jb20wHhcNMjUxMDIyMTIzOTAwWhcNMzUxMDIwMTIz
|
||||
OTAwWjB2MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UE
|
||||
BxMNU2FuIEZyYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEfMB0G
|
||||
A1UEAxMWdGxzY2Eub3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49
|
||||
AwEHA0IABEWENkbWGmSWJwn0s8KCaObbYAUy7tmkrzYHnx26bAxAIA6sYD+Gzp9y
|
||||
NmWfnZwhAn9SIqBnZjdlU0tG3f/zaRKjbTBrMA4GA1UdDwEB/wQEAwIBpjAdBgNV
|
||||
HSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zApBgNV
|
||||
HQ4EIgQg0J5oiI1lZ8QZss91AC5j5+Fh7s0AHK1Nc1Rcr37+GxIwCgYIKoZIzj0E
|
||||
AwIDSQAwRgIhAPn6z/yWWuS3d47MESUG/VjAbWKNyRVjXRwh7gBwvS48AiEAzS9I
|
||||
d7EV6hDpVcaaiBgQhTJE0IAMoyv6bSJaXZcKkd4=
|
||||
-----END CERTIFICATE-----
|
||||
@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../js-yaml/bin/js-yaml.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../js-yaml/bin/js-yaml.js" "$@"
|
||||
fi
|
||||
@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\js-yaml\bin\js-yaml.js" %*
|
||||
@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../js-yaml/bin/js-yaml.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../js-yaml/bin/js-yaml.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../js-yaml/bin/js-yaml.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../js-yaml/bin/js-yaml.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../@grpc/proto-loader/build/bin/proto-loader-gen-types.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../@grpc/proto-loader/build/bin/proto-loader-gen-types.js" "$@"
|
||||
fi
|
||||
@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\@grpc\proto-loader\build\bin\proto-loader-gen-types.js" %*
|
||||
@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../@grpc/proto-loader/build/bin/proto-loader-gen-types.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../@grpc/proto-loader/build/bin/proto-loader-gen-types.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../@grpc/proto-loader/build/bin/proto-loader-gen-types.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../@grpc/proto-loader/build/bin/proto-loader-gen-types.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
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.
|
||||
@ -0,0 +1,79 @@
|
||||
# Pure JavaScript gRPC Client
|
||||
|
||||
## Installation
|
||||
|
||||
Node 12 is recommended. The exact set of compatible Node versions can be found in the `engines` field of the `package.json` file.
|
||||
|
||||
```sh
|
||||
npm install @grpc/grpc-js
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
Documentation specifically for the `@grpc/grpc-js` package is currently not available. However, [documentation is available for the `grpc` package](https://grpc.github.io/grpc/node/grpc.html), and the two packages contain mostly the same interface. There are a few notable differences, however, and these differences are noted in the "Migrating from grpc" section below.
|
||||
|
||||
## Features
|
||||
|
||||
- Clients
|
||||
- Automatic reconnection
|
||||
- Servers
|
||||
- Streaming
|
||||
- Metadata
|
||||
- Partial compression support: clients can compress and decompress messages, and servers can decompress request messages
|
||||
- Pick first and round robin load balancing policies
|
||||
- Client Interceptors
|
||||
- Connection Keepalives
|
||||
- HTTP Connect support (proxies)
|
||||
|
||||
If you need a feature from the `grpc` package that is not provided by the `@grpc/grpc-js`, please file a feature request with that information.
|
||||
|
||||
This library does not directly handle `.proto` files. To use `.proto` files with this library we recommend using the `@grpc/proto-loader` package.
|
||||
|
||||
## Migrating from [`grpc`](https://www.npmjs.com/package/grpc)
|
||||
|
||||
`@grpc/grpc-js` is almost a drop-in replacement for `grpc`, but you may need to make a few code changes to use it:
|
||||
|
||||
- If you are currently loading `.proto` files using `grpc.load`, that function is not available in this library. You should instead load your `.proto` files using `@grpc/proto-loader` and load the resulting package definition objects into `@grpc/grpc-js` using `grpc.loadPackageDefinition`.
|
||||
- If you are currently loading packages generated by `grpc-tools`, you should instead generate your files using the `generate_package_definition` option in `grpc-tools`, then load the object exported by the generated file into `@grpc/grpc-js` using `grpc.loadPackageDefinition`.
|
||||
- If you have a server and you are using `Server#bind` to bind ports, you will need to use `Server#bindAsync` instead.
|
||||
- If you are using any channel options supported in `grpc` but not supported in `@grpc/grpc-js`, you may need to adjust your code to handle the different behavior. Refer to [the list of supported options](#supported-channel-options) below.
|
||||
- Refer to the [detailed package comparison](https://github.com/grpc/grpc-node/blob/master/PACKAGE-COMPARISON.md) for more details on the differences between `grpc` and `@grpc/grpc-js`.
|
||||
|
||||
## Supported Channel Options
|
||||
Many channel arguments supported in `grpc` are not supported in `@grpc/grpc-js`. The channel arguments supported by `@grpc/grpc-js` are:
|
||||
- `grpc.ssl_target_name_override`
|
||||
- `grpc.primary_user_agent`
|
||||
- `grpc.secondary_user_agent`
|
||||
- `grpc.default_authority`
|
||||
- `grpc.keepalive_time_ms`
|
||||
- `grpc.keepalive_timeout_ms`
|
||||
- `grpc.keepalive_permit_without_calls`
|
||||
- `grpc.service_config`
|
||||
- `grpc.max_concurrent_streams`
|
||||
- `grpc.initial_reconnect_backoff_ms`
|
||||
- `grpc.max_reconnect_backoff_ms`
|
||||
- `grpc.use_local_subchannel_pool`
|
||||
- `grpc.max_send_message_length`
|
||||
- `grpc.max_receive_message_length`
|
||||
- `grpc.enable_http_proxy`
|
||||
- `grpc.default_compression_algorithm`
|
||||
- `grpc.enable_channelz`
|
||||
- `grpc.dns_min_time_between_resolutions_ms`
|
||||
- `grpc.enable_retries`
|
||||
- `grpc.per_rpc_retry_buffer_size`
|
||||
- `grpc.retry_buffer_size`
|
||||
- `grpc.service_config_disable_resolution`
|
||||
- `grpc.client_idle_timeout_ms`
|
||||
- `grpc-node.max_session_memory`
|
||||
- `grpc-node.tls_enable_trace`
|
||||
- `channelOverride`
|
||||
- `channelFactoryOverride`
|
||||
|
||||
## Some Notes on API Guarantees
|
||||
|
||||
The public API of this library follows semantic versioning, with some caveats:
|
||||
|
||||
- Some methods are prefixed with an underscore. These methods are internal and should not be considered part of the public API.
|
||||
- The class `Call` is only exposed due to limitations of TypeScript. It should not be considered part of the public API.
|
||||
- In general, any API that is exposed by this library but is not exposed by the `grpc` library is likely an error and should not be considered part of the public API.
|
||||
- The `grpc.experimental` namespace contains APIs that have not stabilized. Any API in that namespace may break in any minor version update.
|
||||
@ -0,0 +1,85 @@
|
||||
{
|
||||
"name": "@grpc/grpc-js",
|
||||
"version": "1.9.15",
|
||||
"description": "gRPC Library for Node - pure JS implementation",
|
||||
"homepage": "https://grpc.io/",
|
||||
"repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js",
|
||||
"main": "build/src/index.js",
|
||||
"engines": {
|
||||
"node": "^8.13.0 || >=10.10.0"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": {
|
||||
"name": "Google Inc."
|
||||
},
|
||||
"types": "build/src/index.d.ts",
|
||||
"license": "Apache-2.0",
|
||||
"devDependencies": {
|
||||
"@types/gulp": "^4.0.6",
|
||||
"@types/gulp-mocha": "0.0.32",
|
||||
"@types/lodash": "^4.14.186",
|
||||
"@types/mocha": "^5.2.6",
|
||||
"@types/ncp": "^2.0.1",
|
||||
"@types/pify": "^3.0.2",
|
||||
"@types/semver": "^7.3.9",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.11",
|
||||
"@typescript-eslint/parser": "^5.59.11",
|
||||
"@typescript-eslint/typescript-estree": "^5.59.11",
|
||||
"clang-format": "^1.0.55",
|
||||
"eslint": "^8.42.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"execa": "^2.0.3",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-mocha": "^6.0.0",
|
||||
"lodash": "^4.17.4",
|
||||
"madge": "^5.0.1",
|
||||
"mocha-jenkins-reporter": "^0.4.1",
|
||||
"ncp": "^2.0.0",
|
||||
"pify": "^4.0.1",
|
||||
"prettier": "^2.8.8",
|
||||
"rimraf": "^3.0.2",
|
||||
"semver": "^7.3.5",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^5.1.3"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Google Inc."
|
||||
}
|
||||
],
|
||||
"scripts": {
|
||||
"build": "npm run compile",
|
||||
"clean": "rimraf ./build",
|
||||
"compile": "tsc -p .",
|
||||
"format": "clang-format -i -style=\"{Language: JavaScript, BasedOnStyle: Google, ColumnLimit: 80}\" src/*.ts test/*.ts",
|
||||
"lint": "eslint src/*.ts test/*.ts",
|
||||
"prepare": "npm run generate-types && npm run compile",
|
||||
"test": "gulp test",
|
||||
"check": "npm run lint",
|
||||
"fix": "eslint --fix src/*.ts test/*.ts",
|
||||
"pretest": "npm run generate-types && npm run generate-test-types && npm run compile",
|
||||
"posttest": "npm run check && madge -c ./build/src",
|
||||
"generate-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --includeDirs proto/ --include-dirs test/fixtures/ -O src/generated/ --grpcLib ../index channelz.proto",
|
||||
"generate-test-types": "proto-loader-gen-types --keepCase --longs String --enums String --defaults --oneofs --includeComments --include-dirs test/fixtures/ -O test/generated/ --grpcLib ../../src/index test_service.proto"
|
||||
},
|
||||
"dependencies": {
|
||||
"@grpc/proto-loader": "^0.7.8",
|
||||
"@types/node": ">=12.12.47"
|
||||
},
|
||||
"files": [
|
||||
"src/**/*.ts",
|
||||
"build/src/**/*.{js,d.ts,js.map}",
|
||||
"proto/*.proto",
|
||||
"LICENSE",
|
||||
"deps/envoy-api/envoy/api/v2/**/*.proto",
|
||||
"deps/envoy-api/envoy/config/**/*.proto",
|
||||
"deps/envoy-api/envoy/service/**/*.proto",
|
||||
"deps/envoy-api/envoy/type/**/*.proto",
|
||||
"deps/udpa/udpa/**/*.proto",
|
||||
"deps/googleapis/google/api/*.proto",
|
||||
"deps/googleapis/google/rpc/*.proto",
|
||||
"deps/protoc-gen-validate/validate/**/*.proto"
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,564 @@
|
||||
// Copyright 2018 The gRPC Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// This file defines an interface for exporting monitoring information
|
||||
// out of gRPC servers. See the full design at
|
||||
// https://github.com/grpc/proposal/blob/master/A14-channelz.md
|
||||
//
|
||||
// The canonical version of this proto can be found at
|
||||
// https://github.com/grpc/grpc-proto/blob/master/grpc/channelz/v1/channelz.proto
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package grpc.channelz.v1;
|
||||
|
||||
import "google/protobuf/any.proto";
|
||||
import "google/protobuf/duration.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "google/protobuf/wrappers.proto";
|
||||
|
||||
option go_package = "google.golang.org/grpc/channelz/grpc_channelz_v1";
|
||||
option java_multiple_files = true;
|
||||
option java_package = "io.grpc.channelz.v1";
|
||||
option java_outer_classname = "ChannelzProto";
|
||||
|
||||
// Channel is a logical grouping of channels, subchannels, and sockets.
|
||||
message Channel {
|
||||
// The identifier for this channel. This should bet set.
|
||||
ChannelRef ref = 1;
|
||||
// Data specific to this channel.
|
||||
ChannelData data = 2;
|
||||
// At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
|
||||
|
||||
// There are no ordering guarantees on the order of channel refs.
|
||||
// There may not be cycles in the ref graph.
|
||||
// A channel ref may be present in more than one channel or subchannel.
|
||||
repeated ChannelRef channel_ref = 3;
|
||||
|
||||
// At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
|
||||
// There are no ordering guarantees on the order of subchannel refs.
|
||||
// There may not be cycles in the ref graph.
|
||||
// A sub channel ref may be present in more than one channel or subchannel.
|
||||
repeated SubchannelRef subchannel_ref = 4;
|
||||
|
||||
// There are no ordering guarantees on the order of sockets.
|
||||
repeated SocketRef socket_ref = 5;
|
||||
}
|
||||
|
||||
// Subchannel is a logical grouping of channels, subchannels, and sockets.
|
||||
// A subchannel is load balanced over by it's ancestor
|
||||
message Subchannel {
|
||||
// The identifier for this channel.
|
||||
SubchannelRef ref = 1;
|
||||
// Data specific to this channel.
|
||||
ChannelData data = 2;
|
||||
// At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
|
||||
|
||||
// There are no ordering guarantees on the order of channel refs.
|
||||
// There may not be cycles in the ref graph.
|
||||
// A channel ref may be present in more than one channel or subchannel.
|
||||
repeated ChannelRef channel_ref = 3;
|
||||
|
||||
// At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
|
||||
// There are no ordering guarantees on the order of subchannel refs.
|
||||
// There may not be cycles in the ref graph.
|
||||
// A sub channel ref may be present in more than one channel or subchannel.
|
||||
repeated SubchannelRef subchannel_ref = 4;
|
||||
|
||||
// There are no ordering guarantees on the order of sockets.
|
||||
repeated SocketRef socket_ref = 5;
|
||||
}
|
||||
|
||||
// These come from the specified states in this document:
|
||||
// https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md
|
||||
message ChannelConnectivityState {
|
||||
enum State {
|
||||
UNKNOWN = 0;
|
||||
IDLE = 1;
|
||||
CONNECTING = 2;
|
||||
READY = 3;
|
||||
TRANSIENT_FAILURE = 4;
|
||||
SHUTDOWN = 5;
|
||||
}
|
||||
State state = 1;
|
||||
}
|
||||
|
||||
// Channel data is data related to a specific Channel or Subchannel.
|
||||
message ChannelData {
|
||||
// The connectivity state of the channel or subchannel. Implementations
|
||||
// should always set this.
|
||||
ChannelConnectivityState state = 1;
|
||||
|
||||
// The target this channel originally tried to connect to. May be absent
|
||||
string target = 2;
|
||||
|
||||
// A trace of recent events on the channel. May be absent.
|
||||
ChannelTrace trace = 3;
|
||||
|
||||
// The number of calls started on the channel
|
||||
int64 calls_started = 4;
|
||||
// The number of calls that have completed with an OK status
|
||||
int64 calls_succeeded = 5;
|
||||
// The number of calls that have completed with a non-OK status
|
||||
int64 calls_failed = 6;
|
||||
|
||||
// The last time a call was started on the channel.
|
||||
google.protobuf.Timestamp last_call_started_timestamp = 7;
|
||||
}
|
||||
|
||||
// A trace event is an interesting thing that happened to a channel or
|
||||
// subchannel, such as creation, address resolution, subchannel creation, etc.
|
||||
message ChannelTraceEvent {
|
||||
// High level description of the event.
|
||||
string description = 1;
|
||||
// The supported severity levels of trace events.
|
||||
enum Severity {
|
||||
CT_UNKNOWN = 0;
|
||||
CT_INFO = 1;
|
||||
CT_WARNING = 2;
|
||||
CT_ERROR = 3;
|
||||
}
|
||||
// the severity of the trace event
|
||||
Severity severity = 2;
|
||||
// When this event occurred.
|
||||
google.protobuf.Timestamp timestamp = 3;
|
||||
// ref of referenced channel or subchannel.
|
||||
// Optional, only present if this event refers to a child object. For example,
|
||||
// this field would be filled if this trace event was for a subchannel being
|
||||
// created.
|
||||
oneof child_ref {
|
||||
ChannelRef channel_ref = 4;
|
||||
SubchannelRef subchannel_ref = 5;
|
||||
}
|
||||
}
|
||||
|
||||
// ChannelTrace represents the recent events that have occurred on the channel.
|
||||
message ChannelTrace {
|
||||
// Number of events ever logged in this tracing object. This can differ from
|
||||
// events.size() because events can be overwritten or garbage collected by
|
||||
// implementations.
|
||||
int64 num_events_logged = 1;
|
||||
// Time that this channel was created.
|
||||
google.protobuf.Timestamp creation_timestamp = 2;
|
||||
// List of events that have occurred on this channel.
|
||||
repeated ChannelTraceEvent events = 3;
|
||||
}
|
||||
|
||||
// ChannelRef is a reference to a Channel.
|
||||
message ChannelRef {
|
||||
// The globally unique id for this channel. Must be a positive number.
|
||||
int64 channel_id = 1;
|
||||
// An optional name associated with the channel.
|
||||
string name = 2;
|
||||
// Intentionally don't use field numbers from other refs.
|
||||
reserved 3, 4, 5, 6, 7, 8;
|
||||
}
|
||||
|
||||
// SubchannelRef is a reference to a Subchannel.
|
||||
message SubchannelRef {
|
||||
// The globally unique id for this subchannel. Must be a positive number.
|
||||
int64 subchannel_id = 7;
|
||||
// An optional name associated with the subchannel.
|
||||
string name = 8;
|
||||
// Intentionally don't use field numbers from other refs.
|
||||
reserved 1, 2, 3, 4, 5, 6;
|
||||
}
|
||||
|
||||
// SocketRef is a reference to a Socket.
|
||||
message SocketRef {
|
||||
// The globally unique id for this socket. Must be a positive number.
|
||||
int64 socket_id = 3;
|
||||
// An optional name associated with the socket.
|
||||
string name = 4;
|
||||
// Intentionally don't use field numbers from other refs.
|
||||
reserved 1, 2, 5, 6, 7, 8;
|
||||
}
|
||||
|
||||
// ServerRef is a reference to a Server.
|
||||
message ServerRef {
|
||||
// A globally unique identifier for this server. Must be a positive number.
|
||||
int64 server_id = 5;
|
||||
// An optional name associated with the server.
|
||||
string name = 6;
|
||||
// Intentionally don't use field numbers from other refs.
|
||||
reserved 1, 2, 3, 4, 7, 8;
|
||||
}
|
||||
|
||||
// Server represents a single server. There may be multiple servers in a single
|
||||
// program.
|
||||
message Server {
|
||||
// The identifier for a Server. This should be set.
|
||||
ServerRef ref = 1;
|
||||
// The associated data of the Server.
|
||||
ServerData data = 2;
|
||||
|
||||
// The sockets that the server is listening on. There are no ordering
|
||||
// guarantees. This may be absent.
|
||||
repeated SocketRef listen_socket = 3;
|
||||
}
|
||||
|
||||
// ServerData is data for a specific Server.
|
||||
message ServerData {
|
||||
// A trace of recent events on the server. May be absent.
|
||||
ChannelTrace trace = 1;
|
||||
|
||||
// The number of incoming calls started on the server
|
||||
int64 calls_started = 2;
|
||||
// The number of incoming calls that have completed with an OK status
|
||||
int64 calls_succeeded = 3;
|
||||
// The number of incoming calls that have a completed with a non-OK status
|
||||
int64 calls_failed = 4;
|
||||
|
||||
// The last time a call was started on the server.
|
||||
google.protobuf.Timestamp last_call_started_timestamp = 5;
|
||||
}
|
||||
|
||||
// Information about an actual connection. Pronounced "sock-ay".
|
||||
message Socket {
|
||||
// The identifier for the Socket.
|
||||
SocketRef ref = 1;
|
||||
|
||||
// Data specific to this Socket.
|
||||
SocketData data = 2;
|
||||
// The locally bound address.
|
||||
Address local = 3;
|
||||
// The remote bound address. May be absent.
|
||||
Address remote = 4;
|
||||
// Security details for this socket. May be absent if not available, or
|
||||
// there is no security on the socket.
|
||||
Security security = 5;
|
||||
|
||||
// Optional, represents the name of the remote endpoint, if different than
|
||||
// the original target name.
|
||||
string remote_name = 6;
|
||||
}
|
||||
|
||||
// SocketData is data associated for a specific Socket. The fields present
|
||||
// are specific to the implementation, so there may be minor differences in
|
||||
// the semantics. (e.g. flow control windows)
|
||||
message SocketData {
|
||||
// The number of streams that have been started.
|
||||
int64 streams_started = 1;
|
||||
// The number of streams that have ended successfully:
|
||||
// On client side, received frame with eos bit set;
|
||||
// On server side, sent frame with eos bit set.
|
||||
int64 streams_succeeded = 2;
|
||||
// The number of streams that have ended unsuccessfully:
|
||||
// On client side, ended without receiving frame with eos bit set;
|
||||
// On server side, ended without sending frame with eos bit set.
|
||||
int64 streams_failed = 3;
|
||||
// The number of grpc messages successfully sent on this socket.
|
||||
int64 messages_sent = 4;
|
||||
// The number of grpc messages received on this socket.
|
||||
int64 messages_received = 5;
|
||||
|
||||
// The number of keep alives sent. This is typically implemented with HTTP/2
|
||||
// ping messages.
|
||||
int64 keep_alives_sent = 6;
|
||||
|
||||
// The last time a stream was created by this endpoint. Usually unset for
|
||||
// servers.
|
||||
google.protobuf.Timestamp last_local_stream_created_timestamp = 7;
|
||||
// The last time a stream was created by the remote endpoint. Usually unset
|
||||
// for clients.
|
||||
google.protobuf.Timestamp last_remote_stream_created_timestamp = 8;
|
||||
|
||||
// The last time a message was sent by this endpoint.
|
||||
google.protobuf.Timestamp last_message_sent_timestamp = 9;
|
||||
// The last time a message was received by this endpoint.
|
||||
google.protobuf.Timestamp last_message_received_timestamp = 10;
|
||||
|
||||
// The amount of window, granted to the local endpoint by the remote endpoint.
|
||||
// This may be slightly out of date due to network latency. This does NOT
|
||||
// include stream level or TCP level flow control info.
|
||||
google.protobuf.Int64Value local_flow_control_window = 11;
|
||||
|
||||
// The amount of window, granted to the remote endpoint by the local endpoint.
|
||||
// This may be slightly out of date due to network latency. This does NOT
|
||||
// include stream level or TCP level flow control info.
|
||||
google.protobuf.Int64Value remote_flow_control_window = 12;
|
||||
|
||||
// Socket options set on this socket. May be absent if 'summary' is set
|
||||
// on GetSocketRequest.
|
||||
repeated SocketOption option = 13;
|
||||
}
|
||||
|
||||
// Address represents the address used to create the socket.
|
||||
message Address {
|
||||
message TcpIpAddress {
|
||||
// Either the IPv4 or IPv6 address in bytes. Will be either 4 bytes or 16
|
||||
// bytes in length.
|
||||
bytes ip_address = 1;
|
||||
// 0-64k, or -1 if not appropriate.
|
||||
int32 port = 2;
|
||||
}
|
||||
// A Unix Domain Socket address.
|
||||
message UdsAddress {
|
||||
string filename = 1;
|
||||
}
|
||||
// An address type not included above.
|
||||
message OtherAddress {
|
||||
// The human readable version of the value. This value should be set.
|
||||
string name = 1;
|
||||
// The actual address message.
|
||||
google.protobuf.Any value = 2;
|
||||
}
|
||||
|
||||
oneof address {
|
||||
TcpIpAddress tcpip_address = 1;
|
||||
UdsAddress uds_address = 2;
|
||||
OtherAddress other_address = 3;
|
||||
}
|
||||
}
|
||||
|
||||
// Security represents details about how secure the socket is.
|
||||
message Security {
|
||||
message Tls {
|
||||
oneof cipher_suite {
|
||||
// The cipher suite name in the RFC 4346 format:
|
||||
// https://tools.ietf.org/html/rfc4346#appendix-C
|
||||
string standard_name = 1;
|
||||
// Some other way to describe the cipher suite if
|
||||
// the RFC 4346 name is not available.
|
||||
string other_name = 2;
|
||||
}
|
||||
// the certificate used by this endpoint.
|
||||
bytes local_certificate = 3;
|
||||
// the certificate used by the remote endpoint.
|
||||
bytes remote_certificate = 4;
|
||||
}
|
||||
message OtherSecurity {
|
||||
// The human readable version of the value.
|
||||
string name = 1;
|
||||
// The actual security details message.
|
||||
google.protobuf.Any value = 2;
|
||||
}
|
||||
oneof model {
|
||||
Tls tls = 1;
|
||||
OtherSecurity other = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// SocketOption represents socket options for a socket. Specifically, these
|
||||
// are the options returned by getsockopt().
|
||||
message SocketOption {
|
||||
// The full name of the socket option. Typically this will be the upper case
|
||||
// name, such as "SO_REUSEPORT".
|
||||
string name = 1;
|
||||
// The human readable value of this socket option. At least one of value or
|
||||
// additional will be set.
|
||||
string value = 2;
|
||||
// Additional data associated with the socket option. At least one of value
|
||||
// or additional will be set.
|
||||
google.protobuf.Any additional = 3;
|
||||
}
|
||||
|
||||
// For use with SocketOption's additional field. This is primarily used for
|
||||
// SO_RCVTIMEO and SO_SNDTIMEO
|
||||
message SocketOptionTimeout {
|
||||
google.protobuf.Duration duration = 1;
|
||||
}
|
||||
|
||||
// For use with SocketOption's additional field. This is primarily used for
|
||||
// SO_LINGER.
|
||||
message SocketOptionLinger {
|
||||
// active maps to `struct linger.l_onoff`
|
||||
bool active = 1;
|
||||
// duration maps to `struct linger.l_linger`
|
||||
google.protobuf.Duration duration = 2;
|
||||
}
|
||||
|
||||
// For use with SocketOption's additional field. Tcp info for
|
||||
// SOL_TCP and TCP_INFO.
|
||||
message SocketOptionTcpInfo {
|
||||
uint32 tcpi_state = 1;
|
||||
|
||||
uint32 tcpi_ca_state = 2;
|
||||
uint32 tcpi_retransmits = 3;
|
||||
uint32 tcpi_probes = 4;
|
||||
uint32 tcpi_backoff = 5;
|
||||
uint32 tcpi_options = 6;
|
||||
uint32 tcpi_snd_wscale = 7;
|
||||
uint32 tcpi_rcv_wscale = 8;
|
||||
|
||||
uint32 tcpi_rto = 9;
|
||||
uint32 tcpi_ato = 10;
|
||||
uint32 tcpi_snd_mss = 11;
|
||||
uint32 tcpi_rcv_mss = 12;
|
||||
|
||||
uint32 tcpi_unacked = 13;
|
||||
uint32 tcpi_sacked = 14;
|
||||
uint32 tcpi_lost = 15;
|
||||
uint32 tcpi_retrans = 16;
|
||||
uint32 tcpi_fackets = 17;
|
||||
|
||||
uint32 tcpi_last_data_sent = 18;
|
||||
uint32 tcpi_last_ack_sent = 19;
|
||||
uint32 tcpi_last_data_recv = 20;
|
||||
uint32 tcpi_last_ack_recv = 21;
|
||||
|
||||
uint32 tcpi_pmtu = 22;
|
||||
uint32 tcpi_rcv_ssthresh = 23;
|
||||
uint32 tcpi_rtt = 24;
|
||||
uint32 tcpi_rttvar = 25;
|
||||
uint32 tcpi_snd_ssthresh = 26;
|
||||
uint32 tcpi_snd_cwnd = 27;
|
||||
uint32 tcpi_advmss = 28;
|
||||
uint32 tcpi_reordering = 29;
|
||||
}
|
||||
|
||||
// Channelz is a service exposed by gRPC servers that provides detailed debug
|
||||
// information.
|
||||
service Channelz {
|
||||
// Gets all root channels (i.e. channels the application has directly
|
||||
// created). This does not include subchannels nor non-top level channels.
|
||||
rpc GetTopChannels(GetTopChannelsRequest) returns (GetTopChannelsResponse);
|
||||
// Gets all servers that exist in the process.
|
||||
rpc GetServers(GetServersRequest) returns (GetServersResponse);
|
||||
// Returns a single Server, or else a NOT_FOUND code.
|
||||
rpc GetServer(GetServerRequest) returns (GetServerResponse);
|
||||
// Gets all server sockets that exist in the process.
|
||||
rpc GetServerSockets(GetServerSocketsRequest) returns (GetServerSocketsResponse);
|
||||
// Returns a single Channel, or else a NOT_FOUND code.
|
||||
rpc GetChannel(GetChannelRequest) returns (GetChannelResponse);
|
||||
// Returns a single Subchannel, or else a NOT_FOUND code.
|
||||
rpc GetSubchannel(GetSubchannelRequest) returns (GetSubchannelResponse);
|
||||
// Returns a single Socket or else a NOT_FOUND code.
|
||||
rpc GetSocket(GetSocketRequest) returns (GetSocketResponse);
|
||||
}
|
||||
|
||||
message GetTopChannelsRequest {
|
||||
// start_channel_id indicates that only channels at or above this id should be
|
||||
// included in the results.
|
||||
// To request the first page, this should be set to 0. To request
|
||||
// subsequent pages, the client generates this value by adding 1 to
|
||||
// the highest seen result ID.
|
||||
int64 start_channel_id = 1;
|
||||
|
||||
// If non-zero, the server will return a page of results containing
|
||||
// at most this many items. If zero, the server will choose a
|
||||
// reasonable page size. Must never be negative.
|
||||
int64 max_results = 2;
|
||||
}
|
||||
|
||||
message GetTopChannelsResponse {
|
||||
// list of channels that the connection detail service knows about. Sorted in
|
||||
// ascending channel_id order.
|
||||
// Must contain at least 1 result, otherwise 'end' must be true.
|
||||
repeated Channel channel = 1;
|
||||
// If set, indicates that the list of channels is the final list. Requesting
|
||||
// more channels can only return more if they are created after this RPC
|
||||
// completes.
|
||||
bool end = 2;
|
||||
}
|
||||
|
||||
message GetServersRequest {
|
||||
// start_server_id indicates that only servers at or above this id should be
|
||||
// included in the results.
|
||||
// To request the first page, this must be set to 0. To request
|
||||
// subsequent pages, the client generates this value by adding 1 to
|
||||
// the highest seen result ID.
|
||||
int64 start_server_id = 1;
|
||||
|
||||
// If non-zero, the server will return a page of results containing
|
||||
// at most this many items. If zero, the server will choose a
|
||||
// reasonable page size. Must never be negative.
|
||||
int64 max_results = 2;
|
||||
}
|
||||
|
||||
message GetServersResponse {
|
||||
// list of servers that the connection detail service knows about. Sorted in
|
||||
// ascending server_id order.
|
||||
// Must contain at least 1 result, otherwise 'end' must be true.
|
||||
repeated Server server = 1;
|
||||
// If set, indicates that the list of servers is the final list. Requesting
|
||||
// more servers will only return more if they are created after this RPC
|
||||
// completes.
|
||||
bool end = 2;
|
||||
}
|
||||
|
||||
message GetServerRequest {
|
||||
// server_id is the identifier of the specific server to get.
|
||||
int64 server_id = 1;
|
||||
}
|
||||
|
||||
message GetServerResponse {
|
||||
// The Server that corresponds to the requested server_id. This field
|
||||
// should be set.
|
||||
Server server = 1;
|
||||
}
|
||||
|
||||
message GetServerSocketsRequest {
|
||||
int64 server_id = 1;
|
||||
// start_socket_id indicates that only sockets at or above this id should be
|
||||
// included in the results.
|
||||
// To request the first page, this must be set to 0. To request
|
||||
// subsequent pages, the client generates this value by adding 1 to
|
||||
// the highest seen result ID.
|
||||
int64 start_socket_id = 2;
|
||||
|
||||
// If non-zero, the server will return a page of results containing
|
||||
// at most this many items. If zero, the server will choose a
|
||||
// reasonable page size. Must never be negative.
|
||||
int64 max_results = 3;
|
||||
}
|
||||
|
||||
message GetServerSocketsResponse {
|
||||
// list of socket refs that the connection detail service knows about. Sorted in
|
||||
// ascending socket_id order.
|
||||
// Must contain at least 1 result, otherwise 'end' must be true.
|
||||
repeated SocketRef socket_ref = 1;
|
||||
// If set, indicates that the list of sockets is the final list. Requesting
|
||||
// more sockets will only return more if they are created after this RPC
|
||||
// completes.
|
||||
bool end = 2;
|
||||
}
|
||||
|
||||
message GetChannelRequest {
|
||||
// channel_id is the identifier of the specific channel to get.
|
||||
int64 channel_id = 1;
|
||||
}
|
||||
|
||||
message GetChannelResponse {
|
||||
// The Channel that corresponds to the requested channel_id. This field
|
||||
// should be set.
|
||||
Channel channel = 1;
|
||||
}
|
||||
|
||||
message GetSubchannelRequest {
|
||||
// subchannel_id is the identifier of the specific subchannel to get.
|
||||
int64 subchannel_id = 1;
|
||||
}
|
||||
|
||||
message GetSubchannelResponse {
|
||||
// The Subchannel that corresponds to the requested subchannel_id. This
|
||||
// field should be set.
|
||||
Subchannel subchannel = 1;
|
||||
}
|
||||
|
||||
message GetSocketRequest {
|
||||
// socket_id is the identifier of the specific socket to get.
|
||||
int64 socket_id = 1;
|
||||
|
||||
// If true, the response will contain only high level information
|
||||
// that is inexpensive to obtain. Fields thay may be omitted are
|
||||
// documented.
|
||||
bool summary = 2;
|
||||
}
|
||||
|
||||
message GetSocketResponse {
|
||||
// The Socket that corresponds to the requested socket_id. This field
|
||||
// should be set.
|
||||
Socket socket = 1;
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2021 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import { ServiceDefinition } from './make-client';
|
||||
import { Server, UntypedServiceImplementation } from './server';
|
||||
|
||||
interface GetServiceDefinition {
|
||||
(): ServiceDefinition;
|
||||
}
|
||||
|
||||
interface GetHandlers {
|
||||
(): UntypedServiceImplementation;
|
||||
}
|
||||
|
||||
const registeredAdminServices: {
|
||||
getServiceDefinition: GetServiceDefinition;
|
||||
getHandlers: GetHandlers;
|
||||
}[] = [];
|
||||
|
||||
export function registerAdminService(
|
||||
getServiceDefinition: GetServiceDefinition,
|
||||
getHandlers: GetHandlers
|
||||
) {
|
||||
registeredAdminServices.push({ getServiceDefinition, getHandlers });
|
||||
}
|
||||
|
||||
export function addAdminServicesToServer(server: Server): void {
|
||||
for (const { getServiceDefinition, getHandlers } of registeredAdminServices) {
|
||||
server.addService(getServiceDefinition(), getHandlers());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright 2019 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
const INITIAL_BACKOFF_MS = 1000;
|
||||
const BACKOFF_MULTIPLIER = 1.6;
|
||||
const MAX_BACKOFF_MS = 120000;
|
||||
const BACKOFF_JITTER = 0.2;
|
||||
|
||||
/**
|
||||
* Get a number uniformly at random in the range [min, max)
|
||||
* @param min
|
||||
* @param max
|
||||
*/
|
||||
function uniformRandom(min: number, max: number) {
|
||||
return Math.random() * (max - min) + min;
|
||||
}
|
||||
|
||||
export interface BackoffOptions {
|
||||
initialDelay?: number;
|
||||
multiplier?: number;
|
||||
jitter?: number;
|
||||
maxDelay?: number;
|
||||
}
|
||||
|
||||
export class BackoffTimeout {
|
||||
/**
|
||||
* The delay time at the start, and after each reset.
|
||||
*/
|
||||
private readonly initialDelay: number = INITIAL_BACKOFF_MS;
|
||||
/**
|
||||
* The exponential backoff multiplier.
|
||||
*/
|
||||
private readonly multiplier: number = BACKOFF_MULTIPLIER;
|
||||
/**
|
||||
* The maximum delay time
|
||||
*/
|
||||
private readonly maxDelay: number = MAX_BACKOFF_MS;
|
||||
/**
|
||||
* The maximum fraction by which the delay time can randomly vary after
|
||||
* applying the multiplier.
|
||||
*/
|
||||
private readonly jitter: number = BACKOFF_JITTER;
|
||||
/**
|
||||
* The delay time for the next time the timer runs.
|
||||
*/
|
||||
private nextDelay: number;
|
||||
/**
|
||||
* The handle of the underlying timer. If running is false, this value refers
|
||||
* to an object representing a timer that has ended, but it can still be
|
||||
* interacted with without error.
|
||||
*/
|
||||
private timerId: NodeJS.Timeout;
|
||||
/**
|
||||
* Indicates whether the timer is currently running.
|
||||
*/
|
||||
private running = false;
|
||||
/**
|
||||
* Indicates whether the timer should keep the Node process running if no
|
||||
* other async operation is doing so.
|
||||
*/
|
||||
private hasRef = true;
|
||||
/**
|
||||
* The time that the currently running timer was started. Only valid if
|
||||
* running is true.
|
||||
*/
|
||||
private startTime: Date = new Date();
|
||||
/**
|
||||
* The approximate time that the currently running timer will end. Only valid
|
||||
* if running is true.
|
||||
*/
|
||||
private endTime: Date = new Date();
|
||||
|
||||
constructor(private callback: () => void, options?: BackoffOptions) {
|
||||
if (options) {
|
||||
if (options.initialDelay) {
|
||||
this.initialDelay = options.initialDelay;
|
||||
}
|
||||
if (options.multiplier) {
|
||||
this.multiplier = options.multiplier;
|
||||
}
|
||||
if (options.jitter) {
|
||||
this.jitter = options.jitter;
|
||||
}
|
||||
if (options.maxDelay) {
|
||||
this.maxDelay = options.maxDelay;
|
||||
}
|
||||
}
|
||||
this.nextDelay = this.initialDelay;
|
||||
this.timerId = setTimeout(() => {}, 0);
|
||||
clearTimeout(this.timerId);
|
||||
}
|
||||
|
||||
private runTimer(delay: number) {
|
||||
this.endTime = this.startTime;
|
||||
this.endTime.setMilliseconds(this.endTime.getMilliseconds() + this.nextDelay);
|
||||
clearTimeout(this.timerId);
|
||||
this.timerId = setTimeout(() => {
|
||||
this.callback();
|
||||
this.running = false;
|
||||
}, delay);
|
||||
if (!this.hasRef) {
|
||||
this.timerId.unref?.();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the callback after the current amount of delay time
|
||||
*/
|
||||
runOnce() {
|
||||
this.running = true;
|
||||
this.startTime = new Date();
|
||||
this.runTimer(this.nextDelay);
|
||||
const nextBackoff = Math.min(
|
||||
this.nextDelay * this.multiplier,
|
||||
this.maxDelay
|
||||
);
|
||||
const jitterMagnitude = nextBackoff * this.jitter;
|
||||
this.nextDelay =
|
||||
nextBackoff + uniformRandom(-jitterMagnitude, jitterMagnitude);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the timer. The callback will not be called until `runOnce` is called
|
||||
* again.
|
||||
*/
|
||||
stop() {
|
||||
clearTimeout(this.timerId);
|
||||
this.running = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the delay time to its initial value. If the timer is still running,
|
||||
* retroactively apply that reset to the current timer.
|
||||
*/
|
||||
reset() {
|
||||
this.nextDelay = this.initialDelay;
|
||||
if (this.running) {
|
||||
const now = new Date();
|
||||
const newEndTime = this.startTime;
|
||||
newEndTime.setMilliseconds(newEndTime.getMilliseconds() + this.nextDelay);
|
||||
clearTimeout(this.timerId);
|
||||
if (now < newEndTime) {
|
||||
this.runTimer(newEndTime.getTime() - now.getTime());
|
||||
} else {
|
||||
this.running = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the timer is currently running.
|
||||
*/
|
||||
isRunning() {
|
||||
return this.running;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set that while the timer is running, it should keep the Node process
|
||||
* running.
|
||||
*/
|
||||
ref() {
|
||||
this.hasRef = true;
|
||||
this.timerId.ref?.();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set that while the timer is running, it should not keep the Node process
|
||||
* running.
|
||||
*/
|
||||
unref() {
|
||||
this.hasRef = false;
|
||||
this.timerId.unref?.();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the approximate timestamp of when the timer will fire. Only valid if
|
||||
* this.isRunning() is true.
|
||||
*/
|
||||
getEndTime() {
|
||||
return this.endTime;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright 2019 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import { Metadata } from './metadata';
|
||||
|
||||
export interface CallMetadataOptions {
|
||||
service_url: string;
|
||||
}
|
||||
|
||||
export type CallMetadataGenerator = (
|
||||
options: CallMetadataOptions,
|
||||
cb: (err: Error | null, metadata?: Metadata) => void
|
||||
) => void;
|
||||
|
||||
// google-auth-library pre-v2.0.0 does not have getRequestHeaders
|
||||
// but has getRequestMetadata, which is deprecated in v2.0.0
|
||||
export interface OldOAuth2Client {
|
||||
getRequestMetadata: (
|
||||
url: string,
|
||||
callback: (
|
||||
err: Error | null,
|
||||
headers?: {
|
||||
[index: string]: string;
|
||||
}
|
||||
) => void
|
||||
) => void;
|
||||
}
|
||||
|
||||
export interface CurrentOAuth2Client {
|
||||
getRequestHeaders: (url?: string) => Promise<{ [index: string]: string }>;
|
||||
}
|
||||
|
||||
export type OAuth2Client = OldOAuth2Client | CurrentOAuth2Client;
|
||||
|
||||
function isCurrentOauth2Client(
|
||||
client: OAuth2Client
|
||||
): client is CurrentOAuth2Client {
|
||||
return (
|
||||
'getRequestHeaders' in client &&
|
||||
typeof client.getRequestHeaders === 'function'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A class that represents a generic method of adding authentication-related
|
||||
* metadata on a per-request basis.
|
||||
*/
|
||||
export abstract class CallCredentials {
|
||||
/**
|
||||
* Asynchronously generates a new Metadata object.
|
||||
* @param options Options used in generating the Metadata object.
|
||||
*/
|
||||
abstract generateMetadata(options: CallMetadataOptions): Promise<Metadata>;
|
||||
/**
|
||||
* Creates a new CallCredentials object from properties of both this and
|
||||
* another CallCredentials object. This object's metadata generator will be
|
||||
* called first.
|
||||
* @param callCredentials The other CallCredentials object.
|
||||
*/
|
||||
abstract compose(callCredentials: CallCredentials): CallCredentials;
|
||||
|
||||
/**
|
||||
* Check whether two call credentials objects are equal. Separate
|
||||
* SingleCallCredentials with identical metadata generator functions are
|
||||
* equal.
|
||||
* @param other The other CallCredentials object to compare with.
|
||||
*/
|
||||
abstract _equals(other: CallCredentials): boolean;
|
||||
|
||||
/**
|
||||
* Creates a new CallCredentials object from a given function that generates
|
||||
* Metadata objects.
|
||||
* @param metadataGenerator A function that accepts a set of options, and
|
||||
* generates a Metadata object based on these options, which is passed back
|
||||
* to the caller via a supplied (err, metadata) callback.
|
||||
*/
|
||||
static createFromMetadataGenerator(
|
||||
metadataGenerator: CallMetadataGenerator
|
||||
): CallCredentials {
|
||||
return new SingleCallCredentials(metadataGenerator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a gRPC credential from a Google credential object.
|
||||
* @param googleCredentials The authentication client to use.
|
||||
* @return The resulting CallCredentials object.
|
||||
*/
|
||||
static createFromGoogleCredential(
|
||||
googleCredentials: OAuth2Client
|
||||
): CallCredentials {
|
||||
return CallCredentials.createFromMetadataGenerator((options, callback) => {
|
||||
let getHeaders: Promise<{ [index: string]: string }>;
|
||||
if (isCurrentOauth2Client(googleCredentials)) {
|
||||
getHeaders = googleCredentials.getRequestHeaders(options.service_url);
|
||||
} else {
|
||||
getHeaders = new Promise((resolve, reject) => {
|
||||
googleCredentials.getRequestMetadata(
|
||||
options.service_url,
|
||||
(err, headers) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
if (!headers) {
|
||||
reject(new Error('Headers not set by metadata plugin'));
|
||||
return;
|
||||
}
|
||||
resolve(headers);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
getHeaders.then(
|
||||
headers => {
|
||||
const metadata = new Metadata();
|
||||
for (const key of Object.keys(headers)) {
|
||||
metadata.add(key, headers[key]);
|
||||
}
|
||||
callback(null, metadata);
|
||||
},
|
||||
err => {
|
||||
callback(err);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
static createEmpty(): CallCredentials {
|
||||
return new EmptyCallCredentials();
|
||||
}
|
||||
}
|
||||
|
||||
class ComposedCallCredentials extends CallCredentials {
|
||||
constructor(private creds: CallCredentials[]) {
|
||||
super();
|
||||
}
|
||||
|
||||
async generateMetadata(options: CallMetadataOptions): Promise<Metadata> {
|
||||
const base: Metadata = new Metadata();
|
||||
const generated: Metadata[] = await Promise.all(
|
||||
this.creds.map(cred => cred.generateMetadata(options))
|
||||
);
|
||||
for (const gen of generated) {
|
||||
base.merge(gen);
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
compose(other: CallCredentials): CallCredentials {
|
||||
return new ComposedCallCredentials(this.creds.concat([other]));
|
||||
}
|
||||
|
||||
_equals(other: CallCredentials): boolean {
|
||||
if (this === other) {
|
||||
return true;
|
||||
}
|
||||
if (other instanceof ComposedCallCredentials) {
|
||||
return this.creds.every((value, index) =>
|
||||
value._equals(other.creds[index])
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SingleCallCredentials extends CallCredentials {
|
||||
constructor(private metadataGenerator: CallMetadataGenerator) {
|
||||
super();
|
||||
}
|
||||
|
||||
generateMetadata(options: CallMetadataOptions): Promise<Metadata> {
|
||||
return new Promise<Metadata>((resolve, reject) => {
|
||||
this.metadataGenerator(options, (err, metadata) => {
|
||||
if (metadata !== undefined) {
|
||||
resolve(metadata);
|
||||
} else {
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
compose(other: CallCredentials): CallCredentials {
|
||||
return new ComposedCallCredentials([this, other]);
|
||||
}
|
||||
|
||||
_equals(other: CallCredentials): boolean {
|
||||
if (this === other) {
|
||||
return true;
|
||||
}
|
||||
if (other instanceof SingleCallCredentials) {
|
||||
return this.metadataGenerator === other.metadataGenerator;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class EmptyCallCredentials extends CallCredentials {
|
||||
generateMetadata(options: CallMetadataOptions): Promise<Metadata> {
|
||||
return Promise.resolve(new Metadata());
|
||||
}
|
||||
|
||||
compose(other: CallCredentials): CallCredentials {
|
||||
return other;
|
||||
}
|
||||
|
||||
_equals(other: CallCredentials): boolean {
|
||||
return other instanceof EmptyCallCredentials;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright 2022 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import { CallCredentials } from './call-credentials';
|
||||
import { Status } from './constants';
|
||||
import { Deadline } from './deadline';
|
||||
import { Metadata } from './metadata';
|
||||
import { ServerSurfaceCall } from './server-call';
|
||||
|
||||
export interface CallStreamOptions {
|
||||
deadline: Deadline;
|
||||
flags: number;
|
||||
host: string;
|
||||
parentCall: ServerSurfaceCall | null;
|
||||
}
|
||||
|
||||
export type PartialCallStreamOptions = Partial<CallStreamOptions>;
|
||||
|
||||
export interface StatusObject {
|
||||
code: Status;
|
||||
details: string;
|
||||
metadata: Metadata;
|
||||
}
|
||||
|
||||
export type PartialStatusObject = Pick<StatusObject, 'code' | 'details'> & {
|
||||
metadata: Metadata | null;
|
||||
};
|
||||
|
||||
export const enum WriteFlags {
|
||||
BufferHint = 1,
|
||||
NoCompress = 2,
|
||||
WriteThrough = 4,
|
||||
}
|
||||
|
||||
export interface WriteObject {
|
||||
message: Buffer;
|
||||
flags?: number;
|
||||
}
|
||||
|
||||
export interface MetadataListener {
|
||||
(metadata: Metadata, next: (metadata: Metadata) => void): void;
|
||||
}
|
||||
|
||||
export interface MessageListener {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(message: any, next: (message: any) => void): void;
|
||||
}
|
||||
|
||||
export interface StatusListener {
|
||||
(status: StatusObject, next: (status: StatusObject) => void): void;
|
||||
}
|
||||
|
||||
export interface FullListener {
|
||||
onReceiveMetadata: MetadataListener;
|
||||
onReceiveMessage: MessageListener;
|
||||
onReceiveStatus: StatusListener;
|
||||
}
|
||||
|
||||
export type Listener = Partial<FullListener>;
|
||||
|
||||
/**
|
||||
* An object with methods for handling the responses to a call.
|
||||
*/
|
||||
export interface InterceptingListener {
|
||||
onReceiveMetadata(metadata: Metadata): void;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
onReceiveMessage(message: any): void;
|
||||
onReceiveStatus(status: StatusObject): void;
|
||||
}
|
||||
|
||||
export function isInterceptingListener(
|
||||
listener: Listener | InterceptingListener
|
||||
): listener is InterceptingListener {
|
||||
return (
|
||||
listener.onReceiveMetadata !== undefined &&
|
||||
listener.onReceiveMetadata.length === 1
|
||||
);
|
||||
}
|
||||
|
||||
export class InterceptingListenerImpl implements InterceptingListener {
|
||||
private processingMetadata = false;
|
||||
private hasPendingMessage = false;
|
||||
private pendingMessage: any;
|
||||
private processingMessage = false;
|
||||
private pendingStatus: StatusObject | null = null;
|
||||
constructor(
|
||||
private listener: FullListener,
|
||||
private nextListener: InterceptingListener
|
||||
) {}
|
||||
|
||||
private processPendingMessage() {
|
||||
if (this.hasPendingMessage) {
|
||||
this.nextListener.onReceiveMessage(this.pendingMessage);
|
||||
this.pendingMessage = null;
|
||||
this.hasPendingMessage = false;
|
||||
}
|
||||
}
|
||||
|
||||
private processPendingStatus() {
|
||||
if (this.pendingStatus) {
|
||||
this.nextListener.onReceiveStatus(this.pendingStatus);
|
||||
}
|
||||
}
|
||||
|
||||
onReceiveMetadata(metadata: Metadata): void {
|
||||
this.processingMetadata = true;
|
||||
this.listener.onReceiveMetadata(metadata, metadata => {
|
||||
this.processingMetadata = false;
|
||||
this.nextListener.onReceiveMetadata(metadata);
|
||||
this.processPendingMessage();
|
||||
this.processPendingStatus();
|
||||
});
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
onReceiveMessage(message: any): void {
|
||||
/* If this listener processes messages asynchronously, the last message may
|
||||
* be reordered with respect to the status */
|
||||
this.processingMessage = true;
|
||||
this.listener.onReceiveMessage(message, msg => {
|
||||
this.processingMessage = false;
|
||||
if (this.processingMetadata) {
|
||||
this.pendingMessage = msg;
|
||||
this.hasPendingMessage = true;
|
||||
} else {
|
||||
this.nextListener.onReceiveMessage(msg);
|
||||
this.processPendingStatus();
|
||||
}
|
||||
});
|
||||
}
|
||||
onReceiveStatus(status: StatusObject): void {
|
||||
this.listener.onReceiveStatus(status, processedStatus => {
|
||||
if (this.processingMetadata || this.processingMessage) {
|
||||
this.pendingStatus = processedStatus;
|
||||
} else {
|
||||
this.nextListener.onReceiveStatus(processedStatus);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export interface WriteCallback {
|
||||
(error?: Error | null): void;
|
||||
}
|
||||
|
||||
export interface MessageContext {
|
||||
callback?: WriteCallback;
|
||||
flags?: number;
|
||||
}
|
||||
|
||||
export interface Call {
|
||||
cancelWithStatus(status: Status, details: string): void;
|
||||
getPeer(): string;
|
||||
start(metadata: Metadata, listener: InterceptingListener): void;
|
||||
sendMessageWithContext(context: MessageContext, message: Buffer): void;
|
||||
startRead(): void;
|
||||
halfClose(): void;
|
||||
getCallNumber(): number;
|
||||
setCredentials(credentials: CallCredentials): void;
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2022 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
let nextCallNumber = 0;
|
||||
|
||||
export function getNextCallNumber() {
|
||||
return nextCallNumber++;
|
||||
}
|
||||
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright 2019 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import { EventEmitter } from 'events';
|
||||
import { Duplex, Readable, Writable } from 'stream';
|
||||
|
||||
import { StatusObject, MessageContext } from './call-interface';
|
||||
import { Status } from './constants';
|
||||
import { EmitterAugmentation1 } from './events';
|
||||
import { Metadata } from './metadata';
|
||||
import { ObjectReadable, ObjectWritable, WriteCallback } from './object-stream';
|
||||
import { InterceptingCallInterface } from './client-interceptors';
|
||||
|
||||
/**
|
||||
* A type extending the built-in Error object with additional fields.
|
||||
*/
|
||||
export type ServiceError = StatusObject & Error;
|
||||
|
||||
/**
|
||||
* A base type for all user-facing values returned by client-side method calls.
|
||||
*/
|
||||
export type SurfaceCall = {
|
||||
call?: InterceptingCallInterface;
|
||||
cancel(): void;
|
||||
getPeer(): string;
|
||||
} & EmitterAugmentation1<'metadata', Metadata> &
|
||||
EmitterAugmentation1<'status', StatusObject> &
|
||||
EventEmitter;
|
||||
|
||||
/**
|
||||
* A type representing the return value of a unary method call.
|
||||
*/
|
||||
export type ClientUnaryCall = SurfaceCall;
|
||||
|
||||
/**
|
||||
* A type representing the return value of a server stream method call.
|
||||
*/
|
||||
export type ClientReadableStream<ResponseType> = {
|
||||
deserialize: (chunk: Buffer) => ResponseType;
|
||||
} & SurfaceCall &
|
||||
ObjectReadable<ResponseType>;
|
||||
|
||||
/**
|
||||
* A type representing the return value of a client stream method call.
|
||||
*/
|
||||
export type ClientWritableStream<RequestType> = {
|
||||
serialize: (value: RequestType) => Buffer;
|
||||
} & SurfaceCall &
|
||||
ObjectWritable<RequestType>;
|
||||
|
||||
/**
|
||||
* A type representing the return value of a bidirectional stream method call.
|
||||
*/
|
||||
export type ClientDuplexStream<RequestType, ResponseType> =
|
||||
ClientWritableStream<RequestType> & ClientReadableStream<ResponseType>;
|
||||
|
||||
/**
|
||||
* Construct a ServiceError from a StatusObject. This function exists primarily
|
||||
* as an attempt to make the error stack trace clearly communicate that the
|
||||
* error is not necessarily a problem in gRPC itself.
|
||||
* @param status
|
||||
*/
|
||||
export function callErrorFromStatus(
|
||||
status: StatusObject,
|
||||
callerStack: string
|
||||
): ServiceError {
|
||||
const message = `${status.code} ${Status[status.code]}: ${status.details}`;
|
||||
const error = new Error(message);
|
||||
const stack = `${error.stack}\nfor call at\n${callerStack}`;
|
||||
return Object.assign(new Error(message), status, { stack });
|
||||
}
|
||||
|
||||
export class ClientUnaryCallImpl
|
||||
extends EventEmitter
|
||||
implements ClientUnaryCall
|
||||
{
|
||||
public call?: InterceptingCallInterface;
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
cancel(): void {
|
||||
this.call?.cancelWithStatus(Status.CANCELLED, 'Cancelled on client');
|
||||
}
|
||||
|
||||
getPeer(): string {
|
||||
return this.call?.getPeer() ?? 'unknown';
|
||||
}
|
||||
}
|
||||
|
||||
export class ClientReadableStreamImpl<ResponseType>
|
||||
extends Readable
|
||||
implements ClientReadableStream<ResponseType>
|
||||
{
|
||||
public call?: InterceptingCallInterface;
|
||||
constructor(readonly deserialize: (chunk: Buffer) => ResponseType) {
|
||||
super({ objectMode: true });
|
||||
}
|
||||
|
||||
cancel(): void {
|
||||
this.call?.cancelWithStatus(Status.CANCELLED, 'Cancelled on client');
|
||||
}
|
||||
|
||||
getPeer(): string {
|
||||
return this.call?.getPeer() ?? 'unknown';
|
||||
}
|
||||
|
||||
_read(_size: number): void {
|
||||
this.call?.startRead();
|
||||
}
|
||||
}
|
||||
|
||||
export class ClientWritableStreamImpl<RequestType>
|
||||
extends Writable
|
||||
implements ClientWritableStream<RequestType>
|
||||
{
|
||||
public call?: InterceptingCallInterface;
|
||||
constructor(readonly serialize: (value: RequestType) => Buffer) {
|
||||
super({ objectMode: true });
|
||||
}
|
||||
|
||||
cancel(): void {
|
||||
this.call?.cancelWithStatus(Status.CANCELLED, 'Cancelled on client');
|
||||
}
|
||||
|
||||
getPeer(): string {
|
||||
return this.call?.getPeer() ?? 'unknown';
|
||||
}
|
||||
|
||||
_write(chunk: RequestType, encoding: string, cb: WriteCallback) {
|
||||
const context: MessageContext = {
|
||||
callback: cb,
|
||||
};
|
||||
const flags = Number(encoding);
|
||||
if (!Number.isNaN(flags)) {
|
||||
context.flags = flags;
|
||||
}
|
||||
this.call?.sendMessageWithContext(context, chunk);
|
||||
}
|
||||
|
||||
_final(cb: Function) {
|
||||
this.call?.halfClose();
|
||||
cb();
|
||||
}
|
||||
}
|
||||
|
||||
export class ClientDuplexStreamImpl<RequestType, ResponseType>
|
||||
extends Duplex
|
||||
implements ClientDuplexStream<RequestType, ResponseType>
|
||||
{
|
||||
public call?: InterceptingCallInterface;
|
||||
constructor(
|
||||
readonly serialize: (value: RequestType) => Buffer,
|
||||
readonly deserialize: (chunk: Buffer) => ResponseType
|
||||
) {
|
||||
super({ objectMode: true });
|
||||
}
|
||||
|
||||
cancel(): void {
|
||||
this.call?.cancelWithStatus(Status.CANCELLED, 'Cancelled on client');
|
||||
}
|
||||
|
||||
getPeer(): string {
|
||||
return this.call?.getPeer() ?? 'unknown';
|
||||
}
|
||||
|
||||
_read(_size: number): void {
|
||||
this.call?.startRead();
|
||||
}
|
||||
|
||||
_write(chunk: RequestType, encoding: string, cb: WriteCallback) {
|
||||
const context: MessageContext = {
|
||||
callback: cb,
|
||||
};
|
||||
const flags = Number(encoding);
|
||||
if (!Number.isNaN(flags)) {
|
||||
context.flags = flags;
|
||||
}
|
||||
this.call?.sendMessageWithContext(context, chunk);
|
||||
}
|
||||
|
||||
_final(cb: Function) {
|
||||
this.call?.halfClose();
|
||||
cb();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,267 @@
|
||||
/*
|
||||
* Copyright 2019 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import {
|
||||
ConnectionOptions,
|
||||
createSecureContext,
|
||||
PeerCertificate,
|
||||
SecureContext,
|
||||
} from 'tls';
|
||||
|
||||
import { CallCredentials } from './call-credentials';
|
||||
import { CIPHER_SUITES, getDefaultRootsData } from './tls-helpers';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function verifyIsBufferOrNull(obj: any, friendlyName: string): void {
|
||||
if (obj && !(obj instanceof Buffer)) {
|
||||
throw new TypeError(`${friendlyName}, if provided, must be a Buffer.`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A callback that will receive the expected hostname and presented peer
|
||||
* certificate as parameters. The callback should return an error to
|
||||
* indicate that the presented certificate is considered invalid and
|
||||
* otherwise returned undefined.
|
||||
*/
|
||||
export type CheckServerIdentityCallback = (
|
||||
hostname: string,
|
||||
cert: PeerCertificate
|
||||
) => Error | undefined;
|
||||
|
||||
/**
|
||||
* Additional peer verification options that can be set when creating
|
||||
* SSL credentials.
|
||||
*/
|
||||
export interface VerifyOptions {
|
||||
/**
|
||||
* If set, this callback will be invoked after the usual hostname verification
|
||||
* has been performed on the peer certificate.
|
||||
*/
|
||||
checkServerIdentity?: CheckServerIdentityCallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* A class that contains credentials for communicating over a channel, as well
|
||||
* as a set of per-call credentials, which are applied to every method call made
|
||||
* over a channel initialized with an instance of this class.
|
||||
*/
|
||||
export abstract class ChannelCredentials {
|
||||
protected callCredentials: CallCredentials;
|
||||
|
||||
protected constructor(callCredentials?: CallCredentials) {
|
||||
this.callCredentials = callCredentials || CallCredentials.createEmpty();
|
||||
}
|
||||
/**
|
||||
* Returns a copy of this object with the included set of per-call credentials
|
||||
* expanded to include callCredentials.
|
||||
* @param callCredentials A CallCredentials object to associate with this
|
||||
* instance.
|
||||
*/
|
||||
abstract compose(callCredentials: CallCredentials): ChannelCredentials;
|
||||
|
||||
/**
|
||||
* Gets the set of per-call credentials associated with this instance.
|
||||
*/
|
||||
_getCallCredentials(): CallCredentials {
|
||||
return this.callCredentials;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a SecureContext object generated from input parameters if this
|
||||
* instance was created with createSsl, or null if this instance was created
|
||||
* with createInsecure.
|
||||
*/
|
||||
abstract _getConnectionOptions(): ConnectionOptions | null;
|
||||
|
||||
/**
|
||||
* Indicates whether this credentials object creates a secure channel.
|
||||
*/
|
||||
abstract _isSecure(): boolean;
|
||||
|
||||
/**
|
||||
* Check whether two channel credentials objects are equal. Two secure
|
||||
* credentials are equal if they were constructed with the same parameters.
|
||||
* @param other The other ChannelCredentials Object
|
||||
*/
|
||||
abstract _equals(other: ChannelCredentials): boolean;
|
||||
|
||||
/**
|
||||
* Return a new ChannelCredentials instance with a given set of credentials.
|
||||
* The resulting instance can be used to construct a Channel that communicates
|
||||
* over TLS.
|
||||
* @param rootCerts The root certificate data.
|
||||
* @param privateKey The client certificate private key, if available.
|
||||
* @param certChain The client certificate key chain, if available.
|
||||
* @param verifyOptions Additional options to modify certificate verification
|
||||
*/
|
||||
static createSsl(
|
||||
rootCerts?: Buffer | null,
|
||||
privateKey?: Buffer | null,
|
||||
certChain?: Buffer | null,
|
||||
verifyOptions?: VerifyOptions
|
||||
): ChannelCredentials {
|
||||
verifyIsBufferOrNull(rootCerts, 'Root certificate');
|
||||
verifyIsBufferOrNull(privateKey, 'Private key');
|
||||
verifyIsBufferOrNull(certChain, 'Certificate chain');
|
||||
if (privateKey && !certChain) {
|
||||
throw new Error(
|
||||
'Private key must be given with accompanying certificate chain'
|
||||
);
|
||||
}
|
||||
if (!privateKey && certChain) {
|
||||
throw new Error(
|
||||
'Certificate chain must be given with accompanying private key'
|
||||
);
|
||||
}
|
||||
const secureContext = createSecureContext({
|
||||
ca: rootCerts ?? getDefaultRootsData() ?? undefined,
|
||||
key: privateKey ?? undefined,
|
||||
cert: certChain ?? undefined,
|
||||
ciphers: CIPHER_SUITES,
|
||||
});
|
||||
return new SecureChannelCredentialsImpl(secureContext, verifyOptions ?? {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new ChannelCredentials instance with credentials created using
|
||||
* the provided secureContext. The resulting instances can be used to
|
||||
* construct a Channel that communicates over TLS. gRPC will not override
|
||||
* anything in the provided secureContext, so the environment variables
|
||||
* GRPC_SSL_CIPHER_SUITES and GRPC_DEFAULT_SSL_ROOTS_FILE_PATH will
|
||||
* not be applied.
|
||||
* @param secureContext The return value of tls.createSecureContext()
|
||||
* @param verifyOptions Additional options to modify certificate verification
|
||||
*/
|
||||
static createFromSecureContext(
|
||||
secureContext: SecureContext,
|
||||
verifyOptions?: VerifyOptions
|
||||
): ChannelCredentials {
|
||||
return new SecureChannelCredentialsImpl(secureContext, verifyOptions ?? {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new ChannelCredentials instance with no credentials.
|
||||
*/
|
||||
static createInsecure(): ChannelCredentials {
|
||||
return new InsecureChannelCredentialsImpl();
|
||||
}
|
||||
}
|
||||
|
||||
class InsecureChannelCredentialsImpl extends ChannelCredentials {
|
||||
constructor(callCredentials?: CallCredentials) {
|
||||
super(callCredentials);
|
||||
}
|
||||
|
||||
compose(callCredentials: CallCredentials): never {
|
||||
throw new Error('Cannot compose insecure credentials');
|
||||
}
|
||||
|
||||
_getConnectionOptions(): ConnectionOptions | null {
|
||||
return null;
|
||||
}
|
||||
_isSecure(): boolean {
|
||||
return false;
|
||||
}
|
||||
_equals(other: ChannelCredentials): boolean {
|
||||
return other instanceof InsecureChannelCredentialsImpl;
|
||||
}
|
||||
}
|
||||
|
||||
class SecureChannelCredentialsImpl extends ChannelCredentials {
|
||||
connectionOptions: ConnectionOptions;
|
||||
|
||||
constructor(
|
||||
private secureContext: SecureContext,
|
||||
private verifyOptions: VerifyOptions
|
||||
) {
|
||||
super();
|
||||
this.connectionOptions = {
|
||||
secureContext,
|
||||
};
|
||||
// Node asserts that this option is a function, so we cannot pass undefined
|
||||
if (verifyOptions?.checkServerIdentity) {
|
||||
this.connectionOptions.checkServerIdentity =
|
||||
verifyOptions.checkServerIdentity;
|
||||
}
|
||||
}
|
||||
|
||||
compose(callCredentials: CallCredentials): ChannelCredentials {
|
||||
const combinedCallCredentials =
|
||||
this.callCredentials.compose(callCredentials);
|
||||
return new ComposedChannelCredentialsImpl(this, combinedCallCredentials);
|
||||
}
|
||||
|
||||
_getConnectionOptions(): ConnectionOptions | null {
|
||||
// Copy to prevent callers from mutating this.connectionOptions
|
||||
return { ...this.connectionOptions };
|
||||
}
|
||||
_isSecure(): boolean {
|
||||
return true;
|
||||
}
|
||||
_equals(other: ChannelCredentials): boolean {
|
||||
if (this === other) {
|
||||
return true;
|
||||
}
|
||||
if (other instanceof SecureChannelCredentialsImpl) {
|
||||
return (
|
||||
this.secureContext === other.secureContext &&
|
||||
this.verifyOptions.checkServerIdentity ===
|
||||
other.verifyOptions.checkServerIdentity
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ComposedChannelCredentialsImpl extends ChannelCredentials {
|
||||
constructor(
|
||||
private channelCredentials: SecureChannelCredentialsImpl,
|
||||
callCreds: CallCredentials
|
||||
) {
|
||||
super(callCreds);
|
||||
}
|
||||
compose(callCredentials: CallCredentials) {
|
||||
const combinedCallCredentials =
|
||||
this.callCredentials.compose(callCredentials);
|
||||
return new ComposedChannelCredentialsImpl(
|
||||
this.channelCredentials,
|
||||
combinedCallCredentials
|
||||
);
|
||||
}
|
||||
|
||||
_getConnectionOptions(): ConnectionOptions | null {
|
||||
return this.channelCredentials._getConnectionOptions();
|
||||
}
|
||||
_isSecure(): boolean {
|
||||
return true;
|
||||
}
|
||||
_equals(other: ChannelCredentials): boolean {
|
||||
if (this === other) {
|
||||
return true;
|
||||
}
|
||||
if (other instanceof ComposedChannelCredentialsImpl) {
|
||||
return (
|
||||
this.channelCredentials._equals(other.channelCredentials) &&
|
||||
this.callCredentials._equals(other.callCredentials)
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2019 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import { CompressionAlgorithms } from './compression-algorithms';
|
||||
|
||||
/**
|
||||
* An interface that contains options used when initializing a Channel instance.
|
||||
*/
|
||||
export interface ChannelOptions {
|
||||
'grpc.ssl_target_name_override'?: string;
|
||||
'grpc.primary_user_agent'?: string;
|
||||
'grpc.secondary_user_agent'?: string;
|
||||
'grpc.default_authority'?: string;
|
||||
'grpc.keepalive_time_ms'?: number;
|
||||
'grpc.keepalive_timeout_ms'?: number;
|
||||
'grpc.keepalive_permit_without_calls'?: number;
|
||||
'grpc.service_config'?: string;
|
||||
'grpc.max_concurrent_streams'?: number;
|
||||
'grpc.initial_reconnect_backoff_ms'?: number;
|
||||
'grpc.max_reconnect_backoff_ms'?: number;
|
||||
'grpc.use_local_subchannel_pool'?: number;
|
||||
'grpc.max_send_message_length'?: number;
|
||||
'grpc.max_receive_message_length'?: number;
|
||||
'grpc.enable_http_proxy'?: number;
|
||||
/* http_connect_target and http_connect_creds are used for passing data
|
||||
* around internally, and should not be documented as public-facing options
|
||||
*/
|
||||
'grpc.http_connect_target'?: string;
|
||||
'grpc.http_connect_creds'?: string;
|
||||
'grpc.default_compression_algorithm'?: CompressionAlgorithms;
|
||||
'grpc.enable_channelz'?: number;
|
||||
'grpc.dns_min_time_between_resolutions_ms'?: number;
|
||||
'grpc.enable_retries'?: number;
|
||||
'grpc.per_rpc_retry_buffer_size'?: number;
|
||||
/* This option is pattered like a core option, but the core does not have
|
||||
* this option. It is closely related to the option
|
||||
* grpc.per_rpc_retry_buffer_size, which is in the core. The core will likely
|
||||
* implement this functionality using the ResourceQuota mechanism, so there
|
||||
* will probably not be any collision or other inconsistency. */
|
||||
'grpc.retry_buffer_size'?: number;
|
||||
'grpc.max_connection_age_ms'?: number;
|
||||
'grpc.max_connection_age_grace_ms'?: number;
|
||||
'grpc-node.max_session_memory'?: number;
|
||||
'grpc.service_config_disable_resolution'?: number;
|
||||
'grpc.client_idle_timeout_ms'?: number;
|
||||
/**
|
||||
* Set the enableTrace option in TLS clients and servers
|
||||
*/
|
||||
'grpc-node.tls_enable_trace'?: number;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is for checking provided options at runtime. This is an object for
|
||||
* easier membership checking.
|
||||
*/
|
||||
export const recognizedOptions = {
|
||||
'grpc.ssl_target_name_override': true,
|
||||
'grpc.primary_user_agent': true,
|
||||
'grpc.secondary_user_agent': true,
|
||||
'grpc.default_authority': true,
|
||||
'grpc.keepalive_time_ms': true,
|
||||
'grpc.keepalive_timeout_ms': true,
|
||||
'grpc.keepalive_permit_without_calls': true,
|
||||
'grpc.service_config': true,
|
||||
'grpc.max_concurrent_streams': true,
|
||||
'grpc.initial_reconnect_backoff_ms': true,
|
||||
'grpc.max_reconnect_backoff_ms': true,
|
||||
'grpc.use_local_subchannel_pool': true,
|
||||
'grpc.max_send_message_length': true,
|
||||
'grpc.max_receive_message_length': true,
|
||||
'grpc.enable_http_proxy': true,
|
||||
'grpc.enable_channelz': true,
|
||||
'grpc.dns_min_time_between_resolutions_ms': true,
|
||||
'grpc.enable_retries': true,
|
||||
'grpc.per_rpc_retry_buffer_size': true,
|
||||
'grpc.retry_buffer_size': true,
|
||||
'grpc.max_connection_age_ms': true,
|
||||
'grpc.max_connection_age_grace_ms': true,
|
||||
'grpc-node.max_session_memory': true,
|
||||
'grpc.service_config_disable_resolution': true,
|
||||
'grpc.client_idle_timeout_ms': true,
|
||||
'grpc-node.tls_enable_trace': true,
|
||||
};
|
||||
|
||||
export function channelOptionsEqual(
|
||||
options1: ChannelOptions,
|
||||
options2: ChannelOptions
|
||||
) {
|
||||
const keys1 = Object.keys(options1).sort();
|
||||
const keys2 = Object.keys(options2).sort();
|
||||
if (keys1.length !== keys2.length) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0; i < keys1.length; i += 1) {
|
||||
if (keys1[i] !== keys2[i]) {
|
||||
return false;
|
||||
}
|
||||
if (options1[keys1[i]] !== options2[keys2[i]]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright 2019 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import { ChannelCredentials } from './channel-credentials';
|
||||
import { ChannelOptions } from './channel-options';
|
||||
import { ServerSurfaceCall } from './server-call';
|
||||
|
||||
import { ConnectivityState } from './connectivity-state';
|
||||
import { ChannelRef } from './channelz';
|
||||
import { Call } from './call-interface';
|
||||
import { InternalChannel } from './internal-channel';
|
||||
import { Deadline } from './deadline';
|
||||
|
||||
/**
|
||||
* An interface that represents a communication channel to a server specified
|
||||
* by a given address.
|
||||
*/
|
||||
export interface Channel {
|
||||
/**
|
||||
* Close the channel. This has the same functionality as the existing
|
||||
* grpc.Client.prototype.close
|
||||
*/
|
||||
close(): void;
|
||||
/**
|
||||
* Return the target that this channel connects to
|
||||
*/
|
||||
getTarget(): string;
|
||||
/**
|
||||
* Get the channel's current connectivity state. This method is here mainly
|
||||
* because it is in the existing internal Channel class, and there isn't
|
||||
* another good place to put it.
|
||||
* @param tryToConnect If true, the channel will start connecting if it is
|
||||
* idle. Otherwise, idle channels will only start connecting when a
|
||||
* call starts.
|
||||
*/
|
||||
getConnectivityState(tryToConnect: boolean): ConnectivityState;
|
||||
/**
|
||||
* Watch for connectivity state changes. This is also here mainly because
|
||||
* it is in the existing external Channel class.
|
||||
* @param currentState The state to watch for transitions from. This should
|
||||
* always be populated by calling getConnectivityState immediately
|
||||
* before.
|
||||
* @param deadline A deadline for waiting for a state change
|
||||
* @param callback Called with no error when a state change, or with an
|
||||
* error if the deadline passes without a state change.
|
||||
*/
|
||||
watchConnectivityState(
|
||||
currentState: ConnectivityState,
|
||||
deadline: Date | number,
|
||||
callback: (error?: Error) => void
|
||||
): void;
|
||||
/**
|
||||
* Get the channelz reference object for this channel. A request to the
|
||||
* channelz service for the id in this object will provide information
|
||||
* about this channel.
|
||||
*/
|
||||
getChannelzRef(): ChannelRef;
|
||||
/**
|
||||
* Create a call object. Call is an opaque type that is used by the Client
|
||||
* class. This function is called by the gRPC library when starting a
|
||||
* request. Implementers should return an instance of Call that is returned
|
||||
* from calling createCall on an instance of the provided Channel class.
|
||||
* @param method The full method string to request.
|
||||
* @param deadline The call deadline
|
||||
* @param host A host string override for making the request
|
||||
* @param parentCall A server call to propagate some information from
|
||||
* @param propagateFlags A bitwise combination of elements of grpc.propagate
|
||||
* that indicates what information to propagate from parentCall.
|
||||
*/
|
||||
createCall(
|
||||
method: string,
|
||||
deadline: Deadline,
|
||||
host: string | null | undefined,
|
||||
parentCall: ServerSurfaceCall | null,
|
||||
propagateFlags: number | null | undefined
|
||||
): Call;
|
||||
}
|
||||
|
||||
export class ChannelImplementation implements Channel {
|
||||
private internalChannel: InternalChannel;
|
||||
|
||||
constructor(
|
||||
target: string,
|
||||
credentials: ChannelCredentials,
|
||||
options: ChannelOptions
|
||||
) {
|
||||
if (typeof target !== 'string') {
|
||||
throw new TypeError('Channel target must be a string');
|
||||
}
|
||||
if (!(credentials instanceof ChannelCredentials)) {
|
||||
throw new TypeError(
|
||||
'Channel credentials must be a ChannelCredentials object'
|
||||
);
|
||||
}
|
||||
if (options) {
|
||||
if (typeof options !== 'object') {
|
||||
throw new TypeError('Channel options must be an object');
|
||||
}
|
||||
}
|
||||
|
||||
this.internalChannel = new InternalChannel(target, credentials, options);
|
||||
}
|
||||
|
||||
close() {
|
||||
this.internalChannel.close();
|
||||
}
|
||||
|
||||
getTarget() {
|
||||
return this.internalChannel.getTarget();
|
||||
}
|
||||
|
||||
getConnectivityState(tryToConnect: boolean) {
|
||||
return this.internalChannel.getConnectivityState(tryToConnect);
|
||||
}
|
||||
|
||||
watchConnectivityState(
|
||||
currentState: ConnectivityState,
|
||||
deadline: Date | number,
|
||||
callback: (error?: Error) => void
|
||||
): void {
|
||||
this.internalChannel.watchConnectivityState(
|
||||
currentState,
|
||||
deadline,
|
||||
callback
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channelz reference object for this channel. The returned value is
|
||||
* garbage if channelz is disabled for this channel.
|
||||
* @returns
|
||||
*/
|
||||
getChannelzRef() {
|
||||
return this.internalChannel.getChannelzRef();
|
||||
}
|
||||
|
||||
createCall(
|
||||
method: string,
|
||||
deadline: Deadline,
|
||||
host: string | null | undefined,
|
||||
parentCall: ServerSurfaceCall | null,
|
||||
propagateFlags: number | null | undefined
|
||||
): Call {
|
||||
if (typeof method !== 'string') {
|
||||
throw new TypeError('Channel#createCall: method must be a string');
|
||||
}
|
||||
if (!(typeof deadline === 'number' || deadline instanceof Date)) {
|
||||
throw new TypeError(
|
||||
'Channel#createCall: deadline must be a number or Date'
|
||||
);
|
||||
}
|
||||
return this.internalChannel.createCall(
|
||||
method,
|
||||
deadline,
|
||||
host,
|
||||
parentCall,
|
||||
propagateFlags
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,886 @@
|
||||
/*
|
||||
* Copyright 2021 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import { isIPv4, isIPv6 } from 'net';
|
||||
import { ConnectivityState } from './connectivity-state';
|
||||
import { Status } from './constants';
|
||||
import { Timestamp } from './generated/google/protobuf/Timestamp';
|
||||
import { Channel as ChannelMessage } from './generated/grpc/channelz/v1/Channel';
|
||||
import { ChannelConnectivityState__Output } from './generated/grpc/channelz/v1/ChannelConnectivityState';
|
||||
import { ChannelRef as ChannelRefMessage } from './generated/grpc/channelz/v1/ChannelRef';
|
||||
import { ChannelTrace } from './generated/grpc/channelz/v1/ChannelTrace';
|
||||
import { GetChannelRequest__Output } from './generated/grpc/channelz/v1/GetChannelRequest';
|
||||
import { GetChannelResponse } from './generated/grpc/channelz/v1/GetChannelResponse';
|
||||
import { sendUnaryData, ServerUnaryCall } from './server-call';
|
||||
import { ServerRef as ServerRefMessage } from './generated/grpc/channelz/v1/ServerRef';
|
||||
import { SocketRef as SocketRefMessage } from './generated/grpc/channelz/v1/SocketRef';
|
||||
import {
|
||||
isTcpSubchannelAddress,
|
||||
SubchannelAddress,
|
||||
} from './subchannel-address';
|
||||
import { SubchannelRef as SubchannelRefMessage } from './generated/grpc/channelz/v1/SubchannelRef';
|
||||
import { GetServerRequest__Output } from './generated/grpc/channelz/v1/GetServerRequest';
|
||||
import { GetServerResponse } from './generated/grpc/channelz/v1/GetServerResponse';
|
||||
import { Server as ServerMessage } from './generated/grpc/channelz/v1/Server';
|
||||
import { GetServersRequest__Output } from './generated/grpc/channelz/v1/GetServersRequest';
|
||||
import { GetServersResponse } from './generated/grpc/channelz/v1/GetServersResponse';
|
||||
import { GetTopChannelsRequest__Output } from './generated/grpc/channelz/v1/GetTopChannelsRequest';
|
||||
import { GetTopChannelsResponse } from './generated/grpc/channelz/v1/GetTopChannelsResponse';
|
||||
import { GetSubchannelRequest__Output } from './generated/grpc/channelz/v1/GetSubchannelRequest';
|
||||
import { GetSubchannelResponse } from './generated/grpc/channelz/v1/GetSubchannelResponse';
|
||||
import { Subchannel as SubchannelMessage } from './generated/grpc/channelz/v1/Subchannel';
|
||||
import { GetSocketRequest__Output } from './generated/grpc/channelz/v1/GetSocketRequest';
|
||||
import { GetSocketResponse } from './generated/grpc/channelz/v1/GetSocketResponse';
|
||||
import { Socket as SocketMessage } from './generated/grpc/channelz/v1/Socket';
|
||||
import { Address } from './generated/grpc/channelz/v1/Address';
|
||||
import { Security } from './generated/grpc/channelz/v1/Security';
|
||||
import { GetServerSocketsRequest__Output } from './generated/grpc/channelz/v1/GetServerSocketsRequest';
|
||||
import { GetServerSocketsResponse } from './generated/grpc/channelz/v1/GetServerSocketsResponse';
|
||||
import {
|
||||
ChannelzDefinition,
|
||||
ChannelzHandlers,
|
||||
} from './generated/grpc/channelz/v1/Channelz';
|
||||
import { ProtoGrpcType as ChannelzProtoGrpcType } from './generated/channelz';
|
||||
import type { loadSync } from '@grpc/proto-loader';
|
||||
import { registerAdminService } from './admin';
|
||||
import { loadPackageDefinition } from './make-client';
|
||||
|
||||
export type TraceSeverity =
|
||||
| 'CT_UNKNOWN'
|
||||
| 'CT_INFO'
|
||||
| 'CT_WARNING'
|
||||
| 'CT_ERROR';
|
||||
|
||||
export interface ChannelRef {
|
||||
kind: 'channel';
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface SubchannelRef {
|
||||
kind: 'subchannel';
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface ServerRef {
|
||||
kind: 'server';
|
||||
id: number;
|
||||
}
|
||||
|
||||
export interface SocketRef {
|
||||
kind: 'socket';
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
function channelRefToMessage(ref: ChannelRef): ChannelRefMessage {
|
||||
return {
|
||||
channel_id: ref.id,
|
||||
name: ref.name,
|
||||
};
|
||||
}
|
||||
|
||||
function subchannelRefToMessage(ref: SubchannelRef): SubchannelRefMessage {
|
||||
return {
|
||||
subchannel_id: ref.id,
|
||||
name: ref.name,
|
||||
};
|
||||
}
|
||||
|
||||
function serverRefToMessage(ref: ServerRef): ServerRefMessage {
|
||||
return {
|
||||
server_id: ref.id,
|
||||
};
|
||||
}
|
||||
|
||||
function socketRefToMessage(ref: SocketRef): SocketRefMessage {
|
||||
return {
|
||||
socket_id: ref.id,
|
||||
name: ref.name,
|
||||
};
|
||||
}
|
||||
|
||||
interface TraceEvent {
|
||||
description: string;
|
||||
severity: TraceSeverity;
|
||||
timestamp: Date;
|
||||
childChannel?: ChannelRef;
|
||||
childSubchannel?: SubchannelRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* The loose upper bound on the number of events that should be retained in a
|
||||
* trace. This may be exceeded by up to a factor of 2. Arbitrarily chosen as a
|
||||
* number that should be large enough to contain the recent relevant
|
||||
* information, but small enough to not use excessive memory.
|
||||
*/
|
||||
const TARGET_RETAINED_TRACES = 32;
|
||||
|
||||
export class ChannelzTrace {
|
||||
events: TraceEvent[] = [];
|
||||
creationTimestamp: Date;
|
||||
eventsLogged = 0;
|
||||
|
||||
constructor() {
|
||||
this.creationTimestamp = new Date();
|
||||
}
|
||||
|
||||
addTrace(
|
||||
severity: TraceSeverity,
|
||||
description: string,
|
||||
child?: ChannelRef | SubchannelRef
|
||||
) {
|
||||
const timestamp = new Date();
|
||||
this.events.push({
|
||||
description: description,
|
||||
severity: severity,
|
||||
timestamp: timestamp,
|
||||
childChannel: child?.kind === 'channel' ? child : undefined,
|
||||
childSubchannel: child?.kind === 'subchannel' ? child : undefined,
|
||||
});
|
||||
// Whenever the trace array gets too large, discard the first half
|
||||
if (this.events.length >= TARGET_RETAINED_TRACES * 2) {
|
||||
this.events = this.events.slice(TARGET_RETAINED_TRACES);
|
||||
}
|
||||
this.eventsLogged += 1;
|
||||
}
|
||||
|
||||
getTraceMessage(): ChannelTrace {
|
||||
return {
|
||||
creation_timestamp: dateToProtoTimestamp(this.creationTimestamp),
|
||||
num_events_logged: this.eventsLogged,
|
||||
events: this.events.map(event => {
|
||||
return {
|
||||
description: event.description,
|
||||
severity: event.severity,
|
||||
timestamp: dateToProtoTimestamp(event.timestamp),
|
||||
channel_ref: event.childChannel
|
||||
? channelRefToMessage(event.childChannel)
|
||||
: null,
|
||||
subchannel_ref: event.childSubchannel
|
||||
? subchannelRefToMessage(event.childSubchannel)
|
||||
: null,
|
||||
};
|
||||
}),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class ChannelzChildrenTracker {
|
||||
private channelChildren: Map<number, { ref: ChannelRef; count: number }> =
|
||||
new Map<number, { ref: ChannelRef; count: number }>();
|
||||
private subchannelChildren: Map<
|
||||
number,
|
||||
{ ref: SubchannelRef; count: number }
|
||||
> = new Map<number, { ref: SubchannelRef; count: number }>();
|
||||
private socketChildren: Map<number, { ref: SocketRef; count: number }> =
|
||||
new Map<number, { ref: SocketRef; count: number }>();
|
||||
|
||||
refChild(child: ChannelRef | SubchannelRef | SocketRef) {
|
||||
switch (child.kind) {
|
||||
case 'channel': {
|
||||
const trackedChild = this.channelChildren.get(child.id) ?? {
|
||||
ref: child,
|
||||
count: 0,
|
||||
};
|
||||
trackedChild.count += 1;
|
||||
this.channelChildren.set(child.id, trackedChild);
|
||||
break;
|
||||
}
|
||||
case 'subchannel': {
|
||||
const trackedChild = this.subchannelChildren.get(child.id) ?? {
|
||||
ref: child,
|
||||
count: 0,
|
||||
};
|
||||
trackedChild.count += 1;
|
||||
this.subchannelChildren.set(child.id, trackedChild);
|
||||
break;
|
||||
}
|
||||
case 'socket': {
|
||||
const trackedChild = this.socketChildren.get(child.id) ?? {
|
||||
ref: child,
|
||||
count: 0,
|
||||
};
|
||||
trackedChild.count += 1;
|
||||
this.socketChildren.set(child.id, trackedChild);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unrefChild(child: ChannelRef | SubchannelRef | SocketRef) {
|
||||
switch (child.kind) {
|
||||
case 'channel': {
|
||||
const trackedChild = this.channelChildren.get(child.id);
|
||||
if (trackedChild !== undefined) {
|
||||
trackedChild.count -= 1;
|
||||
if (trackedChild.count === 0) {
|
||||
this.channelChildren.delete(child.id);
|
||||
} else {
|
||||
this.channelChildren.set(child.id, trackedChild);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'subchannel': {
|
||||
const trackedChild = this.subchannelChildren.get(child.id);
|
||||
if (trackedChild !== undefined) {
|
||||
trackedChild.count -= 1;
|
||||
if (trackedChild.count === 0) {
|
||||
this.subchannelChildren.delete(child.id);
|
||||
} else {
|
||||
this.subchannelChildren.set(child.id, trackedChild);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'socket': {
|
||||
const trackedChild = this.socketChildren.get(child.id);
|
||||
if (trackedChild !== undefined) {
|
||||
trackedChild.count -= 1;
|
||||
if (trackedChild.count === 0) {
|
||||
this.socketChildren.delete(child.id);
|
||||
} else {
|
||||
this.socketChildren.set(child.id, trackedChild);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getChildLists(): ChannelzChildren {
|
||||
const channels: ChannelRef[] = [];
|
||||
for (const { ref } of this.channelChildren.values()) {
|
||||
channels.push(ref);
|
||||
}
|
||||
const subchannels: SubchannelRef[] = [];
|
||||
for (const { ref } of this.subchannelChildren.values()) {
|
||||
subchannels.push(ref);
|
||||
}
|
||||
const sockets: SocketRef[] = [];
|
||||
for (const { ref } of this.socketChildren.values()) {
|
||||
sockets.push(ref);
|
||||
}
|
||||
return { channels, subchannels, sockets };
|
||||
}
|
||||
}
|
||||
|
||||
export class ChannelzCallTracker {
|
||||
callsStarted = 0;
|
||||
callsSucceeded = 0;
|
||||
callsFailed = 0;
|
||||
lastCallStartedTimestamp: Date | null = null;
|
||||
|
||||
addCallStarted() {
|
||||
this.callsStarted += 1;
|
||||
this.lastCallStartedTimestamp = new Date();
|
||||
}
|
||||
addCallSucceeded() {
|
||||
this.callsSucceeded += 1;
|
||||
}
|
||||
addCallFailed() {
|
||||
this.callsFailed += 1;
|
||||
}
|
||||
}
|
||||
|
||||
export interface ChannelzChildren {
|
||||
channels: ChannelRef[];
|
||||
subchannels: SubchannelRef[];
|
||||
sockets: SocketRef[];
|
||||
}
|
||||
|
||||
export interface ChannelInfo {
|
||||
target: string;
|
||||
state: ConnectivityState;
|
||||
trace: ChannelzTrace;
|
||||
callTracker: ChannelzCallTracker;
|
||||
children: ChannelzChildren;
|
||||
}
|
||||
|
||||
export type SubchannelInfo = ChannelInfo;
|
||||
|
||||
export interface ServerInfo {
|
||||
trace: ChannelzTrace;
|
||||
callTracker: ChannelzCallTracker;
|
||||
listenerChildren: ChannelzChildren;
|
||||
sessionChildren: ChannelzChildren;
|
||||
}
|
||||
|
||||
export interface TlsInfo {
|
||||
cipherSuiteStandardName: string | null;
|
||||
cipherSuiteOtherName: string | null;
|
||||
localCertificate: Buffer | null;
|
||||
remoteCertificate: Buffer | null;
|
||||
}
|
||||
|
||||
export interface SocketInfo {
|
||||
localAddress: SubchannelAddress | null;
|
||||
remoteAddress: SubchannelAddress | null;
|
||||
security: TlsInfo | null;
|
||||
remoteName: string | null;
|
||||
streamsStarted: number;
|
||||
streamsSucceeded: number;
|
||||
streamsFailed: number;
|
||||
messagesSent: number;
|
||||
messagesReceived: number;
|
||||
keepAlivesSent: number;
|
||||
lastLocalStreamCreatedTimestamp: Date | null;
|
||||
lastRemoteStreamCreatedTimestamp: Date | null;
|
||||
lastMessageSentTimestamp: Date | null;
|
||||
lastMessageReceivedTimestamp: Date | null;
|
||||
localFlowControlWindow: number | null;
|
||||
remoteFlowControlWindow: number | null;
|
||||
}
|
||||
|
||||
interface ChannelEntry {
|
||||
ref: ChannelRef;
|
||||
getInfo(): ChannelInfo;
|
||||
}
|
||||
|
||||
interface SubchannelEntry {
|
||||
ref: SubchannelRef;
|
||||
getInfo(): SubchannelInfo;
|
||||
}
|
||||
|
||||
interface ServerEntry {
|
||||
ref: ServerRef;
|
||||
getInfo(): ServerInfo;
|
||||
}
|
||||
|
||||
interface SocketEntry {
|
||||
ref: SocketRef;
|
||||
getInfo(): SocketInfo;
|
||||
}
|
||||
|
||||
let nextId = 1;
|
||||
|
||||
function getNextId(): number {
|
||||
return nextId++;
|
||||
}
|
||||
|
||||
const channels: (ChannelEntry | undefined)[] = [];
|
||||
const subchannels: (SubchannelEntry | undefined)[] = [];
|
||||
const servers: (ServerEntry | undefined)[] = [];
|
||||
const sockets: (SocketEntry | undefined)[] = [];
|
||||
|
||||
export function registerChannelzChannel(
|
||||
name: string,
|
||||
getInfo: () => ChannelInfo,
|
||||
channelzEnabled: boolean
|
||||
): ChannelRef {
|
||||
const id = getNextId();
|
||||
const ref: ChannelRef = { id, name, kind: 'channel' };
|
||||
if (channelzEnabled) {
|
||||
channels[id] = { ref, getInfo };
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
export function registerChannelzSubchannel(
|
||||
name: string,
|
||||
getInfo: () => SubchannelInfo,
|
||||
channelzEnabled: boolean
|
||||
): SubchannelRef {
|
||||
const id = getNextId();
|
||||
const ref: SubchannelRef = { id, name, kind: 'subchannel' };
|
||||
if (channelzEnabled) {
|
||||
subchannels[id] = { ref, getInfo };
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
export function registerChannelzServer(
|
||||
getInfo: () => ServerInfo,
|
||||
channelzEnabled: boolean
|
||||
): ServerRef {
|
||||
const id = getNextId();
|
||||
const ref: ServerRef = { id, kind: 'server' };
|
||||
if (channelzEnabled) {
|
||||
servers[id] = { ref, getInfo };
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
export function registerChannelzSocket(
|
||||
name: string,
|
||||
getInfo: () => SocketInfo,
|
||||
channelzEnabled: boolean
|
||||
): SocketRef {
|
||||
const id = getNextId();
|
||||
const ref: SocketRef = { id, name, kind: 'socket' };
|
||||
if (channelzEnabled) {
|
||||
sockets[id] = { ref, getInfo };
|
||||
}
|
||||
return ref;
|
||||
}
|
||||
|
||||
export function unregisterChannelzRef(
|
||||
ref: ChannelRef | SubchannelRef | ServerRef | SocketRef
|
||||
) {
|
||||
switch (ref.kind) {
|
||||
case 'channel':
|
||||
delete channels[ref.id];
|
||||
return;
|
||||
case 'subchannel':
|
||||
delete subchannels[ref.id];
|
||||
return;
|
||||
case 'server':
|
||||
delete servers[ref.id];
|
||||
return;
|
||||
case 'socket':
|
||||
delete sockets[ref.id];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a single section of an IPv6 address as two bytes
|
||||
* @param addressSection A hexadecimal string of length up to 4
|
||||
* @returns The pair of bytes representing this address section
|
||||
*/
|
||||
function parseIPv6Section(addressSection: string): [number, number] {
|
||||
const numberValue = Number.parseInt(addressSection, 16);
|
||||
return [(numberValue / 256) | 0, numberValue % 256];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a chunk of an IPv6 address string to some number of bytes
|
||||
* @param addressChunk Some number of segments of up to 4 hexadecimal
|
||||
* characters each, joined by colons.
|
||||
* @returns The list of bytes representing this address chunk
|
||||
*/
|
||||
function parseIPv6Chunk(addressChunk: string): number[] {
|
||||
if (addressChunk === '') {
|
||||
return [];
|
||||
}
|
||||
const bytePairs = addressChunk
|
||||
.split(':')
|
||||
.map(section => parseIPv6Section(section));
|
||||
const result: number[] = [];
|
||||
return result.concat(...bytePairs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an IPv4 or IPv6 address from string representation to binary
|
||||
* representation
|
||||
* @param ipAddress an IP address in standard IPv4 or IPv6 text format
|
||||
* @returns
|
||||
*/
|
||||
function ipAddressStringToBuffer(ipAddress: string): Buffer | null {
|
||||
if (isIPv4(ipAddress)) {
|
||||
return Buffer.from(
|
||||
Uint8Array.from(
|
||||
ipAddress.split('.').map(segment => Number.parseInt(segment))
|
||||
)
|
||||
);
|
||||
} else if (isIPv6(ipAddress)) {
|
||||
let leftSection: string;
|
||||
let rightSection: string;
|
||||
const doubleColonIndex = ipAddress.indexOf('::');
|
||||
if (doubleColonIndex === -1) {
|
||||
leftSection = ipAddress;
|
||||
rightSection = '';
|
||||
} else {
|
||||
leftSection = ipAddress.substring(0, doubleColonIndex);
|
||||
rightSection = ipAddress.substring(doubleColonIndex + 2);
|
||||
}
|
||||
const leftBuffer = Buffer.from(parseIPv6Chunk(leftSection));
|
||||
const rightBuffer = Buffer.from(parseIPv6Chunk(rightSection));
|
||||
const middleBuffer = Buffer.alloc(
|
||||
16 - leftBuffer.length - rightBuffer.length,
|
||||
0
|
||||
);
|
||||
return Buffer.concat([leftBuffer, middleBuffer, rightBuffer]);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function connectivityStateToMessage(
|
||||
state: ConnectivityState
|
||||
): ChannelConnectivityState__Output {
|
||||
switch (state) {
|
||||
case ConnectivityState.CONNECTING:
|
||||
return {
|
||||
state: 'CONNECTING',
|
||||
};
|
||||
case ConnectivityState.IDLE:
|
||||
return {
|
||||
state: 'IDLE',
|
||||
};
|
||||
case ConnectivityState.READY:
|
||||
return {
|
||||
state: 'READY',
|
||||
};
|
||||
case ConnectivityState.SHUTDOWN:
|
||||
return {
|
||||
state: 'SHUTDOWN',
|
||||
};
|
||||
case ConnectivityState.TRANSIENT_FAILURE:
|
||||
return {
|
||||
state: 'TRANSIENT_FAILURE',
|
||||
};
|
||||
default:
|
||||
return {
|
||||
state: 'UNKNOWN',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function dateToProtoTimestamp(date?: Date | null): Timestamp | null {
|
||||
if (!date) {
|
||||
return null;
|
||||
}
|
||||
const millisSinceEpoch = date.getTime();
|
||||
return {
|
||||
seconds: (millisSinceEpoch / 1000) | 0,
|
||||
nanos: (millisSinceEpoch % 1000) * 1_000_000,
|
||||
};
|
||||
}
|
||||
|
||||
function getChannelMessage(channelEntry: ChannelEntry): ChannelMessage {
|
||||
const resolvedInfo = channelEntry.getInfo();
|
||||
return {
|
||||
ref: channelRefToMessage(channelEntry.ref),
|
||||
data: {
|
||||
target: resolvedInfo.target,
|
||||
state: connectivityStateToMessage(resolvedInfo.state),
|
||||
calls_started: resolvedInfo.callTracker.callsStarted,
|
||||
calls_succeeded: resolvedInfo.callTracker.callsSucceeded,
|
||||
calls_failed: resolvedInfo.callTracker.callsFailed,
|
||||
last_call_started_timestamp: dateToProtoTimestamp(
|
||||
resolvedInfo.callTracker.lastCallStartedTimestamp
|
||||
),
|
||||
trace: resolvedInfo.trace.getTraceMessage(),
|
||||
},
|
||||
channel_ref: resolvedInfo.children.channels.map(ref =>
|
||||
channelRefToMessage(ref)
|
||||
),
|
||||
subchannel_ref: resolvedInfo.children.subchannels.map(ref =>
|
||||
subchannelRefToMessage(ref)
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
function GetChannel(
|
||||
call: ServerUnaryCall<GetChannelRequest__Output, GetChannelResponse>,
|
||||
callback: sendUnaryData<GetChannelResponse>
|
||||
): void {
|
||||
const channelId = Number.parseInt(call.request.channel_id);
|
||||
const channelEntry = channels[channelId];
|
||||
if (channelEntry === undefined) {
|
||||
callback({
|
||||
code: Status.NOT_FOUND,
|
||||
details: 'No channel data found for id ' + channelId,
|
||||
});
|
||||
return;
|
||||
}
|
||||
callback(null, { channel: getChannelMessage(channelEntry) });
|
||||
}
|
||||
|
||||
function GetTopChannels(
|
||||
call: ServerUnaryCall<GetTopChannelsRequest__Output, GetTopChannelsResponse>,
|
||||
callback: sendUnaryData<GetTopChannelsResponse>
|
||||
): void {
|
||||
const maxResults = Number.parseInt(call.request.max_results);
|
||||
const resultList: ChannelMessage[] = [];
|
||||
let i = Number.parseInt(call.request.start_channel_id);
|
||||
for (; i < channels.length; i++) {
|
||||
const channelEntry = channels[i];
|
||||
if (channelEntry === undefined) {
|
||||
continue;
|
||||
}
|
||||
resultList.push(getChannelMessage(channelEntry));
|
||||
if (resultList.length >= maxResults) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
callback(null, {
|
||||
channel: resultList,
|
||||
end: i >= servers.length,
|
||||
});
|
||||
}
|
||||
|
||||
function getServerMessage(serverEntry: ServerEntry): ServerMessage {
|
||||
const resolvedInfo = serverEntry.getInfo();
|
||||
return {
|
||||
ref: serverRefToMessage(serverEntry.ref),
|
||||
data: {
|
||||
calls_started: resolvedInfo.callTracker.callsStarted,
|
||||
calls_succeeded: resolvedInfo.callTracker.callsSucceeded,
|
||||
calls_failed: resolvedInfo.callTracker.callsFailed,
|
||||
last_call_started_timestamp: dateToProtoTimestamp(
|
||||
resolvedInfo.callTracker.lastCallStartedTimestamp
|
||||
),
|
||||
trace: resolvedInfo.trace.getTraceMessage(),
|
||||
},
|
||||
listen_socket: resolvedInfo.listenerChildren.sockets.map(ref =>
|
||||
socketRefToMessage(ref)
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
function GetServer(
|
||||
call: ServerUnaryCall<GetServerRequest__Output, GetServerResponse>,
|
||||
callback: sendUnaryData<GetServerResponse>
|
||||
): void {
|
||||
const serverId = Number.parseInt(call.request.server_id);
|
||||
const serverEntry = servers[serverId];
|
||||
if (serverEntry === undefined) {
|
||||
callback({
|
||||
code: Status.NOT_FOUND,
|
||||
details: 'No server data found for id ' + serverId,
|
||||
});
|
||||
return;
|
||||
}
|
||||
callback(null, { server: getServerMessage(serverEntry) });
|
||||
}
|
||||
|
||||
function GetServers(
|
||||
call: ServerUnaryCall<GetServersRequest__Output, GetServersResponse>,
|
||||
callback: sendUnaryData<GetServersResponse>
|
||||
): void {
|
||||
const maxResults = Number.parseInt(call.request.max_results);
|
||||
const resultList: ServerMessage[] = [];
|
||||
let i = Number.parseInt(call.request.start_server_id);
|
||||
for (; i < servers.length; i++) {
|
||||
const serverEntry = servers[i];
|
||||
if (serverEntry === undefined) {
|
||||
continue;
|
||||
}
|
||||
resultList.push(getServerMessage(serverEntry));
|
||||
if (resultList.length >= maxResults) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
callback(null, {
|
||||
server: resultList,
|
||||
end: i >= servers.length,
|
||||
});
|
||||
}
|
||||
|
||||
function GetSubchannel(
|
||||
call: ServerUnaryCall<GetSubchannelRequest__Output, GetSubchannelResponse>,
|
||||
callback: sendUnaryData<GetSubchannelResponse>
|
||||
): void {
|
||||
const subchannelId = Number.parseInt(call.request.subchannel_id);
|
||||
const subchannelEntry = subchannels[subchannelId];
|
||||
if (subchannelEntry === undefined) {
|
||||
callback({
|
||||
code: Status.NOT_FOUND,
|
||||
details: 'No subchannel data found for id ' + subchannelId,
|
||||
});
|
||||
return;
|
||||
}
|
||||
const resolvedInfo = subchannelEntry.getInfo();
|
||||
const subchannelMessage: SubchannelMessage = {
|
||||
ref: subchannelRefToMessage(subchannelEntry.ref),
|
||||
data: {
|
||||
target: resolvedInfo.target,
|
||||
state: connectivityStateToMessage(resolvedInfo.state),
|
||||
calls_started: resolvedInfo.callTracker.callsStarted,
|
||||
calls_succeeded: resolvedInfo.callTracker.callsSucceeded,
|
||||
calls_failed: resolvedInfo.callTracker.callsFailed,
|
||||
last_call_started_timestamp: dateToProtoTimestamp(
|
||||
resolvedInfo.callTracker.lastCallStartedTimestamp
|
||||
),
|
||||
trace: resolvedInfo.trace.getTraceMessage(),
|
||||
},
|
||||
socket_ref: resolvedInfo.children.sockets.map(ref =>
|
||||
socketRefToMessage(ref)
|
||||
),
|
||||
};
|
||||
callback(null, { subchannel: subchannelMessage });
|
||||
}
|
||||
|
||||
function subchannelAddressToAddressMessage(
|
||||
subchannelAddress: SubchannelAddress
|
||||
): Address {
|
||||
if (isTcpSubchannelAddress(subchannelAddress)) {
|
||||
return {
|
||||
address: 'tcpip_address',
|
||||
tcpip_address: {
|
||||
ip_address:
|
||||
ipAddressStringToBuffer(subchannelAddress.host) ?? undefined,
|
||||
port: subchannelAddress.port,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
address: 'uds_address',
|
||||
uds_address: {
|
||||
filename: subchannelAddress.path,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function GetSocket(
|
||||
call: ServerUnaryCall<GetSocketRequest__Output, GetSocketResponse>,
|
||||
callback: sendUnaryData<GetSocketResponse>
|
||||
): void {
|
||||
const socketId = Number.parseInt(call.request.socket_id);
|
||||
const socketEntry = sockets[socketId];
|
||||
if (socketEntry === undefined) {
|
||||
callback({
|
||||
code: Status.NOT_FOUND,
|
||||
details: 'No socket data found for id ' + socketId,
|
||||
});
|
||||
return;
|
||||
}
|
||||
const resolvedInfo = socketEntry.getInfo();
|
||||
const securityMessage: Security | null = resolvedInfo.security
|
||||
? {
|
||||
model: 'tls',
|
||||
tls: {
|
||||
cipher_suite: resolvedInfo.security.cipherSuiteStandardName
|
||||
? 'standard_name'
|
||||
: 'other_name',
|
||||
standard_name:
|
||||
resolvedInfo.security.cipherSuiteStandardName ?? undefined,
|
||||
other_name: resolvedInfo.security.cipherSuiteOtherName ?? undefined,
|
||||
local_certificate:
|
||||
resolvedInfo.security.localCertificate ?? undefined,
|
||||
remote_certificate:
|
||||
resolvedInfo.security.remoteCertificate ?? undefined,
|
||||
},
|
||||
}
|
||||
: null;
|
||||
const socketMessage: SocketMessage = {
|
||||
ref: socketRefToMessage(socketEntry.ref),
|
||||
local: resolvedInfo.localAddress
|
||||
? subchannelAddressToAddressMessage(resolvedInfo.localAddress)
|
||||
: null,
|
||||
remote: resolvedInfo.remoteAddress
|
||||
? subchannelAddressToAddressMessage(resolvedInfo.remoteAddress)
|
||||
: null,
|
||||
remote_name: resolvedInfo.remoteName ?? undefined,
|
||||
security: securityMessage,
|
||||
data: {
|
||||
keep_alives_sent: resolvedInfo.keepAlivesSent,
|
||||
streams_started: resolvedInfo.streamsStarted,
|
||||
streams_succeeded: resolvedInfo.streamsSucceeded,
|
||||
streams_failed: resolvedInfo.streamsFailed,
|
||||
last_local_stream_created_timestamp: dateToProtoTimestamp(
|
||||
resolvedInfo.lastLocalStreamCreatedTimestamp
|
||||
),
|
||||
last_remote_stream_created_timestamp: dateToProtoTimestamp(
|
||||
resolvedInfo.lastRemoteStreamCreatedTimestamp
|
||||
),
|
||||
messages_received: resolvedInfo.messagesReceived,
|
||||
messages_sent: resolvedInfo.messagesSent,
|
||||
last_message_received_timestamp: dateToProtoTimestamp(
|
||||
resolvedInfo.lastMessageReceivedTimestamp
|
||||
),
|
||||
last_message_sent_timestamp: dateToProtoTimestamp(
|
||||
resolvedInfo.lastMessageSentTimestamp
|
||||
),
|
||||
local_flow_control_window: resolvedInfo.localFlowControlWindow
|
||||
? { value: resolvedInfo.localFlowControlWindow }
|
||||
: null,
|
||||
remote_flow_control_window: resolvedInfo.remoteFlowControlWindow
|
||||
? { value: resolvedInfo.remoteFlowControlWindow }
|
||||
: null,
|
||||
},
|
||||
};
|
||||
callback(null, { socket: socketMessage });
|
||||
}
|
||||
|
||||
function GetServerSockets(
|
||||
call: ServerUnaryCall<
|
||||
GetServerSocketsRequest__Output,
|
||||
GetServerSocketsResponse
|
||||
>,
|
||||
callback: sendUnaryData<GetServerSocketsResponse>
|
||||
): void {
|
||||
const serverId = Number.parseInt(call.request.server_id);
|
||||
const serverEntry = servers[serverId];
|
||||
if (serverEntry === undefined) {
|
||||
callback({
|
||||
code: Status.NOT_FOUND,
|
||||
details: 'No server data found for id ' + serverId,
|
||||
});
|
||||
return;
|
||||
}
|
||||
const startId = Number.parseInt(call.request.start_socket_id);
|
||||
const maxResults = Number.parseInt(call.request.max_results);
|
||||
const resolvedInfo = serverEntry.getInfo();
|
||||
// If we wanted to include listener sockets in the result, this line would
|
||||
// instead say
|
||||
// const allSockets = resolvedInfo.listenerChildren.sockets.concat(resolvedInfo.sessionChildren.sockets).sort((ref1, ref2) => ref1.id - ref2.id);
|
||||
const allSockets = resolvedInfo.sessionChildren.sockets.sort(
|
||||
(ref1, ref2) => ref1.id - ref2.id
|
||||
);
|
||||
const resultList: SocketRefMessage[] = [];
|
||||
let i = 0;
|
||||
for (; i < allSockets.length; i++) {
|
||||
if (allSockets[i].id >= startId) {
|
||||
resultList.push(socketRefToMessage(allSockets[i]));
|
||||
if (resultList.length >= maxResults) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
callback(null, {
|
||||
socket_ref: resultList,
|
||||
end: i >= allSockets.length,
|
||||
});
|
||||
}
|
||||
|
||||
export function getChannelzHandlers(): ChannelzHandlers {
|
||||
return {
|
||||
GetChannel,
|
||||
GetTopChannels,
|
||||
GetServer,
|
||||
GetServers,
|
||||
GetSubchannel,
|
||||
GetSocket,
|
||||
GetServerSockets,
|
||||
};
|
||||
}
|
||||
|
||||
let loadedChannelzDefinition: ChannelzDefinition | null = null;
|
||||
|
||||
export function getChannelzServiceDefinition(): ChannelzDefinition {
|
||||
if (loadedChannelzDefinition) {
|
||||
return loadedChannelzDefinition;
|
||||
}
|
||||
/* The purpose of this complexity is to avoid loading @grpc/proto-loader at
|
||||
* runtime for users who will not use/enable channelz. */
|
||||
const loaderLoadSync = require('@grpc/proto-loader')
|
||||
.loadSync as typeof loadSync;
|
||||
const loadedProto = loaderLoadSync('channelz.proto', {
|
||||
keepCase: true,
|
||||
longs: String,
|
||||
enums: String,
|
||||
defaults: true,
|
||||
oneofs: true,
|
||||
includeDirs: [`${__dirname}/../../proto`],
|
||||
});
|
||||
const channelzGrpcObject = loadPackageDefinition(
|
||||
loadedProto
|
||||
) as unknown as ChannelzProtoGrpcType;
|
||||
loadedChannelzDefinition =
|
||||
channelzGrpcObject.grpc.channelz.v1.Channelz.service;
|
||||
return loadedChannelzDefinition;
|
||||
}
|
||||
|
||||
export function setup() {
|
||||
registerAdminService(getChannelzServiceDefinition, getChannelzHandlers);
|
||||
}
|
||||
@ -0,0 +1,577 @@
|
||||
/*
|
||||
* Copyright 2019 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import { Metadata } from './metadata';
|
||||
import {
|
||||
StatusObject,
|
||||
Listener,
|
||||
MetadataListener,
|
||||
MessageListener,
|
||||
StatusListener,
|
||||
FullListener,
|
||||
InterceptingListener,
|
||||
InterceptingListenerImpl,
|
||||
isInterceptingListener,
|
||||
MessageContext,
|
||||
Call,
|
||||
} from './call-interface';
|
||||
import { Status } from './constants';
|
||||
import { Channel } from './channel';
|
||||
import { CallOptions } from './client';
|
||||
import { ClientMethodDefinition } from './make-client';
|
||||
import { getErrorMessage } from './error';
|
||||
|
||||
/**
|
||||
* Error class associated with passing both interceptors and interceptor
|
||||
* providers to a client constructor or as call options.
|
||||
*/
|
||||
export class InterceptorConfigurationError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = 'InterceptorConfigurationError';
|
||||
Error.captureStackTrace(this, InterceptorConfigurationError);
|
||||
}
|
||||
}
|
||||
|
||||
export interface MetadataRequester {
|
||||
(
|
||||
metadata: Metadata,
|
||||
listener: InterceptingListener,
|
||||
next: (
|
||||
metadata: Metadata,
|
||||
listener: InterceptingListener | Listener
|
||||
) => void
|
||||
): void;
|
||||
}
|
||||
|
||||
export interface MessageRequester {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(message: any, next: (message: any) => void): void;
|
||||
}
|
||||
|
||||
export interface CloseRequester {
|
||||
(next: () => void): void;
|
||||
}
|
||||
|
||||
export interface CancelRequester {
|
||||
(next: () => void): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* An object with methods for intercepting and modifying outgoing call operations.
|
||||
*/
|
||||
export interface FullRequester {
|
||||
start: MetadataRequester;
|
||||
sendMessage: MessageRequester;
|
||||
halfClose: CloseRequester;
|
||||
cancel: CancelRequester;
|
||||
}
|
||||
|
||||
export type Requester = Partial<FullRequester>;
|
||||
|
||||
export class ListenerBuilder {
|
||||
private metadata: MetadataListener | undefined = undefined;
|
||||
private message: MessageListener | undefined = undefined;
|
||||
private status: StatusListener | undefined = undefined;
|
||||
|
||||
withOnReceiveMetadata(onReceiveMetadata: MetadataListener): this {
|
||||
this.metadata = onReceiveMetadata;
|
||||
return this;
|
||||
}
|
||||
|
||||
withOnReceiveMessage(onReceiveMessage: MessageListener): this {
|
||||
this.message = onReceiveMessage;
|
||||
return this;
|
||||
}
|
||||
|
||||
withOnReceiveStatus(onReceiveStatus: StatusListener): this {
|
||||
this.status = onReceiveStatus;
|
||||
return this;
|
||||
}
|
||||
|
||||
build(): Listener {
|
||||
return {
|
||||
onReceiveMetadata: this.metadata,
|
||||
onReceiveMessage: this.message,
|
||||
onReceiveStatus: this.status,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class RequesterBuilder {
|
||||
private start: MetadataRequester | undefined = undefined;
|
||||
private message: MessageRequester | undefined = undefined;
|
||||
private halfClose: CloseRequester | undefined = undefined;
|
||||
private cancel: CancelRequester | undefined = undefined;
|
||||
|
||||
withStart(start: MetadataRequester): this {
|
||||
this.start = start;
|
||||
return this;
|
||||
}
|
||||
|
||||
withSendMessage(sendMessage: MessageRequester): this {
|
||||
this.message = sendMessage;
|
||||
return this;
|
||||
}
|
||||
|
||||
withHalfClose(halfClose: CloseRequester): this {
|
||||
this.halfClose = halfClose;
|
||||
return this;
|
||||
}
|
||||
|
||||
withCancel(cancel: CancelRequester): this {
|
||||
this.cancel = cancel;
|
||||
return this;
|
||||
}
|
||||
|
||||
build(): Requester {
|
||||
return {
|
||||
start: this.start,
|
||||
sendMessage: this.message,
|
||||
halfClose: this.halfClose,
|
||||
cancel: this.cancel,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Listener with a default pass-through implementation of each method. Used
|
||||
* for filling out Listeners with some methods omitted.
|
||||
*/
|
||||
const defaultListener: FullListener = {
|
||||
onReceiveMetadata: (metadata, next) => {
|
||||
next(metadata);
|
||||
},
|
||||
onReceiveMessage: (message, next) => {
|
||||
next(message);
|
||||
},
|
||||
onReceiveStatus: (status, next) => {
|
||||
next(status);
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* A Requester with a default pass-through implementation of each method. Used
|
||||
* for filling out Requesters with some methods omitted.
|
||||
*/
|
||||
const defaultRequester: FullRequester = {
|
||||
start: (metadata, listener, next) => {
|
||||
next(metadata, listener);
|
||||
},
|
||||
sendMessage: (message, next) => {
|
||||
next(message);
|
||||
},
|
||||
halfClose: next => {
|
||||
next();
|
||||
},
|
||||
cancel: next => {
|
||||
next();
|
||||
},
|
||||
};
|
||||
|
||||
export interface InterceptorOptions extends CallOptions {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
method_definition: ClientMethodDefinition<any, any>;
|
||||
}
|
||||
|
||||
export interface InterceptingCallInterface {
|
||||
cancelWithStatus(status: Status, details: string): void;
|
||||
getPeer(): string;
|
||||
start(metadata: Metadata, listener?: Partial<InterceptingListener>): void;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
sendMessageWithContext(context: MessageContext, message: any): void;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
sendMessage(message: any): void;
|
||||
startRead(): void;
|
||||
halfClose(): void;
|
||||
}
|
||||
|
||||
export class InterceptingCall implements InterceptingCallInterface {
|
||||
/**
|
||||
* The requester that this InterceptingCall uses to modify outgoing operations
|
||||
*/
|
||||
private requester: FullRequester;
|
||||
/**
|
||||
* Indicates that metadata has been passed to the requester's start
|
||||
* method but it has not been passed to the corresponding next callback
|
||||
*/
|
||||
private processingMetadata = false;
|
||||
/**
|
||||
* Message context for a pending message that is waiting for
|
||||
*/
|
||||
private pendingMessageContext: MessageContext | null = null;
|
||||
private pendingMessage: any;
|
||||
/**
|
||||
* Indicates that a message has been passed to the requester's sendMessage
|
||||
* method but it has not been passed to the corresponding next callback
|
||||
*/
|
||||
private processingMessage = false;
|
||||
/**
|
||||
* Indicates that a status was received but could not be propagated because
|
||||
* a message was still being processed.
|
||||
*/
|
||||
private pendingHalfClose = false;
|
||||
constructor(
|
||||
private nextCall: InterceptingCallInterface,
|
||||
requester?: Requester
|
||||
) {
|
||||
if (requester) {
|
||||
this.requester = {
|
||||
start: requester.start ?? defaultRequester.start,
|
||||
sendMessage: requester.sendMessage ?? defaultRequester.sendMessage,
|
||||
halfClose: requester.halfClose ?? defaultRequester.halfClose,
|
||||
cancel: requester.cancel ?? defaultRequester.cancel,
|
||||
};
|
||||
} else {
|
||||
this.requester = defaultRequester;
|
||||
}
|
||||
}
|
||||
|
||||
cancelWithStatus(status: Status, details: string) {
|
||||
this.requester.cancel(() => {
|
||||
this.nextCall.cancelWithStatus(status, details);
|
||||
});
|
||||
}
|
||||
|
||||
getPeer() {
|
||||
return this.nextCall.getPeer();
|
||||
}
|
||||
|
||||
private processPendingMessage() {
|
||||
if (this.pendingMessageContext) {
|
||||
this.nextCall.sendMessageWithContext(
|
||||
this.pendingMessageContext,
|
||||
this.pendingMessage
|
||||
);
|
||||
this.pendingMessageContext = null;
|
||||
this.pendingMessage = null;
|
||||
}
|
||||
}
|
||||
|
||||
private processPendingHalfClose() {
|
||||
if (this.pendingHalfClose) {
|
||||
this.nextCall.halfClose();
|
||||
}
|
||||
}
|
||||
|
||||
start(
|
||||
metadata: Metadata,
|
||||
interceptingListener?: Partial<InterceptingListener>
|
||||
): void {
|
||||
const fullInterceptingListener: InterceptingListener = {
|
||||
onReceiveMetadata:
|
||||
interceptingListener?.onReceiveMetadata?.bind(interceptingListener) ??
|
||||
(metadata => {}),
|
||||
onReceiveMessage:
|
||||
interceptingListener?.onReceiveMessage?.bind(interceptingListener) ??
|
||||
(message => {}),
|
||||
onReceiveStatus:
|
||||
interceptingListener?.onReceiveStatus?.bind(interceptingListener) ??
|
||||
(status => {}),
|
||||
};
|
||||
this.processingMetadata = true;
|
||||
this.requester.start(metadata, fullInterceptingListener, (md, listener) => {
|
||||
this.processingMetadata = false;
|
||||
let finalInterceptingListener: InterceptingListener;
|
||||
if (isInterceptingListener(listener)) {
|
||||
finalInterceptingListener = listener;
|
||||
} else {
|
||||
const fullListener: FullListener = {
|
||||
onReceiveMetadata:
|
||||
listener.onReceiveMetadata ?? defaultListener.onReceiveMetadata,
|
||||
onReceiveMessage:
|
||||
listener.onReceiveMessage ?? defaultListener.onReceiveMessage,
|
||||
onReceiveStatus:
|
||||
listener.onReceiveStatus ?? defaultListener.onReceiveStatus,
|
||||
};
|
||||
finalInterceptingListener = new InterceptingListenerImpl(
|
||||
fullListener,
|
||||
fullInterceptingListener
|
||||
);
|
||||
}
|
||||
this.nextCall.start(md, finalInterceptingListener);
|
||||
this.processPendingMessage();
|
||||
this.processPendingHalfClose();
|
||||
});
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
sendMessageWithContext(context: MessageContext, message: any): void {
|
||||
this.processingMessage = true;
|
||||
this.requester.sendMessage(message, finalMessage => {
|
||||
this.processingMessage = false;
|
||||
if (this.processingMetadata) {
|
||||
this.pendingMessageContext = context;
|
||||
this.pendingMessage = message;
|
||||
} else {
|
||||
this.nextCall.sendMessageWithContext(context, finalMessage);
|
||||
this.processPendingHalfClose();
|
||||
}
|
||||
});
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
sendMessage(message: any): void {
|
||||
this.sendMessageWithContext({}, message);
|
||||
}
|
||||
startRead(): void {
|
||||
this.nextCall.startRead();
|
||||
}
|
||||
halfClose(): void {
|
||||
this.requester.halfClose(() => {
|
||||
if (this.processingMetadata || this.processingMessage) {
|
||||
this.pendingHalfClose = true;
|
||||
} else {
|
||||
this.nextCall.halfClose();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getCall(channel: Channel, path: string, options: CallOptions): Call {
|
||||
const deadline = options.deadline ?? Infinity;
|
||||
const host = options.host;
|
||||
const parent = options.parent ?? null;
|
||||
const propagateFlags = options.propagate_flags;
|
||||
const credentials = options.credentials;
|
||||
const call = channel.createCall(path, deadline, host, parent, propagateFlags);
|
||||
if (credentials) {
|
||||
call.setCredentials(credentials);
|
||||
}
|
||||
return call;
|
||||
}
|
||||
|
||||
/**
|
||||
* InterceptingCall implementation that directly owns the underlying Call
|
||||
* object and handles serialization and deseraizliation.
|
||||
*/
|
||||
class BaseInterceptingCall implements InterceptingCallInterface {
|
||||
constructor(
|
||||
protected call: Call,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
protected methodDefinition: ClientMethodDefinition<any, any>
|
||||
) {}
|
||||
cancelWithStatus(status: Status, details: string): void {
|
||||
this.call.cancelWithStatus(status, details);
|
||||
}
|
||||
getPeer(): string {
|
||||
return this.call.getPeer();
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
sendMessageWithContext(context: MessageContext, message: any): void {
|
||||
let serialized: Buffer;
|
||||
try {
|
||||
serialized = this.methodDefinition.requestSerialize(message);
|
||||
} catch (e) {
|
||||
this.call.cancelWithStatus(
|
||||
Status.INTERNAL,
|
||||
`Request message serialization failure: ${getErrorMessage(e)}`
|
||||
);
|
||||
return;
|
||||
}
|
||||
this.call.sendMessageWithContext(context, serialized);
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
sendMessage(message: any) {
|
||||
this.sendMessageWithContext({}, message);
|
||||
}
|
||||
start(
|
||||
metadata: Metadata,
|
||||
interceptingListener?: Partial<InterceptingListener>
|
||||
): void {
|
||||
let readError: StatusObject | null = null;
|
||||
this.call.start(metadata, {
|
||||
onReceiveMetadata: metadata => {
|
||||
interceptingListener?.onReceiveMetadata?.(metadata);
|
||||
},
|
||||
onReceiveMessage: message => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
let deserialized: any;
|
||||
try {
|
||||
deserialized = this.methodDefinition.responseDeserialize(message);
|
||||
} catch (e) {
|
||||
readError = {
|
||||
code: Status.INTERNAL,
|
||||
details: `Response message parsing error: ${getErrorMessage(e)}`,
|
||||
metadata: new Metadata(),
|
||||
};
|
||||
this.call.cancelWithStatus(readError.code, readError.details);
|
||||
return;
|
||||
}
|
||||
interceptingListener?.onReceiveMessage?.(deserialized);
|
||||
},
|
||||
onReceiveStatus: status => {
|
||||
if (readError) {
|
||||
interceptingListener?.onReceiveStatus?.(readError);
|
||||
} else {
|
||||
interceptingListener?.onReceiveStatus?.(status);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
startRead() {
|
||||
this.call.startRead();
|
||||
}
|
||||
halfClose(): void {
|
||||
this.call.halfClose();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* BaseInterceptingCall with special-cased behavior for methods with unary
|
||||
* responses.
|
||||
*/
|
||||
class BaseUnaryInterceptingCall
|
||||
extends BaseInterceptingCall
|
||||
implements InterceptingCallInterface
|
||||
{
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
constructor(call: Call, methodDefinition: ClientMethodDefinition<any, any>) {
|
||||
super(call, methodDefinition);
|
||||
}
|
||||
start(metadata: Metadata, listener?: Partial<InterceptingListener>): void {
|
||||
let receivedMessage = false;
|
||||
const wrapperListener: InterceptingListener = {
|
||||
onReceiveMetadata:
|
||||
listener?.onReceiveMetadata?.bind(listener) ?? (metadata => {}),
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
onReceiveMessage: (message: any) => {
|
||||
receivedMessage = true;
|
||||
listener?.onReceiveMessage?.(message);
|
||||
},
|
||||
onReceiveStatus: (status: StatusObject) => {
|
||||
if (!receivedMessage) {
|
||||
listener?.onReceiveMessage?.(null);
|
||||
}
|
||||
listener?.onReceiveStatus?.(status);
|
||||
},
|
||||
};
|
||||
super.start(metadata, wrapperListener);
|
||||
this.call.startRead();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* BaseInterceptingCall with special-cased behavior for methods with streaming
|
||||
* responses.
|
||||
*/
|
||||
class BaseStreamingInterceptingCall
|
||||
extends BaseInterceptingCall
|
||||
implements InterceptingCallInterface {}
|
||||
|
||||
function getBottomInterceptingCall(
|
||||
channel: Channel,
|
||||
options: InterceptorOptions,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
methodDefinition: ClientMethodDefinition<any, any>
|
||||
) {
|
||||
const call = getCall(channel, methodDefinition.path, options);
|
||||
if (methodDefinition.responseStream) {
|
||||
return new BaseStreamingInterceptingCall(call, methodDefinition);
|
||||
} else {
|
||||
return new BaseUnaryInterceptingCall(call, methodDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
export interface NextCall {
|
||||
(options: InterceptorOptions): InterceptingCallInterface;
|
||||
}
|
||||
|
||||
export interface Interceptor {
|
||||
(options: InterceptorOptions, nextCall: NextCall): InterceptingCall;
|
||||
}
|
||||
|
||||
export interface InterceptorProvider {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(methodDefinition: ClientMethodDefinition<any, any>): Interceptor;
|
||||
}
|
||||
|
||||
export interface InterceptorArguments {
|
||||
clientInterceptors: Interceptor[];
|
||||
clientInterceptorProviders: InterceptorProvider[];
|
||||
callInterceptors: Interceptor[];
|
||||
callInterceptorProviders: InterceptorProvider[];
|
||||
}
|
||||
|
||||
export function getInterceptingCall(
|
||||
interceptorArgs: InterceptorArguments,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
methodDefinition: ClientMethodDefinition<any, any>,
|
||||
options: CallOptions,
|
||||
channel: Channel
|
||||
): InterceptingCallInterface {
|
||||
if (
|
||||
interceptorArgs.clientInterceptors.length > 0 &&
|
||||
interceptorArgs.clientInterceptorProviders.length > 0
|
||||
) {
|
||||
throw new InterceptorConfigurationError(
|
||||
'Both interceptors and interceptor_providers were passed as options ' +
|
||||
'to the client constructor. Only one of these is allowed.'
|
||||
);
|
||||
}
|
||||
if (
|
||||
interceptorArgs.callInterceptors.length > 0 &&
|
||||
interceptorArgs.callInterceptorProviders.length > 0
|
||||
) {
|
||||
throw new InterceptorConfigurationError(
|
||||
'Both interceptors and interceptor_providers were passed as call ' +
|
||||
'options. Only one of these is allowed.'
|
||||
);
|
||||
}
|
||||
let interceptors: Interceptor[] = [];
|
||||
// Interceptors passed to the call override interceptors passed to the client constructor
|
||||
if (
|
||||
interceptorArgs.callInterceptors.length > 0 ||
|
||||
interceptorArgs.callInterceptorProviders.length > 0
|
||||
) {
|
||||
interceptors = ([] as Interceptor[])
|
||||
.concat(
|
||||
interceptorArgs.callInterceptors,
|
||||
interceptorArgs.callInterceptorProviders.map(provider =>
|
||||
provider(methodDefinition)
|
||||
)
|
||||
)
|
||||
.filter(interceptor => interceptor);
|
||||
// Filter out falsy values when providers return nothing
|
||||
} else {
|
||||
interceptors = ([] as Interceptor[])
|
||||
.concat(
|
||||
interceptorArgs.clientInterceptors,
|
||||
interceptorArgs.clientInterceptorProviders.map(provider =>
|
||||
provider(methodDefinition)
|
||||
)
|
||||
)
|
||||
.filter(interceptor => interceptor);
|
||||
// Filter out falsy values when providers return nothing
|
||||
}
|
||||
const interceptorOptions = Object.assign({}, options, {
|
||||
method_definition: methodDefinition,
|
||||
});
|
||||
/* For each interceptor in the list, the nextCall function passed to it is
|
||||
* based on the next interceptor in the list, using a nextCall function
|
||||
* constructed with the following interceptor in the list, and so on. The
|
||||
* initialValue, which is effectively at the end of the list, is a nextCall
|
||||
* function that invokes getBottomInterceptingCall, the result of which
|
||||
* handles (de)serialization and also gets the underlying call from the
|
||||
* channel. */
|
||||
const getCall: NextCall = interceptors.reduceRight<NextCall>(
|
||||
(nextCall: NextCall, nextInterceptor: Interceptor) => {
|
||||
return currentOptions => nextInterceptor(currentOptions, nextCall);
|
||||
},
|
||||
(finalOptions: InterceptorOptions) =>
|
||||
getBottomInterceptingCall(channel, finalOptions, methodDefinition)
|
||||
);
|
||||
return getCall(interceptorOptions);
|
||||
}
|
||||
@ -0,0 +1,715 @@
|
||||
/*
|
||||
* Copyright 2019 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import {
|
||||
ClientDuplexStream,
|
||||
ClientDuplexStreamImpl,
|
||||
ClientReadableStream,
|
||||
ClientReadableStreamImpl,
|
||||
ClientUnaryCall,
|
||||
ClientUnaryCallImpl,
|
||||
ClientWritableStream,
|
||||
ClientWritableStreamImpl,
|
||||
ServiceError,
|
||||
callErrorFromStatus,
|
||||
SurfaceCall,
|
||||
} from './call';
|
||||
import { CallCredentials } from './call-credentials';
|
||||
import { StatusObject } from './call-interface';
|
||||
import { Channel, ChannelImplementation } from './channel';
|
||||
import { ConnectivityState } from './connectivity-state';
|
||||
import { ChannelCredentials } from './channel-credentials';
|
||||
import { ChannelOptions } from './channel-options';
|
||||
import { Status } from './constants';
|
||||
import { Metadata } from './metadata';
|
||||
import { ClientMethodDefinition } from './make-client';
|
||||
import {
|
||||
getInterceptingCall,
|
||||
Interceptor,
|
||||
InterceptorProvider,
|
||||
InterceptorArguments,
|
||||
InterceptingCallInterface,
|
||||
} from './client-interceptors';
|
||||
import {
|
||||
ServerUnaryCall,
|
||||
ServerReadableStream,
|
||||
ServerWritableStream,
|
||||
ServerDuplexStream,
|
||||
} from './server-call';
|
||||
import { Deadline } from './deadline';
|
||||
|
||||
const CHANNEL_SYMBOL = Symbol();
|
||||
const INTERCEPTOR_SYMBOL = Symbol();
|
||||
const INTERCEPTOR_PROVIDER_SYMBOL = Symbol();
|
||||
const CALL_INVOCATION_TRANSFORMER_SYMBOL = Symbol();
|
||||
|
||||
function isFunction<ResponseType>(
|
||||
arg: Metadata | CallOptions | UnaryCallback<ResponseType> | undefined
|
||||
): arg is UnaryCallback<ResponseType> {
|
||||
return typeof arg === 'function';
|
||||
}
|
||||
|
||||
export interface UnaryCallback<ResponseType> {
|
||||
(err: ServiceError | null, value?: ResponseType): void;
|
||||
}
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
export interface CallOptions {
|
||||
deadline?: Deadline;
|
||||
host?: string;
|
||||
parent?:
|
||||
| ServerUnaryCall<any, any>
|
||||
| ServerReadableStream<any, any>
|
||||
| ServerWritableStream<any, any>
|
||||
| ServerDuplexStream<any, any>;
|
||||
propagate_flags?: number;
|
||||
credentials?: CallCredentials;
|
||||
interceptors?: Interceptor[];
|
||||
interceptor_providers?: InterceptorProvider[];
|
||||
}
|
||||
/* eslint-enable @typescript-eslint/no-explicit-any */
|
||||
|
||||
export interface CallProperties<RequestType, ResponseType> {
|
||||
argument?: RequestType;
|
||||
metadata: Metadata;
|
||||
call: SurfaceCall;
|
||||
channel: Channel;
|
||||
methodDefinition: ClientMethodDefinition<RequestType, ResponseType>;
|
||||
callOptions: CallOptions;
|
||||
callback?: UnaryCallback<ResponseType>;
|
||||
}
|
||||
|
||||
export interface CallInvocationTransformer {
|
||||
(callProperties: CallProperties<any, any>): CallProperties<any, any>; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
}
|
||||
|
||||
export type ClientOptions = Partial<ChannelOptions> & {
|
||||
channelOverride?: Channel;
|
||||
channelFactoryOverride?: (
|
||||
address: string,
|
||||
credentials: ChannelCredentials,
|
||||
options: ClientOptions
|
||||
) => Channel;
|
||||
interceptors?: Interceptor[];
|
||||
interceptor_providers?: InterceptorProvider[];
|
||||
callInvocationTransformer?: CallInvocationTransformer;
|
||||
};
|
||||
|
||||
function getErrorStackString(error: Error): string {
|
||||
return error.stack!.split('\n').slice(1).join('\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* A generic gRPC client. Primarily useful as a base class for all generated
|
||||
* clients.
|
||||
*/
|
||||
export class Client {
|
||||
private readonly [CHANNEL_SYMBOL]: Channel;
|
||||
private readonly [INTERCEPTOR_SYMBOL]: Interceptor[];
|
||||
private readonly [INTERCEPTOR_PROVIDER_SYMBOL]: InterceptorProvider[];
|
||||
private readonly [CALL_INVOCATION_TRANSFORMER_SYMBOL]?: CallInvocationTransformer;
|
||||
constructor(
|
||||
address: string,
|
||||
credentials: ChannelCredentials,
|
||||
options: ClientOptions = {}
|
||||
) {
|
||||
options = Object.assign({}, options);
|
||||
this[INTERCEPTOR_SYMBOL] = options.interceptors ?? [];
|
||||
delete options.interceptors;
|
||||
this[INTERCEPTOR_PROVIDER_SYMBOL] = options.interceptor_providers ?? [];
|
||||
delete options.interceptor_providers;
|
||||
if (
|
||||
this[INTERCEPTOR_SYMBOL].length > 0 &&
|
||||
this[INTERCEPTOR_PROVIDER_SYMBOL].length > 0
|
||||
) {
|
||||
throw new Error(
|
||||
'Both interceptors and interceptor_providers were passed as options ' +
|
||||
'to the client constructor. Only one of these is allowed.'
|
||||
);
|
||||
}
|
||||
this[CALL_INVOCATION_TRANSFORMER_SYMBOL] =
|
||||
options.callInvocationTransformer;
|
||||
delete options.callInvocationTransformer;
|
||||
if (options.channelOverride) {
|
||||
this[CHANNEL_SYMBOL] = options.channelOverride;
|
||||
} else if (options.channelFactoryOverride) {
|
||||
const channelFactoryOverride = options.channelFactoryOverride;
|
||||
delete options.channelFactoryOverride;
|
||||
this[CHANNEL_SYMBOL] = channelFactoryOverride(
|
||||
address,
|
||||
credentials,
|
||||
options
|
||||
);
|
||||
} else {
|
||||
this[CHANNEL_SYMBOL] = new ChannelImplementation(
|
||||
address,
|
||||
credentials,
|
||||
options
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
close(): void {
|
||||
this[CHANNEL_SYMBOL].close();
|
||||
}
|
||||
|
||||
getChannel(): Channel {
|
||||
return this[CHANNEL_SYMBOL];
|
||||
}
|
||||
|
||||
waitForReady(deadline: Deadline, callback: (error?: Error) => void): void {
|
||||
const checkState = (err?: Error) => {
|
||||
if (err) {
|
||||
callback(new Error('Failed to connect before the deadline'));
|
||||
return;
|
||||
}
|
||||
let newState;
|
||||
try {
|
||||
newState = this[CHANNEL_SYMBOL].getConnectivityState(true);
|
||||
} catch (e) {
|
||||
callback(new Error('The channel has been closed'));
|
||||
return;
|
||||
}
|
||||
if (newState === ConnectivityState.READY) {
|
||||
callback();
|
||||
} else {
|
||||
try {
|
||||
this[CHANNEL_SYMBOL].watchConnectivityState(
|
||||
newState,
|
||||
deadline,
|
||||
checkState
|
||||
);
|
||||
} catch (e) {
|
||||
callback(new Error('The channel has been closed'));
|
||||
}
|
||||
}
|
||||
};
|
||||
setImmediate(checkState);
|
||||
}
|
||||
|
||||
private checkOptionalUnaryResponseArguments<ResponseType>(
|
||||
arg1: Metadata | CallOptions | UnaryCallback<ResponseType>,
|
||||
arg2?: CallOptions | UnaryCallback<ResponseType>,
|
||||
arg3?: UnaryCallback<ResponseType>
|
||||
): {
|
||||
metadata: Metadata;
|
||||
options: CallOptions;
|
||||
callback: UnaryCallback<ResponseType>;
|
||||
} {
|
||||
if (isFunction(arg1)) {
|
||||
return { metadata: new Metadata(), options: {}, callback: arg1 };
|
||||
} else if (isFunction(arg2)) {
|
||||
if (arg1 instanceof Metadata) {
|
||||
return { metadata: arg1, options: {}, callback: arg2 };
|
||||
} else {
|
||||
return { metadata: new Metadata(), options: arg1, callback: arg2 };
|
||||
}
|
||||
} else {
|
||||
if (
|
||||
!(
|
||||
arg1 instanceof Metadata &&
|
||||
arg2 instanceof Object &&
|
||||
isFunction(arg3)
|
||||
)
|
||||
) {
|
||||
throw new Error('Incorrect arguments passed');
|
||||
}
|
||||
return { metadata: arg1, options: arg2, callback: arg3 };
|
||||
}
|
||||
}
|
||||
|
||||
makeUnaryRequest<RequestType, ResponseType>(
|
||||
method: string,
|
||||
serialize: (value: RequestType) => Buffer,
|
||||
deserialize: (value: Buffer) => ResponseType,
|
||||
argument: RequestType,
|
||||
metadata: Metadata,
|
||||
options: CallOptions,
|
||||
callback: UnaryCallback<ResponseType>
|
||||
): ClientUnaryCall;
|
||||
makeUnaryRequest<RequestType, ResponseType>(
|
||||
method: string,
|
||||
serialize: (value: RequestType) => Buffer,
|
||||
deserialize: (value: Buffer) => ResponseType,
|
||||
argument: RequestType,
|
||||
metadata: Metadata,
|
||||
callback: UnaryCallback<ResponseType>
|
||||
): ClientUnaryCall;
|
||||
makeUnaryRequest<RequestType, ResponseType>(
|
||||
method: string,
|
||||
serialize: (value: RequestType) => Buffer,
|
||||
deserialize: (value: Buffer) => ResponseType,
|
||||
argument: RequestType,
|
||||
options: CallOptions,
|
||||
callback: UnaryCallback<ResponseType>
|
||||
): ClientUnaryCall;
|
||||
makeUnaryRequest<RequestType, ResponseType>(
|
||||
method: string,
|
||||
serialize: (value: RequestType) => Buffer,
|
||||
deserialize: (value: Buffer) => ResponseType,
|
||||
argument: RequestType,
|
||||
callback: UnaryCallback<ResponseType>
|
||||
): ClientUnaryCall;
|
||||
makeUnaryRequest<RequestType, ResponseType>(
|
||||
method: string,
|
||||
serialize: (value: RequestType) => Buffer,
|
||||
deserialize: (value: Buffer) => ResponseType,
|
||||
argument: RequestType,
|
||||
metadata: Metadata | CallOptions | UnaryCallback<ResponseType>,
|
||||
options?: CallOptions | UnaryCallback<ResponseType>,
|
||||
callback?: UnaryCallback<ResponseType>
|
||||
): ClientUnaryCall {
|
||||
const checkedArguments =
|
||||
this.checkOptionalUnaryResponseArguments<ResponseType>(
|
||||
metadata,
|
||||
options,
|
||||
callback
|
||||
);
|
||||
const methodDefinition: ClientMethodDefinition<RequestType, ResponseType> =
|
||||
{
|
||||
path: method,
|
||||
requestStream: false,
|
||||
responseStream: false,
|
||||
requestSerialize: serialize,
|
||||
responseDeserialize: deserialize,
|
||||
};
|
||||
let callProperties: CallProperties<RequestType, ResponseType> = {
|
||||
argument: argument,
|
||||
metadata: checkedArguments.metadata,
|
||||
call: new ClientUnaryCallImpl(),
|
||||
channel: this[CHANNEL_SYMBOL],
|
||||
methodDefinition: methodDefinition,
|
||||
callOptions: checkedArguments.options,
|
||||
callback: checkedArguments.callback,
|
||||
};
|
||||
if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) {
|
||||
callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL]!(
|
||||
callProperties
|
||||
) as CallProperties<RequestType, ResponseType>;
|
||||
}
|
||||
const emitter: ClientUnaryCall = callProperties.call;
|
||||
const interceptorArgs: InterceptorArguments = {
|
||||
clientInterceptors: this[INTERCEPTOR_SYMBOL],
|
||||
clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL],
|
||||
callInterceptors: callProperties.callOptions.interceptors ?? [],
|
||||
callInterceptorProviders:
|
||||
callProperties.callOptions.interceptor_providers ?? [],
|
||||
};
|
||||
const call: InterceptingCallInterface = getInterceptingCall(
|
||||
interceptorArgs,
|
||||
callProperties.methodDefinition,
|
||||
callProperties.callOptions,
|
||||
callProperties.channel
|
||||
);
|
||||
/* This needs to happen before the emitter is used. Unfortunately we can't
|
||||
* enforce this with the type system. We need to construct this emitter
|
||||
* before calling the CallInvocationTransformer, and we need to create the
|
||||
* call after that. */
|
||||
emitter.call = call;
|
||||
let responseMessage: ResponseType | null = null;
|
||||
let receivedStatus = false;
|
||||
let callerStackError: Error | null = new Error();
|
||||
call.start(callProperties.metadata, {
|
||||
onReceiveMetadata: metadata => {
|
||||
emitter.emit('metadata', metadata);
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
onReceiveMessage(message: any) {
|
||||
if (responseMessage !== null) {
|
||||
call.cancelWithStatus(Status.INTERNAL, 'Too many responses received');
|
||||
}
|
||||
responseMessage = message;
|
||||
},
|
||||
onReceiveStatus(status: StatusObject) {
|
||||
if (receivedStatus) {
|
||||
return;
|
||||
}
|
||||
receivedStatus = true;
|
||||
if (status.code === Status.OK) {
|
||||
if (responseMessage === null) {
|
||||
const callerStack = getErrorStackString(callerStackError!);
|
||||
callProperties.callback!(
|
||||
callErrorFromStatus(
|
||||
{
|
||||
code: Status.INTERNAL,
|
||||
details: 'No message received',
|
||||
metadata: status.metadata,
|
||||
},
|
||||
callerStack
|
||||
)
|
||||
);
|
||||
} else {
|
||||
callProperties.callback!(null, responseMessage);
|
||||
}
|
||||
} else {
|
||||
const callerStack = getErrorStackString(callerStackError!);
|
||||
callProperties.callback!(callErrorFromStatus(status, callerStack));
|
||||
}
|
||||
/* Avoid retaining the callerStackError object in the call context of
|
||||
* the status event handler. */
|
||||
callerStackError = null;
|
||||
emitter.emit('status', status);
|
||||
},
|
||||
});
|
||||
call.sendMessage(argument);
|
||||
call.halfClose();
|
||||
return emitter;
|
||||
}
|
||||
|
||||
makeClientStreamRequest<RequestType, ResponseType>(
|
||||
method: string,
|
||||
serialize: (value: RequestType) => Buffer,
|
||||
deserialize: (value: Buffer) => ResponseType,
|
||||
metadata: Metadata,
|
||||
options: CallOptions,
|
||||
callback: UnaryCallback<ResponseType>
|
||||
): ClientWritableStream<RequestType>;
|
||||
makeClientStreamRequest<RequestType, ResponseType>(
|
||||
method: string,
|
||||
serialize: (value: RequestType) => Buffer,
|
||||
deserialize: (value: Buffer) => ResponseType,
|
||||
metadata: Metadata,
|
||||
callback: UnaryCallback<ResponseType>
|
||||
): ClientWritableStream<RequestType>;
|
||||
makeClientStreamRequest<RequestType, ResponseType>(
|
||||
method: string,
|
||||
serialize: (value: RequestType) => Buffer,
|
||||
deserialize: (value: Buffer) => ResponseType,
|
||||
options: CallOptions,
|
||||
callback: UnaryCallback<ResponseType>
|
||||
): ClientWritableStream<RequestType>;
|
||||
makeClientStreamRequest<RequestType, ResponseType>(
|
||||
method: string,
|
||||
serialize: (value: RequestType) => Buffer,
|
||||
deserialize: (value: Buffer) => ResponseType,
|
||||
callback: UnaryCallback<ResponseType>
|
||||
): ClientWritableStream<RequestType>;
|
||||
makeClientStreamRequest<RequestType, ResponseType>(
|
||||
method: string,
|
||||
serialize: (value: RequestType) => Buffer,
|
||||
deserialize: (value: Buffer) => ResponseType,
|
||||
metadata: Metadata | CallOptions | UnaryCallback<ResponseType>,
|
||||
options?: CallOptions | UnaryCallback<ResponseType>,
|
||||
callback?: UnaryCallback<ResponseType>
|
||||
): ClientWritableStream<RequestType> {
|
||||
const checkedArguments =
|
||||
this.checkOptionalUnaryResponseArguments<ResponseType>(
|
||||
metadata,
|
||||
options,
|
||||
callback
|
||||
);
|
||||
const methodDefinition: ClientMethodDefinition<RequestType, ResponseType> =
|
||||
{
|
||||
path: method,
|
||||
requestStream: true,
|
||||
responseStream: false,
|
||||
requestSerialize: serialize,
|
||||
responseDeserialize: deserialize,
|
||||
};
|
||||
let callProperties: CallProperties<RequestType, ResponseType> = {
|
||||
metadata: checkedArguments.metadata,
|
||||
call: new ClientWritableStreamImpl<RequestType>(serialize),
|
||||
channel: this[CHANNEL_SYMBOL],
|
||||
methodDefinition: methodDefinition,
|
||||
callOptions: checkedArguments.options,
|
||||
callback: checkedArguments.callback,
|
||||
};
|
||||
if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) {
|
||||
callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL]!(
|
||||
callProperties
|
||||
) as CallProperties<RequestType, ResponseType>;
|
||||
}
|
||||
const emitter: ClientWritableStream<RequestType> =
|
||||
callProperties.call as ClientWritableStream<RequestType>;
|
||||
const interceptorArgs: InterceptorArguments = {
|
||||
clientInterceptors: this[INTERCEPTOR_SYMBOL],
|
||||
clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL],
|
||||
callInterceptors: callProperties.callOptions.interceptors ?? [],
|
||||
callInterceptorProviders:
|
||||
callProperties.callOptions.interceptor_providers ?? [],
|
||||
};
|
||||
const call: InterceptingCallInterface = getInterceptingCall(
|
||||
interceptorArgs,
|
||||
callProperties.methodDefinition,
|
||||
callProperties.callOptions,
|
||||
callProperties.channel
|
||||
);
|
||||
/* This needs to happen before the emitter is used. Unfortunately we can't
|
||||
* enforce this with the type system. We need to construct this emitter
|
||||
* before calling the CallInvocationTransformer, and we need to create the
|
||||
* call after that. */
|
||||
emitter.call = call;
|
||||
let responseMessage: ResponseType | null = null;
|
||||
let receivedStatus = false;
|
||||
let callerStackError: Error | null = new Error();
|
||||
call.start(callProperties.metadata, {
|
||||
onReceiveMetadata: metadata => {
|
||||
emitter.emit('metadata', metadata);
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
onReceiveMessage(message: any) {
|
||||
if (responseMessage !== null) {
|
||||
call.cancelWithStatus(Status.INTERNAL, 'Too many responses received');
|
||||
}
|
||||
responseMessage = message;
|
||||
},
|
||||
onReceiveStatus(status: StatusObject) {
|
||||
if (receivedStatus) {
|
||||
return;
|
||||
}
|
||||
receivedStatus = true;
|
||||
if (status.code === Status.OK) {
|
||||
if (responseMessage === null) {
|
||||
const callerStack = getErrorStackString(callerStackError!);
|
||||
callProperties.callback!(
|
||||
callErrorFromStatus(
|
||||
{
|
||||
code: Status.INTERNAL,
|
||||
details: 'No message received',
|
||||
metadata: status.metadata,
|
||||
},
|
||||
callerStack
|
||||
)
|
||||
);
|
||||
} else {
|
||||
callProperties.callback!(null, responseMessage);
|
||||
}
|
||||
} else {
|
||||
const callerStack = getErrorStackString(callerStackError!);
|
||||
callProperties.callback!(callErrorFromStatus(status, callerStack));
|
||||
}
|
||||
/* Avoid retaining the callerStackError object in the call context of
|
||||
* the status event handler. */
|
||||
callerStackError = null;
|
||||
emitter.emit('status', status);
|
||||
},
|
||||
});
|
||||
return emitter;
|
||||
}
|
||||
|
||||
private checkMetadataAndOptions(
|
||||
arg1?: Metadata | CallOptions,
|
||||
arg2?: CallOptions
|
||||
): { metadata: Metadata; options: CallOptions } {
|
||||
let metadata: Metadata;
|
||||
let options: CallOptions;
|
||||
if (arg1 instanceof Metadata) {
|
||||
metadata = arg1;
|
||||
if (arg2) {
|
||||
options = arg2;
|
||||
} else {
|
||||
options = {};
|
||||
}
|
||||
} else {
|
||||
if (arg1) {
|
||||
options = arg1;
|
||||
} else {
|
||||
options = {};
|
||||
}
|
||||
metadata = new Metadata();
|
||||
}
|
||||
return { metadata, options };
|
||||
}
|
||||
|
||||
makeServerStreamRequest<RequestType, ResponseType>(
|
||||
method: string,
|
||||
serialize: (value: RequestType) => Buffer,
|
||||
deserialize: (value: Buffer) => ResponseType,
|
||||
argument: RequestType,
|
||||
metadata: Metadata,
|
||||
options?: CallOptions
|
||||
): ClientReadableStream<ResponseType>;
|
||||
makeServerStreamRequest<RequestType, ResponseType>(
|
||||
method: string,
|
||||
serialize: (value: RequestType) => Buffer,
|
||||
deserialize: (value: Buffer) => ResponseType,
|
||||
argument: RequestType,
|
||||
options?: CallOptions
|
||||
): ClientReadableStream<ResponseType>;
|
||||
makeServerStreamRequest<RequestType, ResponseType>(
|
||||
method: string,
|
||||
serialize: (value: RequestType) => Buffer,
|
||||
deserialize: (value: Buffer) => ResponseType,
|
||||
argument: RequestType,
|
||||
metadata?: Metadata | CallOptions,
|
||||
options?: CallOptions
|
||||
): ClientReadableStream<ResponseType> {
|
||||
const checkedArguments = this.checkMetadataAndOptions(metadata, options);
|
||||
const methodDefinition: ClientMethodDefinition<RequestType, ResponseType> =
|
||||
{
|
||||
path: method,
|
||||
requestStream: false,
|
||||
responseStream: true,
|
||||
requestSerialize: serialize,
|
||||
responseDeserialize: deserialize,
|
||||
};
|
||||
let callProperties: CallProperties<RequestType, ResponseType> = {
|
||||
argument: argument,
|
||||
metadata: checkedArguments.metadata,
|
||||
call: new ClientReadableStreamImpl<ResponseType>(deserialize),
|
||||
channel: this[CHANNEL_SYMBOL],
|
||||
methodDefinition: methodDefinition,
|
||||
callOptions: checkedArguments.options,
|
||||
};
|
||||
if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) {
|
||||
callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL]!(
|
||||
callProperties
|
||||
) as CallProperties<RequestType, ResponseType>;
|
||||
}
|
||||
const stream: ClientReadableStream<ResponseType> =
|
||||
callProperties.call as ClientReadableStream<ResponseType>;
|
||||
const interceptorArgs: InterceptorArguments = {
|
||||
clientInterceptors: this[INTERCEPTOR_SYMBOL],
|
||||
clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL],
|
||||
callInterceptors: callProperties.callOptions.interceptors ?? [],
|
||||
callInterceptorProviders:
|
||||
callProperties.callOptions.interceptor_providers ?? [],
|
||||
};
|
||||
const call: InterceptingCallInterface = getInterceptingCall(
|
||||
interceptorArgs,
|
||||
callProperties.methodDefinition,
|
||||
callProperties.callOptions,
|
||||
callProperties.channel
|
||||
);
|
||||
/* This needs to happen before the emitter is used. Unfortunately we can't
|
||||
* enforce this with the type system. We need to construct this emitter
|
||||
* before calling the CallInvocationTransformer, and we need to create the
|
||||
* call after that. */
|
||||
stream.call = call;
|
||||
let receivedStatus = false;
|
||||
let callerStackError: Error | null = new Error();
|
||||
call.start(callProperties.metadata, {
|
||||
onReceiveMetadata(metadata: Metadata) {
|
||||
stream.emit('metadata', metadata);
|
||||
},
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
onReceiveMessage(message: any) {
|
||||
stream.push(message);
|
||||
},
|
||||
onReceiveStatus(status: StatusObject) {
|
||||
if (receivedStatus) {
|
||||
return;
|
||||
}
|
||||
receivedStatus = true;
|
||||
stream.push(null);
|
||||
if (status.code !== Status.OK) {
|
||||
const callerStack = getErrorStackString(callerStackError!);
|
||||
stream.emit('error', callErrorFromStatus(status, callerStack));
|
||||
}
|
||||
/* Avoid retaining the callerStackError object in the call context of
|
||||
* the status event handler. */
|
||||
callerStackError = null;
|
||||
stream.emit('status', status);
|
||||
},
|
||||
});
|
||||
call.sendMessage(argument);
|
||||
call.halfClose();
|
||||
return stream;
|
||||
}
|
||||
|
||||
makeBidiStreamRequest<RequestType, ResponseType>(
|
||||
method: string,
|
||||
serialize: (value: RequestType) => Buffer,
|
||||
deserialize: (value: Buffer) => ResponseType,
|
||||
metadata: Metadata,
|
||||
options?: CallOptions
|
||||
): ClientDuplexStream<RequestType, ResponseType>;
|
||||
makeBidiStreamRequest<RequestType, ResponseType>(
|
||||
method: string,
|
||||
serialize: (value: RequestType) => Buffer,
|
||||
deserialize: (value: Buffer) => ResponseType,
|
||||
options?: CallOptions
|
||||
): ClientDuplexStream<RequestType, ResponseType>;
|
||||
makeBidiStreamRequest<RequestType, ResponseType>(
|
||||
method: string,
|
||||
serialize: (value: RequestType) => Buffer,
|
||||
deserialize: (value: Buffer) => ResponseType,
|
||||
metadata?: Metadata | CallOptions,
|
||||
options?: CallOptions
|
||||
): ClientDuplexStream<RequestType, ResponseType> {
|
||||
const checkedArguments = this.checkMetadataAndOptions(metadata, options);
|
||||
const methodDefinition: ClientMethodDefinition<RequestType, ResponseType> =
|
||||
{
|
||||
path: method,
|
||||
requestStream: true,
|
||||
responseStream: true,
|
||||
requestSerialize: serialize,
|
||||
responseDeserialize: deserialize,
|
||||
};
|
||||
let callProperties: CallProperties<RequestType, ResponseType> = {
|
||||
metadata: checkedArguments.metadata,
|
||||
call: new ClientDuplexStreamImpl<RequestType, ResponseType>(
|
||||
serialize,
|
||||
deserialize
|
||||
),
|
||||
channel: this[CHANNEL_SYMBOL],
|
||||
methodDefinition: methodDefinition,
|
||||
callOptions: checkedArguments.options,
|
||||
};
|
||||
if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) {
|
||||
callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL]!(
|
||||
callProperties
|
||||
) as CallProperties<RequestType, ResponseType>;
|
||||
}
|
||||
const stream: ClientDuplexStream<RequestType, ResponseType> =
|
||||
callProperties.call as ClientDuplexStream<RequestType, ResponseType>;
|
||||
const interceptorArgs: InterceptorArguments = {
|
||||
clientInterceptors: this[INTERCEPTOR_SYMBOL],
|
||||
clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL],
|
||||
callInterceptors: callProperties.callOptions.interceptors ?? [],
|
||||
callInterceptorProviders:
|
||||
callProperties.callOptions.interceptor_providers ?? [],
|
||||
};
|
||||
const call: InterceptingCallInterface = getInterceptingCall(
|
||||
interceptorArgs,
|
||||
callProperties.methodDefinition,
|
||||
callProperties.callOptions,
|
||||
callProperties.channel
|
||||
);
|
||||
/* This needs to happen before the emitter is used. Unfortunately we can't
|
||||
* enforce this with the type system. We need to construct this emitter
|
||||
* before calling the CallInvocationTransformer, and we need to create the
|
||||
* call after that. */
|
||||
stream.call = call;
|
||||
let receivedStatus = false;
|
||||
let callerStackError: Error | null = new Error();
|
||||
call.start(callProperties.metadata, {
|
||||
onReceiveMetadata(metadata: Metadata) {
|
||||
stream.emit('metadata', metadata);
|
||||
},
|
||||
onReceiveMessage(message: Buffer) {
|
||||
stream.push(message);
|
||||
},
|
||||
onReceiveStatus(status: StatusObject) {
|
||||
if (receivedStatus) {
|
||||
return;
|
||||
}
|
||||
receivedStatus = true;
|
||||
stream.push(null);
|
||||
if (status.code !== Status.OK) {
|
||||
const callerStack = getErrorStackString(callerStackError!);
|
||||
stream.emit('error', callErrorFromStatus(status, callerStack));
|
||||
}
|
||||
/* Avoid retaining the callerStackError object in the call context of
|
||||
* the status event handler. */
|
||||
callerStackError = null;
|
||||
stream.emit('status', status);
|
||||
},
|
||||
});
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2021 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
export enum CompressionAlgorithms {
|
||||
identity = 0,
|
||||
deflate = 1,
|
||||
gzip = 2,
|
||||
}
|
||||
@ -0,0 +1,350 @@
|
||||
/*
|
||||
* Copyright 2019 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import * as zlib from 'zlib';
|
||||
|
||||
import { WriteObject, WriteFlags } from './call-interface';
|
||||
import { Channel } from './channel';
|
||||
import { ChannelOptions } from './channel-options';
|
||||
import { CompressionAlgorithms } from './compression-algorithms';
|
||||
import { DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH, LogVerbosity, Status } from './constants';
|
||||
import { BaseFilter, Filter, FilterFactory } from './filter';
|
||||
import * as logging from './logging';
|
||||
import { Metadata, MetadataValue } from './metadata';
|
||||
|
||||
const isCompressionAlgorithmKey = (
|
||||
key: number
|
||||
): key is CompressionAlgorithms => {
|
||||
return (
|
||||
typeof key === 'number' && typeof CompressionAlgorithms[key] === 'string'
|
||||
);
|
||||
};
|
||||
|
||||
type CompressionAlgorithm = keyof typeof CompressionAlgorithms;
|
||||
|
||||
type SharedCompressionFilterConfig = {
|
||||
serverSupportedEncodingHeader?: string;
|
||||
};
|
||||
|
||||
abstract class CompressionHandler {
|
||||
protected abstract compressMessage(message: Buffer): Promise<Buffer>;
|
||||
protected abstract decompressMessage(data: Buffer): Promise<Buffer>;
|
||||
/**
|
||||
* @param message Raw uncompressed message bytes
|
||||
* @param compress Indicates whether the message should be compressed
|
||||
* @return Framed message, compressed if applicable
|
||||
*/
|
||||
async writeMessage(message: Buffer, compress: boolean): Promise<Buffer> {
|
||||
let messageBuffer = message;
|
||||
if (compress) {
|
||||
messageBuffer = await this.compressMessage(messageBuffer);
|
||||
}
|
||||
const output = Buffer.allocUnsafe(messageBuffer.length + 5);
|
||||
output.writeUInt8(compress ? 1 : 0, 0);
|
||||
output.writeUInt32BE(messageBuffer.length, 1);
|
||||
messageBuffer.copy(output, 5);
|
||||
return output;
|
||||
}
|
||||
/**
|
||||
* @param data Framed message, possibly compressed
|
||||
* @return Uncompressed message
|
||||
*/
|
||||
async readMessage(data: Buffer): Promise<Buffer> {
|
||||
const compressed = data.readUInt8(0) === 1;
|
||||
let messageBuffer = data.slice(5);
|
||||
if (compressed) {
|
||||
messageBuffer = await this.decompressMessage(messageBuffer);
|
||||
}
|
||||
return messageBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
class IdentityHandler extends CompressionHandler {
|
||||
async compressMessage(message: Buffer) {
|
||||
return message;
|
||||
}
|
||||
|
||||
async writeMessage(message: Buffer, compress: boolean): Promise<Buffer> {
|
||||
const output = Buffer.allocUnsafe(message.length + 5);
|
||||
/* With "identity" compression, messages should always be marked as
|
||||
* uncompressed */
|
||||
output.writeUInt8(0, 0);
|
||||
output.writeUInt32BE(message.length, 1);
|
||||
message.copy(output, 5);
|
||||
return output;
|
||||
}
|
||||
|
||||
decompressMessage(message: Buffer): Promise<Buffer> {
|
||||
return Promise.reject<Buffer>(
|
||||
new Error(
|
||||
'Received compressed message but "grpc-encoding" header was identity'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class DeflateHandler extends CompressionHandler {
|
||||
constructor(private maxRecvMessageLength: number) {
|
||||
super();
|
||||
}
|
||||
|
||||
compressMessage(message: Buffer) {
|
||||
return new Promise<Buffer>((resolve, reject) => {
|
||||
zlib.deflate(message, (err, output) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(output);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
decompressMessage(message: Buffer) {
|
||||
return new Promise<Buffer>((resolve, reject) => {
|
||||
let totalLength = 0;
|
||||
const messageParts: Buffer[] = [];
|
||||
const decompresser = zlib.createInflate();
|
||||
decompresser.on('data', (chunk: Buffer) => {
|
||||
messageParts.push(chunk);
|
||||
totalLength += chunk.byteLength;
|
||||
if (this.maxRecvMessageLength !== -1 && totalLength > this.maxRecvMessageLength) {
|
||||
decompresser.destroy();
|
||||
reject({
|
||||
code: Status.RESOURCE_EXHAUSTED,
|
||||
details: `Received message that decompresses to a size larger than ${this.maxRecvMessageLength}`
|
||||
});
|
||||
}
|
||||
});
|
||||
decompresser.on('end', () => {
|
||||
resolve(Buffer.concat(messageParts));
|
||||
});
|
||||
decompresser.write(message);
|
||||
decompresser.end();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class GzipHandler extends CompressionHandler {
|
||||
constructor(private maxRecvMessageLength: number) {
|
||||
super();
|
||||
}
|
||||
|
||||
compressMessage(message: Buffer) {
|
||||
return new Promise<Buffer>((resolve, reject) => {
|
||||
zlib.gzip(message, (err, output) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(output);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
decompressMessage(message: Buffer) {
|
||||
return new Promise<Buffer>((resolve, reject) => {
|
||||
let totalLength = 0;
|
||||
const messageParts: Buffer[] = [];
|
||||
const decompresser = zlib.createGunzip();
|
||||
decompresser.on('data', (chunk: Buffer) => {
|
||||
messageParts.push(chunk);
|
||||
totalLength += chunk.byteLength;
|
||||
if (this.maxRecvMessageLength !== -1 && totalLength > this.maxRecvMessageLength) {
|
||||
decompresser.destroy();
|
||||
reject({
|
||||
code: Status.RESOURCE_EXHAUSTED,
|
||||
details: `Received message that decompresses to a size larger than ${this.maxRecvMessageLength}`
|
||||
});
|
||||
}
|
||||
});
|
||||
decompresser.on('end', () => {
|
||||
resolve(Buffer.concat(messageParts));
|
||||
});
|
||||
decompresser.write(message);
|
||||
decompresser.end();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class UnknownHandler extends CompressionHandler {
|
||||
constructor(private readonly compressionName: string) {
|
||||
super();
|
||||
}
|
||||
compressMessage(message: Buffer): Promise<Buffer> {
|
||||
return Promise.reject<Buffer>(
|
||||
new Error(
|
||||
`Received message compressed with unsupported compression method ${this.compressionName}`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
decompressMessage(message: Buffer): Promise<Buffer> {
|
||||
// This should be unreachable
|
||||
return Promise.reject<Buffer>(
|
||||
new Error(`Compression method not supported: ${this.compressionName}`)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getCompressionHandler(compressionName: string, maxReceiveMessageSize: number): CompressionHandler {
|
||||
switch (compressionName) {
|
||||
case 'identity':
|
||||
return new IdentityHandler();
|
||||
case 'deflate':
|
||||
return new DeflateHandler(maxReceiveMessageSize);
|
||||
case 'gzip':
|
||||
return new GzipHandler(maxReceiveMessageSize);
|
||||
default:
|
||||
return new UnknownHandler(compressionName);
|
||||
}
|
||||
}
|
||||
|
||||
export class CompressionFilter extends BaseFilter implements Filter {
|
||||
private sendCompression: CompressionHandler = new IdentityHandler();
|
||||
private receiveCompression: CompressionHandler = new IdentityHandler();
|
||||
private currentCompressionAlgorithm: CompressionAlgorithm = 'identity';
|
||||
private maxReceiveMessageLength: number;
|
||||
|
||||
constructor(
|
||||
channelOptions: ChannelOptions,
|
||||
private sharedFilterConfig: SharedCompressionFilterConfig
|
||||
) {
|
||||
super();
|
||||
|
||||
const compressionAlgorithmKey =
|
||||
channelOptions['grpc.default_compression_algorithm'];
|
||||
this.maxReceiveMessageLength = channelOptions['grpc.max_receive_message_length'] ?? DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH
|
||||
if (compressionAlgorithmKey !== undefined) {
|
||||
if (isCompressionAlgorithmKey(compressionAlgorithmKey)) {
|
||||
const clientSelectedEncoding = CompressionAlgorithms[
|
||||
compressionAlgorithmKey
|
||||
] as CompressionAlgorithm;
|
||||
const serverSupportedEncodings =
|
||||
sharedFilterConfig.serverSupportedEncodingHeader?.split(',');
|
||||
/**
|
||||
* There are two possible situations here:
|
||||
* 1) We don't have any info yet from the server about what compression it supports
|
||||
* In that case we should just use what the client tells us to use
|
||||
* 2) We've previously received a response from the server including a grpc-accept-encoding header
|
||||
* In that case we only want to use the encoding chosen by the client if the server supports it
|
||||
*/
|
||||
if (
|
||||
!serverSupportedEncodings ||
|
||||
serverSupportedEncodings.includes(clientSelectedEncoding)
|
||||
) {
|
||||
this.currentCompressionAlgorithm = clientSelectedEncoding;
|
||||
this.sendCompression = getCompressionHandler(
|
||||
this.currentCompressionAlgorithm,
|
||||
-1
|
||||
);
|
||||
}
|
||||
} else {
|
||||
logging.log(
|
||||
LogVerbosity.ERROR,
|
||||
`Invalid value provided for grpc.default_compression_algorithm option: ${compressionAlgorithmKey}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async sendMetadata(metadata: Promise<Metadata>): Promise<Metadata> {
|
||||
const headers: Metadata = await metadata;
|
||||
headers.set('grpc-accept-encoding', 'identity,deflate,gzip');
|
||||
headers.set('accept-encoding', 'identity');
|
||||
|
||||
// No need to send the header if it's "identity" - behavior is identical; save the bandwidth
|
||||
if (this.currentCompressionAlgorithm === 'identity') {
|
||||
headers.remove('grpc-encoding');
|
||||
} else {
|
||||
headers.set('grpc-encoding', this.currentCompressionAlgorithm);
|
||||
}
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
receiveMetadata(metadata: Metadata): Metadata {
|
||||
const receiveEncoding: MetadataValue[] = metadata.get('grpc-encoding');
|
||||
if (receiveEncoding.length > 0) {
|
||||
const encoding: MetadataValue = receiveEncoding[0];
|
||||
if (typeof encoding === 'string') {
|
||||
this.receiveCompression = getCompressionHandler(encoding, this.maxReceiveMessageLength);
|
||||
}
|
||||
}
|
||||
metadata.remove('grpc-encoding');
|
||||
|
||||
/* Check to see if the compression we're using to send messages is supported by the server
|
||||
* If not, reset the sendCompression filter and have it use the default IdentityHandler */
|
||||
const serverSupportedEncodingsHeader = metadata.get(
|
||||
'grpc-accept-encoding'
|
||||
)[0] as string | undefined;
|
||||
if (serverSupportedEncodingsHeader) {
|
||||
this.sharedFilterConfig.serverSupportedEncodingHeader =
|
||||
serverSupportedEncodingsHeader;
|
||||
const serverSupportedEncodings =
|
||||
serverSupportedEncodingsHeader.split(',');
|
||||
|
||||
if (
|
||||
!serverSupportedEncodings.includes(this.currentCompressionAlgorithm)
|
||||
) {
|
||||
this.sendCompression = new IdentityHandler();
|
||||
this.currentCompressionAlgorithm = 'identity';
|
||||
}
|
||||
}
|
||||
metadata.remove('grpc-accept-encoding');
|
||||
return metadata;
|
||||
}
|
||||
|
||||
async sendMessage(message: Promise<WriteObject>): Promise<WriteObject> {
|
||||
/* This filter is special. The input message is the bare message bytes,
|
||||
* and the output is a framed and possibly compressed message. For this
|
||||
* reason, this filter should be at the bottom of the filter stack */
|
||||
const resolvedMessage: WriteObject = await message;
|
||||
let compress: boolean;
|
||||
if (this.sendCompression instanceof IdentityHandler) {
|
||||
compress = false;
|
||||
} else {
|
||||
compress = ((resolvedMessage.flags ?? 0) & WriteFlags.NoCompress) === 0;
|
||||
}
|
||||
|
||||
return {
|
||||
message: await this.sendCompression.writeMessage(
|
||||
resolvedMessage.message,
|
||||
compress
|
||||
),
|
||||
flags: resolvedMessage.flags,
|
||||
};
|
||||
}
|
||||
|
||||
async receiveMessage(message: Promise<Buffer>) {
|
||||
/* This filter is also special. The input message is framed and possibly
|
||||
* compressed, and the output message is deframed and uncompressed. So
|
||||
* this is another reason that this filter should be at the bottom of the
|
||||
* filter stack. */
|
||||
return this.receiveCompression.readMessage(await message);
|
||||
}
|
||||
}
|
||||
|
||||
export class CompressionFilterFactory
|
||||
implements FilterFactory<CompressionFilter>
|
||||
{
|
||||
private sharedFilterConfig: SharedCompressionFilterConfig = {};
|
||||
constructor(channel: Channel, private readonly options: ChannelOptions) {}
|
||||
createFilter(): CompressionFilter {
|
||||
return new CompressionFilter(this.options, this.sharedFilterConfig);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2021 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
export enum ConnectivityState {
|
||||
IDLE,
|
||||
CONNECTING,
|
||||
READY,
|
||||
TRANSIENT_FAILURE,
|
||||
SHUTDOWN,
|
||||
}
|
||||
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2019 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
export enum Status {
|
||||
OK = 0,
|
||||
CANCELLED,
|
||||
UNKNOWN,
|
||||
INVALID_ARGUMENT,
|
||||
DEADLINE_EXCEEDED,
|
||||
NOT_FOUND,
|
||||
ALREADY_EXISTS,
|
||||
PERMISSION_DENIED,
|
||||
RESOURCE_EXHAUSTED,
|
||||
FAILED_PRECONDITION,
|
||||
ABORTED,
|
||||
OUT_OF_RANGE,
|
||||
UNIMPLEMENTED,
|
||||
INTERNAL,
|
||||
UNAVAILABLE,
|
||||
DATA_LOSS,
|
||||
UNAUTHENTICATED,
|
||||
}
|
||||
|
||||
export enum LogVerbosity {
|
||||
DEBUG = 0,
|
||||
INFO,
|
||||
ERROR,
|
||||
NONE,
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: This enum is not currently used in any implemented API in this
|
||||
* library. It is included only for type parity with the other implementation.
|
||||
*/
|
||||
export enum Propagate {
|
||||
DEADLINE = 1,
|
||||
CENSUS_STATS_CONTEXT = 2,
|
||||
CENSUS_TRACING_CONTEXT = 4,
|
||||
CANCELLATION = 8,
|
||||
// https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/propagation_bits.h#L43
|
||||
DEFAULTS = 0xffff |
|
||||
Propagate.DEADLINE |
|
||||
Propagate.CENSUS_STATS_CONTEXT |
|
||||
Propagate.CENSUS_TRACING_CONTEXT |
|
||||
Propagate.CANCELLATION,
|
||||
}
|
||||
|
||||
// -1 means unlimited
|
||||
export const DEFAULT_MAX_SEND_MESSAGE_LENGTH = -1;
|
||||
|
||||
// 4 MB default
|
||||
export const DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH = 4 * 1024 * 1024;
|
||||
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2022 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import { Status } from './constants';
|
||||
|
||||
const INAPPROPRIATE_CONTROL_PLANE_CODES: Status[] = [
|
||||
Status.OK,
|
||||
Status.INVALID_ARGUMENT,
|
||||
Status.NOT_FOUND,
|
||||
Status.ALREADY_EXISTS,
|
||||
Status.FAILED_PRECONDITION,
|
||||
Status.ABORTED,
|
||||
Status.OUT_OF_RANGE,
|
||||
Status.DATA_LOSS,
|
||||
];
|
||||
|
||||
export function restrictControlPlaneStatusCode(
|
||||
code: Status,
|
||||
details: string
|
||||
): { code: Status; details: string } {
|
||||
if (INAPPROPRIATE_CONTROL_PLANE_CODES.includes(code)) {
|
||||
return {
|
||||
code: Status.INTERNAL,
|
||||
details: `Invalid status from control plane: ${code} ${Status[code]} ${details}`,
|
||||
};
|
||||
} else {
|
||||
return { code, details };
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2019 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
export type Deadline = Date | number;
|
||||
|
||||
export function minDeadline(...deadlineList: Deadline[]): Deadline {
|
||||
let minValue = Infinity;
|
||||
for (const deadline of deadlineList) {
|
||||
const deadlineMsecs =
|
||||
deadline instanceof Date ? deadline.getTime() : deadline;
|
||||
if (deadlineMsecs < minValue) {
|
||||
minValue = deadlineMsecs;
|
||||
}
|
||||
}
|
||||
return minValue;
|
||||
}
|
||||
|
||||
const units: Array<[string, number]> = [
|
||||
['m', 1],
|
||||
['S', 1000],
|
||||
['M', 60 * 1000],
|
||||
['H', 60 * 60 * 1000],
|
||||
];
|
||||
|
||||
export function getDeadlineTimeoutString(deadline: Deadline) {
|
||||
const now = new Date().getTime();
|
||||
if (deadline instanceof Date) {
|
||||
deadline = deadline.getTime();
|
||||
}
|
||||
const timeoutMs = Math.max(deadline - now, 0);
|
||||
for (const [unit, factor] of units) {
|
||||
const amount = timeoutMs / factor;
|
||||
if (amount < 1e8) {
|
||||
return String(Math.ceil(amount)) + unit;
|
||||
}
|
||||
}
|
||||
throw new Error('Deadline is too far in the future');
|
||||
}
|
||||
|
||||
/**
|
||||
* See https://nodejs.org/api/timers.html#settimeoutcallback-delay-args
|
||||
* In particular, "When delay is larger than 2147483647 or less than 1, the
|
||||
* delay will be set to 1. Non-integer delays are truncated to an integer."
|
||||
* This number of milliseconds is almost 25 days.
|
||||
*/
|
||||
const MAX_TIMEOUT_TIME = 2147483647;
|
||||
|
||||
/**
|
||||
* Get the timeout value that should be passed to setTimeout now for the timer
|
||||
* to end at the deadline. For any deadline before now, the timer should end
|
||||
* immediately, represented by a value of 0. For any deadline more than
|
||||
* MAX_TIMEOUT_TIME milliseconds in the future, a timer cannot be set that will
|
||||
* end at that time, so it is treated as infinitely far in the future.
|
||||
* @param deadline
|
||||
* @returns
|
||||
*/
|
||||
export function getRelativeTimeout(deadline: Deadline) {
|
||||
const deadlineMs = deadline instanceof Date ? deadline.getTime() : deadline;
|
||||
const now = new Date().getTime();
|
||||
const timeout = deadlineMs - now;
|
||||
if (timeout < 0) {
|
||||
return 0;
|
||||
} else if (timeout > MAX_TIMEOUT_TIME) {
|
||||
return Infinity;
|
||||
} else {
|
||||
return timeout;
|
||||
}
|
||||
}
|
||||
|
||||
export function deadlineToString(deadline: Deadline): string {
|
||||
if (deadline instanceof Date) {
|
||||
return deadline.toISOString();
|
||||
} else {
|
||||
const dateDeadline = new Date(deadline);
|
||||
if (Number.isNaN(dateDeadline.getTime())) {
|
||||
return '' + deadline;
|
||||
} else {
|
||||
return dateDeadline.toISOString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2022 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
export interface Duration {
|
||||
seconds: number;
|
||||
nanos: number;
|
||||
}
|
||||
|
||||
export function msToDuration(millis: number): Duration {
|
||||
return {
|
||||
seconds: (millis / 1000) | 0,
|
||||
nanos: ((millis % 1000) * 1_000_000) | 0,
|
||||
};
|
||||
}
|
||||
|
||||
export function durationToMs(duration: Duration): number {
|
||||
return (duration.seconds * 1000 + duration.nanos / 1_000_000) | 0;
|
||||
}
|
||||
|
||||
export function isDuration(value: any): value is Duration {
|
||||
return typeof value.seconds === 'number' && typeof value.nanos === 'number';
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2022 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
export function getErrorMessage(error: unknown): string {
|
||||
if (error instanceof Error) {
|
||||
return error.message;
|
||||
} else {
|
||||
return String(error);
|
||||
}
|
||||
}
|
||||
|
||||
export function getErrorCode(error: unknown): number | null {
|
||||
if (
|
||||
typeof error === 'object' &&
|
||||
error !== null &&
|
||||
'code' in error &&
|
||||
typeof (error as Record<string, unknown>).code === 'number'
|
||||
) {
|
||||
return (error as Record<string, number>).code;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2019 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
export 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;
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
export { trace, log } from './logging';
|
||||
export {
|
||||
Resolver,
|
||||
ResolverListener,
|
||||
registerResolver,
|
||||
ConfigSelector,
|
||||
createResolver,
|
||||
} from './resolver';
|
||||
export { GrpcUri, uriToString } from './uri-parser';
|
||||
export { Duration, durationToMs } from './duration';
|
||||
export { ServiceConfig, MethodConfig, RetryPolicy } from './service-config';
|
||||
export { BackoffTimeout } from './backoff-timeout';
|
||||
export {
|
||||
LoadBalancer,
|
||||
LoadBalancingConfig,
|
||||
ChannelControlHelper,
|
||||
createChildChannelControlHelper,
|
||||
registerLoadBalancerType,
|
||||
getFirstUsableConfig,
|
||||
validateLoadBalancingConfig,
|
||||
} from './load-balancer';
|
||||
export {
|
||||
SubchannelAddress,
|
||||
subchannelAddressToString,
|
||||
} from './subchannel-address';
|
||||
export { ChildLoadBalancerHandler } from './load-balancer-child-handler';
|
||||
export {
|
||||
Picker,
|
||||
UnavailablePicker,
|
||||
QueuePicker,
|
||||
PickResult,
|
||||
PickArgs,
|
||||
PickResultType,
|
||||
} from './picker';
|
||||
export { Call as CallStream } from './call-interface';
|
||||
export { Filter, BaseFilter, FilterFactory } from './filter';
|
||||
export { FilterStackFactory } from './filter-stack';
|
||||
export { registerAdminService } from './admin';
|
||||
export {
|
||||
SubchannelInterface,
|
||||
BaseSubchannelWrapper,
|
||||
ConnectivityStateListener,
|
||||
} from './subchannel-interface';
|
||||
export {
|
||||
OutlierDetectionLoadBalancingConfig,
|
||||
SuccessRateEjectionConfig,
|
||||
FailurePercentageEjectionConfig,
|
||||
} from './load-balancer-outlier-detection';
|
||||
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2019 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import { StatusObject, WriteObject } from './call-interface';
|
||||
import { Filter, FilterFactory } from './filter';
|
||||
import { Metadata } from './metadata';
|
||||
|
||||
export class FilterStack implements Filter {
|
||||
constructor(private readonly filters: Filter[]) {}
|
||||
|
||||
sendMetadata(metadata: Promise<Metadata>): Promise<Metadata> {
|
||||
let result: Promise<Metadata> = metadata;
|
||||
|
||||
for (let i = 0; i < this.filters.length; i++) {
|
||||
result = this.filters[i].sendMetadata(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
receiveMetadata(metadata: Metadata) {
|
||||
let result: Metadata = metadata;
|
||||
|
||||
for (let i = this.filters.length - 1; i >= 0; i--) {
|
||||
result = this.filters[i].receiveMetadata(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
sendMessage(message: Promise<WriteObject>): Promise<WriteObject> {
|
||||
let result: Promise<WriteObject> = message;
|
||||
|
||||
for (let i = 0; i < this.filters.length; i++) {
|
||||
result = this.filters[i].sendMessage(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
receiveMessage(message: Promise<Buffer>): Promise<Buffer> {
|
||||
let result: Promise<Buffer> = message;
|
||||
|
||||
for (let i = this.filters.length - 1; i >= 0; i--) {
|
||||
result = this.filters[i].receiveMessage(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
receiveTrailers(status: StatusObject): StatusObject {
|
||||
let result: StatusObject = status;
|
||||
|
||||
for (let i = this.filters.length - 1; i >= 0; i--) {
|
||||
result = this.filters[i].receiveTrailers(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
push(filters: Filter[]) {
|
||||
this.filters.unshift(...filters);
|
||||
}
|
||||
|
||||
getFilters(): Filter[] {
|
||||
return this.filters;
|
||||
}
|
||||
}
|
||||
|
||||
export class FilterStackFactory implements FilterFactory<FilterStack> {
|
||||
constructor(private readonly factories: Array<FilterFactory<Filter>>) {}
|
||||
|
||||
push(filterFactories: FilterFactory<Filter>[]) {
|
||||
this.factories.unshift(...filterFactories);
|
||||
}
|
||||
|
||||
clone(): FilterStackFactory {
|
||||
return new FilterStackFactory([...this.factories]);
|
||||
}
|
||||
|
||||
createFilter(): FilterStack {
|
||||
return new FilterStack(
|
||||
this.factories.map(factory => factory.createFilter())
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2019 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
import { StatusObject, WriteObject } from './call-interface';
|
||||
import { Metadata } from './metadata';
|
||||
|
||||
/**
|
||||
* Filter classes represent related per-call logic and state that is primarily
|
||||
* used to modify incoming and outgoing data. All async filters can be
|
||||
* rejected. The rejection error must be a StatusObject, and a rejection will
|
||||
* cause the call to end with that status.
|
||||
*/
|
||||
export interface Filter {
|
||||
sendMetadata(metadata: Promise<Metadata>): Promise<Metadata>;
|
||||
|
||||
receiveMetadata(metadata: Metadata): Metadata;
|
||||
|
||||
sendMessage(message: Promise<WriteObject>): Promise<WriteObject>;
|
||||
|
||||
receiveMessage(message: Promise<Buffer>): Promise<Buffer>;
|
||||
|
||||
receiveTrailers(status: StatusObject): StatusObject;
|
||||
}
|
||||
|
||||
export abstract class BaseFilter implements Filter {
|
||||
async sendMetadata(metadata: Promise<Metadata>): Promise<Metadata> {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
receiveMetadata(metadata: Metadata): Metadata {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
async sendMessage(message: Promise<WriteObject>): Promise<WriteObject> {
|
||||
return message;
|
||||
}
|
||||
|
||||
async receiveMessage(message: Promise<Buffer>): Promise<Buffer> {
|
||||
return message;
|
||||
}
|
||||
|
||||
receiveTrailers(status: StatusObject): StatusObject {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
export interface FilterFactory<T extends Filter> {
|
||||
createFilter(): T;
|
||||
}
|
||||
@ -0,0 +1,73 @@
|
||||
import type * as grpc from '../index';
|
||||
import type { MessageTypeDefinition } from '@grpc/proto-loader';
|
||||
|
||||
import type { ChannelzClient as _grpc_channelz_v1_ChannelzClient, ChannelzDefinition as _grpc_channelz_v1_ChannelzDefinition } from './grpc/channelz/v1/Channelz';
|
||||
|
||||
type SubtypeConstructor<Constructor extends new (...args: any) => any, Subtype> = {
|
||||
new(...args: ConstructorParameters<Constructor>): Subtype;
|
||||
};
|
||||
|
||||
export interface ProtoGrpcType {
|
||||
google: {
|
||||
protobuf: {
|
||||
Any: MessageTypeDefinition
|
||||
BoolValue: MessageTypeDefinition
|
||||
BytesValue: MessageTypeDefinition
|
||||
DoubleValue: MessageTypeDefinition
|
||||
Duration: MessageTypeDefinition
|
||||
FloatValue: MessageTypeDefinition
|
||||
Int32Value: MessageTypeDefinition
|
||||
Int64Value: MessageTypeDefinition
|
||||
StringValue: MessageTypeDefinition
|
||||
Timestamp: MessageTypeDefinition
|
||||
UInt32Value: MessageTypeDefinition
|
||||
UInt64Value: MessageTypeDefinition
|
||||
}
|
||||
}
|
||||
grpc: {
|
||||
channelz: {
|
||||
v1: {
|
||||
Address: MessageTypeDefinition
|
||||
Channel: MessageTypeDefinition
|
||||
ChannelConnectivityState: MessageTypeDefinition
|
||||
ChannelData: MessageTypeDefinition
|
||||
ChannelRef: MessageTypeDefinition
|
||||
ChannelTrace: MessageTypeDefinition
|
||||
ChannelTraceEvent: MessageTypeDefinition
|
||||
/**
|
||||
* Channelz is a service exposed by gRPC servers that provides detailed debug
|
||||
* information.
|
||||
*/
|
||||
Channelz: SubtypeConstructor<typeof grpc.Client, _grpc_channelz_v1_ChannelzClient> & { service: _grpc_channelz_v1_ChannelzDefinition }
|
||||
GetChannelRequest: MessageTypeDefinition
|
||||
GetChannelResponse: MessageTypeDefinition
|
||||
GetServerRequest: MessageTypeDefinition
|
||||
GetServerResponse: MessageTypeDefinition
|
||||
GetServerSocketsRequest: MessageTypeDefinition
|
||||
GetServerSocketsResponse: MessageTypeDefinition
|
||||
GetServersRequest: MessageTypeDefinition
|
||||
GetServersResponse: MessageTypeDefinition
|
||||
GetSocketRequest: MessageTypeDefinition
|
||||
GetSocketResponse: MessageTypeDefinition
|
||||
GetSubchannelRequest: MessageTypeDefinition
|
||||
GetSubchannelResponse: MessageTypeDefinition
|
||||
GetTopChannelsRequest: MessageTypeDefinition
|
||||
GetTopChannelsResponse: MessageTypeDefinition
|
||||
Security: MessageTypeDefinition
|
||||
Server: MessageTypeDefinition
|
||||
ServerData: MessageTypeDefinition
|
||||
ServerRef: MessageTypeDefinition
|
||||
Socket: MessageTypeDefinition
|
||||
SocketData: MessageTypeDefinition
|
||||
SocketOption: MessageTypeDefinition
|
||||
SocketOptionLinger: MessageTypeDefinition
|
||||
SocketOptionTcpInfo: MessageTypeDefinition
|
||||
SocketOptionTimeout: MessageTypeDefinition
|
||||
SocketRef: MessageTypeDefinition
|
||||
Subchannel: MessageTypeDefinition
|
||||
SubchannelRef: MessageTypeDefinition
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/Any.ts
generated
vendored
13
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/Any.ts
generated
vendored
@ -0,0 +1,13 @@
|
||||
// Original file: null
|
||||
|
||||
import type { AnyExtension } from '@grpc/proto-loader';
|
||||
|
||||
export type Any = AnyExtension | {
|
||||
type_url: string;
|
||||
value: Buffer | Uint8Array | string;
|
||||
}
|
||||
|
||||
export interface Any__Output {
|
||||
'type_url': (string);
|
||||
'value': (Buffer);
|
||||
}
|
||||
10
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/BoolValue.ts
generated
vendored
10
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/BoolValue.ts
generated
vendored
@ -0,0 +1,10 @@
|
||||
// Original file: null
|
||||
|
||||
|
||||
export interface BoolValue {
|
||||
'value'?: (boolean);
|
||||
}
|
||||
|
||||
export interface BoolValue__Output {
|
||||
'value': (boolean);
|
||||
}
|
||||
10
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/BytesValue.ts
generated
vendored
10
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/BytesValue.ts
generated
vendored
@ -0,0 +1,10 @@
|
||||
// Original file: null
|
||||
|
||||
|
||||
export interface BytesValue {
|
||||
'value'?: (Buffer | Uint8Array | string);
|
||||
}
|
||||
|
||||
export interface BytesValue__Output {
|
||||
'value': (Buffer);
|
||||
}
|
||||
10
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/DoubleValue.ts
generated
vendored
10
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/DoubleValue.ts
generated
vendored
@ -0,0 +1,10 @@
|
||||
// Original file: null
|
||||
|
||||
|
||||
export interface DoubleValue {
|
||||
'value'?: (number | string);
|
||||
}
|
||||
|
||||
export interface DoubleValue__Output {
|
||||
'value': (number);
|
||||
}
|
||||
13
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/Duration.ts
generated
vendored
13
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/Duration.ts
generated
vendored
@ -0,0 +1,13 @@
|
||||
// Original file: null
|
||||
|
||||
import type { Long } from '@grpc/proto-loader';
|
||||
|
||||
export interface Duration {
|
||||
'seconds'?: (number | string | Long);
|
||||
'nanos'?: (number);
|
||||
}
|
||||
|
||||
export interface Duration__Output {
|
||||
'seconds': (string);
|
||||
'nanos': (number);
|
||||
}
|
||||
10
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/FloatValue.ts
generated
vendored
10
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/FloatValue.ts
generated
vendored
@ -0,0 +1,10 @@
|
||||
// Original file: null
|
||||
|
||||
|
||||
export interface FloatValue {
|
||||
'value'?: (number | string);
|
||||
}
|
||||
|
||||
export interface FloatValue__Output {
|
||||
'value': (number);
|
||||
}
|
||||
10
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/Int32Value.ts
generated
vendored
10
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/Int32Value.ts
generated
vendored
@ -0,0 +1,10 @@
|
||||
// Original file: null
|
||||
|
||||
|
||||
export interface Int32Value {
|
||||
'value'?: (number);
|
||||
}
|
||||
|
||||
export interface Int32Value__Output {
|
||||
'value': (number);
|
||||
}
|
||||
11
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/Int64Value.ts
generated
vendored
11
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/Int64Value.ts
generated
vendored
@ -0,0 +1,11 @@
|
||||
// Original file: null
|
||||
|
||||
import type { Long } from '@grpc/proto-loader';
|
||||
|
||||
export interface Int64Value {
|
||||
'value'?: (number | string | Long);
|
||||
}
|
||||
|
||||
export interface Int64Value__Output {
|
||||
'value': (string);
|
||||
}
|
||||
10
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/StringValue.ts
generated
vendored
10
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/StringValue.ts
generated
vendored
@ -0,0 +1,10 @@
|
||||
// Original file: null
|
||||
|
||||
|
||||
export interface StringValue {
|
||||
'value'?: (string);
|
||||
}
|
||||
|
||||
export interface StringValue__Output {
|
||||
'value': (string);
|
||||
}
|
||||
13
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/Timestamp.ts
generated
vendored
13
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/Timestamp.ts
generated
vendored
@ -0,0 +1,13 @@
|
||||
// Original file: null
|
||||
|
||||
import type { Long } from '@grpc/proto-loader';
|
||||
|
||||
export interface Timestamp {
|
||||
'seconds'?: (number | string | Long);
|
||||
'nanos'?: (number);
|
||||
}
|
||||
|
||||
export interface Timestamp__Output {
|
||||
'seconds': (string);
|
||||
'nanos': (number);
|
||||
}
|
||||
10
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/UInt32Value.ts
generated
vendored
10
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/UInt32Value.ts
generated
vendored
@ -0,0 +1,10 @@
|
||||
// Original file: null
|
||||
|
||||
|
||||
export interface UInt32Value {
|
||||
'value'?: (number);
|
||||
}
|
||||
|
||||
export interface UInt32Value__Output {
|
||||
'value': (number);
|
||||
}
|
||||
11
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/UInt64Value.ts
generated
vendored
11
travel-backend/node_modules/@grpc/grpc-js/src/generated/google/protobuf/UInt64Value.ts
generated
vendored
@ -0,0 +1,11 @@
|
||||
// Original file: null
|
||||
|
||||
import type { Long } from '@grpc/proto-loader';
|
||||
|
||||
export interface UInt64Value {
|
||||
'value'?: (number | string | Long);
|
||||
}
|
||||
|
||||
export interface UInt64Value__Output {
|
||||
'value': (string);
|
||||
}
|
||||
89
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/Address.ts
generated
vendored
89
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/Address.ts
generated
vendored
@ -0,0 +1,89 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any';
|
||||
|
||||
/**
|
||||
* An address type not included above.
|
||||
*/
|
||||
export interface _grpc_channelz_v1_Address_OtherAddress {
|
||||
/**
|
||||
* The human readable version of the value. This value should be set.
|
||||
*/
|
||||
'name'?: (string);
|
||||
/**
|
||||
* The actual address message.
|
||||
*/
|
||||
'value'?: (_google_protobuf_Any | null);
|
||||
}
|
||||
|
||||
/**
|
||||
* An address type not included above.
|
||||
*/
|
||||
export interface _grpc_channelz_v1_Address_OtherAddress__Output {
|
||||
/**
|
||||
* The human readable version of the value. This value should be set.
|
||||
*/
|
||||
'name': (string);
|
||||
/**
|
||||
* The actual address message.
|
||||
*/
|
||||
'value': (_google_protobuf_Any__Output | null);
|
||||
}
|
||||
|
||||
export interface _grpc_channelz_v1_Address_TcpIpAddress {
|
||||
/**
|
||||
* Either the IPv4 or IPv6 address in bytes. Will be either 4 bytes or 16
|
||||
* bytes in length.
|
||||
*/
|
||||
'ip_address'?: (Buffer | Uint8Array | string);
|
||||
/**
|
||||
* 0-64k, or -1 if not appropriate.
|
||||
*/
|
||||
'port'?: (number);
|
||||
}
|
||||
|
||||
export interface _grpc_channelz_v1_Address_TcpIpAddress__Output {
|
||||
/**
|
||||
* Either the IPv4 or IPv6 address in bytes. Will be either 4 bytes or 16
|
||||
* bytes in length.
|
||||
*/
|
||||
'ip_address': (Buffer);
|
||||
/**
|
||||
* 0-64k, or -1 if not appropriate.
|
||||
*/
|
||||
'port': (number);
|
||||
}
|
||||
|
||||
/**
|
||||
* A Unix Domain Socket address.
|
||||
*/
|
||||
export interface _grpc_channelz_v1_Address_UdsAddress {
|
||||
'filename'?: (string);
|
||||
}
|
||||
|
||||
/**
|
||||
* A Unix Domain Socket address.
|
||||
*/
|
||||
export interface _grpc_channelz_v1_Address_UdsAddress__Output {
|
||||
'filename': (string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Address represents the address used to create the socket.
|
||||
*/
|
||||
export interface Address {
|
||||
'tcpip_address'?: (_grpc_channelz_v1_Address_TcpIpAddress | null);
|
||||
'uds_address'?: (_grpc_channelz_v1_Address_UdsAddress | null);
|
||||
'other_address'?: (_grpc_channelz_v1_Address_OtherAddress | null);
|
||||
'address'?: "tcpip_address"|"uds_address"|"other_address";
|
||||
}
|
||||
|
||||
/**
|
||||
* Address represents the address used to create the socket.
|
||||
*/
|
||||
export interface Address__Output {
|
||||
'tcpip_address'?: (_grpc_channelz_v1_Address_TcpIpAddress__Output | null);
|
||||
'uds_address'?: (_grpc_channelz_v1_Address_UdsAddress__Output | null);
|
||||
'other_address'?: (_grpc_channelz_v1_Address_OtherAddress__Output | null);
|
||||
'address': "tcpip_address"|"uds_address"|"other_address";
|
||||
}
|
||||
68
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/Channel.ts
generated
vendored
68
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/Channel.ts
generated
vendored
@ -0,0 +1,68 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { ChannelRef as _grpc_channelz_v1_ChannelRef, ChannelRef__Output as _grpc_channelz_v1_ChannelRef__Output } from '../../../grpc/channelz/v1/ChannelRef';
|
||||
import type { ChannelData as _grpc_channelz_v1_ChannelData, ChannelData__Output as _grpc_channelz_v1_ChannelData__Output } from '../../../grpc/channelz/v1/ChannelData';
|
||||
import type { SubchannelRef as _grpc_channelz_v1_SubchannelRef, SubchannelRef__Output as _grpc_channelz_v1_SubchannelRef__Output } from '../../../grpc/channelz/v1/SubchannelRef';
|
||||
import type { SocketRef as _grpc_channelz_v1_SocketRef, SocketRef__Output as _grpc_channelz_v1_SocketRef__Output } from '../../../grpc/channelz/v1/SocketRef';
|
||||
|
||||
/**
|
||||
* Channel is a logical grouping of channels, subchannels, and sockets.
|
||||
*/
|
||||
export interface Channel {
|
||||
/**
|
||||
* The identifier for this channel. This should bet set.
|
||||
*/
|
||||
'ref'?: (_grpc_channelz_v1_ChannelRef | null);
|
||||
/**
|
||||
* Data specific to this channel.
|
||||
*/
|
||||
'data'?: (_grpc_channelz_v1_ChannelData | null);
|
||||
/**
|
||||
* There are no ordering guarantees on the order of channel refs.
|
||||
* There may not be cycles in the ref graph.
|
||||
* A channel ref may be present in more than one channel or subchannel.
|
||||
*/
|
||||
'channel_ref'?: (_grpc_channelz_v1_ChannelRef)[];
|
||||
/**
|
||||
* At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
|
||||
* There are no ordering guarantees on the order of subchannel refs.
|
||||
* There may not be cycles in the ref graph.
|
||||
* A sub channel ref may be present in more than one channel or subchannel.
|
||||
*/
|
||||
'subchannel_ref'?: (_grpc_channelz_v1_SubchannelRef)[];
|
||||
/**
|
||||
* There are no ordering guarantees on the order of sockets.
|
||||
*/
|
||||
'socket_ref'?: (_grpc_channelz_v1_SocketRef)[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Channel is a logical grouping of channels, subchannels, and sockets.
|
||||
*/
|
||||
export interface Channel__Output {
|
||||
/**
|
||||
* The identifier for this channel. This should bet set.
|
||||
*/
|
||||
'ref': (_grpc_channelz_v1_ChannelRef__Output | null);
|
||||
/**
|
||||
* Data specific to this channel.
|
||||
*/
|
||||
'data': (_grpc_channelz_v1_ChannelData__Output | null);
|
||||
/**
|
||||
* There are no ordering guarantees on the order of channel refs.
|
||||
* There may not be cycles in the ref graph.
|
||||
* A channel ref may be present in more than one channel or subchannel.
|
||||
*/
|
||||
'channel_ref': (_grpc_channelz_v1_ChannelRef__Output)[];
|
||||
/**
|
||||
* At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
|
||||
* There are no ordering guarantees on the order of subchannel refs.
|
||||
* There may not be cycles in the ref graph.
|
||||
* A sub channel ref may be present in more than one channel or subchannel.
|
||||
*/
|
||||
'subchannel_ref': (_grpc_channelz_v1_SubchannelRef__Output)[];
|
||||
/**
|
||||
* There are no ordering guarantees on the order of sockets.
|
||||
*/
|
||||
'socket_ref': (_grpc_channelz_v1_SocketRef__Output)[];
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
export const _grpc_channelz_v1_ChannelConnectivityState_State = {
|
||||
UNKNOWN: 'UNKNOWN',
|
||||
IDLE: 'IDLE',
|
||||
CONNECTING: 'CONNECTING',
|
||||
READY: 'READY',
|
||||
TRANSIENT_FAILURE: 'TRANSIENT_FAILURE',
|
||||
SHUTDOWN: 'SHUTDOWN',
|
||||
} as const;
|
||||
|
||||
export type _grpc_channelz_v1_ChannelConnectivityState_State =
|
||||
| 'UNKNOWN'
|
||||
| 0
|
||||
| 'IDLE'
|
||||
| 1
|
||||
| 'CONNECTING'
|
||||
| 2
|
||||
| 'READY'
|
||||
| 3
|
||||
| 'TRANSIENT_FAILURE'
|
||||
| 4
|
||||
| 'SHUTDOWN'
|
||||
| 5
|
||||
|
||||
export type _grpc_channelz_v1_ChannelConnectivityState_State__Output = typeof _grpc_channelz_v1_ChannelConnectivityState_State[keyof typeof _grpc_channelz_v1_ChannelConnectivityState_State]
|
||||
|
||||
/**
|
||||
* These come from the specified states in this document:
|
||||
* https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md
|
||||
*/
|
||||
export interface ChannelConnectivityState {
|
||||
'state'?: (_grpc_channelz_v1_ChannelConnectivityState_State);
|
||||
}
|
||||
|
||||
/**
|
||||
* These come from the specified states in this document:
|
||||
* https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md
|
||||
*/
|
||||
export interface ChannelConnectivityState__Output {
|
||||
'state': (_grpc_channelz_v1_ChannelConnectivityState_State__Output);
|
||||
}
|
||||
76
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/ChannelData.ts
generated
vendored
76
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/ChannelData.ts
generated
vendored
@ -0,0 +1,76 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { ChannelConnectivityState as _grpc_channelz_v1_ChannelConnectivityState, ChannelConnectivityState__Output as _grpc_channelz_v1_ChannelConnectivityState__Output } from '../../../grpc/channelz/v1/ChannelConnectivityState';
|
||||
import type { ChannelTrace as _grpc_channelz_v1_ChannelTrace, ChannelTrace__Output as _grpc_channelz_v1_ChannelTrace__Output } from '../../../grpc/channelz/v1/ChannelTrace';
|
||||
import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp';
|
||||
import type { Long } from '@grpc/proto-loader';
|
||||
|
||||
/**
|
||||
* Channel data is data related to a specific Channel or Subchannel.
|
||||
*/
|
||||
export interface ChannelData {
|
||||
/**
|
||||
* The connectivity state of the channel or subchannel. Implementations
|
||||
* should always set this.
|
||||
*/
|
||||
'state'?: (_grpc_channelz_v1_ChannelConnectivityState | null);
|
||||
/**
|
||||
* The target this channel originally tried to connect to. May be absent
|
||||
*/
|
||||
'target'?: (string);
|
||||
/**
|
||||
* A trace of recent events on the channel. May be absent.
|
||||
*/
|
||||
'trace'?: (_grpc_channelz_v1_ChannelTrace | null);
|
||||
/**
|
||||
* The number of calls started on the channel
|
||||
*/
|
||||
'calls_started'?: (number | string | Long);
|
||||
/**
|
||||
* The number of calls that have completed with an OK status
|
||||
*/
|
||||
'calls_succeeded'?: (number | string | Long);
|
||||
/**
|
||||
* The number of calls that have completed with a non-OK status
|
||||
*/
|
||||
'calls_failed'?: (number | string | Long);
|
||||
/**
|
||||
* The last time a call was started on the channel.
|
||||
*/
|
||||
'last_call_started_timestamp'?: (_google_protobuf_Timestamp | null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Channel data is data related to a specific Channel or Subchannel.
|
||||
*/
|
||||
export interface ChannelData__Output {
|
||||
/**
|
||||
* The connectivity state of the channel or subchannel. Implementations
|
||||
* should always set this.
|
||||
*/
|
||||
'state': (_grpc_channelz_v1_ChannelConnectivityState__Output | null);
|
||||
/**
|
||||
* The target this channel originally tried to connect to. May be absent
|
||||
*/
|
||||
'target': (string);
|
||||
/**
|
||||
* A trace of recent events on the channel. May be absent.
|
||||
*/
|
||||
'trace': (_grpc_channelz_v1_ChannelTrace__Output | null);
|
||||
/**
|
||||
* The number of calls started on the channel
|
||||
*/
|
||||
'calls_started': (string);
|
||||
/**
|
||||
* The number of calls that have completed with an OK status
|
||||
*/
|
||||
'calls_succeeded': (string);
|
||||
/**
|
||||
* The number of calls that have completed with a non-OK status
|
||||
*/
|
||||
'calls_failed': (string);
|
||||
/**
|
||||
* The last time a call was started on the channel.
|
||||
*/
|
||||
'last_call_started_timestamp': (_google_protobuf_Timestamp__Output | null);
|
||||
}
|
||||
31
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/ChannelRef.ts
generated
vendored
31
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/ChannelRef.ts
generated
vendored
@ -0,0 +1,31 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Long } from '@grpc/proto-loader';
|
||||
|
||||
/**
|
||||
* ChannelRef is a reference to a Channel.
|
||||
*/
|
||||
export interface ChannelRef {
|
||||
/**
|
||||
* The globally unique id for this channel. Must be a positive number.
|
||||
*/
|
||||
'channel_id'?: (number | string | Long);
|
||||
/**
|
||||
* An optional name associated with the channel.
|
||||
*/
|
||||
'name'?: (string);
|
||||
}
|
||||
|
||||
/**
|
||||
* ChannelRef is a reference to a Channel.
|
||||
*/
|
||||
export interface ChannelRef__Output {
|
||||
/**
|
||||
* The globally unique id for this channel. Must be a positive number.
|
||||
*/
|
||||
'channel_id': (string);
|
||||
/**
|
||||
* An optional name associated with the channel.
|
||||
*/
|
||||
'name': (string);
|
||||
}
|
||||
45
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/ChannelTrace.ts
generated
vendored
45
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/ChannelTrace.ts
generated
vendored
@ -0,0 +1,45 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp';
|
||||
import type { ChannelTraceEvent as _grpc_channelz_v1_ChannelTraceEvent, ChannelTraceEvent__Output as _grpc_channelz_v1_ChannelTraceEvent__Output } from '../../../grpc/channelz/v1/ChannelTraceEvent';
|
||||
import type { Long } from '@grpc/proto-loader';
|
||||
|
||||
/**
|
||||
* ChannelTrace represents the recent events that have occurred on the channel.
|
||||
*/
|
||||
export interface ChannelTrace {
|
||||
/**
|
||||
* Number of events ever logged in this tracing object. This can differ from
|
||||
* events.size() because events can be overwritten or garbage collected by
|
||||
* implementations.
|
||||
*/
|
||||
'num_events_logged'?: (number | string | Long);
|
||||
/**
|
||||
* Time that this channel was created.
|
||||
*/
|
||||
'creation_timestamp'?: (_google_protobuf_Timestamp | null);
|
||||
/**
|
||||
* List of events that have occurred on this channel.
|
||||
*/
|
||||
'events'?: (_grpc_channelz_v1_ChannelTraceEvent)[];
|
||||
}
|
||||
|
||||
/**
|
||||
* ChannelTrace represents the recent events that have occurred on the channel.
|
||||
*/
|
||||
export interface ChannelTrace__Output {
|
||||
/**
|
||||
* Number of events ever logged in this tracing object. This can differ from
|
||||
* events.size() because events can be overwritten or garbage collected by
|
||||
* implementations.
|
||||
*/
|
||||
'num_events_logged': (string);
|
||||
/**
|
||||
* Time that this channel was created.
|
||||
*/
|
||||
'creation_timestamp': (_google_protobuf_Timestamp__Output | null);
|
||||
/**
|
||||
* List of events that have occurred on this channel.
|
||||
*/
|
||||
'events': (_grpc_channelz_v1_ChannelTraceEvent__Output)[];
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp';
|
||||
import type { ChannelRef as _grpc_channelz_v1_ChannelRef, ChannelRef__Output as _grpc_channelz_v1_ChannelRef__Output } from '../../../grpc/channelz/v1/ChannelRef';
|
||||
import type { SubchannelRef as _grpc_channelz_v1_SubchannelRef, SubchannelRef__Output as _grpc_channelz_v1_SubchannelRef__Output } from '../../../grpc/channelz/v1/SubchannelRef';
|
||||
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
/**
|
||||
* The supported severity levels of trace events.
|
||||
*/
|
||||
export const _grpc_channelz_v1_ChannelTraceEvent_Severity = {
|
||||
CT_UNKNOWN: 'CT_UNKNOWN',
|
||||
CT_INFO: 'CT_INFO',
|
||||
CT_WARNING: 'CT_WARNING',
|
||||
CT_ERROR: 'CT_ERROR',
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* The supported severity levels of trace events.
|
||||
*/
|
||||
export type _grpc_channelz_v1_ChannelTraceEvent_Severity =
|
||||
| 'CT_UNKNOWN'
|
||||
| 0
|
||||
| 'CT_INFO'
|
||||
| 1
|
||||
| 'CT_WARNING'
|
||||
| 2
|
||||
| 'CT_ERROR'
|
||||
| 3
|
||||
|
||||
/**
|
||||
* The supported severity levels of trace events.
|
||||
*/
|
||||
export type _grpc_channelz_v1_ChannelTraceEvent_Severity__Output = typeof _grpc_channelz_v1_ChannelTraceEvent_Severity[keyof typeof _grpc_channelz_v1_ChannelTraceEvent_Severity]
|
||||
|
||||
/**
|
||||
* A trace event is an interesting thing that happened to a channel or
|
||||
* subchannel, such as creation, address resolution, subchannel creation, etc.
|
||||
*/
|
||||
export interface ChannelTraceEvent {
|
||||
/**
|
||||
* High level description of the event.
|
||||
*/
|
||||
'description'?: (string);
|
||||
/**
|
||||
* the severity of the trace event
|
||||
*/
|
||||
'severity'?: (_grpc_channelz_v1_ChannelTraceEvent_Severity);
|
||||
/**
|
||||
* When this event occurred.
|
||||
*/
|
||||
'timestamp'?: (_google_protobuf_Timestamp | null);
|
||||
'channel_ref'?: (_grpc_channelz_v1_ChannelRef | null);
|
||||
'subchannel_ref'?: (_grpc_channelz_v1_SubchannelRef | null);
|
||||
/**
|
||||
* ref of referenced channel or subchannel.
|
||||
* Optional, only present if this event refers to a child object. For example,
|
||||
* this field would be filled if this trace event was for a subchannel being
|
||||
* created.
|
||||
*/
|
||||
'child_ref'?: "channel_ref"|"subchannel_ref";
|
||||
}
|
||||
|
||||
/**
|
||||
* A trace event is an interesting thing that happened to a channel or
|
||||
* subchannel, such as creation, address resolution, subchannel creation, etc.
|
||||
*/
|
||||
export interface ChannelTraceEvent__Output {
|
||||
/**
|
||||
* High level description of the event.
|
||||
*/
|
||||
'description': (string);
|
||||
/**
|
||||
* the severity of the trace event
|
||||
*/
|
||||
'severity': (_grpc_channelz_v1_ChannelTraceEvent_Severity__Output);
|
||||
/**
|
||||
* When this event occurred.
|
||||
*/
|
||||
'timestamp': (_google_protobuf_Timestamp__Output | null);
|
||||
'channel_ref'?: (_grpc_channelz_v1_ChannelRef__Output | null);
|
||||
'subchannel_ref'?: (_grpc_channelz_v1_SubchannelRef__Output | null);
|
||||
/**
|
||||
* ref of referenced channel or subchannel.
|
||||
* Optional, only present if this event refers to a child object. For example,
|
||||
* this field would be filled if this trace event was for a subchannel being
|
||||
* created.
|
||||
*/
|
||||
'child_ref': "channel_ref"|"subchannel_ref";
|
||||
}
|
||||
178
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/Channelz.ts
generated
vendored
178
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/Channelz.ts
generated
vendored
@ -0,0 +1,178 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type * as grpc from '../../../../index'
|
||||
import type { MethodDefinition } from '@grpc/proto-loader'
|
||||
import type { GetChannelRequest as _grpc_channelz_v1_GetChannelRequest, GetChannelRequest__Output as _grpc_channelz_v1_GetChannelRequest__Output } from '../../../grpc/channelz/v1/GetChannelRequest';
|
||||
import type { GetChannelResponse as _grpc_channelz_v1_GetChannelResponse, GetChannelResponse__Output as _grpc_channelz_v1_GetChannelResponse__Output } from '../../../grpc/channelz/v1/GetChannelResponse';
|
||||
import type { GetServerRequest as _grpc_channelz_v1_GetServerRequest, GetServerRequest__Output as _grpc_channelz_v1_GetServerRequest__Output } from '../../../grpc/channelz/v1/GetServerRequest';
|
||||
import type { GetServerResponse as _grpc_channelz_v1_GetServerResponse, GetServerResponse__Output as _grpc_channelz_v1_GetServerResponse__Output } from '../../../grpc/channelz/v1/GetServerResponse';
|
||||
import type { GetServerSocketsRequest as _grpc_channelz_v1_GetServerSocketsRequest, GetServerSocketsRequest__Output as _grpc_channelz_v1_GetServerSocketsRequest__Output } from '../../../grpc/channelz/v1/GetServerSocketsRequest';
|
||||
import type { GetServerSocketsResponse as _grpc_channelz_v1_GetServerSocketsResponse, GetServerSocketsResponse__Output as _grpc_channelz_v1_GetServerSocketsResponse__Output } from '../../../grpc/channelz/v1/GetServerSocketsResponse';
|
||||
import type { GetServersRequest as _grpc_channelz_v1_GetServersRequest, GetServersRequest__Output as _grpc_channelz_v1_GetServersRequest__Output } from '../../../grpc/channelz/v1/GetServersRequest';
|
||||
import type { GetServersResponse as _grpc_channelz_v1_GetServersResponse, GetServersResponse__Output as _grpc_channelz_v1_GetServersResponse__Output } from '../../../grpc/channelz/v1/GetServersResponse';
|
||||
import type { GetSocketRequest as _grpc_channelz_v1_GetSocketRequest, GetSocketRequest__Output as _grpc_channelz_v1_GetSocketRequest__Output } from '../../../grpc/channelz/v1/GetSocketRequest';
|
||||
import type { GetSocketResponse as _grpc_channelz_v1_GetSocketResponse, GetSocketResponse__Output as _grpc_channelz_v1_GetSocketResponse__Output } from '../../../grpc/channelz/v1/GetSocketResponse';
|
||||
import type { GetSubchannelRequest as _grpc_channelz_v1_GetSubchannelRequest, GetSubchannelRequest__Output as _grpc_channelz_v1_GetSubchannelRequest__Output } from '../../../grpc/channelz/v1/GetSubchannelRequest';
|
||||
import type { GetSubchannelResponse as _grpc_channelz_v1_GetSubchannelResponse, GetSubchannelResponse__Output as _grpc_channelz_v1_GetSubchannelResponse__Output } from '../../../grpc/channelz/v1/GetSubchannelResponse';
|
||||
import type { GetTopChannelsRequest as _grpc_channelz_v1_GetTopChannelsRequest, GetTopChannelsRequest__Output as _grpc_channelz_v1_GetTopChannelsRequest__Output } from '../../../grpc/channelz/v1/GetTopChannelsRequest';
|
||||
import type { GetTopChannelsResponse as _grpc_channelz_v1_GetTopChannelsResponse, GetTopChannelsResponse__Output as _grpc_channelz_v1_GetTopChannelsResponse__Output } from '../../../grpc/channelz/v1/GetTopChannelsResponse';
|
||||
|
||||
/**
|
||||
* Channelz is a service exposed by gRPC servers that provides detailed debug
|
||||
* information.
|
||||
*/
|
||||
export interface ChannelzClient extends grpc.Client {
|
||||
/**
|
||||
* Returns a single Channel, or else a NOT_FOUND code.
|
||||
*/
|
||||
GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetChannelResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetChannelResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetChannelResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetChannel(argument: _grpc_channelz_v1_GetChannelRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetChannelResponse__Output>): grpc.ClientUnaryCall;
|
||||
|
||||
/**
|
||||
* Returns a single Server, or else a NOT_FOUND code.
|
||||
*/
|
||||
GetServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetServer(argument: _grpc_channelz_v1_GetServerRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetServer(argument: _grpc_channelz_v1_GetServerRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall;
|
||||
/**
|
||||
* Returns a single Server, or else a NOT_FOUND code.
|
||||
*/
|
||||
getServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall;
|
||||
getServer(argument: _grpc_channelz_v1_GetServerRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall;
|
||||
getServer(argument: _grpc_channelz_v1_GetServerRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall;
|
||||
getServer(argument: _grpc_channelz_v1_GetServerRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerResponse__Output>): grpc.ClientUnaryCall;
|
||||
|
||||
/**
|
||||
* Gets all server sockets that exist in the process.
|
||||
*/
|
||||
GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall;
|
||||
/**
|
||||
* Gets all server sockets that exist in the process.
|
||||
*/
|
||||
getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall;
|
||||
getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall;
|
||||
getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall;
|
||||
getServerSockets(argument: _grpc_channelz_v1_GetServerSocketsRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServerSocketsResponse__Output>): grpc.ClientUnaryCall;
|
||||
|
||||
/**
|
||||
* Gets all servers that exist in the process.
|
||||
*/
|
||||
GetServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetServers(argument: _grpc_channelz_v1_GetServersRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetServers(argument: _grpc_channelz_v1_GetServersRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall;
|
||||
/**
|
||||
* Gets all servers that exist in the process.
|
||||
*/
|
||||
getServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall;
|
||||
getServers(argument: _grpc_channelz_v1_GetServersRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall;
|
||||
getServers(argument: _grpc_channelz_v1_GetServersRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall;
|
||||
getServers(argument: _grpc_channelz_v1_GetServersRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetServersResponse__Output>): grpc.ClientUnaryCall;
|
||||
|
||||
/**
|
||||
* Returns a single Socket or else a NOT_FOUND code.
|
||||
*/
|
||||
GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetSocket(argument: _grpc_channelz_v1_GetSocketRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall;
|
||||
/**
|
||||
* Returns a single Socket or else a NOT_FOUND code.
|
||||
*/
|
||||
getSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall;
|
||||
getSocket(argument: _grpc_channelz_v1_GetSocketRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall;
|
||||
getSocket(argument: _grpc_channelz_v1_GetSocketRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall;
|
||||
getSocket(argument: _grpc_channelz_v1_GetSocketRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetSocketResponse__Output>): grpc.ClientUnaryCall;
|
||||
|
||||
/**
|
||||
* Returns a single Subchannel, or else a NOT_FOUND code.
|
||||
*/
|
||||
GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall;
|
||||
/**
|
||||
* Returns a single Subchannel, or else a NOT_FOUND code.
|
||||
*/
|
||||
getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall;
|
||||
getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall;
|
||||
getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall;
|
||||
getSubchannel(argument: _grpc_channelz_v1_GetSubchannelRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetSubchannelResponse__Output>): grpc.ClientUnaryCall;
|
||||
|
||||
/**
|
||||
* Gets all root channels (i.e. channels the application has directly
|
||||
* created). This does not include subchannels nor non-top level channels.
|
||||
*/
|
||||
GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall;
|
||||
GetTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall;
|
||||
/**
|
||||
* Gets all root channels (i.e. channels the application has directly
|
||||
* created). This does not include subchannels nor non-top level channels.
|
||||
*/
|
||||
getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall;
|
||||
getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, metadata: grpc.Metadata, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall;
|
||||
getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, options: grpc.CallOptions, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall;
|
||||
getTopChannels(argument: _grpc_channelz_v1_GetTopChannelsRequest, callback: grpc.requestCallback<_grpc_channelz_v1_GetTopChannelsResponse__Output>): grpc.ClientUnaryCall;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Channelz is a service exposed by gRPC servers that provides detailed debug
|
||||
* information.
|
||||
*/
|
||||
export interface ChannelzHandlers extends grpc.UntypedServiceImplementation {
|
||||
/**
|
||||
* Returns a single Channel, or else a NOT_FOUND code.
|
||||
*/
|
||||
GetChannel: grpc.handleUnaryCall<_grpc_channelz_v1_GetChannelRequest__Output, _grpc_channelz_v1_GetChannelResponse>;
|
||||
|
||||
/**
|
||||
* Returns a single Server, or else a NOT_FOUND code.
|
||||
*/
|
||||
GetServer: grpc.handleUnaryCall<_grpc_channelz_v1_GetServerRequest__Output, _grpc_channelz_v1_GetServerResponse>;
|
||||
|
||||
/**
|
||||
* Gets all server sockets that exist in the process.
|
||||
*/
|
||||
GetServerSockets: grpc.handleUnaryCall<_grpc_channelz_v1_GetServerSocketsRequest__Output, _grpc_channelz_v1_GetServerSocketsResponse>;
|
||||
|
||||
/**
|
||||
* Gets all servers that exist in the process.
|
||||
*/
|
||||
GetServers: grpc.handleUnaryCall<_grpc_channelz_v1_GetServersRequest__Output, _grpc_channelz_v1_GetServersResponse>;
|
||||
|
||||
/**
|
||||
* Returns a single Socket or else a NOT_FOUND code.
|
||||
*/
|
||||
GetSocket: grpc.handleUnaryCall<_grpc_channelz_v1_GetSocketRequest__Output, _grpc_channelz_v1_GetSocketResponse>;
|
||||
|
||||
/**
|
||||
* Returns a single Subchannel, or else a NOT_FOUND code.
|
||||
*/
|
||||
GetSubchannel: grpc.handleUnaryCall<_grpc_channelz_v1_GetSubchannelRequest__Output, _grpc_channelz_v1_GetSubchannelResponse>;
|
||||
|
||||
/**
|
||||
* Gets all root channels (i.e. channels the application has directly
|
||||
* created). This does not include subchannels nor non-top level channels.
|
||||
*/
|
||||
GetTopChannels: grpc.handleUnaryCall<_grpc_channelz_v1_GetTopChannelsRequest__Output, _grpc_channelz_v1_GetTopChannelsResponse>;
|
||||
|
||||
}
|
||||
|
||||
export interface ChannelzDefinition extends grpc.ServiceDefinition {
|
||||
GetChannel: MethodDefinition<_grpc_channelz_v1_GetChannelRequest, _grpc_channelz_v1_GetChannelResponse, _grpc_channelz_v1_GetChannelRequest__Output, _grpc_channelz_v1_GetChannelResponse__Output>
|
||||
GetServer: MethodDefinition<_grpc_channelz_v1_GetServerRequest, _grpc_channelz_v1_GetServerResponse, _grpc_channelz_v1_GetServerRequest__Output, _grpc_channelz_v1_GetServerResponse__Output>
|
||||
GetServerSockets: MethodDefinition<_grpc_channelz_v1_GetServerSocketsRequest, _grpc_channelz_v1_GetServerSocketsResponse, _grpc_channelz_v1_GetServerSocketsRequest__Output, _grpc_channelz_v1_GetServerSocketsResponse__Output>
|
||||
GetServers: MethodDefinition<_grpc_channelz_v1_GetServersRequest, _grpc_channelz_v1_GetServersResponse, _grpc_channelz_v1_GetServersRequest__Output, _grpc_channelz_v1_GetServersResponse__Output>
|
||||
GetSocket: MethodDefinition<_grpc_channelz_v1_GetSocketRequest, _grpc_channelz_v1_GetSocketResponse, _grpc_channelz_v1_GetSocketRequest__Output, _grpc_channelz_v1_GetSocketResponse__Output>
|
||||
GetSubchannel: MethodDefinition<_grpc_channelz_v1_GetSubchannelRequest, _grpc_channelz_v1_GetSubchannelResponse, _grpc_channelz_v1_GetSubchannelRequest__Output, _grpc_channelz_v1_GetSubchannelResponse__Output>
|
||||
GetTopChannels: MethodDefinition<_grpc_channelz_v1_GetTopChannelsRequest, _grpc_channelz_v1_GetTopChannelsResponse, _grpc_channelz_v1_GetTopChannelsRequest__Output, _grpc_channelz_v1_GetTopChannelsResponse__Output>
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Long } from '@grpc/proto-loader';
|
||||
|
||||
export interface GetChannelRequest {
|
||||
/**
|
||||
* channel_id is the identifier of the specific channel to get.
|
||||
*/
|
||||
'channel_id'?: (number | string | Long);
|
||||
}
|
||||
|
||||
export interface GetChannelRequest__Output {
|
||||
/**
|
||||
* channel_id is the identifier of the specific channel to get.
|
||||
*/
|
||||
'channel_id': (string);
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Channel as _grpc_channelz_v1_Channel, Channel__Output as _grpc_channelz_v1_Channel__Output } from '../../../grpc/channelz/v1/Channel';
|
||||
|
||||
export interface GetChannelResponse {
|
||||
/**
|
||||
* The Channel that corresponds to the requested channel_id. This field
|
||||
* should be set.
|
||||
*/
|
||||
'channel'?: (_grpc_channelz_v1_Channel | null);
|
||||
}
|
||||
|
||||
export interface GetChannelResponse__Output {
|
||||
/**
|
||||
* The Channel that corresponds to the requested channel_id. This field
|
||||
* should be set.
|
||||
*/
|
||||
'channel': (_grpc_channelz_v1_Channel__Output | null);
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Long } from '@grpc/proto-loader';
|
||||
|
||||
export interface GetServerRequest {
|
||||
/**
|
||||
* server_id is the identifier of the specific server to get.
|
||||
*/
|
||||
'server_id'?: (number | string | Long);
|
||||
}
|
||||
|
||||
export interface GetServerRequest__Output {
|
||||
/**
|
||||
* server_id is the identifier of the specific server to get.
|
||||
*/
|
||||
'server_id': (string);
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Server as _grpc_channelz_v1_Server, Server__Output as _grpc_channelz_v1_Server__Output } from '../../../grpc/channelz/v1/Server';
|
||||
|
||||
export interface GetServerResponse {
|
||||
/**
|
||||
* The Server that corresponds to the requested server_id. This field
|
||||
* should be set.
|
||||
*/
|
||||
'server'?: (_grpc_channelz_v1_Server | null);
|
||||
}
|
||||
|
||||
export interface GetServerResponse__Output {
|
||||
/**
|
||||
* The Server that corresponds to the requested server_id. This field
|
||||
* should be set.
|
||||
*/
|
||||
'server': (_grpc_channelz_v1_Server__Output | null);
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Long } from '@grpc/proto-loader';
|
||||
|
||||
export interface GetServerSocketsRequest {
|
||||
'server_id'?: (number | string | Long);
|
||||
/**
|
||||
* start_socket_id indicates that only sockets at or above this id should be
|
||||
* included in the results.
|
||||
* To request the first page, this must be set to 0. To request
|
||||
* subsequent pages, the client generates this value by adding 1 to
|
||||
* the highest seen result ID.
|
||||
*/
|
||||
'start_socket_id'?: (number | string | Long);
|
||||
/**
|
||||
* If non-zero, the server will return a page of results containing
|
||||
* at most this many items. If zero, the server will choose a
|
||||
* reasonable page size. Must never be negative.
|
||||
*/
|
||||
'max_results'?: (number | string | Long);
|
||||
}
|
||||
|
||||
export interface GetServerSocketsRequest__Output {
|
||||
'server_id': (string);
|
||||
/**
|
||||
* start_socket_id indicates that only sockets at or above this id should be
|
||||
* included in the results.
|
||||
* To request the first page, this must be set to 0. To request
|
||||
* subsequent pages, the client generates this value by adding 1 to
|
||||
* the highest seen result ID.
|
||||
*/
|
||||
'start_socket_id': (string);
|
||||
/**
|
||||
* If non-zero, the server will return a page of results containing
|
||||
* at most this many items. If zero, the server will choose a
|
||||
* reasonable page size. Must never be negative.
|
||||
*/
|
||||
'max_results': (string);
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { SocketRef as _grpc_channelz_v1_SocketRef, SocketRef__Output as _grpc_channelz_v1_SocketRef__Output } from '../../../grpc/channelz/v1/SocketRef';
|
||||
|
||||
export interface GetServerSocketsResponse {
|
||||
/**
|
||||
* list of socket refs that the connection detail service knows about. Sorted in
|
||||
* ascending socket_id order.
|
||||
* Must contain at least 1 result, otherwise 'end' must be true.
|
||||
*/
|
||||
'socket_ref'?: (_grpc_channelz_v1_SocketRef)[];
|
||||
/**
|
||||
* If set, indicates that the list of sockets is the final list. Requesting
|
||||
* more sockets will only return more if they are created after this RPC
|
||||
* completes.
|
||||
*/
|
||||
'end'?: (boolean);
|
||||
}
|
||||
|
||||
export interface GetServerSocketsResponse__Output {
|
||||
/**
|
||||
* list of socket refs that the connection detail service knows about. Sorted in
|
||||
* ascending socket_id order.
|
||||
* Must contain at least 1 result, otherwise 'end' must be true.
|
||||
*/
|
||||
'socket_ref': (_grpc_channelz_v1_SocketRef__Output)[];
|
||||
/**
|
||||
* If set, indicates that the list of sockets is the final list. Requesting
|
||||
* more sockets will only return more if they are created after this RPC
|
||||
* completes.
|
||||
*/
|
||||
'end': (boolean);
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Long } from '@grpc/proto-loader';
|
||||
|
||||
export interface GetServersRequest {
|
||||
/**
|
||||
* start_server_id indicates that only servers at or above this id should be
|
||||
* included in the results.
|
||||
* To request the first page, this must be set to 0. To request
|
||||
* subsequent pages, the client generates this value by adding 1 to
|
||||
* the highest seen result ID.
|
||||
*/
|
||||
'start_server_id'?: (number | string | Long);
|
||||
/**
|
||||
* If non-zero, the server will return a page of results containing
|
||||
* at most this many items. If zero, the server will choose a
|
||||
* reasonable page size. Must never be negative.
|
||||
*/
|
||||
'max_results'?: (number | string | Long);
|
||||
}
|
||||
|
||||
export interface GetServersRequest__Output {
|
||||
/**
|
||||
* start_server_id indicates that only servers at or above this id should be
|
||||
* included in the results.
|
||||
* To request the first page, this must be set to 0. To request
|
||||
* subsequent pages, the client generates this value by adding 1 to
|
||||
* the highest seen result ID.
|
||||
*/
|
||||
'start_server_id': (string);
|
||||
/**
|
||||
* If non-zero, the server will return a page of results containing
|
||||
* at most this many items. If zero, the server will choose a
|
||||
* reasonable page size. Must never be negative.
|
||||
*/
|
||||
'max_results': (string);
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Server as _grpc_channelz_v1_Server, Server__Output as _grpc_channelz_v1_Server__Output } from '../../../grpc/channelz/v1/Server';
|
||||
|
||||
export interface GetServersResponse {
|
||||
/**
|
||||
* list of servers that the connection detail service knows about. Sorted in
|
||||
* ascending server_id order.
|
||||
* Must contain at least 1 result, otherwise 'end' must be true.
|
||||
*/
|
||||
'server'?: (_grpc_channelz_v1_Server)[];
|
||||
/**
|
||||
* If set, indicates that the list of servers is the final list. Requesting
|
||||
* more servers will only return more if they are created after this RPC
|
||||
* completes.
|
||||
*/
|
||||
'end'?: (boolean);
|
||||
}
|
||||
|
||||
export interface GetServersResponse__Output {
|
||||
/**
|
||||
* list of servers that the connection detail service knows about. Sorted in
|
||||
* ascending server_id order.
|
||||
* Must contain at least 1 result, otherwise 'end' must be true.
|
||||
*/
|
||||
'server': (_grpc_channelz_v1_Server__Output)[];
|
||||
/**
|
||||
* If set, indicates that the list of servers is the final list. Requesting
|
||||
* more servers will only return more if they are created after this RPC
|
||||
* completes.
|
||||
*/
|
||||
'end': (boolean);
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Long } from '@grpc/proto-loader';
|
||||
|
||||
export interface GetSocketRequest {
|
||||
/**
|
||||
* socket_id is the identifier of the specific socket to get.
|
||||
*/
|
||||
'socket_id'?: (number | string | Long);
|
||||
/**
|
||||
* If true, the response will contain only high level information
|
||||
* that is inexpensive to obtain. Fields thay may be omitted are
|
||||
* documented.
|
||||
*/
|
||||
'summary'?: (boolean);
|
||||
}
|
||||
|
||||
export interface GetSocketRequest__Output {
|
||||
/**
|
||||
* socket_id is the identifier of the specific socket to get.
|
||||
*/
|
||||
'socket_id': (string);
|
||||
/**
|
||||
* If true, the response will contain only high level information
|
||||
* that is inexpensive to obtain. Fields thay may be omitted are
|
||||
* documented.
|
||||
*/
|
||||
'summary': (boolean);
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Socket as _grpc_channelz_v1_Socket, Socket__Output as _grpc_channelz_v1_Socket__Output } from '../../../grpc/channelz/v1/Socket';
|
||||
|
||||
export interface GetSocketResponse {
|
||||
/**
|
||||
* The Socket that corresponds to the requested socket_id. This field
|
||||
* should be set.
|
||||
*/
|
||||
'socket'?: (_grpc_channelz_v1_Socket | null);
|
||||
}
|
||||
|
||||
export interface GetSocketResponse__Output {
|
||||
/**
|
||||
* The Socket that corresponds to the requested socket_id. This field
|
||||
* should be set.
|
||||
*/
|
||||
'socket': (_grpc_channelz_v1_Socket__Output | null);
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Long } from '@grpc/proto-loader';
|
||||
|
||||
export interface GetSubchannelRequest {
|
||||
/**
|
||||
* subchannel_id is the identifier of the specific subchannel to get.
|
||||
*/
|
||||
'subchannel_id'?: (number | string | Long);
|
||||
}
|
||||
|
||||
export interface GetSubchannelRequest__Output {
|
||||
/**
|
||||
* subchannel_id is the identifier of the specific subchannel to get.
|
||||
*/
|
||||
'subchannel_id': (string);
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Subchannel as _grpc_channelz_v1_Subchannel, Subchannel__Output as _grpc_channelz_v1_Subchannel__Output } from '../../../grpc/channelz/v1/Subchannel';
|
||||
|
||||
export interface GetSubchannelResponse {
|
||||
/**
|
||||
* The Subchannel that corresponds to the requested subchannel_id. This
|
||||
* field should be set.
|
||||
*/
|
||||
'subchannel'?: (_grpc_channelz_v1_Subchannel | null);
|
||||
}
|
||||
|
||||
export interface GetSubchannelResponse__Output {
|
||||
/**
|
||||
* The Subchannel that corresponds to the requested subchannel_id. This
|
||||
* field should be set.
|
||||
*/
|
||||
'subchannel': (_grpc_channelz_v1_Subchannel__Output | null);
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Long } from '@grpc/proto-loader';
|
||||
|
||||
export interface GetTopChannelsRequest {
|
||||
/**
|
||||
* start_channel_id indicates that only channels at or above this id should be
|
||||
* included in the results.
|
||||
* To request the first page, this should be set to 0. To request
|
||||
* subsequent pages, the client generates this value by adding 1 to
|
||||
* the highest seen result ID.
|
||||
*/
|
||||
'start_channel_id'?: (number | string | Long);
|
||||
/**
|
||||
* If non-zero, the server will return a page of results containing
|
||||
* at most this many items. If zero, the server will choose a
|
||||
* reasonable page size. Must never be negative.
|
||||
*/
|
||||
'max_results'?: (number | string | Long);
|
||||
}
|
||||
|
||||
export interface GetTopChannelsRequest__Output {
|
||||
/**
|
||||
* start_channel_id indicates that only channels at or above this id should be
|
||||
* included in the results.
|
||||
* To request the first page, this should be set to 0. To request
|
||||
* subsequent pages, the client generates this value by adding 1 to
|
||||
* the highest seen result ID.
|
||||
*/
|
||||
'start_channel_id': (string);
|
||||
/**
|
||||
* If non-zero, the server will return a page of results containing
|
||||
* at most this many items. If zero, the server will choose a
|
||||
* reasonable page size. Must never be negative.
|
||||
*/
|
||||
'max_results': (string);
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Channel as _grpc_channelz_v1_Channel, Channel__Output as _grpc_channelz_v1_Channel__Output } from '../../../grpc/channelz/v1/Channel';
|
||||
|
||||
export interface GetTopChannelsResponse {
|
||||
/**
|
||||
* list of channels that the connection detail service knows about. Sorted in
|
||||
* ascending channel_id order.
|
||||
* Must contain at least 1 result, otherwise 'end' must be true.
|
||||
*/
|
||||
'channel'?: (_grpc_channelz_v1_Channel)[];
|
||||
/**
|
||||
* If set, indicates that the list of channels is the final list. Requesting
|
||||
* more channels can only return more if they are created after this RPC
|
||||
* completes.
|
||||
*/
|
||||
'end'?: (boolean);
|
||||
}
|
||||
|
||||
export interface GetTopChannelsResponse__Output {
|
||||
/**
|
||||
* list of channels that the connection detail service knows about. Sorted in
|
||||
* ascending channel_id order.
|
||||
* Must contain at least 1 result, otherwise 'end' must be true.
|
||||
*/
|
||||
'channel': (_grpc_channelz_v1_Channel__Output)[];
|
||||
/**
|
||||
* If set, indicates that the list of channels is the final list. Requesting
|
||||
* more channels can only return more if they are created after this RPC
|
||||
* completes.
|
||||
*/
|
||||
'end': (boolean);
|
||||
}
|
||||
87
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/Security.ts
generated
vendored
87
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/Security.ts
generated
vendored
@ -0,0 +1,87 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any';
|
||||
|
||||
export interface _grpc_channelz_v1_Security_OtherSecurity {
|
||||
/**
|
||||
* The human readable version of the value.
|
||||
*/
|
||||
'name'?: (string);
|
||||
/**
|
||||
* The actual security details message.
|
||||
*/
|
||||
'value'?: (_google_protobuf_Any | null);
|
||||
}
|
||||
|
||||
export interface _grpc_channelz_v1_Security_OtherSecurity__Output {
|
||||
/**
|
||||
* The human readable version of the value.
|
||||
*/
|
||||
'name': (string);
|
||||
/**
|
||||
* The actual security details message.
|
||||
*/
|
||||
'value': (_google_protobuf_Any__Output | null);
|
||||
}
|
||||
|
||||
export interface _grpc_channelz_v1_Security_Tls {
|
||||
/**
|
||||
* The cipher suite name in the RFC 4346 format:
|
||||
* https://tools.ietf.org/html/rfc4346#appendix-C
|
||||
*/
|
||||
'standard_name'?: (string);
|
||||
/**
|
||||
* Some other way to describe the cipher suite if
|
||||
* the RFC 4346 name is not available.
|
||||
*/
|
||||
'other_name'?: (string);
|
||||
/**
|
||||
* the certificate used by this endpoint.
|
||||
*/
|
||||
'local_certificate'?: (Buffer | Uint8Array | string);
|
||||
/**
|
||||
* the certificate used by the remote endpoint.
|
||||
*/
|
||||
'remote_certificate'?: (Buffer | Uint8Array | string);
|
||||
'cipher_suite'?: "standard_name"|"other_name";
|
||||
}
|
||||
|
||||
export interface _grpc_channelz_v1_Security_Tls__Output {
|
||||
/**
|
||||
* The cipher suite name in the RFC 4346 format:
|
||||
* https://tools.ietf.org/html/rfc4346#appendix-C
|
||||
*/
|
||||
'standard_name'?: (string);
|
||||
/**
|
||||
* Some other way to describe the cipher suite if
|
||||
* the RFC 4346 name is not available.
|
||||
*/
|
||||
'other_name'?: (string);
|
||||
/**
|
||||
* the certificate used by this endpoint.
|
||||
*/
|
||||
'local_certificate': (Buffer);
|
||||
/**
|
||||
* the certificate used by the remote endpoint.
|
||||
*/
|
||||
'remote_certificate': (Buffer);
|
||||
'cipher_suite': "standard_name"|"other_name";
|
||||
}
|
||||
|
||||
/**
|
||||
* Security represents details about how secure the socket is.
|
||||
*/
|
||||
export interface Security {
|
||||
'tls'?: (_grpc_channelz_v1_Security_Tls | null);
|
||||
'other'?: (_grpc_channelz_v1_Security_OtherSecurity | null);
|
||||
'model'?: "tls"|"other";
|
||||
}
|
||||
|
||||
/**
|
||||
* Security represents details about how secure the socket is.
|
||||
*/
|
||||
export interface Security__Output {
|
||||
'tls'?: (_grpc_channelz_v1_Security_Tls__Output | null);
|
||||
'other'?: (_grpc_channelz_v1_Security_OtherSecurity__Output | null);
|
||||
'model': "tls"|"other";
|
||||
}
|
||||
45
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/Server.ts
generated
vendored
45
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/Server.ts
generated
vendored
@ -0,0 +1,45 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { ServerRef as _grpc_channelz_v1_ServerRef, ServerRef__Output as _grpc_channelz_v1_ServerRef__Output } from '../../../grpc/channelz/v1/ServerRef';
|
||||
import type { ServerData as _grpc_channelz_v1_ServerData, ServerData__Output as _grpc_channelz_v1_ServerData__Output } from '../../../grpc/channelz/v1/ServerData';
|
||||
import type { SocketRef as _grpc_channelz_v1_SocketRef, SocketRef__Output as _grpc_channelz_v1_SocketRef__Output } from '../../../grpc/channelz/v1/SocketRef';
|
||||
|
||||
/**
|
||||
* Server represents a single server. There may be multiple servers in a single
|
||||
* program.
|
||||
*/
|
||||
export interface Server {
|
||||
/**
|
||||
* The identifier for a Server. This should be set.
|
||||
*/
|
||||
'ref'?: (_grpc_channelz_v1_ServerRef | null);
|
||||
/**
|
||||
* The associated data of the Server.
|
||||
*/
|
||||
'data'?: (_grpc_channelz_v1_ServerData | null);
|
||||
/**
|
||||
* The sockets that the server is listening on. There are no ordering
|
||||
* guarantees. This may be absent.
|
||||
*/
|
||||
'listen_socket'?: (_grpc_channelz_v1_SocketRef)[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Server represents a single server. There may be multiple servers in a single
|
||||
* program.
|
||||
*/
|
||||
export interface Server__Output {
|
||||
/**
|
||||
* The identifier for a Server. This should be set.
|
||||
*/
|
||||
'ref': (_grpc_channelz_v1_ServerRef__Output | null);
|
||||
/**
|
||||
* The associated data of the Server.
|
||||
*/
|
||||
'data': (_grpc_channelz_v1_ServerData__Output | null);
|
||||
/**
|
||||
* The sockets that the server is listening on. There are no ordering
|
||||
* guarantees. This may be absent.
|
||||
*/
|
||||
'listen_socket': (_grpc_channelz_v1_SocketRef__Output)[];
|
||||
}
|
||||
57
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/ServerData.ts
generated
vendored
57
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/ServerData.ts
generated
vendored
@ -0,0 +1,57 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { ChannelTrace as _grpc_channelz_v1_ChannelTrace, ChannelTrace__Output as _grpc_channelz_v1_ChannelTrace__Output } from '../../../grpc/channelz/v1/ChannelTrace';
|
||||
import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp';
|
||||
import type { Long } from '@grpc/proto-loader';
|
||||
|
||||
/**
|
||||
* ServerData is data for a specific Server.
|
||||
*/
|
||||
export interface ServerData {
|
||||
/**
|
||||
* A trace of recent events on the server. May be absent.
|
||||
*/
|
||||
'trace'?: (_grpc_channelz_v1_ChannelTrace | null);
|
||||
/**
|
||||
* The number of incoming calls started on the server
|
||||
*/
|
||||
'calls_started'?: (number | string | Long);
|
||||
/**
|
||||
* The number of incoming calls that have completed with an OK status
|
||||
*/
|
||||
'calls_succeeded'?: (number | string | Long);
|
||||
/**
|
||||
* The number of incoming calls that have a completed with a non-OK status
|
||||
*/
|
||||
'calls_failed'?: (number | string | Long);
|
||||
/**
|
||||
* The last time a call was started on the server.
|
||||
*/
|
||||
'last_call_started_timestamp'?: (_google_protobuf_Timestamp | null);
|
||||
}
|
||||
|
||||
/**
|
||||
* ServerData is data for a specific Server.
|
||||
*/
|
||||
export interface ServerData__Output {
|
||||
/**
|
||||
* A trace of recent events on the server. May be absent.
|
||||
*/
|
||||
'trace': (_grpc_channelz_v1_ChannelTrace__Output | null);
|
||||
/**
|
||||
* The number of incoming calls started on the server
|
||||
*/
|
||||
'calls_started': (string);
|
||||
/**
|
||||
* The number of incoming calls that have completed with an OK status
|
||||
*/
|
||||
'calls_succeeded': (string);
|
||||
/**
|
||||
* The number of incoming calls that have a completed with a non-OK status
|
||||
*/
|
||||
'calls_failed': (string);
|
||||
/**
|
||||
* The last time a call was started on the server.
|
||||
*/
|
||||
'last_call_started_timestamp': (_google_protobuf_Timestamp__Output | null);
|
||||
}
|
||||
31
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/ServerRef.ts
generated
vendored
31
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/ServerRef.ts
generated
vendored
@ -0,0 +1,31 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Long } from '@grpc/proto-loader';
|
||||
|
||||
/**
|
||||
* ServerRef is a reference to a Server.
|
||||
*/
|
||||
export interface ServerRef {
|
||||
/**
|
||||
* A globally unique identifier for this server. Must be a positive number.
|
||||
*/
|
||||
'server_id'?: (number | string | Long);
|
||||
/**
|
||||
* An optional name associated with the server.
|
||||
*/
|
||||
'name'?: (string);
|
||||
}
|
||||
|
||||
/**
|
||||
* ServerRef is a reference to a Server.
|
||||
*/
|
||||
export interface ServerRef__Output {
|
||||
/**
|
||||
* A globally unique identifier for this server. Must be a positive number.
|
||||
*/
|
||||
'server_id': (string);
|
||||
/**
|
||||
* An optional name associated with the server.
|
||||
*/
|
||||
'name': (string);
|
||||
}
|
||||
70
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/Socket.ts
generated
vendored
70
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/Socket.ts
generated
vendored
@ -0,0 +1,70 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { SocketRef as _grpc_channelz_v1_SocketRef, SocketRef__Output as _grpc_channelz_v1_SocketRef__Output } from '../../../grpc/channelz/v1/SocketRef';
|
||||
import type { SocketData as _grpc_channelz_v1_SocketData, SocketData__Output as _grpc_channelz_v1_SocketData__Output } from '../../../grpc/channelz/v1/SocketData';
|
||||
import type { Address as _grpc_channelz_v1_Address, Address__Output as _grpc_channelz_v1_Address__Output } from '../../../grpc/channelz/v1/Address';
|
||||
import type { Security as _grpc_channelz_v1_Security, Security__Output as _grpc_channelz_v1_Security__Output } from '../../../grpc/channelz/v1/Security';
|
||||
|
||||
/**
|
||||
* Information about an actual connection. Pronounced "sock-ay".
|
||||
*/
|
||||
export interface Socket {
|
||||
/**
|
||||
* The identifier for the Socket.
|
||||
*/
|
||||
'ref'?: (_grpc_channelz_v1_SocketRef | null);
|
||||
/**
|
||||
* Data specific to this Socket.
|
||||
*/
|
||||
'data'?: (_grpc_channelz_v1_SocketData | null);
|
||||
/**
|
||||
* The locally bound address.
|
||||
*/
|
||||
'local'?: (_grpc_channelz_v1_Address | null);
|
||||
/**
|
||||
* The remote bound address. May be absent.
|
||||
*/
|
||||
'remote'?: (_grpc_channelz_v1_Address | null);
|
||||
/**
|
||||
* Security details for this socket. May be absent if not available, or
|
||||
* there is no security on the socket.
|
||||
*/
|
||||
'security'?: (_grpc_channelz_v1_Security | null);
|
||||
/**
|
||||
* Optional, represents the name of the remote endpoint, if different than
|
||||
* the original target name.
|
||||
*/
|
||||
'remote_name'?: (string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Information about an actual connection. Pronounced "sock-ay".
|
||||
*/
|
||||
export interface Socket__Output {
|
||||
/**
|
||||
* The identifier for the Socket.
|
||||
*/
|
||||
'ref': (_grpc_channelz_v1_SocketRef__Output | null);
|
||||
/**
|
||||
* Data specific to this Socket.
|
||||
*/
|
||||
'data': (_grpc_channelz_v1_SocketData__Output | null);
|
||||
/**
|
||||
* The locally bound address.
|
||||
*/
|
||||
'local': (_grpc_channelz_v1_Address__Output | null);
|
||||
/**
|
||||
* The remote bound address. May be absent.
|
||||
*/
|
||||
'remote': (_grpc_channelz_v1_Address__Output | null);
|
||||
/**
|
||||
* Security details for this socket. May be absent if not available, or
|
||||
* there is no security on the socket.
|
||||
*/
|
||||
'security': (_grpc_channelz_v1_Security__Output | null);
|
||||
/**
|
||||
* Optional, represents the name of the remote endpoint, if different than
|
||||
* the original target name.
|
||||
*/
|
||||
'remote_name': (string);
|
||||
}
|
||||
150
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/SocketData.ts
generated
vendored
150
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/SocketData.ts
generated
vendored
@ -0,0 +1,150 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from '../../../google/protobuf/Timestamp';
|
||||
import type { Int64Value as _google_protobuf_Int64Value, Int64Value__Output as _google_protobuf_Int64Value__Output } from '../../../google/protobuf/Int64Value';
|
||||
import type { SocketOption as _grpc_channelz_v1_SocketOption, SocketOption__Output as _grpc_channelz_v1_SocketOption__Output } from '../../../grpc/channelz/v1/SocketOption';
|
||||
import type { Long } from '@grpc/proto-loader';
|
||||
|
||||
/**
|
||||
* SocketData is data associated for a specific Socket. The fields present
|
||||
* are specific to the implementation, so there may be minor differences in
|
||||
* the semantics. (e.g. flow control windows)
|
||||
*/
|
||||
export interface SocketData {
|
||||
/**
|
||||
* The number of streams that have been started.
|
||||
*/
|
||||
'streams_started'?: (number | string | Long);
|
||||
/**
|
||||
* The number of streams that have ended successfully:
|
||||
* On client side, received frame with eos bit set;
|
||||
* On server side, sent frame with eos bit set.
|
||||
*/
|
||||
'streams_succeeded'?: (number | string | Long);
|
||||
/**
|
||||
* The number of streams that have ended unsuccessfully:
|
||||
* On client side, ended without receiving frame with eos bit set;
|
||||
* On server side, ended without sending frame with eos bit set.
|
||||
*/
|
||||
'streams_failed'?: (number | string | Long);
|
||||
/**
|
||||
* The number of grpc messages successfully sent on this socket.
|
||||
*/
|
||||
'messages_sent'?: (number | string | Long);
|
||||
/**
|
||||
* The number of grpc messages received on this socket.
|
||||
*/
|
||||
'messages_received'?: (number | string | Long);
|
||||
/**
|
||||
* The number of keep alives sent. This is typically implemented with HTTP/2
|
||||
* ping messages.
|
||||
*/
|
||||
'keep_alives_sent'?: (number | string | Long);
|
||||
/**
|
||||
* The last time a stream was created by this endpoint. Usually unset for
|
||||
* servers.
|
||||
*/
|
||||
'last_local_stream_created_timestamp'?: (_google_protobuf_Timestamp | null);
|
||||
/**
|
||||
* The last time a stream was created by the remote endpoint. Usually unset
|
||||
* for clients.
|
||||
*/
|
||||
'last_remote_stream_created_timestamp'?: (_google_protobuf_Timestamp | null);
|
||||
/**
|
||||
* The last time a message was sent by this endpoint.
|
||||
*/
|
||||
'last_message_sent_timestamp'?: (_google_protobuf_Timestamp | null);
|
||||
/**
|
||||
* The last time a message was received by this endpoint.
|
||||
*/
|
||||
'last_message_received_timestamp'?: (_google_protobuf_Timestamp | null);
|
||||
/**
|
||||
* The amount of window, granted to the local endpoint by the remote endpoint.
|
||||
* This may be slightly out of date due to network latency. This does NOT
|
||||
* include stream level or TCP level flow control info.
|
||||
*/
|
||||
'local_flow_control_window'?: (_google_protobuf_Int64Value | null);
|
||||
/**
|
||||
* The amount of window, granted to the remote endpoint by the local endpoint.
|
||||
* This may be slightly out of date due to network latency. This does NOT
|
||||
* include stream level or TCP level flow control info.
|
||||
*/
|
||||
'remote_flow_control_window'?: (_google_protobuf_Int64Value | null);
|
||||
/**
|
||||
* Socket options set on this socket. May be absent if 'summary' is set
|
||||
* on GetSocketRequest.
|
||||
*/
|
||||
'option'?: (_grpc_channelz_v1_SocketOption)[];
|
||||
}
|
||||
|
||||
/**
|
||||
* SocketData is data associated for a specific Socket. The fields present
|
||||
* are specific to the implementation, so there may be minor differences in
|
||||
* the semantics. (e.g. flow control windows)
|
||||
*/
|
||||
export interface SocketData__Output {
|
||||
/**
|
||||
* The number of streams that have been started.
|
||||
*/
|
||||
'streams_started': (string);
|
||||
/**
|
||||
* The number of streams that have ended successfully:
|
||||
* On client side, received frame with eos bit set;
|
||||
* On server side, sent frame with eos bit set.
|
||||
*/
|
||||
'streams_succeeded': (string);
|
||||
/**
|
||||
* The number of streams that have ended unsuccessfully:
|
||||
* On client side, ended without receiving frame with eos bit set;
|
||||
* On server side, ended without sending frame with eos bit set.
|
||||
*/
|
||||
'streams_failed': (string);
|
||||
/**
|
||||
* The number of grpc messages successfully sent on this socket.
|
||||
*/
|
||||
'messages_sent': (string);
|
||||
/**
|
||||
* The number of grpc messages received on this socket.
|
||||
*/
|
||||
'messages_received': (string);
|
||||
/**
|
||||
* The number of keep alives sent. This is typically implemented with HTTP/2
|
||||
* ping messages.
|
||||
*/
|
||||
'keep_alives_sent': (string);
|
||||
/**
|
||||
* The last time a stream was created by this endpoint. Usually unset for
|
||||
* servers.
|
||||
*/
|
||||
'last_local_stream_created_timestamp': (_google_protobuf_Timestamp__Output | null);
|
||||
/**
|
||||
* The last time a stream was created by the remote endpoint. Usually unset
|
||||
* for clients.
|
||||
*/
|
||||
'last_remote_stream_created_timestamp': (_google_protobuf_Timestamp__Output | null);
|
||||
/**
|
||||
* The last time a message was sent by this endpoint.
|
||||
*/
|
||||
'last_message_sent_timestamp': (_google_protobuf_Timestamp__Output | null);
|
||||
/**
|
||||
* The last time a message was received by this endpoint.
|
||||
*/
|
||||
'last_message_received_timestamp': (_google_protobuf_Timestamp__Output | null);
|
||||
/**
|
||||
* The amount of window, granted to the local endpoint by the remote endpoint.
|
||||
* This may be slightly out of date due to network latency. This does NOT
|
||||
* include stream level or TCP level flow control info.
|
||||
*/
|
||||
'local_flow_control_window': (_google_protobuf_Int64Value__Output | null);
|
||||
/**
|
||||
* The amount of window, granted to the remote endpoint by the local endpoint.
|
||||
* This may be slightly out of date due to network latency. This does NOT
|
||||
* include stream level or TCP level flow control info.
|
||||
*/
|
||||
'remote_flow_control_window': (_google_protobuf_Int64Value__Output | null);
|
||||
/**
|
||||
* Socket options set on this socket. May be absent if 'summary' is set
|
||||
* on GetSocketRequest.
|
||||
*/
|
||||
'option': (_grpc_channelz_v1_SocketOption__Output)[];
|
||||
}
|
||||
47
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/SocketOption.ts
generated
vendored
47
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/SocketOption.ts
generated
vendored
@ -0,0 +1,47 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from '../../../google/protobuf/Any';
|
||||
|
||||
/**
|
||||
* SocketOption represents socket options for a socket. Specifically, these
|
||||
* are the options returned by getsockopt().
|
||||
*/
|
||||
export interface SocketOption {
|
||||
/**
|
||||
* The full name of the socket option. Typically this will be the upper case
|
||||
* name, such as "SO_REUSEPORT".
|
||||
*/
|
||||
'name'?: (string);
|
||||
/**
|
||||
* The human readable value of this socket option. At least one of value or
|
||||
* additional will be set.
|
||||
*/
|
||||
'value'?: (string);
|
||||
/**
|
||||
* Additional data associated with the socket option. At least one of value
|
||||
* or additional will be set.
|
||||
*/
|
||||
'additional'?: (_google_protobuf_Any | null);
|
||||
}
|
||||
|
||||
/**
|
||||
* SocketOption represents socket options for a socket. Specifically, these
|
||||
* are the options returned by getsockopt().
|
||||
*/
|
||||
export interface SocketOption__Output {
|
||||
/**
|
||||
* The full name of the socket option. Typically this will be the upper case
|
||||
* name, such as "SO_REUSEPORT".
|
||||
*/
|
||||
'name': (string);
|
||||
/**
|
||||
* The human readable value of this socket option. At least one of value or
|
||||
* additional will be set.
|
||||
*/
|
||||
'value': (string);
|
||||
/**
|
||||
* Additional data associated with the socket option. At least one of value
|
||||
* or additional will be set.
|
||||
*/
|
||||
'additional': (_google_protobuf_Any__Output | null);
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../google/protobuf/Duration';
|
||||
|
||||
/**
|
||||
* For use with SocketOption's additional field. This is primarily used for
|
||||
* SO_LINGER.
|
||||
*/
|
||||
export interface SocketOptionLinger {
|
||||
/**
|
||||
* active maps to `struct linger.l_onoff`
|
||||
*/
|
||||
'active'?: (boolean);
|
||||
/**
|
||||
* duration maps to `struct linger.l_linger`
|
||||
*/
|
||||
'duration'?: (_google_protobuf_Duration | null);
|
||||
}
|
||||
|
||||
/**
|
||||
* For use with SocketOption's additional field. This is primarily used for
|
||||
* SO_LINGER.
|
||||
*/
|
||||
export interface SocketOptionLinger__Output {
|
||||
/**
|
||||
* active maps to `struct linger.l_onoff`
|
||||
*/
|
||||
'active': (boolean);
|
||||
/**
|
||||
* duration maps to `struct linger.l_linger`
|
||||
*/
|
||||
'duration': (_google_protobuf_Duration__Output | null);
|
||||
}
|
||||
@ -0,0 +1,74 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
|
||||
/**
|
||||
* For use with SocketOption's additional field. Tcp info for
|
||||
* SOL_TCP and TCP_INFO.
|
||||
*/
|
||||
export interface SocketOptionTcpInfo {
|
||||
'tcpi_state'?: (number);
|
||||
'tcpi_ca_state'?: (number);
|
||||
'tcpi_retransmits'?: (number);
|
||||
'tcpi_probes'?: (number);
|
||||
'tcpi_backoff'?: (number);
|
||||
'tcpi_options'?: (number);
|
||||
'tcpi_snd_wscale'?: (number);
|
||||
'tcpi_rcv_wscale'?: (number);
|
||||
'tcpi_rto'?: (number);
|
||||
'tcpi_ato'?: (number);
|
||||
'tcpi_snd_mss'?: (number);
|
||||
'tcpi_rcv_mss'?: (number);
|
||||
'tcpi_unacked'?: (number);
|
||||
'tcpi_sacked'?: (number);
|
||||
'tcpi_lost'?: (number);
|
||||
'tcpi_retrans'?: (number);
|
||||
'tcpi_fackets'?: (number);
|
||||
'tcpi_last_data_sent'?: (number);
|
||||
'tcpi_last_ack_sent'?: (number);
|
||||
'tcpi_last_data_recv'?: (number);
|
||||
'tcpi_last_ack_recv'?: (number);
|
||||
'tcpi_pmtu'?: (number);
|
||||
'tcpi_rcv_ssthresh'?: (number);
|
||||
'tcpi_rtt'?: (number);
|
||||
'tcpi_rttvar'?: (number);
|
||||
'tcpi_snd_ssthresh'?: (number);
|
||||
'tcpi_snd_cwnd'?: (number);
|
||||
'tcpi_advmss'?: (number);
|
||||
'tcpi_reordering'?: (number);
|
||||
}
|
||||
|
||||
/**
|
||||
* For use with SocketOption's additional field. Tcp info for
|
||||
* SOL_TCP and TCP_INFO.
|
||||
*/
|
||||
export interface SocketOptionTcpInfo__Output {
|
||||
'tcpi_state': (number);
|
||||
'tcpi_ca_state': (number);
|
||||
'tcpi_retransmits': (number);
|
||||
'tcpi_probes': (number);
|
||||
'tcpi_backoff': (number);
|
||||
'tcpi_options': (number);
|
||||
'tcpi_snd_wscale': (number);
|
||||
'tcpi_rcv_wscale': (number);
|
||||
'tcpi_rto': (number);
|
||||
'tcpi_ato': (number);
|
||||
'tcpi_snd_mss': (number);
|
||||
'tcpi_rcv_mss': (number);
|
||||
'tcpi_unacked': (number);
|
||||
'tcpi_sacked': (number);
|
||||
'tcpi_lost': (number);
|
||||
'tcpi_retrans': (number);
|
||||
'tcpi_fackets': (number);
|
||||
'tcpi_last_data_sent': (number);
|
||||
'tcpi_last_ack_sent': (number);
|
||||
'tcpi_last_data_recv': (number);
|
||||
'tcpi_last_ack_recv': (number);
|
||||
'tcpi_pmtu': (number);
|
||||
'tcpi_rcv_ssthresh': (number);
|
||||
'tcpi_rtt': (number);
|
||||
'tcpi_rttvar': (number);
|
||||
'tcpi_snd_ssthresh': (number);
|
||||
'tcpi_snd_cwnd': (number);
|
||||
'tcpi_advmss': (number);
|
||||
'tcpi_reordering': (number);
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from '../../../google/protobuf/Duration';
|
||||
|
||||
/**
|
||||
* For use with SocketOption's additional field. This is primarily used for
|
||||
* SO_RCVTIMEO and SO_SNDTIMEO
|
||||
*/
|
||||
export interface SocketOptionTimeout {
|
||||
'duration'?: (_google_protobuf_Duration | null);
|
||||
}
|
||||
|
||||
/**
|
||||
* For use with SocketOption's additional field. This is primarily used for
|
||||
* SO_RCVTIMEO and SO_SNDTIMEO
|
||||
*/
|
||||
export interface SocketOptionTimeout__Output {
|
||||
'duration': (_google_protobuf_Duration__Output | null);
|
||||
}
|
||||
31
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/SocketRef.ts
generated
vendored
31
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/SocketRef.ts
generated
vendored
@ -0,0 +1,31 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { Long } from '@grpc/proto-loader';
|
||||
|
||||
/**
|
||||
* SocketRef is a reference to a Socket.
|
||||
*/
|
||||
export interface SocketRef {
|
||||
/**
|
||||
* The globally unique id for this socket. Must be a positive number.
|
||||
*/
|
||||
'socket_id'?: (number | string | Long);
|
||||
/**
|
||||
* An optional name associated with the socket.
|
||||
*/
|
||||
'name'?: (string);
|
||||
}
|
||||
|
||||
/**
|
||||
* SocketRef is a reference to a Socket.
|
||||
*/
|
||||
export interface SocketRef__Output {
|
||||
/**
|
||||
* The globally unique id for this socket. Must be a positive number.
|
||||
*/
|
||||
'socket_id': (string);
|
||||
/**
|
||||
* An optional name associated with the socket.
|
||||
*/
|
||||
'name': (string);
|
||||
}
|
||||
70
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/Subchannel.ts
generated
vendored
70
travel-backend/node_modules/@grpc/grpc-js/src/generated/grpc/channelz/v1/Subchannel.ts
generated
vendored
@ -0,0 +1,70 @@
|
||||
// Original file: proto/channelz.proto
|
||||
|
||||
import type { SubchannelRef as _grpc_channelz_v1_SubchannelRef, SubchannelRef__Output as _grpc_channelz_v1_SubchannelRef__Output } from '../../../grpc/channelz/v1/SubchannelRef';
|
||||
import type { ChannelData as _grpc_channelz_v1_ChannelData, ChannelData__Output as _grpc_channelz_v1_ChannelData__Output } from '../../../grpc/channelz/v1/ChannelData';
|
||||
import type { ChannelRef as _grpc_channelz_v1_ChannelRef, ChannelRef__Output as _grpc_channelz_v1_ChannelRef__Output } from '../../../grpc/channelz/v1/ChannelRef';
|
||||
import type { SocketRef as _grpc_channelz_v1_SocketRef, SocketRef__Output as _grpc_channelz_v1_SocketRef__Output } from '../../../grpc/channelz/v1/SocketRef';
|
||||
|
||||
/**
|
||||
* Subchannel is a logical grouping of channels, subchannels, and sockets.
|
||||
* A subchannel is load balanced over by it's ancestor
|
||||
*/
|
||||
export interface Subchannel {
|
||||
/**
|
||||
* The identifier for this channel.
|
||||
*/
|
||||
'ref'?: (_grpc_channelz_v1_SubchannelRef | null);
|
||||
/**
|
||||
* Data specific to this channel.
|
||||
*/
|
||||
'data'?: (_grpc_channelz_v1_ChannelData | null);
|
||||
/**
|
||||
* There are no ordering guarantees on the order of channel refs.
|
||||
* There may not be cycles in the ref graph.
|
||||
* A channel ref may be present in more than one channel or subchannel.
|
||||
*/
|
||||
'channel_ref'?: (_grpc_channelz_v1_ChannelRef)[];
|
||||
/**
|
||||
* At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
|
||||
* There are no ordering guarantees on the order of subchannel refs.
|
||||
* There may not be cycles in the ref graph.
|
||||
* A sub channel ref may be present in more than one channel or subchannel.
|
||||
*/
|
||||
'subchannel_ref'?: (_grpc_channelz_v1_SubchannelRef)[];
|
||||
/**
|
||||
* There are no ordering guarantees on the order of sockets.
|
||||
*/
|
||||
'socket_ref'?: (_grpc_channelz_v1_SocketRef)[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Subchannel is a logical grouping of channels, subchannels, and sockets.
|
||||
* A subchannel is load balanced over by it's ancestor
|
||||
*/
|
||||
export interface Subchannel__Output {
|
||||
/**
|
||||
* The identifier for this channel.
|
||||
*/
|
||||
'ref': (_grpc_channelz_v1_SubchannelRef__Output | null);
|
||||
/**
|
||||
* Data specific to this channel.
|
||||
*/
|
||||
'data': (_grpc_channelz_v1_ChannelData__Output | null);
|
||||
/**
|
||||
* There are no ordering guarantees on the order of channel refs.
|
||||
* There may not be cycles in the ref graph.
|
||||
* A channel ref may be present in more than one channel or subchannel.
|
||||
*/
|
||||
'channel_ref': (_grpc_channelz_v1_ChannelRef__Output)[];
|
||||
/**
|
||||
* At most one of 'channel_ref+subchannel_ref' and 'socket' is set.
|
||||
* There are no ordering guarantees on the order of subchannel refs.
|
||||
* There may not be cycles in the ref graph.
|
||||
* A sub channel ref may be present in more than one channel or subchannel.
|
||||
*/
|
||||
'subchannel_ref': (_grpc_channelz_v1_SubchannelRef__Output)[];
|
||||
/**
|
||||
* There are no ordering guarantees on the order of sockets.
|
||||
*/
|
||||
'socket_ref': (_grpc_channelz_v1_SocketRef__Output)[];
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue