feat(grpc-web): support gRPC-Web Proxy (#5964)

This commit is contained in:
帅进超 2022-01-09 23:59:32 +08:00 committed by GitHub
parent 7db31a1a71
commit ddb9cd28bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 2893 additions and 0 deletions

147
apisix/plugins/grpc-web.lua Normal file
View 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

View File

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

View File

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

View File

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

View File

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

View File

@ -51,6 +51,7 @@
"plugins/response-rewrite",
"plugins/proxy-rewrite",
"plugins/grpc-transcode",
"plugins/grpc-web",
"plugins/fault-injection"
]
},

View 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
}
}
}'
```

View File

@ -51,6 +51,7 @@
"plugins/response-rewrite",
"plugins/proxy-rewrite",
"plugins/grpc-transcode",
"plugins/grpc-web",
"plugins/fault-injection"
]
},

View 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
View File

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

View 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",
}

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

View 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")
}

View 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;

View 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
View 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
View 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
View 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
View 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="
}
}
}

View File

@ -0,0 +1,8 @@
{
"name": "apisix-grpc-web",
"dependencies": {
"google-protobuf": "^3.19.1",
"grpc-web": "^1.3.0",
"xhr2": "^0.2.1"
}
}

View 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
View 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)&