mirror of
https://gitee.com/iresty/apisix.git
synced 2024-11-29 18:48:31 +08:00
feat(grpc-web): support gRPC-Web Proxy (#5964)
This commit is contained in:
parent
7db31a1a71
commit
ddb9cd28bf
147
apisix/plugins/grpc-web.lua
Normal file
147
apisix/plugins/grpc-web.lua
Normal file
@ -0,0 +1,147 @@
|
||||
--
|
||||
-- Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
-- contributor license agreements. See the NOTICE file distributed with
|
||||
-- this work for additional information regarding copyright ownership.
|
||||
-- The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
-- (the "License"); you may not use this file except in compliance with
|
||||
-- the License. You may obtain a copy of the License at
|
||||
--
|
||||
-- http://www.apache.org/licenses/LICENSE-2.0
|
||||
--
|
||||
-- Unless required by applicable law or agreed to in writing, software
|
||||
-- distributed under the License is distributed on an "AS IS" BASIS,
|
||||
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
-- See the License for the specific language governing permissions and
|
||||
-- limitations under the License.
|
||||
|
||||
local ngx = ngx
|
||||
local ngx_arg = ngx.arg
|
||||
local core = require("apisix.core")
|
||||
local req_set_uri = ngx.req.set_uri
|
||||
local req_set_body_data = ngx.req.set_body_data
|
||||
local decode_base64 = ngx.decode_base64
|
||||
local encode_base64 = ngx.encode_base64
|
||||
|
||||
|
||||
local ALLOW_METHOD_OPTIONS = "OPTIONS"
|
||||
local ALLOW_METHOD_POST = "POST"
|
||||
local CONTENT_ENCODING_BASE64 = "base64"
|
||||
local CONTENT_ENCODING_BINARY = "binary"
|
||||
local DEFAULT_CORS_CONTENT_TYPE = "application/grpc-web-text+proto"
|
||||
local DEFAULT_CORS_ALLOW_ORIGIN = "*"
|
||||
local DEFAULT_CORS_ALLOW_METHODS = ALLOW_METHOD_POST
|
||||
local DEFAULT_CORS_ALLOW_HEADERS = "content-type,x-grpc-web,x-user-agent"
|
||||
local DEFAULT_PROXY_CONTENT_TYPE = "application/grpc"
|
||||
|
||||
|
||||
local plugin_name = "grpc-web"
|
||||
|
||||
local schema = {
|
||||
type = "object",
|
||||
properties = {},
|
||||
}
|
||||
|
||||
local grpc_web_content_encoding = {
|
||||
["application/grpc-web"] = CONTENT_ENCODING_BINARY,
|
||||
["application/grpc-web-text"] = CONTENT_ENCODING_BASE64,
|
||||
["application/grpc-web+proto"] = CONTENT_ENCODING_BINARY,
|
||||
["application/grpc-web-text+proto"] = CONTENT_ENCODING_BASE64,
|
||||
}
|
||||
|
||||
local _M = {
|
||||
version = 0.1,
|
||||
priority = 505,
|
||||
name = plugin_name,
|
||||
schema = schema,
|
||||
}
|
||||
|
||||
function _M.check_schema(conf)
|
||||
return core.schema.check(schema, conf)
|
||||
end
|
||||
|
||||
function _M.access(conf, ctx)
|
||||
local method = core.request.get_method()
|
||||
if method == ALLOW_METHOD_OPTIONS then
|
||||
return 204
|
||||
end
|
||||
|
||||
if method ~= ALLOW_METHOD_POST then
|
||||
-- https://github.com/grpc/grpc-web/blob/master/doc/browser-features.md#cors-support
|
||||
core.log.error("request method: `", method, "` invalid")
|
||||
return 400
|
||||
end
|
||||
|
||||
local mimetype = core.request.header(ctx, "Content-Type")
|
||||
local encoding = grpc_web_content_encoding[mimetype]
|
||||
if not encoding then
|
||||
core.log.error("request Content-Type: `", mimetype, "` invalid")
|
||||
return 400
|
||||
end
|
||||
|
||||
-- set grpc path
|
||||
if not (ctx.curr_req_matched and ctx.curr_req_matched[":ext"]) then
|
||||
core.log.error("routing configuration error, grpc-web plugin only supports ",
|
||||
"`prefix matching` pattern routing")
|
||||
return 400
|
||||
end
|
||||
|
||||
local path = ctx.curr_req_matched[":ext"]
|
||||
if path:byte(1) ~= core.string.byte("/") then
|
||||
path = "/" .. path
|
||||
end
|
||||
|
||||
req_set_uri(path)
|
||||
|
||||
-- set grpc body
|
||||
local body, err = core.request.get_body()
|
||||
if err then
|
||||
core.log.error("failed to read request body, err: ", err)
|
||||
return 400
|
||||
end
|
||||
|
||||
if encoding == CONTENT_ENCODING_BASE64 then
|
||||
body = decode_base64(body)
|
||||
if not body then
|
||||
core.log.error("failed to decode request body")
|
||||
return 400
|
||||
end
|
||||
end
|
||||
|
||||
-- set grpc content-type
|
||||
core.request.set_header(ctx, "Content-Type", DEFAULT_PROXY_CONTENT_TYPE)
|
||||
-- set grpc body
|
||||
req_set_body_data(body)
|
||||
|
||||
-- set context variable
|
||||
ctx.grpc_web_mime = mimetype
|
||||
ctx.grpc_web_encoding = encoding
|
||||
end
|
||||
|
||||
function _M.header_filter(conf, ctx)
|
||||
local method = core.request.get_method()
|
||||
if method == ALLOW_METHOD_OPTIONS then
|
||||
core.response.set_header("Access-Control-Allow-Methods", DEFAULT_CORS_ALLOW_METHODS)
|
||||
core.response.set_header("Access-Control-Allow-Headers", DEFAULT_CORS_ALLOW_HEADERS)
|
||||
end
|
||||
core.response.set_header("Access-Control-Allow-Origin", DEFAULT_CORS_ALLOW_ORIGIN)
|
||||
core.response.set_header("Content-Type", ctx.grpc_web_mime or DEFAULT_CORS_CONTENT_TYPE)
|
||||
end
|
||||
|
||||
function _M.body_filter(conf, ctx)
|
||||
-- If the MIME extension type description of the gRPC-Web standard is not obtained,
|
||||
-- indicating that the request is not based on the gRPC Web specification,
|
||||
-- the processing of the request body will be ignored
|
||||
-- https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md
|
||||
-- https://github.com/grpc/grpc-web/blob/master/doc/browser-features.md#cors-support
|
||||
if not ctx.grpc_web_mime then
|
||||
return
|
||||
end
|
||||
|
||||
if ctx.grpc_web_encoding == CONTENT_ENCODING_BASE64 then
|
||||
local chunk = ngx_arg[1]
|
||||
chunk = encode_base64(chunk)
|
||||
ngx_arg[1] = chunk
|
||||
end
|
||||
end
|
||||
|
||||
return _M
|
@ -75,6 +75,15 @@ install_dependencies() {
|
||||
# installing grpcurl
|
||||
install_grpcurl
|
||||
|
||||
# install nodejs
|
||||
install_nodejs
|
||||
|
||||
# grpc-web server && client
|
||||
cd t/plugin/grpc-web
|
||||
./setup.sh
|
||||
# back to home directory
|
||||
cd ../../../
|
||||
|
||||
# install dependencies
|
||||
git clone https://github.com/iresty/test-nginx.git test-nginx
|
||||
create_lua_deps
|
||||
|
12
ci/common.sh
12
ci/common.sh
@ -62,4 +62,16 @@ install_vault_cli () {
|
||||
unzip vault_${VAULT_VERSION}_linux_amd64.zip && mv ./vault /usr/local/bin
|
||||
}
|
||||
|
||||
install_nodejs () {
|
||||
NODEJS_PREFIX="/usr/local/node"
|
||||
NODEJS_VERSION="16.13.1"
|
||||
wget https://nodejs.org/dist/v${NODEJS_VERSION}/node-v${NODEJS_VERSION}-linux-x64.tar.xz
|
||||
tar -xvf node-v${NODEJS_VERSION}-linux-x64.tar.xz
|
||||
rm -f /usr/local/bin/node
|
||||
rm -f /usr/local/bin/npm
|
||||
mv node-v${NODEJS_VERSION}-linux-x64 ${NODEJS_PREFIX}
|
||||
ln -s ${NODEJS_PREFIX}/bin/node /usr/local/bin/node
|
||||
ln -s ${NODEJS_PREFIX}/bin/npm /usr/local/bin/npm
|
||||
}
|
||||
|
||||
GRPC_SERVER_EXAMPLE_VER=20210819
|
||||
|
@ -57,6 +57,15 @@ do_install() {
|
||||
# install grpcurl
|
||||
install_grpcurl
|
||||
|
||||
# install nodejs
|
||||
install_nodejs
|
||||
|
||||
# grpc-web server && client
|
||||
cd t/plugin/grpc-web
|
||||
./setup.sh
|
||||
# back to home directory
|
||||
cd ../../../
|
||||
|
||||
# install vault cli capabilities
|
||||
install_vault_cli
|
||||
}
|
||||
|
@ -362,6 +362,7 @@ plugins: # plugin list (sorted by priority)
|
||||
- response-rewrite # priority: 899
|
||||
#- dubbo-proxy # priority: 507
|
||||
- grpc-transcode # priority: 506
|
||||
- grpc-web # priority: 505
|
||||
- prometheus # priority: 500
|
||||
- datadog # priority: 495
|
||||
- echo # priority: 412
|
||||
|
@ -51,6 +51,7 @@
|
||||
"plugins/response-rewrite",
|
||||
"plugins/proxy-rewrite",
|
||||
"plugins/grpc-transcode",
|
||||
"plugins/grpc-web",
|
||||
"plugins/fault-injection"
|
||||
]
|
||||
},
|
||||
|
85
docs/en/latest/plugins/grpc-web.md
Normal file
85
docs/en/latest/plugins/grpc-web.md
Normal file
@ -0,0 +1,85 @@
|
||||
---
|
||||
title: grpc-web
|
||||
---
|
||||
|
||||
<!--
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
-->
|
||||
|
||||
## Summary
|
||||
|
||||
- [**Name**](#name)
|
||||
- [**How To Enable**](#how-to-enable)
|
||||
- [**Test Plugin**](#test-plugin)
|
||||
- [**Disable Plugin**](#disable-plugin)
|
||||
|
||||
## Name
|
||||
|
||||
The `grpc-web` plugin is a proxy plugin used to process [gRPC Web](https://github.com/grpc/grpc-web) client requests to `gRPC Server`.
|
||||
|
||||
gRPC Web Client -> APISIX -> gRPC server
|
||||
|
||||
## How To Enable
|
||||
|
||||
To enable the `gRPC Web` proxy plugin, routing must use the `Prefix matching` pattern (for example: `/*` or `/grpc/example/*`),
|
||||
Because the `gRPC Web` client will pass the `package name`, `service interface name`, `method name` and other information declared in the `proto` in the URI (for example: `/path/a6.RouteService/Insert`) ,
|
||||
When using `Absolute Match`, it will not be able to hit the plugin and extract the `proto` information.
|
||||
|
||||
```bash
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"uri":"/grpc/web/*",
|
||||
"plugins":{
|
||||
"grpc-web":{}
|
||||
},
|
||||
"upstream":{
|
||||
"scheme":"grpc",
|
||||
"type":"roundrobin",
|
||||
"nodes":{
|
||||
"127.0.0.1:1980":1
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
## Test Plugin
|
||||
|
||||
- The request method only supports `POST` and `OPTIONS`, refer to: [CORS support](https://github.com/grpc/grpc-web/blob/master/doc/browser-features.md#cors-support).
|
||||
- The `Content-Type` supports `application/grpc-web`, `application/grpc-web-text`, `application/grpc-web+proto`, `application/grpc-web-text+proto`, refer to: [Protocol differences vs gRPC over HTTP2](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2).
|
||||
- Client deployment, refer to: [gRPC-Web Client Runtime Library](https://www.npmjs.com/package/grpc-web) or [Apache APISIX gRPC Web Test Framework](https://github.com/apache/apisix/tree/master/t/plugin/grpc-web).
|
||||
- After the `gRPC Web` client is deployed, you can initiate a `gRPC Web` proxy request to `APISIX` through `browser` or `node`.
|
||||
|
||||
## Disable Plugin
|
||||
|
||||
Just delete the JSON configuration of `grpc-web` in the plugin configuration.
|
||||
The APISIX plug-in is hot-reloaded, so there is no need to restart APISIX.
|
||||
|
||||
```shell
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"uri":"/grpc/web/*",
|
||||
"plugins":{},
|
||||
"upstream":{
|
||||
"scheme":"grpc",
|
||||
"type":"roundrobin",
|
||||
"nodes":{
|
||||
"127.0.0.1:1980":1
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
@ -51,6 +51,7 @@
|
||||
"plugins/response-rewrite",
|
||||
"plugins/proxy-rewrite",
|
||||
"plugins/grpc-transcode",
|
||||
"plugins/grpc-web",
|
||||
"plugins/fault-injection"
|
||||
]
|
||||
},
|
||||
|
84
docs/zh/latest/plugins/grpc-web.md
Normal file
84
docs/zh/latest/plugins/grpc-web.md
Normal file
@ -0,0 +1,84 @@
|
||||
---
|
||||
title: grpc-web
|
||||
---
|
||||
|
||||
<!--
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
#
|
||||
-->
|
||||
|
||||
## 摘要
|
||||
|
||||
- [**定义**](#定义)
|
||||
- [**如何开启**](#如何开启)
|
||||
- [**测试插件**](#测试插件)
|
||||
- [**禁用插件**](#禁用插件)
|
||||
|
||||
## 定义
|
||||
|
||||
`grpc-web` 插件是一个代理插件,用于转换 [gRPC Web](https://github.com/grpc/grpc-web) 客户端到 `gRPC Server` 的请求。
|
||||
|
||||
gRPC Web Client -> APISIX -> gRPC server
|
||||
|
||||
## 如何开启
|
||||
|
||||
启用 `gRPC Web` 代理插件,路由必须使用 `前缀匹配` 模式(例如:`/*` 或 `/grpc/example/*`),
|
||||
因为 `gRPC Web` 客户端会在 URI 中传递 `proto` 中声明的`包名称`、`服务接口名称`、`方法名称`等信息(例如:`/path/a6.RouteService/Insert`),
|
||||
使用 `绝对匹配` 时将无法命中插件和提取 `proto` 信息。
|
||||
|
||||
```bash
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"uri":"/grpc/web/*",
|
||||
"plugins":{
|
||||
"grpc-web":{}
|
||||
},
|
||||
"upstream":{
|
||||
"scheme":"grpc",
|
||||
"type":"roundrobin",
|
||||
"nodes":{
|
||||
"127.0.0.1:1980":1
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
## 测试插件
|
||||
|
||||
- 请求方式仅支持 `POST` 和 `OPTIONS`,参考:[CORS support](https://github.com/grpc/grpc-web/blob/master/doc/browser-features.md#cors-support) 。
|
||||
- 内容类型支持 `application/grpc-web`、`application/grpc-web-text`、`application/grpc-web+proto`、`application/grpc-web-text+proto`,参考:[Protocol differences vs gRPC over HTTP2](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md#protocol-differences-vs-grpc-over-http2) 。
|
||||
- 客户端部署,参考:[gRPC-Web Client Runtime Library](https://www.npmjs.com/package/grpc-web) 或 [Apache APISIX gRPC Web 测试框架](https://github.com/apache/apisix/tree/master/t/plugin/grpc-web) 。
|
||||
- 完成 `gRPC Web` 客户端部署后,即可通过 `浏览器` 或 `node` 向 `APISIX` 发起 `gRPC Web` 代理请求。
|
||||
|
||||
## 禁用插件
|
||||
|
||||
只需删除插件配置中 `grpc-web` 的JSON配置即可。 APISIX 插件是热加载的,所以不需要重启 APISIX。
|
||||
|
||||
```bash
|
||||
curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"uri":"/grpc/web/*",
|
||||
"plugins":{},
|
||||
"upstream":{
|
||||
"scheme":"grpc",
|
||||
"type":"roundrobin",
|
||||
"nodes":{
|
||||
"127.0.0.1:1980":1
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
1
t/admin/plugins.t
vendored
1
t/admin/plugins.t
vendored
@ -98,6 +98,7 @@ traffic-split
|
||||
redirect
|
||||
response-rewrite
|
||||
grpc-transcode
|
||||
grpc-web
|
||||
prometheus
|
||||
datadog
|
||||
echo
|
||||
|
221
t/plugin/grpc-web.t
vendored
Normal file
221
t/plugin/grpc-web.t
vendored
Normal file
@ -0,0 +1,221 @@
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
use t::APISIX 'no_plan';
|
||||
|
||||
no_long_string();
|
||||
no_shuffle();
|
||||
no_root_location();
|
||||
|
||||
add_block_preprocessor(sub {
|
||||
my ($block) = @_;
|
||||
|
||||
if (!$block->request) {
|
||||
$block->set_value("request", "GET /t");
|
||||
}
|
||||
|
||||
if ((!defined $block->error_log) && (!defined $block->no_error_log)) {
|
||||
$block->set_value("no_error_log", "[error]");
|
||||
}
|
||||
});
|
||||
|
||||
run_tests;
|
||||
|
||||
__DATA__
|
||||
|
||||
=== TEST 1: set route (default grpc web proxy route)
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
|
||||
local config = {
|
||||
uri = "/grpc/*",
|
||||
upstream = {
|
||||
scheme = "grpc",
|
||||
type = "roundrobin",
|
||||
nodes = {
|
||||
["127.0.0.1:50001"] = 1
|
||||
}
|
||||
},
|
||||
plugins = {
|
||||
["grpc-web"] = {}
|
||||
}
|
||||
}
|
||||
local t = require("lib.test_admin").test
|
||||
local code, body = t('/apisix/admin/routes/1', ngx.HTTP_PUT, config)
|
||||
|
||||
if code >= 300 then
|
||||
ngx.status = code
|
||||
ngx.say(body)
|
||||
return
|
||||
end
|
||||
|
||||
ngx.say(body)
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
passed
|
||||
|
||||
|
||||
|
||||
=== TEST 2: Flush all data through APISIX gRPC-Web Proxy
|
||||
--- exec
|
||||
node ./t/plugin/grpc-web/client.js FLUSH
|
||||
--- response_body
|
||||
[]
|
||||
|
||||
|
||||
|
||||
=== TEST 3: Insert first data through APISIX gRPC-Web Proxy
|
||||
--- exec
|
||||
node ./t/plugin/grpc-web/client.js POST 1 route01 path01
|
||||
--- response_body
|
||||
[["1",{"name":"route01","path":"path01"}]]
|
||||
|
||||
|
||||
|
||||
=== TEST 4: Update data through APISIX gRPC-Web Proxy
|
||||
--- exec
|
||||
node ./t/plugin/grpc-web/client.js PUT 1 route01 hello
|
||||
--- response_body
|
||||
[["1",{"name":"route01","path":"hello"}]]
|
||||
|
||||
|
||||
|
||||
=== TEST 5: Insert second data through APISIX gRPC-Web Proxy
|
||||
--- exec
|
||||
node ./t/plugin/grpc-web/client.js POST 2 route02 path02
|
||||
--- response_body
|
||||
[["1",{"name":"route01","path":"hello"}],["2",{"name":"route02","path":"path02"}]]
|
||||
|
||||
|
||||
|
||||
=== TEST 6: Insert third data through APISIX gRPC-Web Proxy
|
||||
--- exec
|
||||
node ./t/plugin/grpc-web/client.js POST 3 route03 path03
|
||||
--- response_body
|
||||
[["1",{"name":"route01","path":"hello"}],["2",{"name":"route02","path":"path02"}],["3",{"name":"route03","path":"path03"}]]
|
||||
|
||||
|
||||
|
||||
=== TEST 7: Delete first data through APISIX gRPC-Web Proxy
|
||||
--- exec
|
||||
node ./t/plugin/grpc-web/client.js DEL 1
|
||||
--- response_body
|
||||
[["2",{"name":"route02","path":"path02"}],["3",{"name":"route03","path":"path03"}]]
|
||||
|
||||
|
||||
|
||||
=== TEST 8: Get second data through APISIX gRPC-Web Proxy
|
||||
--- exec
|
||||
node ./t/plugin/grpc-web/client.js GET 2
|
||||
--- response_body
|
||||
{"name":"route02","path":"path02"}
|
||||
|
||||
|
||||
|
||||
=== TEST 9: Get all data through APISIX gRPC-Web Proxy
|
||||
--- exec
|
||||
node ./t/plugin/grpc-web/client.js all
|
||||
--- response_body
|
||||
[["2",{"name":"route02","path":"path02"}],["3",{"name":"route03","path":"path03"}]]
|
||||
|
||||
|
||||
|
||||
=== TEST 10: test options request
|
||||
--- request
|
||||
OPTIONS /grpc/a6.RouteService/GetAll
|
||||
--- error_code: 204
|
||||
--- response_headers
|
||||
Access-Control-Allow-Methods: POST
|
||||
Access-Control-Allow-Headers: content-type,x-grpc-web,x-user-agent
|
||||
Access-Control-Allow-Origin: *
|
||||
|
||||
|
||||
|
||||
=== TEST 11: test non-options request
|
||||
--- request
|
||||
GET /grpc/a6.RouteService/GetAll
|
||||
--- error_code: 400
|
||||
--- response_headers
|
||||
Access-Control-Allow-Origin: *
|
||||
Content-Type: application/grpc-web-text+proto
|
||||
--- error_log
|
||||
request method: `GET` invalid
|
||||
|
||||
|
||||
|
||||
=== TEST 12: test non gRPC Web MIME type request
|
||||
--- request
|
||||
POST /grpc/a6.RouteService/GetAll
|
||||
--- more_headers
|
||||
Content-Type: application/json
|
||||
--- error_code: 400
|
||||
--- response_headers
|
||||
Access-Control-Allow-Origin: *
|
||||
Content-Type: application/grpc-web-text+proto
|
||||
--- error_log
|
||||
request Content-Type: `application/json` invalid
|
||||
|
||||
|
||||
|
||||
=== TEST 13: set route (absolute match)
|
||||
--- config
|
||||
location /t {
|
||||
content_by_lua_block {
|
||||
|
||||
local config = {
|
||||
uri = "/grpc2/a6.RouteService/GetAll",
|
||||
upstream = {
|
||||
scheme = "grpc",
|
||||
type = "roundrobin",
|
||||
nodes = {
|
||||
["127.0.0.1:50001"] = 1
|
||||
}
|
||||
},
|
||||
plugins = {
|
||||
["grpc-web"] = {}
|
||||
}
|
||||
}
|
||||
local t = require("lib.test_admin").test
|
||||
local code, body = t('/apisix/admin/routes/1', ngx.HTTP_PUT, config)
|
||||
|
||||
if code >= 300 then
|
||||
ngx.status = code
|
||||
ngx.say(body)
|
||||
return
|
||||
end
|
||||
|
||||
ngx.say(body)
|
||||
}
|
||||
}
|
||||
--- response_body
|
||||
passed
|
||||
|
||||
|
||||
|
||||
=== TEST 14: test route (absolute match)
|
||||
--- request
|
||||
POST /grpc2/a6.RouteService/GetAll
|
||||
--- more_headers
|
||||
Content-Type: application/grpc-web
|
||||
--- error_code: 400
|
||||
--- response_headers
|
||||
Access-Control-Allow-Origin: *
|
||||
Content-Type: application/grpc-web-text+proto
|
||||
--- error_log
|
||||
routing configuration error, grpc-web plugin only supports `prefix matching` pattern routing
|
513
t/plugin/grpc-web/a6/routes.pb.go
Normal file
513
t/plugin/grpc-web/a6/routes.pb.go
Normal file
@ -0,0 +1,513 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.
|
||||
*/
|
||||
|
||||
package a6
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type Empty struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Empty) Reset() { *m = Empty{} }
|
||||
func (m *Empty) String() string { return proto.CompactTextString(m) }
|
||||
func (*Empty) ProtoMessage() {}
|
||||
func (*Empty) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_078f480fb67d0ab3, []int{0}
|
||||
}
|
||||
|
||||
func (m *Empty) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Empty.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Empty.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Empty) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Empty.Merge(m, src)
|
||||
}
|
||||
func (m *Empty) XXX_Size() int {
|
||||
return xxx_messageInfo_Empty.Size(m)
|
||||
}
|
||||
func (m *Empty) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Empty.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Empty proto.InternalMessageInfo
|
||||
|
||||
type Route struct {
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Route) Reset() { *m = Route{} }
|
||||
func (m *Route) String() string { return proto.CompactTextString(m) }
|
||||
func (*Route) ProtoMessage() {}
|
||||
func (*Route) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_078f480fb67d0ab3, []int{1}
|
||||
}
|
||||
|
||||
func (m *Route) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Route.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Route) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Route.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Route) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Route.Merge(m, src)
|
||||
}
|
||||
func (m *Route) XXX_Size() int {
|
||||
return xxx_messageInfo_Route.Size(m)
|
||||
}
|
||||
func (m *Route) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Route.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Route proto.InternalMessageInfo
|
||||
|
||||
func (m *Route) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Route) GetPath() string {
|
||||
if m != nil {
|
||||
return m.Path
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Request struct {
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Route *Route `protobuf:"bytes,2,opt,name=route,proto3" json:"route,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Request) Reset() { *m = Request{} }
|
||||
func (m *Request) String() string { return proto.CompactTextString(m) }
|
||||
func (*Request) ProtoMessage() {}
|
||||
func (*Request) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_078f480fb67d0ab3, []int{2}
|
||||
}
|
||||
|
||||
func (m *Request) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Request.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Request.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Request) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Request.Merge(m, src)
|
||||
}
|
||||
func (m *Request) XXX_Size() int {
|
||||
return xxx_messageInfo_Request.Size(m)
|
||||
}
|
||||
func (m *Request) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Request.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Request proto.InternalMessageInfo
|
||||
|
||||
func (m *Request) GetId() string {
|
||||
if m != nil {
|
||||
return m.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Request) GetRoute() *Route {
|
||||
if m != nil {
|
||||
return m.Route
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Response struct {
|
||||
Status bool `protobuf:"varint,1,opt,name=status,proto3" json:"status,omitempty"`
|
||||
Route *Route `protobuf:"bytes,2,opt,name=route,proto3" json:"route,omitempty"`
|
||||
Routes map[string]*Route `protobuf:"bytes,3,rep,name=routes,proto3" json:"routes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Response) Reset() { *m = Response{} }
|
||||
func (m *Response) String() string { return proto.CompactTextString(m) }
|
||||
func (*Response) ProtoMessage() {}
|
||||
func (*Response) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_078f480fb67d0ab3, []int{3}
|
||||
}
|
||||
|
||||
func (m *Response) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Response.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Response.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Response) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Response.Merge(m, src)
|
||||
}
|
||||
func (m *Response) XXX_Size() int {
|
||||
return xxx_messageInfo_Response.Size(m)
|
||||
}
|
||||
func (m *Response) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Response.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Response proto.InternalMessageInfo
|
||||
|
||||
func (m *Response) GetStatus() bool {
|
||||
if m != nil {
|
||||
return m.Status
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *Response) GetRoute() *Route {
|
||||
if m != nil {
|
||||
return m.Route
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Response) GetRoutes() map[string]*Route {
|
||||
if m != nil {
|
||||
return m.Routes
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Empty)(nil), "a6.Empty")
|
||||
proto.RegisterType((*Route)(nil), "a6.Route")
|
||||
proto.RegisterType((*Request)(nil), "a6.Request")
|
||||
proto.RegisterType((*Response)(nil), "a6.Response")
|
||||
proto.RegisterMapType((map[string]*Route)(nil), "a6.Response.RoutesEntry")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("routes.proto", fileDescriptor_078f480fb67d0ab3) }
|
||||
|
||||
var fileDescriptor_078f480fb67d0ab3 = []byte{
|
||||
// 307 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0x4f, 0x4b, 0xf3, 0x40,
|
||||
0x10, 0x87, 0xdf, 0x24, 0x6f, 0xd2, 0x76, 0x52, 0x44, 0xe6, 0x20, 0xa1, 0x17, 0xcb, 0x4a, 0xa1,
|
||||
0xa7, 0x54, 0x2a, 0x14, 0xa9, 0x27, 0xc5, 0x5a, 0xbc, 0xae, 0x78, 0xf1, 0xb6, 0x9a, 0x81, 0x06,
|
||||
0xf3, 0xcf, 0xec, 0x26, 0x90, 0xcf, 0xe6, 0xc7, 0xf2, 0x0b, 0x48, 0x26, 0x39, 0x14, 0x14, 0x73,
|
||||
0x9b, 0x3c, 0x79, 0xe6, 0x37, 0x93, 0x21, 0x30, 0x2d, 0xf3, 0xca, 0x90, 0x0e, 0x8b, 0x32, 0x37,
|
||||
0x39, 0xda, 0x6a, 0x23, 0x46, 0xe0, 0xee, 0xd2, 0xc2, 0x34, 0x62, 0x05, 0xae, 0x6c, 0x5f, 0x22,
|
||||
0xc2, 0xff, 0x4c, 0xa5, 0x14, 0x58, 0x73, 0x6b, 0x39, 0x91, 0x5c, 0xb7, 0xac, 0x50, 0xe6, 0x10,
|
||||
0xd8, 0x1d, 0x6b, 0x6b, 0xb1, 0x85, 0x91, 0xa4, 0x8f, 0x8a, 0xb4, 0xc1, 0x13, 0xb0, 0xe3, 0xa8,
|
||||
0x6f, 0xb0, 0xe3, 0x08, 0xcf, 0xc1, 0xe5, 0x41, 0xec, 0xfb, 0xeb, 0x49, 0xa8, 0x36, 0x21, 0x87,
|
||||
0xcb, 0x8e, 0x8b, 0x4f, 0x0b, 0xc6, 0x92, 0x74, 0x91, 0x67, 0x9a, 0xf0, 0x0c, 0x3c, 0x6d, 0x94,
|
||||
0xa9, 0x34, 0x27, 0x8c, 0x65, 0xff, 0x34, 0x98, 0x82, 0x97, 0xe0, 0x75, 0xdf, 0x13, 0x38, 0x73,
|
||||
0x67, 0xe9, 0xaf, 0x03, 0x36, 0xfa, 0xd8, 0x4e, 0xd5, 0xbb, 0xcc, 0x94, 0x8d, 0xec, 0xbd, 0xd9,
|
||||
0x3d, 0xf8, 0x47, 0x18, 0x4f, 0xc1, 0x79, 0xa7, 0xa6, 0x5f, 0xbc, 0x2d, 0xdb, 0x99, 0xb5, 0x4a,
|
||||
0xaa, 0xdf, 0x66, 0x32, 0xdf, 0xda, 0xd7, 0xd6, 0xfa, 0xcb, 0x82, 0x29, 0xc3, 0x27, 0x2a, 0xeb,
|
||||
0xf8, 0x8d, 0x70, 0x01, 0xe3, 0x87, 0xa4, 0xd2, 0x87, 0xdb, 0x24, 0x41, 0x6e, 0xe1, 0x93, 0xce,
|
||||
0xa6, 0xc7, 0xfb, 0x88, 0x7f, 0x78, 0x01, 0xde, 0x9e, 0xcc, 0x80, 0x24, 0xc0, 0xd9, 0x93, 0x41,
|
||||
0xbf, 0xc3, 0x7c, 0xdf, 0x1f, 0xce, 0x02, 0xbc, 0xc7, 0x4c, 0x53, 0x39, 0xac, 0x3d, 0x17, 0x91,
|
||||
0x32, 0x34, 0xa8, 0x49, 0x4a, 0xf3, 0xfa, 0x6f, 0xed, 0x6e, 0xf4, 0xe2, 0x86, 0xab, 0x1b, 0xb5,
|
||||
0x79, 0xf5, 0xf8, 0xef, 0xb9, 0xfa, 0x0e, 0x00, 0x00, 0xff, 0xff, 0xba, 0xd4, 0xb5, 0x13, 0x4d,
|
||||
0x02, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ grpc.ClientConn
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion4
|
||||
|
||||
// RouteServiceClient is the client API for RouteService service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type RouteServiceClient interface {
|
||||
FlushAll(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Response, error)
|
||||
GetAll(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Response, error)
|
||||
Get(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error)
|
||||
Insert(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error)
|
||||
Update(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error)
|
||||
Remove(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error)
|
||||
}
|
||||
|
||||
type routeServiceClient struct {
|
||||
cc *grpc.ClientConn
|
||||
}
|
||||
|
||||
func NewRouteServiceClient(cc *grpc.ClientConn) RouteServiceClient {
|
||||
return &routeServiceClient{cc}
|
||||
}
|
||||
|
||||
func (c *routeServiceClient) FlushAll(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Response, error) {
|
||||
out := new(Response)
|
||||
err := c.cc.Invoke(ctx, "/a6.RouteService/FlushAll", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *routeServiceClient) GetAll(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Response, error) {
|
||||
out := new(Response)
|
||||
err := c.cc.Invoke(ctx, "/a6.RouteService/GetAll", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *routeServiceClient) Get(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) {
|
||||
out := new(Response)
|
||||
err := c.cc.Invoke(ctx, "/a6.RouteService/Get", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *routeServiceClient) Insert(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) {
|
||||
out := new(Response)
|
||||
err := c.cc.Invoke(ctx, "/a6.RouteService/Insert", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *routeServiceClient) Update(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) {
|
||||
out := new(Response)
|
||||
err := c.cc.Invoke(ctx, "/a6.RouteService/Update", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *routeServiceClient) Remove(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) {
|
||||
out := new(Response)
|
||||
err := c.cc.Invoke(ctx, "/a6.RouteService/Remove", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// RouteServiceServer is the server API for RouteService service.
|
||||
type RouteServiceServer interface {
|
||||
FlushAll(context.Context, *Empty) (*Response, error)
|
||||
GetAll(context.Context, *Empty) (*Response, error)
|
||||
Get(context.Context, *Request) (*Response, error)
|
||||
Insert(context.Context, *Request) (*Response, error)
|
||||
Update(context.Context, *Request) (*Response, error)
|
||||
Remove(context.Context, *Request) (*Response, error)
|
||||
}
|
||||
|
||||
// UnimplementedRouteServiceServer can be embedded to have forward compatible implementations.
|
||||
type UnimplementedRouteServiceServer struct {
|
||||
}
|
||||
|
||||
func (*UnimplementedRouteServiceServer) FlushAll(ctx context.Context, req *Empty) (*Response, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method FlushAll not implemented")
|
||||
}
|
||||
func (*UnimplementedRouteServiceServer) GetAll(ctx context.Context, req *Empty) (*Response, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetAll not implemented")
|
||||
}
|
||||
func (*UnimplementedRouteServiceServer) Get(ctx context.Context, req *Request) (*Response, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Get not implemented")
|
||||
}
|
||||
func (*UnimplementedRouteServiceServer) Insert(ctx context.Context, req *Request) (*Response, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Insert not implemented")
|
||||
}
|
||||
func (*UnimplementedRouteServiceServer) Update(ctx context.Context, req *Request) (*Response, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Update not implemented")
|
||||
}
|
||||
func (*UnimplementedRouteServiceServer) Remove(ctx context.Context, req *Request) (*Response, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Remove not implemented")
|
||||
}
|
||||
|
||||
func RegisterRouteServiceServer(s *grpc.Server, srv RouteServiceServer) {
|
||||
s.RegisterService(&_RouteService_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _RouteService_FlushAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Empty)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RouteServiceServer).FlushAll(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/a6.RouteService/FlushAll",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RouteServiceServer).FlushAll(ctx, req.(*Empty))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _RouteService_GetAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Empty)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RouteServiceServer).GetAll(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/a6.RouteService/GetAll",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RouteServiceServer).GetAll(ctx, req.(*Empty))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _RouteService_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Request)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RouteServiceServer).Get(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/a6.RouteService/Get",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RouteServiceServer).Get(ctx, req.(*Request))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _RouteService_Insert_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Request)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RouteServiceServer).Insert(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/a6.RouteService/Insert",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RouteServiceServer).Insert(ctx, req.(*Request))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _RouteService_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Request)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RouteServiceServer).Update(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/a6.RouteService/Update",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RouteServiceServer).Update(ctx, req.(*Request))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _RouteService_Remove_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Request)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(RouteServiceServer).Remove(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/a6.RouteService/Remove",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(RouteServiceServer).Remove(ctx, req.(*Request))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _RouteService_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "a6.RouteService",
|
||||
HandlerType: (*RouteServiceServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "FlushAll",
|
||||
Handler: _RouteService_FlushAll_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetAll",
|
||||
Handler: _RouteService_GetAll_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Get",
|
||||
Handler: _RouteService_Get_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Insert",
|
||||
Handler: _RouteService_Insert_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Update",
|
||||
Handler: _RouteService_Update_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Remove",
|
||||
Handler: _RouteService_Remove_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "routes.proto",
|
||||
}
|
49
t/plugin/grpc-web/a6/routes.proto
Normal file
49
t/plugin/grpc-web/a6/routes.proto
Normal file
@ -0,0 +1,49 @@
|
||||
//
|
||||
// Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
// contributor license agreements. See the NOTICE file distributed with
|
||||
// this work for additional information regarding copyright ownership.
|
||||
// The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
// (the "License"); you may not use this file except in compliance with
|
||||
// the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package a6;
|
||||
|
||||
option go_package = "./;a6";
|
||||
|
||||
service RouteService {
|
||||
rpc FlushAll (Empty) returns (Response) {}
|
||||
rpc GetAll (Empty) returns (Response) {}
|
||||
rpc Get (Request) returns (Response) {}
|
||||
rpc Insert (Request) returns (Response) {}
|
||||
rpc Update (Request) returns (Response) {}
|
||||
rpc Remove (Request) returns (Response) {}
|
||||
}
|
||||
|
||||
message Empty {}
|
||||
|
||||
message Route {
|
||||
string name = 1;
|
||||
string path = 2;
|
||||
}
|
||||
|
||||
message Request {
|
||||
string id = 1;
|
||||
Route route = 2;
|
||||
}
|
||||
|
||||
message Response {
|
||||
bool status = 1;
|
||||
Route route = 2;
|
||||
map <string, Route> routes = 3;
|
||||
}
|
97
t/plugin/grpc-web/a6/routes_grpc.pb.go
Normal file
97
t/plugin/grpc-web/a6/routes_grpc.pb.go
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.
|
||||
*/
|
||||
|
||||
package a6
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
uuid "github.com/satori/go.uuid"
|
||||
)
|
||||
|
||||
type RouteServer struct {
|
||||
Routes map[string]*Route
|
||||
}
|
||||
|
||||
func (rs *RouteServer) init() {
|
||||
if rs.Routes == nil {
|
||||
rs.Routes = make(map[string]*Route)
|
||||
}
|
||||
}
|
||||
|
||||
func (rs *RouteServer) FlushAll(ctx context.Context, req *Empty) (*Response, error) {
|
||||
if rs.Routes != nil {
|
||||
rs.Routes = make(map[string]*Route)
|
||||
}
|
||||
return &Response{Routes: rs.Routes, Status: true}, nil
|
||||
}
|
||||
|
||||
func (rs *RouteServer) GetAll(ctx context.Context, req *Empty) (*Response, error) {
|
||||
rs.init()
|
||||
return &Response{Routes: rs.Routes, Status: true}, nil
|
||||
}
|
||||
|
||||
func (rs *RouteServer) Get(ctx context.Context, req *Request) (*Response, error) {
|
||||
rs.init()
|
||||
if len(req.Id) == 0 {
|
||||
return &Response{Status: false}, errors.New("route ID undefined")
|
||||
}
|
||||
|
||||
if route, ok := rs.Routes[req.Id]; ok {
|
||||
return &Response{Status: true, Route: route}, nil
|
||||
}
|
||||
|
||||
return &Response{Status: false}, errors.New("route not found")
|
||||
}
|
||||
|
||||
func (rs *RouteServer) Insert(ctx context.Context, req *Request) (*Response, error) {
|
||||
rs.init()
|
||||
if len(req.Id) <= 0 {
|
||||
req.Id = uuid.NewV4().String()
|
||||
}
|
||||
rs.Routes[req.Id] = req.Route
|
||||
return &Response{Status: true, Routes: rs.Routes}, nil
|
||||
}
|
||||
|
||||
func (rs *RouteServer) Update(ctx context.Context, req *Request) (*Response, error) {
|
||||
rs.init()
|
||||
if len(req.Id) == 0 {
|
||||
return &Response{Status: false}, errors.New("route ID undefined")
|
||||
}
|
||||
|
||||
if _, ok := rs.Routes[req.Id]; ok {
|
||||
rs.Routes[req.Id] = req.Route
|
||||
return &Response{Status: true, Routes: rs.Routes}, nil
|
||||
}
|
||||
|
||||
return &Response{Status: false}, errors.New("route not found")
|
||||
}
|
||||
|
||||
func (rs *RouteServer) Remove(ctx context.Context, req *Request) (*Response, error) {
|
||||
rs.init()
|
||||
if len(req.Id) == 0 {
|
||||
return &Response{Status: false}, errors.New("route ID undefined")
|
||||
}
|
||||
|
||||
if _, ok := rs.Routes[req.Id]; ok {
|
||||
delete(rs.Routes, req.Id)
|
||||
return &Response{Status: true, Routes: rs.Routes}, nil
|
||||
}
|
||||
|
||||
return &Response{Status: false}, errors.New("route not found")
|
||||
}
|
443
t/plugin/grpc-web/a6/routes_grpc_web_pb.js
Normal file
443
t/plugin/grpc-web/a6/routes_grpc_web_pb.js
Normal file
@ -0,0 +1,443 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const grpc = {};
|
||||
grpc.web = require('grpc-web');
|
||||
|
||||
const proto = {};
|
||||
proto.a6 = require('./routes_pb.js');
|
||||
|
||||
/**
|
||||
* @param {string} hostname
|
||||
* @param {?Object} credentials
|
||||
* @param {?grpc.web.ClientOptions} options
|
||||
* @constructor
|
||||
* @struct
|
||||
* @final
|
||||
*/
|
||||
proto.a6.RouteServiceClient =
|
||||
function(hostname, credentials, options) {
|
||||
if (!options) options = {};
|
||||
options.format = 'binary';
|
||||
|
||||
/**
|
||||
* @private @const {!grpc.web.GrpcWebClientBase} The client
|
||||
*/
|
||||
this.client_ = new grpc.web.GrpcWebClientBase(options);
|
||||
|
||||
/**
|
||||
* @private @const {string} The hostname
|
||||
*/
|
||||
this.hostname_ = hostname;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} hostname
|
||||
* @param {?Object} credentials
|
||||
* @param {?grpc.web.ClientOptions} options
|
||||
* @constructor
|
||||
* @struct
|
||||
* @final
|
||||
*/
|
||||
proto.a6.RouteServicePromiseClient =
|
||||
function(hostname, credentials, options) {
|
||||
if (!options) options = {};
|
||||
options.format = 'binary';
|
||||
|
||||
/**
|
||||
* @private @const {!grpc.web.GrpcWebClientBase} The client
|
||||
*/
|
||||
this.client_ = new grpc.web.GrpcWebClientBase(options);
|
||||
|
||||
/**
|
||||
* @private @const {string} The hostname
|
||||
*/
|
||||
this.hostname_ = hostname;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.a6.Empty,
|
||||
* !proto.a6.Response>}
|
||||
*/
|
||||
const methodDescriptor_RouteService_FlushAll = new grpc.web.MethodDescriptor(
|
||||
'/a6.RouteService/FlushAll',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.a6.Empty,
|
||||
proto.a6.Response,
|
||||
/**
|
||||
* @param {!proto.a6.Empty} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.a6.Response.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.a6.Empty} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.RpcError, ?proto.a6.Response)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.a6.Response>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.a6.RouteServiceClient.prototype.flushAll =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/a6.RouteService/FlushAll',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_RouteService_FlushAll,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.a6.Empty} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>=} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.a6.Response>}
|
||||
* Promise that resolves to the response
|
||||
*/
|
||||
proto.a6.RouteServicePromiseClient.prototype.flushAll =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/a6.RouteService/FlushAll',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_RouteService_FlushAll);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.a6.Empty,
|
||||
* !proto.a6.Response>}
|
||||
*/
|
||||
const methodDescriptor_RouteService_GetAll = new grpc.web.MethodDescriptor(
|
||||
'/a6.RouteService/GetAll',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.a6.Empty,
|
||||
proto.a6.Response,
|
||||
/**
|
||||
* @param {!proto.a6.Empty} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.a6.Response.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.a6.Empty} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.RpcError, ?proto.a6.Response)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.a6.Response>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.a6.RouteServiceClient.prototype.getAll =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/a6.RouteService/GetAll',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_RouteService_GetAll,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.a6.Empty} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>=} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.a6.Response>}
|
||||
* Promise that resolves to the response
|
||||
*/
|
||||
proto.a6.RouteServicePromiseClient.prototype.getAll =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/a6.RouteService/GetAll',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_RouteService_GetAll);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.a6.Request,
|
||||
* !proto.a6.Response>}
|
||||
*/
|
||||
const methodDescriptor_RouteService_Get = new grpc.web.MethodDescriptor(
|
||||
'/a6.RouteService/Get',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.a6.Request,
|
||||
proto.a6.Response,
|
||||
/**
|
||||
* @param {!proto.a6.Request} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.a6.Response.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.a6.Request} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.RpcError, ?proto.a6.Response)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.a6.Response>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.a6.RouteServiceClient.prototype.get =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/a6.RouteService/Get',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_RouteService_Get,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.a6.Request} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>=} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.a6.Response>}
|
||||
* Promise that resolves to the response
|
||||
*/
|
||||
proto.a6.RouteServicePromiseClient.prototype.get =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/a6.RouteService/Get',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_RouteService_Get);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.a6.Request,
|
||||
* !proto.a6.Response>}
|
||||
*/
|
||||
const methodDescriptor_RouteService_Insert = new grpc.web.MethodDescriptor(
|
||||
'/a6.RouteService/Insert',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.a6.Request,
|
||||
proto.a6.Response,
|
||||
/**
|
||||
* @param {!proto.a6.Request} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.a6.Response.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.a6.Request} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.RpcError, ?proto.a6.Response)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.a6.Response>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.a6.RouteServiceClient.prototype.insert =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/a6.RouteService/Insert',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_RouteService_Insert,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.a6.Request} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>=} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.a6.Response>}
|
||||
* Promise that resolves to the response
|
||||
*/
|
||||
proto.a6.RouteServicePromiseClient.prototype.insert =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/a6.RouteService/Insert',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_RouteService_Insert);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.a6.Request,
|
||||
* !proto.a6.Response>}
|
||||
*/
|
||||
const methodDescriptor_RouteService_Update = new grpc.web.MethodDescriptor(
|
||||
'/a6.RouteService/Update',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.a6.Request,
|
||||
proto.a6.Response,
|
||||
/**
|
||||
* @param {!proto.a6.Request} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.a6.Response.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.a6.Request} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.RpcError, ?proto.a6.Response)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.a6.Response>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.a6.RouteServiceClient.prototype.update =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/a6.RouteService/Update',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_RouteService_Update,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.a6.Request} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>=} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.a6.Response>}
|
||||
* Promise that resolves to the response
|
||||
*/
|
||||
proto.a6.RouteServicePromiseClient.prototype.update =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/a6.RouteService/Update',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_RouteService_Update);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.a6.Request,
|
||||
* !proto.a6.Response>}
|
||||
*/
|
||||
const methodDescriptor_RouteService_Remove = new grpc.web.MethodDescriptor(
|
||||
'/a6.RouteService/Remove',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.a6.Request,
|
||||
proto.a6.Response,
|
||||
/**
|
||||
* @param {!proto.a6.Request} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.a6.Response.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.a6.Request} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.RpcError, ?proto.a6.Response)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.a6.Response>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.a6.RouteServiceClient.prototype.remove =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/a6.RouteService/Remove',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_RouteService_Remove,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.a6.Request} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>=} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.a6.Response>}
|
||||
* Promise that resolves to the response
|
||||
*/
|
||||
proto.a6.RouteServicePromiseClient.prototype.remove =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/a6.RouteService/Remove',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_RouteService_Remove);
|
||||
};
|
||||
|
||||
|
||||
module.exports = proto.a6;
|
||||
|
766
t/plugin/grpc-web/a6/routes_pb.js
Normal file
766
t/plugin/grpc-web/a6/routes_pb.js
Normal file
@ -0,0 +1,766 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var jspb = require('google-protobuf');
|
||||
var goog = jspb;
|
||||
var global = Function('return this')();
|
||||
|
||||
goog.exportSymbol('proto.a6.Empty', null, global);
|
||||
goog.exportSymbol('proto.a6.Request', null, global);
|
||||
goog.exportSymbol('proto.a6.Response', null, global);
|
||||
goog.exportSymbol('proto.a6.Route', null, global);
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
* server response, or constructed directly in Javascript. The array is used
|
||||
* in place and becomes part of the constructed object. It is not cloned.
|
||||
* If no data is provided, the constructed object will be empty, but still
|
||||
* valid.
|
||||
* @extends {jspb.Message}
|
||||
* @constructor
|
||||
*/
|
||||
proto.a6.Empty = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.a6.Empty, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.a6.Empty.displayName = 'proto.a6.Empty';
|
||||
}
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
* server response, or constructed directly in Javascript. The array is used
|
||||
* in place and becomes part of the constructed object. It is not cloned.
|
||||
* If no data is provided, the constructed object will be empty, but still
|
||||
* valid.
|
||||
* @extends {jspb.Message}
|
||||
* @constructor
|
||||
*/
|
||||
proto.a6.Route = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.a6.Route, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.a6.Route.displayName = 'proto.a6.Route';
|
||||
}
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
* server response, or constructed directly in Javascript. The array is used
|
||||
* in place and becomes part of the constructed object. It is not cloned.
|
||||
* If no data is provided, the constructed object will be empty, but still
|
||||
* valid.
|
||||
* @extends {jspb.Message}
|
||||
* @constructor
|
||||
*/
|
||||
proto.a6.Request = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.a6.Request, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.a6.Request.displayName = 'proto.a6.Request';
|
||||
}
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
* server response, or constructed directly in Javascript. The array is used
|
||||
* in place and becomes part of the constructed object. It is not cloned.
|
||||
* If no data is provided, the constructed object will be empty, but still
|
||||
* valid.
|
||||
* @extends {jspb.Message}
|
||||
* @constructor
|
||||
*/
|
||||
proto.a6.Response = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.a6.Response, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.a6.Response.displayName = 'proto.a6.Response';
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||
* Optional fields that are not set will be set to undefined.
|
||||
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||
* For the list of reserved names please see:
|
||||
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||
* JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.a6.Empty.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.a6.Empty.toObject(opt_includeInstance, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static version of the {@see toObject} method.
|
||||
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||
* the JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @param {!proto.a6.Empty} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.a6.Empty.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
obj.$jspbMessageInstance = msg;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format).
|
||||
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||
* @return {!proto.a6.Empty}
|
||||
*/
|
||||
proto.a6.Empty.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.a6.Empty;
|
||||
return proto.a6.Empty.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.a6.Empty} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.a6.Empty}
|
||||
*/
|
||||
proto.a6.Empty.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.a6.Empty.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.a6.Empty.serializeBinaryToWriter(this, writer);
|
||||
return writer.getResultBuffer();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the given message to binary data (in protobuf wire
|
||||
* format), writing to the given BinaryWriter.
|
||||
* @param {!proto.a6.Empty} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.a6.Empty.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||
* Optional fields that are not set will be set to undefined.
|
||||
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||
* For the list of reserved names please see:
|
||||
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||
* JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.a6.Route.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.a6.Route.toObject(opt_includeInstance, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static version of the {@see toObject} method.
|
||||
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||
* the JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @param {!proto.a6.Route} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.a6.Route.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
name: jspb.Message.getFieldWithDefault(msg, 1, ""),
|
||||
path: jspb.Message.getFieldWithDefault(msg, 2, "")
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
obj.$jspbMessageInstance = msg;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format).
|
||||
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||
* @return {!proto.a6.Route}
|
||||
*/
|
||||
proto.a6.Route.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.a6.Route;
|
||||
return proto.a6.Route.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.a6.Route} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.a6.Route}
|
||||
*/
|
||||
proto.a6.Route.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setName(value);
|
||||
break;
|
||||
case 2:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setPath(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.a6.Route.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.a6.Route.serializeBinaryToWriter(this, writer);
|
||||
return writer.getResultBuffer();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the given message to binary data (in protobuf wire
|
||||
* format), writing to the given BinaryWriter.
|
||||
* @param {!proto.a6.Route} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.a6.Route.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getName();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
1,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getPath();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
2,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string name = 1;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.a6.Route.prototype.getName = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.a6.Route} returns this
|
||||
*/
|
||||
proto.a6.Route.prototype.setName = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string path = 2;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.a6.Route.prototype.getPath = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.a6.Route} returns this
|
||||
*/
|
||||
proto.a6.Route.prototype.setPath = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 2, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||
* Optional fields that are not set will be set to undefined.
|
||||
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||
* For the list of reserved names please see:
|
||||
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||
* JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.a6.Request.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.a6.Request.toObject(opt_includeInstance, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static version of the {@see toObject} method.
|
||||
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||
* the JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @param {!proto.a6.Request} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.a6.Request.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
id: jspb.Message.getFieldWithDefault(msg, 1, ""),
|
||||
route: (f = msg.getRoute()) && proto.a6.Route.toObject(includeInstance, f)
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
obj.$jspbMessageInstance = msg;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format).
|
||||
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||
* @return {!proto.a6.Request}
|
||||
*/
|
||||
proto.a6.Request.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.a6.Request;
|
||||
return proto.a6.Request.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.a6.Request} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.a6.Request}
|
||||
*/
|
||||
proto.a6.Request.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setId(value);
|
||||
break;
|
||||
case 2:
|
||||
var value = new proto.a6.Route;
|
||||
reader.readMessage(value,proto.a6.Route.deserializeBinaryFromReader);
|
||||
msg.setRoute(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.a6.Request.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.a6.Request.serializeBinaryToWriter(this, writer);
|
||||
return writer.getResultBuffer();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the given message to binary data (in protobuf wire
|
||||
* format), writing to the given BinaryWriter.
|
||||
* @param {!proto.a6.Request} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.a6.Request.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getId();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
1,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getRoute();
|
||||
if (f != null) {
|
||||
writer.writeMessage(
|
||||
2,
|
||||
f,
|
||||
proto.a6.Route.serializeBinaryToWriter
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string id = 1;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.a6.Request.prototype.getId = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.a6.Request} returns this
|
||||
*/
|
||||
proto.a6.Request.prototype.setId = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional Route route = 2;
|
||||
* @return {?proto.a6.Route}
|
||||
*/
|
||||
proto.a6.Request.prototype.getRoute = function() {
|
||||
return /** @type{?proto.a6.Route} */ (
|
||||
jspb.Message.getWrapperField(this, proto.a6.Route, 2));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {?proto.a6.Route|undefined} value
|
||||
* @return {!proto.a6.Request} returns this
|
||||
*/
|
||||
proto.a6.Request.prototype.setRoute = function(value) {
|
||||
return jspb.Message.setWrapperField(this, 2, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the message field making it undefined.
|
||||
* @return {!proto.a6.Request} returns this
|
||||
*/
|
||||
proto.a6.Request.prototype.clearRoute = function() {
|
||||
return this.setRoute(undefined);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether this field is set.
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.a6.Request.prototype.hasRoute = function() {
|
||||
return jspb.Message.getField(this, 2) != null;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||
* Optional fields that are not set will be set to undefined.
|
||||
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||
* For the list of reserved names please see:
|
||||
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||
* JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.a6.Response.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.a6.Response.toObject(opt_includeInstance, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static version of the {@see toObject} method.
|
||||
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||
* the JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @param {!proto.a6.Response} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.a6.Response.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
status: jspb.Message.getBooleanFieldWithDefault(msg, 1, false),
|
||||
route: (f = msg.getRoute()) && proto.a6.Route.toObject(includeInstance, f),
|
||||
routesMap: (f = msg.getRoutesMap()) ? f.toObject(includeInstance, proto.a6.Route.toObject) : []
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
obj.$jspbMessageInstance = msg;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format).
|
||||
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||
* @return {!proto.a6.Response}
|
||||
*/
|
||||
proto.a6.Response.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.a6.Response;
|
||||
return proto.a6.Response.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.a6.Response} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.a6.Response}
|
||||
*/
|
||||
proto.a6.Response.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = /** @type {boolean} */ (reader.readBool());
|
||||
msg.setStatus(value);
|
||||
break;
|
||||
case 2:
|
||||
var value = new proto.a6.Route;
|
||||
reader.readMessage(value,proto.a6.Route.deserializeBinaryFromReader);
|
||||
msg.setRoute(value);
|
||||
break;
|
||||
case 3:
|
||||
var value = msg.getRoutesMap();
|
||||
reader.readMessage(value, function(message, reader) {
|
||||
jspb.Map.deserializeBinary(message, reader, jspb.BinaryReader.prototype.readString, jspb.BinaryReader.prototype.readMessage, proto.a6.Route.deserializeBinaryFromReader, "", new proto.a6.Route());
|
||||
});
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.a6.Response.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.a6.Response.serializeBinaryToWriter(this, writer);
|
||||
return writer.getResultBuffer();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the given message to binary data (in protobuf wire
|
||||
* format), writing to the given BinaryWriter.
|
||||
* @param {!proto.a6.Response} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.a6.Response.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getStatus();
|
||||
if (f) {
|
||||
writer.writeBool(
|
||||
1,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getRoute();
|
||||
if (f != null) {
|
||||
writer.writeMessage(
|
||||
2,
|
||||
f,
|
||||
proto.a6.Route.serializeBinaryToWriter
|
||||
);
|
||||
}
|
||||
f = message.getRoutesMap(true);
|
||||
if (f && f.getLength() > 0) {
|
||||
f.serializeBinary(3, writer, jspb.BinaryWriter.prototype.writeString, jspb.BinaryWriter.prototype.writeMessage, proto.a6.Route.serializeBinaryToWriter);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional bool status = 1;
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.a6.Response.prototype.getStatus = function() {
|
||||
return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {boolean} value
|
||||
* @return {!proto.a6.Response} returns this
|
||||
*/
|
||||
proto.a6.Response.prototype.setStatus = function(value) {
|
||||
return jspb.Message.setProto3BooleanField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional Route route = 2;
|
||||
* @return {?proto.a6.Route}
|
||||
*/
|
||||
proto.a6.Response.prototype.getRoute = function() {
|
||||
return /** @type{?proto.a6.Route} */ (
|
||||
jspb.Message.getWrapperField(this, proto.a6.Route, 2));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {?proto.a6.Route|undefined} value
|
||||
* @return {!proto.a6.Response} returns this
|
||||
*/
|
||||
proto.a6.Response.prototype.setRoute = function(value) {
|
||||
return jspb.Message.setWrapperField(this, 2, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the message field making it undefined.
|
||||
* @return {!proto.a6.Response} returns this
|
||||
*/
|
||||
proto.a6.Response.prototype.clearRoute = function() {
|
||||
return this.setRoute(undefined);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether this field is set.
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.a6.Response.prototype.hasRoute = function() {
|
||||
return jspb.Message.getField(this, 2) != null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* map<string, Route> routes = 3;
|
||||
* @param {boolean=} opt_noLazyCreate Do not create the map if
|
||||
* empty, instead returning `undefined`
|
||||
* @return {!jspb.Map<string,!proto.a6.Route>}
|
||||
*/
|
||||
proto.a6.Response.prototype.getRoutesMap = function(opt_noLazyCreate) {
|
||||
return /** @type {!jspb.Map<string,!proto.a6.Route>} */ (
|
||||
jspb.Message.getMapField(this, 3, opt_noLazyCreate,
|
||||
proto.a6.Route));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears values from the map. The map will be non-null.
|
||||
* @return {!proto.a6.Response} returns this
|
||||
*/
|
||||
proto.a6.Response.prototype.clearRoutesMap = function() {
|
||||
this.getRoutesMap().clear();
|
||||
return this;};
|
||||
|
||||
|
||||
goog.object.extend(exports, proto.a6);
|
178
t/plugin/grpc-web/client.js
Normal file
178
t/plugin/grpc-web/client.js
Normal file
@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.
|
||||
*/
|
||||
|
||||
global.XMLHttpRequest = require('xhr2')
|
||||
|
||||
const {Empty, Request, Route} = require('./a6/routes_pb')
|
||||
const {RouteServiceClient} = require('./a6/routes_grpc_web_pb')
|
||||
|
||||
const FUNCTION_ALL = "ALL"
|
||||
const FUNCTION_GET = "GET"
|
||||
const FUNCTION_POST = "POST"
|
||||
const FUNCTION_PUT = "PUT"
|
||||
const FUNCTION_DEL = "DEL"
|
||||
const FUNCTION_FLUSH = "FLUSH"
|
||||
|
||||
const functions = [FUNCTION_ALL, FUNCTION_GET, FUNCTION_POST, FUNCTION_PUT, FUNCTION_DEL, FUNCTION_FLUSH]
|
||||
|
||||
class gRPCWebClient {
|
||||
constructor() {
|
||||
this.client = new RouteServiceClient("http://127.0.0.1:1984/grpc", null, null)
|
||||
};
|
||||
|
||||
flush() {
|
||||
let request = new Empty()
|
||||
this.client.flushAll(request, {}, function (error, response) {
|
||||
if (error) {
|
||||
console.log(error)
|
||||
return
|
||||
}
|
||||
console.log(JSON.stringify(response.toObject().routesMap))
|
||||
});
|
||||
}
|
||||
|
||||
all() {
|
||||
let request = new Empty()
|
||||
this.client.getAll(request, {}, function (error, response) {
|
||||
if (error) {
|
||||
console.log(error)
|
||||
return
|
||||
}
|
||||
console.log(JSON.stringify(response.toObject().routesMap))
|
||||
});
|
||||
}
|
||||
|
||||
get(params) {
|
||||
if (params[0] === null) {
|
||||
console.log("route ID invalid")
|
||||
return
|
||||
}
|
||||
let request = new Request()
|
||||
request.setId(params[0])
|
||||
this.client.get(request, {}, function (error, response) {
|
||||
if (error) {
|
||||
console.log(error)
|
||||
return
|
||||
}
|
||||
console.log(JSON.stringify(response.toObject().route))
|
||||
});
|
||||
}
|
||||
|
||||
post(params) {
|
||||
if (params[0] === null) {
|
||||
console.log("route ID invalid")
|
||||
return
|
||||
}
|
||||
if (params[1] === null) {
|
||||
console.log("route Name invalid")
|
||||
return
|
||||
}
|
||||
if (params[2] === null) {
|
||||
console.log("route Path invalid")
|
||||
return
|
||||
}
|
||||
let request = new Request()
|
||||
let route = new Route()
|
||||
request.setId(params[0])
|
||||
route.setName(params[1])
|
||||
route.setPath(params[2])
|
||||
request.setRoute(route)
|
||||
this.client.insert(request, {}, function (error, response) {
|
||||
if (error) {
|
||||
console.log(error)
|
||||
return
|
||||
}
|
||||
console.log(JSON.stringify(response.toObject().routesMap))
|
||||
});
|
||||
}
|
||||
|
||||
put(params) {
|
||||
if (params[0] === null) {
|
||||
console.log("route ID invalid")
|
||||
return
|
||||
}
|
||||
if (params[1] === null) {
|
||||
console.log("route Name invalid")
|
||||
return
|
||||
}
|
||||
if (params[2] === null) {
|
||||
console.log("route Path invalid")
|
||||
return
|
||||
}
|
||||
let request = new Request()
|
||||
let route = new Route()
|
||||
request.setId(params[0])
|
||||
route.setName(params[1])
|
||||
route.setPath(params[2])
|
||||
request.setRoute(route)
|
||||
this.client.update(request, {}, function (error, response) {
|
||||
if (error) {
|
||||
console.log(error)
|
||||
return
|
||||
}
|
||||
console.log(JSON.stringify(response.toObject().routesMap))
|
||||
})
|
||||
}
|
||||
|
||||
del() {
|
||||
if (params[0] === null) {
|
||||
console.log("route ID invalid")
|
||||
return
|
||||
}
|
||||
let request = new Request()
|
||||
request.setId(params[0])
|
||||
this.client.remove(request, {}, function (error, response) {
|
||||
if (error) {
|
||||
console.log(error)
|
||||
return
|
||||
}
|
||||
console.log(JSON.stringify(response.toObject().routesMap))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const arguments = process.argv.splice(2)
|
||||
|
||||
if (arguments.length === 0) {
|
||||
console.log("please input dispatch function, e.g: node client.js insert arg_id arg_name arg_path")
|
||||
return
|
||||
}
|
||||
|
||||
const func = arguments[0].toUpperCase()
|
||||
if (!functions.includes(func)) {
|
||||
console.log("dispatch function not found")
|
||||
return
|
||||
}
|
||||
|
||||
const params = arguments.splice(1)
|
||||
|
||||
let grpc = new gRPCWebClient();
|
||||
|
||||
if (func === FUNCTION_GET) {
|
||||
grpc.get(params)
|
||||
} else if (func === FUNCTION_POST) {
|
||||
grpc.post(params)
|
||||
} else if (func === FUNCTION_PUT) {
|
||||
grpc.put(params)
|
||||
} else if (func === FUNCTION_DEL) {
|
||||
grpc.del(params)
|
||||
} else if (func === FUNCTION_FLUSH) {
|
||||
grpc.flush()
|
||||
} else {
|
||||
grpc.all()
|
||||
}
|
13
t/plugin/grpc-web/go.mod
Normal file
13
t/plugin/grpc-web/go.mod
Normal file
@ -0,0 +1,13 @@
|
||||
module apisix.apache.org/plugin/grpc-web
|
||||
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/golang/protobuf v1.4.3
|
||||
github.com/satori/go.uuid v1.2.0 // indirect
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 // indirect
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da // indirect
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
|
||||
golang.org/x/text v0.3.6 // indirect
|
||||
google.golang.org/grpc v1.43.0
|
||||
)
|
125
t/plugin/grpc-web/go.sum
Normal file
125
t/plugin/grpc-web/go.sum
Normal file
@ -0,0 +1,125 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM=
|
||||
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.43.0 h1:Eeu7bZtDZ2DpRCsLhUlcrLnvYaMK1Gz86a+hMVvELmM=
|
||||
google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
52
t/plugin/grpc-web/package-lock.json
generated
Normal file
52
t/plugin/grpc-web/package-lock.json
generated
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"name": "apisix-grpc-web",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "apisix.apache.org/plugin/grpc-web",
|
||||
"dependencies": {
|
||||
"google-protobuf": "^3.19.1",
|
||||
"grpc-web": "^1.3.0",
|
||||
"xhr2": "^0.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/google-protobuf": {
|
||||
"version": "3.19.1",
|
||||
"resolved": "https://registry.npmmirror.com/google-protobuf/download/google-protobuf-3.19.1.tgz?cache=0&sync_timestamp=1635869461201&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fgoogle-protobuf%2Fdownload%2Fgoogle-protobuf-3.19.1.tgz",
|
||||
"integrity": "sha1-WvU5DoIGxEbY9J/rr/1Lf0rCj0E=",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/grpc-web": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/grpc-web/download/grpc-web-1.3.0.tgz",
|
||||
"integrity": "sha1-TDbZfnp7YQKn30Y+eCLNhtT2Xtg=",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/xhr2": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npm.taobao.org/xhr2/download/xhr2-0.2.1.tgz",
|
||||
"integrity": "sha1-TnOtxPnP7Jy9IVf3Pv3OOl8QipM=",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"google-protobuf": {
|
||||
"version": "3.19.1",
|
||||
"resolved": "https://registry.npmmirror.com/google-protobuf/download/google-protobuf-3.19.1.tgz?cache=0&sync_timestamp=1635869461201&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fgoogle-protobuf%2Fdownload%2Fgoogle-protobuf-3.19.1.tgz",
|
||||
"integrity": "sha1-WvU5DoIGxEbY9J/rr/1Lf0rCj0E="
|
||||
},
|
||||
"grpc-web": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/grpc-web/download/grpc-web-1.3.0.tgz",
|
||||
"integrity": "sha1-TDbZfnp7YQKn30Y+eCLNhtT2Xtg="
|
||||
},
|
||||
"xhr2": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npm.taobao.org/xhr2/download/xhr2-0.2.1.tgz",
|
||||
"integrity": "sha1-TnOtxPnP7Jy9IVf3Pv3OOl8QipM="
|
||||
}
|
||||
}
|
||||
}
|
8
t/plugin/grpc-web/package.json
Normal file
8
t/plugin/grpc-web/package.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "apisix-grpc-web",
|
||||
"dependencies": {
|
||||
"google-protobuf": "^3.19.1",
|
||||
"grpc-web": "^1.3.0",
|
||||
"xhr2": "^0.2.1"
|
||||
}
|
||||
}
|
53
t/plugin/grpc-web/server.go
Normal file
53
t/plugin/grpc-web/server.go
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"net"
|
||||
|
||||
"apisix.apache.org/plugin/grpc-web/a6"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/reflection"
|
||||
)
|
||||
|
||||
var grpcListenAddress string
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&grpcListenAddress, "listen", ":50001", "address for grpc")
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
listen, err := net.Listen("tcp", grpcListenAddress)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to listen gRPC-Web Test Server: %v", err)
|
||||
} else {
|
||||
log.Printf("successful to listen gRPC-Web Test Server, address %s", grpcListenAddress)
|
||||
}
|
||||
|
||||
s := a6.RouteServer{}
|
||||
grpcServer := grpc.NewServer()
|
||||
reflection.Register(grpcServer)
|
||||
a6.RegisterRouteServiceServer(grpcServer, &s)
|
||||
|
||||
if err = grpcServer.Serve(listen); err != nil {
|
||||
log.Fatalf("failed to serve: %v", err)
|
||||
}
|
||||
}
|
25
t/plugin/grpc-web/setup.sh
Executable file
25
t/plugin/grpc-web/setup.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
set -ex
|
||||
|
||||
npm install
|
||||
|
||||
CGO_ENABLED=0 go build -o grpc-web-server server.go
|
||||
|
||||
./grpc-web-server > grpc-web-server.log 2>&1 || (cat grpc-web-server.log && exit 1)&
|
Loading…
Reference in New Issue
Block a user